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:
authorRoman Pogribnyi <pogribnyi@gmail.com>2015-03-15 21:57:06 +0300
committerRoman Pogribnyi <pogribnyi@gmail.com>2015-03-15 21:57:06 +0300
commit5c64aa25541b973db4ec90c97e30b02d09b00075 (patch)
tree0cd3a8912d8b0cbfc5fe0bb94a2a42751e98dcd6
parent2a1a6bc5720a4310e42a67754998e0480bf7c59b (diff)
parent225027ce5dea3785626908b58b01fb3959cf8362 (diff)
Merge branch 'master' into soc-2014-fluid
-rw-r--r--CMakeLists.txt566
-rw-r--r--GNUmakefile91
-rw-r--r--SConstruct54
-rwxr-xr-xbuild_files/build_environment/install_deps.sh163
-rw-r--r--build_files/buildbot/config/user-config-cuda-glibc211-i686.py2
-rw-r--r--build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py2
-rw-r--r--build_files/buildbot/config/user-config-glibc211-i686.py13
-rw-r--r--build_files/buildbot/config/user-config-glibc211-x86_64.py13
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-i686.py2
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-x86_64.py2
-rw-r--r--build_files/buildbot/master.cfg40
-rw-r--r--build_files/buildbot/master_unpack.py30
-rw-r--r--build_files/buildbot/slave_compile.py14
-rw-r--r--build_files/buildbot/slave_pack.py26
-rw-r--r--build_files/cmake/Modules/FindGLEW.cmake2
-rw-r--r--build_files/cmake/Modules/FindJeMalloc.cmake1
-rw-r--r--build_files/cmake/Modules/FindLZO.cmake68
-rw-r--r--build_files/cmake/Modules/FindOpenCOLLADA.cmake5
-rw-r--r--build_files/cmake/Modules/FindOpenColorIO.cmake13
-rw-r--r--build_files/cmake/Modules/FindOpenEXR.cmake7
-rw-r--r--build_files/cmake/Modules/FindOpenGLES.cmake2
-rw-r--r--build_files/cmake/Modules/FindOpenImageIO.cmake20
-rw-r--r--build_files/cmake/Modules/FindOpenJPEG.cmake2
-rw-r--r--build_files/cmake/Modules/FindOpenShadingLanguage.cmake98
-rw-r--r--build_files/cmake/Modules/FindPugiXML.cmake73
-rw-r--r--build_files/cmake/Modules/FindSDL2.cmake72
-rw-r--r--build_files/cmake/Modules/GTestTesting.cmake2
-rw-r--r--build_files/cmake/buildinfo.cmake8
-rwxr-xr-xbuild_files/cmake/cmake_consistency_check.py6
-rwxr-xr-xbuild_files/cmake/cmake_netbeans_project.py4
-rwxr-xr-xbuild_files/cmake/cmake_qtcreator_project.py69
-rw-r--r--build_files/cmake/config/blender_full.cmake62
-rw-r--r--build_files/cmake/config/blender_lite.cmake1
-rw-r--r--build_files/cmake/macros.cmake117
-rw-r--r--build_files/cmake/packaging.cmake26
-rwxr-xr-xbuild_files/package_spec/build_archive.py2
-rw-r--r--build_files/package_spec/pacman/PKGBUILD14
-rw-r--r--build_files/scons/config/darwin-config.py4
-rw-r--r--build_files/scons/config/linux-config.py8
-rw-r--r--build_files/scons/config/win32-mingw-config.py7
-rw-r--r--build_files/scons/config/win32-vc-config.py15
-rw-r--r--build_files/scons/config/win64-mingw-config.py10
-rw-r--r--build_files/scons/config/win64-vc-config.py15
-rw-r--r--[-rwxr-xr-x]build_files/scons/tools/Blender.py39
-rw-r--r--build_files/scons/tools/btools.py17
-rwxr-xr-xbuild_files/utils/build_tgz.sh11
-rwxr-xr-xdoc/blender_file_format/BlendFileDnaExporter_25.py6
-rw-r--r--doc/build_systems/scons-dev.txt15
-rw-r--r--doc/build_systems/scons.txt41
-rw-r--r--doc/doxygen/Doxyfile2
-rw-r--r--doc/doxygen/doxygen.main2
-rwxr-xr-xdoc/manpage/blender.1.py2
-rw-r--r--doc/python_api/examples/bpy.types.Panel.2.py2
-rw-r--r--doc/python_api/examples/mathutils.Quaternion.py9
-rw-r--r--doc/python_api/examples/mathutils.Vector.py10
-rw-r--r--doc/python_api/rst/bge.render.rst23
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst2
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst93
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_ObjectActuator.rst12
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_Scene.rst2
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst21
-rw-r--r--doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst22
-rw-r--r--doc/python_api/rst/bge_types/bge.types.SCA_PythonMouse.rst2
-rw-r--r--doc/python_api/rst/bgl.rst8
-rw-r--r--doc/python_api/rst/info_quickstart.rst146
-rw-r--r--doc/python_api/rst/info_tutorial_addon.rst84
-rw-r--r--doc/python_api/sphinx_changelog_gen.py2
-rw-r--r--doc/python_api/sphinx_doc_gen.py21
-rwxr-xr-xdoc/python_api/sphinx_doc_gen.sh8
-rw-r--r--extern/CMakeLists.txt6
-rw-r--r--extern/SConscript3
-rw-r--r--extern/bullet2/readme.txt5
-rw-r--r--[-rwxr-xr-x]extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp0
-rw-r--r--[-rwxr-xr-x]extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h0
-rw-r--r--extern/carve/CMakeLists.txt1
-rw-r--r--extern/carve/SConscript1
-rwxr-xr-xextern/carve/bundle.sh6
-rw-r--r--extern/carve/include/carve/random/random.h61
-rw-r--r--extern/carve/lib/polyhedron.cpp6
-rw-r--r--extern/carve/patches/files/random.h61
-rw-r--r--extern/carve/patches/random.patch16
-rw-r--r--extern/carve/patches/series1
-rw-r--r--extern/clew/include/clew.h11
-rw-r--r--extern/libmv/CMakeLists.txt93
-rw-r--r--extern/libmv/ChangeLog774
-rw-r--r--extern/libmv/SConscript52
-rwxr-xr-xextern/libmv/bundle.sh132
-rw-r--r--extern/libmv/files.txt26
-rw-r--r--extern/libmv/intern/autotrack.cc99
-rw-r--r--extern/libmv/intern/autotrack.h71
-rw-r--r--extern/libmv/intern/frame_accessor.cc164
-rw-r--r--extern/libmv/intern/frame_accessor.h79
-rw-r--r--extern/libmv/intern/image.cc2
-rw-r--r--extern/libmv/intern/image.h2
-rw-r--r--extern/libmv/intern/logging.cc18
-rw-r--r--extern/libmv/intern/reconstruction.cc13
-rw-r--r--extern/libmv/intern/reconstruction.h2
-rw-r--r--extern/libmv/intern/stub.cc73
-rw-r--r--extern/libmv/intern/tracksN.cc138
-rw-r--r--extern/libmv/intern/tracksN.h129
-rw-r--r--extern/libmv/libmv-capi.h3
-rw-r--r--extern/libmv/libmv/autotrack/autotrack.cc290
-rw-r--r--extern/libmv/libmv/autotrack/autotrack.h226
-rw-r--r--extern/libmv/libmv/autotrack/callbacks.h38
-rw-r--r--extern/libmv/libmv/autotrack/frame_accessor.h86
-rw-r--r--extern/libmv/libmv/autotrack/marker.h144
-rw-r--r--extern/libmv/libmv/autotrack/model.h44
-rw-r--r--extern/libmv/libmv/autotrack/predict_tracks.cc316
-rw-r--r--extern/libmv/libmv/autotrack/predict_tracks.h37
-rw-r--r--extern/libmv/libmv/autotrack/predict_tracks_test.cc201
-rw-r--r--extern/libmv/libmv/autotrack/quad.h57
-rw-r--r--extern/libmv/libmv/autotrack/reconstruction.h89
-rw-r--r--extern/libmv/libmv/autotrack/region.h67
-rw-r--r--extern/libmv/libmv/autotrack/tracks.cc193
-rw-r--r--extern/libmv/libmv/autotrack/tracks.h82
-rw-r--r--extern/libmv/libmv/autotrack/tracks_test.cc52
-rw-r--r--extern/libmv/libmv/base/vector.h6
-rw-r--r--extern/libmv/libmv/image/array_nd.h24
-rw-r--r--extern/libmv/libmv/multiview/homography.cc4
-rw-r--r--extern/libmv/libmv/simple_pipeline/keyframe_selection.cc67
-rw-r--r--extern/libmv/libmv/tracking/kalman_filter.h112
-rw-r--r--extern/libmv/libmv/tracking/track_region.h11
-rwxr-xr-xextern/libmv/third_party/ceres/bundle.sh2
-rw-r--r--extern/libmv/third_party/gflags/AUTHORS.txt (renamed from extern/libmv/third_party/gflags/AUTHORS)0
-rw-r--r--extern/libmv/third_party/gflags/COPYING.txt (renamed from extern/libmv/third_party/gflags/COPYING)0
-rw-r--r--extern/libmv/third_party/gflags/ChangeLog195
-rw-r--r--extern/libmv/third_party/gflags/ChangeLog.txt208
-rw-r--r--extern/libmv/third_party/gflags/NEWS.txt (renamed from extern/libmv/third_party/gflags/NEWS)86
-rw-r--r--extern/libmv/third_party/gflags/README.libmv16
-rw-r--r--extern/libmv/third_party/gflags/config.h162
-rw-r--r--extern/libmv/third_party/gflags/gflags.cc117
-rw-r--r--extern/libmv/third_party/gflags/gflags/gflags.h180
-rw-r--r--extern/libmv/third_party/gflags/gflags/gflags_completions.h17
-rw-r--r--extern/libmv/third_party/gflags/gflags/gflags_declare.h92
-rw-r--r--extern/libmv/third_party/gflags/gflags_completions.cc14
-rw-r--r--extern/libmv/third_party/gflags/gflags_reporting.cc52
-rw-r--r--extern/libmv/third_party/gflags/mutex.h19
-rw-r--r--extern/libmv/third_party/gflags/util.h114
-rw-r--r--extern/libmv/third_party/gflags/windows_port.cc71
-rw-r--r--extern/libmv/third_party/gflags/windows_port.h127
-rw-r--r--extern/libmv/third_party/glog/README.libmv2
-rw-r--r--extern/libmv/third_party/glog/src/demangle.cc5
-rw-r--r--extern/libmv/third_party/glog/src/logging.cc5
-rw-r--r--extern/libmv/third_party/glog/src/symbolize.cc239
-rw-r--r--extern/libmv/third_party/glog/src/symbolize.h41
-rw-r--r--extern/lzo/CMakeLists.txt2
-rw-r--r--extern/sdlew/CMakeLists.txt40
-rw-r--r--extern/sdlew/SConscript35
-rwxr-xr-xextern/sdlew/auto/sdlew_gen.sh250
-rwxr-xr-xextern/sdlew/auto/strip_comments.sh15
-rw-r--r--extern/sdlew/include/SDL2/SDL.h73
-rw-r--r--extern/sdlew/include/SDL2/SDL_assert.h140
-rw-r--r--extern/sdlew/include/SDL2/SDL_atomic.h185
-rw-r--r--extern/sdlew/include/SDL2/SDL_audio.h222
-rw-r--r--extern/sdlew/include/SDL2/SDL_bits.h53
-rw-r--r--extern/sdlew/include/SDL2/SDL_blendmode.h25
-rw-r--r--extern/sdlew/include/SDL2/SDL_clipboard.h29
-rw-r--r--extern/sdlew/include/SDL2/SDL_config.h175
-rw-r--r--extern/sdlew/include/SDL2/SDL_cpuinfo.h86
-rw-r--r--extern/sdlew/include/SDL2/SDL_endian.h193
-rw-r--r--extern/sdlew/include/SDL2/SDL_error.h43
-rw-r--r--extern/sdlew/include/SDL2/SDL_events.h446
-rw-r--r--extern/sdlew/include/SDL2/SDL_gamecontroller.h143
-rw-r--r--extern/sdlew/include/SDL2/SDL_gesture.h38
-rw-r--r--extern/sdlew/include/SDL2/SDL_haptic.h302
-rw-r--r--extern/sdlew/include/SDL2/SDL_hints.h87
-rw-r--r--extern/sdlew/include/SDL2/SDL_joystick.h106
-rw-r--r--extern/sdlew/include/SDL2/SDL_keyboard.h79
-rw-r--r--extern/sdlew/include/SDL2/SDL_keycode.h301
-rw-r--r--extern/sdlew/include/SDL2/SDL_loadso.h31
-rw-r--r--extern/sdlew/include/SDL2/SDL_log.h111
-rw-r--r--extern/sdlew/include/SDL2/SDL_main.h56
-rw-r--r--extern/sdlew/include/SDL2/SDL_messagebox.h80
-rw-r--r--extern/sdlew/include/SDL2/SDL_mouse.h101
-rw-r--r--extern/sdlew/include/SDL2/SDL_mutex.h91
-rw-r--r--extern/sdlew/include/SDL2/SDL_name.h11
-rw-r--r--extern/sdlew/include/SDL2/SDL_opengl.h10607
-rw-r--r--extern/sdlew/include/SDL2/SDL_opengles.h12
-rw-r--r--extern/sdlew/include/SDL2/SDL_opengles2.h12
-rw-r--r--extern/sdlew/include/SDL2/SDL_pixels.h320
-rw-r--r--extern/sdlew/include/SDL2/SDL_platform.h122
-rw-r--r--extern/sdlew/include/SDL2/SDL_power.h32
-rw-r--r--extern/sdlew/include/SDL2/SDL_quit.h11
-rw-r--r--extern/sdlew/include/SDL2/SDL_rect.h72
-rw-r--r--extern/sdlew/include/SDL2/SDL_render.h280
-rw-r--r--extern/sdlew/include/SDL2/SDL_revision.h2
-rw-r--r--extern/sdlew/include/SDL2/SDL_rwops.h162
-rw-r--r--extern/sdlew/include/SDL2/SDL_scancode.h273
-rw-r--r--extern/sdlew/include/SDL2/SDL_shape.h60
-rw-r--r--extern/sdlew/include/SDL2/SDL_stdinc.h378
-rw-r--r--extern/sdlew/include/SDL2/SDL_surface.h190
-rw-r--r--extern/sdlew/include/SDL2/SDL_system.h48
-rw-r--r--extern/sdlew/include/SDL2/SDL_syswm.h171
-rw-r--r--extern/sdlew/include/SDL2/SDL_test.h32
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_assert.h33
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_common.h103
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_compare.h23
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_crc32.h44
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_font.h19
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_fuzzer.h69
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_harness.h67
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_images.h38
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_log.h21
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_md5.h33
-rw-r--r--extern/sdlew/include/SDL2/SDL_test_random.h34
-rw-r--r--extern/sdlew/include/SDL2/SDL_thread.h90
-rw-r--r--extern/sdlew/include/SDL2/SDL_timer.h45
-rw-r--r--extern/sdlew/include/SDL2/SDL_touch.h47
-rw-r--r--extern/sdlew/include/SDL2/SDL_types.h2
-rw-r--r--extern/sdlew/include/SDL2/SDL_version.h56
-rw-r--r--extern/sdlew/include/SDL2/SDL_video.h367
-rw-r--r--extern/sdlew/include/SDL2/begin_code.h107
-rw-r--r--extern/sdlew/include/SDL2/close_code.h9
-rw-r--r--extern/sdlew/include/sdlew.h (renamed from intern/cycles/util/util_dynlib.h)28
-rw-r--r--extern/sdlew/src/sdlew.c1112
-rw-r--r--extern/sdlew/src/sdlew.map7
-rw-r--r--intern/atomic/atomic_ops.h9
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.cpp2
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp22
-rw-r--r--intern/audaspace/intern/AUD_C-API.h2
-rw-r--r--intern/audaspace/intern/AUD_Sequencer.cpp2
-rw-r--r--intern/audaspace/intern/AUD_SequencerHandle.cpp256
-rw-r--r--intern/audaspace/intern/AUD_SequencerHandle.h18
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp2
-rw-r--r--intern/cycles/CMakeLists.txt53
-rw-r--r--intern/cycles/SConscript12
-rw-r--r--intern/cycles/app/CMakeLists.txt78
-rw-r--r--intern/cycles/app/cycles_server.cpp19
-rw-r--r--intern/cycles/app/cycles_standalone.cpp32
-rw-r--r--intern/cycles/app/cycles_xml.cpp21
-rw-r--r--intern/cycles/app/cycles_xml.h2
-rw-r--r--intern/cycles/app/io_export_cycles_xml.py2
-rw-r--r--intern/cycles/blender/CCL_api.h2
-rw-r--r--intern/cycles/blender/CMakeLists.txt2
-rw-r--r--intern/cycles/blender/addon/__init__.py15
-rw-r--r--intern/cycles/blender/addon/engine.py9
-rw-r--r--intern/cycles/blender/addon/osl.py2
-rw-r--r--intern/cycles/blender/addon/presets.py2
-rw-r--r--intern/cycles/blender/addon/properties.py52
-rw-r--r--intern/cycles/blender/addon/ui.py38
-rw-r--r--intern/cycles/blender/addon/version_update.py85
-rw-r--r--intern/cycles/blender/blender_camera.cpp90
-rw-r--r--intern/cycles/blender/blender_curves.cpp81
-rw-r--r--intern/cycles/blender/blender_logging.cpp40
-rw-r--r--intern/cycles/blender/blender_mesh.cpp282
-rw-r--r--intern/cycles/blender/blender_object.cpp28
-rw-r--r--intern/cycles/blender/blender_particles.cpp2
-rw-r--r--intern/cycles/blender/blender_python.cpp42
-rw-r--r--intern/cycles/blender/blender_session.cpp64
-rw-r--r--intern/cycles/blender/blender_session.h6
-rw-r--r--intern/cycles/blender/blender_shader.cpp6
-rw-r--r--intern/cycles/blender/blender_sync.cpp62
-rw-r--r--intern/cycles/blender/blender_sync.h9
-rw-r--r--intern/cycles/blender/blender_util.h6
-rw-r--r--intern/cycles/bvh/bvh.cpp287
-rw-r--r--intern/cycles/bvh/bvh.h12
-rw-r--r--intern/cycles/bvh/bvh_build.cpp178
-rw-r--r--intern/cycles/bvh/bvh_build.h10
-rw-r--r--intern/cycles/bvh/bvh_node.cpp14
-rw-r--r--intern/cycles/bvh/bvh_node.h3
-rw-r--r--intern/cycles/bvh/bvh_params.h16
-rw-r--r--intern/cycles/cmake/external_libs.cmake107
-rw-r--r--intern/cycles/device/CMakeLists.txt2
-rw-r--r--intern/cycles/device/device.cpp30
-rw-r--r--intern/cycles/device/device.h3
-rw-r--r--intern/cycles/device/device_cpu.cpp369
-rw-r--r--intern/cycles/device/device_cuda.cpp186
-rw-r--r--intern/cycles/device/device_intern.h6
-rw-r--r--intern/cycles/device/device_memory.h2
-rw-r--r--intern/cycles/device/device_multi.cpp2
-rw-r--r--intern/cycles/device/device_network.cpp2
-rw-r--r--intern/cycles/device/device_network.h2
-rw-r--r--intern/cycles/device/device_opencl.cpp13
-rw-r--r--intern/cycles/device/device_task.cpp2
-rw-r--r--intern/cycles/device/device_task.h2
-rw-r--r--intern/cycles/kernel/CMakeLists.txt23
-rw-r--r--intern/cycles/kernel/closure/bsdf.h47
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h39
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h4
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse.h13
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse_ramp.h6
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair.h120
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h36
-rw-r--r--intern/cycles/kernel/closure/bsdf_oren_nayar.h16
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h16
-rw-r--r--intern/cycles/kernel/closure/bsdf_reflection.h9
-rw-r--r--intern/cycles/kernel/closure/bsdf_refraction.h16
-rw-r--r--intern/cycles/kernel/closure/bsdf_toon.h8
-rw-r--r--intern/cycles/kernel/closure/bsdf_transparent.h4
-rw-r--r--intern/cycles/kernel/closure/bssrdf.h2
-rw-r--r--intern/cycles/kernel/closure/volume.h20
-rw-r--r--intern/cycles/kernel/geom/geom.h3
-rw-r--r--intern/cycles/kernel/geom/geom_attribute.h5
-rw-r--r--intern/cycles/kernel/geom/geom_bvh.h16
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_shadow.h98
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_subsurface.h132
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_traversal.h195
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_volume.h148
-rw-r--r--intern/cycles/kernel/geom/geom_curve.h6
-rw-r--r--intern/cycles/kernel/geom/geom_motion_curve.h11
-rw-r--r--intern/cycles/kernel/geom/geom_motion_triangle.h3
-rw-r--r--intern/cycles/kernel/geom/geom_object.h59
-rw-r--r--intern/cycles/kernel/geom/geom_primitive.h12
-rw-r--r--intern/cycles/kernel/geom/geom_qbvh.h147
-rw-r--r--intern/cycles/kernel/geom/geom_qbvh_shadow.h403
-rw-r--r--intern/cycles/kernel/geom/geom_qbvh_subsurface.h326
-rw-r--r--intern/cycles/kernel/geom/geom_qbvh_traversal.h418
-rw-r--r--intern/cycles/kernel/geom/geom_qbvh_volume.h355
-rw-r--r--intern/cycles/kernel/geom/geom_triangle.h205
-rw-r--r--intern/cycles/kernel/geom/geom_triangle_intersect.h423
-rw-r--r--intern/cycles/kernel/geom/geom_volume.h2
-rw-r--r--intern/cycles/kernel/kernel.cl2
-rw-r--r--intern/cycles/kernel/kernel.cpp4
-rw-r--r--intern/cycles/kernel/kernel.cu2
-rw-r--r--intern/cycles/kernel/kernel.h2
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h2
-rw-r--r--intern/cycles/kernel/kernel_avx.cpp4
-rw-r--r--intern/cycles/kernel/kernel_avx2.cpp4
-rw-r--r--intern/cycles/kernel/kernel_bake.h24
-rw-r--r--intern/cycles/kernel/kernel_camera.h39
-rw-r--r--intern/cycles/kernel/kernel_compat_cpu.h128
-rw-r--r--intern/cycles/kernel/kernel_compat_cuda.h2
-rw-r--r--intern/cycles/kernel/kernel_compat_opencl.h2
-rw-r--r--intern/cycles/kernel/kernel_debug.h2
-rw-r--r--intern/cycles/kernel/kernel_differential.h2
-rw-r--r--intern/cycles/kernel/kernel_emission.h6
-rw-r--r--intern/cycles/kernel/kernel_film.h2
-rw-r--r--intern/cycles/kernel/kernel_globals.h2
-rw-r--r--intern/cycles/kernel/kernel_jitter.h10
-rw-r--r--intern/cycles/kernel/kernel_light.h184
-rw-r--r--intern/cycles/kernel/kernel_math.h3
-rw-r--r--intern/cycles/kernel/kernel_passes.h2
-rw-r--r--intern/cycles/kernel/kernel_path.h26
-rw-r--r--intern/cycles/kernel/kernel_path_state.h2
-rw-r--r--intern/cycles/kernel/kernel_path_surface.h16
-rw-r--r--intern/cycles/kernel/kernel_path_volume.h25
-rw-r--r--intern/cycles/kernel/kernel_projection.h26
-rw-r--r--intern/cycles/kernel/kernel_random.h2
-rw-r--r--intern/cycles/kernel/kernel_shader.h10
-rw-r--r--intern/cycles/kernel/kernel_shadow.h2
-rw-r--r--intern/cycles/kernel/kernel_sse2.cpp4
-rw-r--r--intern/cycles/kernel/kernel_sse3.cpp4
-rw-r--r--intern/cycles/kernel/kernel_sse41.cpp4
-rw-r--r--intern/cycles/kernel/kernel_subsurface.h2
-rw-r--r--intern/cycles/kernel/kernel_textures.h2
-rw-r--r--intern/cycles/kernel/kernel_types.h93
-rw-r--r--intern/cycles/kernel/kernel_volume.h98
-rw-r--r--intern/cycles/kernel/osl/SConscript12
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp16
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h2
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp63
-rw-r--r--intern/cycles/kernel/osl/osl_services.h90
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp2
-rw-r--r--intern/cycles/kernel/osl/osl_shader.h2
-rw-r--r--intern/cycles/kernel/shaders/node_absorption_volume.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_add_closure.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_ambient_occlusion.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_attribute.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_background.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_blackbody.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_brick_texture.osl7
-rw-r--r--intern/cycles/kernel/shaders/node_brightness.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_bump.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_camera.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_checker_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_color.h2
-rw-r--r--intern/cycles/kernel/shaders/node_combine_hsv.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_combine_rgb.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_combine_xyz.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_color.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_float.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_int.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_normal.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_point.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_string.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_vector.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_diffuse_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_emission.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_environment_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_fresnel.h2
-rw-r--r--intern/cycles/kernel/shaders/node_fresnel.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_gamma.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_geometry.osl13
-rw-r--r--intern/cycles/kernel/shaders/node_glass_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_glossy_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_gradient_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_hair_info.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_holdout.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_hsv.osl7
-rw-r--r--intern/cycles/kernel/shaders/node_image_texture.osl53
-rw-r--r--intern/cycles/kernel/shaders/node_invert.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_layer_weight.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_light_falloff.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_light_path.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_magic_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_mapping.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_math.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_mix.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_mix_closure.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_musgrave_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_noise_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_normal.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_normal_map.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_object_info.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_output_displacement.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_output_surface.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_output_volume.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_particle_info.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_refraction_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_rgb_curves.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_rgb_ramp.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_scatter_volume.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_separate_hsv.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_separate_rgb.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_separate_xyz.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_set_normal.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_sky_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_subsurface_scattering.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_tangent.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_texture.h2
-rw-r--r--intern/cycles/kernel/shaders/node_texture_coordinate.osl11
-rw-r--r--intern/cycles/kernel/shaders/node_toon_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_translucent_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_transparent_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_uv_map.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_value.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_vector_curves.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_vector_math.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_vector_transform.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_velvet_bsdf.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_voronoi_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_wave_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_wavelength.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_wireframe.osl18
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h41
-rw-r--r--intern/cycles/kernel/svm/svm.h11
-rw-r--r--intern/cycles/kernel/svm/svm_attribute.h2
-rw-r--r--intern/cycles/kernel/svm/svm_brick.h7
-rw-r--r--intern/cycles/kernel/svm/svm_brightness.h2
-rw-r--r--intern/cycles/kernel/svm/svm_camera.h2
-rw-r--r--intern/cycles/kernel/svm/svm_checker.h2
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h7
-rw-r--r--intern/cycles/kernel/svm/svm_convert.h2
-rw-r--r--intern/cycles/kernel/svm/svm_displace.h2
-rw-r--r--intern/cycles/kernel/svm/svm_fresnel.h2
-rw-r--r--intern/cycles/kernel/svm/svm_gamma.h2
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h2
-rw-r--r--intern/cycles/kernel/svm/svm_gradient.h2
-rw-r--r--intern/cycles/kernel/svm/svm_hsv.h7
-rw-r--r--intern/cycles/kernel/svm/svm_image.h23
-rw-r--r--intern/cycles/kernel/svm/svm_invert.h2
-rw-r--r--intern/cycles/kernel/svm/svm_light_path.h2
-rw-r--r--intern/cycles/kernel/svm/svm_magic.h2
-rw-r--r--intern/cycles/kernel/svm/svm_mapping.h2
-rw-r--r--intern/cycles/kernel/svm/svm_math.h90
-rw-r--r--intern/cycles/kernel/svm/svm_math_util.h108
-rw-r--r--intern/cycles/kernel/svm/svm_mix.h2
-rw-r--r--intern/cycles/kernel/svm/svm_musgrave.h2
-rw-r--r--intern/cycles/kernel/svm/svm_noisetex.h2
-rw-r--r--intern/cycles/kernel/svm/svm_normal.h2
-rw-r--r--intern/cycles/kernel/svm/svm_ramp.h2
-rw-r--r--intern/cycles/kernel/svm/svm_sepcomb_hsv.h2
-rw-r--r--intern/cycles/kernel/svm/svm_sepcomb_vector.h2
-rw-r--r--intern/cycles/kernel/svm/svm_sky.h2
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h78
-rw-r--r--intern/cycles/kernel/svm/svm_texture.h2
-rw-r--r--intern/cycles/kernel/svm/svm_types.h15
-rw-r--r--intern/cycles/kernel/svm/svm_value.h2
-rw-r--r--intern/cycles/kernel/svm/svm_vector_transform.h2
-rw-r--r--intern/cycles/kernel/svm/svm_voronoi.h2
-rw-r--r--intern/cycles/kernel/svm/svm_wave.h2
-rw-r--r--intern/cycles/kernel/svm/svm_wireframe.h55
-rw-r--r--intern/cycles/render/CMakeLists.txt2
-rw-r--r--intern/cycles/render/attribute.cpp10
-rw-r--r--intern/cycles/render/attribute.h2
-rw-r--r--intern/cycles/render/background.cpp29
-rw-r--r--intern/cycles/render/background.h2
-rw-r--r--intern/cycles/render/bake.cpp2
-rw-r--r--intern/cycles/render/bake.h2
-rw-r--r--intern/cycles/render/blackbody.cpp2
-rw-r--r--intern/cycles/render/blackbody.h4
-rw-r--r--intern/cycles/render/buffers.cpp2
-rw-r--r--intern/cycles/render/buffers.h2
-rw-r--r--intern/cycles/render/camera.cpp58
-rw-r--r--intern/cycles/render/camera.h9
-rw-r--r--intern/cycles/render/curves.cpp2
-rw-r--r--intern/cycles/render/curves.h2
-rw-r--r--intern/cycles/render/film.cpp2
-rw-r--r--intern/cycles/render/film.h2
-rw-r--r--intern/cycles/render/graph.cpp90
-rw-r--r--intern/cycles/render/graph.h7
-rw-r--r--intern/cycles/render/image.cpp2
-rw-r--r--intern/cycles/render/image.h2
-rw-r--r--intern/cycles/render/integrator.cpp8
-rw-r--r--intern/cycles/render/integrator.h3
-rw-r--r--intern/cycles/render/light.cpp112
-rw-r--r--intern/cycles/render/light.h3
-rw-r--r--intern/cycles/render/mesh.cpp186
-rw-r--r--intern/cycles/render/mesh.h6
-rw-r--r--intern/cycles/render/mesh_displace.cpp2
-rw-r--r--intern/cycles/render/nodes.cpp126
-rw-r--r--intern/cycles/render/nodes.h7
-rw-r--r--intern/cycles/render/object.cpp12
-rw-r--r--intern/cycles/render/object.h3
-rw-r--r--intern/cycles/render/osl.cpp38
-rw-r--r--intern/cycles/render/osl.h2
-rw-r--r--intern/cycles/render/particles.cpp2
-rw-r--r--intern/cycles/render/particles.h2
-rw-r--r--intern/cycles/render/scene.cpp72
-rw-r--r--intern/cycles/render/scene.h7
-rw-r--r--intern/cycles/render/session.cpp24
-rw-r--r--intern/cycles/render/session.h5
-rw-r--r--intern/cycles/render/shader.cpp26
-rw-r--r--intern/cycles/render/shader.h15
-rw-r--r--intern/cycles/render/sobol.h2
-rw-r--r--intern/cycles/render/svm.cpp7
-rw-r--r--intern/cycles/render/svm.h2
-rw-r--r--intern/cycles/render/tables.cpp2
-rw-r--r--intern/cycles/render/tables.h2
-rw-r--r--intern/cycles/render/tile.cpp2
-rw-r--r--intern/cycles/render/tile.h2
-rw-r--r--intern/cycles/subd/subd_dice.cpp6
-rw-r--r--intern/cycles/subd/subd_dice.h2
-rw-r--r--intern/cycles/subd/subd_patch.cpp2
-rw-r--r--intern/cycles/subd/subd_patch.h2
-rw-r--r--intern/cycles/subd/subd_split.cpp2
-rw-r--r--intern/cycles/subd/subd_split.h2
-rw-r--r--intern/cycles/util/CMakeLists.txt21
-rw-r--r--intern/cycles/util/util_algorithm.h2
-rw-r--r--intern/cycles/util/util_aligned_malloc.cpp83
-rw-r--r--intern/cycles/util/util_aligned_malloc.h32
-rw-r--r--intern/cycles/util/util_args.h2
-rw-r--r--intern/cycles/util/util_atomic.h33
-rw-r--r--intern/cycles/util/util_boundbox.h2
-rw-r--r--intern/cycles/util/util_cache.cpp8
-rw-r--r--intern/cycles/util/util_cache.h2
-rw-r--r--intern/cycles/util/util_color.h2
-rw-r--r--intern/cycles/util/util_debug.h2
-rw-r--r--intern/cycles/util/util_dynlib.cpp94
-rw-r--r--intern/cycles/util/util_foreach.h2
-rw-r--r--intern/cycles/util/util_function.h2
-rw-r--r--intern/cycles/util/util_guarded_allocator.cpp49
-rw-r--r--intern/cycles/util/util_guarded_allocator.h85
-rw-r--r--intern/cycles/util/util_half.h2
-rw-r--r--intern/cycles/util/util_hash.h2
-rw-r--r--intern/cycles/util/util_image.h2
-rw-r--r--intern/cycles/util/util_list.h2
-rw-r--r--intern/cycles/util/util_logging.cpp50
-rw-r--r--intern/cycles/util/util_logging.h8
-rw-r--r--intern/cycles/util/util_map.h2
-rw-r--r--intern/cycles/util/util_math.h96
-rw-r--r--intern/cycles/util/util_math_fast.h611
-rw-r--r--intern/cycles/util/util_md5.cpp12
-rw-r--r--intern/cycles/util/util_opengl.h10
-rw-r--r--intern/cycles/util/util_optimization.h5
-rw-r--r--intern/cycles/util/util_param.h2
-rw-r--r--intern/cycles/util/util_path.cpp39
-rw-r--r--intern/cycles/util/util_path.h2
-rw-r--r--intern/cycles/util/util_progress.h55
-rw-r--r--intern/cycles/util/util_set.h2
-rw-r--r--intern/cycles/util/util_simd.cpp2
-rw-r--r--intern/cycles/util/util_simd.h2
-rw-r--r--intern/cycles/util/util_sseb.h29
-rw-r--r--intern/cycles/util/util_ssef.h56
-rw-r--r--intern/cycles/util/util_ssei.h22
-rw-r--r--intern/cycles/util/util_stats.h11
-rw-r--r--intern/cycles/util/util_string.cpp2
-rw-r--r--intern/cycles/util/util_string.h2
-rw-r--r--intern/cycles/util/util_system.cpp42
-rw-r--r--intern/cycles/util/util_system.h2
-rw-r--r--intern/cycles/util/util_task.cpp2
-rw-r--r--intern/cycles/util/util_task.h2
-rw-r--r--intern/cycles/util/util_thread.h2
-rw-r--r--intern/cycles/util/util_time.cpp2
-rw-r--r--intern/cycles/util/util_time.h2
-rw-r--r--intern/cycles/util/util_transform.cpp2
-rw-r--r--intern/cycles/util/util_transform.h7
-rw-r--r--intern/cycles/util/util_types.h45
-rw-r--r--intern/cycles/util/util_vector.h93
-rw-r--r--intern/cycles/util/util_view.cpp2
-rw-r--r--intern/cycles/util/util_view.h2
-rw-r--r--intern/cycles/util/util_xml.h6
-rw-r--r--intern/ghost/CMakeLists.txt16
-rw-r--r--intern/ghost/GHOST_C-api.h27
-rw-r--r--intern/ghost/GHOST_ISystem.h3
-rw-r--r--intern/ghost/GHOST_IWindow.h23
-rw-r--r--intern/ghost/GHOST_Types.h31
-rw-r--r--intern/ghost/SConscript8
-rw-r--r--intern/ghost/intern/GHOST_Buttons.h8
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp24
-rw-r--r--intern/ghost/intern/GHOST_CallbackEventConsumer.h4
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.h18
-rw-r--r--intern/ghost/intern/GHOST_ContextCGL.mm10
-rw-r--r--intern/ghost/intern/GHOST_ContextEGL.h12
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.cpp120
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.h24
-rw-r--r--intern/ghost/intern/GHOST_ContextNone.h14
-rw-r--r--intern/ghost/intern/GHOST_ContextSDL.h20
-rw-r--r--intern/ghost/intern/GHOST_ContextWGL.cpp75
-rw-r--r--intern/ghost/intern/GHOST_ContextWGL.h25
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCocoa.h10
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.h10
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.h2
-rw-r--r--intern/ghost/intern/GHOST_Event.h8
-rw-r--r--intern/ghost/intern/GHOST_EventManager.h28
-rw-r--r--intern/ghost/intern/GHOST_EventPrinter.h2
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.cpp520
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.h405
-rw-r--r--intern/ghost/intern/GHOST_ModifierKeys.h10
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp61
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.h4
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerX11.cpp10
-rw-r--r--intern/ghost/intern/GHOST_System.cpp11
-rw-r--r--intern/ghost/intern/GHOST_System.h40
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h31
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm67
-rw-r--r--intern/ghost/intern/GHOST_SystemNULL.h6
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsCocoa.h6
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsWin32.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsX11.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.cpp7
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.h3
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp148
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h88
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp38
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h11
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.h16
-rw-r--r--intern/ghost/intern/GHOST_TimerTask.h24
-rw-r--r--intern/ghost/intern/GHOST_Window.h84
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.h54
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm38
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.h24
-rw-r--r--intern/ghost/intern/GHOST_WindowNULL.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp25
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h68
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp345
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h5
-rw-r--r--intern/glew-mx/CMakeLists.txt3
-rw-r--r--intern/glew-mx/SConscript8
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h18
-rw-r--r--intern/guardedalloc/intern/mallocn.c1
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c3
-rw-r--r--intern/guardedalloc/intern/mallocn_lockfree_impl.c10
-rw-r--r--intern/locale/CMakeLists.txt4
-rw-r--r--intern/memutil/MEM_CacheLimiter.h36
-rw-r--r--intern/memutil/MEM_RefCounted.h4
-rw-r--r--intern/memutil/MEM_RefCountedC-Api.h2
-rw-r--r--intern/opennl/superlu/heap_relax_snode.c2
-rw-r--r--intern/opennl/superlu/relax_snode.c2
-rw-r--r--intern/opennl/superlu/smemory.c6
-rw-r--r--intern/smoke/intern/FLUID_3D.cpp42
-rw-r--r--intern/smoke/intern/FLUID_3D.h3
-rw-r--r--intern/smoke/intern/smoke_API.cpp16
-rw-r--r--intern/smoke/intern/spectrum.cpp2
-rw-r--r--release/datafiles/blender_icons.svg12120
-rw-r--r--release/datafiles/blender_icons16/icon16_border_lasso.datbin1048 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_camera_stereo.datbin1048 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_disclosure_tri_down.datbin1048 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_file_hidden.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_image_rgb_alpha.datbin1048 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_mod_data_transfer.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons16/icon16_mod_normaledit.datbin0 -> 1048 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_border_lasso.datbin4120 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_camera_stereo.datbin4120 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_disclosure_tri_down.datbin4120 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_file_hidden.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_image_rgb_alpha.datbin4120 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_mod_data_transfer.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/blender_icons32/icon32_mod_normaledit.datbin0 -> 4120 bytes
-rw-r--r--release/datafiles/colormanagement/config.ocio2
-rwxr-xr-xrelease/datafiles/ctodata.py2
-rwxr-xr-xrelease/datafiles/datatoc.py2
m---------release/datafiles/locale0
-rw-r--r--release/datafiles/prvicons.pngbin15991 -> 15781 bytes
-rw-r--r--release/datafiles/splash.pngbin187919 -> 166788 bytes
-rw-r--r--release/datafiles/splash_2x.pngbin582704 -> 625100 bytes
-rw-r--r--release/datafiles/startup.blendbin443048 -> 432264 bytes
m---------release/scripts/addons0
m---------release/scripts/addons_contrib0
-rw-r--r--release/scripts/freestyle/modules/freestyle/chainingiterators.py8
-rw-r--r--release/scripts/freestyle/modules/freestyle/shaders.py18
-rw-r--r--release/scripts/freestyle/modules/freestyle/utils.py8
-rw-r--r--release/scripts/freestyle/modules/parameter_editor.py52
-rw-r--r--release/scripts/freestyle/styles/anisotropic_diffusion.py4
-rw-r--r--release/scripts/freestyle/styles/apriori_density.py2
-rw-r--r--release/scripts/freestyle/styles/backbone_stretcher.py2
-rw-r--r--release/scripts/freestyle/styles/blueprint_circles.py2
-rw-r--r--release/scripts/freestyle/styles/blueprint_ellipses.py2
-rw-r--r--release/scripts/freestyle/styles/blueprint_squares.py2
-rw-r--r--release/scripts/freestyle/styles/cartoon.py2
-rw-r--r--release/scripts/freestyle/styles/curvature2d.py2
-rw-r--r--release/scripts/freestyle/styles/external_contour_sketchy.py2
-rw-r--r--release/scripts/freestyle/styles/japanese_bigbrush.py4
-rw-r--r--release/scripts/freestyle/styles/multiple_parameterization.py2
-rw-r--r--release/scripts/freestyle/styles/near_lines.py2
-rw-r--r--release/scripts/freestyle/styles/qi0_not_external_contour.py2
-rw-r--r--release/scripts/freestyle/styles/sequentialsplit_sketchy.py2
-rw-r--r--release/scripts/freestyle/styles/sketchy_multiple_parameterization.py2
-rw-r--r--release/scripts/freestyle/styles/sketchy_topology_broken.py10
-rw-r--r--release/scripts/freestyle/styles/sketchy_topology_preserved.py2
-rw-r--r--release/scripts/freestyle/styles/split_at_highest_2d_curvatures.py2
-rw-r--r--release/scripts/freestyle/styles/split_at_tvertices.py2
-rw-r--r--release/scripts/freestyle/styles/stroke_texture.py49
-rw-r--r--release/scripts/freestyle/styles/uniformpruning_zsort.py3
-rw-r--r--release/scripts/modules/addon_utils.py46
-rw-r--r--release/scripts/modules/animsys_refactor.py2
-rw-r--r--release/scripts/modules/bl_i18n_utils/bl_extract_messages.py13
-rwxr-xr-xrelease/scripts/modules/bl_i18n_utils/merge_po.py11
-rw-r--r--release/scripts/modules/bl_i18n_utils/settings.py7
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils.py7
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils_spell_check.py8
-rw-r--r--release/scripts/modules/bpy/__init__.py4
-rw-r--r--release/scripts/modules/bpy/ops.py7
-rw-r--r--release/scripts/modules/bpy/path.py9
-rw-r--r--release/scripts/modules/bpy/utils.py25
-rw-r--r--release/scripts/modules/bpy_extras/anim_utils.py38
-rw-r--r--release/scripts/modules/bpy_extras/io_utils.py38
-rw-r--r--release/scripts/modules/bpy_extras/keyconfig_utils.py8
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py14
-rw-r--r--release/scripts/modules/bpy_extras/view3d_utils.py27
-rw-r--r--release/scripts/modules/bpy_restrict_state.py6
-rw-r--r--release/scripts/modules/bpyml.py2
-rw-r--r--release/scripts/modules/bpyml_ui.py2
-rw-r--r--release/scripts/modules/console_python.py13
-rw-r--r--release/scripts/modules/nodeitems_utils.py6
-rw-r--r--release/scripts/modules/rna_info.py6
-rw-r--r--release/scripts/modules/rna_keymap_ui.py2
-rw-r--r--release/scripts/modules/rna_prop_ui.py2
-rw-r--r--release/scripts/modules/rna_xml.py2
-rw-r--r--release/scripts/modules/sys_info.py23
-rw-r--r--release/scripts/presets/hair_dynamics/default.py17
-rw-r--r--release/scripts/presets/interface_theme/back_to_black.xml3
-rw-r--r--release/scripts/presets/interface_theme/blender_24x.xml25
-rw-r--r--release/scripts/presets/interface_theme/elsyiun.xml25
-rw-r--r--release/scripts/presets/interface_theme/flatty_light.xml1175
-rw-r--r--release/scripts/presets/interface_theme/graph.xml24
-rw-r--r--release/scripts/presets/interface_theme/hexagon.xml25
-rw-r--r--release/scripts/presets/interface_theme/rtheme.xml1176
-rw-r--r--release/scripts/presets/interface_theme/science_lab.xml24
-rw-r--r--release/scripts/presets/interface_theme/softimage.xml7
-rw-r--r--release/scripts/presets/interface_theme/ubuntu_ambiance.xml25
-rw-r--r--release/scripts/presets/keyconfig/maya.py8
-rw-r--r--release/scripts/presets/safe_areas/14_colon_9_in_16_colon_9.py7
-rw-r--r--release/scripts/presets/safe_areas/16_colon_9.py7
-rw-r--r--release/scripts/presets/safe_areas/4_colon_3_in_16_colon_9.py7
-rw-r--r--release/scripts/startup/bl_operators/__init__.py5
-rw-r--r--release/scripts/startup/bl_operators/add_mesh_torus.py7
-rw-r--r--release/scripts/startup/bl_operators/anim.py20
-rw-r--r--release/scripts/startup/bl_operators/clip.py151
-rw-r--r--release/scripts/startup/bl_operators/console.py7
-rw-r--r--release/scripts/startup/bl_operators/freestyle.py24
-rw-r--r--release/scripts/startup/bl_operators/node.py24
-rw-r--r--release/scripts/startup/bl_operators/object.py14
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py17
-rw-r--r--release/scripts/startup/bl_operators/presets.py52
-rw-r--r--release/scripts/startup/bl_operators/rigidbody.py10
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_lightmap.py2
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py34
-rw-r--r--release/scripts/startup/bl_operators/vertexpaint_dirt.py34
-rw-r--r--release/scripts/startup/bl_operators/wm.py16
-rw-r--r--release/scripts/startup/bl_ui/__init__.py14
-rw-r--r--release/scripts/startup/bl_ui/properties_animviz.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_constraint.py22
-rw-r--r--release/scripts/startup/bl_ui/properties_data_armature.py11
-rw-r--r--release/scripts/startup/bl_ui/properties_data_bone.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_camera.py79
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_empty.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lamp.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_lattice.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py12
-rw-r--r--release/scripts/startup/bl_ui/properties_data_metaball.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py183
-rw-r--r--release/scripts/startup/bl_ui/properties_data_speaker.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_freestyle.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_game.py60
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py456
-rw-r--r--release/scripts/startup/bl_ui/properties_mask_common.py18
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py42
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py207
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_cloth.py11
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_common.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py9
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_field.py9
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_fluid.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_smoke.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_softbody.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_render_layer.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_scene.py72
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py37
-rw-r--r--release/scripts/startup/bl_ui/properties_world.py3
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py92
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py23
-rw-r--r--release/scripts/startup/bl_ui/space_filebrowser.py136
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py27
-rw-r--r--release/scripts/startup/bl_ui/space_image.py91
-rw-r--r--release/scripts/startup/bl_ui/space_info.py21
-rw-r--r--release/scripts/startup/bl_ui/space_nla.py10
-rw-r--r--release/scripts/startup/bl_ui/space_node.py54
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py3
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py126
-rw-r--r--release/scripts/startup/bl_ui/space_time.py2
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py32
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py160
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py76
-rw-r--r--release/scripts/startup/nodeitems_builtins.py1
-rw-r--r--release/scripts/templates_py/custom_nodes.py3
-rw-r--r--release/scripts/templates_py/operator_mesh_add.py1
-rw-r--r--release/scripts/templates_py/operator_modal_view3d_raycast.py4
-rw-r--r--release/text/readme.html113
-rw-r--r--source/blender/CMakeLists.txt2
-rw-r--r--source/blender/SConscript1
-rw-r--r--source/blender/avi/intern/avi.c2
-rw-r--r--source/blender/blenfont/BLF_translation.h8
-rw-r--r--source/blender/blenfont/CMakeLists.txt6
-rw-r--r--source/blender/blenfont/intern/blf.c39
-rw-r--r--source/blender/blenfont/intern/blf_dir.c2
-rw-r--r--source/blender/blenfont/intern/blf_font.c4
-rw-r--r--source/blender/blenfont/intern/blf_font_win32_compat.c145
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c4
-rw-r--r--source/blender/blenfont/intern/blf_internal.h7
-rw-r--r--source/blender/blenfont/intern/blf_lang.c38
-rw-r--r--source/blender/blenfont/intern/blf_translation.c8
-rw-r--r--source/blender/blenfont/intern/blf_util.c1
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h14
-rw-r--r--source/blender/blenkernel/BKE_animsys.h20
-rw-r--r--source/blender/blenkernel/BKE_appdir.h80
-rw-r--r--source/blender/blenkernel/BKE_armature.h2
-rw-r--r--source/blender/blenkernel/BKE_blender.h8
-rw-r--r--source/blender/blenkernel/BKE_brush.h5
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h46
-rw-r--r--source/blender/blenkernel/BKE_camera.h7
-rw-r--r--source/blender/blenkernel/BKE_cdderivedmesh.h5
-rw-r--r--source/blender/blenkernel/BKE_cloth.h80
-rw-r--r--source/blender/blenkernel/BKE_collision.h4
-rw-r--r--source/blender/blenkernel/BKE_constraint.h6
-rw-r--r--source/blender/blenkernel/BKE_context.h11
-rw-r--r--source/blender/blenkernel/BKE_curve.h5
-rw-r--r--source/blender/blenkernel/BKE_customdata.h145
-rw-r--r--source/blender/blenkernel/BKE_customdata_file.h12
-rw-r--r--source/blender/blenkernel/BKE_data_transfer.h159
-rw-r--r--source/blender/blenkernel/BKE_deform.h17
-rw-r--r--source/blender/blenkernel/BKE_editmesh_bvh.h14
-rw-r--r--source/blender/blenkernel/BKE_effect.h85
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h5
-rw-r--r--source/blender/blenkernel/BKE_global.h5
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h9
-rw-r--r--source/blender/blenkernel/BKE_group.h1
-rw-r--r--source/blender/blenkernel/BKE_idprop.h16
-rw-r--r--source/blender/blenkernel/BKE_image.h30
-rw-r--r--source/blender/blenkernel/BKE_key.h39
-rw-r--r--source/blender/blenkernel/BKE_library.h4
-rw-r--r--source/blender/blenkernel/BKE_mesh.h59
-rw-r--r--source/blender/blenkernel/BKE_mesh_mapping.h63
-rw-r--r--source/blender/blenkernel/BKE_mesh_remap.h171
-rw-r--r--source/blender/blenkernel/BKE_modifier.h6
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h1
-rw-r--r--source/blender/blenkernel/BKE_nla.h5
-rw-r--r--source/blender/blenkernel/BKE_node.h72
-rw-r--r--source/blender/blenkernel/BKE_object.h6
-rw-r--r--source/blender/blenkernel/BKE_object_deform.h50
-rw-r--r--source/blender/blenkernel/BKE_paint.h15
-rw-r--r--source/blender/blenkernel/BKE_particle.h74
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h1
-rw-r--r--source/blender/blenkernel/BKE_scene.h5
-rw-r--r--source/blender/blenkernel/BKE_screen.h6
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h41
-rw-r--r--source/blender/blenkernel/BKE_sound.h4
-rw-r--r--source/blender/blenkernel/BKE_text.h2
-rw-r--r--source/blender/blenkernel/BKE_texture.h1
-rw-r--r--source/blender/blenkernel/BKE_tracking.h21
-rw-r--r--source/blender/blenkernel/CMakeLists.txt41
-rw-r--r--source/blender/blenkernel/SConscript6
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c63
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h22
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c175
-rw-r--r--source/blender/blenkernel/intern/action.c22
-rw-r--r--source/blender/blenkernel/intern/addon.c6
-rw-r--r--source/blender/blenkernel/intern/anim.c3
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c190
-rw-r--r--source/blender/blenkernel/intern/appdir.c808
-rw-r--r--source/blender/blenkernel/intern/armature.c89
-rw-r--r--source/blender/blenkernel/intern/autoexec.c5
-rw-r--r--source/blender/blenkernel/intern/blender.c94
-rw-r--r--source/blender/blenkernel/intern/boids.c4
-rw-r--r--source/blender/blenkernel/intern/bpath.c8
-rw-r--r--source/blender/blenkernel/intern/brush.c46
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c578
-rw-r--r--source/blender/blenkernel/intern/camera.c242
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c1140
-rw-r--r--source/blender/blenkernel/intern/cloth.c352
-rw-r--r--source/blender/blenkernel/intern/collision.c563
-rw-r--r--source/blender/blenkernel/intern/colortools.c1
-rw-r--r--source/blender/blenkernel/intern/constraint.c100
-rw-r--r--source/blender/blenkernel/intern/context.c40
-rw-r--r--source/blender/blenkernel/intern/curve.c56
-rw-r--r--source/blender/blenkernel/intern/customdata.c768
-rw-r--r--source/blender/blenkernel/intern/customdata_file.c14
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c1370
-rw-r--r--source/blender/blenkernel/intern/data_transfer_intern.h61
-rw-r--r--source/blender/blenkernel/intern/deform.c398
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c25
-rw-r--r--source/blender/blenkernel/intern/displist.c22
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c51
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c80
-rw-r--r--source/blender/blenkernel/intern/editmesh_bvh.c96
-rw-r--r--source/blender/blenkernel/intern/effect.c170
-rw-r--r--source/blender/blenkernel/intern/fcurve.c73
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c14
-rw-r--r--source/blender/blenkernel/intern/font.c2
-rw-r--r--source/blender/blenkernel/intern/freestyle.c2
-rw-r--r--source/blender/blenkernel/intern/gpencil.c60
-rw-r--r--source/blender/blenkernel/intern/group.c41
-rw-r--r--source/blender/blenkernel/intern/idprop.c173
-rw-r--r--source/blender/blenkernel/intern/image.c155
-rw-r--r--source/blender/blenkernel/intern/implicit.c1964
-rw-r--r--source/blender/blenkernel/intern/ipo.c28
-rw-r--r--source/blender/blenkernel/intern/key.c597
-rw-r--r--source/blender/blenkernel/intern/lamp.c5
-rw-r--r--source/blender/blenkernel/intern/lattice.c22
-rw-r--r--source/blender/blenkernel/intern/library.c15
-rw-r--r--source/blender/blenkernel/intern/linestyle.c15
-rw-r--r--source/blender/blenkernel/intern/mask.c18
-rw-r--r--source/blender/blenkernel/intern/mask_evaluate.c2
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c6
-rw-r--r--source/blender/blenkernel/intern/material.c76
-rw-r--r--source/blender/blenkernel/intern/mball.c24
-rw-r--r--source/blender/blenkernel/intern/mesh.c21
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c1212
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c380
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c2010
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c107
-rw-r--r--source/blender/blenkernel/intern/modifier.c15
-rw-r--r--source/blender/blenkernel/intern/movieclip.c41
-rw-r--r--source/blender/blenkernel/intern/multires.c5
-rw-r--r--source/blender/blenkernel/intern/nla.c168
-rw-r--r--source/blender/blenkernel/intern/node.c45
-rw-r--r--source/blender/blenkernel/intern/object.c291
-rw-r--r--source/blender/blenkernel/intern/object_deform.c548
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c8
-rw-r--r--source/blender/blenkernel/intern/ocean.c2
-rw-r--r--source/blender/blenkernel/intern/packedFile.c64
-rw-r--r--source/blender/blenkernel/intern/paint.c104
-rw-r--r--source/blender/blenkernel/intern/particle.c1260
-rw-r--r--source/blender/blenkernel/intern/particle_child.c732
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c1417
-rw-r--r--source/blender/blenkernel/intern/particle_system.c1407
-rw-r--r--source/blender/blenkernel/intern/pbvh.c19
-rw-r--r--source/blender/blenkernel/intern/pointcache.c61
-rw-r--r--source/blender/blenkernel/intern/property.c54
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c19
-rw-r--r--source/blender/blenkernel/intern/sca.c39
-rw-r--r--source/blender/blenkernel/intern/scene.c95
-rw-r--r--source/blender/blenkernel/intern/screen.c68
-rw-r--r--source/blender/blenkernel/intern/seqcache.c20
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c8
-rw-r--r--source/blender/blenkernel/intern/sequencer.c252
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c5
-rw-r--r--source/blender/blenkernel/intern/sketch.c10
-rw-r--r--source/blender/blenkernel/intern/smoke.c20
-rw-r--r--source/blender/blenkernel/intern/softbody.c14
-rw-r--r--source/blender/blenkernel/intern/sound.c65
-rw-r--r--source/blender/blenkernel/intern/speaker.c4
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c230
-rw-r--r--source/blender/blenkernel/intern/text.c191
-rw-r--r--source/blender/blenkernel/intern/texture.c61
-rw-r--r--source/blender/blenkernel/intern/tracking.c53
-rw-r--r--source/blender/blenkernel/intern/tracking_auto.c568
-rw-r--r--source/blender/blenkernel/intern/tracking_detect.c1
-rw-r--r--source/blender/blenkernel/intern/tracking_region_tracker.c481
-rw-r--r--source/blender/blenkernel/intern/tracking_solver.c9
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c449
-rw-r--r--source/blender/blenkernel/intern/world.c15
-rw-r--r--source/blender/blenkernel/intern/writeavi.c6
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c32
-rw-r--r--source/blender/blenkernel/intern/writeframeserver.c6
-rw-r--r--source/blender/blenkernel/tracking_private.h28
-rw-r--r--source/blender/blenlib/BLI_array.h71
-rw-r--r--source/blender/blenlib/BLI_array_utils.h41
-rw-r--r--source/blender/blenlib/BLI_astar.h98
-rw-r--r--source/blender/blenlib/BLI_bitmap.h15
-rw-r--r--source/blender/blenlib/BLI_buffer.h2
-rw-r--r--source/blender/blenlib/BLI_callbacks.h1
-rw-r--r--source/blender/blenlib/BLI_compiler_compat.h12
-rw-r--r--source/blender/blenlib/BLI_compiler_typecheck.h23
-rw-r--r--source/blender/blenlib/BLI_dial.h4
-rw-r--r--source/blender/blenlib/BLI_edgehash.h4
-rw-r--r--source/blender/blenlib/BLI_fileops.h61
-rw-r--r--source/blender/blenlib/BLI_ghash.h8
-rw-r--r--source/blender/blenlib/BLI_hash_md5.h (renamed from source/blender/blenlib/BLI_md5.h)18
-rw-r--r--source/blender/blenlib/BLI_hash_mm2a.h45
-rw-r--r--source/blender/blenlib/BLI_heap.h1
-rw-r--r--source/blender/blenlib/BLI_kdopbvh.h4
-rw-r--r--source/blender/blenlib/BLI_linklist.h2
-rw-r--r--source/blender/blenlib/BLI_linklist_stack.h32
-rw-r--r--source/blender/blenlib/BLI_listbase.h7
-rw-r--r--source/blender/blenlib/BLI_math_base.h35
-rw-r--r--source/blender/blenlib/BLI_math_color.h7
-rw-r--r--source/blender/blenlib/BLI_math_geom.h20
-rw-r--r--source/blender/blenlib/BLI_math_matrix.h6
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h5
-rw-r--r--source/blender/blenlib/BLI_math_vector.h5
-rw-r--r--source/blender/blenlib/BLI_path_util.h60
-rw-r--r--source/blender/blenlib/BLI_polyfill2d.h3
-rw-r--r--source/blender/blenlib/BLI_polyfill2d_beautify.h42
-rw-r--r--source/blender/blenlib/BLI_rand.h3
-rw-r--r--source/blender/blenlib/BLI_smallhash.h15
-rw-r--r--source/blender/blenlib/BLI_string.h7
-rw-r--r--source/blender/blenlib/BLI_string_utf8.h1
-rw-r--r--source/blender/blenlib/BLI_system.h5
-rw-r--r--source/blender/blenlib/BLI_task.h8
-rw-r--r--source/blender/blenlib/BLI_utildefines.h186
-rw-r--r--source/blender/blenlib/CMakeLists.txt21
-rw-r--r--source/blender/blenlib/PIL_time.h8
-rw-r--r--source/blender/blenlib/SConscript6
-rw-r--r--source/blender/blenlib/intern/BLI_args.c2
-rw-r--r--source/blender/blenlib/intern/BLI_array.c57
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c5
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c31
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c82
-rw-r--r--source/blender/blenlib/intern/BLI_linklist.c79
-rw-r--r--source/blender/blenlib/intern/array_utils.c85
-rw-r--r--source/blender/blenlib/intern/astar.c294
-rw-r--r--source/blender/blenlib/intern/boxpack2d.c45
-rw-r--r--source/blender/blenlib/intern/convexhull2d.c4
-rw-r--r--source/blender/blenlib/intern/dynlib.c2
-rw-r--r--source/blender/blenlib/intern/easing.c2
-rw-r--r--source/blender/blenlib/intern/edgehash.c99
-rw-r--r--source/blender/blenlib/intern/fileops.c16
-rw-r--r--source/blender/blenlib/intern/graph.c8
-rw-r--r--source/blender/blenlib/intern/hash_md5.c (renamed from source/blender/blenlib/intern/md5.c)15
-rw-r--r--source/blender/blenlib/intern/hash_mm2a.c107
-rw-r--r--source/blender/blenlib/intern/lasso.c1
-rw-r--r--source/blender/blenlib/intern/listbase.c43
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c31
-rw-r--r--source/blender/blenlib/intern/math_color.c21
-rw-r--r--source/blender/blenlib/intern/math_color_inline.c20
-rw-r--r--source/blender/blenlib/intern/math_geom.c522
-rw-r--r--source/blender/blenlib/intern/math_geom_inline.c6
-rw-r--r--source/blender/blenlib/intern/math_interp.c16
-rw-r--r--source/blender/blenlib/intern/math_matrix.c122
-rw-r--r--source/blender/blenlib/intern/math_rotation.c36
-rw-r--r--source/blender/blenlib/intern/math_vector.c23
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c12
-rw-r--r--source/blender/blenlib/intern/noise.c4
-rw-r--r--source/blender/blenlib/intern/path_util.c822
-rw-r--r--source/blender/blenlib/intern/polyfill2d.c4
-rw-r--r--source/blender/blenlib/intern/polyfill2d_beautify.c493
-rw-r--r--source/blender/blenlib/intern/rand.c26
-rw-r--r--source/blender/blenlib/intern/scanfill.c30
-rw-r--r--source/blender/blenlib/intern/scanfill_utils.c14
-rw-r--r--source/blender/blenlib/intern/smallhash.c59
-rw-r--r--source/blender/blenlib/intern/storage.c78
-rw-r--r--source/blender/blenlib/intern/string.c121
-rw-r--r--source/blender/blenlib/intern/string_utf8.c38
-rw-r--r--source/blender/blenlib/intern/system.c80
-rw-r--r--source/blender/blenlib/intern/task.c119
-rw-r--r--source/blender/blenlib/intern/time.c18
-rw-r--r--source/blender/blenlib/intern/winstuff_dir.c10
-rw-r--r--source/blender/blenloader/BLO_readfile.h3
-rw-r--r--source/blender/blenloader/intern/readblenentry.c8
-rw-r--r--source/blender/blenloader/intern/readfile.c515
-rw-r--r--source/blender/blenloader/intern/readfile.h8
-rw-r--r--source/blender/blenloader/intern/runtime.c1
-rw-r--r--source/blender/blenloader/intern/undofile.c1
-rw-r--r--source/blender/blenloader/intern/versioning_250.c14
-rw-r--r--source/blender/blenloader/intern/versioning_260.c4
-rw-r--r--source/blender/blenloader/intern/versioning_270.c256
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c28
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c115
-rw-r--r--source/blender/blenloader/intern/writefile.c83
-rw-r--r--source/blender/bmesh/CMakeLists.txt3
-rw-r--r--source/blender/bmesh/bmesh.h1
-rw-r--r--source/blender/bmesh/bmesh_class.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_callback_generic.c60
-rw-r--r--source/blender/bmesh/intern/bmesh_callback_generic.h45
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c24
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c407
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.h37
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.h31
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c188
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c300
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h7
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c12
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c8
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c26
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c33
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h9
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c204
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h21
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c100
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h28
-rw-r--r--source/blender/bmesh/intern/bmesh_queries_inline.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c3
-rw-r--r--source/blender/bmesh/operators/bmo_bridge.c32
-rw-r--r--source/blender/bmesh/operators/bmo_connect_concave.c219
-rw-r--r--source/blender/bmesh/operators/bmo_connect_nonplanar.c21
-rw-r--r--source/blender/bmesh/operators/bmo_connect_pair.c240
-rw-r--r--source/blender/bmesh/operators/bmo_create.c2
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c2
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c2
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c6
-rw-r--r--source/blender/bmesh/operators/bmo_fill_grid.c7
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c4
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c12
-rw-r--r--source/blender/bmesh/operators/bmo_normals.c167
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c102
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c4
-rw-r--r--source/blender/bmesh/operators/bmo_similar.c13
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c18
-rw-r--r--source/blender/bmesh/operators/bmo_triangulate.c9
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c204
-rw-r--r--source/blender/bmesh/operators/bmo_wireframe.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_beautify.c123
-rw-r--r--source/blender/bmesh/tools/bmesh_beautify.h14
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c121
-rw-r--r--source/blender/bmesh/tools/bmesh_bisect_plane.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c13
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.c12
-rw-r--r--source/blender/bmesh/tools/bmesh_path.c6
-rw-r--r--source/blender/bmesh/tools/bmesh_path.h9
-rw-r--r--source/blender/bmesh/tools/bmesh_region_match.c8
-rw-r--r--source/blender/bmesh/tools/bmesh_triangulate.c74
-rw-r--r--source/blender/collada/AnimationExporter.cpp90
-rw-r--r--source/blender/collada/AnimationExporter.h1
-rw-r--r--source/blender/collada/AnimationImporter.cpp2
-rw-r--r--source/blender/collada/ArmatureExporter.cpp4
-rw-r--r--source/blender/collada/ArmatureImporter.cpp340
-rw-r--r--source/blender/collada/ArmatureImporter.h44
-rw-r--r--source/blender/collada/ControllerExporter.cpp4
-rw-r--r--source/blender/collada/DocumentImporter.cpp5
-rw-r--r--source/blender/collada/EffectExporter.cpp16
-rw-r--r--source/blender/collada/ErrorHandler.cpp26
-rw-r--r--source/blender/collada/GeometryExporter.cpp2
-rw-r--r--source/blender/collada/ImageExporter.cpp4
-rw-r--r--source/blender/collada/ImportSettings.cpp2
-rw-r--r--source/blender/collada/ImportSettings.h6
-rw-r--r--source/blender/collada/MeshImporter.cpp61
-rw-r--r--source/blender/collada/MeshImporter.h2
-rw-r--r--source/blender/collada/SkinInfo.cpp9
-rw-r--r--source/blender/collada/TransformWriter.cpp2
-rw-r--r--source/blender/collada/collada.cpp13
-rw-r--r--source/blender/collada/collada.h5
-rw-r--r--source/blender/collada/collada_internal.cpp135
-rw-r--r--source/blender/collada/collada_utils.cpp3
-rw-r--r--source/blender/compositor/CMakeLists.txt2
-rw-r--r--source/blender/compositor/COM_defines.h4
-rw-r--r--source/blender/compositor/intern/COM_ChannelInfo.h121
-rw-r--r--source/blender/compositor/intern/COM_CompositorContext.h2
-rw-r--r--source/blender/compositor/intern/COM_Debug.cpp3
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystem.cpp16
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.cpp92
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.h139
-rw-r--r--source/blender/compositor/intern/COM_MemoryProxy.cpp3
-rw-r--r--source/blender/compositor/intern/COM_MemoryProxy.h9
-rw-r--r--source/blender/compositor/intern/COM_NodeGraph.cpp2
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.cpp8
-rw-r--r--source/blender/compositor/intern/COM_OpenCLDevice.cpp40
-rw-r--r--source/blender/compositor/intern/COM_OpenCLDevice.h6
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cpp4
-rw-r--r--source/blender/compositor/nodes/COM_BokehBlurNode.cpp9
-rw-r--r--source/blender/compositor/nodes/COM_CompositorNode.cpp2
-rw-r--r--source/blender/compositor/nodes/COM_ImageNode.cpp66
-rw-r--r--source/blender/compositor/nodes/COM_MathNode.cpp38
-rw-r--r--source/blender/compositor/nodes/COM_MixNode.cpp4
-rw-r--r--source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp8
-rw-r--r--source/blender/compositor/nodes/COM_SocketProxyNode.cpp5
-rw-r--r--source/blender/compositor/nodes/COM_TextureNode.cpp2
-rw-r--r--source/blender/compositor/nodes/COM_TranslateNode.cpp4
-rw-r--r--source/blender/compositor/nodes/COM_ViewerNode.cpp2
-rw-r--r--source/blender/compositor/operations/COM_AntiAliasOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_BokehBlurOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_ConvertOperation.cpp23
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.cpp23
-rw-r--r--source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp25
-rw-r--r--source/blender/compositor/operations/COM_FlipOperation.cpp14
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp7
-rw-r--r--source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_GlareBaseOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp18
-rw-r--r--source/blender/compositor/operations/COM_GlareGhostOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_GlareStreaksOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_InpaintOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_KeyingBlurOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_KeyingClipOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_MapUVOperation.cpp10
-rw-r--r--source/blender/compositor/operations/COM_MovieClipOperation.cpp8
-rw-r--r--source/blender/compositor/operations/COM_NormalizeOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_OpenCLKernels.cl12
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.cpp10
-rw-r--r--source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp152
-rw-r--r--source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h49
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.cpp62
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.h9
-rw-r--r--source/blender/compositor/operations/COM_QualityStepHelper.cpp6
-rw-r--r--source/blender/compositor/operations/COM_ReadBufferOperation.cpp20
-rw-r--r--source/blender/compositor/operations/COM_ReadBufferOperation.h3
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.cpp84
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.h1
-rw-r--r--source/blender/compositor/operations/COM_SetVectorOperation.cpp1
-rw-r--r--source/blender/compositor/operations/COM_SunBeamsOperation.cpp96
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.cpp20
-rw-r--r--source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp33
-rw-r--r--source/blender/compositor/operations/COM_VectorBlurOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_VectorCurveOperation.cpp1
-rw-r--r--source/blender/compositor/operations/COM_WrapOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_WrapOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_WriteBufferOperation.cpp22
-rw-r--r--source/blender/compositor/operations/COM_WriteBufferOperation.h2
-rw-r--r--source/blender/datatoc/datatoc_icon.c3
-rwxr-xr-xsource/blender/datatoc/datatoc_icon.py11
-rwxr-xr-xsource/blender/datatoc/datatoc_icon_split.py2
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c196
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c256
-rw-r--r--source/blender/editors/animation/anim_deps.c2
-rw-r--r--source/blender/editors/animation/anim_draw.c9
-rw-r--r--source/blender/editors/animation/anim_filter.c128
-rw-r--r--source/blender/editors/animation/anim_markers.c98
-rw-r--r--source/blender/editors/animation/anim_ops.c69
-rw-r--r--source/blender/editors/animation/drivers.c29
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c84
-rw-r--r--source/blender/editors/animation/keyframes_draw.c35
-rw-r--r--source/blender/editors/animation/keyframes_edit.c50
-rw-r--r--source/blender/editors/animation/keyframes_general.c128
-rw-r--r--source/blender/editors/animation/keyframing.c84
-rw-r--r--source/blender/editors/animation/keyingsets.c69
-rw-r--r--source/blender/editors/armature/armature_add.c2
-rw-r--r--source/blender/editors/armature/armature_edit.c76
-rw-r--r--source/blender/editors/armature/armature_intern.h2
-rw-r--r--source/blender/editors/armature/armature_naming.c7
-rw-r--r--source/blender/editors/armature/armature_ops.c4
-rw-r--r--source/blender/editors/armature/armature_relations.c166
-rw-r--r--source/blender/editors/armature/armature_select.c17
-rw-r--r--source/blender/editors/armature/armature_skinning.c24
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c18
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c28
-rw-r--r--source/blender/editors/armature/pose_edit.c13
-rw-r--r--source/blender/editors/armature/pose_group.c14
-rw-r--r--source/blender/editors/armature/pose_lib.c16
-rw-r--r--source/blender/editors/armature/pose_select.c2
-rw-r--r--source/blender/editors/armature/pose_transform.c2
-rw-r--r--source/blender/editors/armature/pose_utils.c4
-rw-r--r--source/blender/editors/armature/reeb.c26
-rw-r--r--source/blender/editors/curve/curve_ops.c4
-rw-r--r--source/blender/editors/curve/editcurve.c643
-rw-r--r--source/blender/editors/curve/editcurve_add.c14
-rw-r--r--source/blender/editors/curve/editfont.c16
-rw-r--r--source/blender/editors/gpencil/CMakeLists.txt3
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c858
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c61
-rw-r--r--source/blender/editors/gpencil/gpencil_buttons.c378
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c1334
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h93
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c204
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c312
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c946
-rw-r--r--source/blender/editors/gpencil/gpencil_undo.c61
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c211
-rw-r--r--source/blender/editors/include/BIF_gl.h27
-rw-r--r--source/blender/editors/include/BIF_glutil.h8
-rw-r--r--source/blender/editors/include/ED_anim_api.h3
-rw-r--r--source/blender/editors/include/ED_curve.h2
-rw-r--r--source/blender/editors/include/ED_fileselect.h35
-rw-r--r--source/blender/editors/include/ED_gpencil.h35
-rw-r--r--source/blender/editors/include/ED_image.h5
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h9
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h13
-rw-r--r--source/blender/editors/include/ED_keyframing.h2
-rw-r--r--source/blender/editors/include/ED_markers.h5
-rw-r--r--source/blender/editors/include/ED_mesh.h15
-rw-r--r--source/blender/editors/include/ED_object.h14
-rw-r--r--source/blender/editors/include/ED_render.h7
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_sculpt.h3
-rw-r--r--source/blender/editors/include/ED_sequencer.h6
-rw-r--r--source/blender/editors/include/ED_text.h3
-rw-r--r--source/blender/editors/include/ED_transform.h3
-rw-r--r--source/blender/editors/include/ED_uvedit.h11
-rw-r--r--source/blender/editors/include/ED_view3d.h19
-rw-r--r--source/blender/editors/include/UI_icons.h16
-rw-r--r--source/blender/editors/include/UI_interface.h482
-rw-r--r--source/blender/editors/include/UI_interface_icons.h4
-rw-r--r--source/blender/editors/include/UI_resources.h21
-rw-r--r--source/blender/editors/include/UI_view2d.h5
-rw-r--r--source/blender/editors/interface/CMakeLists.txt6
-rw-r--r--source/blender/editors/interface/SConscript4
-rw-r--r--source/blender/editors/interface/interface.c772
-rw-r--r--source/blender/editors/interface/interface_anim.c51
-rw-r--r--source/blender/editors/interface/interface_draw.c130
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c513
-rw-r--r--source/blender/editors/interface/interface_handlers.c1384
-rw-r--r--source/blender/editors/interface/interface_icons.c46
-rw-r--r--source/blender/editors/interface/interface_intern.h159
-rw-r--r--source/blender/editors/interface/interface_layout.c323
-rw-r--r--source/blender/editors/interface/interface_ops.c39
-rw-r--r--source/blender/editors/interface/interface_panel.c60
-rw-r--r--source/blender/editors/interface/interface_regions.c665
-rw-r--r--source/blender/editors/interface/interface_style.c133
-rw-r--r--source/blender/editors/interface/interface_templates.c695
-rw-r--r--source/blender/editors/interface/interface_utils.c73
-rw-r--r--source/blender/editors/interface/interface_widgets.c456
-rw-r--r--source/blender/editors/interface/resources.c160
-rw-r--r--source/blender/editors/interface/view2d.c18
-rw-r--r--source/blender/editors/interface/view2d_ops.c57
-rw-r--r--source/blender/editors/io/io_collada.c63
-rw-r--r--source/blender/editors/io/io_ops.c13
-rw-r--r--source/blender/editors/mask/mask_ops.c4
-rw-r--r--source/blender/editors/mask/mask_relationships.c1
-rw-r--r--source/blender/editors/mesh/editface.c2
-rw-r--r--source/blender/editors/mesh/editmesh_add.c11
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c225
-rw-r--r--source/blender/editors/mesh/editmesh_intersect.c3
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c635
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c2
-rw-r--r--source/blender/editors/mesh/editmesh_path.c22
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c2
-rw-r--r--source/blender/editors/mesh/editmesh_rip_edge.c7
-rw-r--r--source/blender/editors/mesh/editmesh_select.c27
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c353
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c60
-rw-r--r--source/blender/editors/mesh/mesh_data.c121
-rw-r--r--source/blender/editors/mesh/mesh_intern.h4
-rw-r--r--source/blender/editors/mesh/mesh_ops.c6
-rw-r--r--source/blender/editors/mesh/meshtools.c6
-rw-r--r--source/blender/editors/metaball/mball_edit.c3
-rw-r--r--source/blender/editors/metaball/mball_ops.c4
-rw-r--r--source/blender/editors/object/CMakeLists.txt1
-rw-r--r--source/blender/editors/object/object_add.c194
-rw-r--r--source/blender/editors/object/object_bake.c5
-rw-r--r--source/blender/editors/object/object_bake_api.c26
-rw-r--r--source/blender/editors/object/object_constraint.c55
-rw-r--r--source/blender/editors/object/object_data_transfer.c687
-rw-r--r--source/blender/editors/object/object_edit.c71
-rw-r--r--source/blender/editors/object/object_group.c53
-rw-r--r--source/blender/editors/object/object_hook.c14
-rw-r--r--source/blender/editors/object/object_intern.h16
-rw-r--r--source/blender/editors/object/object_lattice.c2
-rw-r--r--source/blender/editors/object/object_lod.c8
-rw-r--r--source/blender/editors/object/object_modifier.c37
-rw-r--r--source/blender/editors/object/object_ops.c10
-rw-r--r--source/blender/editors/object/object_relations.c37
-rw-r--r--source/blender/editors/object/object_select.c6
-rw-r--r--source/blender/editors/object/object_shapekey.c14
-rw-r--r--source/blender/editors/object/object_transform.c3
-rw-r--r--source/blender/editors/object/object_vgroup.c1078
-rw-r--r--source/blender/editors/object/object_warp.c1
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c5
-rw-r--r--source/blender/editors/physics/particle_edit.c216
-rw-r--r--source/blender/editors/physics/particle_object.c495
-rw-r--r--source/blender/editors/physics/physics_fluid.c2
-rw-r--r--source/blender/editors/physics/physics_intern.h3
-rw-r--r--source/blender/editors/physics/physics_ops.c7
-rw-r--r--source/blender/editors/physics/rigidbody_constraint.c2
-rw-r--r--source/blender/editors/physics/rigidbody_object.c5
-rw-r--r--source/blender/editors/physics/rigidbody_world.c8
-rw-r--r--source/blender/editors/render/render_internal.c46
-rw-r--r--source/blender/editors/render/render_opengl.c70
-rw-r--r--source/blender/editors/render/render_preview.c43
-rw-r--r--source/blender/editors/render/render_shading.c29
-rw-r--r--source/blender/editors/render/render_update.c43
-rw-r--r--source/blender/editors/render/render_view.c23
-rw-r--r--source/blender/editors/screen/area.c132
-rw-r--r--source/blender/editors/screen/glutil.c11
-rw-r--r--source/blender/editors/screen/screen_context.c121
-rw-r--r--source/blender/editors/screen/screen_edit.c67
-rw-r--r--source/blender/editors/screen/screen_ops.c169
-rw-r--r--source/blender/editors/screen/screendump.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c26
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c32
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c15
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c1521
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h13
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c37
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c138
-rw-r--r--source/blender/editors/sculpt_paint/paint_undo.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c56
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c39
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c214
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c10
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c25
-rw-r--r--source/blender/editors/sound/sound_ops.c21
-rw-r--r--source/blender/editors/space_action/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_action/SConscript1
-rw-r--r--source/blender/editors/space_action/action_draw.c6
-rw-r--r--source/blender/editors/space_action/action_edit.c470
-rw-r--r--source/blender/editors/space_action/action_intern.h3
-rw-r--r--source/blender/editors/space_action/action_ops.c10
-rw-r--r--source/blender/editors/space_action/space_action.c4
-rw-r--r--source/blender/editors/space_api/spacetypes.c9
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c8
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c22
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c24
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c5
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c71
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c15
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_ops.c1
-rw-r--r--source/blender/editors/space_clip/clip_draw.c3
-rw-r--r--source/blender/editors/space_clip/clip_editor.c1
-rw-r--r--source/blender/editors/space_clip/clip_graph_draw.c1
-rw-r--r--source/blender/editors/space_clip/clip_graph_ops.c2
-rw-r--r--source/blender/editors/space_clip/clip_ops.c18
-rw-r--r--source/blender/editors/space_clip/clip_toolbar.c2
-rw-r--r--source/blender/editors/space_clip/clip_utils.c4
-rw-r--r--source/blender/editors/space_clip/space_clip.c13
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c31
-rw-r--r--source/blender/editors/space_clip/tracking_select.c9
-rw-r--r--source/blender/editors/space_console/console_draw.c1
-rw-r--r--source/blender/editors/space_console/console_ops.c10
-rw-r--r--source/blender/editors/space_file/file_draw.c302
-rw-r--r--source/blender/editors/space_file/file_intern.h6
-rw-r--r--source/blender/editors/space_file/file_ops.c371
-rw-r--r--source/blender/editors/space_file/file_panels.c172
-rw-r--r--source/blender/editors/space_file/filelist.c1122
-rw-r--r--source/blender/editors/space_file/filelist.h60
-rw-r--r--source/blender/editors/space_file/filesel.c88
-rw-r--r--source/blender/editors/space_file/fsmenu.c264
-rw-r--r--source/blender/editors/space_file/fsmenu.h40
-rw-r--r--source/blender/editors/space_file/space_file.c135
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c68
-rw-r--r--source/blender/editors/space_graph/graph_draw.c91
-rw-r--r--source/blender/editors/space_graph/graph_edit.c19
-rw-r--r--source/blender/editors/space_graph/graph_intern.h1
-rw-r--r--source/blender/editors/space_graph/graph_ops.c205
-rw-r--r--source/blender/editors/space_graph/graph_select.c85
-rw-r--r--source/blender/editors/space_graph/graph_utils.c1
-rw-r--r--source/blender/editors/space_graph/space_graph.c4
-rw-r--r--source/blender/editors/space_image/image_buttons.c137
-rw-r--r--source/blender/editors/space_image/image_draw.c33
-rw-r--r--source/blender/editors/space_image/image_edit.c15
-rw-r--r--source/blender/editors/space_image/image_ops.c64
-rw-r--r--source/blender/editors/space_image/space_image.c35
-rw-r--r--source/blender/editors/space_info/info_draw.c3
-rw-r--r--source/blender/editors/space_info/info_ops.c16
-rw-r--r--source/blender/editors/space_info/textview.c2
-rw-r--r--source/blender/editors/space_logic/logic_buttons.c5
-rw-r--r--source/blender/editors/space_logic/logic_ops.c9
-rw-r--r--source/blender/editors/space_logic/logic_window.c227
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c15
-rw-r--r--source/blender/editors/space_nla/nla_channels.c3
-rw-r--r--source/blender/editors/space_nla/nla_draw.c17
-rw-r--r--source/blender/editors/space_nla/nla_edit.c31
-rw-r--r--source/blender/editors/space_nla/nla_intern.h2
-rw-r--r--source/blender/editors/space_nla/nla_ops.c4
-rw-r--r--source/blender/editors/space_nla/space_nla.c6
-rw-r--r--source/blender/editors/space_node/drawnode.c140
-rw-r--r--source/blender/editors/space_node/node_add.c63
-rw-r--r--source/blender/editors/space_node/node_buttons.c15
-rw-r--r--source/blender/editors/space_node/node_draw.c162
-rw-r--r--source/blender/editors/space_node/node_edit.c50
-rw-r--r--source/blender/editors/space_node/node_group.c20
-rw-r--r--source/blender/editors/space_node/node_intern.h1
-rw-r--r--source/blender/editors/space_node/node_ops.c7
-rw-r--r--source/blender/editors/space_node/node_relationships.c52
-rw-r--r--source/blender/editors/space_node/node_select.c16
-rw-r--r--source/blender/editors/space_node/node_templates.c34
-rw-r--r--source/blender/editors/space_node/node_toolbar.c9
-rw-r--r--source/blender/editors/space_node/space_node.c25
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c368
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c241
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h10
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c6
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c11
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c376
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c226
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c53
-rw-r--r--source/blender/editors/space_script/script_edit.c3
-rw-r--r--source/blender/editors/space_script/script_ops.c13
-rw-r--r--source/blender/editors/space_script/space_script.c2
-rw-r--r--source/blender/editors/space_sequencer/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c11
-rw-r--r--source/blender/editors/space_sequencer/sequencer_buttons.c7
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c541
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c467
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h24
-rw-r--r--source/blender/editors/space_sequencer/sequencer_modifier.c12
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c7
-rw-r--r--source/blender/editors/space_sequencer/sequencer_preview.c172
-rw-r--r--source/blender/editors/space_sequencer/sequencer_scopes.c32
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c11
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c37
-rw-r--r--source/blender/editors/space_text/space_text.c4
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c10
-rw-r--r--source/blender/editors/space_text/text_draw.c128
-rw-r--r--source/blender/editors/space_text/text_header.c25
-rw-r--r--source/blender/editors/space_text/text_intern.h3
-rw-r--r--source/blender/editors/space_text/text_ops.c189
-rw-r--r--source/blender/editors/space_time/space_time.c33
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c2
-rw-r--r--source/blender/editors/space_userpref/userpref_ops.c1
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_view3d/drawanimviz.c1
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c5
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c109
-rw-r--r--source/blender/editors/space_view3d/drawobject.c253
-rw-r--r--source/blender/editors/space_view3d/drawsimdebug.c173
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c5
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c100
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c106
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c751
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c276
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c17
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h9
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c21
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c15
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c223
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c28
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c80
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c4
-rw-r--r--source/blender/editors/transform/transform.c694
-rw-r--r--source/blender/editors/transform/transform.h54
-rw-r--r--source/blender/editors/transform/transform_constraints.c2
-rw-r--r--source/blender/editors/transform/transform_conversions.c447
-rw-r--r--source/blender/editors/transform/transform_generics.c123
-rw-r--r--source/blender/editors/transform/transform_manipulator.c56
-rw-r--r--source/blender/editors/transform/transform_ops.c41
-rw-r--r--source/blender/editors/transform/transform_orientations.c30
-rw-r--r--source/blender/editors/transform/transform_snap.c73
-rw-r--r--source/blender/editors/util/ed_transverts.c4
-rw-r--r--source/blender/editors/util/ed_util.c10
-rw-r--r--source/blender/editors/util/editmode_undo.c8
-rw-r--r--source/blender/editors/util/numinput.c2
-rw-r--r--source/blender/editors/util/undo.c20
-rw-r--r--source/blender/editors/uvedit/uvedit_buttons.c29
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c11
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h2
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c37
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c22
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c28
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c96
-rw-r--r--source/blender/freestyle/CMakeLists.txt5
-rw-r--r--source/blender/freestyle/intern/application/AppConfig.cpp4
-rw-r--r--source/blender/freestyle/intern/application/Controller.cpp39
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp11
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp516
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h21
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp9
-rw-r--r--source/blender/freestyle/intern/python/BPy_Convert.cpp11
-rw-r--r--source/blender/freestyle/intern/python/BPy_Convert.h1
-rw-r--r--source/blender/freestyle/intern/python/BPy_Freestyle.cpp43
-rw-r--r--source/blender/freestyle/intern/python/BPy_Operators.cpp3
-rw-r--r--source/blender/freestyle/intern/python/BPy_SShape.cpp10
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewShape.cpp27
-rw-r--r--source/blender/freestyle/intern/python/Director.cpp6
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp30
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp18
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp16
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeCamera.h2
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeSceneRenderLayer.cpp35
-rw-r--r--source/blender/freestyle/intern/scene_graph/NodeSceneRenderLayer.h76
-rw-r--r--source/blender/freestyle/intern/scene_graph/SceneHash.cpp47
-rw-r--r--source/blender/freestyle/intern/scene_graph/SceneHash.h25
-rw-r--r--source/blender/freestyle/intern/scene_graph/SceneVisitor.h2
-rw-r--r--source/blender/freestyle/intern/stroke/Canvas.h6
-rw-r--r--source/blender/freestyle/intern/stroke/ChainingIterators.h2
-rw-r--r--source/blender/freestyle/intern/stroke/Curve.cpp2
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.cpp25
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.h1
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRep.cpp2
-rw-r--r--source/blender/freestyle/intern/system/StringUtils.h3
-rw-r--r--source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp14
-rw-r--r--source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h8
-rw-r--r--source/blender/freestyle/intern/view_map/AutoPtrHelper.h60
-rw-r--r--source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp12
-rw-r--r--source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h8
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp2
-rw-r--r--source/blender/freestyle/intern/view_map/GridDensityProvider.h9
-rw-r--r--source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp32
-rw-r--r--source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h8
-rw-r--r--source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp12
-rw-r--r--source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h8
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp12
-rw-r--r--source/blender/freestyle/intern/winged_edge/Curvature.cpp7
-rw-r--r--source/blender/gpu/CMakeLists.txt28
-rw-r--r--source/blender/gpu/GPU_buffers.h11
-rw-r--r--source/blender/gpu/GPU_compositing.h96
-rw-r--r--source/blender/gpu/GPU_debug.h77
-rw-r--r--source/blender/gpu/GPU_draw.h6
-rw-r--r--source/blender/gpu/GPU_extensions.h33
-rw-r--r--source/blender/gpu/GPU_material.h96
-rw-r--r--source/blender/gpu/SConscript7
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c186
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c262
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h72
-rw-r--r--source/blender/gpu/intern/gpu_compositing.c987
-rw-r--r--source/blender/gpu/intern/gpu_debug.c749
-rw-r--r--source/blender/gpu/intern/gpu_draw.c484
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c549
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c6
-rw-r--r--source/blender/gpu/intern/gpu_material.c276
-rw-r--r--source/blender/gpu/intern/gpu_private.h49
-rw-r--r--source/blender/gpu/intern/gpu_select.c19
-rw-r--r--source/blender/gpu/intern/gpu_simple_shader.c3
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl208
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl68
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_lib.glsl47
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl86
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_vert.glsl9
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl125
-rw-r--r--source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex_world.glsl13
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.c7
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c3
-rw-r--r--source/blender/imbuf/IMB_imbuf.h13
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h6
-rw-r--r--source/blender/imbuf/intern/IMB_metadata.h7
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c26
-rw-r--r--source/blender/imbuf/intern/anim_movie.c29
-rw-r--r--source/blender/imbuf/intern/bmp.c135
-rw-r--r--source/blender/imbuf/intern/cache.c3
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c2
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c10
-rw-r--r--source/blender/imbuf/intern/colormanagement.c30
-rw-r--r--source/blender/imbuf/intern/dds/Stream.cpp15
-rw-r--r--source/blender/imbuf/intern/divers.c15
-rw-r--r--source/blender/imbuf/intern/filetype.c2
-rw-r--r--source/blender/imbuf/intern/indexer.c77
-rw-r--r--source/blender/imbuf/intern/iris.c1
-rw-r--r--source/blender/imbuf/intern/jp2.c3
-rw-r--r--source/blender/imbuf/intern/jpeg.c46
-rw-r--r--source/blender/imbuf/intern/metadata.c105
-rw-r--r--source/blender/imbuf/intern/moviecache.c60
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp46
-rw-r--r--source/blender/imbuf/intern/png.c32
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c62
-rw-r--r--source/blender/imbuf/intern/rectop.c2
-rw-r--r--source/blender/imbuf/intern/rotate.c2
-rw-r--r--source/blender/imbuf/intern/scaling.c2
-rw-r--r--source/blender/imbuf/intern/targa.c1
-rw-r--r--source/blender/imbuf/intern/thumbs.c19
-rw-r--r--source/blender/imbuf/intern/thumbs_blend.c4
-rw-r--r--source/blender/imbuf/intern/tiff.c8
-rw-r--r--source/blender/imbuf/intern/writeimage.c2
-rw-r--r--source/blender/makesdna/DNA_ID.h134
-rw-r--r--source/blender/makesdna/DNA_action_types.h12
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h3
-rw-r--r--source/blender/makesdna/DNA_anim_types.h14
-rw-r--r--source/blender/makesdna/DNA_armature_types.h2
-rw-r--r--source/blender/makesdna/DNA_brush_types.h8
-rw-r--r--source/blender/makesdna/DNA_camera_types.h8
-rw-r--r--source/blender/makesdna/DNA_cloth_types.h19
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h24
-rw-r--r--source/blender/makesdna/DNA_curve_types.h203
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h11
-rw-r--r--source/blender/makesdna/DNA_dynamicpaint_types.h166
-rw-r--r--source/blender/makesdna/DNA_fileglobal_types.h4
-rw-r--r--source/blender/makesdna/DNA_freestyle_types.h96
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h110
-rw-r--r--source/blender/makesdna/DNA_gpu_types.h66
-rw-r--r--source/blender/makesdna/DNA_image_types.h1
-rw-r--r--source/blender/makesdna/DNA_key_types.h6
-rw-r--r--source/blender/makesdna/DNA_material_types.h1
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h98
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h109
-rw-r--r--source/blender/makesdna/DNA_node_types.h43
-rw-r--r--source/blender/makesdna/DNA_object_types.h2
-rw-r--r--source/blender/makesdna/DNA_particle_types.h119
-rw-r--r--source/blender/makesdna/DNA_scene_types.h92
-rw-r--r--source/blender/makesdna/DNA_screen_types.h47
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h17
-rw-r--r--source/blender/makesdna/DNA_sound_types.h9
-rw-r--r--source/blender/makesdna/DNA_space_types.h80
-rw-r--r--source/blender/makesdna/DNA_texture_types.h22
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h22
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h61
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h32
-rw-r--r--source/blender/makesdna/DNA_world_types.h1
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c2
-rw-r--r--source/blender/makesdna/intern/makesdna.c3
-rw-r--r--source/blender/makesrna/RNA_access.h5
-rw-r--r--source/blender/makesrna/RNA_enum_types.h8
-rw-r--r--source/blender/makesrna/RNA_types.h6
-rw-r--r--source/blender/makesrna/SConscript4
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt32
-rw-r--r--source/blender/makesrna/intern/SConscript4
-rw-r--r--source/blender/makesrna/intern/makesrna.c109
-rw-r--r--source/blender/makesrna/intern/rna_ID.c35
-rw-r--r--source/blender/makesrna/intern/rna_access.c142
-rw-r--r--source/blender/makesrna/intern/rna_action.c12
-rw-r--r--source/blender/makesrna/intern/rna_actuator.c35
-rw-r--r--source/blender/makesrna/intern/rna_animation.c69
-rw-r--r--source/blender/makesrna/intern/rna_animviz.c10
-rw-r--r--source/blender/makesrna/intern/rna_boid.c4
-rw-r--r--source/blender/makesrna/intern/rna_brush.c98
-rw-r--r--source/blender/makesrna/intern/rna_camera.c32
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c113
-rw-r--r--source/blender/makesrna/intern/rna_color.c13
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c39
-rw-r--r--source/blender/makesrna/intern/rna_controller.c11
-rw-r--r--source/blender/makesrna/intern/rna_define.c45
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c2
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c4
-rw-r--r--source/blender/makesrna/intern/rna_fcurve_api.c108
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c282
-rw-r--r--source/blender/makesrna/intern/rna_image.c33
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c31
-rw-r--r--source/blender/makesrna/intern/rna_internal.h5
-rw-r--r--source/blender/makesrna/intern/rna_key.c7
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c18
-rw-r--r--source/blender/makesrna/intern/rna_main.c7
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c110
-rw-r--r--source/blender/makesrna/intern/rna_material.c2
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c603
-rw-r--r--source/blender/makesrna/intern/rna_mesh_api.c138
-rw-r--r--source/blender/makesrna/intern/rna_mesh_utils.h2
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c830
-rw-r--r--source/blender/makesrna/intern/rna_movieclip.c2
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c121
-rw-r--r--source/blender/makesrna/intern/rna_object.c62
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c61
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c4
-rw-r--r--source/blender/makesrna/intern/rna_particle.c147
-rw-r--r--source/blender/makesrna/intern/rna_pose.c8
-rw-r--r--source/blender/makesrna/intern/rna_property.c11
-rw-r--r--source/blender/makesrna/intern/rna_render.c8
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c3
-rw-r--r--source/blender/makesrna/intern/rna_rna.c48
-rw-r--r--source/blender/makesrna/intern/rna_scene.c296
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c36
-rw-r--r--source/blender/makesrna/intern/rna_screen.c9
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c64
-rw-r--r--source/blender/makesrna/intern/rna_sensor.c14
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c33
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c29
-rw-r--r--source/blender/makesrna/intern/rna_sound.c7
-rw-r--r--source/blender/makesrna/intern/rna_sound_api.c73
-rw-r--r--source/blender/makesrna/intern/rna_space.c518
-rw-r--r--source/blender/makesrna/intern/rna_space_api.c31
-rw-r--r--source/blender/makesrna/intern/rna_texture.c28
-rw-r--r--source/blender/makesrna/intern/rna_texture_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c2
-rw-r--r--source/blender/makesrna/intern/rna_ui.c5
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c26
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c146
-rw-r--r--source/blender/makesrna/intern/rna_vfont.c2
-rw-r--r--source/blender/makesrna/intern/rna_vfont_api.c73
-rw-r--r--source/blender/makesrna/intern/rna_wm.c25
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c12
-rw-r--r--source/blender/makesrna/intern/rna_world.c2
-rw-r--r--source/blender/modifiers/CMakeLists.txt2
-rw-r--r--source/blender/modifiers/MOD_modifiertypes.h2
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c1
-rw-r--r--source/blender/modifiers/intern/MOD_array.c16
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c5
-rw-r--r--source/blender/modifiers/intern/MOD_boolean_util.c25
-rw-r--r--source/blender/modifiers/intern/MOD_build.c19
-rw-r--r--source/blender/modifiers/intern/MOD_cast.c1
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c13
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c3
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c3
-rw-r--r--source/blender/modifiers/intern/MOD_datatransfer.c243
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c5
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c1
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c4
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c3
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim.c4
-rw-r--r--source/blender/modifiers/intern/MOD_hook.c223
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c2
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c9
-rw-r--r--source/blender/modifiers/intern/MOD_lattice.c2
-rw-r--r--source/blender/modifiers/intern/MOD_mask.c162
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c2
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c3
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c27
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c3
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c3
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.c514
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c2
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c52
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c32
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c1
-rw-r--r--source/blender/modifiers/intern/MOD_shapekey.c7
-rw-r--r--source/blender/modifiers/intern/MOD_shrinkwrap.c2
-rw-r--r--source/blender/modifiers/intern/MOD_simpledeform.c3
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c57
-rw-r--r--source/blender/modifiers/intern/MOD_smoke.c77
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c38
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c1
-rw-r--r--source/blender/modifiers/intern/MOD_util.c9
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c2
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.c1
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c59
-rw-r--r--source/blender/modifiers/intern/MOD_wave.c1
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.c5
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c6
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c5
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c5
-rw-r--r--source/blender/modifiers/intern/MOD_wireframe.c8
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c10
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_boxmask.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_colorbalance.c3
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_common.c1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_composite.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_defocus.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c12
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_keying.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_keyingscreen.c6
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_mask.c4
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_movieclip.c3
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_moviedistortion.c2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_outputFile.c5
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c3
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_stabilize2d.c3
-rw-r--r--source/blender/nodes/intern/node_common.c4
-rw-r--r--source/blender/nodes/intern/node_socket.c3
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c9
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_background.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bump.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_gamma.c15
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geom.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geometry.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_lamp.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_material.c8
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.c89
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mixRgb.c12
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal.c10
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_world.c13
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_script.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_coord.c18
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c21
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_texture.c3
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vectMath.c7
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c3
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_math.c42
-rw-r--r--source/blender/physics/BPH_mass_spring.h62
-rw-r--r--source/blender/physics/CMakeLists.txt53
-rw-r--r--source/blender/physics/SConscript44
-rw-r--r--source/blender/physics/intern/BPH_mass_spring.cpp1117
-rw-r--r--source/blender/physics/intern/ConstrainedConjugateGradient.h294
-rw-r--r--source/blender/physics/intern/eigen_utils.h230
-rw-r--r--source/blender/physics/intern/hair_volume.cpp1154
-rw-r--r--source/blender/physics/intern/implicit.h186
-rw-r--r--source/blender/physics/intern/implicit_blender.c2041
-rw-r--r--source/blender/physics/intern/implicit_eigen.cpp1369
-rw-r--r--source/blender/python/SConscript5
-rw-r--r--source/blender/python/bmesh/bmesh_py_geometry.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops.c5
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c18
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c188
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.h21
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c10
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.c17
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_select.c12
-rw-r--r--source/blender/python/bmesh/bmesh_py_utils.c13
-rw-r--r--source/blender/python/generic/CMakeLists.txt3
-rw-r--r--source/blender/python/generic/blf_py_api.c8
-rw-r--r--source/blender/python/generic/bpy_internal_import.c6
-rw-r--r--source/blender/python/generic/idprop_py_api.c49
-rw-r--r--source/blender/python/generic/py_capi_utils.c18
-rw-r--r--source/blender/python/generic/py_capi_utils.h1
-rw-r--r--source/blender/python/generic/python_utildefines.h60
-rw-r--r--source/blender/python/intern/CMakeLists.txt16
-rw-r--r--source/blender/python/intern/bpy.c29
-rw-r--r--source/blender/python/intern/bpy_app.c15
-rw-r--r--source/blender/python/intern/bpy_app_build_options.c7
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c42
-rw-r--r--source/blender/python/intern/bpy_app_sdl.c136
-rw-r--r--source/blender/python/intern/bpy_app_sdl.h (renamed from source/blender/gpu/intern/gpu_extensions_private.h)16
-rw-r--r--source/blender/python/intern/bpy_app_translations.c44
-rw-r--r--source/blender/python/intern/bpy_driver.c2
-rw-r--r--source/blender/python/intern/bpy_interface.c5
-rw-r--r--source/blender/python/intern/bpy_library.c15
-rw-r--r--source/blender/python/intern/bpy_operator.c22
-rw-r--r--source/blender/python/intern/bpy_props.c81
-rw-r--r--source/blender/python/intern/bpy_rna.c117
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c7
-rw-r--r--source/blender/python/intern/bpy_utils_units.c2
-rw-r--r--source/blender/python/intern/gpu.c5
-rw-r--r--source/blender/python/mathutils/CMakeLists.txt2
-rw-r--r--source/blender/python/mathutils/mathutils.c132
-rw-r--r--source/blender/python/mathutils/mathutils.h53
-rw-r--r--source/blender/python/mathutils/mathutils_Color.c140
-rw-r--r--source/blender/python/mathutils/mathutils_Color.h15
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.c143
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.h15
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c281
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.h21
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c224
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.h15
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c235
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.h22
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c816
-rw-r--r--source/blender/python/mathutils/mathutils_interpolate.c137
-rw-r--r--source/blender/python/mathutils/mathutils_interpolate.h (renamed from source/blender/compositor/intern/COM_ChannelInfo.cpp)27
-rw-r--r--source/blender/python/mathutils/mathutils_kdtree.c14
-rw-r--r--source/blender/python/mathutils/mathutils_noise.c14
-rw-r--r--source/blender/quicktime/apple/qtkit_export.m20
-rw-r--r--source/blender/render/CMakeLists.txt1
-rw-r--r--source/blender/render/SConscript2
-rw-r--r--source/blender/render/extern/include/RE_engine.h1
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h2
-rw-r--r--source/blender/render/extern/include/RE_render_ext.h2
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h4
-rw-r--r--source/blender/render/intern/include/envmap.h2
-rw-r--r--source/blender/render/intern/include/rayintersection.h2
-rw-r--r--source/blender/render/intern/include/render_types.h1
-rw-r--r--source/blender/render/intern/include/texture.h4
-rw-r--r--source/blender/render/intern/source/bake.c10
-rw-r--r--source/blender/render/intern/source/bake_api.c7
-rw-r--r--source/blender/render/intern/source/convertblender.c67
-rw-r--r--source/blender/render/intern/source/envmap.c14
-rw-r--r--source/blender/render/intern/source/external_engine.c20
-rw-r--r--source/blender/render/intern/source/imagetexture.c16
-rw-r--r--source/blender/render/intern/source/initrender.c17
-rw-r--r--source/blender/render/intern/source/occlusion.c2
-rw-r--r--source/blender/render/intern/source/pipeline.c60
-rw-r--r--source/blender/render/intern/source/pixelblending.c1
-rw-r--r--source/blender/render/intern/source/pixelshading.c11
-rw-r--r--source/blender/render/intern/source/pointdensity.c3
-rw-r--r--source/blender/render/intern/source/rayshade.c16
-rw-r--r--source/blender/render/intern/source/render_result.c85
-rw-r--r--source/blender/render/intern/source/render_texture.c107
-rw-r--r--source/blender/render/intern/source/rendercore.c10
-rw-r--r--source/blender/render/intern/source/renderdatabase.c13
-rw-r--r--source/blender/render/intern/source/shadbuf.c1
-rw-r--r--source/blender/render/intern/source/shadeinput.c2
-rw-r--r--source/blender/render/intern/source/shadeoutput.c4
-rw-r--r--source/blender/render/intern/source/sss.c13
-rw-r--r--source/blender/render/intern/source/strand.c3
-rw-r--r--source/blender/render/intern/source/sunsky.c11
-rw-r--r--source/blender/render/intern/source/texture_ocean.c2
-rw-r--r--source/blender/render/intern/source/voxeldata.c28
-rw-r--r--source/blender/render/intern/source/zbuf.c4
-rw-r--r--source/blender/windowmanager/CMakeLists.txt8
-rw-r--r--source/blender/windowmanager/SConscript5
-rw-r--r--source/blender/windowmanager/WM_api.h10
-rw-r--r--source/blender/windowmanager/WM_types.h41
-rw-r--r--source/blender/windowmanager/intern/wm.c19
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c45
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c153
-rw-r--r--source/blender/windowmanager/intern/wm_files.c69
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c1
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c22
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c27
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c153
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c787
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c9
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c3
-rw-r--r--source/blender/windowmanager/intern/wm_window.c29
-rw-r--r--source/blender/windowmanager/wm_event_system.h3
-rw-r--r--source/blender/windowmanager/wm_event_types.h48
-rw-r--r--source/blender/windowmanager/wm_window.h5
-rw-r--r--source/blenderplayer/CMakeLists.txt13
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c55
-rw-r--r--source/creator/CMakeLists.txt309
-rw-r--r--source/creator/blender.map1
-rw-r--r--source/creator/creator.c238
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp14
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp5
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.h1
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp11
-rw-r--r--source/gameengine/Converter/BL_ArmatureChannel.cpp2
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp3
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp265
-rw-r--r--source/gameengine/Converter/BL_ModifierDeformer.cpp1
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp4
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp118
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp3
-rw-r--r--source/gameengine/Expressions/ListValue.cpp2
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp6
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h12
-rw-r--r--source/gameengine/Expressions/Value.cpp2
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp51
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp15
-rw-r--r--source/gameengine/GameLogic/SCA_IInputDevice.h2
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h3
-rw-r--r--source/gameengine/GameLogic/SCA_IScene.cpp2
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.cpp12
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp1
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.h2
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Canvas.cpp5
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Canvas.h2
-rw-r--r--source/gameengine/GamePlayer/ghost/CMakeLists.txt7
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp27
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp28
-rw-r--r--source/gameengine/GamePlayer/ghost/SConscript4
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.h2
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.cpp2
-rw-r--r--source/gameengine/Ketsji/BL_Material.cpp8
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp12
-rw-r--r--source/gameengine/Ketsji/KXNetwork/CMakeLists.txt1
-rw-r--r--source/gameengine/Ketsji/KXNetwork/SConscript1
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_Dome.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_FontObject.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_FontObject.h1
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp163
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h18
-rw-r--r--source/gameengine/Ketsji/KX_ISceneConverter.h8
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp92
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h1
-rw-r--r--source/gameengine/Ketsji/KX_MouseActuator.cpp56
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp224
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.h3
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp411
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.h23
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.cpp39
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.h3
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp36
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h2
-rw-r--r--source/gameengine/Ketsji/KX_SteeringActuator.cpp27
-rw-r--r--source/gameengine/Ketsji/KX_SteeringActuator.h4
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.cpp24
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.h24
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.cpp76
-rw-r--r--source/gameengine/Network/CMakeLists.txt1
-rw-r--r--source/gameengine/Network/SConscript1
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp69
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h14
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp257
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h6
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp46
-rw-r--r--source/gameengine/VideoTexture/ImageBase.cpp30
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp2
-rw-r--r--source/gameengine/VideoTexture/Texture.cpp38
-rw-r--r--source/gameengine/VideoTexture/Texture.h8
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.cpp7
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.h3
-rw-r--r--source/gameengine/VideoTexture/blendVideoTex.cpp27
-rw-r--r--tests/gtests/blenlib/BLI_hash_mm2a_test.cc75
-rw-r--r--tests/gtests/blenlib/BLI_path_util_test.cc1
-rw-r--r--tests/gtests/blenlib/BLI_polyfill2d_test.cc28
-rw-r--r--tests/gtests/blenlib/CMakeLists.txt1
-rw-r--r--tests/gtests/testing/testing_main.cc2
-rw-r--r--tests/python/CMakeLists.txt47
-rw-r--r--tests/python/batch_import.py4
-rw-r--r--tests/python/bl_load_addons.py34
-rw-r--r--tests/python/bl_load_py_modules.py28
-rw-r--r--tests/python/bl_pyapi_mathutils.py31
-rw-r--r--tests/python/bl_rna_wiki_reference.py37
-rw-r--r--tests/python/bl_run_operators.py8
-rwxr-xr-xtests/python/cycles_render_tests.py166
-rw-r--r--tests/python/pep8.py12
2065 files changed, 116004 insertions, 41664 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d66610c14c9..6b879b45401 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -117,6 +117,76 @@ set(TESTS_OUTPUT_DIR ${EXECUTABLE_OUTPUT_PATH}/tests CACHE INTERNAL "" FORCE)
get_blender_version()
+#-----------------------------------------------------------------------------
+# Platform Specific Defaults
+
+# list of var-names
+set(_init_vars)
+
+# initialize to ON
+macro(option_defaults_init)
+ foreach(_var ${ARGV})
+ set(${_var} ON)
+ list(APPEND _init_vars "${_var}")
+ endforeach()
+ unset(_INC)
+endmacro()
+
+# remove from namespace
+macro(option_defaults_clear)
+ foreach(_var ${_init_vars})
+ unset(${_var})
+ endforeach()
+ unset(_var)
+ unset(_init_vars)
+endmacro()
+
+
+# values to initialize WITH_****
+option_defaults_init(
+ _init_BUILDINFO
+ _init_CODEC_FFMPEG
+ _init_CYCLES_OSL
+ _init_IMAGE_OPENEXR
+ _init_IMAGE_REDCODE
+ _init_INPUT_NDOF
+ _init_JACK
+ _init_LIBMV_SCHUR_SPECIALIZATION
+ _init_OPENCOLLADA
+ _init_OPENCOLORIO
+ _init_SDL
+ _init_FFTW3
+ _init_GAMEENGINE
+)
+
+# customize...
+if(UNIX AND NOT APPLE)
+ # some of these libraries are problematic on Linux
+ # disable less important dependencies by default
+ set(_init_BUILDINFO OFF)
+ set(_init_CODEC_FFMPEG OFF)
+ set(_init_CYCLES_OSL OFF)
+ set(_init_IMAGE_OPENEXR OFF)
+ set(_init_IMAGE_REDCODE OFF)
+ set(_init_INPUT_NDOF OFF)
+ set(_init_JACK OFF)
+ set(_init_LIBMV_SCHUR_SPECIALIZATION OFF)
+ set(_init_OPENCOLLADA OFF)
+ set(_init_OPENCOLORIO OFF)
+ set(_init_SDL OFF)
+ set(_init_FFTW3 OFF)
+ set(_init_GAMEENGINE OFF)
+endif()
+
+
+#-----------------------------------------------------------------------------
+# Options
+
+# First platform spesific non-cached vars
+if(UNIX AND NOT APPLE)
+ set(WITH_X11 ON)
+endif()
+
# Blender internal features
option(WITH_BLENDER "Build blender (disable to build only the blender player)" ON)
mark_as_advanced(WITH_BLENDER)
@@ -130,12 +200,13 @@ mark_as_advanced(WITH_PYTHON_SECURITY) # some distributions see this as a secur
set(WITH_PYTHON_SECURITY ON CACHE BOOL "ON" FORCE) # temp force on.
option(WITH_PYTHON_SAFETY "Enable internal API error checking to track invalid data to prevent crash on access (at the expense of some effeciency, only enable for development)." OFF)
+mark_as_advanced(WITH_PYTHON_SAFETY)
option(WITH_PYTHON_MODULE "Enable building as a python module which runs without a user interface, like running regular blender in background mode (experimental, only enable for development)" OFF)
if(APPLE)
option(WITH_PYTHON_FRAMEWORK "Enable building using the Python available in the framework (OSX only)" OFF)
endif()
-option(WITH_BUILDINFO "Include extra build details (only disable for development & faster builds)" ON)
+option(WITH_BUILDINFO "Include extra build details (only disable for development & faster builds)" ${_init_BUILDINFO})
if(${CMAKE_VERSION} VERSION_LESS 2.8.8)
# add_library OBJECT arg unsupported
set(WITH_BUILDINFO OFF)
@@ -143,13 +214,13 @@ endif()
option(WITH_IK_ITASC "Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)" ON)
option(WITH_IK_SOLVER "Enable Legacy IK solver (only disable for development)" ON)
-option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke and audio effects)" ON)
+option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke and audio effects)" ${_init_FFTW3})
option(WITH_BULLET "Enable Bullet (Physics Engine)" ON)
option(WITH_SYSTEM_BULLET "Use the systems bullet library (currently unsupported due to missing features in upstream!)" )
mark_as_advanced(WITH_SYSTEM_BULLET)
-option(WITH_GAMEENGINE "Enable Game Engine" ON)
+option(WITH_GAMEENGINE "Enable Game Engine" ${_init_GAMEENGINE})
option(WITH_PLAYER "Build Player" OFF)
-option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ON)
+option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLORIO})
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
option(WITH_MOD_MANTA "Enable Mantaflow Framework" ON)
@@ -160,6 +231,10 @@ mark_as_advanced(WITH_GHOST_DEBUG)
option(WITH_GHOST_SDL "Enable building blender against SDL for windowing rather then the native APIs" OFF)
mark_as_advanced(WITH_GHOST_SDL)
+if(WITH_X11)
+ option(WITH_GHOST_XDND "Enable drag'n'drop support on X11 using XDND protocol" ON)
+endif()
+
# Misc...
option(WITH_HEADLESS "Build without graphical support (renderfarm, server mode only)" OFF)
mark_as_advanced(WITH_HEADLESS)
@@ -169,14 +244,9 @@ mark_as_advanced(WITH_AUDASPACE)
option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ON)
-if(UNIX AND NOT APPLE)
- set(WITH_X11 ON)
-endif()
-
if(WITH_X11)
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
option(WITH_X11_XF86VMODE "Enable X11 video mode switching" ON)
- option(WITH_GHOST_XDND "Enable drag'n'drop support on X11 using XDND protocol" ON)
endif()
if(UNIX AND NOT APPLE)
@@ -190,13 +260,7 @@ endif()
# (unix defaults to System OpenJPEG On)
-if(UNIX AND NOT APPLE)
- set(PLATFORM_DEFAULT ON)
-else()
- set(PLATFORM_DEFAULT OFF)
-endif()
-option(WITH_SYSTEM_OPENJPEG "Use the operating systems OpenJPEG library" ${PLATFORM_DEFAULT})
-unset(PLATFORM_DEFAULT)
+option(WITH_SYSTEM_OPENJPEG "Use the operating systems OpenJPEG library" OFF)
# Modifiers
@@ -209,57 +273,60 @@ option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" OFF)
# Image format support
-option(WITH_OPENIMAGEIO "Enable OpenImageIO Support (http://www.openimageio.org)" OFF)
-option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
+option(WITH_OPENIMAGEIO "Enable OpenImageIO Support (http://www.openimageio.org)" ON)
+option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ${_init_IMAGE_OPENEXR})
option(WITH_IMAGE_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org)" ON)
option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON)
option(WITH_IMAGE_DDS "Enable DDS Image Support" ON)
option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON)
option(WITH_IMAGE_HDR "Enable HDR Image Support" ON)
-option(WITH_IMAGE_REDCODE "Enable RedCode Image Support" OFF)
+option(WITH_IMAGE_REDCODE "Enable RedCode Image Support" ${_init_IMAGE_REDCODE})
option(WITH_IMAGE_FRAMESERVER "Enable image FrameServer Support for rendering" ON)
# Audio/Video format support
option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON)
-option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" OFF)
+option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" ${_init_CODEC_FFMPEG})
option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF)
if(APPLE)
- option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" ON)
option(WITH_CODEC_QUICKTIME "Enable Quicktime Support" ON)
-else()
- option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" OFF)
endif()
# 3D format support
# Disable opencollada when we don't have precompiled libs
-if(APPLE OR WIN32)
- option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" ON)
-else()
- option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" OFF)
-endif()
+option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" ${_init_OPENCOLLADA})
# Sound output
-option(WITH_SDL "Enable SDL for sound and joystick support" ON)
+option(WITH_SDL "Enable SDL for sound and joystick support" ${_init_SDL})
option(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
-option(WITH_JACK "Enable Jack Support (http://www.jackaudio.org)" OFF)
+option(WITH_JACK "Enable Jack Support (http://www.jackaudio.org)" ${_init_JACK})
if(UNIX AND NOT APPLE)
option(WITH_JACK_DYNLOAD "Enable runtime dynamic Jack libraries loading" OFF)
endif()
+if(UNIX AND NOT APPLE)
+ option(WITH_SDL_DYNLOAD "Enable runtime dynamic SDL libraries loading" OFF)
+endif()
# Compression
option(WITH_LZO "Enable fast LZO compression (used for pointcache)" ON)
option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)" ON)
+if(UNIX AND NOT APPLE)
+ option(WITH_SYSTEM_LZO "Use the system LZO library" OFF)
+endif()
# Camera/motion tracking
option(WITH_LIBMV "Enable libmv structure from motion library" ON)
-option(WITH_LIBMV_SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON)
+option(WITH_LIBMV_SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ${_init_LIBMV_SCHUR_SPECIALIZATION})
+mark_as_advanced(WITH_LIBMV_SCHUR_SPECIALIZATIONS)
# Freestyle
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
# Misc
-option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
+if(WIN32)
+ option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON)
+endif()
+option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ${_init_INPUT_NDOF})
option(WITH_RAYOPTIMIZATION "Enable use of SIMD (SSE) optimizations for the raytracer" ON)
option(WITH_OPENNL "Enable use of Open Numerical Library" ON)
if(UNIX AND NOT APPLE)
@@ -287,13 +354,13 @@ endif()
option(WITH_CYCLES "Enable cycles Render Engine" ON)
option(WITH_CYCLES_STANDALONE "Build cycles standalone application" OFF)
option(WITH_CYCLES_STANDALONE_GUI "Build cycles standalone with GUI" OFF)
-option(WITH_CYCLES_OSL "Build Cycles with OSL support" OFF)
+option(WITH_CYCLES_OSL "Build Cycles with OSL support" ${_init_CYCLES_OSL})
option(WITH_CYCLES_CUDA_BINARIES "Build cycles CUDA binaries" OFF)
set(CYCLES_CUDA_BINARIES_ARCH sm_20 sm_21 sm_30 sm_35 sm_50 CACHE STRING "CUDA architectures to build binaries for")
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
unset(PLATFORM_DEFAULT)
-option(WITH_CYCLES_LOGGING "Build cycles with logging support" OFF)
-option(WITH_CYCLES_DEBUG "Build cycles with with extra debug capabilties" OFF)
+option(WITH_CYCLES_LOGGING "Build cycles with logging support" ON)
+option(WITH_CYCLES_DEBUG "Build cycles with extra debug capabilities" OFF)
mark_as_advanced(WITH_CYCLES_LOGGING)
mark_as_advanced(WITH_CYCLES_DEBUG)
@@ -307,7 +374,7 @@ endif()
mark_as_advanced(LLVM_STATIC)
# disable for now, but plan to support on all platforms eventually
-option(WITH_MEM_JEMALLOC "Enable malloc replacement (http://www.canonware.com/jemalloc)" OFF)
+option(WITH_MEM_JEMALLOC "Enable malloc replacement (http://www.canonware.com/jemalloc)" ON)
mark_as_advanced(WITH_MEM_JEMALLOC)
# currently only used for BLI_mempool
@@ -323,14 +390,16 @@ mark_as_advanced(WITH_ASSERT_ABORT)
option(WITH_BOOST "Enable features depending on boost" ON)
-if(CMAKE_COMPILER_IS_GNUCC)
- option(WITH_GCC_MUDFLAP "Enable mudflap" OFF)
- mark_as_advanced(WITH_GCC_MUDFLAP)
-endif()
-
# Unit testsing
option(WITH_GTESTS "Enable GTest unit testing" OFF)
+
+# Documentation
+if(UNIX AND NOT APPLE)
+ option(WITH_DOC_MANPAGE "Create a manual page (Unix manpage)" OFF)
+endif()
+
+
# OpenGL
option(WITH_GLEW_MX "Support multiple GLEW contexts (experimental)" OFF )
@@ -339,6 +408,7 @@ option(WITH_GL_EGL "Use the EGL OpenGL system library instead of th
option(WITH_GL_PROFILE_COMPAT "Support using the OpenGL 'compatibility' profile. (deprecated)" ON )
option(WITH_GL_PROFILE_CORE "Support using the OpenGL 3.2+ 'core' profile." OFF)
option(WITH_GL_PROFILE_ES20 "Support using OpenGL ES 2.0. (thru either EGL or the AGL/WGL/XGL 'es20' profile)" OFF)
+option(WITH_GPU_DEBUG "Create a debug OpenGL context (allows inserting custom messages and getting notifications for bad GL use)" OFF)
mark_as_advanced(
WITH_GLEW_MX
@@ -347,9 +417,10 @@ mark_as_advanced(
WITH_GL_PROFILE_COMPAT
WITH_GL_PROFILE_CORE
WITH_GL_PROFILE_ES20
+ WITH_GPU_DEBUG
)
-if (WITH_GL_PROFILE_COMPAT)
+if(WITH_GL_PROFILE_COMPAT)
set(WITH_GLU ON)
else()
set(WITH_GLU OFF)
@@ -365,6 +436,38 @@ if(WITH_GLEW_ES AND WITH_SYSTEM_GLEW)
set(WITH_SYSTEM_GLEW OFF)
endif()
+if(MSVC)
+ getDefaultWindowsPrefixBase(CMAKE_GENERIC_PROGRAM_FILES)
+ set(CPACK_INSTALL_PREFIX ${CMAKE_GENERIC_PROGRAM_FILES}/${})
+endif()
+
+# Experimental support of C++11
+option(WITH_CPP11 "Build with C++11 standard enabled, for development use only!" OFF)
+mark_as_advanced(WITH_CPP11)
+
+# avoid using again
+option_defaults_clear()
+
+# end option(...)
+
+
+
+# By default we want to install to the directory we are compiling our executables
+# unless specified otherwise, which we currently do not allow
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ if(MSVC)
+ set(CMAKE_INSTALL_PREFIX ${EXECUTABLE_OUTPUT_PATH}/\${BUILD_TYPE} CACHE PATH "default install path" FORCE)
+ elseif(APPLE)
+ set(CMAKE_INSTALL_PREFIX ${EXECUTABLE_OUTPUT_PATH}/\${BUILD_TYPE} CACHE PATH "default install path" FORCE)
+ else()
+ if(WITH_INSTALL_PORTABLE)
+ set(CMAKE_INSTALL_PREFIX ${EXECUTABLE_OUTPUT_PATH} CACHE PATH "default install path" FORCE)
+ endif()
+ endif()
+endif()
+
+
+
# Apple
if(APPLE)
@@ -517,7 +620,7 @@ if(NOT WITH_PYTHON)
set(WITH_CYCLES OFF)
endif()
-# enable boost for cycles, booleans, audaspace or i18n
+# enable boost for cycles, audaspace or i18n
# otherwise if the user disabled
if(NOT WITH_BOOST)
# Explicitly disabled. so disable all deps.
@@ -530,13 +633,12 @@ if(NOT WITH_BOOST)
endmacro()
set_and_warn(WITH_CYCLES OFF)
- set_and_warn(WITH_MOD_BOOLEAN OFF)
set_and_warn(WITH_AUDASPACE OFF)
set_and_warn(WITH_INTERNATIONAL OFF)
set_and_warn(WITH_OPENAL OFF) # depends on AUDASPACE
set_and_warn(WITH_GAMEENGINE OFF) # depends on AUDASPACE
-elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_MOD_BOOLEAN OR WITH_AUDASPACE OR WITH_INTERNATIONAL)
+elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_AUDASPACE OR WITH_INTERNATIONAL)
# Keep enabled
else()
# Enabled but we don't need it
@@ -556,7 +658,7 @@ endif()
# auto enable llvm for cycles_osl
if(WITH_CYCLES_OSL)
- set(WITH_LLVM ON CACHE BOOL "ON" FORCE)
+ set(WITH_LLVM ON CACHE BOOL "" FORCE)
endif()
# don't store paths to libs for portable distribution
@@ -687,7 +789,6 @@ endif()
if(UNIX AND NOT APPLE)
macro(find_package_wrapper)
- string(TOUPPER ${ARGV0} _NAME_UPPER)
if(WITH_STATIC_LIBS)
set(_cmake_find_library_suffixes_back ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
@@ -704,6 +805,13 @@ if(UNIX AND NOT APPLE)
find_package_wrapper(ZLIB REQUIRED)
find_package_wrapper(Freetype REQUIRED)
+ if(WITH_LZO AND WITH_SYSTEM_LZO)
+ find_package_wrapper(LZO)
+ if(NOT LZO_FOUND)
+ message(FATAL_ERROR "Failed finding system LZO version!")
+ endif()
+ endif()
+
if(WITH_PYTHON)
# No way to set py34. remove for now.
# find_package(PythonLibs)
@@ -747,16 +855,27 @@ if(UNIX AND NOT APPLE)
endif()
if(WITH_SDL)
- find_package_wrapper(SDL)
- mark_as_advanced(
- SDLMAIN_LIBRARY
- SDL_INCLUDE_DIR
- SDL_LIBRARY
- SDL_LIBRARY_TEMP
- )
- # unset(SDLMAIN_LIBRARY CACHE)
- if(NOT SDL_FOUND)
- set(WITH_SDL OFF)
+ if(WITH_SDL_DYNLOAD)
+ set(SDL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extern/sdlew/include/SDL2")
+ set(SDL_LIBRARY)
+ else()
+ find_package_wrapper(SDL2)
+ if(SDL2_FOUND)
+ # Use same names for both versions of SDL until we move to 2.x.
+ set(SDL_INCLUDE_DIR "${SDL2_INCLUDE_DIR}")
+ set(SDL_LIBRARY "${SDL2_LIBRARY}")
+ set(SDL_FOUND "${SDL2_FOUND}")
+ else()
+ find_package_wrapper(SDL)
+ endif()
+ mark_as_advanced(
+ SDL_INCLUDE_DIR
+ SDL_LIBRARY
+ )
+ # unset(SDLMAIN_LIBRARY CACHE)
+ if(NOT SDL_FOUND)
+ set(WITH_SDL OFF)
+ endif()
endif()
endif()
@@ -829,6 +948,24 @@ if(UNIX AND NOT APPLE)
endif()
endif()
+ if(WITH_CYCLES_OSL)
+ set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
+ if(NOT OSL_ROOT)
+ set(OSL_ROOT ${CYCLES_OSL})
+ endif()
+ find_package_wrapper(OpenShadingLanguage)
+ if(OSL_FOUND)
+ if(${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6")
+ # Note: --whole-archive is needed to force loading of all symbols in liboslexec,
+ # otherwise LLVM is missing the osl_allocate_closure_component function
+ set(OSL_LIBRARIES ${OSL_OSLCOMP_LIBRARY} -Wl,--whole-archive ${OSL_OSLEXEC_LIBRARY} -Wl,--no-whole-archive ${OSL_OSLQUERY_LIBRARY})
+ endif()
+ else()
+ message(STATUS "OSL not found, disabling it from Cycles")
+ set(WITH_CYCLES_OSL OFF)
+ endif()
+ endif()
+
if(WITH_BOOST)
# uses in build instructions to override include and library variables
if(NOT BOOST_CUSTOM)
@@ -837,6 +974,12 @@ if(UNIX AND NOT APPLE)
endif()
set(Boost_USE_MULTITHREADED ON)
set(__boost_packages filesystem regex system thread date_time)
+ if(WITH_CYCLES_OSL)
+ if(NOT (${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6"))
+ list(APPEND __boost_packages wave)
+ else()
+ endif()
+ endif()
if(WITH_INTERNATIONAL)
list(APPEND __boost_packages locale)
endif()
@@ -866,6 +1009,12 @@ if(UNIX AND NOT APPLE)
if(WITH_OPENIMAGEIO)
find_package_wrapper(OpenImageIO)
+ if(NOT OPENIMAGEIO_PUGIXML_FOUND AND WITH_CYCLES_STANDALONE)
+ find_package_wrapper(PugiXML)
+ else()
+ set(PUGIXML_INCLUDE_DIR "${OPENIMAGEIO_INCLUDE_DIR/OpenImageIO}")
+ set(PUGIXML_LIBRARIES "")
+ endif()
set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARIES} ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${ZLIB_LIBRARIES} ${BOOST_LIBRARIES})
set(OPENIMAGEIO_LIBPATH) # TODO, remove and reference the absolute path everywhere
@@ -899,18 +1048,18 @@ if(UNIX AND NOT APPLE)
# XXX Maybe most of this section should go into an llvm module?
if(WITH_LLVM)
- # Set llvm version if not specified
- if(NOT LLVM_VERSION)
- set(LLVM_VERSION "3.0")
- endif()
- if(LLVM_DIRECTORY)
- find_program(LLVM_CONFIG llvm-config-${LLVM_VERSION} HINTS ${LLVM_DIRECTORY}/bin NO_CMAKE_PATH)
+ if(LLVM_ROOT_DIR)
+ if(NOT DEFINED LLVM_VERSION)
+ find_program(LLVM_CONFIG llvm-config-${LLVM_VERSION} HINTS ${LLVM_ROOT_DIR}/bin NO_CMAKE_PATH)
+ endif()
if(NOT LLVM_CONFIG)
- find_program(LLVM_CONFIG llvm-config HINTS ${LLVM_DIRECTORY}/bin NO_CMAKE_PATH)
+ find_program(LLVM_CONFIG llvm-config HINTS ${LLVM_ROOT_DIR}/bin NO_CMAKE_PATH)
endif()
else()
- find_program(LLVM_CONFIG llvm-config-${LLVM_VERSION})
+ if(NOT DEFINED LLVM_VERSION)
+ find_program(LLVM_CONFIG llvm-config-${LLVM_VERSION})
+ endif()
if(NOT LLVM_CONFIG)
find_program(LLVM_CONFIG llvm-config)
endif()
@@ -922,11 +1071,11 @@ if(UNIX AND NOT APPLE)
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(LLVM_VERSION ${LLVM_VERSION} CACHE STRING "Version of LLVM to use")
endif()
- if(NOT DEFINED LLVM_DIRECTORY)
+ if(NOT DEFINED LLVM_ROOT_DIR)
execute_process(COMMAND ${LLVM_CONFIG} --prefix
- OUTPUT_VARIABLE LLVM_DIRECTORY
+ OUTPUT_VARIABLE LLVM_ROOT_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
- set(LLVM_DIRECTORY ${LLVM_DIRECTORY} CACHE PATH "Path to the LLVM installation")
+ set(LLVM_ROOT_DIR ${LLVM_ROOT_DIR} CACHE PATH "Path to the LLVM installation")
endif()
if(NOT DEFINED LLVM_LIBPATH)
execute_process(COMMAND ${LLVM_CONFIG} --libdir
@@ -947,7 +1096,7 @@ if(UNIX AND NOT APPLE)
endif()
- if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIBPATH)
+ if(LLVM_LIBRARY AND LLVM_ROOT_DIR AND LLVM_LIBPATH)
if(LLVM_STATIC)
# if static LLVM libraries were requested, use llvm-config to generate
# the list of what libraries we need, and substitute that in the right
@@ -961,36 +1110,24 @@ if(UNIX AND NOT APPLE)
message(FATAL_ERROR "LLVM not found.")
endif()
- # Fix for conflict with Mesa llvmpipe
- set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,--version-script=${CMAKE_SOURCE_DIR}/source/creator/blender.map")
endif()
- if(WITH_CYCLES_OSL)
- set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
-
- message(STATUS "CYCLES_OSL = ${CYCLES_OSL}")
-
- find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib)
- find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib)
- find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib)
- # Note: --whole-archive is needed to force loading of all symbols in liboslexec,
- # otherwise LLVM is missing the osl_allocate_closure_component function
- list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} -Wl,--whole-archive ${OSL_LIB_EXEC} -Wl,--no-whole-archive ${OSL_LIB_QUERY})
- find_path(OSL_INCLUDES OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
- find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
-
- if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER)
- set(OSL_FOUND TRUE)
- message(STATUS "OSL includes = ${OSL_INCLUDES}")
- message(STATUS "OSL library = ${OSL_LIBRARIES}")
- message(STATUS "OSL compiler = ${OSL_COMPILER}")
- else()
- message(STATUS "OSL not found")
- endif()
+ if(WITH_LLVM OR WITH_SDL_DYNLOAD)
+ # Fix for conflict with Mesa llvmpipe
+ set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,--version-script=${CMAKE_SOURCE_DIR}/source/creator/blender.map")
endif()
# OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed
- list(APPEND PLATFORM_LINKLIBS -lutil -lc -lm -lpthread)
+ list(APPEND PLATFORM_LINKLIBS -lutil -lc -lm)
+
+ find_package(Threads REQUIRED)
+ list(APPEND PLATFORM_LINKLIBS ${CMAKE_THREAD_LIBS_INIT})
+ # used by other platforms
+ set(PTHREADS_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
+
+ if(CMAKE_DL_LIBS)
+ list(APPEND PLATFORM_LINKLIBS ${CMAKE_DL_LIBS})
+ endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
if(NOT WITH_PYTHON_MODULE)
@@ -1000,11 +1137,6 @@ if(UNIX AND NOT APPLE)
endif()
endif()
- set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -pthread")
- if(CMAKE_DL_LIBS)
- list(APPEND PLATFORM_LINKLIBS ${CMAKE_DL_LIBS})
- endif()
-
# lfs on glibc, all compilers should use
add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
@@ -1052,7 +1184,11 @@ elseif(WIN32)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO")
- list(APPEND PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid psapi)
+ list(APPEND PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid psapi Dbghelp)
+
+ if(WITH_INPUT_IME)
+ list(APPEND PLATFORM_LINKLIBS imm32)
+ endif()
add_definitions(
-D_CRT_NONSTDC_NO_DEPRECATE
@@ -1063,18 +1199,16 @@ elseif(WIN32)
)
# MSVC11 needs _ALLOW_KEYWORD_MACROS to build
- if(NOT MSVC_VERSION VERSION_LESS 1700)
- add_definitions(-D_ALLOW_KEYWORD_MACROS)
- endif()
+ add_definitions(-D_ALLOW_KEYWORD_MACROS)
if(CMAKE_CL_64)
# We want to support Vista level ABI for x64
- if(NOT MSVC_VERSION VERSION_LESS 1700)
- add_definitions(-D_WIN32_WINNT=0x600)
- endif()
+ add_definitions(-D_WIN32_WINNT=0x600)
endif()
- add_definitions(-DOIIO_STATIC_BUILD)
+ # Make cmake find the msvc redistributables
+ set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
+ include(InstallRequiredSystemLibraries)
set(CMAKE_CXX_FLAGS "/nologo /J /Gd /EHsc /MP" CACHE STRING "MSVC MT C++ flags " FORCE)
set(CMAKE_C_FLAGS "/nologo /J /Gd /MP" CACHE STRING "MSVC MT C++ flags " FORCE)
@@ -1096,30 +1230,6 @@ elseif(WIN32)
set(CMAKE_C_FLAGS_MINSIZEREL "/O1 /Ob1 /MT /MP" CACHE STRING "MSVC MT flags " FORCE)
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/O2 /Ob1 /MT /Zi /MP" CACHE STRING "MSVC MT flags " FORCE)
- # most msvc warnings are C & C++
- set(_WARNINGS
- # warning level:
- "/W3"
- "/w34062" # switch statement contains 'default' but no 'case' labels
- # disable:
- "/wd4018" # signed/unsigned mismatch
- "/wd4065" # switch statement contains 'default' but no 'case' labels
- "/wd4127" # conditional expression is constant
- "/wd4181" # qualifier applied to reference type; ignored
- "/wd4200" # zero-sized array in struct/union
- "/wd4244" # conversion from 'type1' to 'type2', possible loss of data
- "/wd4267" # conversion from 'size_t' to 'type', possible loss of data
- "/wd4305" # truncation from 'type1' to 'type2'
- "/wd4800" # forcing value to bool 'true' or 'false'
- # errors:
- "/we4013" # 'function' undefined; assuming extern returning int
- "/we4431" # missing type specifier - int assumed
- )
-
- string(REPLACE ";" " " _WARNINGS "${_WARNINGS}")
- set(C_WARNINGS "${_WARNINGS}")
- set(CXX_WARNINGS "${_WARNINGS}")
- unset(_WARNINGS)
set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib")
@@ -1136,28 +1246,22 @@ elseif(WIN32)
# Setup 64bit and 64bit windows systems
if(CMAKE_CL_64)
message(STATUS "64 bit compiler detected.")
- set(LIBDIR_BASE ${CMAKE_SOURCE_DIR}/../lib/win64)
+ set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/win64_vc12)
else()
message(STATUS "32 bit compiler detected.")
- set(LIBDIR_BASE ${CMAKE_SOURCE_DIR}/../lib/windows)
- endif()
- if(MSVC12)
- message(STATUS "Visual C++ 2013 detected.")
- set(LIBDIR ${LIBDIR_BASE}_vc12)
- else()
- set(LIBDIR ${LIBDIR_BASE})
+ set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/windows_vc12)
endif()
else()
message(STATUS using LIBDIR ${LIBDIR})
endif()
# Add each of our libraries to our cmake_prefix_path so find_package() could work
- FILE(GLOB children RELATIVE ${LIBDIR} ${LIBDIR}/*)
- FOREACH(child ${children})
- IF(IS_DIRECTORY ${LIBDIR}/${child})
- LIST(APPEND CMAKE_PREFIX_PATH ${LIBDIR}/${child})
- ENDIF()
- ENDFOREACH()
+ file(GLOB children RELATIVE ${LIBDIR} ${LIBDIR}/*)
+ foreach(child ${children})
+ if(IS_DIRECTORY ${LIBDIR}/${child})
+ list(APPEND CMAKE_PREFIX_PATH ${LIBDIR}/${child})
+ endif()
+ endforeach()
set(ZLIB_INCLUDE_DIRS ${LIBDIR}/zlib/include)
set(ZLIB_LIBRARIES ${LIBDIR}/zlib/lib/libz_st.lib)
@@ -1169,8 +1273,8 @@ elseif(WIN32)
find_package(png)
if(NOT PNG_FOUND)
- set(PNG_PNG_INCLUDE_DIR ${LIBDIR}/png/include)
message(WARNING "Using HARDCODED libpng locations")
+ set(PNG_PNG_INCLUDE_DIR ${LIBDIR}/png/include)
set(PNG_LIBRARIES libpng)
set(PNG "${LIBDIR}/png")
set(PNG_INCLUDE_DIRS "${PNG}/include")
@@ -1257,29 +1361,19 @@ elseif(WIN32)
set(OPENEXR_VERSION "2.1")
find_package(OPENEXR REQUIRED)
if(NOT OPENEXR_FOUND)
- message(WARNING "Using HARDCODED OpenEXR locations")
- set(OPENEXR ${LIBDIR}/openexr)
- set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include)
- set(OPENEXR_INCLUDE_DIRS ${OPENEXR}/include/OpenEXR)
- set(OPENEXR_LIBPATH ${OPENEXR}/lib)
- if(MSVC12)
- set(OPENEXR_LIBRARIES
- ${OPENEXR_LIBPATH}/Iex-2_1.lib
- ${OPENEXR_LIBPATH}/Half.lib
- ${OPENEXR_LIBPATH}/IlmImf-2_1.lib
- ${OPENEXR_LIBPATH}/Imath-2_1.lib
- ${OPENEXR_LIBPATH}/IlmThread-2_1.lib
- )
- else()
+ message(WARNING "Using HARDCODED OpenEXR locations")
+ set(OPENEXR ${LIBDIR}/openexr)
+ set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include)
+ set(OPENEXR_INCLUDE_DIRS ${OPENEXR}/include/OpenEXR)
+ set(OPENEXR_LIBPATH ${OPENEXR}/lib)
set(OPENEXR_LIBRARIES
- ${OPENEXR_LIBPATH}/Iex.lib
+ ${OPENEXR_LIBPATH}/Iex-2_2.lib
${OPENEXR_LIBPATH}/Half.lib
- ${OPENEXR_LIBPATH}/IlmImf.lib
- ${OPENEXR_LIBPATH}/Imath.lib
- ${OPENEXR_LIBPATH}/IlmThread.lib
+ ${OPENEXR_LIBPATH}/IlmImf-2_2.lib
+ ${OPENEXR_LIBPATH}/Imath-2_2.lib
+ ${OPENEXR_LIBPATH}/IlmThread-2_2.lib
)
endif()
- endif(NOT OPENEXR_FOUND)
endif()
if(WITH_IMAGE_TIFF)
@@ -1319,15 +1413,15 @@ elseif(WIN32)
if(WITH_BOOST)
if(WITH_CYCLES_OSL)
set(boost_extra_libs wave)
- endif(WITH_CYCLES_OSL)
+ endif()
if(WITH_INTERNATIONAL)
list(APPEND boost_extra_libs locale)
- endif(WITH_INTERNATIONAL)
+ endif()
set(Boost_USE_STATIC_RUNTIME ON) # prefix lib
set(Boost_USE_MULTITHREADED ON) # suffix -mt
set(Boost_USE_STATIC_LIBS ON) # suffix -s
find_package(Boost COMPONENTS date_time filesystem thread regex system ${boost_extra_libs})
- IF(NOT Boost_FOUND)
+ if(NOT Boost_FOUND)
message(WARNING "USING HARDCODED boost locations")
set(BOOST ${LIBDIR}/boost)
set(BOOST_INCLUDE_DIR ${BOOST}/include)
@@ -1374,19 +1468,22 @@ elseif(WIN32)
set(OPENIMAGEIO_LIBRARIES ${OIIO_OPTIMIZED} ${OIIO_DEBUG})
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
set(OPENIMAGEIO_DEFINITIONS "-DUSE_TBB=0")
+ set(OPENCOLORIO_DEFINITIONS "-DOCIO_STATIC_BUILD")
+ set(OPENIMAGEIO_IDIFF "${OPENIMAGEIO}/bin/idiff.exe")
+ add_definitions(-DOIIO_STATIC_BUILD)
endif()
if(WITH_LLVM)
- set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
- file(GLOB LLVM_LIBRARY_OPTIMIZED ${LLVM_DIRECTORY}/lib/*.lib)
+ set(LLVM_ROOT_DIR ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
+ file(GLOB LLVM_LIBRARY_OPTIMIZED ${LLVM_ROOT_DIR}/lib/*.lib)
- if(EXISTS ${LLVM_DIRECTORY}/debug/lib)
+ if(EXISTS ${LLVM_ROOT_DIR}/debug/lib)
foreach(LLVM_OPTIMIZED_LIB ${LLVM_LIBRARY_OPTIMIZED})
get_filename_component(LIBNAME ${LLVM_OPTIMIZED_LIB} ABSOLUTE)
list(APPEND LLVM_LIBS optimized ${LIBNAME})
endforeach(LLVM_OPTIMIZED_LIB)
- file(GLOB LLVM_LIBRARY_DEBUG ${LLVM_DIRECTORY}/debug/lib/*.lib)
+ file(GLOB LLVM_LIBRARY_DEBUG ${LLVM_ROOT_DIR}/debug/lib/*.lib)
foreach(LLVM_DEBUG_LIB ${LLVM_LIBRARY_DEBUG})
get_filename_component(LIBNAME ${LLVM_DEBUG_LIB} ABSOLUTE)
@@ -1421,6 +1518,13 @@ elseif(WIN32)
)
endif()
+ if(WITH_SDL)
+ set(SDL ${LIBDIR}/sdl)
+ set(SDL_INCLUDE_DIR ${SDL}/include)
+ set(SDL_LIBRARY SDL2)
+ set(SDL_LIBPATH ${SDL}/lib)
+ endif()
+
# used in many places so include globally, like OpenGL
blender_include_dirs_sys("${PTHREADS_INCLUDE_DIRS}")
@@ -1438,7 +1542,12 @@ elseif(WIN32)
if(WITH_MINGW64)
message(STATUS "Compiling for 64 bit with MinGW-w64.")
- set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/mingw64)
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
+ if(GCC_VERSION VERSION_GREATER 4.9 OR GCC_VERSION VERSION_EQUAL 4.9)
+ set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/mingw64_gcc49)
+ else()
+ set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/mingw64)
+ endif()
else()
message(STATUS "Compiling for 32 bit with MinGW-w32.")
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/mingw32)
@@ -1448,7 +1557,12 @@ elseif(WIN32)
endif()
endif()
- list(APPEND PLATFORM_LINKLIBS -lshell32 -lshfolder -lgdi32 -lmsvcrt -lwinmm -lmingw32 -lm -lws2_32 -lz -lstdc++ -lole32 -luuid -lwsock32 -lpsapi)
+ list(APPEND PLATFORM_LINKLIBS -lshell32 -lshfolder -lgdi32 -lmsvcrt -lwinmm -lmingw32 -lm -lws2_32 -lz -lstdc++ -lole32 -luuid -lwsock32 -lpsapi -ldbghelp)
+
+ if(WITH_INPUT_IME)
+ list(APPEND PLATFORM_LINKLIBS -limm32)
+ endif()
+
set(PLATFORM_CFLAGS "-pipe -funsigned-char -fno-strict-aliasing")
if(WITH_MINGW64)
@@ -1602,11 +1716,12 @@ elseif(WIN32)
set(OPENIMAGEIO_LIBRARIES OpenImageIO)
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
set(OPENIMAGEIO_DEFINITIONS "")
+ set(OPENIMAGEIO_IDIFF "${OPENIMAGEIO}/bin/idiff.exe")
endif()
if(WITH_LLVM)
- set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
- set(LLVM_LIBPATH ${LLVM_DIRECTORY}/lib)
+ set(LLVM_ROOT_DIR ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
+ set(LLVM_LIBPATH ${LLVM_ROOT_DIR}/lib)
# Explicitly set llvm lib order.
#---- WARNING ON GCC ORDER OF LIBS IS IMPORTANT, DO NOT CHANGE! ---------
set(LLVM_LIBRARY LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMAnalysis LLVMArchive
@@ -1639,6 +1754,13 @@ elseif(WIN32)
set(OPENCOLORIO_DEFINITIONS)
endif()
+ if(WITH_SDL)
+ set(SDL ${LIBDIR}/sdl)
+ set(SDL_INCLUDE_DIR ${SDL}/include)
+ set(SDL_LIBRARY SDL)
+ set(SDL_LIBPATH ${SDL}/lib)
+ endif()
+
set(PLATFORM_LINKFLAGS "-Xlinker --stack=2097152")
## DISABLE - causes linking errors
@@ -1670,13 +1792,6 @@ elseif(WIN32)
set(SNDFILE_LIBPATH ${SNDFILE}/lib) # TODO, deprecate
endif()
- if(WITH_SDL)
- set(SDL ${LIBDIR}/sdl)
- set(SDL_INCLUDE_DIR ${SDL}/include)
- set(SDL_LIBRARY SDL)
- set(SDL_LIBPATH ${SDL}/lib)
- endif()
-
if(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD)
add_definitions(-D__SSE__ -D__MMX__)
endif()
@@ -1691,13 +1806,14 @@ elseif(WIN32)
find_library(OSL_LIB_COMP_DEBUG NAMES oslcomp_d PATHS ${CYCLES_OSL}/lib)
find_library(OSL_LIB_QUERY_DEBUG NAMES oslquery_d PATHS ${CYCLES_OSL}/lib)
list(APPEND OSL_LIBRARIES optimized ${OSL_LIB_COMP} optimized ${OSL_LIB_EXEC} optimized ${OSL_LIB_QUERY} debug ${OSL_LIB_EXEC_DEBUG} debug ${OSL_LIB_COMP_DEBUG} debug ${OSL_LIB_QUERY_DEBUG})
- find_path(OSL_INCLUDES OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
+ find_path(OSL_INCLUDE_DIR OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
- if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER)
+ if(OSL_INCLUDE_DIR AND OSL_LIBRARIES AND OSL_COMPILER)
set(OSL_FOUND TRUE)
else()
message(STATUS "OSL not found")
+ set(WITH_CYCLES_OSL OFF)
endif()
endif()
@@ -1881,8 +1997,9 @@ elseif(APPLE)
if(WITH_SDL)
set(SDL ${LIBDIR}/sdl)
set(SDL_INCLUDE_DIR ${SDL}/include)
- set(SDL_LIBRARY SDL)
+ set(SDL_LIBRARY SDL2)
set(SDL_LIBPATH ${SDL}/lib)
+ set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -lazy_framework ForceFeedback")
endif()
set(PNG "${LIBDIR}/png")
@@ -1928,6 +2045,7 @@ elseif(APPLE)
set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO}/lib/libOpenImageIO.a ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES})
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib ${JPEG_LIBPATH} ${PNG_LIBPATH} ${TIFF_LIBPATH} ${OPENEXR_LIBPATH} ${ZLIB_LIBPATH})
set(OPENIMAGEIO_DEFINITIONS "-DOIIO_STATIC_BUILD")
+ set(OPENIMAGEIO_IDIFF "${LIBDIR}/openimageio/bin/idiff")
endif()
if(WITH_OPENCOLORIO)
@@ -1935,14 +2053,13 @@ elseif(APPLE)
set(OPENCOLORIO_INCLUDE_DIRS ${OPENCOLORIO}/include)
set(OPENCOLORIO_LIBRARIES OpenColorIO tinyxml yaml-cpp)
set(OPENCOLORIO_LIBPATH ${OPENCOLORIO}/lib)
- set(OPENCOLORIO_DEFINITIONS "-DOCIO_STATIC_BUILD")
endif()
if(WITH_LLVM)
- set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
+ set(LLVM_ROOT_DIR ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
set(LLVM_VERSION "3.4" CACHE STRING "Version of LLVM to use")
- if(EXISTS "${LLVM_DIRECTORY}/bin/llvm-config")
- set(LLVM_CONFIG "${LLVM_DIRECTORY}/bin/llvm-config")
+ if(EXISTS "${LLVM_ROOT_DIR}/bin/llvm-config")
+ set(LLVM_CONFIG "${LLVM_ROOT_DIR}/bin/llvm-config")
else()
set(LLVM_CONFIG llvm-config)
endif()
@@ -1950,7 +2067,7 @@ elseif(APPLE)
OUTPUT_VARIABLE LLVM_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${LLVM_CONFIG} --prefix
- OUTPUT_VARIABLE LLVM_DIRECTORY
+ OUTPUT_VARIABLE LLVM_ROOT_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${LLVM_CONFIG} --libdir
OUTPUT_VARIABLE LLVM_LIBPATH
@@ -1959,7 +2076,7 @@ elseif(APPLE)
NAMES LLVMAnalysis # first of a whole bunch of libs to get
PATHS ${LLVM_LIBPATH})
- if(LLVM_LIBRARY AND LLVM_DIRECTORY AND LLVM_LIBPATH)
+ if(LLVM_LIBRARY AND LLVM_ROOT_DIR AND LLVM_LIBPATH)
if(LLVM_STATIC)
# if static LLVM libraries were requested, use llvm-config to generate
# the list of what libraries we need, and substitute that in the right
@@ -1984,13 +2101,14 @@ elseif(APPLE)
find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib)
# WARNING! depends on correct order of OSL libs linking
list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} -force_load ${OSL_LIB_EXEC} ${OSL_LIB_QUERY})
- find_path(OSL_INCLUDES OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
+ find_path(OSL_INCLUDE_DIR OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
- if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER)
+ if(OSL_INCLUDE_DIR AND OSL_LIBRARIES AND OSL_COMPILER)
set(OSL_FOUND TRUE)
else()
message(STATUS "OSL not found")
+ set(WITH_CYCLES_OSL OFF)
endif()
endif()
@@ -2009,7 +2127,7 @@ elseif(APPLE)
link_directories(${LIBDIR}/openmp/lib)
# This is a workaround for our helperbinaries ( datatoc, masgfmt, ... ),
# They are linked also to omp lib, so we need it in builddir for runtime exexcution, TODO: remove all unneeded dependencies from these
- execute_process(COMMAND ditto -arch ${CMAKE_OSX_ARCHITECTURES} ${LIBDIR}/openmp/lib/libiomp5.dylib ${CMAKE_BINARY_DIR}/bin/libiomp5.dylib) # for intermediate binaries, lib id @loader_path
+ execute_process(COMMAND ditto -arch ${CMAKE_OSX_ARCHITECTURES} ${LIBDIR}/openmp/lib/libiomp5.dylib ${CMAKE_BINARY_DIR}/Resources/lib/libiomp5.dylib) # for intermediate binaries, in respect to lib ID
endif()
endif()
endif()
@@ -2162,7 +2280,7 @@ elseif(WITH_GL_PROFILE_ES20)
list(APPEND BLENDER_GL_LIBRARIES "${OPENGLES_LIBRARY}")
- if (NOT OPENGLES_LIBRARY)
+ if(NOT OPENGLES_LIBRARY)
message(FATAL_ERROR "To compile WITH_GL_EGL you need to set OPENGLES_LIBRARY to the file path of an OpenGL ES 2.0 library.")
endif()
@@ -2188,7 +2306,7 @@ elseif(WITH_GL_PROFILE_ES20)
mark_as_advanced(D3DCOMPILER_DLL)
- if (D3DCOMPILER_DLL STREQUAL "")
+ if(D3DCOMPILER_DLL STREQUAL "")
message(FATAL_ERROR "To compile WITH_GL_ANGLE you need to set D3DCOMPILER_DLL to the file path of a copy of the DirectX redistributable DLL file: D3DCompiler_46.dll")
endif()
@@ -2214,7 +2332,7 @@ if(WITH_GL_EGL)
list(APPEND BLENDER_GL_LIBRARIES "${OPENGLES_LIBRARY}" "${OPENGLES_EGL_LIBRARY}")
- if (NOT OPENGLES_EGL_LIBRARY)
+ if(NOT OPENGLES_EGL_LIBRARY)
message(FATAL_ERROR "To compile WITH_GL_EGL you need to set OPENGLES_EGL_LIBRARY to the file path of an EGL library.")
endif()
@@ -2250,6 +2368,10 @@ if(WITH_GL_EGL)
list(APPEND GL_DEFINITIONS -DWITH_EGL)
endif()
+if(WITH_GPU_DEBUG)
+ list(APPEND GL_DEFINITIONS -DWITH_GPU_DEBUG)
+endif()
+
#-----------------------------------------------------------------------------
# Configure OpenMP.
if(WITH_OPENMP)
@@ -2525,7 +2647,31 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
# disable numbered, false positives
set(C_WARNINGS "${C_WARNINGS} -wd188,186,144,913,556")
set(CXX_WARNINGS "${CXX_WARNINGS} -wd188,186,144,913,556")
+elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC")
+ # most msvc warnings are C & C++
+ set(_WARNINGS
+ # warning level:
+ "/W3"
+ "/w34062" # switch statement contains 'default' but no 'case' labels
+ # disable:
+ "/wd4018" # signed/unsigned mismatch
+ "/wd4065" # switch statement contains 'default' but no 'case' labels
+ "/wd4127" # conditional expression is constant
+ "/wd4181" # qualifier applied to reference type; ignored
+ "/wd4200" # zero-sized array in struct/union
+ "/wd4244" # conversion from 'type1' to 'type2', possible loss of data
+ "/wd4267" # conversion from 'size_t' to 'type', possible loss of data
+ "/wd4305" # truncation from 'type1' to 'type2'
+ "/wd4800" # forcing value to bool 'true' or 'false'
+ # errors:
+ "/we4013" # 'function' undefined; assuming extern returning int
+ "/we4431" # missing type specifier - int assumed
+ )
+ string(REPLACE ";" " " _WARNINGS "${_WARNINGS}")
+ set(C_WARNINGS "${_WARNINGS}")
+ set(CXX_WARNINGS "${_WARNINGS}")
+ unset(_WARNINGS)
endif()
# ensure python header is found since detection can fail, this could happen
@@ -2552,11 +2698,14 @@ if(WITH_PYTHON)
endif()
endif()
-if(WITH_GCC_MUDFLAP)
- set(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -fmudflapth -funwind-tables")
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread -lmudflapth -rdynamic")
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_ERROR_MUDFLAP -Wno-error=mudflap)
- ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_ERROR_MUDFLAP -Wno-error=mudflap)
+if(WITH_CPP11)
+ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ elseif(MSVC12)
+ # Nothing special is needed, C++11 features are available by default.
+ else()
+ message(FATAL_ERROR "Compiler ${CMAKE_C_COMPILER_ID} is not supported for C++11 build yet")
+ endif()
endif()
# Include warnings first, so its possible to disable them with user defined flags
@@ -2571,12 +2720,12 @@ mark_as_advanced(
OSL_COMPILER
OSL_LIB_COMP
OSL_LIB_QUERY
- OSL_INCLUDES
+ OSL_INCLUDE_DIR
)
mark_as_advanced(
LLVM_CONFIG
- LLVM_DIRECTORY
+ LLVM_ROOT_DIR
LLVM_LIBRARY
LLVM_VERSION
)
@@ -2712,6 +2861,7 @@ if(FIRST_RUN)
info_cfg_text("Audio:")
info_cfg_option(WITH_OPENAL)
info_cfg_option(WITH_SDL)
+ info_cfg_option(WITH_SDL_DYNLOAD)
info_cfg_option(WITH_JACK)
info_cfg_option(WITH_JACK_DYNLOAD)
info_cfg_option(WITH_CODEC_AVI)
@@ -2744,6 +2894,7 @@ if(FIRST_RUN)
info_cfg_option(WITH_GL_PROFILE_COMPAT)
info_cfg_option(WITH_GL_PROFILE_CORE)
info_cfg_option(WITH_GL_PROFILE_ES20)
+ info_cfg_option(WITH_GPU_DEBUG)
if(WIN32)
info_cfg_option(WITH_GL_ANGLE)
endif()
@@ -2758,3 +2909,8 @@ if(FIRST_RUN)
message("${_config_msg}")
endif()
+
+if(0)
+ print_all_vars()
+endif()
+
diff --git a/GNUmakefile b/GNUmakefile
index fb38c8ae0f1..775d0ae532b 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -52,6 +52,10 @@ ifneq "$(findstring debug, $(MAKECMDGOALS))" ""
BUILD_DIR:=$(BUILD_DIR)_debug
BUILD_TYPE:=Debug
endif
+ifneq "$(findstring full, $(MAKECMDGOALS))" ""
+ BUILD_DIR:=$(BUILD_DIR)_full
+ BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/blender_full.cmake"
+endif
ifneq "$(findstring lite, $(MAKECMDGOALS))" ""
BUILD_DIR:=$(BUILD_DIR)_lite
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/blender_lite.cmake"
@@ -109,7 +113,7 @@ endif
# -----------------------------------------------------------------------------
# Build Blender
-all:
+all: FORCE
@echo
@echo Configuring Blender ...
@@ -129,6 +133,7 @@ all:
@echo
debug: all
+full: all
lite: all
cycles: all
headless: all
@@ -137,16 +142,17 @@ bpy: all
# -----------------------------------------------------------------------------
# Configuration (save some cd'ing around)
-config:
+config: FORCE
$(CMAKE_CONFIG_TOOL) "$(BUILD_DIR)"
# -----------------------------------------------------------------------------
# Help for build targets
-help:
+help: FORCE
@echo ""
@echo "Convenience targets provided for building blender, (multiple at once can be used)"
@echo " * debug - build a debug binary"
+ @echo " * full - enable all supported dependencies & options"
@echo " * lite - disable non essential features for a smaller binary and faster build"
@echo " * headless - build without an interface (renderfarm or server automation)"
@echo " * cycles - build Cycles standalone only, without Blender"
@@ -201,17 +207,20 @@ help:
@echo " * doc_dna - generate blender file format reference"
@echo " * doc_man - generate manpage"
@echo ""
+ @echo "Information"
+ @echo " * help - this help message"
+ @echo " * help_features - show a list of optional features when building"
# -----------------------------------------------------------------------------
# Packages
#
-package_debian:
+package_debian: FORCE
cd build_files/package_spec ; DEB_BUILD_OPTIONS="parallel=$(NPROCS)" sh ./build_debian.sh
-package_pacman:
+package_pacman: FORCE
cd build_files/package_spec/pacman ; MAKEFLAGS="-j$(NPROCS)" makepkg --asroot
-package_archive:
+package_archive: FORCE
make -C "$(BUILD_DIR)" -s package_archive
@echo archive in "$(BUILD_DIR)/release"
@@ -219,24 +228,24 @@ package_archive:
# -----------------------------------------------------------------------------
# Tests
#
-test:
+test: FORCE
cd $(BUILD_DIR) ; ctest . --output-on-failure
# run pep8 check check on scripts we distribute.
-test_pep8:
+test_pep8: FORCE
python3 tests/python/pep8.py > test_pep8.log 2>&1
@echo "written: test_pep8.log"
# run some checks on our cmakefiles.
-test_cmake:
+test_cmake: FORCE
python3 build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1
@echo "written: test_cmake_consistency.log"
# run deprecation tests, see if we have anything to remove.
-test_deprecated:
+test_deprecated: FORCE
python3 tests/check_deprecated.py
-test_style_c:
+test_style_c: FORCE
# run our own checks on C/C++ style
PYTHONIOENCODING=utf_8 python3 \
"$(BLENDER_DIR)/source/tools/check_source/check_style_c.py" \
@@ -244,7 +253,7 @@ test_style_c:
"$(BLENDER_DIR)/source/creator" \
--no-length-check
-test_style_c_qtc:
+test_style_c_qtc: FORCE
# run our own checks on C/C++ style
USE_QTC_TASK=1 \
PYTHONIOENCODING=utf_8 python3 \
@@ -257,7 +266,7 @@ test_style_c_qtc:
@echo "written: test_style.tasks"
-test_style_osl:
+test_style_osl: FORCE
# run our own checks on C/C++ style
PYTHONIOENCODING=utf_8 python3 \
"$(BLENDER_DIR)/source/tools/check_source/check_style_c.py" \
@@ -265,7 +274,7 @@ test_style_osl:
"$(BLENDER_DIR)/release/scripts/templates_osl"
-test_style_osl_qtc:
+test_style_osl_qtc: FORCE
# run our own checks on C/C++ style
USE_QTC_TASK=1 \
PYTHONIOENCODING=utf_8 python3 \
@@ -280,13 +289,13 @@ test_style_osl_qtc:
# Project Files
#
-project_qtcreator:
+project_qtcreator: FORCE
python3 build_files/cmake/cmake_qtcreator_project.py "$(BUILD_DIR)"
-project_netbeans:
+project_netbeans: FORCE
python3 build_files/cmake/cmake_netbeans_project.py "$(BUILD_DIR)"
-project_eclipse:
+project_eclipse: FORCE
cmake -G"Eclipse CDT4 - Unix Makefiles" -H"$(BLENDER_DIR)" -B"$(BUILD_DIR)"
@@ -294,40 +303,40 @@ project_eclipse:
# Static Checking
#
-check_cppcheck:
+check_cppcheck: FORCE
$(CMAKE_CONFIG)
cd "$(BUILD_DIR)" ; \
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py" 2> \
"$(BLENDER_DIR)/check_cppcheck.txt"
@echo "written: check_cppcheck.txt"
-check_clang_array:
+check_clang_array: FORCE
$(CMAKE_CONFIG)
cd "$(BUILD_DIR)" ; \
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py"
-check_splint:
+check_splint: FORCE
$(CMAKE_CONFIG)
cd "$(BUILD_DIR)" ; \
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py"
-check_sparse:
+check_sparse: FORCE
$(CMAKE_CONFIG)
cd "$(BUILD_DIR)" ; \
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py"
-check_smatch:
+check_smatch: FORCE
$(CMAKE_CONFIG)
cd "$(BUILD_DIR)" ; \
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py"
-check_spelling_py:
+check_spelling_py: FORCE
cd "$(BUILD_DIR)" ; \
PYTHONIOENCODING=utf_8 python3 \
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
"$(BLENDER_DIR)/release/scripts"
-check_spelling_c:
+check_spelling_c: FORCE
cd "$(BUILD_DIR)" ; \
PYTHONIOENCODING=utf_8 python3 \
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
@@ -336,7 +345,7 @@ check_spelling_c:
"$(BLENDER_DIR)/intern/guardedalloc" \
"$(BLENDER_DIR)/intern/ghost" \
-check_spelling_c_qtc:
+check_spelling_c_qtc: FORCE
cd "$(BUILD_DIR)" ; USE_QTC_TASK=1 \
PYTHONIOENCODING=utf_8 python3 \
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
@@ -347,13 +356,13 @@ check_spelling_c_qtc:
> \
"$(BLENDER_DIR)/check_spelling_c.tasks"
-check_spelling_osl:
+check_spelling_osl: FORCE
cd "$(BUILD_DIR)" ;\
PYTHONIOENCODING=utf_8 python3 \
"$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" \
"$(BLENDER_DIR)/intern/cycles/kernel/shaders"
-check_descriptions:
+check_descriptions: FORCE
"$(BUILD_DIR)/bin/blender" --background -noaudio --factory-startup --python \
"$(BLENDER_DIR)/source/tools/check_source/check_descriptions.py"
@@ -361,14 +370,14 @@ check_descriptions:
# Utilities
#
-tgz:
+tgz: FORCE
./build_files/utils/build_tgz.sh
-icons:
+icons: FORCE
"$(BLENDER_DIR)/release/datafiles/blender_icons_update.py"
"$(BLENDER_DIR)/release/datafiles/prvicons_update.py"
-update:
+update: FORCE
if [ -d "../lib" ]; then \
svn update ../lib/* ; \
fi
@@ -381,24 +390,36 @@ update:
#
# Simple version of ./doc/python_api/sphinx_doc_gen.sh with no PDF generation.
-doc_py:
+doc_py: FORCE
"$(BUILD_DIR)/bin/blender" --background -noaudio --factory-startup --python doc/python_api/sphinx_doc_gen.py
cd doc/python_api ; sphinx-build -b html sphinx-in sphinx-out
@echo "docs written into: '$(BLENDER_DIR)/doc/python_api/sphinx-out/contents.html'"
-doc_doxy:
+doc_doxy: FORCE
cd doc/doxygen; doxygen Doxyfile
@echo "docs written into: '$(BLENDER_DIR)/doc/doxygen/html/index.html'"
-doc_dna:
+doc_dna: FORCE
"$(BUILD_DIR)/bin/blender" --background -noaudio --factory-startup --python doc/blender_file_format/BlendFileDnaExporter_25.py
@echo "docs written into: '$(BLENDER_DIR)/doc/blender_file_format/dna.html'"
-doc_man:
+doc_man: FORCE
python3 doc/manpage/blender.1.py "$(BUILD_DIR)/bin/blender"
+help_features: FORCE
+ @python3 -c \
+ "import re; \
+ print('\n'.join([ \
+ w for l in open('"$(BLENDER_DIR)"/CMakeLists.txt', 'r').readlines() \
+ if not l.lstrip().startswith('#') \
+ for w in (re.sub(\
+ r'.*\boption\s*\(\s*(WITH_[a-zA-Z0-9_]+)\s+(\".*\")\s*.*', r'\g<1> - \g<2>', l).strip('() \n'),) \
+ if w.startswith('WITH_')]))" | uniq
+
-clean:
+clean: FORCE
$(MAKE) -C "$(BUILD_DIR)" clean
.PHONY: all
+
+FORCE:
diff --git a/SConstruct b/SConstruct
index 50fad5acbd3..a151d493a73 100644
--- a/SConstruct
+++ b/SConstruct
@@ -218,6 +218,8 @@ else:
if not env['BF_FANCY']:
B.bc.disable()
+if env['WITH_BF_SDL_DYNLOAD']:
+ env['BF_SDL_INC'] = '#extern/sdlew/include/SDL2'
# remove install dir so old and new files are not mixed.
# NOTE: only do the scripts directory for now, otherwise is too disruptive for developers
@@ -265,6 +267,7 @@ if 'blenderlite' in B.targets:
target_env_defs['WITH_BF_BOOLEAN'] = False
target_env_defs['WITH_BF_REMESH'] = False
target_env_defs['WITH_BF_PYTHON'] = False
+ target_env_defs['WITH_BF_IME'] = False
target_env_defs['WITH_BF_3DMOUSE'] = False
target_env_defs['WITH_BF_LIBMV'] = False
target_env_defs['WITH_BF_FREESTYLE'] = False
@@ -421,6 +424,9 @@ if env['OURPLATFORM']=='darwin':
env.Append(LINKFLAGS=['-F/Library/Frameworks','-Xlinker','-weak_framework','-Xlinker','Jackmp'])
print B.bc.OKGREEN + "Using Jack"
+ if env['WITH_BF_SDL']:
+ env.Append(LINKFLAGS=['-lazy_framework','ForceFeedback'])
+
if env['WITH_BF_QUICKTIME'] == 1:
env['PLATFORM_LINKFLAGS'] = env['PLATFORM_LINKFLAGS']+['-framework','QTKit']
@@ -475,6 +481,13 @@ if env['WITH_BF_OPENMP'] == 1:
else:
env.Append(CCFLAGS=['-fopenmp'])
+if env['WITH_BF_CPP11']:
+ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+ # Nothing special is needed, C++11 features are available by default.
+ pass
+ else:
+ env['CXXFLAGS'].append('-std=c++11')
+
#check for additional debug libnames
if env.has_key('BF_DEBUG_LIBS'):
@@ -753,8 +766,15 @@ if B.targets != ['cudakernels']:
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex_world.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_lib.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_vert.glsl")
data_to_c_simple("intern/opencolorio/gpu_shader_display_transform.glsl")
# --- blender ---
@@ -856,9 +876,11 @@ if B.targets != ['cudakernels']:
from FindUnorderedMap import FindUnorderedMap
conf = Configure(env)
+ old_linkflags = conf.env['LINKFLAGS']
conf.env.Append(LINKFLAGS=env['PLATFORM_LINKFLAGS'])
FindSharedPtr(conf)
FindUnorderedMap(conf)
+ conf.env['LINKFLAGS'] = old_linkflags
env = conf.Finish()
# End of auto configuration
@@ -1002,6 +1024,7 @@ if env['OURPLATFORM']!='darwin':
source.append('intern/cycles/util/util_color.h')
source.append('intern/cycles/util/util_half.h')
source.append('intern/cycles/util/util_math.h')
+ source.append('intern/cycles/util/util_math_fast.h')
source.append('intern/cycles/util/util_transform.h')
source.append('intern/cycles/util/util_types.h')
scriptinstall.append(env.Install(dir=dir,source=source))
@@ -1152,9 +1175,37 @@ if env['OURPLATFORM']=='linuxcross':
textlist = []
texttargetlist = []
for tp, tn, tf in os.walk('release/text'):
+ tf.remove("readme.html")
for f in tf:
textlist.append(tp+os.sep+f)
+def readme_version_patch():
+ readme_src = "release/text/readme.html"
+ readme_dst = os.path.abspath(os.path.normpath(os.path.join(env['BF_BUILDDIR'], "readme.html")))
+
+ if not os.path.exists(readme_dst) or (os.path.getmtime(readme_dst) < os.path.getmtime(readme_src)):
+ f = open(readme_src, "r")
+ data = f.read()
+ f.close()
+
+ data = data.replace("BLENDER_VERSION", VERSION)
+ f = open(readme_dst, "w")
+ f.write(data)
+ f.close()
+
+ textlist.append(readme_dst)
+
+readme_version_patch()
+del readme_version_patch
+
+
+'''Command(
+ "release/text/readme.html"
+
+ )
+Command("file.out", "file.in", Copy(env['BF_INSTALLDIR'], "release/text/readme.html"))
+'''
+
# Font licenses
textlist.append('release/datafiles/LICENSE-bfont.ttf.txt')
if env['WITH_BF_INTERNATIONAL']:
@@ -1181,7 +1232,7 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
dllsources += ['${BF_PTHREADS_LIBPATH}/${BF_PTHREADS_LIB}.dll']
if env['WITH_BF_SDL']:
- dllsources.append('${BF_SDL_LIBPATH}/SDL.dll')
+ dllsources.append('${BF_SDL_LIBPATH}/SDL2.dll')
if env['WITH_BF_PYTHON']:
if env['BF_DEBUG']:
@@ -1200,7 +1251,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
if env['WITH_BF_OPENAL']:
dllsources.append('${LCGDIR}/openal/lib/OpenAL32.dll')
- dllsources.append('${LCGDIR}/openal/lib/wrap_oal.dll')
if env['WITH_BF_SNDFILE']:
dllsources.append('${LCGDIR}/sndfile/lib/libsndfile-1.dll')
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 66eecd4d4cd..1c78858ac59 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -209,14 +209,14 @@ OCIO_VERSION_MIN="1.0"
OCIO_FORCE_REBUILD=false
OCIO_SKIP=false
-OPENEXR_VERSION="2.1.0"
+OPENEXR_VERSION="2.2.0"
OPENEXR_VERSION_MIN="2.0.1"
-ILMBASE_VERSION="2.1.0"
+ILMBASE_VERSION="2.2.0"
OPENEXR_FORCE_REBUILD=false
OPENEXR_SKIP=false
_with_built_openexr=false
-OIIO_VERSION="1.4.11"
+OIIO_VERSION="1.4.16"
OIIO_VERSION_MIN="1.4.0"
OIIO_FORCE_REBUILD=false
OIIO_SKIP=false
@@ -228,7 +228,7 @@ LLVM_FORCE_REBUILD=false
LLVM_SKIP=false
# OSL needs to be compiled for now!
-OSL_VERSION="1.5.0"
+OSL_VERSION="1.5.11"
OSL_VERSION_MIN=$OSL_VERSION
OSL_FORCE_REBUILD=false
OSL_SKIP=false
@@ -485,21 +485,29 @@ BOOST_SOURCE=( "http://sourceforge.net/projects/boost/files/boost/$BOOST_VERSION
OCIO_SOURCE=( "https://github.com/imageworks/OpenColorIO/tarball/v$OCIO_VERSION" )
-#OPENEXR_SOURCE=( "http://download.savannah.nongnu.org/releases/openexr/openexr-$OPENEXR_VERSION.tar.gz" )
-OPENEXR_SOURCE=( "https://github.com/mont29/openexr.git" )
-OPENEXR_REPO_UID="2787aa1cf652d244ed45ae124eb1553f6cff11ee"
+OPENEXR_USE_REPO=false
+OPENEXR_SOURCE=( "http://download.savannah.nongnu.org/releases/openexr/openexr-$OPENEXR_VERSION.tar.gz" )
+OPENEXR_SOURCE_REPO=( "https://github.com/mont29/openexr.git" )
+OPENEXR_SOURCE_REPO_UID="2787aa1cf652d244ed45ae124eb1553f6cff11ee"
ILMBASE_SOURCE=( "http://download.savannah.nongnu.org/releases/openexr/ilmbase-$ILMBASE_VERSION.tar.gz" )
-#OIIO_SOURCE=( "https://github.com/OpenImageIO/oiio/archive/Release-$OIIO_VERSION.tar.gz" )
-OIIO_SOURCE=( "https://github.com/OpenImageIO/oiio.git" )
-OIIO_REPO_UID="c9e67275a0b248ead96152f6d2221cc0c0f278a4"
+OIIO_USE_REPO=false
+OIIO_SOURCE=( "https://github.com/OpenImageIO/oiio/archive/Release-$OIIO_VERSION.tar.gz" )
+OIIO_SOURCE_REPO=( "https://github.com/OpenImageIO/oiio.git" )
+OIIO_SOURCE_REPO_UID="c9e67275a0b248ead96152f6d2221cc0c0f278a4"
LLVM_SOURCE=( "http://llvm.org/releases/$LLVM_VERSION/llvm-$LLVM_VERSION.src.tar.gz" )
LLVM_CLANG_SOURCE=( "http://llvm.org/releases/$LLVM_VERSION/clang-$LLVM_VERSION.src.tar.gz" "http://llvm.org/releases/$LLVM_VERSION/cfe-$LLVM_VERSION.src.tar.gz" )
-#OSL_SOURCE=( "https://github.com/imageworks/OpenShadingLanguage/archive/Release-$OSL_VERSION.tar.gz" )
-#OSL_SOURCE=( "https://github.com/imageworks/OpenShadingLanguage.git" )
-OSL_SOURCE=( "https://github.com/mont29/OpenShadingLanguage.git" )
-OSL_REPO_UID="85179714e1bc69cd25ecb6bb711c1a156685d395"
+OSL_USE_REPO=true
+#~ OSL_SOURCE=( "https://github.com/imageworks/OpenShadingLanguage/archive/Release-$OSL_VERSION.tar.gz" )
+OSL_SOURCE=( "https://github.com/Nazg-Gul/OpenShadingLanguage/archive/Release-1.5.11.tar.gz" )
+#~ OSL_SOURCE_REPO=( "https://github.com/imageworks/OpenShadingLanguage.git" )
+#~ OSL_SOURCE_REPO=( "https://github.com/mont29/OpenShadingLanguage.git" )
+#~ OSL_SOURCE_REPO_UID="85179714e1bc69cd25ecb6bb711c1a156685d395"
+#~ OSL_SOURCE_REPO_BRANCH="master"
+OSL_SOURCE_REPO=( "https://github.com/Nazg-Gul/OpenShadingLanguage.git" )
+OSL_SOURCE_REPO_UID="22ee5ea298fd215430dfbd160b5aefd507f06db0"
+OSL_SOURCE_REPO_BRANCH="blender-fixes"
OPENCOLLADA_SOURCE=( "https://github.com/KhronosGroup/OpenCOLLADA.git" )
OPENCOLLADA_REPO_UID="18da7f4109a8eafaa290a33f5550501cc4c8bae8"
@@ -975,7 +983,7 @@ clean_ILMBASE() {
compile_ILMBASE() {
# To be changed each time we make edits that would modify the compiled result!
- ilmbase_magic=9
+ ilmbase_magic=10
_init_ilmbase
# Clean install if needed!
@@ -999,8 +1007,7 @@ compile_ILMBASE() {
download ILMBASE_SOURCE[@] $_src.tar.gz
INFO "Unpacking ILMBase-$ILMBASE_VERSION"
- tar -C $SRC --transform "s,(.*/?)ilmbase-[^/]*(.*),\1ILMBase-$ILMBASE_VERSION\2,x" \
- -xf $_src.tar.gz
+ tar -C $SRC --transform "s,(.*/?)ilmbase-[^/]*(.*),\1ILMBase-$ILMBASE_VERSION\2,x" -xf $_src.tar.gz
fi
@@ -1016,6 +1023,7 @@ compile_ILMBASE() {
cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst"
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D BUILD_SHARED_LIBS=ON"
+ cmake_d="$cmake_d -D NAMESPACE_VERSIONING=OFF" # VERY IMPORTANT!!!
if file /bin/cp | grep -q '32-bit'; then
cflags="-fPIC -m32 -march=i686"
@@ -1088,24 +1096,28 @@ compile_OPENEXR() {
INFO "Downloading OpenEXR-$OPENEXR_VERSION"
mkdir -p $SRC
-# download OPENEXR_SOURCE[@] $_src.tar.gz
-
-# INFO "Unpacking OpenEXR-$OPENEXR_VERSION"
-# tar -C $SRC --transform "s,(.*/?)openexr[^/]*(.*),\1OpenEXR-$OPENEXR_VERSION\2,x" \
-# -xf $_src.tar.gz
-
- git clone ${OPENEXR_SOURCE[0]} $_src
+ if [ $OPENEXR_USE_REPO == true ]; then
+ git clone ${OPENEXR_SOURCE_REPO[0]} $_src
+ else
+ download OPENEXR_SOURCE[@] $_src.tar.gz
+ INFO "Unpacking OpenEXR-$OPENEXR_VERSION"
+ tar -C $SRC --transform "s,(.*/?)openexr[^/]*(.*),\1OpenEXR-$OPENEXR_VERSION\2,x" -xf $_src.tar.gz
+ fi
fi
cd $_src
- # XXX For now, always update from latest repo...
- git pull origin master
-
- # Stick to same rev as windows' libs...
- git checkout $OPENEXR_REPO_UID
- git reset --hard
+ if [ $OPENEXR_USE_REPO == true ]; then
+ # XXX For now, always update from latest repo...
+ git pull origin master
+ # Stick to same rev as windows' libs...
+ git checkout $OPENEXR_SOURCE_REPO_UID
+ git reset --hard
+ oiio_src_path="../OpenEXR"
+ else
+ oiio_src_path=".."
+ fi
# Always refresh the whole build!
if [ -d build ]; then
@@ -1119,6 +1131,7 @@ compile_OPENEXR() {
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D ILMBASE_PACKAGE_PREFIX=$_ilmbase_inst"
cmake_d="$cmake_d -D BUILD_SHARED_LIBS=ON"
+ cmake_d="$cmake_d -D NAMESPACE_VERSIONING=OFF" # VERY IMPORTANT!!!
if file /bin/cp | grep -q '32-bit'; then
cflags="-fPIC -m32 -march=i686"
@@ -1126,7 +1139,7 @@ compile_OPENEXR() {
cflags="-fPIC"
fi
- cmake $cmake_d -D CMAKE_CXX_FLAGS="$cflags" -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" ../OpenEXR
+ cmake $cmake_d -D CMAKE_CXX_FLAGS="$cflags" -D CMAKE_EXE_LINKER_FLAGS="-lgcc_s -lgcc" $oiio_src_path
make -j$THREADS && make install
@@ -1190,24 +1203,25 @@ compile_OIIO() {
if [ ! -d $_src ]; then
mkdir -p $SRC
- #download OIIO_SOURCE[@] "$_src.tar.gz"
-#
- #INFO "Unpacking OpenImageIO-$OIIO_VERSION"
- #tar -C $SRC --transform "s,(.*/?)oiio-Release-[^/]*(.*),\1OpenImageIO-$OIIO_VERSION\2,x" \
- #-xf $_src.tar.gz
-
- git clone ${OIIO_SOURCE[0]} $_src
+ if [ $OIIO_USE_REPO == true ]; then
+ git clone ${OIIO_SOURCE_REPO[0]} $_src
+ else
+ download OIIO_SOURCE[@] "$_src.tar.gz"
+ INFO "Unpacking OpenImageIO-$OIIO_VERSION"
+ tar -C $SRC --transform "s,(.*/?)oiio-Release-[^/]*(.*),\1OpenImageIO-$OIIO_VERSION\2,x" -xf $_src.tar.gz
+ fi
fi
cd $_src
- # XXX For now, always update from latest repo...
- git pull origin master
-
- # Stick to same rev as windows' libs...
- git checkout $OIIO_REPO_UID
- git reset --hard
+ if [ $OIIO_USE_REPO == true ]; then
+ # XXX For now, always update from latest repo...
+ git pull origin master
+ # Stick to same rev as windows' libs...
+ git checkout $OIIO_SOURCE_REPO_UID
+ git reset --hard
+ fi
# Always refresh the whole build!
if [ -d build ]; then
@@ -1229,6 +1243,7 @@ compile_OIIO() {
if [ $_with_built_openexr == true ]; then
cmake_d="$cmake_d -D ILMBASE_HOME=$INST/openexr"
cmake_d="$cmake_d -D OPENEXR_HOME=$INST/openexr"
+ INFO "ILMBASE_HOME=$INST/openexr"
fi
# Optional tests and cmd tools
@@ -1405,14 +1420,15 @@ clean_OSL() {
compile_OSL() {
# To be changed each time we make edits that would modify the compiled result!
- osl_magic=15
+ osl_magic=17
_init_osl
# Clean install if needed!
magic_compile_check osl-$OSL_VERSION $osl_magic
- if [ $? -eq 1 -o $OSL_FORCE_REBUILD == true ]; then
- clean_OSL
- fi
+ #~ if [ $? -eq 1 -o $OSL_FORCE_REBUILD == true ]; then
+ #~ rm -Rf $_src # XXX Radical, but not easy to change remote repo fully automatically
+ #~ clean_OSL
+ #~ fi
if [ ! -d $_inst ]; then
INFO "Building OpenShadingLanguage-$OSL_VERSION"
@@ -1422,26 +1438,26 @@ compile_OSL() {
if [ ! -d $_src ]; then
mkdir -p $SRC
- #download OSL_SOURCE[@] "$_src.tar.gz"
-
- #INFO "Unpacking OpenShadingLanguage-$OSL_VERSION"
- #tar -C $SRC --transform "s,(.*/?)OpenShadingLanguage-[^/]*(.*),\1OpenShadingLanguage-$OSL_VERSION\2,x" \
- #-xf $_src.tar.gz
-
- git clone ${OSL_SOURCE[0]} $_src
-
+ if [ $OSL_USE_REPO == true ]; then
+ git clone ${OSL_SOURCE_REPO[0]} $_src
+ else
+ download OSL_SOURCE[@] "$_src.tar.gz"
+ INFO "Unpacking OpenShadingLanguage-$OSL_VERSION"
+ tar -C $SRC --transform "s,(.*/?)OpenShadingLanguage-[^/]*(.*),\1OpenShadingLanguage-$OSL_VERSION\2,x" \
+ -xf $_src.tar.gz
+ fi
fi
cd $_src
- git remote set-url origin $OSL_SOURCE
-
- # XXX For now, always update from latest repo...
- git pull -X theirs origin master
-
- # Stick to same rev as windows' libs...
- git checkout $OSL_REPO_UID
- git reset --hard
+ if [ $OSL_USE_REPO == true ]; then
+ git remote set-url origin ${OSL_SOURCE_REPO[0]}
+ # XXX For now, always update from latest repo...
+ git pull --no-edit -X theirs origin $OSL_SOURCE_REPO_BRANCH
+ # Stick to same rev as windows' libs...
+ git checkout $OSL_SOURCE_REPO_UID
+ git reset --hard
+ fi
# Always refresh the whole build!
if [ -d build ]; then
@@ -1456,11 +1472,14 @@ compile_OSL() {
cmake_d="$cmake_d -D STOP_ON_WARNING=OFF"
cmake_d="$cmake_d -D BUILDSTATIC=OFF"
- cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
+ #~ cmake_d="$cmake_d -D ILMBASE_VERSION=$ILMBASE_VERSION"
if [ $_with_built_openexr == true ]; then
INFO "ILMBASE_HOME=$INST/openexr"
cmake_d="$cmake_d -D ILMBASE_HOME=$INST/openexr"
+ # XXX Temp workaround... sigh, ILMBase really messed the things up by defining their custom names ON by default :(
+ cmake_d="$cmake_d -D ILMBASE_CUSTOM=ON"
+ cmake_d="$cmake_d -D ILMBASE_CUSTOM_LIBRARIES='Half;Iex;Imath;IlmThread'"
fi
if [ -d $INST/boost ]; then
@@ -1474,7 +1493,7 @@ compile_OSL() {
if [ ! -z $LLVM_VERSION_FOUND ]; then
cmake_d="$cmake_d -D LLVM_VERSION=$LLVM_VERSION_FOUND"
if [ -d $INST/llvm ]; then
- cmake_d="$cmake_d -D LLVM_DIRECTORY=$INST/llvm"
+ cmake_d="$cmake_d -D LLVM_ROOT_DIR=$INST/llvm"
cmake_d="$cmake_d -D LLVM_STATIC=ON"
fi
fi
@@ -1973,7 +1992,7 @@ install_DEB() {
if [ $? -eq 0 ]; then
install_packages_DEB libboost-locale$boost_version-dev libboost-filesystem$boost_version-dev \
libboost-regex$boost_version-dev libboost-system$boost_version-dev \
- libboost-thread$boost_version-dev
+ libboost-thread$boost_version-dev libboost-wave$boost_version-dev
clean_Boost
else
compile_Boost
@@ -2978,7 +2997,7 @@ print_info() {
_buildargs="$_buildargs $_1"
fi
if [ -d $INST/llvm ]; then
- _1="-D LLVM_DIRECTORY=$INST/llvm"
+ _1="-D LLVM_ROOT_DIR=$INST/llvm"
_2="-D LLVM_STATIC=ON"
PRINT " $_1"
PRINT " $_2"
@@ -3034,10 +3053,10 @@ print_info() {
PRINT "BF_OPENEXR = '$INST/openexr'"
_ilm_libs_ext=""
- version_ge $OPENEXR_VERSION "2.1.0"
- if [ $? -eq 0 ]; then
- _ilm_libs_ext=`echo $OPENEXR_VERSION | sed -r 's/([0-9]+)\.([0-9]+).*/-\1_\2/'`
- fi
+ #~ version_ge $OPENEXR_VERSION "2.1.0"
+ #~ if [ $? -eq 0 ]; then
+ #~ _ilm_libs_ext=`echo $OPENEXR_VERSION | sed -r 's/([0-9]+)\.([0-9]+).*/-\1_\2/'`
+ #~ fi
PRINT "BF_OPENEXR_LIB = 'Half IlmImf$_ilm_libs_ext Iex$_ilm_libs_ext Imath$_ilm_libs_ext '"
# BF_OPENEXR_LIB does not work, things like '-lIlmImf-2_1' do not suit ld.
# For now, hack around!!!
diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
index 854f535398b..ae5cbac8cc7 100644
--- a/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-cuda-glibc211-i686.py
@@ -2,4 +2,4 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-i686'
BF_INSTALLDIR = '../blender-install/linux-glibc211-i686'
BF_NUMJOBS = 1
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50', 'sm_52']
diff --git a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
index 7e928948762..29b1b9f1ad7 100644
--- a/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-cuda-glibc211-x86_64.py
@@ -2,4 +2,4 @@ BF_BUILDDIR = '../blender-build/linux-glibc211-x86_64'
BF_INSTALLDIR = '../blender-install/linux-glibc211-x86_64'
BF_NUMJOBS = 1
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50', 'sm_52']
diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py
index 0971735f641..06c43be32f2 100644
--- a/build_files/buildbot/config/user-config-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-glibc211-i686.py
@@ -79,6 +79,8 @@ WITH_BF_STATICZLIB = True
BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
WITH_BF_SDL = True
+WITH_BF_SDL_DYNLOAD = True
+
WITH_BF_OGG = True
WITH_BF_OPENMP = True
@@ -122,13 +124,15 @@ BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_JPEG}/lib/libjpeg.a'
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
+BF_IS_NEW_OSL = False
WITH_BF_CYCLES_OSL = True
-WITH_BF_STATICOSL = False
+WITH_BF_STATICOSL = BF_IS_NEW_OSL
BF_OSL = '/opt/lib/osl'
BF_OSL_INC = '${BF_OSL}/include'
# note oslexec would passed via program linkflags, which is needed to
# make llvm happy with osl_allocate_closure_component
BF_OSL_LIB = 'oslcomp oslexec oslquery'
+BF_OSL_LIB_STATIC = '${BF_OSL}/lib/liboslcomp.a ${BF_OSL}/lib/liboslexec.a ${BF_OSL}/lib/liboslquery.a'
BF_OSL_LIBPATH = '${BF_OSL}/lib'
BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
@@ -155,6 +159,8 @@ BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
'${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a \
${BF_BOOST_LIBPATH}/libboost_thread.a'
+if BF_IS_NEW_OSL:
+ BF_BOOST_LIB_STATIC += ' ${BF_BOOST_LIBPATH}/libboost_wave.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# Ocean Simulation
@@ -164,4 +170,7 @@ WITH_BF_OCEANSIM = True
BF_DEBUG = False
REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-lrt']
-BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
+if BF_IS_NEW_OSL:
+ BF_PROGRAM_LINKFLAGS = ['-Wl,--version-script=source/creator/blender.map']
+else:
+ BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py
index 748d1004850..29f6143f50e 100644
--- a/build_files/buildbot/config/user-config-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py
@@ -79,6 +79,8 @@ WITH_BF_STATICZLIB = True
BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
WITH_BF_SDL = True
+WITH_BF_SDL_DYNLOAD = True
+
WITH_BF_OGG = True
WITH_BF_OPENMP = True
@@ -122,13 +124,15 @@ BF_OIIO_INC = '${BF_OIIO}/include'
BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_JPEG}/lib/libjpeg.a'
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
+BF_IS_NEW_OSL = False
WITH_BF_CYCLES_OSL = True
-WITH_BF_STATICOSL = False
+WITH_BF_STATICOSL = BF_IS_NEW_OSL
BF_OSL = '/opt/lib/osl'
BF_OSL_INC = '${BF_OSL}/include'
# note oslexec would passed via program linkflags, which is needed to
# make llvm happy with osl_allocate_closure_component
BF_OSL_LIB = 'oslcomp oslexec oslquery'
+BF_OSL_LIB_STATIC = '${BF_OSL}/lib/liboslcomp.a ${BF_OSL}/lib/liboslexec.a ${BF_OSL}/lib/liboslquery.a'
BF_OSL_LIBPATH = '${BF_OSL}/lib'
BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
@@ -155,6 +159,8 @@ BF_BOOST_INC = '${BF_BOOST}/include'
BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBPATH}/libboost_date_time.a ' + \
'${BF_BOOST_LIBPATH}/libboost_regex.a ${BF_BOOST_LIBPATH}/libboost_locale.a ${BF_BOOST_LIBPATH}/libboost_system.a \
${BF_BOOST_LIBPATH}/libboost_thread.a'
+if BF_IS_NEW_OSL:
+ BF_BOOST_LIB_STATIC += ' ${BF_BOOST_LIBPATH}/libboost_wave.a'
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
# Ocean Simulation
@@ -164,4 +170,7 @@ WITH_BF_OCEANSIM = True
BF_DEBUG = False
REL_CCFLAGS = ['-DNDEBUG', '-O2', '-msse', '-msse2'] # C & C++
PLATFORM_LINKFLAGS = ['-lrt']
-BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
+if BF_IS_NEW_OSL:
+ BF_PROGRAM_LINKFLAGS = ['-Wl,--version-script=source/creator/blender.map']
+else:
+ BF_PROGRAM_LINKFLAGS = ['-Wl,--whole-archive', '-loslexec', '-Wl,--no-whole-archive', '-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py
index 384da4070eb..b3c26ebb310 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py
@@ -64,6 +64,8 @@ WITH_BF_STATICZLIB = True
BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
WITH_BF_SDL = True
+WITH_BF_SDL_DYNLOAD = True
+
WITH_BF_OGG = False
WITH_BF_OPENMP = True
diff --git a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
index 5176d59d5a0..173e15b08ca 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
@@ -64,6 +64,8 @@ WITH_BF_STATICZLIB = True
BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
WITH_BF_SDL = True
+WITH_BF_SDL_DYNLOAD = True
+
WITH_BF_OGG = False
WITH_BF_OPENMP = True
diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg
index 66b456f2586..026d5e4f861 100644
--- a/build_files/buildbot/master.cfg
+++ b/build_files/buildbot/master.cfg
@@ -3,6 +3,12 @@
# <pep8 compliant>
+# List of the branches being built automatically overnight
+NIGHT_SCHEDULE_BRANCHES = [None, "gooseberry"]
+
+# List of the branches available for force build
+FORCE_SCHEDULE_BRANCHES = ["master", "gooseberry", "experimental-build"]
+
"""
Stock Twisted directory lister doesn't provide any information about last file
modification time, we hack the class a bit in order to have such functionaliity
@@ -92,6 +98,7 @@ all_repositories = {
r'https://svn.blender.org/svnroot/bf-blender/': 'lib svn',
}
+
def codebaseGenerator(chdict):
return all_repositories[chdict['repository']]
@@ -107,13 +114,14 @@ from buildbot.schedulers import timed, forcesched
c['schedulers'] = []
+
def schedule_force_build(name):
c['schedulers'].append(forcesched.ForceScheduler(name='force ' + name,
builderNames=[name],
codebases=[forcesched.CodebaseParameter(
codebase="blender",
branch=forcesched.ChoiceStringParameter(
- name="branch", choices=["master", "experimental-build"], default="master"),
+ name="branch", choices=FORCE_SCHEDULE_BRANCHES, default="master"),
# Do not hide revision, can be handy!
repository=forcesched.FixedParameter(name="repository", default="", hide=True),
project=forcesched.FixedParameter(name="project", default="", hide=True)),
@@ -127,18 +135,22 @@ def schedule_force_build(name):
def schedule_build(name, hour, minute=0):
- c['schedulers'].append(timed.Nightly(name='nightly ' + name,
- codebases={
- "blender": {"repository": ""},
- "blender-translations": {"repository": ""},
- "blender-addons": {"repository": ""},
- "blender-addons-contrib": {"repository": ""},
- "scons": {"repository": ""},
- "lib svn": {"repository": ""}},
- branch=None,
- builderNames=[name],
- hour=hour,
- minute=minute))
+ for current_branch in NIGHT_SCHEDULE_BRANCHES:
+ scheduler_name = "nightly " + name
+ if current_branch:
+ scheduler_name += ' ' + current_branch
+ c['schedulers'].append(timed.Nightly(name=scheduler_name,
+ codebases={
+ "blender": {"repository": ""},
+ "blender-translations": {"repository": "", "branch": "master"},
+ "blender-addons": {"repository": "", "branch": "master"},
+ "blender-addons-contrib": {"repository": "", "branch": "master"},
+ "scons": {"repository": "", "branch": "master"},
+ "lib svn": {"repository": "", "branch": "trunk"}},
+ branch=current_branch,
+ builderNames=[name],
+ hour=hour,
+ minute=minute))
# BUILDERS
@@ -295,6 +307,8 @@ add_builder(c, 'linux_glibc211_i386_scons', '', generic_builder, hour=1)
add_builder(c, 'linux_glibc211_x86_64_scons', '', generic_builder, hour=2)
add_builder(c, 'win32_scons_vc2013', 'windows_vc12', generic_builder, hour=1)
add_builder(c, 'win64_scons_vc2013', 'win64_vc12', generic_builder, hour=2)
+add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=3)
+add_builder(c, 'win64_cmake_vc2013', 'win64_vc12', generic_builder, hour=4)
#add_builder(c, 'mingw_win32_scons', 'mingw32', generic_builder, hour=4)
add_builder(c, 'mingw_win64_scons', 'mingw64', generic_builder, hour=3)
#add_builder(c, 'freebsd_i386_cmake', '', generic_builder, hour=1)
diff --git a/build_files/buildbot/master_unpack.py b/build_files/buildbot/master_unpack.py
index 35d26617893..46131c5e1de 100644
--- a/build_files/buildbot/master_unpack.py
+++ b/build_files/buildbot/master_unpack.py
@@ -30,11 +30,12 @@ import zipfile
# extension stripping
def strip_extension(filename):
extensions = '.zip', '.tar', '.bz2', '.gz', '.tgz', '.tbz', '.exe'
- filename_noext, ext = os.path.splitext(filename)
- if ext in extensions:
- return strip_extension(filename_noext) # may have .tar.bz2
- else:
- return filename
+
+ for ext in extensions:
+ if filename.endswith(ext):
+ filename = filename[:-len(ext)]
+
+ return filename
# extract platform from package name
@@ -48,12 +49,11 @@ def get_platform(filename):
tokens = filename.split("-")
platforms = ('osx', 'mac', 'bsd',
'win', 'linux', 'source',
- 'solaris',
- 'mingw')
+ 'irix', 'solaris', 'mingw')
platform_tokens = []
found = False
- for token in tokens:
+ for i, token in enumerate(tokens):
if not found:
for platform in platforms:
if platform in token.lower():
@@ -95,7 +95,7 @@ if not os.path.exists(filename):
try:
z = zipfile.ZipFile(filename, "r")
-except Exception, ex:
+except Exception as ex:
sys.stderr.write('Failed to open zip file: %s\n' % str(ex))
sys.exit(1)
@@ -112,16 +112,16 @@ branch = get_branch(packagename)
if platform == '':
sys.stderr.write('Failed to detect platform ' +
- 'from package: %r\n' % packagename)
+ 'from package: %r\n' % packagename)
sys.exit(1)
# extract
-directory = 'public_html/download'
if not branch or branch == 'master':
directory = 'public_html/download'
elif branch == 'experimental-build':
directory = 'public_html/download/experimental'
-# else: put 'official' branches in their own public subdir of download/ ?
+else:
+ directory = 'public_html/download'
try:
zf = z.open(package)
@@ -131,9 +131,7 @@ try:
zf.close()
z.close()
-
- os.remove(filename)
-except Exception, ex:
+except Exception as ex:
sys.stderr.write('Failed to unzip package: %s\n' % str(ex))
sys.exit(1)
@@ -143,6 +141,6 @@ try:
if get_platform(f) == platform and get_branch(f) == branch:
if f != packagename:
os.remove(os.path.join(directory, f))
-except Exception, ex:
+except Exception as ex:
sys.stderr.write('Failed to remove old packages: %s\n' % str(ex))
sys.exit(1)
diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py
index a5dadbde05c..cbe345e764c 100644
--- a/build_files/buildbot/slave_compile.py
+++ b/build_files/buildbot/slave_compile.py
@@ -33,7 +33,7 @@ builder = sys.argv[1]
# we run from build/ directory
blender_dir = '../blender.git'
-if builder.find('cmake') != -1:
+if 'cmake' in builder:
# cmake
# set build options
@@ -46,11 +46,21 @@ if builder.find('cmake') != -1:
elif builder.endswith('mac_ppc_cmake'):
cmake_options.append('-DCMAKE_OSX_ARCHITECTURES:STRING=ppc')
+ if 'win64' in builder:
+ cmake_options.append(['-G', '"Visual Studio 12 2013 Win64"'])
+ elif 'win32' in builder:
+ cmake_options.append(['-G', '"Visual Studio 12 2013"'])
+
+ cmake_options.append("-C../blender.git/build_files/cmake/config/blender_full.cmake")
+ cmake_options.append("-DWITH_CYCLES_CUDA_BINARIES=1")
# configure and make
retcode = subprocess.call(['cmake', blender_dir] + cmake_options)
if retcode != 0:
sys.exit(retcode)
- retcode = subprocess.call(['make', '-s', '-j4', 'install'])
+ if 'win' in builder:
+ retcode = subprocess.call(['msbuild', 'INSTALL.vcxproj', '/p:Configuration=Release'])
+ else:
+ retcode = subprocess.call(['make', '-s', '-j4', 'install'])
sys.exit(retcode)
else:
python_bin = 'python'
diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py
index c989cd8e31a..4e5d77b2a0a 100644
--- a/build_files/buildbot/slave_pack.py
+++ b/build_files/buildbot/slave_pack.py
@@ -115,6 +115,28 @@ if builder.find('scons') != -1:
retcode = subprocess.call([python_bin, 'scons/scons.py'] + scons_options)
sys.exit(retcode)
+else:
+ # CMake
+ if 'win' in builder:
+ files = [f for f in os.listdir('.') if os.path.isfile(f) and f.endswith('.zip')]
+ for f in files:
+ os.remove(f)
+ retcode = subprocess.call(['cpack', '-G', 'ZIP'])
+ result_file = [f for f in os.listdir('.') if os.path.isfile(f) and f.endswith('.zip')][0]
+ os.rename(result_file, "{}.zip".format(builder))
+ # create zip file
+ try:
+ upload_zip = "buildbot_upload.zip"
+ if os.path.exists(upload_zip):
+ os.remove(upload_zip)
+ z = zipfile.ZipFile(upload_zip, "w", compression=zipfile.ZIP_STORED)
+ z.write("{}.zip".format(builder))
+ z.close()
+ sys.exit(retcode)
+ except Exception as ex:
+ sys.stderr.write('Create buildbot_upload.zip failed' + str(ex) + '\n')
+ sys.exit(1)
+
# clean release directory if it already exists
release_dir = 'release'
@@ -127,7 +149,7 @@ if os.path.exists(release_dir):
# create release package
try:
subprocess.call(['make', 'package_archive'])
-except Exception, ex:
+except Exception as ex:
sys.stderr.write('Make package release failed' + str(ex) + '\n')
sys.exit(1)
@@ -158,6 +180,6 @@ try:
z = zipfile.ZipFile(upload_zip, "w", compression=zipfile.ZIP_STORED)
z.write(filepath, arcname=file)
z.close()
-except Exception, ex:
+except Exception as ex:
sys.stderr.write('Create buildbot_upload.zip failed' + str(ex) + '\n')
sys.exit(1)
diff --git a/build_files/cmake/Modules/FindGLEW.cmake b/build_files/cmake/Modules/FindGLEW.cmake
index 8589e143ada..2f098d5d9a4 100644
--- a/build_files/cmake/Modules/FindGLEW.cmake
+++ b/build_files/cmake/Modules/FindGLEW.cmake
@@ -75,3 +75,5 @@ MARK_AS_ADVANCED(
GLEW_LIBRARY
GLEW_MX_LIBRARY
)
+
+UNSET(_glew_SEARCH_DIRS)
diff --git a/build_files/cmake/Modules/FindJeMalloc.cmake b/build_files/cmake/Modules/FindJeMalloc.cmake
index 5c7aa2cf1e1..466456baf32 100644
--- a/build_files/cmake/Modules/FindJeMalloc.cmake
+++ b/build_files/cmake/Modules/FindJeMalloc.cmake
@@ -33,6 +33,7 @@ SET(_jemalloc_SEARCH_DIRS
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
+ /opt/lib/jemalloc
)
FIND_PATH(JEMALLOC_INCLUDE_DIR
diff --git a/build_files/cmake/Modules/FindLZO.cmake b/build_files/cmake/Modules/FindLZO.cmake
new file mode 100644
index 00000000000..a21aa0a03bb
--- /dev/null
+++ b/build_files/cmake/Modules/FindLZO.cmake
@@ -0,0 +1,68 @@
+# - Find LZO library
+# Find the native LZO includes and library
+# This module defines
+# LZO_INCLUDE_DIRS, where to find lzo1x.h, Set when
+# LZO_INCLUDE_DIR is found.
+# LZO_LIBRARIES, libraries to link against to use LZO.
+# LZO_ROOT_DIR, The base directory to search for LZO.
+# This can also be an environment variable.
+# LZO_FOUND, If false, do not try to use LZO.
+#
+# also defined, but not for general use are
+# LZO_LIBRARY, where to find the LZO library.
+
+#=============================================================================
+# Copyright 2015 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+# If LZO_ROOT_DIR was defined in the environment, use it.
+IF(NOT LZO_ROOT_DIR AND NOT $ENV{LZO_ROOT_DIR} STREQUAL "")
+ SET(LZO_ROOT_DIR $ENV{LZO_ROOT_DIR})
+ENDIF()
+
+SET(_lzo_SEARCH_DIRS
+ ${LZO_ROOT_DIR}
+ /usr/local
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+)
+
+FIND_PATH(LZO_INCLUDE_DIR lzo/lzo1x.h
+ HINTS
+ ${_lzo_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include
+)
+
+FIND_LIBRARY(LZO_LIBRARY
+ NAMES
+ lzo2
+ HINTS
+ ${_lzo_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+# handle the QUIETLY and REQUIRED arguments and set LZO_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZO DEFAULT_MSG
+ LZO_LIBRARY LZO_INCLUDE_DIR)
+
+IF(LZO_FOUND)
+ SET(LZO_LIBRARIES ${LZO_LIBRARY})
+ SET(LZO_INCLUDE_DIRS ${LZO_INCLUDE_DIR})
+ENDIF(LZO_FOUND)
+
+MARK_AS_ADVANCED(
+ LZO_INCLUDE_DIR
+ LZO_LIBRARY
+)
diff --git a/build_files/cmake/Modules/FindOpenCOLLADA.cmake b/build_files/cmake/Modules/FindOpenCOLLADA.cmake
index 84aead58b60..1c10d5a71de 100644
--- a/build_files/cmake/Modules/FindOpenCOLLADA.cmake
+++ b/build_files/cmake/Modules/FindOpenCOLLADA.cmake
@@ -140,3 +140,8 @@ IF(OPENCOLLADA_FOUND)
SET(OPENCOLLADA_LIBRARIES ${_opencollada_LIBRARIES})
SET(OPENCOLLADA_INCLUDE_DIRS ${_opencollada_INCLUDES})
ENDIF(OPENCOLLADA_FOUND)
+
+UNSET(COMPONENT)
+UNSET(UPPERCOMPONENT)
+UNSET(_opencollada_LIBRARIES)
+UNSET(_opencollada_INCLUDES)
diff --git a/build_files/cmake/Modules/FindOpenColorIO.cmake b/build_files/cmake/Modules/FindOpenColorIO.cmake
index e152f0f81d9..bd1ecac0a39 100644
--- a/build_files/cmake/Modules/FindOpenColorIO.cmake
+++ b/build_files/cmake/Modules/FindOpenColorIO.cmake
@@ -63,11 +63,12 @@ FOREACH(COMPONENT ${_opencolorio_FIND_COMPONENTS})
PATH_SUFFIXES
lib64 lib
)
- if(OPENCOLORIO_${UPPERCOMPONENT}_LIBRARY)
+ IF(OPENCOLORIO_${UPPERCOMPONENT}_LIBRARY)
LIST(APPEND _opencolorio_LIBRARIES "${OPENCOLORIO_${UPPERCOMPONENT}_LIBRARY}")
- endif()
+ ENDIF()
ENDFOREACH()
+
# handle the QUIETLY and REQUIRED arguments and set OPENCOLORIO_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
@@ -82,5 +83,13 @@ ENDIF(OPENCOLORIO_FOUND)
MARK_AS_ADVANCED(
OPENCOLORIO_INCLUDE_DIR
OPENCOLORIO_LIBRARY
+ OPENCOLORIO_OPENCOLORIO_LIBRARY
+ OPENCOLORIO_TINYXML_LIBRARY
+ OPENCOLORIO_YAML-CPP_LIBRARY
)
+UNSET(COMPONENT)
+UNSET(UPPERCOMPONENT)
+UNSET(_opencolorio_FIND_COMPONENTS)
+UNSET(_opencolorio_LIBRARIES)
+UNSET(_opencolorio_SEARCH_DIRS)
diff --git a/build_files/cmake/Modules/FindOpenEXR.cmake b/build_files/cmake/Modules/FindOpenEXR.cmake
index 1c59ef49e59..41e60a75294 100644
--- a/build_files/cmake/Modules/FindOpenEXR.cmake
+++ b/build_files/cmake/Modules/FindOpenEXR.cmake
@@ -51,6 +51,7 @@ SET(_openexr_SEARCH_DIRS
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
+ /opt/lib/openexr
)
FIND_PATH(OPENEXR_INCLUDE_DIR
@@ -137,3 +138,9 @@ FOREACH(COMPONENT ${_openexr_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
MARK_AS_ADVANCED(OPENEXR_${UPPERCOMPONENT}_LIBRARY)
ENDFOREACH()
+
+UNSET(COMPONENT)
+UNSET(UPPERCOMPONENT)
+UNSET(_openexr_FIND_COMPONENTS)
+UNSET(_openexr_LIBRARIES)
+UNSET(_openexr_SEARCH_DIRS)
diff --git a/build_files/cmake/Modules/FindOpenGLES.cmake b/build_files/cmake/Modules/FindOpenGLES.cmake
index 1bb06c2f31c..e3484d26ecd 100644
--- a/build_files/cmake/Modules/FindOpenGLES.cmake
+++ b/build_files/cmake/Modules/FindOpenGLES.cmake
@@ -71,6 +71,8 @@ ENDIF()
MARK_AS_ADVANCED(
OPENGLES_EGL_INCLUDE_DIR
OPENGLES_EGL_LIBRARY
+ OPENGLES_LIBRARY
OPENGLES_INCLUDE_DIR
)
+UNSET(_opengles_SEARCH_DIRS)
diff --git a/build_files/cmake/Modules/FindOpenImageIO.cmake b/build_files/cmake/Modules/FindOpenImageIO.cmake
index 9b8c8b075b1..5e454b6e5cd 100644
--- a/build_files/cmake/Modules/FindOpenImageIO.cmake
+++ b/build_files/cmake/Modules/FindOpenImageIO.cmake
@@ -7,6 +7,8 @@
# OPENIMAGEIO_ROOT_DIR, The base directory to search for OpenImageIO.
# This can also be an environment variable.
# OPENIMAGEIO_FOUND, If false, do not try to use OpenImageIO.
+# OPENIMAGEIO_PUGIXML_FOUND, Indicates whether OIIO has biltin PuguXML parser.
+# OPENIMAGEIO_IDIFF, full path to idiff application if found.
#
# also defined, but not for general use are
# OPENIMAGEIO_LIBRARY, where to find the OpenImageIO library.
@@ -54,6 +56,14 @@ FIND_LIBRARY(OPENIMAGEIO_LIBRARY
lib64 lib
)
+FIND_FILE(OPENIMAGEIO_IDIFF
+ NAMES
+ idiff
+ ${OPENIMAGEIO_ROOT_DIR}
+ PATH_SUFFIXES
+ bin
+)
+
# handle the QUIETLY and REQUIRED arguments and set OPENIMAGEIO_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
@@ -63,9 +73,17 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenImageIO DEFAULT_MSG
IF(OPENIMAGEIO_FOUND)
SET(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARY})
SET(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIR})
-ENDIF(OPENIMAGEIO_FOUND)
+ IF(EXISTS ${OPENIMAGEIO_INCLUDE_DIR}/OpenImageIO/pugixml.hpp)
+ SET(OPENIMAGEIO_PUGIXML_FOUND TRUE)
+ ENDIF()
+ELSE()
+ SET(OPENIMAGEIO_PUGIXML_FOUND FALSE)
+ENDIF()
MARK_AS_ADVANCED(
OPENIMAGEIO_INCLUDE_DIR
OPENIMAGEIO_LIBRARY
+ OPENIMAGEIO_IDIFF
)
+
+UNSET(_openimageio_SEARCH_DIRS)
diff --git a/build_files/cmake/Modules/FindOpenJPEG.cmake b/build_files/cmake/Modules/FindOpenJPEG.cmake
index 8bd1a584ac7..d765103638b 100644
--- a/build_files/cmake/Modules/FindOpenJPEG.cmake
+++ b/build_files/cmake/Modules/FindOpenJPEG.cmake
@@ -69,3 +69,5 @@ MARK_AS_ADVANCED(
OPENJPEG_INCLUDE_DIR
OPENJPEG_LIBRARY
)
+
+UNSET(_openjpeg_SEARCH_DIRS)
diff --git a/build_files/cmake/Modules/FindOpenShadingLanguage.cmake b/build_files/cmake/Modules/FindOpenShadingLanguage.cmake
new file mode 100644
index 00000000000..824d0f90597
--- /dev/null
+++ b/build_files/cmake/Modules/FindOpenShadingLanguage.cmake
@@ -0,0 +1,98 @@
+# - Find OpenShadingLanguage library
+# Find the native OpenShadingLanguage includes and library
+# This module defines
+# OSL_INCLUDE_DIRS, where to find OSL headers, Set when
+# OSL_INCLUDE_DIR is found.
+# OSL_LIBRARIES, libraries to link against to use OSL.
+# OSL_ROOT_DIR, the base directory to search for OSL.
+# This can also be an environment variable.
+# OSL_COMPILER, full path to OSL script compiler.
+# OSL_FOUND, if false, do not try to use OSL.
+# OSL_LIBRARY_VERSION_MAJOR, OSL_LIBRARY_VERSION_MINOR, the major
+# and minor versions of OSL library if found.
+#
+#=============================================================================
+# Copyright 2014 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+# If OSL_ROOT_DIR was defined in the environment, use it.
+IF(NOT OSL_ROOT_DIR AND NOT $ENV{OSL_ROOT_DIR} STREQUAL "")
+ SET(OSL_ROOT_DIR $ENV{OSL_ROOT_DIR})
+ENDIF()
+
+SET(_osl_FIND_COMPONENTS
+ oslcomp
+ oslexec
+ oslquery
+)
+
+SET(_osl_SEARCH_DIRS
+ ${OSL_ROOT_DIR}
+ /usr/local
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt/lib/osl
+)
+
+FIND_PATH(OSL_INCLUDE_DIR
+ NAMES
+ OSL/oslversion.h
+ HINTS
+ ${_osl_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include
+)
+
+SET(_osl_LIBRARIES)
+FOREACH(COMPONENT ${_osl_FIND_COMPONENTS})
+ STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
+
+ FIND_LIBRARY(OSL_${UPPERCOMPONENT}_LIBRARY
+ NAMES
+ ${COMPONENT}
+ HINTS
+ ${_osl_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+ LIST(APPEND _osl_LIBRARIES "${OSL_${UPPERCOMPONENT}_LIBRARY}")
+ENDFOREACH()
+
+FIND_PROGRAM(OSL_COMPILER oslc
+ HINTS ${_osl_SEARCH_DIRS}
+ PATH_SUFFIXES bin)
+
+# handle the QUIETLY and REQUIRED arguments and set OSL_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(OSL DEFAULT_MSG _osl_LIBRARIES OSL_INCLUDE_DIR OSL_COMPILER)
+
+IF(OSL_FOUND)
+ SET(OSL_LIBRARIES ${_osl_LIBRARIES})
+ SET(OSL_INCLUDE_DIRS ${OSL_INCLUDE_DIR})
+
+ FILE(STRINGS "${OSL_INCLUDE_DIR}/OSL/oslversion.h" OSL_LIBRARY_VERSION_MAJOR
+ REGEX "^[ \t]*#define[ \t]+OSL_LIBRARY_VERSION_MAJOR[ \t]+[0-9]+.*$")
+ FILE(STRINGS "${OSL_INCLUDE_DIR}/OSL/oslversion.h" OSL_LIBRARY_VERSION_MINOR
+ REGEX "^[ \t]*#define[ \t]+OSL_LIBRARY_VERSION_MINOR[ \t]+[0-9]+.*$")
+ STRING(REGEX REPLACE ".*#define[ \t]+OSL_LIBRARY_VERSION_MAJOR[ \t]+([.0-9]+).*"
+ "\\1" OSL_LIBRARY_VERSION_MAJOR ${OSL_LIBRARY_VERSION_MAJOR})
+ STRING(REGEX REPLACE ".*#define[ \t]+OSL_LIBRARY_VERSION_MINOR[ \t]+([.0-9]+).*"
+ "\\1" OSL_LIBRARY_VERSION_MINOR ${OSL_LIBRARY_VERSION_MINOR})
+ENDIF(OSL_FOUND)
+
+MARK_AS_ADVANCED(
+ OSL_INCLUDE_DIR
+)
+FOREACH(COMPONENT ${_osl_FIND_COMPONENTS})
+ STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
+ MARK_AS_ADVANCED(OSL_${UPPERCOMPONENT}_LIBRARY)
+ENDFOREACH()
diff --git a/build_files/cmake/Modules/FindPugiXML.cmake b/build_files/cmake/Modules/FindPugiXML.cmake
new file mode 100644
index 00000000000..f7104c16921
--- /dev/null
+++ b/build_files/cmake/Modules/FindPugiXML.cmake
@@ -0,0 +1,73 @@
+# - Find PugiXML library
+# Find the native PugiXML includes and library
+# This module defines
+# PUGIXML_INCLUDE_DIRS, where to find pugixml.hpp, Set when
+# PugiXML is found.
+# PUGIXML_LIBRARIES, libraries to link against to use PugiiXML.
+# PUGIXML_ROOT_DIR, The base directory to search for PugiXML.
+# This can also be an environment variable.
+# PUGIXML_FOUND, If false, do not try to use PugiXML.
+#
+# also defined, but not for general use are
+# PUGIXML_LIBRARY, where to find the PugiXML library.
+
+#=============================================================================
+# Copyright 2014 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+# If PUGIXML_ROOT_DIR was defined in the environment, use it.
+IF(NOT PUGIXML_ROOT_DIR AND NOT $ENV{PUGIXML_ROOT_DIR} STREQUAL "")
+ SET(PUGIXML_ROOT_DIR $ENV{PUGIXML_ROOT_DIR})
+ENDIF()
+
+SET(_pugixml_SEARCH_DIRS
+ ${PUGIXML_ROOT_DIR}
+ /usr/local
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt/lib/oiio
+)
+
+FIND_PATH(PUGIXML_INCLUDE_DIR
+ NAMES
+ pugixml.hpp
+ HINTS
+ ${_pugixml_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include
+)
+
+FIND_LIBRARY(PUGIXML_LIBRARY
+ NAMES
+ pugixml
+ HINTS
+ ${_pugixml_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+# handle the QUIETLY and REQUIRED arguments and set PUGIXML_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(PUGIXML DEFAULT_MSG
+ PUGIXML_LIBRARY PUGIXML_INCLUDE_DIR)
+
+IF(PUGIXML_FOUND)
+ SET(PUGIXML_LIBRARIES ${PUGIXML_LIBRARY})
+ SET(PUGIXML_INCLUDE_DIRS ${PUGIXML_INCLUDE_DIR})
+ELSE()
+ SET(PUGIXML_PUGIXML_FOUND FALSE)
+ENDIF()
+
+MARK_AS_ADVANCED(
+ PUGIXML_INCLUDE_DIR
+ PUGIXML_LIBRARY
+)
diff --git a/build_files/cmake/Modules/FindSDL2.cmake b/build_files/cmake/Modules/FindSDL2.cmake
new file mode 100644
index 00000000000..2a835cf94fa
--- /dev/null
+++ b/build_files/cmake/Modules/FindSDL2.cmake
@@ -0,0 +1,72 @@
+# - Find SDL library
+# Find the native SDL includes and library
+# This module defines
+# SDL2_INCLUDE_DIRS, where to find SDL.h, Set when SDL2_INCLUDE_DIR is found.
+# SDL2_LIBRARIES, libraries to link against to use SDL.
+# SDL2_ROOT_DIR, The base directory to search for SDL.
+# This can also be an environment variable.
+# SDL2_FOUND, If false, do not try to use SDL.
+#
+# also defined, but not for general use are
+# SDL2_LIBRARY, where to find the SDL library.
+
+#=============================================================================
+# Copyright 2015 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+# If SDL2_ROOT_DIR was defined in the environment, use it.
+IF(NOT SDL2_ROOT_DIR AND NOT $ENV{SDL2_ROOT_DIR} STREQUAL "")
+ SET(SDL2_ROOT_DIR $ENV{SDL2_ROOT_DIR})
+ENDIF()
+
+SET(_sdl2_SEARCH_DIRS
+ ${SDL2_ROOT_DIR}
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /usr/local
+ /usr
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+)
+
+FIND_PATH(SDL2_INCLUDE_DIR
+ NAMES
+ SDL.h
+ HINTS
+ ${_sdl2_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include/SDL2 include
+)
+
+FIND_LIBRARY(SDL2_LIBRARY
+ NAMES
+ SDL2
+ HINTS
+ ${_sdl2_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+# handle the QUIETLY and REQUIRED arguments and set SDL2_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 DEFAULT_MSG
+ SDL2_LIBRARY SDL2_INCLUDE_DIR)
+
+IF(SDL2_FOUND)
+ SET(SDL2_LIBRARIES ${SDL2_LIBRARY})
+ SET(SDL2_INCLUDE_DIRS ${SDL2_INCLUDE_DIR})
+ENDIF(SDL2_FOUND)
+
+MARK_AS_ADVANCED(
+ SDL2_INCLUDE_DIR
+ SDL2_LIBRARY
+)
diff --git a/build_files/cmake/Modules/GTestTesting.cmake b/build_files/cmake/Modules/GTestTesting.cmake
index fd0379b8f78..6a9cae22f33 100644
--- a/build_files/cmake/Modules/GTestTesting.cmake
+++ b/build_files/cmake/Modules/GTestTesting.cmake
@@ -32,6 +32,8 @@ macro(BLENDER_SRC_GTEST NAME SRC EXTRA_LIBS)
bf_testing_main
bf_intern_guardedalloc
extern_gtest
+ # needed for glog
+ ${PTHREADS_LIBRARIES}
extern_glog)
set_target_properties(${NAME}_test PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${TESTS_OUTPUT_DIR}"
diff --git a/build_files/cmake/buildinfo.cmake b/build_files/cmake/buildinfo.cmake
index fecd19c62e2..8ef29b06213 100644
--- a/build_files/cmake/buildinfo.cmake
+++ b/build_files/cmake/buildinfo.cmake
@@ -146,6 +146,14 @@ file(WRITE buildinfo.h.txt
"#define BUILD_TIME \"${BUILD_TIME}\"\n"
)
+# cleanup
+unset(MY_WC_HASH)
+unset(MY_WC_COMMIT_TIMESTAMP)
+unset(MY_WC_BRANCH)
+unset(BUILD_DATE)
+unset(BUILD_TIME)
+
+
# Copy the file to the final header only if the version changes
# and avoid needless rebuilds
# TODO: verify this comment is true, as BUILD_TIME probably changes
diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py
index 2e0eeb1e067..0883bdbf2d7 100755
--- a/build_files/cmake/cmake_consistency_check.py
+++ b/build_files/cmake/cmake_consistency_check.py
@@ -187,6 +187,8 @@ def cmake_get_src(f):
pass
elif new_file.endswith(".osl"): # open shading language
pass
+ elif new_file.endswith(".glsl"):
+ pass
else:
raise Exception("unknown file type - not c or h %s -> %s" % (f, new_file))
@@ -201,7 +203,7 @@ def cmake_get_src(f):
# replace_line(f, i - 1, new_path_rel)
else:
- raise Exception("non existant include %s:%d -> %s" % (f, i, new_file))
+ raise Exception("non existent include %s:%d -> %s" % (f, i, new_file))
# print(new_file)
@@ -305,7 +307,7 @@ if UTF8_CHECK:
try:
for l in open(f, "r", encoding="utf8"):
i += 1
- except:
+ except UnicodeDecodeError:
print("Non utf8: %s:%d" % (f, i))
if i > 1:
traceback.print_exc()
diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py
index fc6c64db1cd..81b1a460f67 100755
--- a/build_files/cmake/cmake_netbeans_project.py
+++ b/build_files/cmake/cmake_netbeans_project.py
@@ -125,6 +125,8 @@ def create_nb_project_main():
f.write(' </configuration>\n')
f.write('</project>\n')
+ f.close()
+
f = open(join(PROJECT_DIR_NB, "configurations.xml"), 'w')
f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
@@ -243,6 +245,8 @@ def create_nb_project_main():
f.write('</configurationDescriptor>\n')
+ f.close()
+
def main():
create_nb_project_main()
diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py
index 346f5ea6a8e..1676d634cf2 100755
--- a/build_files/cmake/cmake_qtcreator_project.py
+++ b/build_files/cmake/cmake_qtcreator_project.py
@@ -27,7 +27,7 @@ Example Win32 usage:
c:\Python32\python.exe c:\blender_dev\blender\build_files\cmake\cmake_qtcreator_project.py c:\blender_dev\cmake_build
example linux usage
- python .~/blender-git/blender/build_files/cmake/cmake_qtcreator_project.py ~/blender-git/cmake
+ python ~/blender-git/blender/build_files/cmake/cmake_qtcreator_project.py ~/blender-git/cmake
"""
from project_info import (SIMPLE_PROJECTFILE,
@@ -63,21 +63,21 @@ def create_qtc_project_main():
if SIMPLE_PROJECTFILE:
# --- qtcreator specific, simple format
PROJECT_NAME = "Blender"
- f = open(os.path.join(PROJECT_DIR, "%s.files" % PROJECT_NAME), 'w')
- f.write("\n".join(files_rel))
+ with open(os.path.join(PROJECT_DIR, "%s.files" % PROJECT_NAME), 'w') as f:
+ f.write("\n".join(files_rel))
- f = open(os.path.join(PROJECT_DIR, "%s.includes" % PROJECT_NAME), 'w')
- f.write("\n".join(sorted(list(set(os.path.dirname(f)
- for f in files_rel if is_c_header(f))))))
+ with open(os.path.join(PROJECT_DIR, "%s.includes" % PROJECT_NAME), 'w') as f:
+ f.write("\n".join(sorted(list(set(os.path.dirname(f)
+ for f in files_rel if is_c_header(f))))))
qtc_prj = os.path.join(PROJECT_DIR, "%s.creator" % PROJECT_NAME)
- f = open(qtc_prj, 'w')
- f.write("[General]\n")
+ with open(qtc_prj, 'w') as f:
+ f.write("[General]\n")
qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % PROJECT_NAME)
if not os.path.exists(qtc_cfg):
- f = open(qtc_cfg, 'w')
- f.write("// ADD PREDEFINED MACROS HERE!\n")
+ with open(qtc_cfg, 'w') as f:
+ f.write("// ADD PREDEFINED MACROS HERE!\n")
else:
includes, defines = cmake_advanced_info()
@@ -96,29 +96,30 @@ def create_qtc_project_main():
PROJECT_NAME = project_name_get()
FILE_NAME = PROJECT_NAME.lower()
- f = open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w')
- f.write("\n".join(files_rel))
+ with open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w') as f:
+ f.write("\n".join(files_rel))
- f = open(os.path.join(PROJECT_DIR, "%s.includes" % FILE_NAME), 'w', encoding='utf-8')
- f.write("\n".join(sorted(includes)))
+ with open(os.path.join(PROJECT_DIR, "%s.includes" % FILE_NAME), 'w', encoding='utf-8') as f:
+ f.write("\n".join(sorted(includes)))
qtc_prj = os.path.join(PROJECT_DIR, "%s.creator" % FILE_NAME)
- f = open(qtc_prj, 'w')
- f.write("[General]\n")
+ with open(qtc_prj, 'w') as f:
+ f.write("[General]\n")
qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % FILE_NAME)
- f = open(qtc_cfg, 'w')
- f.write("// ADD PREDEFINED MACROS TO %s_custom.config!\n" % FILE_NAME)
- qtc_custom_cfg = os.path.join(PROJECT_DIR, "%s_custom.config" % FILE_NAME)
- if os.path.exists(qtc_custom_cfg):
- fc = open(qtc_custom_cfg, 'r')
- f.write(fc.read())
- fc.close()
- f.write("\n")
- defines_final = [("#define %s %s" % (item[0], quote_define(item[1]))) for item in defines]
- if sys.platform != "win32":
- defines_final += cmake_compiler_defines()
- f.write("\n".join(defines_final))
+ with open(qtc_cfg, 'w') as f:
+ f.write("// ADD PREDEFINED MACROS TO %s_custom.config!\n" % FILE_NAME)
+
+ qtc_custom_cfg = os.path.join(PROJECT_DIR, "%s_custom.config" % FILE_NAME)
+ if os.path.exists(qtc_custom_cfg):
+ with open(qtc_custom_cfg, 'r') as fc:
+ f.write(fc.read())
+ f.write("\n")
+
+ defines_final = [("#define %s %s" % (item[0], quote_define(item[1]))) for item in defines]
+ if sys.platform != "win32":
+ defines_final += cmake_compiler_defines()
+ f.write("\n".join(defines_final))
print("Blender project file written to: %r" % qtc_prj)
# --- end
@@ -137,17 +138,17 @@ def create_qtc_project_python():
PROJECT_NAME = project_name_get() + "_Python"
FILE_NAME = PROJECT_NAME.lower()
- f = open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w')
- f.write("\n".join(files_rel))
+ with open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w') as f:
+ f.write("\n".join(files_rel))
qtc_prj = os.path.join(PROJECT_DIR, "%s.creator" % FILE_NAME)
- f = open(qtc_prj, 'w')
- f.write("[General]\n")
+ with open(qtc_prj, 'w') as f:
+ f.write("[General]\n")
qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % FILE_NAME)
if not os.path.exists(qtc_cfg):
- f = open(qtc_cfg, 'w')
- f.write("// ADD PREDEFINED MACROS HERE!\n")
+ with open(qtc_cfg, 'w') as f:
+ f.write("// ADD PREDEFINED MACROS HERE!\n")
print("Python project file written to: %r" % qtc_prj)
diff --git a/build_files/cmake/config/blender_full.cmake b/build_files/cmake/config/blender_full.cmake
new file mode 100644
index 00000000000..d41f97a8348
--- /dev/null
+++ b/build_files/cmake/config/blender_full.cmake
@@ -0,0 +1,62 @@
+# turn everything OFF except for python which defaults to ON
+# and is needed for the UI
+#
+# Example usage:
+# cmake -C../blender/build_files/cmake/config/blender_full.cmake ../blender
+#
+
+set(WITH_BUILDINFO ON CACHE BOOL "" FORCE)
+set(WITH_BULLET ON CACHE BOOL "" FORCE)
+set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
+set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
+set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
+set(WITH_CYCLES ON CACHE BOOL "" FORCE)
+set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
+set(WITH_LIBMV ON CACHE BOOL "" FORCE)
+set(WITH_GAMEENGINE ON CACHE BOOL "" FORCE)
+set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
+set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
+set(WITH_GHOST_XDND ON CACHE BOOL "" FORCE)
+set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
+set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
+set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
+set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE)
+set(WITH_IMAGE_FRAMESERVER ON CACHE BOOL "" FORCE)
+set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE)
+set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE)
+set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE)
+set(WITH_IMAGE_REDCODE ON CACHE BOOL "" FORCE)
+set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE)
+set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE)
+set(WITH_INTERNATIONAL ON CACHE BOOL "" FORCE)
+set(WITH_JACK ON CACHE BOOL "" FORCE)
+set(WITH_LZMA ON CACHE BOOL "" FORCE)
+set(WITH_LZO ON CACHE BOOL "" FORCE)
+set(WITH_MOD_BOOLEAN ON CACHE BOOL "" FORCE)
+set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
+set(WITH_MOD_REMESH ON CACHE BOOL "" FORCE)
+set(WITH_MOD_SMOKE ON CACHE BOOL "" FORCE)
+set(WITH_MOD_OCEANSIM ON CACHE BOOL "" FORCE)
+set(WITH_AUDASPACE ON CACHE BOOL "" FORCE)
+set(WITH_OPENAL ON CACHE BOOL "" FORCE)
+set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE)
+set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE)
+set(WITH_OPENMP ON CACHE BOOL "" FORCE)
+set(WITH_OPENNL ON CACHE BOOL "" FORCE)
+set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
+set(WITH_RAYOPTIMIZATION ON CACHE BOOL "" FORCE)
+set(WITH_SDL ON CACHE BOOL "" FORCE)
+set(WITH_X11_XINPUT ON CACHE BOOL "" FORCE)
+set(WITH_X11_XF86VMODE ON CACHE BOOL "" FORCE)
+
+set(WITH_PLAYER ON CACHE BOOL "" FORCE)
+set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
+
+if(UNIX AND NOT APPLE)
+ set(WITH_DOC_MANPAGE ON CACHE BOOL "" FORCE)
+endif()
+
+if(APPLE)
+ set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE)
+endif()
+
diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake
index bf5c4f9e103..3a702014bae 100644
--- a/build_files/cmake/config/blender_lite.cmake
+++ b/build_files/cmake/config/blender_lite.cmake
@@ -44,6 +44,7 @@ set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
set(WITH_OPENCOLORIO OFF CACHE BOOL "" FORCE)
+set(WITH_OPENIMAGEIO OFF CACHE BOOL "" FORCE)
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
set(WITH_OPENNL OFF CACHE BOOL "" FORCE)
set(WITH_PYTHON_INSTALL OFF CACHE BOOL "" FORCE)
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 86cbe3375df..c4363b97c4a 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -118,6 +118,19 @@ macro(target_link_libraries_debug TARGET LIBS)
unset(_LIB)
endmacro()
+macro(target_link_libraries_decoupled target libraries_var)
+ if(NOT MSVC)
+ target_link_libraries(${target} ${${libraries_var}})
+ else()
+ # For MSVC we link to different libraries depending whether
+ # release or debug target is being built.
+ file_list_suffix(_libraries_debug "${${libraries_var}}" "_d")
+ target_link_libraries_debug(${target} "${_libraries_debug}")
+ target_link_libraries_optimized(${target} "${${libraries_var}}")
+ unset(_libraries_debug)
+ endif()
+endmacro()
+
# Nicer makefiles with -I/1/foo/ instead of -I/1/2/3/../../foo/
# use it instead of include_directories()
macro(blender_include_dirs
@@ -221,7 +234,7 @@ macro(SETUP_LIBDIRS)
if(WITH_PYTHON) # AND NOT WITH_PYTHON_MODULE # WIN32 needs
link_directories(${PYTHON_LIBPATH})
endif()
- if(WITH_SDL)
+ if(WITH_SDL AND NOT WITH_SDL_DYNLOAD)
link_directories(${SDL_LIBPATH})
endif()
if(WITH_CODEC_FFMPEG)
@@ -283,8 +296,13 @@ macro(setup_liblinks
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
+
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")
+ set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
+
target_link_libraries(${target}
- ${BLENDER_GL_LIBRARIES}
${PNG_LIBRARIES}
${ZLIB_LIBRARIES}
${FREETYPE_LIBRARY})
@@ -303,6 +321,9 @@ macro(setup_liblinks
endif()
endif()
+ if(WITH_LZO AND WITH_SYSTEM_LZO)
+ target_link_libraries(${target} ${LZO_LIBRARIES})
+ endif()
if(WITH_SYSTEM_GLEW)
target_link_libraries(${target} ${BLENDER_GLEW_LIBRARIES})
endif()
@@ -321,7 +342,7 @@ macro(setup_liblinks
if(WITH_CODEC_SNDFILE)
target_link_libraries(${target} ${SNDFILE_LIBRARIES})
endif()
- if(WITH_SDL)
+ if(WITH_SDL AND NOT WITH_SDL_DYNLOAD)
target_link_libraries(${target} ${SDL_LIBRARY})
endif()
if(WITH_CODEC_QUICKTIME)
@@ -336,6 +357,9 @@ macro(setup_liblinks
if(WITH_OPENCOLORIO)
target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
endif()
+ if(WITH_CYCLES_OSL)
+ target_link_libraries(${target} ${OSL_LIBRARIES})
+ endif()
if(WITH_BOOST)
target_link_libraries(${target} ${BOOST_LIBRARIES})
if(Boost_USE_STATIC_LIBS AND Boost_USE_ICU)
@@ -357,14 +381,6 @@ macro(setup_liblinks
target_link_libraries(${target} ${OPENJPEG_LIBRARIES})
endif()
if(WITH_CODEC_FFMPEG)
-
- # Strange! Without this ffmpeg gives linking errors (on linux),
- # even though it's linked above.
- # XXX: Does FFMPEG depend on GLU?
- if(WITH_GLU)
- target_link_libraries(${target} ${OPENGL_glu_LIBRARY})
- endif()
-
target_link_libraries(${target} ${FFMPEG_LIBRARIES})
endif()
if(WITH_OPENCOLLADA)
@@ -402,9 +418,6 @@ macro(setup_liblinks
if(WITH_MOD_CLOTH_ELTOPO)
target_link_libraries(${target} ${LAPACK_LIBRARIES})
endif()
- if(WITH_CYCLES_OSL)
- target_link_libraries(${target} ${OSL_LIBRARIES})
- endif()
if(WITH_LLVM)
target_link_libraries(${target} ${LLVM_LIBRARY})
endif()
@@ -412,13 +425,17 @@ macro(setup_liblinks
target_link_libraries(${target} ${PTHREADS_LIBRARIES})
endif()
- target_link_libraries(${target} ${PLATFORM_LINKLIBS} ${CMAKE_DL_LIBS})
-
# We put CLEW and CUEW here because OPENSUBDIV_LIBRARIES dpeends on them..
if(WITH_CYCLES OR WITH_COMPOSITOR OR WITH_OPENSUBDIV)
target_link_libraries(${target} "extern_clew")
target_link_libraries(${target} "extern_cuew")
endif()
+
+ #system libraries with no dependencies such as platform link libs or opengl should go last
+ target_link_libraries(${target}
+ ${BLENDER_GL_LIBRARIES})
+
+ target_link_libraries(${target} ${PLATFORM_LINKLIBS} ${CMAKE_DL_LIBS})
endmacro()
macro(SETUP_BLENDER_SORTED_LIBS)
@@ -501,6 +518,7 @@ macro(SETUP_BLENDER_SORTED_LIBS)
bf_modifiers
bf_bmesh
bf_blenkernel
+ bf_physics
bf_nodes
bf_rna
bf_gpu
@@ -525,7 +543,6 @@ macro(SETUP_BLENDER_SORTED_LIBS)
ge_phys_dummy
ge_phys_bullet
bf_intern_smoke
- extern_minilzo
extern_lzma
extern_colamd
ge_logic_ketsji
@@ -560,6 +577,7 @@ macro(SETUP_BLENDER_SORTED_LIBS)
extern_wcwidth
extern_libmv
extern_glog
+ extern_sdlew
bf_intern_glew_mx
)
@@ -578,6 +596,10 @@ macro(SETUP_BLENDER_SORTED_LIBS)
list(APPEND BLENDER_SORTED_LIBS extern_eltopo)
endif()
+ if(NOT WITH_SYSTEM_LZO)
+ list(APPEND BLENDER_SORTED_LIBS extern_minilzo)
+ endif()
+
if(NOT WITH_SYSTEM_GLEW)
list(APPEND BLENDER_SORTED_LIBS ${BLENDER_GLEW_LIBRARIES})
endif()
@@ -910,6 +932,7 @@ macro(remove_strict_flags)
remove_cc_flag("-Wstrict-prototypes")
remove_cc_flag("-Wmissing-prototypes")
remove_cc_flag("-Wunused-parameter")
+ remove_cc_flag("-Wunused-macros")
remove_cc_flag("-Wwrite-strings")
remove_cc_flag("-Wredundant-decls")
remove_cc_flag("-Wundef")
@@ -999,7 +1022,16 @@ macro(ADD_CHECK_CXX_COMPILER_FLAG
endif()
endmacro()
-macro(get_blender_version)
+function(get_blender_version)
+ # extracts header vars and defines them in the parent scope:
+ #
+ # - BLENDER_VERSION (major.minor)
+ # - BLENDER_VERSION_MAJOR
+ # - BLENDER_VERSION_MINOR
+ # - BLENDER_SUBVERSION (used for internal versioning mainly)
+ # - BLENDER_VERSION_CHAR (a, b, c, ...or empty string)
+ # - BLENDER_VERSION_CYCLE (alpha, beta, rc, release)
+
# So cmake depends on BKE_blender.h, beware of inf-loops!
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender.h
${CMAKE_BINARY_DIR}/source/blender/blenkernel/BKE_blender.h.done)
@@ -1032,33 +1064,29 @@ macro(get_blender_version)
message(FATAL_ERROR "Version parsing failed for BLENDER_VERSION_CYCLE")
endif()
- math(EXPR BLENDER_VERSION_MAJOR "${_out_version} / 100")
- math(EXPR BLENDER_VERSION_MINOR "${_out_version} % 100")
- set(BLENDER_VERSION "${BLENDER_VERSION_MAJOR}.${BLENDER_VERSION_MINOR}")
-
- set(BLENDER_SUBVERSION ${_out_subversion})
- set(BLENDER_VERSION_CHAR ${_out_version_char})
- set(BLENDER_VERSION_CYCLE ${_out_version_cycle})
+ math(EXPR _out_version_major "${_out_version} / 100")
+ math(EXPR _out_version_minor "${_out_version} % 100")
# for packaging, alpha to numbers
- string(COMPARE EQUAL "${BLENDER_VERSION_CHAR}" "" _out_version_char_empty)
+ string(COMPARE EQUAL "${_out_version_char}" "" _out_version_char_empty)
if(${_out_version_char_empty})
- set(BLENDER_VERSION_CHAR_INDEX "0")
+ set(_out_version_char_index "0")
else()
set(_char_ls a b c d e f g h i j k l m n o p q r s t u v w x y z)
- list(FIND _char_ls ${BLENDER_VERSION_CHAR} _out_version_char_index)
- math(EXPR BLENDER_VERSION_CHAR_INDEX "${_out_version_char_index} + 1")
- unset(_char_ls)
- unset(_out_version_char_index)
+ list(FIND _char_ls ${_out_version_char} _out_version_char_index)
+ math(EXPR _out_version_char_index "${_out_version_char_index} + 1")
endif()
- unset(_out_subversion)
- unset(_out_version_char)
- unset(_out_version_char_empty)
- unset(_out_version_cycle)
+ # output vars
+ set(BLENDER_VERSION "${_out_version_major}.${_out_version_minor}" PARENT_SCOPE)
+ set(BLENDER_VERSION_MAJOR "${_out_version_major}" PARENT_SCOPE)
+ set(BLENDER_VERSION_MINOR "${_out_version_minor}" PARENT_SCOPE)
+ set(BLENDER_SUBVERSION "${_out_subversion}" PARENT_SCOPE)
+ set(BLENDER_VERSION_CHAR "${_out_version_char}" PARENT_SCOPE)
+ set(BLENDER_VERSION_CHAR_INDEX "${_out_version_char_index}" PARENT_SCOPE)
+ set(BLENDER_VERSION_CYCLE "${_out_version_cycle}" PARENT_SCOPE)
- # message(STATUS "Version (Internal): ${BLENDER_VERSION}.${BLENDER_SUBVERSION}, Version (external): ${BLENDER_VERSION}${BLENDER_VERSION_CHAR}-${BLENDER_VERSION_CYCLE}")
-endmacro()
+endfunction()
# hacks to override initial project settings
@@ -1095,7 +1123,7 @@ endmacro()
macro(blender_project_hack_post)
# --------------
# MINGW HACK END
- if (_reset_standard_libraries)
+ if(_reset_standard_libraries)
# Must come after projecINCt(...)
#
# MINGW workaround for -ladvapi32 being included which surprisingly causes
@@ -1155,6 +1183,7 @@ macro(delayed_install
endif()
set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_DESTINATIONS ${destination})
endforeach()
+ unset(f)
endmacro()
# note this is a function instead of a macro so that ${BUILD_TYPE} in targetdir
@@ -1174,6 +1203,7 @@ function(delayed_do_install
list(GET destinations ${i} d)
install(FILES ${f} DESTINATION ${targetdir}/${d})
endforeach()
+ unset(f)
endif()
endfunction()
@@ -1388,3 +1418,14 @@ macro(find_python_package
unset(_upper_package)
endmacro()
+
+# like Python's 'print(dir())'
+macro(print_all_vars)
+ get_cmake_property(_vars VARIABLES)
+ foreach(_var ${_vars})
+ message("${_var}=${${_var}}")
+ endforeach()
+ unset(_vars)
+ unset(_var)
+endmacro()
+
diff --git a/build_files/cmake/packaging.cmake b/build_files/cmake/packaging.cmake
index 735d3fd819e..95bbb2b59a8 100644
--- a/build_files/cmake/packaging.cmake
+++ b/build_files/cmake/packaging.cmake
@@ -2,7 +2,6 @@ set(PROJECT_DESCRIPTION "Blender is a very fast and versatile 3D modeller/rende
set(PROJECT_COPYRIGHT "Copyright (C) 2001-2012 Blender Foundation")
set(PROJECT_CONTACT "foundation@blender.org")
set(PROJECT_VENDOR "Blender Foundation")
-set(ORG_WEBSITE "www.blender.org")
set(MAJOR_VERSION ${BLENDER_VERSION_MAJOR})
set(MINOR_VERSION ${BLENDER_VERSION_MINOR})
@@ -32,6 +31,7 @@ if(EXISTS ${CMAKE_SOURCE_DIR}/.git/)
endif()
endif()
set(BUILD_REV ${MY_WC_HASH})
+unset(MY_WC_HASH)
# Force Package Name
@@ -41,7 +41,7 @@ set(CPACK_PACKAGE_FILE_NAME ${PROJECT_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}.${
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
# RPM packages
include(build_files/cmake/RpmBuild.cmake)
- if(RPMBUILD_FOUND AND NOT WIN32)
+ if(RPMBUILD_FOUND)
set(CPACK_GENERATOR "RPM")
set(CPACK_RPM_PACKAGE_RELEASE "git${CPACK_DATE}.${BUILD_REV}")
set(CPACK_SET_DESTDIR "true")
@@ -61,7 +61,25 @@ if(APPLE)
set(CPACK_COMPONENT_LIBRARIES_HIDDEN TRUE)
endif()
-set(CPACK_PACKAGE_EXECUTABLES "blender")
+if(WIN32)
+ set(CPACK_PACKAGE_INSTALL_DIRECTORY "Blender Foundation/Blender")
+ set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "Blender Foundation/Blender")
+
+ set(CPACK_NSIS_MUI_ICON ${CMAKE_SOURCE_DIR}/source/icons/winblender.ico)
+ set(CPACK_NSIS_COMPRESSOR "/SOLID lzma")
+
+ set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/release/text/GPL-license.txt)
+ set(CPACK_WIX_PRODUCT_ICON ${CMAKE_SOURCE_DIR}/source/icons/winblender.ico)
+ set(CPACK_WIX_UPGRADE_GUID "B767E4FD-7DE7-4094-B051-3AE62E13A17A")
+
+ set(CPACK_WIX_UI_BANNER ${LIBDIR}/package/installer_wix/WIX_UI_BANNER.bmp)
+ set(CPACK_WIX_UI_DIALOG ${LIBDIR}/package/installer_wix/WIX_UI_DIALOG.bmp)
+
+ #force lzma instead of deflate
+ set(CPACK_WIX_LIGHT_EXTRA_FLAGS -dcl:high)
+endif()
+
+set(CPACK_PACKAGE_EXECUTABLES "blender" "blender")
include(CPack)
# Target for build_archive.py script, to automatically pass along
@@ -76,6 +94,8 @@ macro(add_package_archive packagename extension)
OUTPUT ${package_output}
COMMAND ${build_archive} ${packagename} ${extension} bin release
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+ unset(build_archive)
+ unset(package_output)
endmacro()
if(APPLE)
diff --git a/build_files/package_spec/build_archive.py b/build_files/package_spec/build_archive.py
index 0329d16b1ec..6a7ec8a0faa 100755
--- a/build_files/package_spec/build_archive.py
+++ b/build_files/package_spec/build_archive.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
# <pep8 compliant>
diff --git a/build_files/package_spec/pacman/PKGBUILD b/build_files/package_spec/pacman/PKGBUILD
index e59d1cf31d7..cc5198a88e3 100644
--- a/build_files/package_spec/pacman/PKGBUILD
+++ b/build_files/package_spec/pacman/PKGBUILD
@@ -17,7 +17,7 @@ else
blender_version_full=${blender_version}
fi
-blender_ver_string=$blender_version+svn$blender_version_full
+blender_ver_string=$blender_version+git$blender_version_full
pkgname=blender-snapshot
pkgver=$blender_ver_string
@@ -27,8 +27,8 @@ arch=('i686' 'x86_64')
url="www.blender.org"
license=('GPL')
groups=()
-depends=('libjpeg' 'libpng' 'openjpeg' 'libtiff' 'openexr' 'python>=3.2' 'gettext' 'libxi' 'libxmu' 'mesa' 'freetype2' 'openal' 'sdl' 'libsndfile' 'ffmpeg')
-makedepends=('cmake' 'svn')
+depends=('libjpeg' 'libpng' 'openjpeg' 'libtiff' 'openexr' 'python>=3.4' 'gettext' 'libxi' 'libxmu' 'mesa' 'freetype2' 'openal' 'sdl' 'libsndfile' 'ffmpeg')
+makedepends=('cmake' 'git')
optdepends=()
provides=()
conflicts=('blender')
@@ -36,7 +36,7 @@ replaces=('blender')
backup=()
options=()
install=blender.install
-# use current svn to make the package.
+# use current git to make the package.
# source=(http://download.blender.org/source/$pkgname-$pkgver.tar.gz)
# md5sums=('27edb80c82c25252d43d6a01980d953a') #generate with 'makepkg -g'
source=()
@@ -51,11 +51,7 @@ build() {
-DCMAKE_BUILD_TYPE:STRING=Release \
-DWITH_INSTALL_PORTABLE:BOOL=OFF \
-DWITH_PYTHON_INSTALL:BOOL=OFF \
- -DWITH_OPENCOLLADA:BOOL=OFF \
- -DPYTHON_VERSION:STRING=3.2 \
- -DPYTHON_LIBPATH:STRING=/usr/lib \
- -DPYTHON_LIBRARY:STRING=python3.2mu \
- -DPYTHON_INCLUDE_DIRS:STRING=/usr/include/python3.2mu
+ -DWITH_OPENCOLLADA:BOOL=OFF
make $MAKEFLAGS
}
diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py
index 338065e5e88..1fb6d649ae9 100644
--- a/build_files/scons/config/darwin-config.py
+++ b/build_files/scons/config/darwin-config.py
@@ -68,7 +68,7 @@ BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib ${BF_FFMPEG}/lib' #ogg libs are stored i
WITH_BF_SDL = True
BF_SDL = LIBDIR + '/sdl' #$(shell sdl-config --prefix)
BF_SDL_INC = '${BF_SDL}/include' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
-BF_SDL_LIB = 'SDL' #BF_SDL #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
+BF_SDL_LIB = 'SDL2' #BF_SDL #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
BF_SDL_LIBPATH = '${BF_SDL}/lib'
WITH_BF_OPENEXR = True
@@ -205,7 +205,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50', 'sm_52']
#Freestyle
WITH_BF_FREESTYLE = True
diff --git a/build_files/scons/config/linux-config.py b/build_files/scons/config/linux-config.py
index d460ece721a..455dd23cdb3 100644
--- a/build_files/scons/config/linux-config.py
+++ b/build_files/scons/config/linux-config.py
@@ -144,7 +144,7 @@ BF_REDCODE_LIB = ''
BF_REDCODE_INC = '${BF_REDCODE}/../' #C files request "libredcode/format.h" which is in "#extern/libredcode/format.h", stupid but compiles for now.
BF_REDCODE_LIBPATH='${BF_REDCODE}/lib'
-# Mesa Libs should go here if your using them as well....
+# Mesa Libs should go here if you're using them as well....
WITH_BF_STATICOPENGL = False
BF_OPENGL = '/usr'
BF_OPENGL_INC = '${BF_OPENGL}/include'
@@ -262,6 +262,6 @@ BF_INSTALLDIR='../install/linux'
#Link against pthread
PLATFORM_LINKFLAGS = ['-pthread']
-#Fix for LLVM conflict with Mesa llvmpipe
-if WITH_BF_LLVM:
- PLATFORM_LINKFLAGS += ['-Wl,--version-script=source/creator/blender.map']
+#Fix for LLVM conflict with Mesa llvmpipe, SDL dynload also requires symbols to be hidden.
+# TODO(sergey): Move this to SConstruct, so we can have this line depended on user config.
+PLATFORM_LINKFLAGS += ['-Wl,--version-script=source/creator/blender.map']
diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py
index 85aa72af19c..87c35e179cb 100644
--- a/build_files/scons/config/win32-mingw-config.py
+++ b/build_files/scons/config/win32-mingw-config.py
@@ -170,6 +170,8 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
+WITH_BF_IME = True
+
WITH_BF_OPENMP = True
#CUDA
@@ -196,7 +198,10 @@ C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement', '-Wstrict-pro
CC_WARN = [ '-Wall' ]
-LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid', '-lwsock32', '-lpsapi']
+LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid', '-lwsock32', '-lpsapi', '-ldbghelp']
+
+if WITH_BF_IME:
+ LLIBS.append('-limm32')
PLATFORM_LINKFLAGS = ['-Xlinker', '--stack=2097152']
diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py
index 6dd853b7da4..9f3b3440628 100644
--- a/build_files/scons/config/win32-vc-config.py
+++ b/build_files/scons/config/win32-vc-config.py
@@ -33,7 +33,7 @@ WITH_BF_PYTHON_INSTALL_NUMPY = True
WITH_BF_OPENAL = True
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include '
-BF_OPENAL_LIB = 'wrap_oal'
+BF_OPENAL_LIB = 'OpenAL32'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
WITH_BF_ICONV = True
@@ -57,7 +57,7 @@ BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib'
WITH_BF_SDL = True
BF_SDL = LIBDIR + '/sdl'
BF_SDL_INC = '${BF_SDL}/include'
-BF_SDL_LIB = 'SDL.lib'
+BF_SDL_LIB = 'SDL2.lib'
BF_SDL_LIBPATH = '${BF_SDL}/lib'
BF_PTHREADS = LIBDIR + '/pthreads'
@@ -69,7 +69,7 @@ WITH_BF_OPENEXR = True
WITH_BF_STATICOPENEXR = False
BF_OPENEXR = LIBDIR + '/openexr'
BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR '
-BF_OPENEXR_LIB = ' Iex-2_1 Half IlmImf-2_1 Imath-2_1 IlmThread-2_1 '
+BF_OPENEXR_LIB = ' Iex-2_2 Half IlmImf-2_2 Imath-2_2 IlmThread-2_2 '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
@@ -151,6 +151,8 @@ BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include/opencollada'
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml pcre buffer ftoa'
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
+WITH_BF_IME = True
+
WITH_BF_3DMOUSE = True
WITH_BF_OPENMP = True
@@ -197,7 +199,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
WITH_BF_CYCLES_CUDA_BINARIES = False
#BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50', 'sm_52']
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
@@ -235,7 +237,10 @@ C_WARN = []
CC_WARN = []
CXX_WARN = []
-LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid', 'psapi']
+LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid', 'psapi', 'Dbghelp']
+
+if WITH_BF_IME:
+ LLIBS.append('imm32')
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/STACK:2097152','/INCREMENTAL:NO', '/LARGEADDRESSAWARE', '/NODEFAULTLIB:msvcrt.lib', '/NODEFAULTLIB:msvcmrt.lib', '/NODEFAULTLIB:msvcurt.lib', '/NODEFAULTLIB:msvcrtd.lib']
diff --git a/build_files/scons/config/win64-mingw-config.py b/build_files/scons/config/win64-mingw-config.py
index 92dcd6db455..57eaae81d49 100644
--- a/build_files/scons/config/win64-mingw-config.py
+++ b/build_files/scons/config/win64-mingw-config.py
@@ -169,6 +169,8 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-mmmx', '-msse', '-msse2']
+WITH_BF_IME = True
+
WITH_BF_OPENMP = True
#Freestyle
@@ -186,11 +188,15 @@ REL_CFLAGS = []
REL_CXXFLAGS = []
REL_CCFLAGS = ['-O2', '-ftree-vectorize']
+# NOTE: C_WARN seems to get ignored - at least -Wno-char-subscripts doesn't work!
C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement', '-Wstrict-prototypes']
-CC_WARN = [ '-Wall' ]
+CC_WARN = [ '-Wall', '-Wno-char-subscripts' ]
+
+LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid', '-lwsock32', '-lpsapi', '-lpthread', '-ldbghelp']
-LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid', '-lwsock32', '-lpsapi', '-lpthread']
+if WITH_BF_IME:
+ LLIBS.append('-limm32')
PLATFORM_LINKFLAGS = ['-Xlinker', '--stack=2097152']
diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py
index f928f166ba7..9ac0173537e 100644
--- a/build_files/scons/config/win64-vc-config.py
+++ b/build_files/scons/config/win64-vc-config.py
@@ -34,7 +34,7 @@ WITH_BF_PYTHON_INSTALL_NUMPY = True
WITH_BF_OPENAL = True
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include '
-BF_OPENAL_LIB = 'wrap_oal'
+BF_OPENAL_LIB = 'OpenAL32'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
WITH_BF_SNDFILE = True
@@ -52,7 +52,7 @@ BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
WITH_BF_SDL = True
BF_SDL = LIBDIR + '/sdl'
BF_SDL_INC = '${BF_SDL}/include'
-BF_SDL_LIB = 'SDL.lib'
+BF_SDL_LIB = 'SDL2.lib'
BF_SDL_LIBPATH = '${BF_SDL}/lib'
WITH_BF_JACK = False
@@ -66,7 +66,7 @@ WITH_BF_OPENEXR = True
WITH_BF_STATICOPENEXR = False
BF_OPENEXR = LIBDIR + '/openexr'
BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR '
-BF_OPENEXR_LIB = ' Iex-2_1 Half IlmImf-2_1 Imath-2_1 IlmThread-2_1 '
+BF_OPENEXR_LIB = ' Iex-2_2 Half IlmImf-2_2 Imath-2_2 IlmThread-2_2 '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
@@ -154,6 +154,8 @@ BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include/opencollada'
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml pcre buffer ftoa'
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada'
+WITH_BF_IME = True
+
WITH_BF_3DMOUSE = True
WITH_BF_OPENMP = True
@@ -200,7 +202,7 @@ BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
#CUDA
WITH_BF_CYCLES_CUDA_BINARIES = False
#BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35', 'sm_50', 'sm_52']
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
@@ -242,7 +244,10 @@ C_WARN = []
CC_WARN = []
CXX_WARN = []
-LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid', 'psapi']
+LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid', 'psapi', 'Dbghelp']
+
+if WITH_BF_IME:
+ LLIBS.append('imm32')
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/STACK:2097152','/OPT:NOREF','/INCREMENTAL:NO', '/NODEFAULTLIB:msvcrt.lib', '/NODEFAULTLIB:msvcmrt.lib', '/NODEFAULTLIB:msvcurt.lib', '/NODEFAULTLIB:msvcrtd.lib']
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index b5853b22455..060904e7cd7 100755..100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -143,7 +143,7 @@ def setup_staticlibs(lenv):
libincs += Split(lenv['BF_FREETYPE_LIBPATH'])
if lenv['WITH_BF_PYTHON']:
libincs += Split(lenv['BF_PYTHON_LIBPATH'])
- if lenv['WITH_BF_SDL']:
+ if lenv['WITH_BF_SDL'] and not lenv['WITH_BF_SDL_DYNLOAD']:
libincs += Split(lenv['BF_SDL_LIBPATH'])
if lenv['WITH_BF_JACK'] and not lenv['WITH_BF_JACK_DYNLOAD']:
libincs += Split(lenv['BF_JACK_LIBPATH'])
@@ -216,16 +216,16 @@ def setup_staticlibs(lenv):
if lenv['WITH_BF_STATICOCIO']:
statlibs += Split(lenv['BF_OCIO_LIB_STATIC'])
- if lenv['WITH_BF_BOOST']:
- libincs += Split(lenv['BF_BOOST_LIBPATH'])
- if lenv['WITH_BF_STATICBOOST']:
- statlibs += Split(lenv['BF_BOOST_LIB_STATIC'])
-
if lenv['WITH_BF_CYCLES_OSL']:
libincs += Split(lenv['BF_OSL_LIBPATH'])
if lenv['WITH_BF_STATICOSL']:
statlibs += Split(lenv['BF_OSL_LIB_STATIC'])
+ if lenv['WITH_BF_BOOST']:
+ libincs += Split(lenv['BF_BOOST_LIBPATH'])
+ if lenv['WITH_BF_STATICBOOST']:
+ statlibs += Split(lenv['BF_BOOST_LIB_STATIC'])
+
if lenv['WITH_BF_LLVM']:
libincs += Split(lenv['BF_LLVM_LIBPATH'])
if lenv['WITH_BF_STATICLLVM']:
@@ -303,7 +303,7 @@ def setup_syslibs(lenv):
if lenv['WITH_BF_ELTOPO']:
syslibs += Split(lenv['BF_LAPACK_LIB'])
'''
- if lenv['WITH_BF_SDL']:
+ if lenv['WITH_BF_SDL'] and not lenv['WITH_BF_SDL_DYNLOAD']:
syslibs += Split(lenv['BF_SDL_LIB'])
if not lenv['WITH_BF_STATICOPENGL']:
syslibs += Split(lenv['BF_OPENGL_LIB'])
@@ -325,16 +325,16 @@ def setup_syslibs(lenv):
if lenv['WITH_BF_3DMOUSE']:
if not lenv['WITH_BF_STATIC3DMOUSE']:
syslibs += Split(lenv['BF_3DMOUSE_LIB'])
-
+
+ if lenv['WITH_BF_CYCLES_OSL'] and not lenv['WITH_BF_STATICOSL']:
+ syslibs += Split(lenv['BF_OSL_LIB'])
+
if lenv['WITH_BF_BOOST'] and not lenv['WITH_BF_STATICBOOST']:
syslibs += Split(lenv['BF_BOOST_LIB'])
-
+
if lenv['WITH_BF_INTERNATIONAL']:
syslibs += Split(lenv['BF_BOOST_LIB_INTERNATIONAL'])
- if lenv['WITH_BF_CYCLES_OSL'] and not lenv['WITH_BF_STATICOSL']:
- syslibs += Split(lenv['BF_OSL_LIB'])
-
if lenv['WITH_BF_LLVM'] and not lenv['WITH_BF_STATICLLVM']:
syslibs += Split(lenv['BF_LLVM_LIB'])
@@ -381,12 +381,19 @@ def creator(env):
defs.append('WITH_BINRELOC')
if env['WITH_BF_SDL']:
+ if env['WITH_BF_SDL_DYNLOAD']:
+ defs.append('WITH_SDL_DYNLOAD')
+ incs.append('#/extern/sdlew/include')
defs.append('WITH_SDL')
if env['WITH_BF_LIBMV']:
incs.append('#/extern/libmv')
defs.append('WITH_LIBMV')
+ if env['WITH_BF_CYCLES'] and env['WITH_BF_CYCLES_LOGGING']:
+ incs.append('#/intern/cycles/blender')
+ defs.append('WITH_CYCLES_LOGGING')
+
if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG')
@@ -647,7 +654,7 @@ def WinPyBundle(target=None, source=None, env=None):
# Extract Numpy
if env['WITH_BF_PYTHON_INSTALL_NUMPY']:
py_tar = env.subst(env['LCGDIR']).lstrip("#")
- py_tar += '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '_numpy_1.8.tar.gz'
+ py_tar += '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '_numpy_1.9.tar.gz'
py_target = env.subst(env['BF_INSTALLDIR']).lstrip("#")
py_target = os.path.join(py_target, VERSION, 'python', 'lib', 'site-packages')
@@ -755,7 +762,7 @@ def AppIt(target=None, source=None, env=None):
commands.getoutput(cmd)
cmd = 'cp -R %s/kernel/*.h %s/kernel/*.cl %s/kernel/*.cu %s/kernel/' % (croot, croot, croot, cinstalldir)
commands.getoutput(cmd)
- cmd = 'cp -R %s/kernel/svm %s/kernel/closure %s/kernel/geom %s/util/util_color.h %s/util/util_half.h %s/util/util_math.h %s/util/util_transform.h %s/util/util_types.h %s/kernel/' % (croot, croot, croot, croot, croot, croot, croot, croot, cinstalldir)
+ cmd = 'cp -R %s/kernel/svm %s/kernel/closure %s/kernel/geom %s/util/util_color.h %s/util/util_half.h %s/util/util_math.h %s/util/util_math_fast.h %s/util/util_transform.h %s/util/util_types.h %s/kernel/' % (croot, croot, croot, croot, croot, croot, croot, croot, croot, cinstalldir)
commands.getoutput(cmd)
cmd = 'cp -R %s/../intern/cycles/kernel/*.cubin %s/lib/' % (builddir, cinstalldir)
commands.getoutput(cmd)
@@ -809,10 +816,6 @@ def AppIt(target=None, source=None, env=None):
instname = env['LCGDIR'][1:] # made libiomp5 part of blender libs
cmd = 'ditto --arch %s %s/openmp/lib/libiomp5.dylib %s/%s.app/Contents/Resources/lib/'%(osxarch, instname, installdir, binary) # copy libiomp5
commands.getoutput(cmd)
- cmd = 'install_name_tool -id @loader_path/../Resources/lib/libiomp5.dylib %s/%s.app/Contents/Resources/lib/libiomp5.dylib'%(installdir, binary) # change id of libiomp5
- commands.getoutput(cmd)
- cmd = 'install_name_tool -change @loader_path/libiomp5.dylib @loader_path/../Resources/lib/libiomp5.dylib %s/%s.app/Contents/MacOS/%s'%(installdir, binary, binary) # change ref to libiomp5 ( blender )
- commands.getoutput(cmd)
# extract copy system python, be sure to update other build systems
# when making changes to the files that are copied.
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index 54af157c60e..aa0631af9fe 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -108,7 +108,7 @@ def validate_arguments(args, bc):
opts_list = [
'WITH_BF_FREESTYLE', 'WITH_BF_PYTHON', 'WITH_BF_PYTHON_SAFETY', 'WITH_BF_PYTHON_SECURITY', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'BF_PYTHON_LIBPATH_ARCH', 'WITH_BF_STATICPYTHON', 'WITH_OSX_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', 'BF_PYTHON_DLL', 'BF_PYTHON_ABI_FLAGS',
'WITH_BF_OPENAL', 'BF_OPENAL', 'BF_OPENAL_INC', 'BF_OPENAL_LIB', 'BF_OPENAL_LIBPATH', 'WITH_BF_STATICOPENAL', 'BF_OPENAL_LIB_STATIC',
- 'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH',
+ 'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH', 'WITH_BF_SDL_DYNLOAD',
'WITH_BF_JACK', 'BF_JACK', 'BF_JACK_INC', 'BF_JACK_LIB', 'BF_JACK_LIBPATH', 'WITH_BF_JACK_DYNLOAD',
'WITH_BF_SNDFILE', 'BF_SNDFILE', 'BF_SNDFILE_INC', 'BF_SNDFILE_LIB', 'BF_SNDFILE_LIBPATH', 'WITH_BF_STATICSNDFILE', 'BF_SNDFILE_LIB_STATIC',
'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
@@ -137,6 +137,7 @@ def validate_arguments(args, bc):
'WITH_BF_FFTW3', 'BF_FFTW3', 'BF_FFTW3_INC', 'BF_FFTW3_LIB', 'BF_FFTW3_LIBPATH', 'WITH_BF_STATICFFTW3', 'BF_FFTW3_LIB_STATIC',
'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC',
'WITH_BF_EGL', 'WITH_BF_GLEW_ES', 'BF_GLEW_INC', 'WITH_BF_GL_PROFILE_CORE', 'WITH_BF_GL_PROFILE_COMPAT', 'WITH_BF_GL_PROFILE_ES20',
+ 'WITH_BF_GLEW_MX', 'WITH_BF_GL_EGL', 'WITH_BF_GL_ANGLE',
'WITH_BF_COLLADA', 'BF_COLLADA', 'BF_COLLADA_INC', 'BF_COLLADA_LIB', 'BF_OPENCOLLADA', 'BF_OPENCOLLADA_INC', 'BF_OPENCOLLADA_LIB', 'BF_OPENCOLLADA_LIBPATH', 'BF_PCRE', 'BF_PCRE_LIB', 'BF_PCRE_LIBPATH', 'BF_EXPAT', 'BF_EXPAT_LIB', 'BF_EXPAT_LIBPATH',
'WITH_BF_STATICOPENCOLLADA', 'BF_OPENCOLLADA_LIB_STATIC',
@@ -174,6 +175,7 @@ def validate_arguments(args, bc):
'WITH_BF_CXX_GUARDEDALLOC',
'WITH_BF_JEMALLOC', 'WITH_BF_STATICJEMALLOC', 'BF_JEMALLOC', 'BF_JEMALLOC_INC', 'BF_JEMALLOC_LIBPATH', 'BF_JEMALLOC_LIB', 'BF_JEMALLOC_LIB_STATIC',
'BUILDBOT_BRANCH',
+ 'WITH_BF_IME',
'WITH_BF_3DMOUSE', 'WITH_BF_STATIC3DMOUSE', 'BF_3DMOUSE', 'BF_3DMOUSE_INC', 'BF_3DMOUSE_LIB', 'BF_3DMOUSE_LIBPATH', 'BF_3DMOUSE_LIB_STATIC',
'WITH_BF_CYCLES', 'WITH_BF_CYCLES_CUDA_BINARIES', 'BF_CYCLES_CUDA_NVCC', 'BF_CYCLES_CUDA_NVCC', 'WITH_BF_CYCLES_CUDA_THREADED_COMPILE', 'BF_CYCLES_CUDA_ENV',
'WITH_BF_OIIO', 'WITH_BF_STATICOIIO', 'BF_OIIO', 'BF_OIIO_INC', 'BF_OIIO_LIB', 'BF_OIIO_LIB_STATIC', 'BF_OIIO_LIBPATH',
@@ -197,7 +199,8 @@ def validate_arguments(args, bc):
'C_WARN', 'CC_WARN', 'CXX_WARN',
'LLIBS', 'PLATFORM_LINKFLAGS', 'MACOSX_ARCHITECTURE', 'MACOSX_SDK', 'XCODE_CUR_VER', 'C_COMPILER_ID',
'BF_CYCLES_CUDA_BINARIES_ARCH', 'BF_PROGRAM_LINKFLAGS', 'MACOSX_DEPLOYMENT_TARGET',
- 'WITH_BF_CYCLES_DEBUG'
+ 'WITH_BF_CYCLES_DEBUG', 'WITH_BF_CYCLES_LOGGING',
+ 'WITH_BF_CPP11'
]
@@ -301,6 +304,7 @@ def read_opts(env, cfg, args):
('BF_SDL_INC', 'SDL include path', ''),
('BF_SDL_LIB', 'SDL library', ''),
('BF_SDL_LIBPATH', 'SDL library path', ''),
+ (BoolVariable('WITH_BF_SDL_DYNLOAD', 'Enable runtime dynamic SDL libraries loading (works only on Linux)', False)),
(BoolVariable('WITH_BF_JACK', 'Enable jack support if true', True)),
('BF_JACK', 'jack base path', ''),
@@ -467,7 +471,7 @@ def read_opts(env, cfg, args):
('BF_OPENGL_LIB_STATIC', 'OpenGL static libraries', ''),
('BF_OPENGL_LINKFLAGS', 'OpenGL link flags', ''),
- (BoolVariable('WITH_BF_GLEW_MX', '', True)),
+ (BoolVariable('WITH_BF_GLEW_MX', '', False)),
(BoolVariable('WITH_BF_GLEW_ES', '', False)),
(BoolVariable('WITH_BF_GL_EGL', '', False)),
(BoolVariable('WITH_BF_GL_PROFILE_COMPAT', '', True)),
@@ -507,6 +511,8 @@ def read_opts(env, cfg, args):
(BoolVariable('WITH_BF_PLAYER', 'Build blenderplayer if true', False)),
(BoolVariable('WITH_BF_NOBLENDER', 'Do not build blender if true', False)),
+ (BoolVariable('WITH_BF_IME', 'Enable Input Method Editor (IME) for complex Asian character input', False)),
+
(BoolVariable('WITH_BF_3DMOUSE', 'Build blender with support of 3D mouses', False)),
(BoolVariable('WITH_BF_STATIC3DMOUSE', 'Staticly link to 3d mouse library', False)),
('BF_3DMOUSE', '3d mouse library base path', ''),
@@ -605,6 +611,7 @@ def read_opts(env, cfg, args):
('BF_CYCLES_CUDA_ENV', 'preset environement nvcc will execute in', ''),
('BF_CYCLES_CUDA_BINARIES_ARCH', 'CUDA architectures to compile binaries for', []),
(BoolVariable('WITH_BF_CYCLES_DEBUG', 'Build Cycles engine with extra debugging capabilities', False)),
+ (BoolVariable('WITH_BF_CYCLES_LOGGING', 'Build Cycles engine with logging support', True)),
(BoolVariable('WITH_BF_OIIO', 'Build with OpenImageIO', False)),
(BoolVariable('WITH_BF_STATICOIIO', 'Statically link to OpenImageIO', False)),
@@ -649,7 +656,9 @@ def read_opts(env, cfg, args):
('BF_LLVM_LIBPATH', 'LLVM library path', ''),
('BF_LLVM_LIB_STATIC', 'LLVM static library', ''),
- ('BF_PROGRAM_LINKFLAGS', 'Link flags applied only to final binaries (blender and blenderplayer, not makesrna/makesdna)', '')
+ ('BF_PROGRAM_LINKFLAGS', 'Link flags applied only to final binaries (blender and blenderplayer, not makesrna/makesdna)', ''),
+
+ (BoolVariable('WITH_BF_CPP11', '"Build with C++11 standard enabled, for development use only!', False)),
) # end of opts.AddOptions()
return localopts
diff --git a/build_files/utils/build_tgz.sh b/build_files/utils/build_tgz.sh
index 16899fd34b2..3c921081c29 100755
--- a/build_files/utils/build_tgz.sh
+++ b/build_files/utils/build_tgz.sh
@@ -25,7 +25,16 @@ TARBALL="blender-$VERSION.tar.gz"
cd "$blender_srcdir"
# not so nice, but works
-FILTER_FILES_PY="import os, sys; [print(l[:-1]) for l in sys.stdin.readlines() if os.path.isfile(l[:-1])]"
+FILTER_FILES_PY=\
+"import os, sys; "\
+"[print(l[:-1]) for l in sys.stdin.readlines() "\
+"if os.path.isfile(l[:-1]) "\
+"if os.path.basename(l[:-1]) not in {"\
+"'.gitignore', "\
+"'.gitmodules', "\
+"'.arcconfig', "\
+"}"\
+"]"
# Build master list
echo -n "Building manifest of files: \"$BASE_DIR/$MANIFEST\" ..."
diff --git a/doc/blender_file_format/BlendFileDnaExporter_25.py b/doc/blender_file_format/BlendFileDnaExporter_25.py
index 837b67c6eed..64c92c7cf80 100755
--- a/doc/blender_file_format/BlendFileDnaExporter_25.py
+++ b/doc/blender_file_format/BlendFileDnaExporter_25.py
@@ -112,7 +112,7 @@ class DNACatalogHTML:
# ${version} and ${revision}
if bpy:
version = '.'.join(map(str, bpy.app.version))
- revision = bpy.app.build_revision[:-1]
+ revision = bpy.app.build_hash
else:
version = str(header.Version)
revision = 'Unknown'
@@ -404,7 +404,7 @@ def main():
# Files
if '--dna-versioned' in sys.argv:
blender_version = '_'.join(map(str, bpy.app.version))
- filename = 'dna-{0}-{1}_endian-{2}-r{3}'.format(sys.arch, sys.byteorder, blender_version, bpy.app.build_revision[2:-1])
+ filename = 'dna-{0}-{1}_endian-{2}-{3}'.format(sys.arch, sys.byteorder, blender_version, bpy.app.build_hash)
else:
filename = 'dna'
dir = os.path.dirname(__file__)
@@ -451,7 +451,7 @@ def main():
os.remove(Path_Blend)
# export dna to xhtml
- log.info("6: export sdna to xhtml file")
+ log.info("6: export sdna to xhtml file: %r" % Path_HTML)
handleHTML = open(Path_HTML, "w")
catalog.WriteToHTML(handleHTML)
handleHTML.close()
diff --git a/doc/build_systems/scons-dev.txt b/doc/build_systems/scons-dev.txt
index ae2be2b2a94..9ca072c38c5 100644
--- a/doc/build_systems/scons-dev.txt
+++ b/doc/build_systems/scons-dev.txt
@@ -35,13 +35,14 @@
defaults.
Much of the actual functionality can be found in the python scripts
- in the directory $BLENDERHOME/tools, with Blender.py defining the
- bulk of the functionality. btools.py has some helper functions, and
- bcolors.py is for the terminal colors. mstoolkit.py and crossmingw.py
- are modules which set up SCons for the MS VC++ 2003 toolkit and
- the cross-compile toolset for compiling Windows binaries on Linux
- respectively. Note: the cross-compile doesn't work yet for Blender,
- but is added in preparation for having it work in the distant future.
+ in the directory $BLENDERHOME/build_files/scons/tools, with
+ Blender.py defining the bulk of the functionality. btools.py has some
+ helper functions, and bcolors.py is for the terminal
+ colors. mstoolkit.py and crossmingw.py are modules which set up SCons
+ for the MS VC++ 2003 toolkit and the cross-compile toolset for
+ compiling Windows binaries on Linux respectively. Note: the
+ cross-compile doesn't work yet for Blender, but is added in
+ preparation for having it work in the distant future.
BlenderEnvironment
------------------
diff --git a/doc/build_systems/scons.txt b/doc/build_systems/scons.txt
index cb88c56ddbc..e3438f1fe04 100644
--- a/doc/build_systems/scons.txt
+++ b/doc/build_systems/scons.txt
@@ -29,9 +29,9 @@
a scons-local installation, which can be found in the scons/ subdirectory.
This document uses the scons-local installation for its examples.
- Check from the page
- http://www.blender.org/development/building-blender/getting-dependencies/
- that you have all dependencies needed for building Blender. Note that for
+ For build instructions, including dependencies, consult the appropriate
+ section for your platform at
+ http://wiki.blender.org/index.php/Dev:Doc/Building_Blender. Note that for
windows many of these dependencies already come in the lib/windows module
from CVS.
@@ -53,12 +53,13 @@
from the command-line is given, then all libraries and binaries to
build are configured.
- The build uses BF_BUILDDIR to build into and BF_INSTALLDIR to
- finally copy all needed files to get a proper setup. The BF_DOCDIR is
- used to generate Blender Python documentation files to. These
- variables have default values for every platform in
- $BLENDERHOME/config/(platform)-config.py. After the build successfully
- completes, you can find everything you need in BF_INSTALLDIR.
+ The build uses BF_BUILDDIR to build into and BF_INSTALLDIR to finally copy
+ all needed files to get a proper setup. The BF_DOCDIR is used to generate
+ Blender Python documentation files to. These variables have default values
+ for every platform in
+ $BLENDERHOME/build_files/scons/config/(platform)-config.py. See the next
+ section of this document for how to customize these paths. After the build
+ successfully completes, you can find everything you need in BF_INSTALLDIR.
If you want to create the installer package of Blender on Windows you'll
need to install nullsoft scriptable install system from http://nsis.sf.net.
@@ -72,8 +73,8 @@
---------------------
The default values for your platform can be found in the directory
- $BLENDERHOME/config. Your platform specific defaults are in
- (platform)-config.py, where platform is one of:
+ $BLENDERHOME/build_files/scons/config. Your platform specific defaults are
+ in (platform)-config.py, where platform is one of:
- linux, for machines running Linux
- win32-vc, for Windows machines, compiling with a Microsoft compiler
@@ -81,12 +82,13 @@
- darwin, for OS X machines
(TBD: add cygwin, solaris and freebsd support)
- These files you will normally not change. If you need to override
- a default value, make a file called $BLENDERHOME/user-config.py, and copy
- settings from the config/(platform)-config.py that you want to change. Don't
- copy the entire file (unless explicitely stated in the configuration file),
- because you may not get updated options you don't change yourself, which may
- result in build errors.
+ These files you will normally not change. If you need to override a
+ default value, make a file called $BLENDERHOME/user-config.py, and copy
+ settings from the build_files/scons/config/(platform)-config.py that you
+ want to change. Don't copy the entire file (unless explicitly stated in
+ the configuration file), because you may not get updated options you don't
+ change yourself, which may result in build errors. You should NEVER have
+ to modify $BLENDERHOME/build_files/scons/config/(platform)-config.py.
You can use BF_CONFIG argument to override the default user-config.py
check. This is just like the user-config.py, but just with another name:
@@ -113,11 +115,6 @@
(unless you have overridden any of them in your
$BLENDERHOME/user-config.py).
- NOTE: The best way to avoid confusion is the
- copy $BLENDERHOME/config/(platform)-config.py to
- $BLENDERHOME/user-config.py. You should NEVER have to modify
- $BLENDERHOME/config/(platform)-config.py
-
Configuring the output
----------------------
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
index 397cc301627..3865729fe56 100644
--- a/doc/doxygen/Doxyfile
+++ b/doc/doxygen/Doxyfile
@@ -34,7 +34,7 @@ PROJECT_NAME = Blender
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = "V2.6x"
+PROJECT_NUMBER = "V2.7x"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
diff --git a/doc/doxygen/doxygen.main b/doc/doxygen/doxygen.main
index 188382d6a9c..7f63764d7c6 100644
--- a/doc/doxygen/doxygen.main
+++ b/doc/doxygen/doxygen.main
@@ -7,7 +7,7 @@
* These pages document the source code of blender.
*
* \subsection implinks Important Links
- * - <a href="http://projects.blender.org">projects.blender.org</a> with <a href="http://projects.blender.org/tracker/index.php?group_id=9&atid=498">bug tracker</a>
+ * - <a href="http://developer.blender.org">developer.blender.org</a> with bug tracker
* - <a href="http://wiki.blender.org/index.php/Dev:Contents">Development documents</a> on our wiki.
*
* \subsection blother Other
diff --git a/doc/manpage/blender.1.py b/doc/manpage/blender.1.py
index 77f5c5e4f16..cdd2d7ca2df 100755
--- a/doc/manpage/blender.1.py
+++ b/doc/manpage/blender.1.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
# ##### BEGIN GPL LICENSE BLOCK #####
#
diff --git a/doc/python_api/examples/bpy.types.Panel.2.py b/doc/python_api/examples/bpy.types.Panel.2.py
index a4b2f1fd338..261430f1396 100644
--- a/doc/python_api/examples/bpy.types.Panel.2.py
+++ b/doc/python_api/examples/bpy.types.Panel.2.py
@@ -7,7 +7,7 @@ A mix-in parent class can be used to share common properties and
import bpy
-class View3DPanel():
+class View3DPanel:
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
diff --git a/doc/python_api/examples/mathutils.Quaternion.py b/doc/python_api/examples/mathutils.Quaternion.py
index d8c696e6ba6..7e5538b7a96 100644
--- a/doc/python_api/examples/mathutils.Quaternion.py
+++ b/doc/python_api/examples/mathutils.Quaternion.py
@@ -21,3 +21,12 @@ print(quat_out)
print("%.2f, %.2f, %.2f" % tuple(math.degrees(a) for a in quat_out.to_euler()))
print("(%.2f, %.2f, %.2f), %.2f" % (quat_out.axis[:] +
(math.degrees(quat_out.angle), )))
+
+# multiple rotations can be interpolated using the exponential map
+quat_c = mathutils.Quaternion((1.0, 0.0, 0.0), math.radians(15.0))
+exp_avg = (quat_a.to_exponential_map() +
+ quat_b.to_exponential_map() +
+ quat_c.to_exponential_map()) / 3.0
+quat_avg = mathutils.Quaternion(exp_avg)
+print("Average rotation:")
+print(quat_avg)
diff --git a/doc/python_api/examples/mathutils.Vector.py b/doc/python_api/examples/mathutils.Vector.py
index 14b8829c3b5..3f79fdebff1 100644
--- a/doc/python_api/examples/mathutils.Vector.py
+++ b/doc/python_api/examples/mathutils.Vector.py
@@ -18,16 +18,16 @@ matrix = mathutils.Matrix()
# Comparison operators can be done on Vector classes:
-# greater and less then test vector length.
+# (In)equality operators == and != test component values, e.g. 1,2,3 != 3,2,1
+vec_a == vec_b
+vec_a != vec_b
+
+# Ordering operators >, >=, > and <= test vector length.
vec_a > vec_b
vec_a >= vec_b
vec_a < vec_b
vec_a <= vec_b
-# ==, != test vector values e.g. 1,2,3 != 3,2,1 even if they are the same length
-vec_a == vec_b
-vec_a != vec_b
-
# Math can be performed on Vector classes
vec_a + vec_b
diff --git a/doc/python_api/rst/bge.render.rst b/doc/python_api/rst/bge.render.rst
index 9dd4057c82f..77d5bd71761 100644
--- a/doc/python_api/rst/bge.render.rst
+++ b/doc/python_api/rst/bge.render.rst
@@ -8,9 +8,13 @@ Intro
.. module:: bge.render
+Example of using a :class:`bge.types.SCA_MouseSensor`, and two :class:`bge.types.KX_ObjectActuator` to implement MouseLook:
+
+.. note::
+ This can also be achieved with the :class:`bge.types.KX_MouseActuator`.
+
.. code-block:: python
- # Example Uses an L{SCA_MouseSensor}, and two L{KX_ObjectActuator}s to implement MouseLook::
# To use a mouse movement sensor "Mouse" and a
# motion actuator to mouse look:
import bge
@@ -75,6 +79,14 @@ Constants
Enables adaptive vsync if supported. Adaptive vsync enables vsync if the framerate is above the monitors refresh rate. Otherwise, vsync is diabled if the framerate is too low.
+.. data:: LEFT_EYE
+
+ Left eye being used during stereoscopic rendering.
+
+.. data:: RIGHT_EYE
+
+ Right eye being used during stereoscopic rendering.
+
*********
Functions
*********
@@ -217,6 +229,15 @@ Functions
:rtype: float
+.. function:: getStereoEye()
+
+ Gets the current stereoscopy eye being rendered.
+ This function is mainly used in a :class:`bge.types.KX_Scene.pre_draw` callback
+ function to customize the camera projection matrices for each
+ stereoscopic eye.
+
+ :rtype: LEFT_EYE, RIGHT_EYE
+
.. function:: setMaterialMode(mode)
Set the material mode to use for OpenGL rendering.
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst b/doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst
index 4d9dd5b5c34..e326892a824 100644
--- a/doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst
+++ b/doc/python_api/rst/bge_types/bge.types.KX_CharacterWrapper.rst
@@ -37,7 +37,7 @@ base class --- :class:`PyObjectPlus`
The speed and direction the character is traveling in using world coordinates. This should be used instead of applyMovement() to properly move the character.
- :type: list [x, y, z]
+ :type: Vector((x, y, z))
.. method:: jump()
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
index a6d03dee1a1..8d6996dc401 100644
--- a/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
+++ b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
@@ -78,6 +78,27 @@ base class --- :class:`SCA_IObject`
The object must have a physics controller for the mass to be applied, otherwise the mass value will be returned as 0.0.
+ .. attribute:: linearDamping
+
+ The object's linear damping, also known as translational damping. Can be set simultaneously with angular damping using the :py:meth:`setDamping` method.
+
+ :type: float between 0 and 1 inclusive.
+
+ .. note::
+
+ The object must have a physics controller for the linear damping to be applied, otherwise the value will be returned as 0.0.
+
+ .. attribute:: angularDamping
+
+ The object's angular damping, also known as rotationation damping. Can be set simultaneously with linear damping using the :py:meth:`setDamping` method.
+
+ :type: float between 0 and 1 inclusive.
+
+ .. note::
+
+ The object must have a physics controller for the angular damping to be applied, otherwise the value will be returned as 0.0.
+
+
.. attribute:: linVelocityMin
Enforces the object keeps moving at a minimum velocity.
@@ -114,7 +135,7 @@ base class --- :class:`SCA_IObject`
the object's inertia vector in local coordinates. Read only.
- :type: list [ix, iy, iz]
+ :type: Vector((ix, iy, iz))
.. attribute:: parent
@@ -124,21 +145,58 @@ base class --- :class:`SCA_IObject`
.. attribute:: groupMembers
- Returns the list of group members if the object is a group object, otherwise None is returned.
+ Returns the list of group members if the object is a group object (dupli group instance), otherwise None is returned.
:type: :class:`CListValue` of :class:`KX_GameObject` or None
.. attribute:: groupObject
- Returns the group object that the object belongs to or None if the object is not part of a group.
+ Returns the group object (dupli group instance) that the object belongs to or None if the object is not part of a group.
:type: :class:`KX_GameObject` or None
.. attribute:: collisionCallbacks
- A list of callables to be run when a collision occurs.
+ A list of functions to be called when a collision occurs.
- :type: list
+ :type: list of functions and/or methods
+
+ Callbacks should either accept one argument `(object)`, or three
+ arguments `(object, point, normal)`. For simplicity, per
+ colliding object only the first collision point is reported.
+
+ .. code-block:: python
+
+ # Function form
+ def callback_three(object, point, normal):
+ print('Hit by %r at %s with normal %s' % (object.name, point, normal))
+
+ def callback_one(object):
+ print('Hit by %r' % object.name)
+
+ def register_callback(controller):
+ controller.owner.collisionCallbacks.append(callback_three)
+ controller.owner.collisionCallbacks.append(callback_one)
+
+
+ # Method form
+ class YourGameEntity(bge.types.KX_GameObject):
+ def __init__(self, old_owner):
+ self.collisionCallbacks.append(self.on_collision_three)
+ self.collisionCallbacks.append(self.on_collision_one)
+
+ def on_collision_three(self, object, point, normal):
+ print('Hit by %r at %s with normal %s' % (object.name, point, normal))
+
+ def on_collision_one(self, object):
+ print('Hit by %r' % object.name)
+
+ .. note::
+ For backward compatibility, a callback with variable number of
+ arguments (using `*args`) will be passed only the `object`
+ argument. Only when there is more than one fixed argument (not
+ counting `self` for methods) will the three-argument form be
+ used.
.. attribute:: scene
@@ -374,6 +432,12 @@ base class --- :class:`SCA_IObject`
If true, the object's and children's debug properties will be displayed on screen.
:type: boolean
+
+ .. attribute:: currentLodLevel
+
+ The index of the level of detail (LOD) currently used by this object (read-only).
+
+ :type: int
.. method:: endObject()
@@ -496,7 +560,7 @@ base class --- :class:`SCA_IObject`
* True: you get the "local" velocity ie: relative to object orientation.
:type local: boolean
:return: the object's linear velocity.
- :rtype: list [vx, vy, vz]
+ :rtype: Vector((vx, vy, vz))
.. method:: setLinearVelocity(velocity, local=False)
@@ -523,7 +587,7 @@ base class --- :class:`SCA_IObject`
* True: you get the "local" velocity ie: relative to object orientation.
:type local: boolean
:return: the object's angular velocity.
- :rtype: list [vx, vy, vz]
+ :rtype: Vector((vx, vy, vz))
.. method:: setAngularVelocity(velocity, local=False)
@@ -547,7 +611,7 @@ base class --- :class:`SCA_IObject`
:arg point: optional point to return the velocity for, in local coordinates.
:type point: 3D Vector
:return: the velocity at the specified point.
- :rtype: list [vx, vy, vz]
+ :rtype: Vector((vx, vy, vz))
.. method:: getReactionForce()
@@ -557,7 +621,7 @@ base class --- :class:`SCA_IObject`
This also includes impulses, eg from collisions.
:return: the reaction force of this object.
- :rtype: list [fx, fy, fz]
+ :rtype: Vector((fx, fy, fz))
.. note::
@@ -580,6 +644,15 @@ base class --- :class:`SCA_IObject`
* True: you get the "local" impulse ie: relative to local coordinates with object orientation.
:type local: boolean
+ .. method:: setDamping(linear_damping, angular_damping)
+
+ Sets both the :py:attr:`linearDamping` and :py:attr:`angularDamping` simultaneously. This is more efficient than setting both properties individually.
+
+ :arg linear_damping: Linear ("translational") damping factor.
+ :type linear_damping: float ∈ [0, 1]
+ :arg angular_damping: Angular ("rotational") damping factor.
+ :type angular_damping: float ∈ [0, 1]
+
.. method:: suspendDynamics()
Suspends physics for this object.
@@ -876,4 +949,4 @@ base class --- :class:`SCA_IObject`
:arg name: name of the property that added to the debug list.
:type name: string
:arg debug: the debug state.
- :type debug: boolean \ No newline at end of file
+ :type debug: boolean
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_ObjectActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_ObjectActuator.rst
index f10f101a4cc..347b000be3d 100644
--- a/doc/python_api/rst/bge_types/bge.types.KX_ObjectActuator.rst
+++ b/doc/python_api/rst/bge_types/bge.types.KX_ObjectActuator.rst
@@ -15,7 +15,7 @@ base class --- :class:`SCA_IActuator`
The force applied by the actuator.
- :type: list [x, y, z]
+ :type: Vector((x, y, z))
.. attribute:: useLocalForce
@@ -27,7 +27,7 @@ base class --- :class:`SCA_IActuator`
The torque applied by the actuator.
- :type: list [x, y, z]
+ :type: Vector((x, y, z))
.. attribute:: useLocalTorque
@@ -39,7 +39,7 @@ base class --- :class:`SCA_IActuator`
The displacement vector applied by the actuator.
- :type: list [x, y, z]
+ :type: Vector((x, y, z))
.. attribute:: useLocalDLoc
@@ -51,7 +51,7 @@ base class --- :class:`SCA_IActuator`
The angular displacement vector applied by the actuator
- :type: list [x, y, z]
+ :type: Vector((x, y, z))
.. note::
@@ -67,7 +67,7 @@ base class --- :class:`SCA_IActuator`
The linear velocity applied by the actuator.
- :type: list [x, y, z]
+ :type: Vector((x, y, z))
.. attribute:: useLocalLinV
@@ -83,7 +83,7 @@ base class --- :class:`SCA_IActuator`
The angular velocity applied by the actuator.
- :type: list [x, y, z]
+ :type: Vector((x, y, z))
.. attribute:: useLocalAngV
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_Scene.rst b/doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
index f2dad58731c..fc5ba357add 100644
--- a/doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
+++ b/doc/python_api/rst/bge_types/bge.types.KX_Scene.rst
@@ -123,7 +123,7 @@ base class --- :class:`PyObjectPlus`
The scene gravity using the world x, y and z axis.
- :type: list [fx, fy, fz]
+ :type: Vector((gx, gy, gz))
.. method:: addObject(object, other, time=0)
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst b/doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst
index 9340d33f8a9..631075363ca 100644
--- a/doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst
+++ b/doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst
@@ -11,22 +11,25 @@ base class --- :class:`PyObjectPlus`
TODO - description
- .. method:: addWheel(wheel, attachPos, attachDir, axleDir, suspensionRestLength, wheelRadius, hasSteering)
+ .. method:: addWheel(wheel, attachPos, downDir, axleDir, suspensionRestLength, wheelRadius, hasSteering)
Add a wheel to the vehicle
:arg wheel: The object to use as a wheel.
- :type wheel: :class:`KX_GameObject` or a KX_GameObject name
- :arg attachPos: The position that this wheel will attach to.
+ :type wheel: :class:`KX_GameObject` or a :class:`KX_GameObject` name
+ :arg attachPos: The position to attach the wheel, relative to the chassis object center.
:type attachPos: vector of 3 floats
- :arg attachDir: The direction this wheel points.
- :type attachDir: vector of 3 floats
- :arg axleDir: The direction of this wheels axle.
+ :arg downDir: The direction vector pointing down to where the vehicle should collide with the floor.
+ :type downDir: vector of 3 floats
+ :arg axleDir: The axis the wheel rotates around, relative to the chassis.
:type axleDir: vector of 3 floats
- :arg suspensionRestLength: TODO - Description
+ :arg suspensionRestLength: The length of the suspension when no forces are being applied.
:type suspensionRestLength: float
- :arg wheelRadius: The size of the wheel.
+ :arg wheelRadius: The radius of the wheel (half the diameter).
:type wheelRadius: float
+ :arg hasSteering: True if the wheel should turn with steering, typically used in front wheels.
+ :type hasSteering: boolean
+
.. method:: applyBraking(force, wheelIndex)
@@ -38,6 +41,7 @@ base class --- :class:`PyObjectPlus`
:arg wheelIndex: index of the wheel where the force needs to be applied
:type wheelIndex: integer
+
.. method:: applyEngineForce(force, wheelIndex)
Apply an engine force to the specified wheel
@@ -48,6 +52,7 @@ base class --- :class:`PyObjectPlus`
:arg wheelIndex: index of the wheel where the force needs to be applied
:type wheelIndex: integer
+
.. method:: getConstraintId()
Get the constraint ID
diff --git a/doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst b/doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst
index 9c0d1169d49..73d692770d6 100644
--- a/doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst
+++ b/doc/python_api/rst/bge_types/bge.types.KX_VertexProxy.rst
@@ -17,25 +17,25 @@ base class --- :class:`SCA_IObject`
The position of the vertex.
- :type: list [x, y, z]
+ :type: Vector((x, y, z))
.. attribute:: UV
The texture coordinates of the vertex.
- :type: list [u, v]
+ :type: Vector((u, v))
.. attribute:: normal
The normal of the vertex.
- :type: list [nx, ny, nz]
+ :type: Vector((nx, ny, nz))
.. attribute:: color
The color of the vertex.
- :type: list [r, g, b, a]
+ :type: Vector((r, g, b, a))
Black = [0.0, 0.0, 0.0, 1.0], White = [1.0, 1.0, 1.0, 1.0]
@@ -110,13 +110,13 @@ base class --- :class:`SCA_IObject`
Gets the position of this vertex.
:return: this vertexes position in local coordinates.
- :rtype: list [x, y, z]
+ :rtype: Vector((x, y, z))
.. method:: setXYZ(pos)
Sets the position of this vertex.
- :type: list [x, y, z]
+ :type: Vector((x, y, z))
:arg pos: the new position for this vertex in local coordinates.
@@ -125,26 +125,26 @@ base class --- :class:`SCA_IObject`
Gets the UV (texture) coordinates of this vertex.
:return: this vertexes UV (texture) coordinates.
- :rtype: list [u, v]
+ :rtype: Vector((u, v))
.. method:: setUV(uv)
Sets the UV (texture) coordinates of this vertex.
- :type: list [u, v]
+ :type: Vector((u, v))
.. method:: getUV2()
Gets the 2nd UV (texture) coordinates of this vertex.
:return: this vertexes UV (texture) coordinates.
- :rtype: list [u, v]
+ :rtype: Vector((u, v))
.. method:: setUV2(uv, unit)
Sets the 2nd UV (texture) coordinates of this vertex.
- :type: list [u, v]
+ :type: Vector((u, v))
:arg unit: optional argument, FLAT==1, SECOND_UV==2, defaults to SECOND_UV
:arg unit: integer
@@ -197,7 +197,7 @@ base class --- :class:`SCA_IObject`
Gets the normal vector of this vertex.
:return: normalized normal vector.
- :rtype: list [nx, ny, nz]
+ :rtype: Vector((nx, ny, nz))
.. method:: setNormal(normal)
diff --git a/doc/python_api/rst/bge_types/bge.types.SCA_PythonMouse.rst b/doc/python_api/rst/bge_types/bge.types.SCA_PythonMouse.rst
index b1c6e5d1487..5dfa78d3942 100644
--- a/doc/python_api/rst/bge_types/bge.types.SCA_PythonMouse.rst
+++ b/doc/python_api/rst/bge_types/bge.types.SCA_PythonMouse.rst
@@ -25,7 +25,7 @@ base class --- :class:`PyObjectPlus`
The normalized x and y position of the mouse cursor.
- :type: list [x, y]
+ :type: tuple (x, y)
.. attribute:: visible
diff --git a/doc/python_api/rst/bgl.rst b/doc/python_api/rst/bgl.rst
index dfdb4a17998..67d0c59aa32 100644
--- a/doc/python_api/rst/bgl.rst
+++ b/doc/python_api/rst/bgl.rst
@@ -8,19 +8,17 @@ This module wraps OpenGL constants and functions, making them available from
within Blender Python.
The complete list can be retrieved from the module itself, by listing its
-contents: dir(bgl). A simple search on the net can point to more
+contents: dir(bgl). A simple search on the web can point to more
than enough material to teach OpenGL programming, from books to many
collections of tutorials.
-The "red book": "I{OpenGL Programming Guide: The Official Guide to Learning
-OpenGL}" and the online NeHe tutorials are two of the best resources.
+Here is a comprehensive `list of books <http://www.opengl.org/documentation/books/>`_ (non free). The `arcsynthesis tutorials <http://www.arcsynthesis.org/gltut/>`_ is one of the best resources to learn modern OpenGL and `g-truc <http://www.g-truc.net/post-tech-content-sample.html>`_ offers a set of extensive examples, including advanced features.
+
.. note::
You can use the :class:`Image` type to load and set textures.
See :class:`Image.gl_load` and :class:`Image.gl_load`,
for example.
- `OpenGL.org <http://www.opengl.org>`_
- `NeHe GameDev <http://nehe.gamedev.net>`_
.. function:: glAccum(op, value):
diff --git a/doc/python_api/rst/info_quickstart.rst b/doc/python_api/rst/info_quickstart.rst
index a1052bf4208..dc1bba01f00 100644
--- a/doc/python_api/rst/info_quickstart.rst
+++ b/doc/python_api/rst/info_quickstart.rst
@@ -11,32 +11,22 @@ This API is generally stable but some areas are still being added and improved.
The Blender/Python API can do the following:
-* Edit any data the user interface can (Scenes, Meshes, Particles etc.)
-
-* Modify user preferences, keymaps and themes
-
-* Run tools with own settings
-
-* Create user interface elements such as menus, headers and panels
-
-* Create new tools
-
-* Create interactive tools
-
-* Create new rendering engines that integrate with Blender
-
-* Define new settings in existing Blender data
-
-* Draw in the 3D view using OpenGL commands from Python
+- Edit any data the user interface can (Scenes, Meshes, Particles etc.)
+- Modify user preferences, keymaps and themes
+- Run tools with own settings
+- Create user interface elements such as menus, headers and panels
+- Create new tools
+- Create interactive tools
+- Create new rendering engines that integrate with Blender
+- Define new settings in existing Blender data
+- Draw in the 3D view using OpenGL commands from Python
The Blender/Python API **can't** (yet)...
-* Create new space types.
-
-* Assign custom properties to every type.
-
-* Define callbacks or listeners to be notified when data is changed.
+- Create new space types.
+- Assign custom properties to every type.
+- Define callbacks or listeners to be notified when data is changed.
Before Starting
@@ -47,23 +37,21 @@ This document isn't intended to fully cover each topic. Rather, its purpose is t
A quick list of helpful things to know before starting:
-* Blender uses Python 3.x; some 3rd party extensions are not available yet.
-
-* The interactive console is great for testing one-liners, It also has autocompletion so you can inspect the api quickly.
-
-* Button tool tips show Python attributes and operator names.
-
-* Right clicking on buttons and menu items directly links to API documentation.
-
-* For more examples, the text menu has a templates section where some example operators can be found.
+- Blender uses Python 3.x; some online documentation still assumes 2.x.
+- The interactive console is great for testing one-liners, It also has autocompletion so you can inspect the API quickly.
+- Button tool tips show Python attributes and operator names.
+- Right clicking on buttons and menu items directly links to API documentation.
+- For more examples, the text menu has a templates section where some example operators can be found.
+- To examine further scripts distributed with Blender, see:
-* To examine further scripts distributed with Blender, see ``~/.blender/scripts/startup/bl_ui`` for the user interface and ``~/.blender/scripts/startup/bl_op`` for operators.
+ | ``~/.blender/scripts/startup/bl_ui`` for the user interface,
+ | ``~/.blender/scripts/startup/bl_op`` for operators.
Running Scripts
---------------
-The two most common ways to execute python scripts are using the built-in text editor or entering commands in the python console.
+The two most common ways to execute Python scripts are using the built-in text editor or entering commands in the Python console.
Both the **Text Editor** and **Python Console** are space types you can select from the view header.
@@ -82,7 +70,7 @@ Key Concepts
Data Access
-----------
-Accessing datablocks
+Accessing DataBlocks
^^^^^^^^^^^^^^^^^^^^
Python accesses Blender's data in the same way as the animation system and user interface; this implies that any setting that can be changed via a button can also be changed from Python.
@@ -116,7 +104,7 @@ Unlike Python's dictionaries, both methods are acceptable; however, the index of
bpy.data.objects["Cube"]
-Accessing attributes
+Accessing Attributes
^^^^^^^^^^^^^^^^^^^^
Once you have a data block, such as a material, object, groups etc., its attributes can be accessed much like you would change a setting using the graphical interface. In fact, the tooltip for each button also displays the Python attribute which can help in finding what settings to change in a script.
@@ -144,7 +132,7 @@ Example of a data path that can be quickly found via the console:
Data Creation/Removal
^^^^^^^^^^^^^^^^^^^^^
-Those of you familiar with other python api's may be surprised that new datablocks in the bpy api can't be created by calling the class:
+Those of you familiar with other Python API's may be surprised that new datablocks in the bpy API can't be created by calling the class:
>>> bpy.types.Mesh()
Traceback (most recent call last):
@@ -153,9 +141,9 @@ Those of you familiar with other python api's may be surprised that new databloc
This is an intentional part of the API design.
-The blender/python api can't create blender data that exists outside the main blender database (accessed through bpy.data), because this data is managed by blender (save/load/undo/append... etc).
+The Blender/Python API can't create Blender data that exists outside the main Blender database (accessed through :mod:`bpy.data`), because this data is managed by Blender (save/load/undo/append... etc).
-Data is added and removed via methods on the collections in bpy.data, eg:
+Data is added and removed via methods on the collections in :mod:`bpy.data`, eg:
>>> mesh = bpy.data.meshes.new(name="MyMesh")
>>> print(mesh)
@@ -167,7 +155,8 @@ Data is added and removed via methods on the collections in bpy.data, eg:
Custom Properties
^^^^^^^^^^^^^^^^^
-Python can access properties on any datablock that has an ID (data that can be linked in and accessed from :mod:`bpy.data`. When assigning a property, you can make up your own names, these will be created when needed or overwritten if they exist.
+Python can access properties on any datablock that has an ID (data that can be linked in and accessed from :mod:`bpy.data`.
+When assigning a property, you can make up your own names, these will be created when needed or overwritten if they exist.
This data is saved with the blend file and copied with objects.
@@ -180,7 +169,7 @@ Example:
if "SomeProp" in bpy.context.object:
print("Property found")
- # Use the get function like a python dictionary
+ # Use the get function like a Python dictionary
# which can have a fallback value.
value = bpy.data.scenes["Scene"].get("test_prop", "fallback value")
@@ -193,11 +182,9 @@ Example:
Note that these properties can only be assigned basic Python types.
-* int, float, string
-
-* array of ints/floats
-
-* dictionary (only string keys are supported, values must be basic types too)
+- int, float, string
+- array of ints/floats
+- dictionary (only string keys are supported, values must be basic types too)
These properties are valid outside of Python. They can be animated by curves or used in driver paths.
@@ -205,7 +192,8 @@ These properties are valid outside of Python. They can be animated by curves or
Context
-------
-While it's useful to be able to access data directly by name or as a list, it's more common to operate on the user's selection. The context is always available from '''bpy.context''' and can be used to get the active object, scene, tool settings along with many other attributes.
+While it's useful to be able to access data directly by name or as a list, it's more common to operate on the user's selection.
+The context is always available from ``bpy.context`` and can be used to get the active object, scene, tool settings along with many other attributes.
Common-use cases:
@@ -220,9 +208,10 @@ So ``bpy.context.object = obj`` will raise an error.
But ``bpy.context.scene.objects.active = obj`` will work as expected.
-The context attributes change depending on where they are accessed. The 3D view has different context members than the console, so take care when accessing context attributes that the user state is known.
+The context attributes change depending on where they are accessed.
+The 3D view has different context members than the console, so take care when accessing context attributes that the user state is known.
-See :mod:`bpy.context` API reference
+See :mod:`bpy.context` API reference.
Operators (Tools)
@@ -241,16 +230,17 @@ Examples:
.. note::
- The menu item: Help -> Operator Cheat Sheet" gives a list of all operators and their default values in Python syntax, along with the generated docs. This is a good way to get an overview of all blender's operators.
+ The menu item: :menuselection:`Help --> Operator Cheat Sheet` gives a list of all operators and their default values in Python syntax, along with the generated docs.
+ This is a good way to get an overview of all Blender's operators.
Operator Poll()
^^^^^^^^^^^^^^^
Many operators have a "poll" function which may check that the mouse is in a valid area or that the object is in the correct mode (Edit Mode, Weight Paint etc).
-When an operator's poll function fails within python, an exception is raised.
+When an operator's poll function fails within Python, an exception is raised.
-For example, calling bpy.ops.view3d.render_border() from the console raises the following error:
+For example, calling ``bpy.ops.view3d.render_border()`` from the console raises the following error:
.. code-block:: python
@@ -271,13 +261,10 @@ Integration
Python scripts can integrate with Blender in the following ways:
-* By defining a rendering engine.
-
-* By defining operators.
-
-* By defining menus, headers and panels.
-
-* By inserting new buttons into existing menus, headers and panels
+- By defining a rendering engine.
+- By defining operators.
+- By defining menus, headers and panels.
+- By inserting new buttons into existing menus, headers and panels
In Python, this is done by defining a class, which is a subclass of an existing type.
@@ -292,24 +279,17 @@ Once this script runs, ``SimpleOperator`` is registered with Blender and can be
To run the script:
-#. Highlight the above code then press Ctrl+C to copy it.
-
+#. Highlight the above code then press :kbd:`Ctrl-C` to copy it.
#. Start Blender
-
-#. Press Ctrl+Right twice to change to the Scripting layout.
-
+#. Press :kbd:`Ctrl-Right` twice to change to the Scripting layout.
#. Click the button labeled ``New`` and the confirmation pop up in order to create a new text block.
-
-#. Press Ctrl+V to paste the code into the text panel (the upper left frame).
-
+#. Press :kbd:`Ctrl-V` to paste the code into the text panel (the upper left frame).
#. Click on the button **Run Script**.
-
#. Move your mouse into the 3D view, press spacebar for the operator search menu, and type "Simple".
-
#. Click on the "Simple Operator" item found in search.
-.. seealso:: The class members with the **bl_** prefix are documented in the API
+.. seealso:: The class members with the ``bl_`` prefix are documented in the API
reference :class:`bpy.types.Operator`
.. note:: The output from the ``main`` function is sent to the terminal; in order to see this, be sure to :ref:`use the terminal <use_the_terminal>`.
@@ -317,33 +297,25 @@ To run the script:
Example Panel
-------------
-Panels register themselves as a class, like an operator. Notice the extra **bl_** variables used to set the context they display in.
+Panels register themselves as a class, like an operator. Notice the extra ``bl_`` variables used to set the context they display in.
.. literalinclude:: ../../../release/scripts/templates_py/ui_panel_simple.py
To run the script:
-#. Highlight the above code then press Ctrl+C to copy it
-
+#. Highlight the above code then press :kbd:`Ctrl-C` to copy it
#. Start Blender
-
-#. Press Ctrl+Right twice to change to the Scripting layout
-
+#. Press :kbd:`Ctrl-Right` twice to change to the Scripting layout
#. Click the button labeled ``New`` and the confirmation pop up in order to create a new text block.
-
-#. Press Ctrl+V to paste the code into the text panel (the upper left frame)
-
+#. Press :kbd:`Ctrl-V` to paste the code into the text panel (the upper left frame)
#. Click on the button **Run Script**.
To view the results:
#. Select the the default cube.
-
#. Click on the Object properties icon in the buttons panel (far right; appears as a tiny cube).
-
#. Scroll down to see a panel named **Hello World Panel**.
-
#. Changing the object name also updates **Hello World Panel's** Name: field.
Note the row distribution and the label and properties that are available through the code.
@@ -362,16 +334,14 @@ Blender's Python API can be split up into 3 categories.
Native Types
------------
-In simple cases returning a number or a string as a custom type would be cumbersome, so these are accessed as normal python types.
+In simple cases returning a number or a string as a custom type would be cumbersome, so these are accessed as normal Python types.
-* blender float/int/boolean -> float/int/boolean
-
-* blender enumerator -> string
+- Blender float/int/boolean -> float/int/boolean
+- Blender enumerator -> string
>>> C.object.rotation_mode = 'AXIS_ANGLE'
-
-* blender enumerator (multiple) -> set of strings
+- Blender enumerator (multiple) -> set of strings
.. code-block:: python
@@ -389,7 +359,7 @@ Used for Blender datablocks and collections: :class:`bpy.types.bpy_struct`
For data that contains its own attributes groups/meshes/bones/scenes... etc.
-There are 2 main types that wrap Blenders data, one for datablocks (known internally as bpy_struct), another for properties.
+There are 2 main types that wrap Blenders data, one for datablocks (known internally as ``bpy_struct``), another for properties.
>>> bpy.context.object
bpy.data.objects['Cube']
diff --git a/doc/python_api/rst/info_tutorial_addon.rst b/doc/python_api/rst/info_tutorial_addon.rst
index 5637cf2f638..659b80df632 100644
--- a/doc/python_api/rst/info_tutorial_addon.rst
+++ b/doc/python_api/rst/info_tutorial_addon.rst
@@ -19,21 +19,17 @@ Prerequisites
Before going through the tutorial you should...
-* Familiarity with the basics of working in Blender.
-
-* Know how to run a script in Blender's text editor (as documented in the quick-start)
-
-* Have an understanding of Python primitive types (int, boolean, string, list, tuple, dictionary, and set).
-
-* Be familiar with the concept of Python modules.
-
-* Basic understanding of classes (object orientation) in Python.
+- Familiarity with the basics of working in Blender.
+- Know how to run a script in Blender's text editor (as documented in the quick-start)
+- Have an understanding of Python primitive types (int, boolean, string, list, tuple, dictionary, and set).
+- Be familiar with the concept of Python modules.
+- Basic understanding of classes (object orientation) in Python.
Suggested reading before starting this tutorial.
-* `Dive Into Python <http://getpython3.com/diveintopython3/index.html>`_ sections (1, 2, 3, 4, and 7).
-* :ref:`Blender API Quickstart <info_quickstart>`
+- `Dive Into Python <http://getpython3.com/diveintopython3/index.html>`_ sections (1, 2, 3, 4, and 7).
+- :ref:`Blender API Quickstart <info_quickstart>`
to help become familiar with Blender/Python basics.
@@ -45,13 +41,11 @@ Documentation Links
While going through the tutorial you may want to look into our reference documentation.
-* :ref:`Blender API Overview <info_overview>`. -
+- :ref:`Blender API Overview <info_overview>`. -
*This document is rather detailed but helpful if you want to know more on a topic.*
-
-* :mod:`bpy.context` api reference. -
+- :mod:`bpy.context` api reference. -
*Handy to have a list of available items your script may operate on.*
-
-* :class:`bpy.types.Operator`. -
+- :class:`bpy.types.Operator`. -
*The following addons define operators, these docs give details and more examples of operators.*
@@ -78,11 +72,11 @@ To give an example, here is the simplest possible addon.
print("Goodbye World")
-* ``bl_info`` is a dictionary containing addon meta-data such as the title, version and author to be displayed in the
+- ``bl_info`` is a dictionary containing addon meta-data such as the title, version and author to be displayed in the
user preferences addon list.
-* ``register`` is a function which only runs when enabling the addon, this means the module can be loaded without
+- ``register`` is a function which only runs when enabling the addon, this means the module can be loaded without
activating the addon.
-* ``unregister`` is a function to unload anything setup by ``register``, this is called when the addon is disabled.
+- ``unregister`` is a function to unload anything setup by ``register``, this is called when the addon is disabled.
@@ -184,12 +178,15 @@ This addon takes the body of the script above, and adds them to an operator's ``
register()
-.. note:: ``bl_info`` is split across multiple lines, this is just a style convention used to more easily add items.
+.. note::
+
+ ``bl_info`` is split across multiple lines, this is just a style convention used to more easily add items.
+
+.. note::
-.. note:: Rather than using ``bpy.context.scene``, we use the ``context.scene`` argument passed to ``execute()``.
- In most cases these will be the same however in some cases operators will be passed a custom context
- so script authors should prefer the ``context`` argument passed to operators.
-
+ Rather than using ``bpy.context.scene``, we use the ``context.scene`` argument passed to ``execute()``.
+ In most cases these will be the same however in some cases operators will be passed a custom context
+ so script authors should prefer the ``context`` argument passed to operators.
To test the script you can copy and paste this into Blender text editor and run it, this will execute the script
directly and call register immediately.
@@ -202,8 +199,8 @@ However running the script wont move any objects, for this you need to execute t
:height: 574px
:alt: Spacebar
-Do this by pressing ``SpaceBar`` to bring up the operator search dialog and type in "Move X by One" (the ``bl_label``),
-then press ``Enter``.
+Do this by pressing :kbd:`Spacebar` to bring up the operator search dialog and type in
+"Move X by One" (the ``bl_label``), then :kbd:`Enter`.
@@ -214,8 +211,8 @@ The objects should move as before.
Install The Addon
-----------------
-Once you have your addon within in Blender's text editor, you will want to be able to install it so it can be enabled in
-the user preferences to load on startup.
+Once you have your addon within in Blender's text editor,
+you will want to be able to install it so it can be enabled in the user preferences to load on startup.
Even though the addon above is a test, lets go through the steps anyway so you know how to do it for later.
@@ -563,20 +560,26 @@ Bringing it all together
# handle the keymap
wm = bpy.context.window_manager
- km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
- kmi = km.keymap_items.new(ObjectCursorArray.bl_idname, 'SPACE', 'PRESS', ctrl=True, shift=True)
- kmi.properties.total = 4
- addon_keymaps.append((km, kmi))
+ # Note that in background mode (no GUI available), keyconfigs are not available either, so we have to check this
+ # to avoid nasty errors in background case.
+ kc = wm.keyconfigs.addon
+ if kc:
+ km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
+ kmi = km.keymap_items.new(ObjectCursorArray.bl_idname, 'SPACE', 'PRESS', ctrl=True, shift=True)
+ kmi.properties.total = 4
+ addon_keymaps.append((km, kmi))
def unregister():
- bpy.utils.unregister_class(ObjectCursorArray)
- bpy.types.VIEW3D_MT_object.remove(menu_func)
-
+ # Note: when unregistering, it's usually good practice to do it in reverse order you registered.
+ # Can avoid strange issues like keymap still referring to operators already unregistered...
# handle the keymap
for km, kmi in addon_keymaps:
km.keymap_items.remove(kmi)
addon_keymaps.clear()
+ bpy.utils.unregister_class(ObjectCursorArray)
+ bpy.types.VIEW3D_MT_object.remove(menu_func)
+
if __name__ == "__main__":
register()
@@ -627,15 +630,12 @@ you want to see example code for, this is a good place to start.
Here are some sites you might like to check on after completing this tutorial.
-* :ref:`Blender/Python API Overview <info_overview>` -
+- :ref:`Blender/Python API Overview <info_overview>` -
*For more background details on Blender/Python integration.*
-
-* `How to Think Like a Computer Scientist <http://interactivepython.org/courselib/static/thinkcspy/index.html>`_ -
+- `How to Think Like a Computer Scientist <http://interactivepython.org/courselib/static/thinkcspy/index.html>`_ -
*Great info for those who are still learning Python.*
-
-* `Blender Development (Wiki) <http://wiki.blender.org/index.php/Dev:Contents>`_ -
+- `Blender Development (Wiki) <http://wiki.blender.org/index.php/Dev:Contents>`_ -
*Blender Development, general information and helpful links.*
-
-* `Blender Artists (Coding Section) <http://blenderartists.org/forum/forumdisplay.php?47-Coding>`_ -
+- `Blender Artists (Coding Section) <http://blenderartists.org/forum/forumdisplay.php?47-Coding>`_ -
*forum where people ask Python development questions*
diff --git a/doc/python_api/sphinx_changelog_gen.py b/doc/python_api/sphinx_changelog_gen.py
index 3b968de9a2c..0b083c31c58 100644
--- a/doc/python_api/sphinx_changelog_gen.py
+++ b/doc/python_api/sphinx_changelog_gen.py
@@ -316,7 +316,7 @@ def main():
try:
import argparse
- except:
+ except ImportError:
print("Old Blender, just dumping")
api_dump()
return
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 0b9a4e6a37b..344e6769524 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -937,10 +937,16 @@ def pymodule2sphinx(basepath, module_name, module, title):
fw(title_string(heading, heading_char))
# May need to be its own function
- fw(".. class:: %s\n\n" % type_name)
if value.__doc__:
- write_indented_lines(" ", fw, value.__doc__, False)
- fw("\n")
+ if value.__doc__.startswith(".. class::"):
+ fw(value.__doc__)
+ else:
+ fw(".. class:: %s\n\n" % type_name)
+ write_indented_lines(" ", fw, value.__doc__, False)
+ else:
+ fw(".. class:: %s\n\n" % type_name)
+ fw("\n")
+
write_example_ref(" ", fw, module_name + "." + type_name)
descr_items = [(key, descr) for key, descr in sorted(value.__dict__.items()) if not key.startswith("__")]
@@ -971,10 +977,12 @@ def pymodule2sphinx(basepath, module_name, module, title):
context_type_map = {
"active_base": ("ObjectBase", False),
"active_bone": ("EditBone", False),
+ "active_gpencil_frame": ("GreasePencilLayer", True),
+ "active_gpencil_layer": ("GPencilLayer", True),
+ "active_node": ("Node", False),
"active_object": ("Object", False),
"active_operator": ("Operator", False),
"active_pose_bone": ("PoseBone", False),
- "active_node": ("Node", False),
"armature": ("Armature", False),
"bone": ("Bone", False),
"brush": ("Brush", False),
@@ -990,7 +998,11 @@ context_type_map = {
"edit_object": ("Object", False),
"edit_text": ("Text", False),
"editable_bones": ("EditBone", True),
+ "editable_gpencil_layers": ("GPencilLayer", True),
+ "editable_gpencil_strokes": ("GPencilStroke", True),
"fluid": ("FluidSimulationModifier", False),
+ "gpencil_data": ("GreasePencel", False),
+ "gpencil_data_owner": ("ID", False),
"image_paint_object": ("Object", False),
"lamp": ("Lamp", False),
"lattice": ("Lattice", False),
@@ -1030,6 +1042,7 @@ context_type_map = {
"vertex_paint_object": ("Object", False),
"visible_bases": ("ObjectBase", True),
"visible_bones": ("EditBone", True),
+ "visible_gpencil_layers": ("GPencilLayer", True),
"visible_objects": ("Object", True),
"visible_pose_bones": ("PoseBone", True),
"weight_paint_object": ("Object", False),
diff --git a/doc/python_api/sphinx_doc_gen.sh b/doc/python_api/sphinx_doc_gen.sh
index d7fc372a8d8..01de3e2c2ea 100755
--- a/doc/python_api/sphinx_doc_gen.sh
+++ b/doc/python_api/sphinx_doc_gen.sh
@@ -3,6 +3,10 @@
# bash doc/python_api/sphinx_doc_gen.sh
# ssh upload means you need an account on the server
+if [ "$1" == "" ] ; then
+ echo "Expected a single argument for the username on blender.org, aborting"
+ exit 1
+fi
# ----------------------------------------------------------------------------
# Upload vars
@@ -16,9 +20,9 @@ DO_OUT_PDF=false
BLENDER="./blender.bin"
-SSH_USER="ideasman42"
+SSH_USER=$1
SSH_HOST=$SSH_USER"@blender.org"
-SSH_UPLOAD="/data/www/vhosts/www.blender.org/documentation" # blender_python_api_VERSION, added after
+SSH_UPLOAD="/data/www/vhosts/www.blender.org/api" # blender_python_api_VERSION, added after
# ----------------------------------------------------------------------------
# Blender Version & Info
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index 84194208bf9..0caa5e21782 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -67,7 +67,7 @@ if(WITH_IMAGE_REDCODE)
add_subdirectory(libredcode)
endif()
-if(WITH_LZO)
+if(WITH_LZO AND NOT WITH_SYSTEM_LZO)
add_subdirectory(lzo)
endif()
@@ -91,3 +91,7 @@ endif()
if(WITH_GTESTS)
add_subdirectory(gtest)
endif()
+
+if(WITH_SDL AND WITH_SDL_DYNLOAD)
+ add_subdirectory(sdlew)
+endif()
diff --git a/extern/SConscript b/extern/SConscript
index 589e56d7dfe..b02e705220c 100644
--- a/extern/SConscript
+++ b/extern/SConscript
@@ -51,3 +51,6 @@ if env['WITH_GHOST_XDND']:
# FreeBSD doesn't seems to support XDND protocol
if env['OURPLATFORM'] in ('linux', 'openbsd3', 'sunos5', 'aix4', 'aix5'):
SConscript(['xdnd/SConscript'])
+
+if env['WITH_BF_SDL'] and env['WITH_BF_SDL_DYNLOAD']:
+ SConscript(['sdlew/SConscript'])
diff --git a/extern/bullet2/readme.txt b/extern/bullet2/readme.txt
index 3c09dad1fbf..3b286afa579 100644
--- a/extern/bullet2/readme.txt
+++ b/extern/bullet2/readme.txt
@@ -6,3 +6,8 @@ Erwin
Apply patches/convex_hull.patch to add access to the convex hull
operation, used in the BMesh convex hull operator.
+
+Documentation is available at:
+http://code.google.com/p/bullet/source/browse/trunk/Bullet_User_Manual.pdf
+and:
+https://github.com/bulletphysics/bullet3/tree/master/docs
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
index aff9f27f594..aff9f27f594 100755..100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
index 57ebb47d8e7..57ebb47d8e7 100755..100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
diff --git a/extern/carve/CMakeLists.txt b/extern/carve/CMakeLists.txt
index 5754290d710..643bd423546 100644
--- a/extern/carve/CMakeLists.txt
+++ b/extern/carve/CMakeLists.txt
@@ -161,6 +161,7 @@ if(WITH_BOOST)
add_definitions(
-DCARVE_SYSTEM_BOOST
+ -DHAVE_BOOST_LIBRARY
)
list(APPEND INC_SYS
diff --git a/extern/carve/SConscript b/extern/carve/SConscript
index f975e253d60..e08e75e6640 100644
--- a/extern/carve/SConscript
+++ b/extern/carve/SConscript
@@ -19,6 +19,7 @@ if env['WITH_BF_BOOST']:
defs.append('HAVE_BOOST_UNORDERED_COLLECTIONS')
defs.append('CARVE_SYSTEM_BOOST')
+ defs.append('HAVE_BOOST_LIBRARY')
incs.append(env['BF_BOOST_INC'])
env.BlenderLib ('extern_carve', Split(sources), incs, defs, libtype=['extern'], priority=[40] )
diff --git a/extern/carve/bundle.sh b/extern/carve/bundle.sh
index 2a3e621fab0..dec902e30c0 100755
--- a/extern/carve/bundle.sh
+++ b/extern/carve/bundle.sh
@@ -31,6 +31,8 @@ headers=`find ./lib -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t
includes=`find ./include -type f -iname '*.h' -or -iname '*.hpp' | sed -r 's/^\.\//\t/' | sort -d`
cp patches/files/config.h include/carve/config.h
+mkdir -p include/carve/random
+cp patches/files/random.h include/carve/random/random.h
cat > CMakeLists.txt << EOF
# ***** BEGIN GPL LICENSE BLOCK *****
@@ -91,6 +93,7 @@ if(WITH_BOOST)
add_definitions(
-DCARVE_SYSTEM_BOOST
+ -DHAVE_BOOST_LIBRARY
)
list(APPEND INC_SYS
@@ -102,8 +105,6 @@ blender_add_lib(extern_carve "\${SRC}" "\${INC}" "\${INC_SYS}")
EOF
cat > SConscript << EOF
-#!/usr/bin/python
-
# NOTE: This file is automatically generated by bundle.sh script
# If you're doing changes in this file, please update template
# in that script too
@@ -123,6 +124,7 @@ if env['WITH_BF_BOOST']:
defs.append('HAVE_BOOST_UNORDERED_COLLECTIONS')
defs.append('CARVE_SYSTEM_BOOST')
+ defs.append('HAVE_BOOST_LIBRARY')
incs.append(env['BF_BOOST_INC'])
env.BlenderLib ('extern_carve', Split(sources), incs, defs, libtype=['extern'], priority=[40] )
diff --git a/extern/carve/include/carve/random/random.h b/extern/carve/include/carve/random/random.h
new file mode 100644
index 00000000000..634063cb90c
--- /dev/null
+++ b/extern/carve/include/carve/random/random.h
@@ -0,0 +1,61 @@
+#include <cassert>
+#include <cmath>
+#include <vector>
+
+namespace boost {
+#if __cplusplus > 199711L
+# include <random>
+typedef std::mt19937 mt19937;
+#else
+# include <stdlib.h>
+struct mt19937 {
+ int operator()() {
+ return rand();
+ }
+
+ int max() {
+ return RAND_MAX;
+ }
+};
+#endif
+
+template<typename T>
+struct uniform_on_sphere {
+ typedef std::vector<T> result_type;
+
+ uniform_on_sphere(int dimension) {
+ assert(dimension == 3);
+ }
+
+ std::vector<T>
+ operator()(float u1, float u2) {
+ T z = 1.0 - 2.0*u1;
+ T r = std::sqrt(std::max(0.0, 1.0 - z*z));
+ T phi = 2.0*M_PI*u2;
+ T x = r*std::cos(phi);
+ T y = r*std::sin(phi);
+ std::vector<T> result;
+ result.push_back(x);
+ result.push_back(y);
+ result.push_back(z);
+ return result;
+ }
+};
+
+template<typename RNG, typename DISTR>
+struct variate_generator {
+
+ variate_generator(RNG rng, DISTR distr)
+ : rng_(rng), distr_(distr) {}
+
+ typename DISTR::result_type
+ operator()() {
+ float rng_max_inv = 1.0 / rng_.max();
+ return distr_(rng_() * rng_max_inv, rng_() * rng_max_inv);
+ }
+
+ RNG rng_;
+ DISTR distr_;
+};
+
+}
diff --git a/extern/carve/lib/polyhedron.cpp b/extern/carve/lib/polyhedron.cpp
index 7f65da8c125..d402fce36df 100644
--- a/extern/carve/lib/polyhedron.cpp
+++ b/extern/carve/lib/polyhedron.cpp
@@ -36,7 +36,11 @@
#include <carve/mesh.hpp>
-#include BOOST_INCLUDE(random.hpp)
+#ifdef HAVE_BOOST_LIBRARY
+# include BOOST_INCLUDE(random.hpp)
+#else
+# include <carve/random/random.h>
+#endif
namespace {
bool emb_test(carve::poly::Polyhedron *poly,
diff --git a/extern/carve/patches/files/random.h b/extern/carve/patches/files/random.h
new file mode 100644
index 00000000000..634063cb90c
--- /dev/null
+++ b/extern/carve/patches/files/random.h
@@ -0,0 +1,61 @@
+#include <cassert>
+#include <cmath>
+#include <vector>
+
+namespace boost {
+#if __cplusplus > 199711L
+# include <random>
+typedef std::mt19937 mt19937;
+#else
+# include <stdlib.h>
+struct mt19937 {
+ int operator()() {
+ return rand();
+ }
+
+ int max() {
+ return RAND_MAX;
+ }
+};
+#endif
+
+template<typename T>
+struct uniform_on_sphere {
+ typedef std::vector<T> result_type;
+
+ uniform_on_sphere(int dimension) {
+ assert(dimension == 3);
+ }
+
+ std::vector<T>
+ operator()(float u1, float u2) {
+ T z = 1.0 - 2.0*u1;
+ T r = std::sqrt(std::max(0.0, 1.0 - z*z));
+ T phi = 2.0*M_PI*u2;
+ T x = r*std::cos(phi);
+ T y = r*std::sin(phi);
+ std::vector<T> result;
+ result.push_back(x);
+ result.push_back(y);
+ result.push_back(z);
+ return result;
+ }
+};
+
+template<typename RNG, typename DISTR>
+struct variate_generator {
+
+ variate_generator(RNG rng, DISTR distr)
+ : rng_(rng), distr_(distr) {}
+
+ typename DISTR::result_type
+ operator()() {
+ float rng_max_inv = 1.0 / rng_.max();
+ return distr_(rng_() * rng_max_inv, rng_() * rng_max_inv);
+ }
+
+ RNG rng_;
+ DISTR distr_;
+};
+
+}
diff --git a/extern/carve/patches/random.patch b/extern/carve/patches/random.patch
new file mode 100644
index 00000000000..36cc8d10430
--- /dev/null
+++ b/extern/carve/patches/random.patch
@@ -0,0 +1,16 @@
+diff -r 9a85d733a43d lib/polyhedron.cpp
+--- a/lib/polyhedron.cpp Tue Jun 24 11:15:23 2014 +1000
++++ b/lib/polyhedron.cpp Thu Nov 13 17:36:06 2014 +0500
+@@ -36,7 +36,11 @@
+
+ #include <carve/mesh.hpp>
+
+-#include BOOST_INCLUDE(random.hpp)
++#ifdef HAVE_BOOST_LIBRARY
++# include BOOST_INCLUDE(random.hpp)
++#else
++# include <carve/random/random.h>
++#endif
+
+ namespace {
+ bool emb_test(carve::poly::Polyhedron *poly,
diff --git a/extern/carve/patches/series b/extern/carve/patches/series
index 4691339b419..b7e97d68c4c 100644
--- a/extern/carve/patches/series
+++ b/extern/carve/patches/series
@@ -11,3 +11,4 @@ mesh_simplify_uninitialized_var.patch
memory_leak_fix.patch
msvc_fix.patch
face_hole_merge_workaround.patch
+random.patch
diff --git a/extern/clew/include/clew.h b/extern/clew/include/clew.h
index 624fdb299fe..328fd52857a 100644
--- a/extern/clew/include/clew.h
+++ b/extern/clew/include/clew.h
@@ -350,7 +350,7 @@ typedef unsigned int cl_GLenum;
#ifdef _MSC_VER
#if defined(_M_IX86)
-#if _M_IX86_FP >= 0
+#if _M_IX86_FP >= 0 && !defined(__SSE__)
#define __SSE__
#endif
#if _M_IX86_FP >= 1
@@ -1815,6 +1815,11 @@ typedef struct _cl_buffer_region {
/* Function signature typedef's */
+#ifdef __APPLE__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wignored-attributes"
+#endif
+
/* Platform API */
typedef CL_API_ENTRY cl_int (CL_API_CALL *
PFNCLGETPLATFORMIDS)(cl_uint /* num_entries */,
@@ -2476,6 +2481,10 @@ PFNCLCREATEFROMGLTEXTURE3D)(cl_context /* context */,
cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED;
#endif
+#ifdef __APPLE__
+# pragma GCC diagnostic pop // ignored "-Wignored-attributes"
+#endif
+
/* cl_khr_gl_sharing extension */
#define cl_khr_gl_sharing 1
diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt
index 09c36fc4383..80e64046534 100644
--- a/extern/libmv/CMakeLists.txt
+++ b/extern/libmv/CMakeLists.txt
@@ -37,13 +37,42 @@ set(SRC
libmv-capi.h
)
-if(WITH_LIBMV)
+if(WITH_LIBMV OR WITH_GTESTS OR (WITH_CYCLES AND WITH_CYCLES_LOGGING))
+ list(APPEND INC
+ third_party/gflags
+ third_party/gflags/gflags
+ third_party/glog/src
+ third_party/ceres/include
+ third_party/ceres/config
+ ../../intern/guardedalloc
+ )
+
+ list(APPEND INC_SYS
+ ../Eigen3
+ ${PNG_INCLUDE_DIRS}
+ ${ZLIB_INCLUDE_DIRS}
+ )
+
+ if(WIN32)
+ list(APPEND INC
+ third_party/glog/src/windows
+ )
+
+ if(NOT MINGW)
+ list(APPEND INC
+ third_party/msinttypes
+ )
+ endif()
+ endif()
+
add_definitions(
-DWITH_LIBMV_GUARDED_ALLOC
-DGOOGLE_GLOG_DLL_DECL=
-DLIBMV_NO_FAST_DETECTOR=
)
+endif()
+if(WITH_LIBMV)
TEST_SHARED_PTR_SUPPORT()
if(SHARED_PTR_FOUND)
if(SHARED_PTR_TR1_MEMORY_HEADER)
@@ -56,29 +85,21 @@ if(WITH_LIBMV)
message(FATAL_ERROR "Unable to find shared_ptr.")
endif()
- list(APPEND INC
- third_party/gflags
- third_party/glog/src
- third_party/ceres/include
- third_party/ceres/config
- ../../intern/guardedalloc
- )
-
- list(APPEND INC_SYS
- ../Eigen3
- ${PNG_INCLUDE_DIRS}
- ${ZLIB_INCLUDE_DIRS}
- )
-
list(APPEND SRC
+ intern/autotrack.cc
intern/camera_intrinsics.cc
intern/detector.cc
+ intern/frame_accessor.cc
intern/homography.cc
intern/image.cc
intern/logging.cc
intern/reconstruction.cc
intern/track_region.cc
intern/tracks.cc
+ intern/tracksN.cc
+ libmv/autotrack/autotrack.cc
+ libmv/autotrack/predict_tracks.cc
+ libmv/autotrack/tracks.cc
libmv/base/aligned_malloc.cc
libmv/image/array_nd.cc
libmv/image/convolve.cc
@@ -114,14 +135,27 @@ if(WITH_LIBMV)
libmv/tracking/trklt_region_tracker.cc
+ intern/autotrack.h
intern/camera_intrinsics.h
intern/detector.h
+ intern/frame_accessor.h
intern/homography.h
intern/image.h
intern/logging.h
intern/reconstruction.h
intern/track_region.h
intern/tracks.h
+ intern/tracksN.h
+ libmv/autotrack/autotrack.h
+ libmv/autotrack/callbacks.h
+ libmv/autotrack/frame_accessor.h
+ libmv/autotrack/marker.h
+ libmv/autotrack/model.h
+ libmv/autotrack/predict_tracks.h
+ libmv/autotrack/quad.h
+ libmv/autotrack/reconstruction.h
+ libmv/autotrack/region.h
+ libmv/autotrack/tracks.h
libmv/base/aligned_malloc.h
libmv/base/id_generator.h
libmv/base/scoped_ptr.h
@@ -171,6 +205,7 @@ if(WITH_LIBMV)
libmv/simple_pipeline/tracks.h
libmv/tracking/brute_region_tracker.h
libmv/tracking/hybrid_region_tracker.h
+ libmv/tracking/kalman_filter.h
libmv/tracking/klt_region_tracker.h
libmv/tracking/pyramid_region_tracker.h
libmv/tracking/region_tracker.h
@@ -182,21 +217,12 @@ if(WITH_LIBMV)
third_party/msinttypes/stdint.h
)
- if(WIN32)
- list(APPEND INC
- third_party/glog/src/windows
- )
-
- if(NOT MINGW)
- list(APPEND INC
- third_party/msinttypes
- )
- endif()
- endif()
if(WITH_GTESTS)
blender_add_lib(libmv_test_dataset "./libmv/multiview/test_data_sets.cc" "" "")
+ BLENDER_SRC_GTEST("libmv_predict_tracks" "./libmv/autotrack/predict_tracks_test.cc" "libmv_test_dataset;extern_libmv;extern_ceres")
+ BLENDER_SRC_GTEST("libmv_tracks" "./libmv/autotrack/tracks_test.cc" "libmv_test_dataset;extern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_scoped_ptr" "./libmv/base/scoped_ptr_test.cc" "libmv_test_dataset;extern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_vector" "./libmv/base/vector_test.cc" "libmv_test_dataset;extern_libmv;extern_ceres")
BLENDER_SRC_GTEST("libmv_array_nd" "./libmv/image/array_nd_test.cc" "libmv_test_dataset;extern_libmv;extern_ceres")
@@ -240,7 +266,7 @@ if(WITH_LIBMV)
endif()
# make GLog a separate target, so it can be used for gtest as well.
-if(WITH_LIBMV OR WITH_GTESTS OR WITH_CYCLES_LOGGING)
+if(WITH_LIBMV OR WITH_GTESTS OR (WITH_CYCLES AND WITH_CYCLES_LOGGING))
# We compile GLog together with GFlag so we don't worry about
# adding extra lib to linker.
set(GLOG_SRC
@@ -281,6 +307,9 @@ if(WITH_LIBMV OR WITH_GTESTS OR WITH_CYCLES_LOGGING)
third_party/glog/src/windows/glog/log_severity.h
third_party/glog/src/windows/port.h
third_party/glog/src/windows/config.h
+
+ third_party/gflags/windows_port.cc
+ third_party/gflags/windows_port.h
)
else()
list(APPEND GLOG_SRC
@@ -316,13 +345,5 @@ if(WITH_LIBMV OR WITH_GTESTS OR WITH_CYCLES_LOGGING)
)
endif()
- set(GLOG_INC
- third_party/gflags
- third_party/glog/src
- )
-
- set(GLOG_INC_SYS
- )
-
- blender_add_lib(extern_glog "${GLOG_SRC}" "${GLOG_INC}" "${GLOG_INC_SYS}")
+ blender_add_lib(extern_glog "${GLOG_SRC}" "${INC}" "${INC_SYS}")
endif()
diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog
index 276fbb2ff0d..0bb340b2491 100644
--- a/extern/libmv/ChangeLog
+++ b/extern/libmv/ChangeLog
@@ -1,3 +1,404 @@
+commit 7d6020d2ec42c6cb2749bc891186b4880d26d40b
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed Dec 31 15:32:07 2014 +0500
+
+ Update GLog to latest upstream revision 143
+
+ Mainly to solve compilation error with demangle.cc.
+
+commit 5dc746700eaf85cb674f0fb73ff3c1b49a7f6315
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Fri Dec 12 14:59:55 2014 +0500
+
+ Update GFlags to latest release 2.1.1
+
+ Main purpose of this (andsome of upcoming) update is to check if the
+ upstream sources are useable without any modifications for us. And if
+ not, then we'll need to consider moving some changes into upstream.
+
+ This commit contains an one-to-one copy of the upstream GFlags library
+ and also changes namespace usage since it's changed in the upstream.
+
+commit 6fe6d75f7e90e161b44643b953f058a3829a5247
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Sat Nov 1 02:53:36 2014 +0500
+
+ Libmv: Code cleanup, mixed class/struct in declaration/definition
+
+commit d2a5f7953812d2d09765431b59c6c4ac72faf35b
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Thu Oct 30 23:13:53 2014 +0500
+
+ Libmv: Support disabled color channels in tracking settings
+
+ This was never ported to a new tracking pipeline and now it's done using
+ FrameAccessor::Transform routines. Quite striaghtforward, but i've changed
+ order of grayscale conversion in blender side with call of transform callback.
+
+ This way it's much easier to perform rescaling in libmv side.
+
+commit d976e034cdf74b34860e0632d7b29713f47c5756
+Author: Keir Mierle <mierle@gmail.com>
+Date: Sat Aug 23 00:38:01 2014 -0700
+
+ Minor keyframe selection cleanups
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D757
+
+commit bc99ca55dadfca89fde0f93764397c2fe028943d
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Sat Aug 23 01:55:32 2014 +0600
+
+ implement backward prediction
+
+ The title actually says it all, just extend current implementation
+ of PredictMarkerPosition() to cases when tracking happens in the reverse
+ order (from the end frame to start).
+
+ it's still doesn't solve all the ambiguity happening in the function
+ in cases when one tracks the feature and then re-tracks it in order
+ to refine the sliding. This is considered a separate TODO for now and
+ will likely be solved by passing tracking direction to the prediction
+ function.
+
+ Reviewers: keir
+
+ Reviewed By: keir
+
+ Differential Revision: https://developer.blender.org/D663
+
+commit 5b87682d98df65ade02638bc6482d824cf0dd0b3
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu Aug 21 22:45:22 2014 -0700
+
+ Make libmv compile on Ubuntu 14.04
+
+ Reviewers: fsiddi
+
+ Reviewed By: fsiddi
+
+ Subscribers: sergey
+
+ Differential Revision: https://developer.blender.org/D755
+
+commit 0a81db623c458e0384b4f7060d1bcff8993fb469
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed Jul 23 00:42:00 2014 +0600
+
+ Fix wrong residual blocks counter
+
+ This happened in cases when having zero-weighted tracks
+ and could lead to some assert failures on marking parameter
+ block constant.
+
+commit 2824dbac54cacf74828678be7a5c9fd960ce83e2
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Fri Jul 18 12:52:03 2014 +0600
+
+ Fix search area sliding issue
+
+ The only way to do this is to store search region in floats
+ and round when we need to sample it. Otherwise you'll always
+ have sliding effect caused by rounding the issues, especially
+ when doing incremental offset (thing which happens in the
+ prediction code).
+
+ Pretty much straightforward change apart from stuff to be kept
+ in mind: offset calculation int should happen relative to the
+ rounded search region. This is because tracker works in the space
+ of the search window image which get's rounded on the frame access,
+
+ This makes API a bit creepy because frame accessor uses the same
+ Region struct as the search window in Marker and ideally we would
+ need to have either IntRegion or Region<int> in order to make
+ Libmv fully track on what's getting rounded and when.
+
+ Reviewers: keir
+
+ Reviewed By: keir
+
+ Differential Revision: https://developer.blender.org/D616
+
+commit 04862c479332308be47a0f27361402444ace8880
+Author: Keir Mierle <mierle@gmail.com>
+Date: Fri May 9 23:00:03 2014 +0200
+
+ Start the automatic 2D tracking code
+
+ This starts the 2D automatic tracking code. It is totally unfinished.
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D523
+
+commit be679f67d807a2139c1f7d7e2ca45141940b30d5
+Author: Keir Mierle <mierle@gmail.com>
+Date: Fri May 9 14:36:04 2014 +0200
+
+ Also shift the search window
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D520
+
+commit 66b8f5eef2633ebcde32a388fc14c60171011821
+Author: Keir Mierle <mierle@gmail.com>
+Date: Fri May 9 13:06:28 2014 +0200
+
+ Change the search region to absolute frame coordinates
+
+ Smarter Eigen usage
+
+ Better error logging
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D519
+
+commit a08193319ae409fad8f08887eae1f79f02e91eaa
+Author: Keir Mierle <mierle@gmail.com>
+Date: Fri May 9 12:02:47 2014 +0200
+
+ First cut at predictive tracing
+
+ This adds a Kalman filter-based approach to predict where a marker
+ will go in the next frame to track. Hopefully this will make the
+ tracker work faster by avoiding lengthy searches. This code
+ compiles, but is otherwise untested, and likely does not work.
+
+ Fix else branch
+
+ Add some tests
+
+ Update patch coordinates as well (and test)
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D518
+
+commit 607ffb2f62b56e34a841abbb952d83e19cd1e23c
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu May 8 16:05:28 2014 +0200
+
+ Add constructor to AutoTrack
+
+commit c39e20a0c27da3733804c3848454b5d4c4f0e66b
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu May 8 16:04:20 2014 +0200
+
+ Fix GetMarker compilation issue
+
+commit 8dd93e431b6e44439c803bfd26ec2669b656177e
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu May 8 15:50:26 2014 +0200
+
+ Expose GetMarker() in AutoTrack
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D516
+
+commit 4405dff60ea08d454b64da1a7c0595d9328cf8a3
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu May 8 15:38:14 2014 +0200
+
+ Add public SetMarkers to AutoTrack
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D515
+
+commit c90837f6db276a3b1f610eaad509155f6a43b24f
+Author: Keir Mierle <mierle@gmail.com>
+Date: Thu May 8 15:17:48 2014 +0200
+
+ Make autotrack skeleton compile
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D514
+
+commit be01baa2e82e36f63e548f073157e68d2ff870c0
+Author: Keir Mierle <mierle@gmail.com>
+Date: Wed May 7 18:48:55 2014 +0200
+
+ Add preliminary TrackMarkerToFrame in autotrack
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D509
+
+commit 0cab028d591b3d08672ca86eb6c6e4ac1aacf1d0
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed May 7 17:59:11 2014 +0200
+
+ Remove assert from ArrayND Resize
+
+ That assert broke initialization of arrays which doesn't
+ own the data since constructor uses Resize to set shape
+ and strides.
+
+ Strides are still to be fixed, but that's for later.
+
+commit 64f9c118029a9351e9023e96527c120e1d724d5b
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed May 7 17:42:21 2014 +0200
+
+ Fix ArrayND freeing the data it doesn't own
+
+ Can't really guarantee it works fully correct now,
+ but at least this check is needed anyway and compilation
+ works just fine.
+
+ Reviewers: keir
+
+ Reviewed By: keir
+
+ Differential Revision: https://developer.blender.org/D508
+
+commit 0618f1c8e88dfc738cdde55784da80b889905e7c
+Author: Keir Mierle <mierle@gmail.com>
+Date: Wed May 7 12:03:32 2014 +0200
+
+ Minor changes
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D505
+
+commit 5c34335e1bb90c4ed701ee830c718ed4e20dbffa
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Wed May 7 11:12:23 2014 +0200
+
+ Fix compilation error in frame accessor
+
+ - int64 is not a standard type, we've got int64_t defined in
+ std int. We also have an msvc port of this header, so should
+ not be an issue.
+
+ - Fixed inconsistency in usage of CacheKey and Key, used Key.
+
+ - Some functions weren't marked as virtual.
+
+ Additional change: added self to authors.
+
+ Reviewers: keir
+
+ Reviewed By: keir
+
+ Differential Revision: https://developer.blender.org/D504
+
+commit 06bc207614e262cd688e2c3ed820ade7c77bdb66
+Author: Keir Mierle <mierle@gmail.com>
+Date: Tue May 6 22:30:59 2014 +0200
+
+ Start new Tracks implementation
+
+ This adds the new Tracks implementation, as well as a
+ trivial test to show it compiles.
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D502
+
+commit 25ce061e6da69881460ba7718bb0d660a2380a02
+Author: Keir Mierle <mierle@gmail.com>
+Date: Tue May 6 19:10:51 2014 +0200
+
+ Add Reconstruction class for new API
+
+ This starts the new Reconstruction class (with support for e.g. planes). This
+ also starts the new namespace "mv" which will eventually have all the symbols
+ we wish to export.
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D501
+
+commit 0a6af3e29016048978aea607673340500e050339
+Author: Keir Mierle <mierle@gmail.com>
+Date: Tue May 6 17:52:53 2014 +0200
+
+ Add a new Tracks implementation
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D500
+
+commit 887b68d29c2b198f4939f9ab5153881aa2c1806e
+Author: Keir Mierle <mierle@gmail.com>
+Date: Tue May 6 17:01:39 2014 +0200
+
+ Initial commit of unfinished AutoTrack API
+
+ This starts the creating the new AutoTrack API. The new API will
+ make it possible for libmv to do full autotracking, including
+ predictive tracking and also support multiple motion models (3D
+ planes etc).
+
+ The first goal (not in this patch) is to convert Blender to use
+ the new API without adding any new functionality.
+
+ Note: This does not add any of the API to the build system!
+ It likely does not compile.
+
+ Reviewers: sergey
+
+ Reviewed By: sergey
+
+ Differential Revision: https://developer.blender.org/D499
+
+commit 08cc227d431d257d27f300fbb8e6991e663302da
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date: Tue May 6 13:09:22 2014 +0200
+
+ Fix homography test failure
+
+ It was caused by assuming that reconstructed homography matrix
+ should look exactly the same as the matrix used to generate a
+ test case.
+
+ It's not actually valid assumption because different-looking
+ matrices could correspond to the same exact transform.
+
+ In this change we make it so actual "re-projected" vectors
+ are being checked, not the values in matrix. This makes it
+ more predictable verification.
+
+ Reviewers: keir
+
+ Reviewed By: keir
+
+ Differential Revision: https://developer.blender.org/D488
+
commit 0b7d83dc9627447dc7df64d7e3a468aefe9ddc13
Author: Sergey Sharybin <sergey.vfx@gmail.com>
Date: Wed Apr 23 19:14:55 2014 +0600
@@ -304,376 +705,3 @@ Author: Sergey Sharybin <sergey.vfx@gmail.com>
Date: Tue Feb 18 19:38:22 2014 +0600
Remove .orig file which was added by accident
-
-commit 62597e3cf0f266a2fefec415c89759e502793e06
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Thu Jan 2 16:02:08 2014 +0600
-
- Upgrade glog to latest svn r139
-
- The intention of this upgrade is to get rid of custom patches
- we've been having to support compilation on different platforms
- and compilers.
-
-commit 2452d5d42b390c7ab853e6fe60e58bdd7a01a004
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Feb 18 18:46:08 2014 +0600
-
- Tweak Ceres CMake to detect uninstall target properly on Windows
-
-commit 98a281d58ce2301f3dd239a97a448e53f48d0258
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Feb 14 00:36:44 2014 +0600
-
- Fix order of third party libs compilation and options used by them
-
- WITH_FAST_DETECTOR was defined too late and third_party folder
- didn't see this option.
-
-commit 4962bccd643ec0f2aed3035170d5f20e8f6efc85
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Thu Feb 13 23:55:03 2014 +0600
-
- Disable Ceres unit tests and examples by default
-
- Actually we're to switch to external Ceres rather than
- bundled one, would make life much easier actually.
-
-commit b1381540305d69c702eb2f051bd543fb5c1c3e2c
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Thu Feb 6 18:01:58 2014 +0600
-
- Made FAST detector optional
-
- This way it's possible to bundle Libmv sources subset
- to applications which doesn't need FAST detector.
-
- Mainly this is done for Blender integration.
-
-commit da4607f010bca0b3532cd4444afbb10bc774fc32
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Jan 28 18:32:39 2014 +0600
-
- Implemented scoped_array and use it in detector
-
- scoped_array is pretty much the same as scoped_ptr
- with the only difference that it'll free memory using
- delete[] operator.
-
- It also gives some additional API functions to access
- array elements.
-
- Currently it only used to manage images denoted as byte
- arrays in detector.
-
- Reviewers: keir
-
- Reviewed By: keir
-
- Differential Revision: https://developer.blender.org/D266
-
-commit cd7eb3eff2e69ce5e08570ead83ae6d35ee48857
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Jan 28 17:23:47 2014 +0600
-
- Improvements to weighted tracks behavior
-
- First thing changed by this commit is making it so
- Euclidean intersection takes track weight into account
- when solving minimization problem. This behaves the
- same exact way as it is for BA step.
-
- Second thing is related on how average reprojection error
- is being calculated. It didn't take track weight into
- account which could confuse users. Now average reprojection
- error will give the same result as intersection/BA uses
- during minimization which gives much more predictable
- behavior.
-
- Reviewers: keir
-
- Reviewed By: keir
-
- CC: sebastian_k
-
- Differential Revision: https://developer.blender.org/D265
-
-commit 6559b36dc14369175bfa0830323146acd3426483
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Jan 28 16:39:14 2014 +0600
-
- Fixes for keyframe selection
-
- Using tracks with constant zero weight used to crash
- keyframe selection since it was trying to use missing
- parameter blocks for Jacobian evaluation,
-
- Also fixed possible issues with wrong camera block being
- marked as variable. This could technically happen when
- having zero weighted tracks. Made it so all camera blocks
- are marked as variable for now.
-
-commit 557d531b061aa69d114e89cbb325c5175389afec
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Jan 28 16:10:33 2014 +0600
-
- Style cleanup: wrong indentation of wrapped line
-
-commit ca15262cf07a873268173965ee1fb84f9729b744
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Jan 28 15:21:36 2014 +0600
-
- Rework detector API and implement Harris detector
-
- Switch the detector API to a single function which accepts
- a float image and detector options. This makes usage of
- feature detection more unified across different algorithms.
-
- Options structure is pretty much straightforward and contains
- detector to be used and all the detector-specific settings.
-
- Also implemented Harris feature detection algorithm which
- is not as fast as FAST one but is expected to detect more
- robust feature points.
-
- Reviewers: keir
-
- Reviewed By: keir
-
- Differential Revision: https://developer.blender.org/D258
-
-commit 6458915f64fceba108c5279b7320ca8c76e8a742
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Fri Jan 24 19:14:18 2014 +0600
-
- Add arcanist configuration file
-
-commit 0a69fadadc5aacbd339f839ac5bd12c3571278b1
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Thu Jan 9 15:50:11 2014 +0600
-
- Fix compilation error on NetBSD
-
- - NetBSD doesn't provide sincos(3) in libm, so don't try to use it
- - Use posix_memalign on NetBSD
-
- Original patch is by Jeorg Sonnenberger to Blender patch tracker, thanks!
-
-commit b0df3e291e6c85f791658be04334efafc41989f5
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Thu Jan 2 15:12:18 2014 +0600
-
- Fix build configuration warnings
-
- Those warnings were mainly caused by installation
- configuration of Ceres. Made some tweaks to make
- CMake happy for now.
-
- But for sure bigger cleanup here is needed.
-
-commit b68de6acd20f3ffab92e0cd450198a700cd109ab
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Thu Jan 2 15:04:05 2014 +0600
-
- Code and style cleanup
-
- Mainly fixed some style warnings reported by cpplint.
-
- Also changed how camera (un)distortion happens internally
- by replacing number of channels as a template argument
- with number as channels passing as function argument.
- Makes code easier to follow by eliminating loads checks
- how much channels are used and which argument to pass to
- the template.
-
-commit b9e467e7c077b58199c4110f6967b7c18d1e7bf7
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Dec 31 20:34:39 2013 +0600
-
- Update Ceres to the latest upstream
-
- This brings up much easier termination type usage,
- which for us means we might use:
-
- ceres::Summary::IsSolutionUsable()
-
- instead of doing manual funky enum values check.
-
-commit 3aeb2367e50b52ca2b9d59d4f0f0b4bbfd6a05e8
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Dec 31 20:43:24 2013 +0600
-
- Update gtest to latest version 1.7.0
-
- Also reshuffled CMakeLists in order to avoid
- conflicts happening between gflags bundled to
- Ceres and third_party.
-
-commit 30aaa9cd0b4a4eb0948a17824e7e7622d8ebcb41
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Dec 31 20:10:06 2013 +0600
-
- Changes for VC2013
-
- Solves compilation error when using msvc2013
-
- Original patch is by Alexandr Kuznetsov to blender.git
-
-commit b204c0d25065a2b149de256929ff37d8f00f45bb
-Author: Keir Mierle <mierle@gmail.com>
-Date: Tue Dec 31 20:05:58 2013 +0600
-
- Eagerly attempt to refine a track before doing a brute search
-
- Before the refinement phase of tracking, a brute force SAD search
- is run across the search area. This works well but is slow;
- especially if the guess for the track's location is accurate.
-
- This patch runs a refinement phase before running a brute force
- search, hoping that the guessed position (in x2, y2) is close to
- the best answer. If it is, then no brute search is done. If it is
- not, then a normal brute force search followed by refinement is
- done.
-
- In some cases this may produce worse tracks than before; the
- regressions will need investigation. The predictive motion model
- (to be implemented) will reduce the probability of that happening.
-
-commit 5361513f0328ff94b53125d29129561bb03132e8
-Author: Keir Mierle <mierle@gmail.com>
-Date: Tue Dec 31 20:04:46 2013 +0600
-
- Fix bug where libmv tracking incorrectly succeeds on failure
-
- Before this patch, if Ceres returned USER_SUCCESS indicating that
- Ceres was only changing the tracked quad slightly between
- iterations (indicating convergence), no final correlation check
- was done. This leads to incorrectly returning that the tracking
- was successful, when it actually failed.
-
-commit ba9e63eed09e33a48bbcb081058f45ac16f8738e
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Dec 31 20:00:46 2013 +0600
-
- Implementation of weighted tracks
-
- Added a weight field to Track structure which means
- how much affect this track will have on the final
- reconstruction.
-
- Currently it affects on BA step only which in most
- cases will work just fine. However, it worth looking
- into weight support for intersection/resection.
-
-commit 4600df8b685ca8c4daa22d6c3b0125fd42c3bc67
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Dec 31 19:30:14 2013 +0600
-
- Code cleanup: move function prototype to header file
-
-commit 0ce5b6efde774b3f042acf9e42c95674548f1c01
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Dec 31 19:26:48 2013 +0600
-
- Get rid of Allow Fallback option for euclidean resection
-
- It was rather confusing from the user usage point of view
- and didn't get so much improvement after new bundle adjuster
- was added.
-
- In the future we might want to switch resection to PPnP algorithm,
- which could also might be a nice alternative to fallback option.
-
-commit 5d063426f4809000c27f38ed798e4224bbd09a6d
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Dec 31 19:24:05 2013 +0600
-
- Use explicit declaration of int types sign
-
- Mainly needs to make blender happy with this custom
- header which used to run into conflict with other int
- types headers.
-
- Wouldn't harm being more explicit here anyway.
-
-commit c5be59dee94f94de369006c544080282cfb245cc
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Tue Dec 31 14:50:00 2013 +0600
-
- Implement refinement of estimated homography/fundamental matrices
-
- It was only possible to perform algebraic estimation, which didn't
- give so much accurate results.
-
- Implemented a way to perform algebraic estimation followed with
- refinement step using Ceres minimizer.
-
- The code was actually mostly already there since keyframe selection
- patch. Made such estimation a generic function in multiview/ and
- hanged API for estimation in order to pass all additional options via
- an options structure (the same way as it's done fr Ceres).
-
- Most of the options are straight-forward to understand,but some
- deserves more description here:
-
- * expected_average_symmetric_distance is used as an early output check
- and as soon as average symmetric error goes below this threshold
- refining finishes.
-
- This distance is measured in the same units as input points are.
-
- It is arguable whether we need callback for this or not, but seems
- Ceres doesn't have some kind of absolute threshold for function value
- and function_tolerance behaves different from logic behind expected
- symmetric error.
-
- * There' an option to normalize correspondences before estimating the
- homography in order to increase estimation stability. See
-
- R. Hartley and A. Zisserman. Multiple View Geometry in Computer
- Vision. Cambridge University Press, second edition, 2003.
-
- https://www.cs.ubc.ca/grads/resources/thesis/May09/Dubrofsky_Elan.pdf
-
-commit 1cdad972c4a9005e78891524cbd6d65600ca7e99
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Wed Sep 25 16:12:29 2013 +0600
-
- Code cleanup: Minor function capitalization fix
-
- Original patch by Joseph Mansfield to the Blender repository.
-
-commit 434316d084e8a41fd452f03610d7244d664948dc
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Wed Sep 25 16:07:43 2013 +0600
-
- Code cleanup: spelling correction
-
- Original patch by Joseph Mansfield to the Blender repository.
-
-commit 5cfe8465ac70407c0959c53bcd5206657a1322a2
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Wed Sep 25 16:02:48 2013 +0600
-
- Fix for uninitialized covariance matrix
-
- Lead to unpredictable tracking termination criteria.
-
-commit fd86b77d413489649a989f075b061714ed9a72fc
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Wed Sep 25 16:01:19 2013 +0600
-
- Add Procrustes PNP ("PPnP") resection algorithm to libmv
-
- This adds a new Euclidean resection method, used to create the
- initial reconstruction in the motion tracker, to libmv. The method
- is based on the Procrustes PNP algorithm (aka "PPnP"). Currently
- the algorithm is not connected with the motion tracker, but it
- will be eventually since it supports initialization.
-
- Having an initial guess when doing resection is important for
- ambiguous cases where potentially the user could offer extra
- guidance to the solver, in the form of "this point is in front of
- that point".
-
- Original patch by Keir Mierle made to Blender repository.
diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript
index 162fb88df53..251e5835d64 100644
--- a/extern/libmv/SConscript
+++ b/extern/libmv/SConscript
@@ -6,13 +6,28 @@
import sys
import os
-from FindSharedPtr import FindSharedPtr
Import('env')
defs = []
incs = '.'
+if env['WITH_BF_LIBMV'] or (env['WITH_BF_CYCLES'] and env['WITH_BF_CYCLES_LOGGING']):
+ defs.append('GOOGLE_GLOG_DLL_DECL=')
+ defs.append('WITH_LIBMV_GUARDED_ALLOC')
+ defs.append('LIBMV_NO_FAST_DETECTOR')
+
+ incs += ' ../Eigen3 third_party/gflags third_party/gflags/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
+ incs += ' ' + env['BF_PNG_INC']
+ incs += ' ' + env['BF_ZLIB_INC']
+
+ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+ incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog'
+ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+ incs += ' ./third_party/msinttypes'
+ else:
+ incs += ' ./third_party/glog/src'
+
if env['WITH_BF_LIBMV']:
if not env['WITH_SHARED_PTR_SUPPORT']:
print("-- Unable to find shared_ptr which is required for compilation.")
@@ -23,40 +38,33 @@ if env['WITH_BF_LIBMV']:
if env['SHARED_PTR_NAMESPACE'] == 'std::tr1':
defs.append('CERES_TR1_SHARED_PTR')
- defs.append('GOOGLE_GLOG_DLL_DECL=')
- defs.append('WITH_LIBMV_GUARDED_ALLOC')
- defs.append('LIBMV_NO_FAST_DETECTOR')
-
src = env.Glob('intern/*.cc')
src.remove('intern' + os.sep + 'stub.cc')
+ src += env.Glob('libmv/autotrack/*.cc')
src += env.Glob('libmv/base/*.cc')
src += env.Glob('libmv/image/*.cc')
src += env.Glob('libmv/multiview/*.cc')
src += env.Glob('libmv/numeric/*.cc')
src += env.Glob('libmv/simple_pipeline/*.cc')
src += env.Glob('libmv/tracking/*.cc')
- src += env.Glob('third_party/gflags/*.cc')
-
- incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
- incs += ' ' + env['BF_PNG_INC']
- incs += ' ' + env['BF_ZLIB_INC']
-
- if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
- incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog'
- if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
- incs += ' ./third_party/msinttypes'
-
- src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc']
- src += ['./third_party/glog/src/windows/port.cc']
- else:
- src += env.Glob("third_party/glog/src/*.cc")
- incs += ' ./third_party/glog/src'
else:
src = env.Glob("intern/stub.cc")
src = [src for src in src if src.find('_test.cc') == -1]
-env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137] )
+env.BlenderLib(libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137])
+
+if env['WITH_BF_LIBMV'] or (env['WITH_BF_CYCLES'] and env['WITH_BF_CYCLES_LOGGING']):
+ glog_src = []
+ glog_src += env.Glob("third_party/gflags/*.cc")
+ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+ glog_src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc']
+ glog_src += ['./third_party/glog/src/windows/port.cc']
+ else:
+ glog_src.remove('third_party/gflags/windows_port.cc')
+ glog_src += env.Glob("third_party/glog/src/*.cc")
+
+ env.BlenderLib(libname = 'extern_glog', sources=glog_src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137])
if env['WITH_BF_LIBMV']:
SConscript(['third_party/SConscript'])
diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh
index f352f77373b..66023fa693c 100755
--- a/extern/libmv/bundle.sh
+++ b/extern/libmv/bundle.sh
@@ -75,7 +75,7 @@ for x in $src_dir $src_third_dir; do
fi
fi
- if test `echo $x | grep -c windows ` -eq 0; then
+ if test `echo $x | grep -c "windows\|gflags" ` -eq 0; then
if [ -z "$src" ]; then
src=$t
else
@@ -130,13 +130,42 @@ set(SRC
libmv-capi.h
)
-if(WITH_LIBMV)
+if(WITH_LIBMV OR WITH_GTESTS OR (WITH_CYCLES AND WITH_CYCLES_LOGGING))
+ list(APPEND INC
+ third_party/gflags
+ third_party/gflags/gflags
+ third_party/glog/src
+ third_party/ceres/include
+ third_party/ceres/config
+ ../../intern/guardedalloc
+ )
+
+ list(APPEND INC_SYS
+ ../Eigen3
+ \${PNG_INCLUDE_DIRS}
+ \${ZLIB_INCLUDE_DIRS}
+ )
+
+ if(WIN32)
+ list(APPEND INC
+ third_party/glog/src/windows
+ )
+
+ if(NOT MINGW)
+ list(APPEND INC
+ third_party/msinttypes
+ )
+ endif()
+ endif()
+
add_definitions(
-DWITH_LIBMV_GUARDED_ALLOC
-DGOOGLE_GLOG_DLL_DECL=
-DLIBMV_NO_FAST_DETECTOR=
)
+endif()
+if(WITH_LIBMV)
TEST_SHARED_PTR_SUPPORT()
if(SHARED_PTR_FOUND)
if(SHARED_PTR_TR1_MEMORY_HEADER)
@@ -149,56 +178,37 @@ if(WITH_LIBMV)
message(FATAL_ERROR "Unable to find shared_ptr.")
endif()
- list(APPEND INC
- third_party/gflags
- third_party/glog/src
- third_party/ceres/include
- third_party/ceres/config
- ../../intern/guardedalloc
- )
-
- list(APPEND INC_SYS
- ../Eigen3
- \${PNG_INCLUDE_DIR}
- \${ZLIB_INCLUDE_DIRS}
- )
-
list(APPEND SRC
+ intern/autotrack.cc
intern/camera_intrinsics.cc
intern/detector.cc
+ intern/frame_accessor.cc
intern/homography.cc
intern/image.cc
intern/logging.cc
intern/reconstruction.cc
intern/track_region.cc
intern/tracks.cc
+ intern/tracksN.cc
${sources}
${third_sources}
+ intern/autotrack.h
intern/camera_intrinsics.h
intern/detector.h
+ intern/frame_accessor.h
intern/homography.h
intern/image.h
intern/logging.h
intern/reconstruction.h
intern/track_region.h
intern/tracks.h
+ intern/tracksN.h
${headers}
${third_headers}
)
- if(WIN32)
- list(APPEND INC
- third_party/glog/src/windows
- )
-
- if(NOT MINGW)
- list(APPEND INC
- third_party/msinttypes
- )
- endif()
- endif()
if(WITH_GTESTS)
blender_add_lib(libmv_test_dataset "./libmv/multiview/test_data_sets.cc" "${INC}" "${INC_SYS}")
@@ -207,7 +217,7 @@ ${tests}
endif()
else()
list(APPEND SRC
- libmv-capi_stub.cc
+ intern/stub.cc
)
endif()
@@ -218,7 +228,7 @@ if(WITH_LIBMV)
endif()
# make GLog a separate target, so it can be used for gtest as well.
-if(WITH_LIBMV OR WITH_GTESTS)
+if(WITH_LIBMV OR WITH_GTESTS OR (WITH_CYCLES AND WITH_CYCLES_LOGGING))
# We compile GLog together with GFlag so we don't worry about
# adding extra lib to linker.
set(GLOG_SRC
@@ -252,6 +262,9 @@ ${third_gflags_headers}
third_party/glog/src/windows/glog/log_severity.h
third_party/glog/src/windows/port.h
third_party/glog/src/windows/config.h
+
+ third_party/gflags/windows_port.cc
+ third_party/gflags/windows_port.h
)
else()
list(APPEND GLOG_SRC
@@ -261,21 +274,11 @@ ${third_glog_headers}
)
endif()
- set(GLOG_INC
- third_party/gflags
- third_party/glog/src
- )
-
- set(GLOG_INC_SYS
- )
-
- blender_add_lib(extern_glog "\${GLOG_SRC}" "\${GLOG_INC}" "\${GLOG_INC_SYS}")
+ blender_add_lib(extern_glog "\${GLOG_SRC}" "\${INC}" "\${INC_SYS}")
endif()
EOF
cat > SConscript << EOF
-#!/usr/bin/python
-
# NOTE: This file is automatically generated by bundle.sh script
# If you're doing changes in this file, please update template
# in that script too
@@ -288,25 +291,12 @@ Import('env')
defs = []
incs = '.'
-if env['WITH_BF_LIBMV']:
- if not env['WITH_SHARED_PTR_SUPPORT']:
- print("-- Unable to find shared_ptr which is required for compilation.")
- exit(1)
-
- if env['SHARED_PTR_HEADER'] == 'tr1/memory':
- defs.append('CERES_TR1_MEMORY_HEADER')
- if env['SHARED_PTR_NAMESPACE'] == 'std::tr1':
- defs.append('CERES_TR1_SHARED_PTR')
-
+if env['WITH_BF_LIBMV'] or (env['WITH_BF_CYCLES'] and env['WITH_BF_CYCLES_LOGGING']):
defs.append('GOOGLE_GLOG_DLL_DECL=')
defs.append('WITH_LIBMV_GUARDED_ALLOC')
defs.append('LIBMV_NO_FAST_DETECTOR')
- src = env.Glob('intern/*.cc')
- src.remove('intern' + os.sep + 'stub.cc')
-$src
-
- incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
+ incs += ' ../Eigen3 third_party/gflags third_party/gflags/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
incs += ' ' + env['BF_PNG_INC']
incs += ' ' + env['BF_ZLIB_INC']
@@ -314,18 +304,40 @@ $src
incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog'
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
incs += ' ./third_party/msinttypes'
-${win_src}
- src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc']
- src += ['./third_party/glog/src/windows/port.cc']
else:
- src += env.Glob("third_party/glog/src/*.cc")
incs += ' ./third_party/glog/src'
+
+if env['WITH_BF_LIBMV']:
+ if not env['WITH_SHARED_PTR_SUPPORT']:
+ print("-- Unable to find shared_ptr which is required for compilation.")
+ exit(1)
+
+ if env['SHARED_PTR_HEADER'] == 'tr1/memory':
+ defs.append('CERES_TR1_MEMORY_HEADER')
+ if env['SHARED_PTR_NAMESPACE'] == 'std::tr1':
+ defs.append('CERES_TR1_SHARED_PTR')
+
+ src = env.Glob('intern/*.cc')
+ src.remove('intern' + os.sep + 'stub.cc')
+$src
else:
src = env.Glob("intern/stub.cc")
src = [src for src in src if src.find('_test.cc') == -1]
-env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137] )
+env.BlenderLib(libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137])
+
+if env['WITH_BF_LIBMV'] or (env['WITH_BF_CYCLES'] and env['WITH_BF_CYCLES_LOGGING']):
+ glog_src = []
+ glog_src += env.Glob("third_party/gflags/*.cc")
+ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+ glog_src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc']
+ glog_src += ['./third_party/glog/src/windows/port.cc']
+ else:
+ glog_src.remove('third_party/gflags/windows_port.cc')
+ glog_src += env.Glob("third_party/glog/src/*.cc")
+
+ env.BlenderLib(libname = 'extern_glog', sources=glog_src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137])
if env['WITH_BF_LIBMV']:
SConscript(['third_party/SConscript'])
diff --git a/extern/libmv/files.txt b/extern/libmv/files.txt
index f1eb9580ff5..11f8ef24781 100644
--- a/extern/libmv/files.txt
+++ b/extern/libmv/files.txt
@@ -1,3 +1,18 @@
+libmv/autotrack/autotrack.cc
+libmv/autotrack/autotrack.h
+libmv/autotrack/callbacks.h
+libmv/autotrack/frame_accessor.h
+libmv/autotrack/marker.h
+libmv/autotrack/model.h
+libmv/autotrack/predict_tracks.cc
+libmv/autotrack/predict_tracks.h
+libmv/autotrack/predict_tracks_test.cc
+libmv/autotrack/quad.h
+libmv/autotrack/reconstruction.h
+libmv/autotrack/region.h
+libmv/autotrack/tracks.cc
+libmv/autotrack/tracks.h
+libmv/autotrack/tracks_test.cc
libmv/base/aligned_malloc.cc
libmv/base/aligned_malloc.h
libmv/base/id_generator.h
@@ -104,6 +119,7 @@ libmv/tracking/brute_region_tracker.h
libmv/tracking/brute_region_tracker_test.cc
libmv/tracking/hybrid_region_tracker.cc
libmv/tracking/hybrid_region_tracker.h
+libmv/tracking/kalman_filter.h
libmv/tracking/klt_region_tracker.cc
libmv/tracking/klt_region_tracker.h
libmv/tracking/klt_region_tracker_test.cc
@@ -117,10 +133,10 @@ libmv/tracking/track_region.cc
libmv/tracking/track_region.h
libmv/tracking/trklt_region_tracker.cc
libmv/tracking/trklt_region_tracker.h
-third_party/gflags/AUTHORS
-third_party/gflags/ChangeLog
+third_party/gflags/AUTHORS.txt
+third_party/gflags/ChangeLog.txt
third_party/gflags/config.h
-third_party/gflags/COPYING
+third_party/gflags/COPYING.txt
third_party/gflags/gflags.cc
third_party/gflags/gflags_completions.cc
third_party/gflags/gflags/gflags_completions.h
@@ -128,9 +144,11 @@ third_party/gflags/gflags/gflags_declare.h
third_party/gflags/gflags/gflags.h
third_party/gflags/gflags_reporting.cc
third_party/gflags/mutex.h
-third_party/gflags/NEWS
+third_party/gflags/NEWS.txt
third_party/gflags/README.libmv
third_party/gflags/util.h
+third_party/gflags/windows_port.cc
+third_party/gflags/windows_port.h
third_party/glog/AUTHORS
third_party/glog/ChangeLog
third_party/glog/COPYING
diff --git a/extern/libmv/intern/autotrack.cc b/extern/libmv/intern/autotrack.cc
new file mode 100644
index 00000000000..f0cbc68f11e
--- /dev/null
+++ b/extern/libmv/intern/autotrack.cc
@@ -0,0 +1,99 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/autotrack.h"
+#include "intern/tracksN.h"
+#include "intern/utildefines.h"
+#include "libmv/autotrack/autotrack.h"
+
+using mv::AutoTrack;
+using mv::FrameAccessor;
+using mv::Marker;
+using libmv::TrackRegionOptions;
+using libmv::TrackRegionResult;
+
+libmv_AutoTrack* libmv_autoTrackNew(libmv_FrameAccessor *frame_accessor) {
+ return (libmv_AutoTrack*) LIBMV_OBJECT_NEW(AutoTrack,
+ (FrameAccessor*) frame_accessor);
+}
+
+void libmv_autoTrackDestroy(libmv_AutoTrack* libmv_autotrack) {
+ LIBMV_OBJECT_DELETE(libmv_autotrack, AutoTrack);
+}
+
+void libmv_autoTrackSetOptions(libmv_AutoTrack* libmv_autotrack,
+ const libmv_AutoTrackOptions* options) {
+ AutoTrack *autotrack = ((AutoTrack*) libmv_autotrack);
+ libmv_configureTrackRegionOptions(options->track_region,
+ &autotrack->options.track_region);
+
+ autotrack->options.search_region.min(0) = options->search_region.min[0];
+ autotrack->options.search_region.min(1) = options->search_region.min[1];
+ autotrack->options.search_region.max(0) = options->search_region.max[0];
+ autotrack->options.search_region.max(1) = options->search_region.max[1];
+}
+
+int libmv_autoTrackMarker(libmv_AutoTrack* libmv_autotrack,
+ const libmv_TrackRegionOptions* libmv_options,
+ libmv_Marker *libmv_tracked_marker,
+ libmv_TrackRegionResult* libmv_result) {
+
+ Marker tracked_marker;
+ TrackRegionOptions options;
+ TrackRegionResult result;
+ libmv_apiMarkerToMarker(*libmv_tracked_marker, &tracked_marker);
+ libmv_configureTrackRegionOptions(*libmv_options,
+ &options);
+ (((AutoTrack*) libmv_autotrack)->TrackMarker(&tracked_marker,
+ &result,
+ &options));
+ libmv_markerToApiMarker(tracked_marker, libmv_tracked_marker);
+ libmv_regionTrackergetResult(result, libmv_result);
+ return result.is_usable();
+}
+
+void libmv_autoTrackAddMarker(libmv_AutoTrack* libmv_autotrack,
+ const libmv_Marker* libmv_marker) {
+ Marker marker;
+ libmv_apiMarkerToMarker(*libmv_marker, &marker);
+ ((AutoTrack*) libmv_autotrack)->AddMarker(marker);
+}
+
+int libmv_autoTrackGetMarker(libmv_AutoTrack* libmv_autotrack,
+ int clip,
+ int frame,
+ int track,
+ libmv_Marker *libmv_marker) {
+ Marker marker;
+ int ok = ((AutoTrack*) libmv_autotrack)->GetMarker(clip,
+ frame,
+ track,
+ &marker);
+ if (ok) {
+ libmv_markerToApiMarker(marker, libmv_marker);
+ }
+ return ok;
+}
diff --git a/extern/libmv/intern/autotrack.h b/extern/libmv/intern/autotrack.h
new file mode 100644
index 00000000000..2a4a8f3c97f
--- /dev/null
+++ b/extern/libmv/intern/autotrack.h
@@ -0,0 +1,71 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_AUTOTRACK_H_
+#define LIBMV_C_API_AUTOTRACK_H_
+
+#include "intern/frame_accessor.h"
+#include "intern/tracksN.h"
+#include "intern/track_region.h"
+#include "intern/region.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_AutoTrack libmv_AutoTrack;
+
+typedef struct libmv_AutoTrackOptions {
+ libmv_TrackRegionOptions track_region;
+ libmv_Region search_region;
+} libmv_AutoTrackOptions;
+
+libmv_AutoTrack* libmv_autoTrackNew(libmv_FrameAccessor *frame_accessor);
+
+void libmv_autoTrackDestroy(libmv_AutoTrack* libmv_autotrack);
+
+void libmv_autoTrackSetOptions(libmv_AutoTrack* libmv_autotrack,
+ const libmv_AutoTrackOptions* options);
+
+int libmv_autoTrackMarker(libmv_AutoTrack* libmv_autotrack,
+ const libmv_TrackRegionOptions* libmv_options,
+ libmv_Marker *libmv_tracker_marker,
+ libmv_TrackRegionResult* libmv_result);
+
+void libmv_autoTrackAddMarker(libmv_AutoTrack* libmv_autotrack,
+ const libmv_Marker* libmv_marker);
+
+int libmv_autoTrackGetMarker(libmv_AutoTrack* libmv_autotrack,
+ int clip,
+ int frame,
+ int track,
+ libmv_Marker *libmv_marker);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_TRACKS_H_
diff --git a/extern/libmv/intern/frame_accessor.cc b/extern/libmv/intern/frame_accessor.cc
new file mode 100644
index 00000000000..8bf2cab914b
--- /dev/null
+++ b/extern/libmv/intern/frame_accessor.cc
@@ -0,0 +1,164 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/frame_accessor.h"
+#include "intern/image.h"
+#include "intern/utildefines.h"
+#include "libmv/autotrack/frame_accessor.h"
+#include "libmv/autotrack/region.h"
+#include "libmv/image/image.h"
+
+namespace {
+
+using libmv::FloatImage;
+using mv::FrameAccessor;
+using mv::Region;
+
+struct LibmvFrameAccessor : public FrameAccessor {
+ LibmvFrameAccessor(libmv_FrameAccessorUserData* user_data,
+ libmv_GetImageCallback get_image_callback,
+ libmv_ReleaseImageCallback release_image_callback)
+ : user_data_(user_data),
+ get_image_callback_(get_image_callback),
+ release_image_callback_(release_image_callback) { }
+
+ libmv_InputMode get_libmv_input_mode(InputMode input_mode) {
+ switch (input_mode) {
+#define CHECK_INPUT_MODE(mode) \
+ case mode: \
+ return LIBMV_IMAGE_MODE_ ## mode;
+ CHECK_INPUT_MODE(MONO)
+ CHECK_INPUT_MODE(RGBA)
+#undef CHECK_INPUT_MODE
+ }
+ assert(!"unknown input mode passed from Libmv.");
+ // TODO(sergey): Proper error handling here in the future.
+ return LIBMV_IMAGE_MODE_MONO;
+ }
+
+ void get_libmv_region(const Region& region,
+ libmv_Region* libmv_region) {
+ libmv_region->min[0] = region.min(0);
+ libmv_region->min[1] = region.min(1);
+ libmv_region->max[0] = region.max(0);
+ libmv_region->max[1] = region.max(1);
+ }
+
+ Key GetImage(int clip,
+ int frame,
+ InputMode input_mode,
+ int downscale,
+ const Region* region,
+ const Transform* transform,
+ FloatImage* destination) {
+ float *float_buffer;
+ int width, height, channels;
+ libmv_Region libmv_region;
+ if (region) {
+ get_libmv_region(*region, &libmv_region);
+ }
+ Key cache_key = get_image_callback_(user_data_,
+ clip,
+ frame,
+ get_libmv_input_mode(input_mode),
+ downscale,
+ region != NULL ? &libmv_region : NULL,
+ (libmv_FrameTransform*) transform,
+ &float_buffer,
+ &width,
+ &height,
+ &channels);
+
+ // TODO(sergey): Dumb code for until we can set data directly.
+ FloatImage temp_image(float_buffer,
+ height,
+ width,
+ channels);
+ destination->CopyFrom(temp_image);
+
+ return cache_key;
+ }
+
+ void ReleaseImage(Key cache_key) {
+ release_image_callback_(cache_key);
+ }
+
+ bool GetClipDimensions(int clip, int *width, int *height) {
+ return false;
+ }
+
+ int NumClips() {
+ return 1;
+ }
+
+ int NumFrames(int clip) {
+ return 0;
+ }
+
+ libmv_FrameAccessorUserData* user_data_;
+ libmv_GetImageCallback get_image_callback_;
+ libmv_ReleaseImageCallback release_image_callback_;
+};
+
+} // namespace
+
+libmv_FrameAccessor* libmv_FrameAccessorNew(
+ libmv_FrameAccessorUserData* user_data,
+ libmv_GetImageCallback get_image_callback,
+ libmv_ReleaseImageCallback release_image_callback) {
+ return (libmv_FrameAccessor*) LIBMV_OBJECT_NEW(LibmvFrameAccessor,
+ user_data,
+ get_image_callback,
+ release_image_callback);
+}
+
+void libmv_FrameAccessorDestroy(libmv_FrameAccessor* frame_accessor) {
+ LIBMV_OBJECT_DELETE(frame_accessor, LibmvFrameAccessor);
+}
+
+int64_t libmv_frameAccessorgetTransformKey(const libmv_FrameTransform *transform) {
+ return ((FrameAccessor::Transform*) transform)->key();
+}
+
+void libmv_frameAccessorgetTransformRun(const libmv_FrameTransform *transform,
+ const libmv_FloatImage *input_image,
+ libmv_FloatImage *output_image) {
+ const FloatImage input(input_image->buffer,
+ input_image->height,
+ input_image->width,
+ input_image->channels);
+
+ FloatImage output;
+ ((FrameAccessor::Transform*) transform)->run(input,
+ &output);
+
+ int num_pixels = output.Width() *output.Height() * output.Depth();
+ output_image->buffer = new float[num_pixels];
+ memcpy(output_image->buffer, output.Data(), num_pixels * sizeof(float));
+ output_image->width = output.Width();
+ output_image->height = output.Height();
+ output_image->channels = output.Depth();
+}
diff --git a/extern/libmv/intern/frame_accessor.h b/extern/libmv/intern/frame_accessor.h
new file mode 100644
index 00000000000..3e813fe7581
--- /dev/null
+++ b/extern/libmv/intern/frame_accessor.h
@@ -0,0 +1,79 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_FRAME_ACCESSOR_H_
+#define LIBMV_C_API_FRAME_ACCESSOR_H_
+
+#include <stdint.h>
+
+#include "intern/image.h"
+#include "intern/region.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_FrameAccessor libmv_FrameAccessor;
+typedef struct libmv_FrameTransform libmv_FrameTransform;
+typedef struct libmv_FrameAccessorUserData libmv_FrameAccessorUserData;
+typedef void *libmv_CacheKey;
+
+typedef enum {
+ LIBMV_IMAGE_MODE_MONO,
+ LIBMV_IMAGE_MODE_RGBA,
+} libmv_InputMode;
+
+typedef libmv_CacheKey (*libmv_GetImageCallback) (
+ libmv_FrameAccessorUserData* user_data,
+ int clip,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ const libmv_Region* region,
+ const libmv_FrameTransform* transform,
+ float** destination,
+ int* width,
+ int* height,
+ int* channels);
+
+typedef void (*libmv_ReleaseImageCallback) (libmv_CacheKey cache_key);
+
+libmv_FrameAccessor* libmv_FrameAccessorNew(
+ libmv_FrameAccessorUserData* user_data,
+ libmv_GetImageCallback get_image_callback,
+ libmv_ReleaseImageCallback release_image_callback);
+void libmv_FrameAccessorDestroy(libmv_FrameAccessor* frame_accessor);
+
+int64_t libmv_frameAccessorgetTransformKey(const libmv_FrameTransform *transform);
+
+void libmv_frameAccessorgetTransformRun(const libmv_FrameTransform *transform,
+ const libmv_FloatImage *input_image,
+ libmv_FloatImage *output_image);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_FRAME_ACCESSOR_H_
diff --git a/extern/libmv/intern/image.cc b/extern/libmv/intern/image.cc
index df9a01ee8de..5018caef5b1 100644
--- a/extern/libmv/intern/image.cc
+++ b/extern/libmv/intern/image.cc
@@ -34,7 +34,7 @@
using libmv::FloatImage;
using libmv::SamplePlanarPatch;
-void libmv_floatImaheDestroy(libmv_FloatImage *image) {
+void libmv_floatImageDestroy(libmv_FloatImage *image) {
delete [] image->buffer;
}
diff --git a/extern/libmv/intern/image.h b/extern/libmv/intern/image.h
index 9936e748b9d..1213943aac4 100644
--- a/extern/libmv/intern/image.h
+++ b/extern/libmv/intern/image.h
@@ -64,7 +64,7 @@ typedef struct libmv_FloatImage {
int channels;
} libmv_FloatImage;
-void libmv_floatImaheDestroy(libmv_FloatImage *image);
+void libmv_floatImageDestroy(libmv_FloatImage *image);
void libmv_samplePlanarPatchFloat(const float* image,
int width,
diff --git a/extern/libmv/intern/logging.cc b/extern/libmv/intern/logging.cc
index 4ab2d91c8b4..77b56ef4df3 100644
--- a/extern/libmv/intern/logging.cc
+++ b/extern/libmv/intern/logging.cc
@@ -35,21 +35,21 @@ void libmv_initLogging(const char* argv0) {
google::GLOG_FATAL);
google::InitGoogleLogging(argv0);
- google::SetCommandLineOption("logtostderr", "1");
- google::SetCommandLineOption("v", "0");
- google::SetCommandLineOption("stderrthreshold", severity_fatal);
- google::SetCommandLineOption("minloglevel", severity_fatal);
+ gflags::SetCommandLineOption("logtostderr", "1");
+ gflags::SetCommandLineOption("v", "0");
+ gflags::SetCommandLineOption("stderrthreshold", severity_fatal);
+ gflags::SetCommandLineOption("minloglevel", severity_fatal);
}
void libmv_startDebugLogging(void) {
- google::SetCommandLineOption("logtostderr", "1");
- google::SetCommandLineOption("v", "2");
- google::SetCommandLineOption("stderrthreshold", "1");
- google::SetCommandLineOption("minloglevel", "0");
+ gflags::SetCommandLineOption("logtostderr", "1");
+ gflags::SetCommandLineOption("v", "2");
+ gflags::SetCommandLineOption("stderrthreshold", "1");
+ gflags::SetCommandLineOption("minloglevel", "0");
}
void libmv_setLoggingVerbosity(int verbosity) {
char val[10];
snprintf(val, sizeof(val), "%d", verbosity);
- google::SetCommandLineOption("v", val);
+ gflags::SetCommandLineOption("v", val);
}
diff --git a/extern/libmv/intern/reconstruction.cc b/extern/libmv/intern/reconstruction.cc
index f89efd8e8ca..046671e467f 100644
--- a/extern/libmv/intern/reconstruction.cc
+++ b/extern/libmv/intern/reconstruction.cc
@@ -61,6 +61,7 @@ struct libmv_Reconstruction {
CameraIntrinsics *intrinsics;
double error;
+ bool is_valid;
};
namespace {
@@ -289,6 +290,12 @@ libmv_Reconstruction *libmv_solveReconstruction(
LG << "number of markers for init: " << keyframe_markers.size();
+ if (keyframe_markers.size() < 8) {
+ LG << "No enough markers to initialize from";
+ libmv_reconstruction->is_valid = false;
+ return libmv_reconstruction;
+ }
+
update_callback.invoke(0, "Initial reconstruction");
EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
@@ -319,6 +326,7 @@ libmv_Reconstruction *libmv_solveReconstruction(
progress_update_callback,
callback_customdata);
+ libmv_reconstruction->is_valid = true;
return (libmv_Reconstruction *) libmv_reconstruction;
}
@@ -377,9 +385,14 @@ libmv_Reconstruction *libmv_solveModal(
progress_update_callback,
callback_customdata);
+ libmv_reconstruction->is_valid = true;
return (libmv_Reconstruction *) libmv_reconstruction;
}
+int libmv_reconstructionIsValid(libmv_Reconstruction *libmv_reconstruction) {
+ return libmv_reconstruction->is_valid;
+}
+
void libmv_reconstructionDestroy(libmv_Reconstruction *libmv_reconstruction) {
LIBMV_OBJECT_DELETE(libmv_reconstruction->intrinsics, CameraIntrinsics);
LIBMV_OBJECT_DELETE(libmv_reconstruction, libmv_Reconstruction);
diff --git a/extern/libmv/intern/reconstruction.h b/extern/libmv/intern/reconstruction.h
index 88e810b54aa..8b6b34a6142 100644
--- a/extern/libmv/intern/reconstruction.h
+++ b/extern/libmv/intern/reconstruction.h
@@ -68,6 +68,8 @@ libmv_Reconstruction* libmv_solveModal(
reconstruct_progress_update_cb progress_update_callback,
void* callback_customdata);
+int libmv_reconstructionIsValid(libmv_Reconstruction *libmv_reconstruction);
+
void libmv_reconstructionDestroy(libmv_Reconstruction* libmv_reconstruction);
int libmv_reprojectionPointForTrack(
diff --git a/extern/libmv/intern/stub.cc b/extern/libmv/intern/stub.cc
index cd8bb8ab841..f02509de90a 100644
--- a/extern/libmv/intern/stub.cc
+++ b/extern/libmv/intern/stub.cc
@@ -97,6 +97,10 @@ void libmv_samplePlanarPatchByte(const unsigned char * /*image*/,
/* TODO(sergey): implement */
}
+void libmv_floatImageDestroy(libmv_FloatImage* /*image*/)
+{
+}
+
/* ************ Tracks ************ */
libmv_Tracks *libmv_tracksNew(void) {
@@ -134,6 +138,10 @@ libmv_Reconstruction *libmv_solveModal(
return NULL;
}
+int libmv_reconstructionIsValid(libmv_Reconstruction * /*libmv_reconstruction*/) {
+ return 0;
+}
+
int libmv_reprojectionPointForTrack(
const libmv_Reconstruction * /*libmv_reconstruction*/,
int /*track*/,
@@ -328,3 +336,68 @@ void libmv_homography2DFromCorrespondencesEuc(/* const */ double (*x1)[2],
H[1][1] = 1.0f;
H[2][2] = 1.0f;
}
+
+/* ************ autotrack ************ */
+
+libmv_AutoTrack* libmv_autoTrackNew(libmv_FrameAccessor* /*frame_accessor*/)
+{
+ return NULL;
+}
+
+void libmv_autoTrackDestroy(libmv_AutoTrack* /*libmv_autotrack*/)
+{
+}
+
+void libmv_autoTrackSetOptions(libmv_AutoTrack* /*libmv_autotrack*/,
+ const libmv_AutoTrackOptions* /*options*/)
+{
+}
+
+int libmv_autoTrackMarker(libmv_AutoTrack* /*libmv_autotrack*/,
+ const libmv_TrackRegionOptions* /*libmv_options*/,
+ libmv_Marker */*libmv_tracker_marker*/,
+ libmv_TrackRegionResult* /*libmv_result*/)
+{
+ return 0;
+}
+
+void libmv_autoTrackAddMarker(libmv_AutoTrack* /*libmv_autotrack*/,
+ const libmv_Marker* /*libmv_marker*/)
+{
+}
+
+int libmv_autoTrackGetMarker(libmv_AutoTrack* /*libmv_autotrack*/,
+ int /*clip*/,
+ int /*frame*/,
+ int /*track*/,
+ libmv_Marker* /*libmv_marker*/)
+{
+ return 0;
+}
+
+/* ************ frame accessor ************ */
+
+libmv_FrameAccessor* libmv_FrameAccessorNew(
+ libmv_FrameAccessorUserData* /*user_data**/,
+ libmv_GetImageCallback /*get_image_callback*/,
+ libmv_ReleaseImageCallback /*release_image_callback*/)
+{
+ return NULL;
+}
+
+void libmv_FrameAccessorDestroy(libmv_FrameAccessor* /*frame_accessor*/)
+{
+}
+
+int64_t libmv_frameAccessorgetTransformKey(
+ const libmv_FrameTransform */*transform*/)
+{
+ return 0;
+}
+
+void libmv_frameAccessorgetTransformRun(const libmv_FrameTransform* /*transform*/,
+ const libmv_FloatImage* /*input_image*/,
+ libmv_FloatImage* /*output_image*/)
+{
+}
+
diff --git a/extern/libmv/intern/tracksN.cc b/extern/libmv/intern/tracksN.cc
new file mode 100644
index 00000000000..9e1da88ef10
--- /dev/null
+++ b/extern/libmv/intern/tracksN.cc
@@ -0,0 +1,138 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/tracksN.h"
+#include "intern/utildefines.h"
+#include "libmv/autotrack/marker.h"
+#include "libmv/autotrack/tracks.h"
+
+using mv::Marker;
+using mv::Tracks;
+
+void libmv_apiMarkerToMarker(const libmv_Marker& libmv_marker,
+ Marker *marker) {
+ marker->clip = libmv_marker.clip;
+ marker->frame = libmv_marker.frame;
+ marker->track = libmv_marker.track;
+ marker->center(0) = libmv_marker.center[0];
+ marker->center(1) = libmv_marker.center[1];
+ for (int i = 0; i < 4; i++) {
+ marker->patch.coordinates(i, 0) = libmv_marker.patch[i][0];
+ marker->patch.coordinates(i, 1) = libmv_marker.patch[i][1];
+ }
+ marker->search_region.min(0) = libmv_marker.search_region_min[0];
+ marker->search_region.min(1) = libmv_marker.search_region_min[1];
+ marker->search_region.max(0) = libmv_marker.search_region_max[0];
+ marker->search_region.max(1) = libmv_marker.search_region_max[1];
+ marker->weight = libmv_marker.weight;
+ marker->source = (Marker::Source) libmv_marker.source;
+ marker->status = (Marker::Status) libmv_marker.status;
+ marker->reference_clip = libmv_marker.reference_clip;
+ marker->reference_frame = libmv_marker.reference_frame;
+ marker->model_type = (Marker::ModelType) libmv_marker.model_type;
+ marker->model_id = libmv_marker.model_id;
+ marker->disabled_channels = libmv_marker.disabled_channels;
+}
+
+void libmv_markerToApiMarker(const Marker& marker,
+ libmv_Marker *libmv_marker) {
+ libmv_marker->clip = marker.clip;
+ libmv_marker->frame = marker.frame;
+ libmv_marker->track = marker.track;
+ libmv_marker->center[0] = marker.center(0);
+ libmv_marker->center[1] = marker.center(1);
+ for (int i = 0; i < 4; i++) {
+ libmv_marker->patch[i][0] = marker.patch.coordinates(i, 0);
+ libmv_marker->patch[i][1] = marker.patch.coordinates(i, 1);
+ }
+ libmv_marker->search_region_min[0] = marker.search_region.min(0);
+ libmv_marker->search_region_min[1] = marker.search_region.min(1);
+ libmv_marker->search_region_max[0] = marker.search_region.max(0);
+ libmv_marker->search_region_max[1] = marker.search_region.max(1);
+ libmv_marker->weight = marker.weight;
+ libmv_marker->source = (libmv_MarkerSource) marker.source;
+ libmv_marker->status = (libmv_MarkerStatus) marker.status;
+ libmv_marker->reference_clip = marker.reference_clip;
+ libmv_marker->reference_frame = marker.reference_frame;
+ libmv_marker->model_type = (libmv_MarkerModelType) marker.model_type;
+ libmv_marker->model_id = marker.model_id;
+ libmv_marker->disabled_channels = marker.disabled_channels;
+}
+
+libmv_TracksN* libmv_tracksNewN(void) {
+ Tracks* tracks = LIBMV_OBJECT_NEW(Tracks);
+
+ return (libmv_TracksN*) tracks;
+}
+
+void libmv_tracksDestroyN(libmv_TracksN* libmv_tracks) {
+ LIBMV_OBJECT_DELETE(libmv_tracks, Tracks);
+}
+
+void libmv_tracksAddMarkerN(libmv_TracksN* libmv_tracks,
+ const libmv_Marker* libmv_marker) {
+ Marker marker;
+ libmv_apiMarkerToMarker(*libmv_marker, &marker);
+ ((Tracks*) libmv_tracks)->AddMarker(marker);
+}
+
+void libmv_tracksGetMarkerN(libmv_TracksN* libmv_tracks,
+ int clip,
+ int frame,
+ int track,
+ libmv_Marker* libmv_marker) {
+ Marker marker;
+ ((Tracks*) libmv_tracks)->GetMarker(clip, frame, track, &marker);
+ libmv_markerToApiMarker(marker, libmv_marker);
+}
+
+void libmv_tracksRemoveMarkerN(libmv_TracksN* libmv_tracks,
+ int clip,
+ int frame,
+ int track) {
+ ((Tracks *) libmv_tracks)->RemoveMarker(clip, frame, track);
+}
+
+void libmv_tracksRemoveMarkersForTrack(libmv_TracksN* libmv_tracks,
+ int track) {
+ ((Tracks *) libmv_tracks)->RemoveMarkersForTrack(track);
+}
+
+int libmv_tracksMaxClipN(libmv_TracksN* libmv_tracks) {
+ return ((Tracks*) libmv_tracks)->MaxClip();
+}
+
+int libmv_tracksMaxFrameN(libmv_TracksN* libmv_tracks, int clip) {
+ return ((Tracks*) libmv_tracks)->MaxFrame(clip);
+}
+
+int libmv_tracksMaxTrackN(libmv_TracksN* libmv_tracks) {
+ return ((Tracks*) libmv_tracks)->MaxTrack();
+}
+
+int libmv_tracksNumMarkersN(libmv_TracksN* libmv_tracks) {
+ return ((Tracks*) libmv_tracks)->NumMarkers();
+}
diff --git a/extern/libmv/intern/tracksN.h b/extern/libmv/intern/tracksN.h
new file mode 100644
index 00000000000..d0cb54e40bc
--- /dev/null
+++ b/extern/libmv/intern/tracksN.h
@@ -0,0 +1,129 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+// TODO(serrgey): For the time being we're converting simple pipeline
+// to an autotrack pipeline we call it tracks.
+// Once we've done with porting we remove N.
+
+#ifndef LIBMV_C_API_TRACKSN_H_
+#define LIBMV_C_API_TRACKSN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_TracksN libmv_TracksN;
+
+// Keep order in this enums exactly the same as in mv::Marker.
+// Otherwise API wouldn't convert the values properly.
+typedef enum libmv_MarkerSource {
+ LIBMV_MARKER_SOURCE_MANUAL,
+ LIBMV_MARKER_SOURCE_DETECTED,
+ LIBMV_MARKER_SOURCE_TRACKED,
+ LIBMV_MARKER_SOURCE_MATCHED,
+ LIBMV_MARKER_SOURCE_PREDICTED,
+} libmv_MarkerSource;
+
+typedef enum libmv_MarkerStatus {
+ LIBMV_MARKER_STATUS_UNKNOWN,
+ LIBMV_MARKER_STATUS_INLIER,
+ LIBMV_MARKER_STATUS_OUTLIER,
+} libmv_MarkerStatus;
+
+typedef enum libmv_MarkerModelType {
+ LIBMV_MARKER_MODEL_TYPE_POINT,
+ LIBMV_MARKER_MODEL_TYPE_PLANE,
+ LIBMV_MARKER_MODEL_TYPE_LINE,
+ LIBMV_MARKER_MODEL_TYPE_CUBE,
+} libmv_MarkerModelType;
+
+enum libmv_MarkerChannel {
+ LIBMV_MARKER_CHANNEL_R = (1 << 0),
+ LIBMV_MARKER_CHANNEL_G = (1 << 1),
+ LIBMV_MARKER_CHANNEL_B = (1 << 2),
+};
+
+typedef struct libmv_Marker {
+ int clip;
+ int frame;
+ int track;
+ float center[2];
+ float patch[4][2];
+ float search_region_min[2];
+ float search_region_max[2];
+ float weight;
+ libmv_MarkerSource source;
+ libmv_MarkerStatus status;
+ int reference_clip;
+ int reference_frame;
+ libmv_MarkerModelType model_type;
+ int model_id;
+ int disabled_channels;
+} libmv_Marker;
+
+#ifdef __cplusplus
+namespace mv {
+ struct Marker;
+}
+void libmv_apiMarkerToMarker(const libmv_Marker& libmv_marker,
+ mv::Marker *marker);
+
+void libmv_markerToApiMarker(const mv::Marker& marker,
+ libmv_Marker *libmv_marker);
+#endif
+
+libmv_TracksN* libmv_tracksNewN(void);
+
+void libmv_tracksDestroyN(libmv_TracksN* libmv_tracks);
+
+
+void libmv_tracksAddMarkerN(libmv_TracksN* libmv_tracks,
+ const libmv_Marker* libmv_marker);
+
+void libmv_tracksGetMarkerN(libmv_TracksN* libmv_tracks,
+ int clip,
+ int frame,
+ int track,
+ libmv_Marker* libmv_marker);
+
+void libmv_tracksRemoveMarkerN(libmv_TracksN* libmv_tracks,
+ int clip,
+ int frame,
+ int track);
+
+void libmv_tracksRemoveMarkersForTrack(libmv_TracksN* libmv_tracks,
+ int track);
+
+int libmv_tracksMaxClipN(libmv_TracksN* libmv_tracks);
+int libmv_tracksMaxFrameN(libmv_TracksN* libmv_tracks, int clip);
+int libmv_tracksMaxTrackN(libmv_TracksN* libmv_tracks);
+int libmv_tracksNumMarkersN(libmv_TracksN* libmv_tracks);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_TRACKS_H_
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index 524f1822bc7..92e206a19b2 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -27,13 +27,16 @@
#ifndef LIBMV_C_API_H
#define LIBMV_C_API_H
+#include "intern/autotrack.h"
#include "intern/camera_intrinsics.h"
#include "intern/detector.h"
+#include "intern/frame_accessor.h"
#include "intern/homography.h"
#include "intern/image.h"
#include "intern/logging.h"
#include "intern/reconstruction.h"
#include "intern/track_region.h"
#include "intern/tracks.h"
+#include "intern/tracksN.h"
#endif // LIBMV_C_API_H
diff --git a/extern/libmv/libmv/autotrack/autotrack.cc b/extern/libmv/libmv/autotrack/autotrack.cc
new file mode 100644
index 00000000000..96a0ef64a50
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/autotrack.cc
@@ -0,0 +1,290 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#include "libmv/autotrack/autotrack.h"
+#include "libmv/autotrack/quad.h"
+#include "libmv/autotrack/frame_accessor.h"
+#include "libmv/autotrack/predict_tracks.h"
+#include "libmv/base/scoped_ptr.h"
+#include "libmv/logging/logging.h"
+#include "libmv/numeric/numeric.h"
+
+namespace mv {
+
+namespace {
+
+class DisableChannelsTransform : public FrameAccessor::Transform {
+ public:
+ DisableChannelsTransform(int disabled_channels)
+ : disabled_channels_(disabled_channels) { }
+
+ int64_t key() const {
+ return disabled_channels_;
+ }
+
+ void run(const FloatImage& input, FloatImage* output) const {
+ bool disable_red = (disabled_channels_ & Marker::CHANNEL_R) != 0,
+ disable_green = (disabled_channels_ & Marker::CHANNEL_G) != 0,
+ disable_blue = (disabled_channels_ & Marker::CHANNEL_B) != 0;
+
+ LG << "Disabling channels: "
+ << (disable_red ? "R " : "")
+ << (disable_green ? "G " : "")
+ << (disable_blue ? "B" : "");
+
+ // It's important to rescale the resultappropriately so that e.g. if only
+ // blue is selected, it's not zeroed out.
+ float scale = (disable_red ? 0.0f : 0.2126f) +
+ (disable_green ? 0.0f : 0.7152f) +
+ (disable_blue ? 0.0f : 0.0722f);
+
+ output->Resize(input.Height(), input.Width(), 1);
+ for (int y = 0; y < input.Height(); y++) {
+ for (int x = 0; x < input.Width(); x++) {
+ float r = disable_red ? 0.0f : input(y, x, 0);
+ float g = disable_green ? 0.0f : input(y, x, 1);
+ float b = disable_blue ? 0.0f : input(y, x, 2);
+ (*output)(y, x, 0) = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
+ }
+ }
+ }
+
+ private:
+ // Bitfield representing visible channels, bits are from Marker::Channel.
+ int disabled_channels_;
+};
+
+template<typename QuadT, typename ArrayT>
+void QuadToArrays(const QuadT& quad, ArrayT* x, ArrayT* y) {
+ for (int i = 0; i < 4; ++i) {
+ x[i] = quad.coordinates(i, 0);
+ y[i] = quad.coordinates(i, 1);
+ }
+}
+
+void MarkerToArrays(const Marker& marker, double* x, double* y) {
+ Quad2Df offset_quad = marker.patch;
+ Vec2f origin = marker.search_region.Rounded().min;
+ offset_quad.coordinates.rowwise() -= origin.transpose();
+ QuadToArrays(offset_quad, x, y);
+ x[4] = marker.center.x() - origin(0);
+ y[4] = marker.center.y() - origin(1);
+}
+
+FrameAccessor::Key GetImageForMarker(const Marker& marker,
+ FrameAccessor* frame_accessor,
+ FloatImage* image) {
+ // TODO(sergey): Currently we pass float region to the accessor,
+ // but we don't want the accessor to decide the rounding, so we
+ // do rounding here.
+ // Ideally we would need to pass IntRegion to the frame accessor.
+ Region region = marker.search_region.Rounded();
+ libmv::scoped_ptr<FrameAccessor::Transform> transform = NULL;
+ if (marker.disabled_channels != 0) {
+ transform.reset(new DisableChannelsTransform(marker.disabled_channels));
+ }
+ return frame_accessor->GetImage(marker.clip,
+ marker.frame,
+ FrameAccessor::MONO,
+ 0, // No downscale for now.
+ &region,
+ transform.get(),
+ image);
+}
+
+} // namespace
+
+bool AutoTrack::TrackMarker(Marker* tracked_marker,
+ TrackRegionResult* result,
+ const TrackRegionOptions* track_options) {
+ // Try to predict the location of the second marker.
+ bool predicted_position = false;
+ if (PredictMarkerPosition(tracks_, tracked_marker)) {
+ LG << "Succesfully predicted!";
+ predicted_position = true;
+ } else {
+ LG << "Prediction failed; trying to track anyway.";
+ }
+
+ Marker reference_marker;
+ tracks_.GetMarker(tracked_marker->reference_clip,
+ tracked_marker->reference_frame,
+ tracked_marker->track,
+ &reference_marker);
+
+ // Convert markers into the format expected by TrackRegion.
+ double x1[5], y1[5];
+ MarkerToArrays(reference_marker, x1, y1);
+
+ double x2[5], y2[5];
+ MarkerToArrays(*tracked_marker, x2, y2);
+
+ // TODO(keir): Technically this could take a smaller slice from the source
+ // image instead of taking one the size of the search window.
+ FloatImage reference_image;
+ FrameAccessor::Key reference_key = GetImageForMarker(reference_marker,
+ frame_accessor_,
+ &reference_image);
+ if (!reference_key) {
+ LG << "Couldn't get frame for reference marker: " << reference_marker;
+ return false;
+ }
+
+ FloatImage tracked_image;
+ FrameAccessor::Key tracked_key = GetImageForMarker(*tracked_marker,
+ frame_accessor_,
+ &tracked_image);
+ if (!tracked_key) {
+ LG << "Couldn't get frame for tracked marker: " << tracked_marker;
+ return false;
+ }
+
+ // Store original position befoer tracking, so we can claculate offset later.
+ Vec2f original_center = tracked_marker->center;
+
+ // Do the tracking!
+ TrackRegionOptions local_track_region_options;
+ if (track_options) {
+ local_track_region_options = *track_options;
+ }
+ local_track_region_options.num_extra_points = 1; // For center point.
+ local_track_region_options.attempt_refine_before_brute = predicted_position;
+ TrackRegion(reference_image,
+ tracked_image,
+ x1, y1,
+ local_track_region_options,
+ x2, y2,
+ result);
+
+ // Copy results over the tracked marker.
+ Vec2f tracked_origin = tracked_marker->search_region.Rounded().min;
+ for (int i = 0; i < 4; ++i) {
+ tracked_marker->patch.coordinates(i, 0) = x2[i] + tracked_origin[0];
+ tracked_marker->patch.coordinates(i, 1) = y2[i] + tracked_origin[1];
+ }
+ tracked_marker->center(0) = x2[4] + tracked_origin[0];
+ tracked_marker->center(1) = y2[4] + tracked_origin[1];
+ Vec2f delta = tracked_marker->center - original_center;
+ tracked_marker->search_region.Offset(delta);
+ tracked_marker->source = Marker::TRACKED;
+ tracked_marker->status = Marker::UNKNOWN;
+ tracked_marker->reference_clip = reference_marker.clip;
+ tracked_marker->reference_frame = reference_marker.frame;
+
+ // Release the images from the accessor cache.
+ frame_accessor_->ReleaseImage(reference_key);
+ frame_accessor_->ReleaseImage(tracked_key);
+
+ // TODO(keir): Possibly the return here should get removed since the results
+ // are part of TrackResult. However, eventually the autotrack stuff will have
+ // extra status (e.g. prediction fail, etc) that should get included.
+ return true;
+}
+
+void AutoTrack::AddMarker(const Marker& marker) {
+ tracks_.AddMarker(marker);
+}
+
+void AutoTrack::SetMarkers(vector<Marker>* markers) {
+ tracks_.SetMarkers(markers);
+}
+
+bool AutoTrack::GetMarker(int clip, int frame, int track,
+ Marker* markers) const {
+ return tracks_.GetMarker(clip, frame, track, markers);
+}
+
+void AutoTrack::DetectAndTrack(const DetectAndTrackOptions& options) {
+ int num_clips = frame_accessor_->NumClips();
+ for (int clip = 0; clip < num_clips; ++clip) {
+ int num_frames = frame_accessor_->NumFrames(clip);
+ vector<Marker> previous_frame_markers;
+ // Q: How to decide track #s when detecting?
+ // Q: How to match markers from previous frame? set of prev frame tracks?
+ // Q: How to decide what markers should get tracked and which ones should not?
+ for (int frame = 0; frame < num_frames; ++frame) {
+ if (Cancelled()) {
+ LG << "Got cancel message while detecting and tracking...";
+ return;
+ }
+ // First, get or detect markers for this frame.
+ vector<Marker> this_frame_markers;
+ tracks_.GetMarkersInFrame(clip, frame, &this_frame_markers);
+ LG << "Clip " << clip << ", frame " << frame << " have "
+ << this_frame_markers.size();
+ if (this_frame_markers.size() < options.min_num_features) {
+ DetectFeaturesInFrame(clip, frame);
+ this_frame_markers.clear();
+ tracks_.GetMarkersInFrame(clip, frame, &this_frame_markers);
+ LG << "... detected " << this_frame_markers.size() << " features.";
+ }
+ if (previous_frame_markers.empty()) {
+ LG << "First frame; skipping tracking stage.";
+ previous_frame_markers.swap(this_frame_markers);
+ continue;
+ }
+ // Second, find tracks that should get tracked forward into this frame.
+ // To avoid tracking markers that are already tracked to this frame, make
+ // a sorted set of the tracks that exist in the last frame.
+ vector<int> tracks_in_this_frame;
+ for (int i = 0; i < this_frame_markers.size(); ++i) {
+ tracks_in_this_frame.push_back(this_frame_markers[i].track);
+ }
+ std::sort(tracks_in_this_frame.begin(),
+ tracks_in_this_frame.end());
+
+ // Find tracks in the previous frame that are not in this one.
+ vector<Marker*> previous_frame_markers_to_track;
+ int num_skipped = 0;
+ for (int i = 0; i < previous_frame_markers.size(); ++i) {
+ if (std::binary_search(tracks_in_this_frame.begin(),
+ tracks_in_this_frame.end(),
+ previous_frame_markers[i].track)) {
+ num_skipped++;
+ } else {
+ previous_frame_markers_to_track.push_back(&previous_frame_markers[i]);
+ }
+ }
+
+ // Finally track the markers from the last frame into this one.
+ // TODO(keir): Use OMP.
+ for (int i = 0; i < previous_frame_markers_to_track.size(); ++i) {
+ Marker this_frame_marker = *previous_frame_markers_to_track[i];
+ this_frame_marker.frame = frame;
+ LG << "Tracking: " << this_frame_marker;
+ TrackRegionResult result;
+ TrackMarker(&this_frame_marker, &result);
+ if (result.is_usable()) {
+ LG << "Success: " << this_frame_marker;
+ AddMarker(this_frame_marker);
+ this_frame_markers.push_back(this_frame_marker);
+ } else {
+ LG << "Failed to track: " << this_frame_marker;
+ }
+ }
+ // Put the markers from this frame
+ previous_frame_markers.swap(this_frame_markers);
+ }
+ }
+}
+
+} // namespace mv
diff --git a/extern/libmv/libmv/autotrack/autotrack.h b/extern/libmv/libmv/autotrack/autotrack.h
new file mode 100644
index 00000000000..1d7422f54e7
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/autotrack.h
@@ -0,0 +1,226 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef LIBMV_AUTOTRACK_AUTOTRACK_H_
+#define LIBMV_AUTOTRACK_AUTOTRACK_H_
+
+#include "libmv/autotrack/tracks.h"
+#include "libmv/autotrack/region.h"
+#include "libmv/tracking/track_region.h"
+
+namespace libmv {
+class CameraIntrinsics;
+};
+
+namespace mv {
+
+using libmv::CameraIntrinsics;
+using libmv::TrackRegionOptions;
+using libmv::TrackRegionResult;
+
+struct FrameAccessor;
+class OperationListener;
+
+// The coordinator of all tracking operations; keeps track of all state
+// relating to tracking and reconstruction; for example, 2D tracks and motion
+// models, reconstructed cameras, points, and planes; tracking settings; etc.
+//
+// Typical usage for full autotrack:
+//
+// AutoTrack auto_track(image_accessor);
+// auto_track.SetNumFramesInClip(0, 10);
+// auto_track.SetNumFramesInClip(1, 54);
+// auto_track.AutoTrack()
+//
+// It is also possible to specify options to control the reconstruction.
+// Furthermore, the individual methods of reconstruction are exposed to make it
+// possible to interact with the pipeline as it runs. For example, to track one
+// marker across frames,
+//
+// AutoTrack auto_track(image_accessor);
+// auto_track.SetNumFramesInClip(0, 10);
+// auto_track.SetNumFramesInClip(1, 54);
+// auto_track.AddMarker(...);
+// auto_track.TrackMarkerToFrame(int clip1, int frame1,
+// int clip2, int frame2,
+// options?)
+//
+class AutoTrack {
+ public:
+ struct Options {
+ // Default configuration for 2D tracking when calling TrackMarkerToFrame().
+ TrackRegionOptions track_region;
+
+ // Default search window for region tracking, in absolute frame pixels.
+ Region search_region;
+ };
+
+ AutoTrack(FrameAccessor* frame_accessor)
+ : frame_accessor_(frame_accessor) {}
+
+ // Marker manipulation.
+ // Clip manipulation.
+
+ // Set the number of clips. These clips will get accessed from the frame
+ // accessor, matches between frames found, and a reconstruction created.
+ //void SetNumFrames(int clip, int num_frames);
+
+ // Tracking & Matching
+
+ // Find the marker for the track in the frame indicated by the marker.
+ // Caller maintains ownership of *result and *tracked_marker.
+ bool TrackMarker(Marker* tracked_marker,
+ TrackRegionResult* result,
+ const TrackRegionOptions* track_options=NULL);
+
+ // Wrapper around Tracks API; however these may add additional processing.
+ void AddMarker(const Marker& tracked_marker);
+ void SetMarkers(vector<Marker>* markers);
+ bool GetMarker(int clip, int frame, int track, Marker* marker) const;
+
+ // TODO(keir): Implement frame matching! This could be very cool for loop
+ // closing and connecting across clips.
+ //void MatchFrames(int clip1, int frame1, int clip2, int frame2) {}
+
+ // Wrapper around the Reconstruction API.
+ // Returns the new ID.
+ int AddCameraIntrinsics(CameraIntrinsics* intrinsics) {
+ (void) intrinsics;
+ return 0;
+ } // XXX
+ int SetClipIntrinsics(int clip, int intrinsics) {
+ (void) clip;
+ (void) intrinsics;
+ return 0;
+ } // XXX
+
+ enum Motion {
+ GENERAL_CAMERA_MOTION,
+ TRIPOD_CAMERA_MOTION,
+ };
+ int SetClipMotion(int clip, Motion motion) {
+ (void) clip;
+ (void) motion;
+ return 0;
+ } // XXX
+
+ // Decide what to refine for the given intrinsics. bundle_options is from
+ // bundle.h (e.g. BUNDLE_FOCAL_LENGTH | BUNDLE_RADIAL_K1).
+ void SetIntrinsicsRefine(int intrinsics, int bundle_options) {
+ (void) intrinsics;
+ (void) bundle_options;
+ } // XXX
+
+ // Keyframe read/write.
+ struct ClipFrame {
+ int clip;
+ int frame;
+ };
+ const vector<ClipFrame>& keyframes() { return keyframes_; }
+ void ClearKeyframes() { keyframes_.clear(); }
+ void SetKeyframes(const vector<ClipFrame>& keyframes) {
+ keyframes_ = keyframes;
+ }
+
+ // What about reporting what happened? -- callbacks; maybe result struct.
+ void Reconstruct();
+
+ // Detect and track in 2D.
+ struct DetectAndTrackOptions {
+ int min_num_features;
+ };
+ void DetectAndTrack(const DetectAndTrackOptions& options);
+
+ struct DetectFeaturesInFrameOptions {
+ };
+ void DetectFeaturesInFrame(int clip, int frame,
+ const DetectFeaturesInFrameOptions* options=NULL) {
+ (void) clip;
+ (void) frame;
+ (void) options;
+ } // XXX
+
+ // Does not take ownership of the given listener, but keeps a reference to it.
+ void AddListener(OperationListener* listener) {(void) listener;} // XXX
+
+ // Create the initial reconstruction,
+ //void FindInitialReconstruction();
+
+ // State machine
+ //
+ // Question: Have explicit state? Or determine state from existing data?
+ // Conclusion: Determine state from existing data.
+ //
+ // Preliminary state thoughts
+ //
+ // No tracks or markers
+ // - Tracks empty.
+ //
+ // Initial tracks found
+ // - All images have at least 5 tracks
+ //
+ // Ran RANSAC on tracks to mark inliers / outliers.
+ // - All images have at least 8 "inlier" tracks
+ //
+ // Detector matching run to close loops and match across clips
+ // - At least 5 matching tracks between clips
+ //
+ // Initial reconstruction found (2 frames)?
+ // - There exists two cameras with intrinsics / extrinsics
+ //
+ // Preliminary reconstruction finished
+ // - Poses for all frames in all clips estimated.
+ //
+ // Final reconstruction finished
+ // - Final reconstruction bundle adjusted.
+
+ // For now, expose options directly. In the future this may change.
+ Options options;
+
+ private:
+ bool Log();
+ bool Progress();
+ bool Cancelled() { return false; }
+
+ Tracks tracks_; // May be normalized camera coordinates or raw pixels.
+ //Reconstruction reconstruction_;
+
+ // TODO(keir): Add the motion models here.
+ //vector<MotionModel> motion_models_;
+
+ // TODO(keir): Should num_clips and num_frames get moved to FrameAccessor?
+ // TODO(keir): What about masking for clips and frames to prevent various
+ // things like reconstruction or tracking from happening on certain frames?
+ FrameAccessor* frame_accessor_;
+ //int num_clips_;
+ //vector<int> num_frames_; // Indexed by clip.
+
+ // The intrinsics for each clip, assuming each clip has fixed intrinsics.
+ // TODO(keir): Decide what the semantics should be for varying focal length.
+ vector<int> clip_intrinsics_;
+
+ vector<ClipFrame> keyframes_;
+};
+
+} // namespace mv
+
+#endif // LIBMV_AUTOTRACK_AUTOTRACK_H_
diff --git a/extern/libmv/libmv/autotrack/callbacks.h b/extern/libmv/libmv/autotrack/callbacks.h
new file mode 100644
index 00000000000..e65841de3ce
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/callbacks.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef LIBMV_AUTOTRACK_LISTENER_H_
+#define LIBMV_AUTOTRACK_LISTENER_H_
+
+namespace mv {
+
+struct OperationListener {
+ // All hooks return true to continue or false to indicate the operation
+ // should abort. Hooks should be thread safe (reentrant).
+ virtual bool Log(const string& message) = 0;
+ virtual bool Progress(double fraction) = 0;
+ virtual bool Cancelled() = 0;
+};
+
+} // namespace mv
+
+#endif // LIBMV_AUTOTRACK_LISTENER_H_
diff --git a/extern/libmv/libmv/autotrack/frame_accessor.h b/extern/libmv/libmv/autotrack/frame_accessor.h
new file mode 100644
index 00000000000..8de5d865cd7
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/frame_accessor.h
@@ -0,0 +1,86 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef LIBMV_AUTOTRACK_FRAME_ACCESSOR_H_
+#define LIBMV_AUTOTRACK_FRAME_ACCESSOR_H_
+
+#include <stdint.h>
+
+#include "libmv/image/image.h"
+
+namespace mv {
+
+struct Region;
+
+using libmv::FloatImage;
+
+// This is the abstraction to different sources of images that will be part of
+// a reconstruction. These may come from disk or they may come from Blender. In
+// most cases it's expected that the implementation provides some caching
+// otherwise performance will be terrible. Sometimes the images need to get
+// filtered, and this interface provides for that as well (and permits
+// implementations to cache filtered image pieces).
+struct FrameAccessor {
+ struct Transform {
+ virtual ~Transform() { }
+ // The key should depend on the transform arguments. Must be non-zero.
+ virtual int64_t key() const = 0;
+
+ // Apply the expected transform. Output is sized correctly already.
+ // TODO(keir): What about blurs that need to access pixels outside the ROI?
+ virtual void run(const FloatImage& input, FloatImage* output) const = 0;
+ };
+
+ enum InputMode {
+ MONO,
+ RGBA
+ };
+
+ typedef void* Key;
+
+ // Get a possibly-filtered version of a frame of a video. Downscale will
+ // cause the input image to get downscaled by 2^downscale for pyramid access.
+ // Region is always in original-image coordinates, and describes the
+ // requested area. The transform describes an (optional) transform to apply
+ // to the image before it is returned.
+ //
+ // When done with an image, you must call ReleaseImage with the returned key.
+ virtual Key GetImage(int clip,
+ int frame,
+ InputMode input_mode,
+ int downscale, // Downscale by 2^downscale.
+ const Region* region, // Get full image if NULL.
+ const Transform* transform, // May be NULL.
+ FloatImage* destination) = 0;
+
+ // Releases an image from the frame accessor. Non-caching implementations may
+ // free the image immediately; others may hold onto the image.
+ virtual void ReleaseImage(Key) = 0;
+
+ virtual bool GetClipDimensions(int clip, int* width, int* height) = 0;
+ virtual int NumClips() = 0;
+ virtual int NumFrames(int clip) = 0;
+};
+
+} // namespace libmv
+
+#endif // LIBMV_AUTOTRACK_FRAME_ACCESSOR_H_
diff --git a/extern/libmv/libmv/autotrack/marker.h b/extern/libmv/libmv/autotrack/marker.h
new file mode 100644
index 00000000000..bb803313af8
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/marker.h
@@ -0,0 +1,144 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef LIBMV_AUTOTRACK_MARKER_H_
+#define LIBMV_AUTOTRACK_MARKER_H_
+
+#include <ostream>
+
+#include "libmv/autotrack/quad.h"
+#include "libmv/autotrack/region.h"
+#include "libmv/numeric/numeric.h"
+
+namespace mv {
+
+using libmv::Vec2f;
+
+// A marker is the 2D location of a tracked region (quad) in an image.
+// Note that some of this information could be normalized by having a
+// collection of inter-connected structs. Instead the "fat Marker" design below
+// trades memory for data structure simplicity.
+struct Marker {
+ int clip; // The clip this marker is from.
+ int frame; // The frame within the clip this marker is from.
+ int track; // The track this marker is from.
+
+ // The center of the marker in frame coordinates. This is typically, but not
+ // always, the same as the center of the patch.
+ Vec2f center;
+
+ // A frame-realtive quad defining the part of the image the marker covers.
+ // For reference markers, the pixels in the patch are the tracking pattern.
+ Quad2Df patch;
+
+ // Some markers are less certain than others; the weight determines the
+ // amount this marker contributes to the error. 1.0 indicates normal
+ // contribution; 0.0 indicates a zero-weight track (and will be omitted from
+ // bundle adjustment).
+ float weight;
+
+ enum Source {
+ MANUAL, // The user placed this marker manually.
+ DETECTED, // A keypoint detector found this point.
+ TRACKED, // The tracking algorithm placed this marker.
+ MATCHED, // A matching algorithm (e.g. SIFT or SURF or ORB) found this.
+ PREDICTED, // A motion model predicted this marker. This is needed for
+ // handling occlusions in some cases where an imaginary marker
+ // is placed to keep camera motion smooth.
+ };
+ Source source;
+
+ // Markers may be inliers or outliers if the tracking fails; this allows
+ // visualizing the markers in the image.
+ enum Status {
+ UNKNOWN,
+ INLIER,
+ OUTLIER
+ };
+ Status status;
+
+ // When doing correlation tracking, where to search in the current frame for
+ // the pattern from the reference frame, in absolute frame coordinates.
+ Region search_region;
+
+ // For tracked and matched markers, indicates what the reference was.
+ int reference_clip;
+ int reference_frame;
+
+ // Model related information for non-point tracks.
+ //
+ // Some tracks are on a larger object, such as a plane or a line or perhaps
+ // another primitive (a rectangular prisim). This captures the information
+ // needed to say that for example a collection of markers belongs to model #2
+ // (and model #2 is a plane).
+ enum ModelType {
+ POINT,
+ PLANE,
+ LINE,
+ CUBE
+ };
+ ModelType model_type;
+
+ // The model ID this track (e.g. the second model, which is a plane).
+ int model_id;
+
+ // TODO(keir): Add a "int model_argument" to capture that e.g. a marker is on
+ // the 3rd face of a cube.
+
+ enum Channel {
+ CHANNEL_R = (1 << 0),
+ CHANNEL_G = (1 << 1),
+ CHANNEL_B = (1 << 2),
+ };
+
+ // Channels from the original frame which this marker is unable to see.
+ int disabled_channels;
+
+ // Offset everything (center, patch, search) by the given delta.
+ template<typename T>
+ void Offset(const T& offset) {
+ center += offset.template cast<float>();
+ patch.coordinates.rowwise() += offset.template cast<int>();
+ search_region.Offset(offset);
+ }
+
+ // Shift the center to the given new position (and patch, search).
+ template<typename T>
+ void SetPosition(const T& new_center) {
+ Offset(new_center - center);
+ }
+};
+
+inline std::ostream& operator<<(std::ostream& out, const Marker& marker) {
+ out << "{"
+ << marker.clip << ", "
+ << marker.frame << ", "
+ << marker.track << ", ("
+ << marker.center.x() << ", "
+ << marker.center.y() << ")"
+ << "}";
+ return out;
+}
+
+} // namespace mv
+
+#endif // LIBMV_AUTOTRACK_MARKER_H_
diff --git a/extern/libmv/libmv/autotrack/model.h b/extern/libmv/libmv/autotrack/model.h
new file mode 100644
index 00000000000..1165281cdac
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/model.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef LIBMV_AUTOTRACK_MODEL_H_
+#define LIBMV_AUTOTRACK_MODEL_H_
+
+#include "libmv/numeric/numeric.h"
+#include "libmv/autotrack/quad.h"
+
+namespace mv {
+
+struct Model {
+ enum ModelType {
+ POINT,
+ PLANE,
+ LINE,
+ CUBE
+ };
+
+ // ???
+};
+
+} // namespace mv
+
+#endif // LIBMV_AUTOTRACK_MODEL_H_
diff --git a/extern/libmv/libmv/autotrack/predict_tracks.cc b/extern/libmv/libmv/autotrack/predict_tracks.cc
new file mode 100644
index 00000000000..adc986a0033
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/predict_tracks.cc
@@ -0,0 +1,316 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#include "libmv/autotrack/marker.h"
+#include "libmv/autotrack/predict_tracks.h"
+#include "libmv/autotrack/tracks.h"
+#include "libmv/base/vector.h"
+#include "libmv/logging/logging.h"
+#include "libmv/tracking/kalman_filter.h"
+
+namespace mv {
+
+namespace {
+
+using libmv::vector;
+using libmv::Vec2;
+
+// Implied time delta between steps. Set empirically by tweaking and seeing
+// what numbers did best at prediction.
+const double dt = 3.8;
+
+// State transition matrix.
+
+// The states for predicting a track are as follows:
+//
+// 0 - X position
+// 1 - X velocity
+// 2 - X acceleration
+// 3 - Y position
+// 4 - Y velocity
+// 5 - Y acceleration
+//
+// Note that in the velocity-only state transition matrix, the acceleration
+// component is ignored; so technically the system could be modelled with only
+// 4 states instead of 6. For ease of implementation, this keeps order 6.
+
+// Choose one or the other model from below (velocity or acceleration).
+
+// For a typical system having constant velocity. This gives smooth-appearing
+// predictions, but they are not always as accurate.
+const double velocity_state_transition_data[] = {
+ 1, dt, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 1, dt, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 1
+};
+
+// This 3rd-order system also models acceleration. This makes for "jerky"
+// predictions, but that tend to be more accurate.
+const double acceleration_state_transition_data[] = {
+ 1, dt, dt*dt/2, 0, 0, 0,
+ 0, 1, dt, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 1, dt, dt*dt/2,
+ 0, 0, 0, 0, 1, dt,
+ 0, 0, 0, 0, 0, 1
+};
+
+// This system (attempts) to add an angular velocity component. However, it's
+// total junk.
+const double angular_state_transition_data[] = {
+ 1, dt, -dt, 0, 0, 0, // Position x
+ 0, 1, 0, 0, 0, 0, // Velocity x
+ 0, 0, 1, 0, 0, 0, // Angular momentum
+ 0, 0, dt, 1, dt, 0, // Position y
+ 0, 0, 0, 0, 1, 0, // Velocity y
+ 0, 0, 0, 0, 0, 1 // Ignored
+};
+
+const double* state_transition_data = velocity_state_transition_data;
+
+// Observation matrix.
+const double observation_data[] = {
+ 1., 0., 0., 0., 0., 0.,
+ 0., 0., 0., 1., 0., 0.
+};
+
+// Process covariance.
+const double process_covariance_data[] = {
+ 35, 0, 0, 0, 0, 0,
+ 0, 5, 0, 0, 0, 0,
+ 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 35, 0, 0,
+ 0, 0, 0, 0, 5, 0,
+ 0, 0, 0, 0, 0, 5
+};
+
+// Process covariance.
+const double measurement_covariance_data[] = {
+ 0.01, 0.00,
+ 0.00, 0.01,
+};
+
+// Initial covariance.
+const double initial_covariance_data[] = {
+ 10, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 1
+};
+
+typedef mv::KalmanFilter<double, 6, 2> TrackerKalman;
+
+TrackerKalman filter(state_transition_data,
+ observation_data,
+ process_covariance_data,
+ measurement_covariance_data);
+
+bool OrderByFrameLessThan(const Marker* a, const Marker* b) {
+ if (a->frame == b->frame) {
+ if (a->clip == b->clip) {
+ return a->track < b->track;
+ }
+ return a->clip < b->clip;
+ }
+ return a->frame < b-> frame;
+}
+
+// Predicted must be after the previous markers (in the frame numbering sense).
+void RunPrediction(const vector<Marker*> previous_markers,
+ Marker* predicted_marker) {
+ TrackerKalman::State state;
+ state.mean << previous_markers[0]->center.x(), 0, 0,
+ previous_markers[0]->center.y(), 0, 0;
+ state.covariance = Eigen::Matrix<double, 6, 6, Eigen::RowMajor>(
+ initial_covariance_data);
+
+ int current_frame = previous_markers[0]->frame;
+ int target_frame = predicted_marker->frame;
+
+ bool predict_forward = current_frame < target_frame;
+ int frame_delta = predict_forward ? 1 : -1;
+
+ for (int i = 1; i < previous_markers.size(); ++i) {
+ // Step forward predicting the state until it is on the current marker.
+ int predictions = 0;
+ for (;
+ current_frame != previous_markers[i]->frame;
+ current_frame += frame_delta) {
+ filter.Step(&state);
+ predictions++;
+ LG << "Predicted point (frame " << current_frame << "): "
+ << state.mean(0) << ", " << state.mean(3);
+ }
+ // Log the error -- not actually used, but interesting.
+ Vec2 error = previous_markers[i]->center.cast<double>() -
+ Vec2(state.mean(0), state.mean(3));
+ LG << "Prediction error for " << predictions << " steps: ("
+ << error.x() << ", " << error.y() << "); norm: " << error.norm();
+ // Now that the state is predicted in the current frame, update the state
+ // based on the measurement from the current frame.
+ filter.Update(previous_markers[i]->center.cast<double>(),
+ Eigen::Matrix<double, 2, 2, Eigen::RowMajor>(
+ measurement_covariance_data),
+ &state);
+ LG << "Updated point: " << state.mean(0) << ", " << state.mean(3);
+ }
+ // At this point as all the prediction that's possible is done. Finally
+ // predict until the target frame.
+ for (; current_frame != target_frame; current_frame += frame_delta) {
+ filter.Step(&state);
+ LG << "Final predicted point (frame " << current_frame << "): "
+ << state.mean(0) << ", " << state.mean(3);
+ }
+
+ // The x and y positions are at 0 and 3; ignore acceleration and velocity.
+ predicted_marker->center.x() = state.mean(0);
+ predicted_marker->center.y() = state.mean(3);
+
+ // Take the patch from the last marker then shift it to match the prediction.
+ const Marker& last_marker = *previous_markers[previous_markers.size() - 1];
+ predicted_marker->patch = last_marker.patch;
+ Vec2f delta = predicted_marker->center - last_marker.center;
+ for (int i = 0; i < 4; ++i) {
+ predicted_marker->patch.coordinates.row(i) += delta;
+ }
+
+ // Alter the search area as well so it always corresponds to the center.
+ predicted_marker->search_region = last_marker.search_region;
+ predicted_marker->search_region.Offset(delta);
+}
+
+} // namespace
+
+bool PredictMarkerPosition(const Tracks& tracks, Marker* marker) {
+ // Get all markers for this clip and track.
+ vector<Marker> markers;
+ tracks.GetMarkersForTrackInClip(marker->clip, marker->track, &markers);
+
+ if (markers.empty()) {
+ LG << "No markers to predict from for " << *marker;
+ return false;
+ }
+
+ // Order the markers by frame within the clip.
+ vector<Marker*> boxed_markers(markers.size());
+ for (int i = 0; i < markers.size(); ++i) {
+ boxed_markers[i] = &markers[i];
+ }
+ std::sort(boxed_markers.begin(), boxed_markers.end(), OrderByFrameLessThan);
+
+ // Find the insertion point for this marker among the returned ones.
+ int insert_at = -1; // If we find the exact frame
+ int insert_before = -1; // Otherwise...
+ for (int i = 0; i < boxed_markers.size(); ++i) {
+ if (boxed_markers[i]->frame == marker->frame) {
+ insert_at = i;
+ break;
+ }
+ if (boxed_markers[i]->frame > marker->frame) {
+ insert_before = i;
+ break;
+ }
+ }
+
+ // Forward starts at the marker or insertion point, and goes forward.
+ int forward_scan_begin, forward_scan_end;
+
+ // Backward scan starts at the marker or insertion point, and goes backward.
+ int backward_scan_begin, backward_scan_end;
+
+ // Determine the scanning ranges.
+ if (insert_at == -1 && insert_before == -1) {
+ // Didn't find an insertion point except the end.
+ forward_scan_begin = forward_scan_end = 0;
+ backward_scan_begin = markers.size() - 1;
+ backward_scan_end = 0;
+ } else if (insert_at != -1) {
+ // Found existing marker; scan before and after it.
+ forward_scan_begin = insert_at + 1;
+ forward_scan_end = markers.size() - 1;;
+ backward_scan_begin = insert_at - 1;
+ backward_scan_end = 0;
+ } else {
+ // Didn't find existing marker but found an insertion point.
+ forward_scan_begin = insert_before;
+ forward_scan_end = markers.size() - 1;;
+ backward_scan_begin = insert_before - 1;
+ backward_scan_end = 0;
+ }
+
+ const int num_consecutive_needed = 2;
+
+ if (forward_scan_begin <= forward_scan_end &&
+ forward_scan_end - forward_scan_begin > num_consecutive_needed) {
+ // TODO(keir): Finish this.
+ }
+
+ bool predict_forward = false;
+ if (backward_scan_end <= backward_scan_begin) {
+ // TODO(keir): Add smarter handling and detecting of consecutive frames!
+ predict_forward = true;
+ }
+
+ const int max_frames_to_predict_from = 20;
+ if (predict_forward) {
+ if (backward_scan_begin - backward_scan_end < num_consecutive_needed) {
+ // Not enough information to do a prediction.
+ LG << "Predicting forward impossible, not enough information";
+ return false;
+ }
+ LG << "Predicting forward";
+ int predict_begin =
+ std::max(backward_scan_begin - max_frames_to_predict_from, 0);
+ int predict_end = backward_scan_begin;
+ vector<Marker*> previous_markers;
+ for (int i = predict_begin; i <= predict_end; ++i) {
+ previous_markers.push_back(boxed_markers[i]);
+ }
+ RunPrediction(previous_markers, marker);
+ return true;
+ } else {
+ if (forward_scan_end - forward_scan_begin < num_consecutive_needed) {
+ // Not enough information to do a prediction.
+ LG << "Predicting backward impossible, not enough information";
+ return false;
+ }
+ LG << "Predicting backward";
+ int predict_begin =
+ std::min(forward_scan_begin + max_frames_to_predict_from,
+ forward_scan_end);
+ int predict_end = forward_scan_begin;
+ vector<Marker*> previous_markers;
+ for (int i = predict_begin; i >= predict_end; --i) {
+ previous_markers.push_back(boxed_markers[i]);
+ }
+ RunPrediction(previous_markers, marker);
+ return false;
+ }
+
+}
+
+} // namespace mv
diff --git a/extern/libmv/libmv/autotrack/predict_tracks.h b/extern/libmv/libmv/autotrack/predict_tracks.h
new file mode 100644
index 00000000000..0a176d08378
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/predict_tracks.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef LIBMV_AUTOTRACK_PREDICT_TRACKS_H_
+#define LIBMV_AUTOTRACK_PREDICT_TRACKS_H_
+
+namespace mv {
+
+class Tracks;
+struct Marker;
+
+// Predict the position of the given marker, and update it accordingly. The
+// existing position will be overwritten.
+bool PredictMarkerPosition(const Tracks& tracks, Marker* marker);
+
+} // namespace mv
+
+#endif // LIBMV_AUTOTRACK_PREDICT_TRACKS_H_
diff --git a/extern/libmv/libmv/autotrack/predict_tracks_test.cc b/extern/libmv/libmv/autotrack/predict_tracks_test.cc
new file mode 100644
index 00000000000..fc90e260d94
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/predict_tracks_test.cc
@@ -0,0 +1,201 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#include "libmv/autotrack/predict_tracks.h"
+
+#include "libmv/autotrack/marker.h"
+#include "libmv/autotrack/tracks.h"
+#include "libmv/logging/logging.h"
+#include "testing/testing.h"
+
+namespace mv {
+
+void AddMarker(int frame, float x, float y, Tracks* tracks) {
+ Marker marker;
+ marker.clip = marker.track = 0;
+ marker.frame = frame;
+ marker.center.x() = x;
+ marker.center.y() = y;
+ marker.patch.coordinates << x - 1, y - 1,
+ x + 1, y - 1,
+ x + 1, y + 1,
+ x - 1, y + 1;
+ tracks->AddMarker(marker);
+}
+
+TEST(PredictMarkerPosition, EasyLinearMotion) {
+ Tracks tracks;
+ AddMarker(0, 1.0, 0.0, &tracks);
+ AddMarker(1, 2.0, 5.0, &tracks);
+ AddMarker(2, 3.0, 10.0, &tracks);
+ AddMarker(3, 4.0, 15.0, &tracks);
+ AddMarker(4, 5.0, 20.0, &tracks);
+ AddMarker(5, 6.0, 25.0, &tracks);
+ AddMarker(6, 7.0, 30.0, &tracks);
+ AddMarker(7, 8.0, 35.0, &tracks);
+
+ Marker predicted;
+ predicted.clip = 0;
+ predicted.track = 0;
+ predicted.frame = 8;
+
+ PredictMarkerPosition(tracks, &predicted);
+ double error = (libmv::Vec2f(9.0, 40.0) - predicted.center).norm();
+ LG << "Got error: " << error;
+ EXPECT_LT(error, 0.1);
+
+ // Check the patch coordinates as well.
+ double x = 9, y = 40.0;
+ Quad2Df expected_patch;
+ expected_patch.coordinates << x - 1, y - 1,
+ x + 1, y - 1,
+ x + 1, y + 1,
+ x - 1, y + 1;
+
+ error = (expected_patch.coordinates - predicted.patch.coordinates).norm();
+ LG << "Patch error: " << error;
+ EXPECT_LT(error, 0.1);
+}
+
+TEST(PredictMarkerPosition, EasyBackwardLinearMotion) {
+ Tracks tracks;
+ AddMarker(8, 1.0, 0.0, &tracks);
+ AddMarker(7, 2.0, 5.0, &tracks);
+ AddMarker(6, 3.0, 10.0, &tracks);
+ AddMarker(5, 4.0, 15.0, &tracks);
+ AddMarker(4, 5.0, 20.0, &tracks);
+ AddMarker(3, 6.0, 25.0, &tracks);
+ AddMarker(2, 7.0, 30.0, &tracks);
+ AddMarker(1, 8.0, 35.0, &tracks);
+
+ Marker predicted;
+ predicted.clip = 0;
+ predicted.track = 0;
+ predicted.frame = 0;
+
+ PredictMarkerPosition(tracks, &predicted);
+ LG << predicted;
+ double error = (libmv::Vec2f(9.0, 40.0) - predicted.center).norm();
+ LG << "Got error: " << error;
+ EXPECT_LT(error, 0.1);
+
+ // Check the patch coordinates as well.
+ double x = 9.0, y = 40.0;
+ Quad2Df expected_patch;
+ expected_patch.coordinates << x - 1, y - 1,
+ x + 1, y - 1,
+ x + 1, y + 1,
+ x - 1, y + 1;
+
+ error = (expected_patch.coordinates - predicted.patch.coordinates).norm();
+ LG << "Patch error: " << error;
+ EXPECT_LT(error, 0.1);
+}
+
+TEST(PredictMarkerPosition, TwoFrameGap) {
+ Tracks tracks;
+ AddMarker(0, 1.0, 0.0, &tracks);
+ AddMarker(1, 2.0, 5.0, &tracks);
+ AddMarker(2, 3.0, 10.0, &tracks);
+ AddMarker(3, 4.0, 15.0, &tracks);
+ AddMarker(4, 5.0, 20.0, &tracks);
+ AddMarker(5, 6.0, 25.0, &tracks);
+ AddMarker(6, 7.0, 30.0, &tracks);
+ // Missing frame 7!
+
+ Marker predicted;
+ predicted.clip = 0;
+ predicted.track = 0;
+ predicted.frame = 8;
+
+ PredictMarkerPosition(tracks, &predicted);
+ double error = (libmv::Vec2f(9.0, 40.0) - predicted.center).norm();
+ LG << "Got error: " << error;
+ EXPECT_LT(error, 0.1);
+}
+
+TEST(PredictMarkerPosition, FourFrameGap) {
+ Tracks tracks;
+ AddMarker(0, 1.0, 0.0, &tracks);
+ AddMarker(1, 2.0, 5.0, &tracks);
+ AddMarker(2, 3.0, 10.0, &tracks);
+ AddMarker(3, 4.0, 15.0, &tracks);
+ // Missing frames 4, 5, 6, 7.
+
+ Marker predicted;
+ predicted.clip = 0;
+ predicted.track = 0;
+ predicted.frame = 8;
+
+ PredictMarkerPosition(tracks, &predicted);
+ double error = (libmv::Vec2f(9.0, 40.0) - predicted.center).norm();
+ LG << "Got error: " << error;
+ EXPECT_LT(error, 2.0); // Generous error due to larger prediction window.
+}
+
+TEST(PredictMarkerPosition, MultipleGaps) {
+ Tracks tracks;
+ AddMarker(0, 1.0, 0.0, &tracks);
+ AddMarker(1, 2.0, 5.0, &tracks);
+ AddMarker(2, 3.0, 10.0, &tracks);
+ // AddMarker(3, 4.0, 15.0, &tracks); // Note the 3-frame gap.
+ // AddMarker(4, 5.0, 20.0, &tracks);
+ // AddMarker(5, 6.0, 25.0, &tracks);
+ AddMarker(6, 7.0, 30.0, &tracks); // Intermediate measurement.
+ // AddMarker(7, 8.0, 35.0, &tracks);
+
+ Marker predicted;
+ predicted.clip = 0;
+ predicted.track = 0;
+ predicted.frame = 8;
+
+ PredictMarkerPosition(tracks, &predicted);
+ double error = (libmv::Vec2f(9.0, 40.0) - predicted.center).norm();
+ LG << "Got error: " << error;
+ EXPECT_LT(error, 1.0); // Generous error due to larger prediction window.
+}
+
+TEST(PredictMarkerPosition, MarkersInRandomOrder) {
+ Tracks tracks;
+
+ // This is the same as the easy, except that the tracks are randomly ordered.
+ AddMarker(0, 1.0, 0.0, &tracks);
+ AddMarker(2, 3.0, 10.0, &tracks);
+ AddMarker(7, 8.0, 35.0, &tracks);
+ AddMarker(5, 6.0, 25.0, &tracks);
+ AddMarker(4, 5.0, 20.0, &tracks);
+ AddMarker(3, 4.0, 15.0, &tracks);
+ AddMarker(6, 7.0, 30.0, &tracks);
+ AddMarker(1, 2.0, 5.0, &tracks);
+
+ Marker predicted;
+ predicted.clip = 0;
+ predicted.track = 0;
+ predicted.frame = 8;
+
+ PredictMarkerPosition(tracks, &predicted);
+ double error = (libmv::Vec2f(9.0, 40.0) - predicted.center).norm();
+ LG << "Got error: " << error;
+ EXPECT_LT(error, 0.1);
+}
+
+} // namespace mv
diff --git a/extern/libmv/libmv/autotrack/quad.h b/extern/libmv/libmv/autotrack/quad.h
new file mode 100644
index 00000000000..0c70f9882da
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/quad.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef LIBMV_AUTOTRACK_QUAD_H_
+#define LIBMV_AUTOTRACK_QUAD_H_
+
+#include <Eigen/Core>
+
+namespace mv {
+
+template<typename T, int D>
+struct Quad {
+ // A quad is 4 points; generally in 2D or 3D.
+ //
+ // +----------> x
+ // |\.
+ // | \.
+ // | z (z goes into screen)
+ // |
+ // | r0----->r1
+ // | ^ |
+ // | | . |
+ // | | V
+ // | r3<-----r2
+ // | \.
+ // | \.
+ // v normal goes away (right handed).
+ // y
+ //
+ // Each row is one of the corners coordinates; either (x, y) or (x, y, z).
+ Eigen::Matrix<T, 4, D> coordinates;
+};
+
+typedef Quad<float, 2> Quad2Df;
+
+} // namespace mv
+
+#endif // LIBMV_AUTOTRACK_QUAD_H_
diff --git a/extern/libmv/libmv/autotrack/reconstruction.h b/extern/libmv/libmv/autotrack/reconstruction.h
new file mode 100644
index 00000000000..e1d4e882cbd
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/reconstruction.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef LIBMV_AUTOTRACK_RECONSTRUCTION_H_
+#define LIBMV_AUTOTRACK_RECONSTRUCTION_H_
+
+#include "libmv/base/vector.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/simple_pipeline/camera_intrinsics.h"
+
+namespace mv {
+
+using libmv::CameraIntrinsics;
+using libmv::vector;
+
+class Model;
+
+class CameraPose {
+ int clip;
+ int frame;
+ int intrinsics;
+ Mat3 R;
+ Vec3 t;
+};
+
+class Point {
+ int track;
+
+ // The coordinates of the point. Note that not all coordinates are always
+ // used; for example points on a plane only use the first two coordinates.
+ Vec3 X;
+};
+
+// A reconstruction for a set of tracks. The indexing for clip, frame, and
+// track should match that of a Tracs object, stored elsewhere.
+class Reconstruction {
+ public:
+ // All methods copy their input reference or take ownership of the pointer.
+ void AddCameraPose(const CameraPose& pose);
+ int AddCameraIntrinsics(CameraIntrinsics* intrinsics);
+ int AddPoint(const Point& point);
+ int AddModel(Model* model);
+
+ // Returns the corresponding pose or point or NULL if missing.
+ CameraPose* CameraPoseForFrame(int clip, int frame);
+ const CameraPose* CameraPoseForFrame(int clip, int frame) const;
+ Point* PointForTrack(int track);
+ const Point* PointForTrack(int track) const;
+
+ const vector<vector<CameraPose> >& camera_poses() const {
+ return camera_poses_;
+ }
+
+ private:
+ // Indexed by CameraPose::intrinsics. Owns the intrinsics objects.
+ vector<CameraIntrinsics*> camera_intrinsics_;
+
+ // Indexed by Marker::clip then by Marker::frame.
+ vector<vector<CameraPose> > camera_poses_;
+
+ // Indexed by Marker::track.
+ vector<Point> points_;
+
+ // Indexed by Marker::model_id. Owns model objects.
+ vector<Model*> models_;
+};
+
+} // namespace mv
+
+#endif // LIBMV_AUTOTRACK_RECONSTRUCTION_H_
diff --git a/extern/libmv/libmv/autotrack/region.h b/extern/libmv/libmv/autotrack/region.h
new file mode 100644
index 00000000000..b35d99eb60d
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/region.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef LIBMV_AUTOTRACK_REGION_H_
+#define LIBMV_AUTOTRACK_REGION_H_
+
+#include "libmv/numeric/numeric.h"
+
+namespace mv {
+
+using libmv::Vec2f;
+
+// A region is a bounding box within an image.
+//
+// +----------> x
+// |
+// | (min.x, min.y) (max.x, min.y)
+// | +-------------------------+
+// | | |
+// | | |
+// | | |
+// | +-------------------------+
+// v (min.x, max.y) (max.x, max.y)
+// y
+//
+struct Region {
+ Vec2f min;
+ Vec2f max;
+
+ template<typename T>
+ void Offset(const T& offset) {
+ min += offset.template cast<float>();
+ max += offset.template cast<float>();
+ }
+
+ Region Rounded() const {
+ Region result;
+ result.min(0) = ceil(this->min(0));
+ result.min(1) = ceil(this->min(1));
+ result.max(0) = ceil(this->max(0));
+ result.max(1) = ceil(this->max(1));
+ return result;
+ }
+};
+
+} // namespace mv
+
+#endif // LIBMV_AUTOTRACK_REGION_H_
diff --git a/extern/libmv/libmv/autotrack/tracks.cc b/extern/libmv/libmv/autotrack/tracks.cc
new file mode 100644
index 00000000000..174f264f3f2
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/tracks.cc
@@ -0,0 +1,193 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#include "libmv/autotrack/tracks.h"
+
+#include <algorithm>
+#include <vector>
+#include <iterator>
+
+#include "libmv/numeric/numeric.h"
+
+namespace mv {
+
+Tracks::Tracks(const Tracks& other) {
+ markers_ = other.markers_;
+}
+
+Tracks::Tracks(const vector<Marker>& markers) : markers_(markers) {}
+
+bool Tracks::GetMarker(int clip, int frame, int track, Marker* marker) const {
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (markers_[i].clip == clip &&
+ markers_[i].frame == frame &&
+ markers_[i].track == track) {
+ *marker = markers_[i];
+ return true;
+ }
+ }
+ return false;
+}
+
+void Tracks::GetMarkersForTrack(int track, vector<Marker>* markers) const {
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (track == markers_[i].track) {
+ markers->push_back(markers_[i]);
+ }
+ }
+}
+
+void Tracks::GetMarkersForTrackInClip(int clip,
+ int track,
+ vector<Marker>* markers) const {
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (clip == markers_[i].clip &&
+ track == markers_[i].track) {
+ markers->push_back(markers_[i]);
+ }
+ }
+}
+
+void Tracks::GetMarkersInFrame(int clip,
+ int frame,
+ vector<Marker>* markers) const {
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (markers_[i].clip == clip &&
+ markers_[i].frame == frame) {
+ markers->push_back(markers_[i]);
+ }
+ }
+}
+
+void Tracks::GetMarkersForTracksInBothImages(int clip1, int frame1,
+ int clip2, int frame2,
+ vector<Marker>* markers) const {
+ std::vector<int> image1_tracks;
+ std::vector<int> image2_tracks;
+
+ // Collect the tracks in each of the two images.
+ for (int i = 0; i < markers_.size(); ++i) {
+ int clip = markers_[i].clip;
+ int frame = markers_[i].frame;
+ if (clip == clip1 && frame == frame1) {
+ image1_tracks.push_back(markers_[i].track);
+ } else if (clip == clip2 && frame == frame2) {
+ image2_tracks.push_back(markers_[i].track);
+ }
+ }
+
+ // Intersect the two sets to find the tracks of interest.
+ std::sort(image1_tracks.begin(), image1_tracks.end());
+ std::sort(image2_tracks.begin(), image2_tracks.end());
+ std::vector<int> intersection;
+ std::set_intersection(image1_tracks.begin(), image1_tracks.end(),
+ image2_tracks.begin(), image2_tracks.end(),
+ std::back_inserter(intersection));
+
+ // Scan through and get the relevant tracks from the two images.
+ for (int i = 0; i < markers_.size(); ++i) {
+ // Save markers that are in either frame and are in our candidate set.
+ if (((markers_[i].clip == clip1 &&
+ markers_[i].frame == frame1) ||
+ (markers_[i].clip == clip2 &&
+ markers_[i].frame == frame2)) &&
+ std::binary_search(intersection.begin(),
+ intersection.end(),
+ markers_[i].track)) {
+ markers->push_back(markers_[i]);
+ }
+ }
+}
+
+void Tracks::AddMarker(const Marker& marker) {
+ // TODO(keir): This is quadratic for repeated insertions. Fix this by adding
+ // a smarter data structure like a set<>.
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (markers_[i].clip == marker.clip &&
+ markers_[i].frame == marker.frame &&
+ markers_[i].track == marker.track) {
+ markers_[i] = marker;
+ return;
+ }
+ }
+ markers_.push_back(marker);
+}
+
+void Tracks::SetMarkers(vector<Marker>* markers) {
+ std::swap(markers_, *markers);
+}
+
+bool Tracks::RemoveMarker(int clip, int frame, int track) {
+ int size = markers_.size();
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (markers_[i].clip == clip &&
+ markers_[i].frame == frame &&
+ markers_[i].track == track) {
+ markers_[i] = markers_[size - 1];
+ markers_.resize(size - 1);
+ return true;
+ }
+ }
+ return false;
+}
+
+void Tracks::RemoveMarkersForTrack(int track) {
+ int size = 0;
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (markers_[i].track != track) {
+ markers_[size++] = markers_[i];
+ }
+ }
+ markers_.resize(size);
+}
+
+int Tracks::MaxClip() const {
+ int max_clip = 0;
+ for (int i = 0; i < markers_.size(); ++i) {
+ max_clip = std::max(markers_[i].clip, max_clip);
+ }
+ return max_clip;
+}
+
+int Tracks::MaxFrame(int clip) const {
+ int max_frame = 0;
+ for (int i = 0; i < markers_.size(); ++i) {
+ if (markers_[i].clip == clip) {
+ max_frame = std::max(markers_[i].frame, max_frame);
+ }
+ }
+ return max_frame;
+}
+
+int Tracks::MaxTrack() const {
+ int max_track = 0;
+ for (int i = 0; i < markers_.size(); ++i) {
+ max_track = std::max(markers_[i].track, max_track);
+ }
+ return max_track;
+}
+
+int Tracks::NumMarkers() const {
+ return markers_.size();
+}
+
+} // namespace mv
diff --git a/extern/libmv/libmv/autotrack/tracks.h b/extern/libmv/libmv/autotrack/tracks.h
new file mode 100644
index 00000000000..0b7de91d211
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/tracks.h
@@ -0,0 +1,82 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#ifndef LIBMV_AUTOTRACK_TRACKS_H_
+#define LIBMV_AUTOTRACK_TRACKS_H_
+
+#include "libmv/base/vector.h"
+#include "libmv/autotrack/marker.h"
+
+namespace mv {
+
+using libmv::vector;
+
+// The Tracks container stores correspondences between frames.
+class Tracks {
+ public:
+ Tracks() { }
+ Tracks(const Tracks &other);
+
+ // Create a tracks object with markers already initialized. Copies markers.
+ explicit Tracks(const vector<Marker>& markers);
+
+ // All getters append to the output argument vector.
+ bool GetMarker(int clip, int frame, int track, Marker* marker) const;
+ void GetMarkersForTrack(int track, vector<Marker>* markers) const;
+ void GetMarkersForTrackInClip(int clip,
+ int track,
+ vector<Marker>* markers) const;
+ void GetMarkersInFrame(int clip, int frame, vector<Marker>* markers) const;
+
+ // Get the markers in frame1 and frame2 which have a common track.
+ //
+ // This is not the same as the union of the markers in frame1 and
+ // frame2; each marker is for a track that appears in both images.
+ void GetMarkersForTracksInBothImages(int clip1, int frame1,
+ int clip2, int frame2,
+ vector<Marker>* markers) const;
+
+ void AddMarker(const Marker& marker);
+
+ // Moves the contents of *markers over top of the existing markers. This
+ // destroys *markers in the process (but avoids copies).
+ void SetMarkers(vector<Marker>* markers);
+ bool RemoveMarker(int clip, int frame, int track);
+ void RemoveMarkersForTrack(int track);
+
+ int MaxClip() const;
+ int MaxFrame(int clip) const;
+ int MaxTrack() const;
+ int NumMarkers() const;
+
+ const vector<Marker>& markers() const { return markers_; }
+
+ private:
+ vector<Marker> markers_;
+
+ // TODO(keir): Consider adding access-map data structures to avoid all the
+ // linear lookup penalties for the accessors.
+};
+
+} // namespace mv
+
+#endif // LIBMV_AUTOTRACK_TRACKS_H_
diff --git a/extern/libmv/libmv/autotrack/tracks_test.cc b/extern/libmv/libmv/autotrack/tracks_test.cc
new file mode 100644
index 00000000000..028b4a10913
--- /dev/null
+++ b/extern/libmv/libmv/autotrack/tracks_test.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#include "libmv/autotrack/tracks.h"
+
+#include "testing/testing.h"
+#include "libmv/logging/logging.h"
+
+namespace mv {
+
+TEST(Tracks, MaxFrame) {
+ Marker marker;
+ Tracks tracks;
+
+ // Add some markers to clip 0.
+ marker.clip = 0;
+ marker.frame = 1;
+ tracks.AddMarker(marker);
+
+ // Add some markers to clip 1.
+ marker.clip = 1;
+ marker.frame = 1;
+ tracks.AddMarker(marker);
+
+ marker.clip = 1;
+ marker.frame = 12;
+ tracks.AddMarker(marker);
+
+ EXPECT_EQ(1, tracks.MaxFrame(0));
+ EXPECT_EQ(12, tracks.MaxFrame(1));
+}
+
+} // namespace mv
diff --git a/extern/libmv/libmv/base/vector.h b/extern/libmv/libmv/base/vector.h
index 067db4ba7f7..1931fb0b1f9 100644
--- a/extern/libmv/libmv/base/vector.h
+++ b/extern/libmv/libmv/base/vector.h
@@ -101,8 +101,6 @@ class vector {
size_ = size;
}
-
-
void push_back(const T &value) {
if (size_ == capacity_) {
reserve(size_ ? 2 * size_ : 1);
@@ -130,6 +128,10 @@ class vector {
}
}
+ bool empty() {
+ return size_ == 0;
+ }
+
private:
void construct(int start, int end) {
for (int i = start; i < end; ++i) {
diff --git a/extern/libmv/libmv/image/array_nd.h b/extern/libmv/libmv/image/array_nd.h
index c5099f24d7b..b56a765223b 100644
--- a/extern/libmv/libmv/image/array_nd.h
+++ b/extern/libmv/libmv/image/array_nd.h
@@ -41,33 +41,35 @@ class ArrayND : public BaseArray {
typedef Tuple<int, N> Index;
/// Create an empty array.
- ArrayND() : data_(NULL), own_data(true) { Resize(Index(0)); }
+ ArrayND() : data_(NULL), own_data_(true) { Resize(Index(0)); }
/// Create an array with the specified shape.
- ArrayND(const Index &shape) : data_(NULL), own_data(true) { Resize(shape); }
+ ArrayND(const Index &shape) : data_(NULL), own_data_(true) { Resize(shape); }
/// Create an array with the specified shape.
- ArrayND(int *shape) : data_(NULL), own_data(true) { Resize(shape); }
+ ArrayND(int *shape) : data_(NULL), own_data_(true) { Resize(shape); }
/// Copy constructor.
- ArrayND(const ArrayND<T, N> &b) : data_(NULL), own_data(true) {
+ ArrayND(const ArrayND<T, N> &b) : data_(NULL), own_data_(true) {
ResizeLike(b);
std::memcpy(Data(), b.Data(), sizeof(T) * Size());
}
- ArrayND(int s0) : data_(NULL), own_data(true) { Resize(s0); }
- ArrayND(int s0, int s1) : data_(NULL), own_data(true) { Resize(s0, s1); }
- ArrayND(int s0, int s1, int s2) : data_(NULL), own_data(true) {
+ ArrayND(int s0) : data_(NULL), own_data_(true) { Resize(s0); }
+ ArrayND(int s0, int s1) : data_(NULL), own_data_(true) { Resize(s0, s1); }
+ ArrayND(int s0, int s1, int s2) : data_(NULL), own_data_(true) {
Resize(s0, s1, s2);
}
- ArrayND(T* data, int s0, int s1, int s2) : data_(data), own_data(false) {
+ ArrayND(T* data, int s0, int s1, int s2) : data_(data), own_data_(false) {
Resize(s0, s1, s2);
}
/// Destructor deletes pixel data.
~ArrayND() {
- delete [] data_;
+ if (own_data_) {
+ delete [] data_;
+ }
}
/// Assignation copies pixel data.
@@ -97,7 +99,7 @@ class ArrayND : public BaseArray {
for (int i = N - 1; i > 0; --i) {
strides_(i - 1) = strides_(i) * shape_(i);
}
- if (own_data) {
+ if (own_data_) {
delete [] data_;
data_ = NULL;
if (Size() > 0) {
@@ -336,7 +338,7 @@ class ArrayND : public BaseArray {
T *data_;
/// Flag if this Array either own or reference the data
- bool own_data;
+ bool own_data_;
};
/// 3D array (row, column, channel).
diff --git a/extern/libmv/libmv/multiview/homography.cc b/extern/libmv/libmv/multiview/homography.cc
index ce533a3ead2..a7679c33bbf 100644
--- a/extern/libmv/libmv/multiview/homography.cc
+++ b/extern/libmv/libmv/multiview/homography.cc
@@ -209,8 +209,8 @@ class HomographySymmetricGeometricCostFunctor {
return true;
}
- const Vec2 x_;
- const Vec2 y_;
+ const Vec2 &x_;
+ const Vec2 &y_;
};
// Termination checking callback used for homography estimation.
diff --git a/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc b/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
index 7b90c28bbca..241b5600505 100644
--- a/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
+++ b/extern/libmv/libmv/simple_pipeline/keyframe_selection.cc
@@ -69,54 +69,50 @@ double GRIC(const Vec &e, int d, int k, int r) {
// http://www.robots.ox.ac.uk/~vgg/publications/papers/torr99.ps.gz
double lambda3 = 2.0;
- // measurement error of tracker
+ // Variance of tracker position. Physically, this is typically about 0.1px,
+ // and when squared becomes 0.01 px^2.
double sigma2 = 0.01;
- // Actual GRIC computation
- double gric_result = 0.0;
-
+ // Finally, calculate the GRIC score.
+ double gric = 0.0;
for (int i = 0; i < n; i++) {
- double rho = std::min(e(i) * e(i) / sigma2, lambda3 * (r - d));
- gric_result += rho;
+ gric += std::min(e(i) * e(i) / sigma2, lambda3 * (r - d));
}
-
- gric_result += lambda1 * d * n;
- gric_result += lambda2 * k;
-
- return gric_result;
+ gric += lambda1 * d * n;
+ gric += lambda2 * k;
+ return gric;
}
-// Compute a generalized inverse using eigen value decomposition.
-// It'll actually also zero 7 last eigen values to deal with
-// gauges, since this function is used to compute variance of
+// Compute a generalized inverse using eigen value decomposition, clamping the
+// smallest eigenvalues if requested. This is needed to compute the variance of
// reconstructed 3D points.
//
-// TODO(sergey): Could be generalized by making it so number
-// of values to be zeroed is passed by an argument
-// and moved to numeric module.
-Mat pseudoInverse(const Mat &matrix) {
- Eigen::EigenSolver<Mat> eigenSolver(matrix);
- Mat D = eigenSolver.pseudoEigenvalueMatrix();
- Mat V = eigenSolver.pseudoEigenvectors();
-
+// TODO(keir): Consider moving this into the numeric code, since this is not
+// related to keyframe selection.
+Mat PseudoInverseWithClampedEigenvalues(const Mat &matrix,
+ int num_eigenvalues_to_clamp) {
+ Eigen::EigenSolver<Mat> eigen_solver(matrix);
+ Mat D = eigen_solver.pseudoEigenvalueMatrix();
+ Mat V = eigen_solver.pseudoEigenvectors();
+
+ // Clamp too-small singular values to zero to prevent numeric blowup.
double epsilon = std::numeric_limits<double>::epsilon();
-
for (int i = 0; i < D.cols(); ++i) {
- if (D(i, i) > epsilon)
+ if (D(i, i) > epsilon) {
D(i, i) = 1.0 / D(i, i);
- else
+ } else {
D(i, i) = 0.0;
+ }
}
- // Zero last 7 (which corresponds to smallest eigen values).
- // 7 equals to the number of gauge freedoms.
- for (int i = D.cols() - 7; i < D.cols(); ++i)
+ // Apply the clamp.
+ for (int i = D.cols() - num_eigenvalues_to_clamp; i < D.cols(); ++i) {
D(i, i) = 0.0;
-
+ }
return V * D * V.inverse();
}
-void filterZeroWeightMarkersFromTracks(const Tracks &tracks,
+void FilterZeroWeightMarkersFromTracks(const Tracks &tracks,
Tracks *filtered_tracks) {
vector<Marker> all_markers = tracks.AllMarkers();
@@ -143,7 +139,7 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks &_tracks,
// http://www.cs.ait.ac.th/~mdailey/papers/Tahir-KeyFrame.pdf
Tracks filtered_tracks;
- filterZeroWeightMarkersFromTracks(_tracks, &filtered_tracks);
+ FilterZeroWeightMarkersFromTracks(_tracks, &filtered_tracks);
int max_image = filtered_tracks.MaxImage();
int next_keyframe = 1;
@@ -224,9 +220,9 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks &_tracks,
EstimateFundamentalOptions estimate_fundamental_options;
EstimateFundamentalFromCorrespondences(x1,
- x2,
- estimate_fundamental_options,
- &F);
+ x2,
+ estimate_fundamental_options,
+ &F);
// Convert fundamental to original pixel space.
F = N_inverse * F * N;
@@ -379,7 +375,8 @@ void SelectKeyframesBasedOnGRICAndVariance(const Tracks &_tracks,
Mat &jacobian = evaluation.jacobian;
Mat JT_J = jacobian.transpose() * jacobian;
- Mat JT_J_inv = pseudoInverse(JT_J);
+ // There are 7 degrees of freedom, so clamp them out.
+ Mat JT_J_inv = PseudoInverseWithClampedEigenvalues(JT_J, 7);
Mat temp_derived = JT_J * JT_J_inv * JT_J;
bool is_inversed = (temp_derived - JT_J).cwiseAbs2().sum() <
diff --git a/extern/libmv/libmv/tracking/kalman_filter.h b/extern/libmv/libmv/tracking/kalman_filter.h
new file mode 100644
index 00000000000..9841f0e912c
--- /dev/null
+++ b/extern/libmv/libmv/tracking/kalman_filter.h
@@ -0,0 +1,112 @@
+// Copyright (c) 2014 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_TRACKING_KALMAN_FILTER_H_
+
+#include "libmv/numeric/numeric.h"
+
+namespace mv {
+
+// A Kalman filter with order N and observation size K.
+template<typename T, int N, int K>
+class KalmanFilter {
+ public:
+ struct State {
+ Eigen::Matrix<T, N, 1> mean;
+ Eigen::Matrix<T, N, N> covariance;
+ };
+
+ // Initialize from row-major data; convenient for constant initializers.
+ KalmanFilter(const T* state_transition_data,
+ const T* observation_data,
+ const T* process_covariance_data,
+ const T* default_measurement_covariance_data)
+ : state_transition_matrix_(
+ Eigen::Matrix<T, N, N, Eigen::RowMajor>(state_transition_data)),
+ observation_matrix_(
+ Eigen::Matrix<T, K, N, Eigen::RowMajor>(observation_data)),
+ process_covariance_(
+ Eigen::Matrix<T, N, N, Eigen::RowMajor>(process_covariance_data)),
+ default_measurement_covariance_(
+ Eigen::Matrix<T, K, K, Eigen::RowMajor>(
+ default_measurement_covariance_data)) {
+ }
+
+ KalmanFilter(
+ const Eigen::Matrix<T, N, N> &state_transition_matrix,
+ const Eigen::Matrix<T, K, N> &observation_matrix,
+ const Eigen::Matrix<T, N, N> &process_covariance,
+ const Eigen::Matrix<T, K, K> &default_measurement_covariance)
+ : state_transition_matrix_(state_transition_matrix),
+ observation_matrix_(observation_matrix),
+ process_covariance_(process_covariance),
+ default_measurement_covariance_(default_measurement_covariance) {
+ }
+
+ // Advances the system according to the current state estimate.
+ void Step(State *state) const {
+ state->mean = state_transition_matrix_ * state->mean;
+ state->covariance = state_transition_matrix_ *
+ state->covariance *
+ state_transition_matrix_.transpose() +
+ process_covariance_;
+ }
+
+ // Updates a state with a new measurement.
+ void Update(const Eigen::Matrix<T, K, 1> &measurement_mean,
+ const Eigen::Matrix<T, K, K> &measurement_covariance,
+ State *state) const {
+ // Calculate the innovation, which is a distribution over prediction error.
+ Eigen::Matrix<T, K, 1> innovation_mean = measurement_mean -
+ observation_matrix_ *
+ state->mean;
+ Eigen::Matrix<T, K, K> innovation_covariance =
+ observation_matrix_ *
+ state->covariance *
+ observation_matrix_.transpose() +
+ measurement_covariance;
+
+ // Calculate the Kalman gain.
+ Eigen::Matrix<T, 6, 2> kalman_gain = state->covariance *
+ observation_matrix_.transpose() *
+ innovation_covariance.inverse();
+
+ // Update the state mean and covariance.
+ state->mean += kalman_gain * innovation_mean;
+ state->covariance = (Eigen::Matrix<T, N, N>::Identity() -
+ kalman_gain * observation_matrix_) *
+ state->covariance;
+ }
+
+ void Update(State *state,
+ const Eigen::Matrix<T, K, 1> &measurement_mean) const {
+ Update(state, measurement_mean, default_measurement_covariance_);
+ }
+
+ private:
+ const Eigen::Matrix<T, N, N> state_transition_matrix_;
+ const Eigen::Matrix<T, K, N> observation_matrix_;
+ const Eigen::Matrix<T, N, N> process_covariance_;
+ const Eigen::Matrix<T, K, K> default_measurement_covariance_;
+};
+
+} // namespace mv
+
+#endif // LIBMV_TRACKING_KALMAN_FILTER_H_
diff --git a/extern/libmv/libmv/tracking/track_region.h b/extern/libmv/libmv/tracking/track_region.h
index 2ced9dd6550..be1d8ef3e03 100644
--- a/extern/libmv/libmv/tracking/track_region.h
+++ b/extern/libmv/libmv/tracking/track_region.h
@@ -42,7 +42,13 @@ struct TrackRegionOptions {
};
Mode mode;
+ // Minimum normalized cross-correlation necessary between the final tracked
+ // positoin of the patch on the destination image and the reference patch
+ // needed to declare tracking success. If the minimum correlation is not met,
+ // then TrackResult::termination is INSUFFICIENT_CORRELATION.
double minimum_correlation;
+
+ // Maximum number of Ceres iterations to run for the inner minimization.
int max_iterations;
// Use the "Efficient Second-order Minimization" scheme. This increases
@@ -124,6 +130,11 @@ struct TrackRegionResult {
};
Termination termination;
+ bool is_usable() {
+ return termination == CONVERGENCE ||
+ termination == NO_CONVERGENCE;
+ }
+
int num_iterations;
double correlation;
diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh
index 14ce2c5135d..659f29e98ea 100755
--- a/extern/libmv/third_party/ceres/bundle.sh
+++ b/extern/libmv/third_party/ceres/bundle.sh
@@ -201,7 +201,7 @@ blender_add_lib(extern_ceres "\${SRC}" "\${INC}" "\${INC_SYS}")
EOF
cat > SConscript << EOF
-#!/usr/bin/python
+#!/usr/bin/env python
# NOTE: This file is automatically generated by bundle.sh script
# If you're doing changes in this file, please update template
diff --git a/extern/libmv/third_party/gflags/AUTHORS b/extern/libmv/third_party/gflags/AUTHORS.txt
index 887918bd00e..887918bd00e 100644
--- a/extern/libmv/third_party/gflags/AUTHORS
+++ b/extern/libmv/third_party/gflags/AUTHORS.txt
diff --git a/extern/libmv/third_party/gflags/COPYING b/extern/libmv/third_party/gflags/COPYING.txt
index d15b0c24134..d15b0c24134 100644
--- a/extern/libmv/third_party/gflags/COPYING
+++ b/extern/libmv/third_party/gflags/COPYING.txt
diff --git a/extern/libmv/third_party/gflags/ChangeLog b/extern/libmv/third_party/gflags/ChangeLog
deleted file mode 100644
index f9ef9350984..00000000000
--- a/extern/libmv/third_party/gflags/ChangeLog
+++ /dev/null
@@ -1,195 +0,0 @@
-Wed Jan 25 15:09:14 2012 Google Inc. <google-gflags@googlegroups.com>
-
- * gflags: version 2.0
- * Changed the 'official' gflags email in setup.py/etc
- * Renamed google-gflags.sln to gflags.sln
- * Changed copyright text to reflect Google's relinquished ownership
-
-Tue Dec 20 19:48:57 2011 Google Inc. <opensource@google.com>
-
- * google-gflags: version 1.7
- * Add CommandLineFlagInfo::flag_ptr pointing to current storage (musji)
- * PORTING: flush after writing to stderr, needed on cygwin
- * PORTING: Clean up the GFLAGS_DLL_DECL stuff better
- * Fix a bug in StringPrintf() that affected large strings (csilvers)
- * Die at configure-time when g++ isn't installed
-
-Fri Jul 29 19:05:21 2011 Google Inc. <opensource@google.com>
-
- * google-gflags: version 1.6
- * BUGFIX: Fix a bug where we were leaving out a required $(top_srcdir)
- * Fix definition of clstring (jyrki)
- * Split up flag declares into its own file (jyrki)
- * Add --version support (csilvers)
- * Update the README for gflags with static libs
- * Update acx_pthread.m4 for nostdlib
- * Change ReparseCommandLineFlags to return void (csilvers)
- * Some doc typofixes and example augmentation (various)
-
-Mon Jan 24 16:11:35 2011 Google Inc. <opensource@google.com>
-
- * google-gflags: version 1.5
- * Better reporting of current vs default value (handler)
- * Add API for cleaning up of memory at program-exit (jmarantz)
- * Fix macros to work inside namespaces (csilvers)
- * Use our own string typedef in case string is redefined (csilvers)
- * Updated to autoconf 2.65
-
-Wed Oct 13 17:40:12 2010 Google Inc. <opensource@google.com>
-
- * google-gflags: version 1.4
- * Add a check to prevent passing 0 to DEFINE_string (jorg)
- * Reduce compile (.o) size (jyrki)
- * Some small changes to quiet debug compiles (alexk)
- * PORTING: better support static linking on windows (csilvers)
- * DOCUMENTATION: change default values, use validators, etc.
- * Update the NEWS file to be non-empty
- * Add pkg-config (.pc) files for libgflags and libgflags_nothreads
-
-Mon Jan 4 18:09:30 2010 Google Inc. <opensource@google.com>
-
- * google-gflags: version 1.3
- * PORTABILITY: can now build and run tests under MSVC (csilvers)
- * Remove the python gflags code, which is now its own package (tansell)
- * Clarify that "last flag wins" in the docs (csilvers)
- * Comment danger of using GetAllFlags in validators (wojtekm)
- * PORTABILITY: Some fixes necessary for c++0x (mboerger)
- * Makefile fix: $(srcdir) -> $(top_srcdir) in one place (csilvres)
- * INSTALL: autotools to autoconf v2.64 + automake v1.11 (csilvers)
-
-Thu Sep 10 12:53:04 2009 Google Inc. <opensource@google.com>
-
- * google-gflags: version 1.2
- * PORTABILITY: can now build and run tests under mingw (csilvers)
- * Using a string arg for a bool flag is a compile-time error (rbayardo)
- * Add --helpxml to gflags.py (salcianu)
- * Protect against a hypothetical global d'tor mutex problem (csilvers)
- * BUGFIX: can now define a flag after 'using namespace google' (hamaji)
-
-Tue Apr 14 12:35:25 2009 Google Inc. <opensource@google.com>
-
- * google-gflags: version 1.1
- * Add both foo and nofoo for boolean flags, with --undefok (andychu)
- * Better document how validators work (wojtekm)
- * Improve binary-detection for bash-completion (mtamsky)
- * Python: Add a concept of "key flags", used with --help (salcianu)
- * Python: Robustify flag_values (salcianu)
- * Python: Add a new DEFINE_bool alias (keir, andrewliu)
- * Python: Do module introspection based on module name (dsturtevant)
- * Fix autoconf a bit better, especially on windows and solaris (ajenjo)
- * BUG FIX: gflags_nothreads was linking against the wrong lib (ajenjo)
- * BUG FIX: threads-detection failed on FreeBSD; replace it (ajenjo)
- * PORTABILITY: Quiet an internal compiler error with SUSE 10 (csilvers)
- * PORTABILITY: Update deb.sh for more recenty debuilds (csilvers)
- * PORTABILITY: #include more headers to satify new gcc's (csilvers)
- * INSTALL: Updated to autoconf 2.61 and libtool 1.5.26 (csilvers)
-
-Fri Oct 3 15:16:46 2008 Google Inc. <opensource@google.com>
-
- * google-gflags: version 1.0
- * Add a missing newline to an error string (bcmills)
- * (otherwise exactly the same as gflags 1.0rc2)
-
-Thu Sep 18 12:58:05 2008 Google Inc. <opensource@google.com>
-
- * google-gflags: version 1.0rc2
- * Report current flag values in --helpxml (hdn)
- * Fix compilation troubles with gcc 4.3.3 (simonb)
- * BUG FIX: I was missing a std:: in DECLARE_string (csilvers)
- * BUG FIX: Clarify in docs how to specify --bool flags (csilvers)
- * BUG FIX: Fix --helpshort for source files not in a subdir (csilvers)
- * BUG FIX: Fix python unittest for 64-bit builds (bcmills)
-
-Tue Aug 19 16:15:48 2008
-
- * google-gflags: version 1.0rc1
- * Move #include files from google/ to gflags/ (csilvers)
- * Small optimizations to reduce binary (library) size (jyrki)
- * BUGFIX: forgot a std:: in one of the .h files (csilvers)
- * Speed up locking by making sure calls are inlined (ajenjo)
- * 64-BIT COMPATIBILITY: Use %PRId64 instead of %lld (csilvers)
- * PORTABILITY: fix Makefile to work with Cygwin (ajenjo)
- * PORTABILITY: fix code to compile under Visual Studio (ajenjo)
- * PORTABILITY: fix code to compile under Solaris 10 with CC (csilvers)
-
-Mon Jul 21 23:01:38 2008 Google Inc. <opensource@google.com>
-
- * google-gflags: version 0.9
- * Add the ability to validate a command-line flag (csilvers)
- * Add completion support for commandline flags in bash (daven)
- * Add -W compile flags to Makefile, when using gcc (csilvers)
- * Allow helpstring to be NULL (cristianoc)
- * Improved documentation of classes in the .cc file (csilvers)
- * Fix python bug with AppendFlagValues + shortnames (jjtswan)
- * Use bool instead of int for boolean flags in gflags.py (bcmills)
- * Simplify the way we declare flags, now more foolproof (csilvers)
- * Better error messages when bool flags collide (colohan)
- * Only evaluate DEFINE_foo macro args once (csilvers)
-
-Wed Mar 26 15:20:18 2008 Google Inc. <opensource@google.com>
-
- * google-gflags: version 0.8
- * Export DescribeOneFlag() in the API
- * Add support for automatic line wrapping at 80 cols for gflags.py
- * Bugfix: do not treat an isolated "-" the same as an isolated "--"
- * Update rpm spec to point to Google Code rather than sourceforge (!)
- * Improve documentation (including documenting thread-safety)
- * Improve #include hygiene
- * Improve testing
-
-Thu Oct 18 11:33:20 2007 Google Inc. <opensource@google.com>
-
- * google-gflags: version 0.7
- * Deal even more correctly with libpthread not linked in (csilvers)
- * Add STRIP_LOG, an improved DO_NOT_SHOW_COMMANDLINE_HELP (sioffe)
- * Be more accurate printing default flag values in --help (dsturtevant)
- * Reduce .o file size a bit by using shorter namespace names (jeff)
- * Use relative install path, so 'setup.py --home' works (csilvers)
- * Notice when a boolean flag has a non-boolean default (bnmouli)
- * Broaden --helpshort to match foo-main.cc and foo_main.cc (hendrie)
- * Fix "no modules match" message for --helpshort, etc (hendrie)
-
-Wed Aug 15 07:35:51 2007 Google Inc. <opensource@google.com>
-
- * google-gflags: version 0.6
- * Deal correctly with case that libpthread is not linked in (csilvers)
- * Update Makefile/tests so we pass "make distcheck" (csilvers)
- * Document and test that last assignment to a flag wins (wan)
-
-Tue Jun 12 15:23:42 2007 Google Inc. <opensource@google.com>
-
- * google-gflags: version 0.5
- * Include all m4 macros in the distribution (csilvers)
- * Python: Fix broken data_files field in setup.py (sidlon)
- * Python: better string serliaizing and unparsing (abo, csimmons)
- * Fix checks for NaN and inf to work with Mac OS X (csilvers)
-
-Thu Apr 19 15:15:07 2007 Google Inc. <opensource@google.com>
-
- * google-gflags: version 0.4
- * Remove is_default from GetCommandLineFlagInfo (csilvers)
- * Portability fixes: includes, strtoll, gcc4.3 errors (csilvers)
- * A few doc typo cleanups (csilvers)
-
-Wed Mar 28 12:15:56 2007 Google Inc. <opensource@google.com>
-
- * google-gflags: version 0.3
- * python portability fix: use popen instead of subprocess (csilvers)
- * Add is_default to CommandLineFlagInfo (pchien)
- * Make docs a bit prettier (csilvers)
- * Actually include the python files in the distribution! :-/ (csilvers)
-
-Mon Jan 22 15:33:06 2007 Google Inc. <opensource@google.com>
-
- * google-gflags: version 0.2
- * added support for python commandlineflags, as well as c++
- * gflags2man, a script to turn flags into a man page (dchristian)
-
-Wed Dec 13 12:37:19 2006 Google Inc. <opensource@google.com>
-
- * google-gflags: initial release:
- The gflags package contains a library that implements commandline
- flags processing. As such it's a replacement for getopt(). It
- has increased flexibility, including built-in support for C++
- types like string, and the ability to define flags in the source
- file in which they're used.
diff --git a/extern/libmv/third_party/gflags/ChangeLog.txt b/extern/libmv/third_party/gflags/ChangeLog.txt
new file mode 100644
index 00000000000..e14d88e35f2
--- /dev/null
+++ b/extern/libmv/third_party/gflags/ChangeLog.txt
@@ -0,0 +1,208 @@
+* Sun Mar 20 2014 - Andreas Schuh <google-gflags@googlegroups.com>
+
+- gflags: version 2.1.1
+- Fixed issue 77: GFLAGS_IS_A_DLL expands to empty string in gflags_declare.h
+- Fixed issue 79: GFLAGS_NAMESPACE not expanded to actual namespace in gflags_declare.h
+- Fixed issue 80: Allow include path to differ from GFLAGS_NAMESPACE
+
+* Thu Mar 20 2014 - Andreas Schuh <google-gflags@googlegroups.com>
+
+- gflags: version 2.1.0
+- Build system configuration using CMake instead of autotools
+- CPack packaging support for Debian/Ubuntu, Red Hat, and Mac OS X
+- Fixed issue 54: Fix "invalid suffix on literal" (C++11)
+- Fixed issue 57: Use _strdup instead of strdup on Windows
+- Fixed issue 62: Change all preprocessor include guards to start with GFLAGS_
+- Fixed issue 64: Add DEFINE_validator macro
+- Fixed issue 73: Warnings in Visual Studio 2010 and unable to compile unit test
+
+* Wed Jan 25 2012 - Google Inc. <google-gflags@googlegroups.com>
+
+- gflags: version 2.0
+- Changed the 'official' gflags email in setup.py/etc
+- Renamed google-gflags.sln to gflags.sln
+- Changed copyright text to reflect Google's relinquished ownership
+
+* Tue Dec 20 2011 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.7
+- Add CommandLineFlagInfo::flag_ptr pointing to current storage (musji)
+- PORTING: flush after writing to stderr, needed on cygwin
+- PORTING: Clean up the GFLAGS_DLL_DECL stuff better
+- Fix a bug in StringPrintf() that affected large strings (csilvers)
+- Die at configure-time when g++ isn't installed
+
+* Fri Jul 29 2011 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.6
+- BUGFIX: Fix a bug where we were leaving out a required $(top_srcdir)
+- Fix definition of clstring (jyrki)
+- Split up flag declares into its own file (jyrki)
+- Add --version support (csilvers)
+- Update the README for gflags with static libs
+- Update acx_pthread.m4 for nostdlib
+- Change ReparseCommandLineFlags to return void (csilvers)
+- Some doc typofixes and example augmentation (various)
+
+* Mon Jan 24 2011 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.5
+- Better reporting of current vs default value (handler)
+- Add API for cleaning up of memory at program-exit (jmarantz)
+- Fix macros to work inside namespaces (csilvers)
+- Use our own string typedef in case string is redefined (csilvers)
+- Updated to autoconf 2.65
+
+* Wed Oct 13 2010 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.4
+- Add a check to prevent passing 0 to DEFINE_string (jorg)
+- Reduce compile (.o) size (jyrki)
+- Some small changes to quiet debug compiles (alexk)
+- PORTING: better support static linking on windows (csilvers)
+- DOCUMENTATION: change default values, use validators, etc.
+- Update the NEWS file to be non-empty
+- Add pkg-config (.pc) files for libgflags and libgflags_nothreads
+
+* Mon Jan 4 2010 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.3
+- PORTABILITY: can now build and run tests under MSVC (csilvers)
+- Remove the python gflags code, which is now its own package (tansell)
+- Clarify that "last flag wins" in the docs (csilvers)
+- Comment danger of using GetAllFlags in validators (wojtekm)
+- PORTABILITY: Some fixes necessary for c++0x (mboerger)
+- Makefile fix: $(srcdir) -> $(top_srcdir) in one place (csilvres)
+- INSTALL: autotools to autoconf v2.64 + automake v1.11 (csilvers)
+
+* Thu Sep 10 2009 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.2
+- PORTABILITY: can now build and run tests under mingw (csilvers)
+- Using a string arg for a bool flag is a compile-time error (rbayardo)
+- Add --helpxml to gflags.py (salcianu)
+- Protect against a hypothetical global d'tor mutex problem (csilvers)
+- BUGFIX: can now define a flag after 'using namespace google' (hamaji)
+
+* Tue Apr 14 2009 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.1
+- Add both foo and nofoo for boolean flags, with --undefok (andychu)
+- Better document how validators work (wojtekm)
+- Improve binary-detection for bash-completion (mtamsky)
+- Python: Add a concept of "key flags", used with --help (salcianu)
+- Python: Robustify flag_values (salcianu)
+- Python: Add a new DEFINE_bool alias (keir, andrewliu)
+- Python: Do module introspection based on module name (dsturtevant)
+- Fix autoconf a bit better, especially on windows and solaris (ajenjo)
+- BUG FIX: gflags_nothreads was linking against the wrong lib (ajenjo)
+- BUG FIX: threads-detection failed on FreeBSD; replace it (ajenjo)
+- PORTABILITY: Quiet an internal compiler error with SUSE 10 (csilvers)
+- PORTABILITY: Update deb.sh for more recenty debuilds (csilvers)
+- PORTABILITY: #include more headers to satify new gcc's (csilvers)
+- INSTALL: Updated to autoconf 2.61 and libtool 1.5.26 (csilvers)
+
+* Fri Oct 3 2008 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.0
+- Add a missing newline to an error string (bcmills)
+- (otherwise exactly the same as gflags 1.0rc2)
+
+* Thu Sep 18 2008 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.0rc2
+- Report current flag values in --helpxml (hdn)
+- Fix compilation troubles with gcc 4.3.3 (simonb)
+- BUG FIX: I was missing a std:: in DECLARE_string (csilvers)
+- BUG FIX: Clarify in docs how to specify --bool flags (csilvers)
+- BUG FIX: Fix --helpshort for source files not in a subdir (csilvers)
+- BUG FIX: Fix python unittest for 64-bit builds (bcmills)
+
+* Tue Aug 19 2008 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.0rc1
+- Move #include files from google/ to gflags/ (csilvers)
+- Small optimizations to reduce binary (library) size (jyrki)
+- BUGFIX: forgot a std:: in one of the .h files (csilvers)
+- Speed up locking by making sure calls are inlined (ajenjo)
+- 64-BIT COMPATIBILITY: Use %PRId64 instead of %lld (csilvers)
+- PORTABILITY: fix Makefile to work with Cygwin (ajenjo)
+- PORTABILITY: fix code to compile under Visual Studio (ajenjo)
+- PORTABILITY: fix code to compile under Solaris 10 with CC (csilvers)
+
+* Mon Jul 21 2008 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.9
+- Add the ability to validate a command-line flag (csilvers)
+- Add completion support for commandline flags in bash (daven)
+- Add -W compile flags to Makefile, when using gcc (csilvers)
+- Allow helpstring to be NULL (cristianoc)
+- Improved documentation of classes in the .cc file (csilvers)
+- Fix python bug with AppendFlagValues + shortnames (jjtswan)
+- Use bool instead of int for boolean flags in gflags.py (bcmills)
+- Simplify the way we declare flags, now more foolproof (csilvers)
+- Better error messages when bool flags collide (colohan)
+- Only evaluate DEFINE_foo macro args once (csilvers)
+
+* Wed Mar 26 2008 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.8
+- Export DescribeOneFlag() in the API
+- Add support for automatic line wrapping at 80 cols for gflags.py
+- Bugfix: do not treat an isolated "-" the same as an isolated "--"
+- Update rpm spec to point to Google Code rather than sourceforge (!)
+- Improve documentation (including documenting thread-safety)
+- Improve #include hygiene
+- Improve testing
+
+* Thu Oct 18 2007 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.7
+- Deal even more correctly with libpthread not linked in (csilvers)
+- Add STRIP_LOG, an improved DO_NOT_SHOW_COMMANDLINE_HELP (sioffe)
+- Be more accurate printing default flag values in --help (dsturtevant)
+- Reduce .o file size a bit by using shorter namespace names (jeff)
+- Use relative install path, so 'setup.py --home' works (csilvers)
+- Notice when a boolean flag has a non-boolean default (bnmouli)
+- Broaden --helpshort to match foo-main.cc and foo_main.cc (hendrie)
+- Fix "no modules match" message for --helpshort, etc (hendrie)
+
+* Wed Aug 15 2007 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.6
+- Deal correctly with case that libpthread is not linked in (csilvers)
+- Update Makefile/tests so we pass "make distcheck" (csilvers)
+- Document and test that last assignment to a flag wins (wan)
+
+* Tue Jun 12 2007 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.5
+- Include all m4 macros in the distribution (csilvers)
+- Python: Fix broken data_files field in setup.py (sidlon)
+- Python: better string serliaizing and unparsing (abo, csimmons)
+- Fix checks for NaN and inf to work with Mac OS X (csilvers)
+
+* Thu Apr 19 2007 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.4
+- Remove is_default from GetCommandLineFlagInfo (csilvers)
+- Portability fixes: includes, strtoll, gcc4.3 errors (csilvers)
+- A few doc typo cleanups (csilvers)
+
+* Wed Mar 28 2007 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.3
+- python portability fix: use popen instead of subprocess (csilvers)
+- Add is_default to CommandLineFlagInfo (pchien)
+- Make docs a bit prettier (csilvers)
+- Actually include the python files in the distribution! :-/ (csilvers)
+
+* Mon Jan 22 2007 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.2
+- added support for python commandlineflags, as well as c++
+- gflags2man, a script to turn flags into a man page (dchristian)
+
+* Wed Dec 13 2006 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.1
diff --git a/extern/libmv/third_party/gflags/NEWS b/extern/libmv/third_party/gflags/NEWS.txt
index ffc0127d91e..74186071129 100644
--- a/extern/libmv/third_party/gflags/NEWS
+++ b/extern/libmv/third_party/gflags/NEWS.txt
@@ -1,4 +1,86 @@
-== 25 January 2012 ==
+=== 30 March 2014 ===
+
+I've just released gflags 2.1.1.
+
+This release fixes a few bugs in the configuration of gflags_declare.h
+and adds a separate GFLAGS_INCLUDE_DIR CMake variable to the build configuration.
+Setting GFLAGS_NAMESPACE to "google" no longer changes also the include
+path of the public header files. This allows the use of the library with
+other Google projects such as glog which still use the deprecated "google"
+namespace for the gflags library, but include it as "gflags/gflags.h".
+
+=== 20 March 2014 ===
+
+I've just released gflags 2.1.
+
+The major changes are the use of CMake for the build configuration instead
+of the autotools and packaging support through CPack. The default namespace
+of all C++ symbols is now "gflags" instead of "google". This can be
+configured via the GFLAGS_NAMESPACE variable.
+
+This release compiles with all major compilers without warnings and passed
+the unit tests on Ubuntu 12.04, Windows 7 (Visual Studio 2008 and 2010,
+Cygwin, MinGW), and Mac OS X (Xcode 5.1).
+
+The SVN repository on Google Code is now frozen and replaced by a Git
+repository such that it can be used as Git submodule by projects. The main
+hosting of this project remains at Google Code. Thanks to the distributed
+character of Git, I can push (and pull) changes from both GitHub and Google Code
+in order to keep the two public repositories in sync.
+When fixing an issue for a pull request through either of these hosting
+platforms, please reference the issue number as
+[https://code.google.com/p/support/wiki/IssueTracker#Integration_with_version_control described here].
+For the further development, I am following the
+[http://nvie.com/posts/a-successful-git-branching-model/ Git branching model]
+with feature branch names prefixed by "feature/" and bugfix branch names
+prefixed by "bugfix/", respectively.
+
+Binary and source [https://github.com/schuhschuh/gflags/releases packages] are available on GitHub.
+
+
+=== 14 January 2013 ===
+
+The migration of the build system to CMake is almost complete.
+What remains to be done is rewriting the tests in Python such they can be
+executed on non-Unix platforms and splitting them up into separate CTest tests.
+Though merging these changes into the master branch yet remains to be done,
+it is recommended to already start using the
+[https://github.com/schuhschuh/gflags/tree/cmake-migration cmake-migration] branch.
+
+
+=== 20 April 2013 ===
+
+More than a year has past since I (Andreas) took over the maintenance for
+`gflags`. Only few minor changes have been made since then, much to my regret.
+To get more involved and stimulate participation in the further
+development of the library, I moved the project source code today to
+[https://github.com/schuhschuh/gflags GitHub].
+I believe that the strengths of [http://git-scm.com/ Git] will allow for better community collaboration
+as well as ease the integration of changes made by others. I encourage everyone
+who would like to contribute to send me pull requests.
+Git's lightweight feature branches will also provide the right tool for more
+radical changes which should only be merged back into the master branch
+after these are complete and implement the desired behavior.
+
+The SVN repository remains accessible at Google Code and I will keep the
+master branch of the Git repository hosted at GitHub and the trunk of the
+Subversion repository synchronized. Initially, I was going to simply switch the
+Google Code project to Git, but in this case the SVN repository would be
+frozen and force everyone who would like the latest development changes to
+use Git as well. Therefore I decided to host the public Git repository at GitHub
+instead.
+
+Please continue to report any issues with gflags on Google Code. The GitHub project will
+only be used to host the Git repository.
+
+One major change of the project structure I have in mind for the next weeks
+is the migration from autotools to [http://www.cmake.org/ CMake].
+Check out the (unstable!)
+[https://github.com/schuhschuh/gflags/tree/cmake-migration cmake-migration]
+branch on GitHub for details.
+
+
+=== 25 January 2012 ===
I've just released gflags 2.0.
@@ -128,7 +210,7 @@ If you've tried to install a .rpm or .deb and it doesn't work for you,
let me know. I'm excited to finally have 64-bit package files, but
there may still be some wrinkles in the new system to iron out.
-===1 October 2008===
+=== 1 October 2008 ===
gflags 1.0rc2 was out for a few weeks without any issues, so gflags
1.0 is now released. This is much like gflags 0.9. The major change
diff --git a/extern/libmv/third_party/gflags/README.libmv b/extern/libmv/third_party/gflags/README.libmv
index b310c57ac34..f4310b39bbb 100644
--- a/extern/libmv/third_party/gflags/README.libmv
+++ b/extern/libmv/third_party/gflags/README.libmv
@@ -1,16 +1,18 @@
Project: Google Flags
URL: http://code.google.com/p/google-gflags/
License: New BSD
-Upstream version: 2.0
+Upstream version: 2.1.1
Local modifications:
-- Flattened the tree and only included files needed for libmv. This involved
- changing some of the includes to point to the current directory instead of a
- nested gflags directory.
+- Flattened the tree and only included files needed for libmv.
-- Added a poor-man's version of upstream's port.cc/h to make gflags compile on
- windows. This isn't sufficient but is a stopgap for now.
+- config.h was originally generated on linux machine with some
+ further tweaks:
-- Added -fPIC flag, so shared libraries from Ceres could be linked against static glog
+ * OS_WINDOWS need to be conditinally defined from inside #ifdef WIN32
+ * Same applies yo HAVE_SHLWAPI_H
+ * Disabeld HAVE_FNMATCH_H
+
+- Removed attribute(unused) from FlagSaver.
TODO(keir): Import and use gflags for Windows from upstream.
diff --git a/extern/libmv/third_party/gflags/config.h b/extern/libmv/third_party/gflags/config.h
index 03ed03ca99b..858510835c1 100644
--- a/extern/libmv/third_party/gflags/config.h
+++ b/extern/libmv/third_party/gflags/config.h
@@ -1,101 +1,117 @@
-/* src/config.h. Generated from config.h.in by configure. */
-/* src/config.h.in. Generated from configure.ac by autoheader. */
+/* Generated from config.h.in during build configuration using CMake. */
-/* Always the empty-string on non-windows systems. On windows, should be
- "__declspec(dllexport)". This way, when we compile the dll, we export our
- functions/classes. It's safe to define this here because config.h is only
- used internally, to compile the DLL, and every DLL source file #includes
- "config.h" before anything else. */
-#define GFLAGS_DLL_DECL /**/
+// Note: This header file is only used internally. It is not part of public interface!
-/* Namespace for Google classes */
-#define GOOGLE_NAMESPACE ::google
+// ---------------------------------------------------------------------------
+// System checks
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
+// Define if you build this library for a MS Windows OS.
+#ifdef WIN32
+# define OS_WINDOWS
+#endif
-/* Define to 1 if you have the <fnmatch.h> header file. */
-/* #ubdef HAVE_FNMATCH_H 1 */
+// Define if you have the <stdint.h> header file.
+#define HAVE_STDINT_H
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
+// Define if you have the <sys/types.h> header file.
+#define HAVE_SYS_TYPES_H
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
+// Define if you have the <inttypes.h> header file.
+#define HAVE_INTTYPES_H
-/* define if the compiler implements namespaces */
-#define HAVE_NAMESPACES 1
+// Define if you have the <sys/stat.h> header file.
+#define HAVE_SYS_STAT_H
-/* Define if you have POSIX threads libraries and header files. */
-#define HAVE_PTHREAD 1
+// Define if you have the <unistd.h> header file.
+#define HAVE_UNISTD_H
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
+// Define if you have the <fnmatch.h> header file.
+/* #undef HAVE_FNMATCH_H */
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
+// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
+#undef HAVE_SHLWAPI_H
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
+// Define if you have the strtoll function.
+#define HAVE_STRTOLL
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
+// Define if you have the strtoq function.
+/* #undef HAVE_STRTOQ */
-/* Define to 1 if you have the `strtoll' function. */
-#define HAVE_STRTOLL 1
+// Define if you have the <pthread.h> header file.
+#define HAVE_PTHREAD
-/* Define to 1 if you have the `strtoq' function. */
-#define HAVE_STRTOQ 1
+// Define if your pthread library defines the type pthread_rwlock_t
+#define HAVE_RWLOCK
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
+// gcc requires this to get PRId64, etc.
+#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
+# define __STDC_FORMAT_MACROS 1
+#endif
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
+// ---------------------------------------------------------------------------
+// Package information
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
+// Name of package.
+#define PACKAGE gflags
-/* define if your compiler has __attribute__ */
-#define HAVE___ATTRIBUTE__ 1
+// Define to the full name of this package.
+#define PACKAGE_NAME gflags
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
+// Define to the full name and version of this package.
+#define PACKAGE_STRING gflags 2.1.1
-/* Name of package */
-#define PACKAGE "gflags"
+// Define to the one symbol short name of this package.
+#define PACKAGE_TARNAME gflags-2.1.1
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "google-gflags@googlegroups.com"
+// Define to the version of this package.
+#define PACKAGE_VERSION 2.1.1
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "gflags"
+// Version number of package.
+#define VERSION PACKAGE_VERSION
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "gflags 2.0"
+// Define to the address where bug reports for this package should be sent.
+#define PACKAGE_BUGREPORT https://code.google.com/p/gflags/issues/
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "gflags"
+// Namespace of gflags library symbols.
+#define GFLAGS_NAMESPACE gflags
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.0"
+// ---------------------------------------------------------------------------
+// Path separator
+#ifndef PATH_SEPARATOR
+# ifdef OS_WINDOWS
+# define PATH_SEPARATOR '\\'
+# else
+# define PATH_SEPARATOR '/'
+# endif
+#endif
-/* Define to necessary symbol if this constant uses a non-standard name on
- your system. */
-/* #undef PTHREAD_CREATE_JOINABLE */
+// ---------------------------------------------------------------------------
+// Windows
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
+// Whether gflags library is a DLL.
+#ifndef GFLAGS_IS_A_DLL
+# define GFLAGS_IS_A_DLL 0
+#endif
-/* the namespace where STL code like vector<> is defined */
-#define STL_NAMESPACE std
-
-/* Version number of package */
-#define VERSION "2.0"
-
-/* Stops putting the code inside the Google namespace */
-#define _END_GOOGLE_NAMESPACE_ }
-
-/* Puts following code inside the Google namespace */
-#define _START_GOOGLE_NAMESPACE_ namespace google {
+// Always export symbols when compiling a shared library as this file is only
+// included by internal modules when building the gflags library itself.
+// The gflags_declare.h header file will set it to import these symbols otherwise.
+#ifndef GFLAGS_DLL_DECL
+# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
+# define GFLAGS_DLL_DECL __declspec(dllexport)
+# else
+# define GFLAGS_DLL_DECL
+# endif
+#endif
+// Flags defined by the gflags library itself must be exported
+#ifndef GFLAGS_DLL_DEFINE_FLAG
+# define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL
+#endif
+
+#ifdef OS_WINDOWS
+// The unittests import the symbols of the shared gflags library
+# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
+# define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
+# endif
+# include "windows_port.h"
+#endif
diff --git a/extern/libmv/third_party/gflags/gflags.cc b/extern/libmv/third_party/gflags/gflags.cc
index 4ba2b6f393c..285050fe9ec 100644
--- a/extern/libmv/third_party/gflags/gflags.cc
+++ b/extern/libmv/third_party/gflags/gflags.cc
@@ -87,18 +87,16 @@
// other hand, hooks into CommandLineFlagParser. Other API functions
// are, similarly, mostly hooks into the functionality described above.
-// This comes first to ensure we define __STDC_FORMAT_MACROS in time.
#include "config.h"
-#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
-# define __STDC_FORMAT_MACROS 1 // gcc requires this to get PRId64, etc.
-#endif
+#include "gflags.h"
-#include "gflags/gflags.h"
#include <assert.h>
#include <ctype.h>
#include <errno.h>
-#ifdef HAVE_FNMATCH_H
-# include <fnmatch.h>
+#if defined(HAVE_FNMATCH_H)
+# include <fnmatch.h>
+#elif defined(HAVE_SHLWAPI_H)
+# include <shlwapi.h>
#endif
#include <stdarg.h> // For va_list and related operations
#include <stdio.h>
@@ -109,31 +107,23 @@
#include <string>
#include <utility> // for pair<>
#include <vector>
+
#include "mutex.h"
#include "util.h"
-#ifndef PATH_SEPARATOR
-#define PATH_SEPARATOR '/'
-#endif
-
-
// Special flags, type 1: the 'recursive' flags. They set another flag's val.
-DEFINE_string(flagfile, "",
- "load flags from file");
-DEFINE_string(fromenv, "",
- "set flags from the environment"
- " [use 'export FLAGS_flag1=value']");
-DEFINE_string(tryfromenv, "",
- "set flags from the environment if present");
+DEFINE_string(flagfile, "", "load flags from file");
+DEFINE_string(fromenv, "", "set flags from the environment"
+ " [use 'export FLAGS_flag1=value']");
+DEFINE_string(tryfromenv, "", "set flags from the environment if present");
// Special flags, type 2: the 'parsing' flags. They modify how we parse.
-DEFINE_string(undefok, "",
- "comma-separated list of flag names that it is okay to specify "
- "on the command line even if the program does not define a flag "
- "with that name. IMPORTANT: flags in this list that have "
- "arguments MUST use the flag=value format");
+DEFINE_string(undefok, "", "comma-separated list of flag names that it is okay to specify "
+ "on the command line even if the program does not define a flag "
+ "with that name. IMPORTANT: flags in this list that have "
+ "arguments MUST use the flag=value format");
-_START_GOOGLE_NAMESPACE_
+namespace GFLAGS_NAMESPACE {
using std::map;
using std::pair;
@@ -206,7 +196,7 @@ class FlagValue {
private:
friend class CommandLineFlag; // for many things, including Validate()
- friend class GOOGLE_NAMESPACE::FlagSaverImpl; // calls New()
+ friend class GFLAGS_NAMESPACE::FlagSaverImpl; // calls New()
friend class FlagRegistry; // checks value_buffer_ for flags_by_ptr_ map
template <typename T> friend T GetFromEnv(const char*, const char*, T);
friend bool TryParseLocked(const CommandLineFlag*, FlagValue*,
@@ -348,13 +338,13 @@ string FlagValue::ToString() const {
case FV_BOOL:
return VALUE_AS(bool) ? "true" : "false";
case FV_INT32:
- snprintf(intbuf, sizeof(intbuf), "%"PRId32, VALUE_AS(int32));
+ snprintf(intbuf, sizeof(intbuf), "%" PRId32, VALUE_AS(int32));
return intbuf;
case FV_INT64:
- snprintf(intbuf, sizeof(intbuf), "%"PRId64, VALUE_AS(int64));
+ snprintf(intbuf, sizeof(intbuf), "%" PRId64, VALUE_AS(int64));
return intbuf;
case FV_UINT64:
- snprintf(intbuf, sizeof(intbuf), "%"PRIu64, VALUE_AS(uint64));
+ snprintf(intbuf, sizeof(intbuf), "%" PRIu64, VALUE_AS(uint64));
return intbuf;
case FV_DOUBLE:
snprintf(intbuf, sizeof(intbuf), "%.17g", VALUE_AS(double));
@@ -406,8 +396,7 @@ const char* FlagValue::TypeName() const {
assert(false);
return "";
}
- // Directly indexing the strigns in the 'types' string, each of them
- // is 7 bytes long.
+ // Directly indexing the strings in the 'types' string, each of them is 7 bytes long.
return &types[type_ * 7];
}
@@ -504,7 +493,7 @@ class CommandLineFlag {
private:
// for SetFlagLocked() and setting flags_by_ptr_
friend class FlagRegistry;
- friend class GOOGLE_NAMESPACE::FlagSaverImpl; // for cloning the values
+ friend class GFLAGS_NAMESPACE::FlagSaverImpl; // for cloning the values
// set validate_fn
friend bool AddFlagValidator(const void*, ValidateFnProto);
@@ -671,9 +660,9 @@ class FlagRegistry {
static FlagRegistry* GlobalRegistry(); // returns a singleton registry
private:
- friend class GOOGLE_NAMESPACE::FlagSaverImpl; // reads all the flags in order to copy them
+ friend class GFLAGS_NAMESPACE::FlagSaverImpl; // reads all the flags in order to copy them
friend class CommandLineFlagParser; // for ValidateAllFlags
- friend void GOOGLE_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*);
+ friend void GFLAGS_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*);
// The map from name to flag, for FindFlagLocked().
typedef map<const char*, CommandLineFlag*, StringCmp> FlagMap;
@@ -1003,8 +992,8 @@ static string ReadFileIntoString(const char* filename) {
const int kBufSize = 8092;
char buffer[kBufSize];
string s;
- FILE* fp = fopen(filename, "r");
- if (!fp) PFATAL(filename);
+ FILE* fp;
+ if ((errno = SafeFOpen(&fp, filename, "r")) != 0) PFATAL(filename);
size_t n;
while ( (n=fread(buffer, 1, kBufSize, fp)) > 0 ) {
if (ferror(fp)) PFATAL(filename);
@@ -1148,8 +1137,8 @@ string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval,
}
const string envname = string("FLAGS_") + string(flagname);
- const char* envval = getenv(envname.c_str());
- if (!envval) {
+ string envval;
+ if (!SafeGetEnv(envname.c_str(), envval)) {
if (errors_are_fatal) {
error_flags_[flagname] = (string(kError) + envname +
" not found in environment\n");
@@ -1158,15 +1147,14 @@ string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval,
}
// Avoid infinite recursion.
- if ((strcmp(envval, "fromenv") == 0) ||
- (strcmp(envval, "tryfromenv") == 0)) {
+ if (envval == "fromenv" || envval == "tryfromenv") {
error_flags_[flagname] =
StringPrintf("%sinfinite recursion on environment flag '%s'\n",
- kError, envval);
+ kError, envval.c_str());
continue;
}
- msg += ProcessSingleOptionLocked(flag, envval, set_mode);
+ msg += ProcessSingleOptionLocked(flag, envval.c_str(), set_mode);
}
return msg;
}
@@ -1318,13 +1306,12 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked(
// We try matching both against the full argv0 and basename(argv0)
if (glob == ProgramInvocationName() // small optimization
|| glob == ProgramInvocationShortName()
-#ifdef HAVE_FNMATCH_H
- || fnmatch(glob.c_str(),
- ProgramInvocationName(),
- FNM_PATHNAME) == 0
- || fnmatch(glob.c_str(),
- ProgramInvocationShortName(),
- FNM_PATHNAME) == 0
+#if defined(HAVE_FNMATCH_H)
+ || fnmatch(glob.c_str(), ProgramInvocationName(), FNM_PATHNAME) == 0
+ || fnmatch(glob.c_str(), ProgramInvocationShortName(), FNM_PATHNAME) == 0
+#elif defined(HAVE_SHLWAPI_H)
+ || PathMatchSpec(glob.c_str(), ProgramInvocationName())
+ || PathMatchSpec(glob.c_str(), ProgramInvocationShortName())
#endif
) {
flags_are_relevant = true;
@@ -1346,14 +1333,15 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked(
template<typename T>
T GetFromEnv(const char *varname, const char* type, T dflt) {
- const char* const valstr = getenv(varname);
- if (!valstr)
- return dflt;
- FlagValue ifv(new T, type, true);
- if (!ifv.ParseFrom(valstr))
- ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n",
- varname, valstr);
- return OTHER_VALUE_AS(ifv, T);
+ std::string valstr;
+ if (SafeGetEnv(varname, valstr)) {
+ FlagValue ifv(new T, type, true);
+ if (!ifv.ParseFrom(valstr.c_str())) {
+ ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n",
+ varname, valstr.c_str());
+ }
+ return OTHER_VALUE_AS(ifv, T);
+ } else return dflt;
}
bool AddFlagValidator(const void* flag_ptr, ValidateFnProto validate_fn_proto) {
@@ -1765,8 +1753,8 @@ bool ReadFlagsFromString(const string& flagfilecontents,
// TODO(csilvers): nix prog_name in favor of ProgramInvocationShortName()
bool AppendFlagsIntoFile(const string& filename, const char *prog_name) {
- FILE *fp = fopen(filename.c_str(), "a");
- if (!fp) {
+ FILE *fp;
+ if (SafeFOpen(&fp, filename.c_str(), "a") != 0) {
return false;
}
@@ -1824,10 +1812,18 @@ uint64 Uint64FromEnv(const char *v, uint64 dflt) {
double DoubleFromEnv(const char *v, double dflt) {
return GetFromEnv(v, "double", dflt);
}
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4996) // ignore getenv security warning
+#endif
const char *StringFromEnv(const char *varname, const char *dflt) {
const char* const val = getenv(varname);
return val ? val : dflt;
}
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
// --------------------------------------------------------------------
@@ -1957,4 +1953,5 @@ void ShutDownCommandLineFlags() {
FlagRegistry::DeleteGlobalRegistry();
}
-_END_GOOGLE_NAMESPACE_
+
+} // namespace GFLAGS_NAMESPACE
diff --git a/extern/libmv/third_party/gflags/gflags/gflags.h b/extern/libmv/third_party/gflags/gflags/gflags.h
index e69812c8c38..797a54cac52 100644
--- a/extern/libmv/third_party/gflags/gflags/gflags.h
+++ b/extern/libmv/third_party/gflags/gflags/gflags.h
@@ -75,21 +75,26 @@
// other thread is writing to the variable or calling non-const
// methods of this class.
-#ifndef BASE_COMMANDLINEFLAGS_H_
-#define BASE_COMMANDLINEFLAGS_H_
+#ifndef GFLAGS_GFLAGS_H_
+#define GFLAGS_GFLAGS_H_
#include <string>
#include <vector>
-#include "gflags_declare.h" // IWYU pragma: export
-namespace google {
-//
-// NOTE: all functions below MUST have an explicit 'extern' before
-// them. Our automated opensourcing tools use this as a signal to do
-// appropriate munging for windows, which needs to add GFLAGS_DLL_DECL.
-//
-#define GFLAGS_DLL_DECL /* rewritten to be non-empty in windows dir */
-#define GFLAGS_DLL_DEFINE_FLAG /* rewritten to be non-empty in windows dir */
+#include "gflags_declare.h" // IWYU pragma: export
+
+
+// We always want to export variables defined in user code
+#ifndef GFLAGS_DLL_DEFINE_FLAG
+# if 0 && defined(_MSC_VER)
+# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
+# else
+# define GFLAGS_DLL_DEFINE_FLAG
+# endif
+#endif
+
+
+namespace gflags {
// --------------------------------------------------------------------
@@ -121,19 +126,17 @@ namespace google {
// Returns true if successfully registered, false if not (because the
// first argument doesn't point to a command-line flag, or because a
// validator is already registered for this flag).
-extern bool RegisterFlagValidator(const bool* flag,
- bool (*validate_fn)(const char*, bool));
-extern bool RegisterFlagValidator(const int32* flag,
- bool (*validate_fn)(const char*, int32));
-extern bool RegisterFlagValidator(const int64* flag,
- bool (*validate_fn)(const char*, int64));
-extern bool RegisterFlagValidator(const uint64* flag,
- bool (*validate_fn)(const char*, uint64));
-extern bool RegisterFlagValidator(const double* flag,
- bool (*validate_fn)(const char*, double));
-extern bool RegisterFlagValidator(const std::string* flag,
- bool (*validate_fn)(const char*,
- const std::string&));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&));
+
+// Convenience macro for the registration of a flag validator
+#define DEFINE_validator(name, validator) \
+ static const bool name##_validator_registered = \
+ gflags::RegisterFlagValidator(&FLAGS_##name, validator)
// --------------------------------------------------------------------
@@ -146,19 +149,20 @@ extern bool RegisterFlagValidator(const std::string* flag,
// In addition to accessing flags, you can also access argv[0] (the program
// name) and argv (the entire commandline), which we sock away a copy of.
// These variables are static, so you should only set them once.
-
-struct GFLAGS_DLL_DECL CommandLineFlagInfo {
+//
+// No need to export this data only structure from DLL, avoiding VS warning 4251.
+struct CommandLineFlagInfo {
std::string name; // the name of the flag
std::string type; // the type of the flag: int32, etc
std::string description; // the "help text" associated with the flag
std::string current_value; // the current value, as a string
std::string default_value; // the default value, as a string
std::string filename; // 'cleaned' version of filename holding the flag
- bool has_validator_fn; // true if RegisterFlagValidator called on this flag
- bool is_default; // true if the flag has the default value and
- // has not been set explicitly from the cmdline
- // or via SetCommandLineOption
- const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
+ bool has_validator_fn; // true if RegisterFlagValidator called on this flag
+ bool is_default; // true if the flag has the default value and
+ // has not been set explicitly from the cmdline
+ // or via SetCommandLineOption
+ const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
};
// Using this inside of a validator is a recipe for a deadlock.
@@ -166,34 +170,34 @@ struct GFLAGS_DLL_DECL CommandLineFlagInfo {
// call validators during ParseAllFlags.
// Also make sure then to uncomment the corresponding unit test in
// gflags_unittest.sh
-extern void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
+extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
// These two are actually defined in gflags_reporting.cc.
-extern void ShowUsageWithFlags(const char *argv0); // what --help does
-extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
+extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does
+extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
// Create a descriptive string for a flag.
// Goes to some trouble to make pretty line breaks.
-extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
+extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
// Thread-hostile; meant to be called before any threads are spawned.
-extern void SetArgv(int argc, const char** argv);
+extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
// The following functions are thread-safe as long as SetArgv() is
// only called before any threads start.
-extern const std::vector<std::string>& GetArgvs();
-extern const char* GetArgv(); // all of argv as a string
-extern const char* GetArgv0(); // only argv0
-extern uint32 GetArgvSum(); // simple checksum of argv
-extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
-extern const char* ProgramInvocationShortName(); // basename(argv0)
+extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
+extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string
+extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0
+extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv
+extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
+extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0)
// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
// called before any threads start.
-extern const char* ProgramUsage(); // string set by SetUsageMessage()
+extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage()
// VersionString() is thread-safe as long as SetVersionString() is only
// called before any threads start.
-extern const char* VersionString(); // string set by SetVersionString()
+extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString()
@@ -207,17 +211,16 @@ extern const char* VersionString(); // string set by SetVersionString()
// Return true iff the flagname was found.
// OUTPUT is set to the flag's value, or unchanged if we return false.
-extern bool GetCommandLineOption(const char* name, std::string* OUTPUT);
+extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT);
// Return true iff the flagname was found. OUTPUT is set to the flag's
// CommandLineFlagInfo or unchanged if we return false.
-extern bool GetCommandLineFlagInfo(const char* name,
- CommandLineFlagInfo* OUTPUT);
+extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT);
// Return the CommandLineFlagInfo of the flagname. exit() if name not found.
// Example usage, to check if a flag's value is currently the default value:
// if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
-extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
+extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
enum GFLAGS_DLL_DECL FlagSettingMode {
// update the flag's value (can call this multiple times).
@@ -239,9 +242,8 @@ enum GFLAGS_DLL_DECL FlagSettingMode {
// non-empty else.
// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
-extern std::string SetCommandLineOption(const char* name, const char* value);
-extern std::string SetCommandLineOptionWithMode(const char* name, const char* value,
- FlagSettingMode set_mode);
+extern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value);
+extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode);
// --------------------------------------------------------------------
@@ -262,8 +264,8 @@ extern std::string SetCommandLineOptionWithMode(const char* name, const char* va
// // without worrying about restoring the FLAG values.
// }
//
-// Note: This class is marked with ATTRIBUTE_UNUSED because all the
-// work is done in the constructor and destructor, so in the standard
+// Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all
+// the work is done in the constructor and destructor, so in the standard
// usage example above, the compiler would complain that it's an
// unused variable.
//
@@ -282,27 +284,23 @@ class GFLAGS_DLL_DECL FlagSaver {
FlagSaver(const FlagSaver&); // no copying!
void operator=(const FlagSaver&);
-}
-#ifndef _MSC_VER
-__attribute__ ((unused))
-#endif
-;
+};
// --------------------------------------------------------------------
// Some deprecated or hopefully-soon-to-be-deprecated functions.
// This is often used for logging. TODO(csilvers): figure out a better way
-extern std::string CommandlineFlagsIntoString();
+extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
// Usually where this is used, a FlagSaver should be used instead.
-extern bool ReadFlagsFromString(const std::string& flagfilecontents,
- const char* prog_name,
- bool errors_are_fatal); // uses SET_FLAGS_VALUE
+extern GFLAGS_DLL_DECL
+bool ReadFlagsFromString(const std::string& flagfilecontents,
+ const char* prog_name,
+ bool errors_are_fatal); // uses SET_FLAGS_VALUE
// These let you manually implement --flagfile functionality.
// DEPRECATED.
-extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
-extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
- bool errors_are_fatal); // uses SET_FLAGS_VALUE
+extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
+extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE
// --------------------------------------------------------------------
@@ -313,12 +311,12 @@ extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name
// Otherwise, return the value. NOTE: for booleans, for true use
// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
-extern bool BoolFromEnv(const char *varname, bool defval);
-extern int32 Int32FromEnv(const char *varname, int32 defval);
-extern int64 Int64FromEnv(const char *varname, int64 defval);
-extern uint64 Uint64FromEnv(const char *varname, uint64 defval);
-extern double DoubleFromEnv(const char *varname, double defval);
-extern const char *StringFromEnv(const char *varname, const char *defval);
+extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval);
+extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval);
+extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval);
+extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval);
+extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval);
+extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval);
// --------------------------------------------------------------------
@@ -330,12 +328,12 @@ extern const char *StringFromEnv(const char *varname, const char *defval);
// SetUsageMessage(usage);
// Do not include commandline flags in the usage: we do that for you!
// Thread-hostile; meant to be called before any threads are spawned.
-extern void SetUsageMessage(const std::string& usage);
+extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
// Sets the version string, which is emitted with --version.
// For instance: SetVersionString("1.3");
// Thread-hostile; meant to be called before any threads are spawned.
-extern void SetVersionString(const std::string& version);
+extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
// Looks for flags in argv and parses them. Rearranges argv to put
@@ -345,7 +343,7 @@ extern void SetVersionString(const std::string& version);
// of the first non-flag argument.
// See top-of-file for more details on this function.
#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
-extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
+extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
#endif
@@ -359,18 +357,18 @@ extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
// defined more than once in the command line or flag file, the last
// definition is used. Returns the index (into argv) of the first
// non-flag argument. (If remove_flags is true, will always return 1.)
-extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
- bool remove_flags);
+extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags);
+
// This is actually defined in gflags_reporting.cc.
// This function is misnamed (it also handles --version, etc.), but
// it's too late to change that now. :-(
-extern void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
+extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
// Allow command line reparsing. Disables the error normally
// generated when an unknown flag is found, since it may be found in a
// later parse. Thread-hostile; meant to be called before any threads
// are spawned.
-extern void AllowCommandLineReparsing();
+extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
// Reparse the flags that have not yet been recognized. Only flags
// registered since the last parse will be recognized. Any flag value
@@ -378,7 +376,7 @@ extern void AllowCommandLineReparsing();
// separate command line argument that follows the flag argument.
// Intended for handling flags from dynamically loaded libraries,
// since their flags are not registered until they are loaded.
-extern void ReparseCommandLineNonHelpFlags();
+extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
// Clean up memory allocated by flags. This is only needed to reduce
// the quantity of "potentially leaked" reports emitted by memory
@@ -389,7 +387,7 @@ extern void ReparseCommandLineNonHelpFlags();
// called will have unexpected consequences. This is not safe to run
// when multiple threads might be running: the function is
// thread-hostile.
-extern void ShutDownCommandLineFlags();
+extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
// --------------------------------------------------------------------
@@ -420,7 +418,7 @@ extern void ShutDownCommandLineFlags();
// directly. The idea is that DEFINE puts the flag in the weird
// namespace, and DECLARE imports the flag from there into the current
// namespace. The net result is to force people to use DECLARE to get
-// access to a flag, rather than saying "extern bool FLAGS_whatever;"
+// access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;"
// or some such instead. We want this so we can put extra
// functionality (like sanity-checking) in DECLARE if we want, and
// make sure it is picked up everywhere.
@@ -441,16 +439,18 @@ class GFLAGS_DLL_DECL FlagRegisterer {
// binary file. This can reduce the size of the resulting binary
// somewhat, and may also be useful for security reasons.
-extern const char kStrippedFlagHelp[];
+extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
+
+
+} // namespace gflags
-}
#ifndef SWIG // In swig, ignore the main flag declarations
#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
// Need this construct to avoid the 'defined but not used' warning.
#define MAYBE_STRIPPED_HELP(txt) \
- (false ? (txt) : ::google::kStrippedFlagHelp)
+ (false ? (txt) : gflags::kStrippedFlagHelp)
#else
#define MAYBE_STRIPPED_HELP(txt) txt
#endif
@@ -472,7 +472,7 @@ extern const char kStrippedFlagHelp[];
/* We always want to export defined variables, dll or no */ \
GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
type FLAGS_no##name = FLAGS_nono##name; \
- static ::google::FlagRegisterer o_##name( \
+ static gflags::FlagRegisterer o_##name( \
#name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
&FLAGS_##name, &FLAGS_no##name); \
} \
@@ -505,15 +505,15 @@ GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
DEFINE_VARIABLE(bool, B, name, val, txt)
#define DEFINE_int32(name, val, txt) \
- DEFINE_VARIABLE(::google::int32, I, \
+ DEFINE_VARIABLE(gflags::int32, I, \
name, val, txt)
#define DEFINE_int64(name, val, txt) \
- DEFINE_VARIABLE(::google::int64, I64, \
+ DEFINE_VARIABLE(gflags::int64, I64, \
name, val, txt)
#define DEFINE_uint64(name,val, txt) \
- DEFINE_VARIABLE(::google::uint64, U64, \
+ DEFINE_VARIABLE(gflags::uint64, U64, \
name, val, txt)
#define DEFINE_double(name, val, txt) \
@@ -554,7 +554,7 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
clstring* const FLAGS_no##name = ::fLS:: \
dont_pass0toDEFINE_string(s_##name[0].s, \
val); \
- static ::google::FlagRegisterer o_##name( \
+ static gflags::FlagRegisterer o_##name( \
#name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
@@ -565,4 +565,4 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
#endif // SWIG
-#endif // BASE_COMMANDLINEFLAGS_H_
+#endif // GFLAGS_GFLAGS_H_
diff --git a/extern/libmv/third_party/gflags/gflags/gflags_completions.h b/extern/libmv/third_party/gflags/gflags/gflags_completions.h
index 37f5b0ec2cf..2fa0db6d48a 100644
--- a/extern/libmv/third_party/gflags/gflags/gflags_completions.h
+++ b/extern/libmv/third_party/gflags/gflags/gflags_completions.h
@@ -109,22 +109,13 @@ $ complete -o bashdefault -o default -o nospace -C \
// produce the expected completion output.
-#ifndef BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
-#define BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
+#ifndef GFLAGS_COMPLETIONS_H_
+#define GFLAGS_COMPLETIONS_H_
-// Annoying stuff for windows -- makes sure clients can import these functions
-//
-// NOTE: all functions below MUST have an explicit 'extern' before
-// them. Our automated opensourcing tools use this as a signal to do
-// appropriate munging for windows, which needs to add GFLAGS_DLL_DECL.
-//
-#define GFLAGS_DLL_DECL /* rewritten to be non-empty in windows dir */
-
-
-namespace google {
+namespace gflags {
extern void HandleCommandLineCompletions(void);
}
-#endif // BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
+#endif // GFLAGS_COMPLETIONS_H_
diff --git a/extern/libmv/third_party/gflags/gflags/gflags_declare.h b/extern/libmv/third_party/gflags/gflags/gflags_declare.h
index 503b686657f..335c389b610 100644
--- a/extern/libmv/third_party/gflags/gflags/gflags_declare.h
+++ b/extern/libmv/third_party/gflags/gflags/gflags_declare.h
@@ -34,43 +34,64 @@
// This is the file that should be included by any file which declares
// command line flag.
-#ifndef BASE_COMMANDLINEFLAGS_DECLARE_H_
-#define BASE_COMMANDLINEFLAGS_DECLARE_H_
-
-#include <string>
-#if 1
-#include <stdint.h> // the normal place uint16_t is defined
+#ifndef GFLAGS_DECLARE_H_
+#define GFLAGS_DECLARE_H_
+
+// ---------------------------------------------------------------------------
+// Windows DLL import/export.
+
+// We always want to import the symbols of the gflags library
+#ifndef GFLAGS_DLL_DECL
+# if 0 && defined(_MSC_VER)
+# define GFLAGS_DLL_DECL __declspec(dllimport)
+# else
+# define GFLAGS_DLL_DECL
+# endif
#endif
-#if 1
-#include <sys/types.h> // the normal place u_int16_t is defined
+
+// We always want to import variables declared in user code
+#ifndef GFLAGS_DLL_DECLARE_FLAG
+# if 0 && defined(_MSC_VER)
+# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
+# else
+# define GFLAGS_DLL_DECLARE_FLAG
+# endif
#endif
+
+// ---------------------------------------------------------------------------
+// Flag types
+#include <string>
#if 1
-#include <inttypes.h> // a third place for uint16_t or u_int16_t
+# include <stdint.h> // the normal place uint32_t is defined
+#elif 1
+# include <sys/types.h> // the normal place u_int32_t is defined
+#elif 1
+# include <inttypes.h> // a third place for uint32_t or u_int32_t
#endif
-namespace google {
-#if defined(__GNUC__) || defined(__MINGW32__) // the C99 format
-typedef int32_t int32;
-typedef uint32_t uint32;
-typedef int64_t int64;
-typedef uint64_t uint64;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) // the BSD format
-typedef int32_t int32;
-typedef u_int32_t uint32;
-typedef int64_t int64;
-typedef u_int64_t uint64;
-#elif defined(_MSC_VER) // the windows (vc7) format
-typedef __int32 int32;
+namespace gflags {
+
+#if 1 // C99
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#elif 0 // BSD
+typedef int32_t int32;
+typedef u_int32_t uint32;
+typedef int64_t int64;
+typedef u_int64_t uint64;
+#elif 0 // Windows
+typedef __int32 int32;
typedef unsigned __int32 uint32;
-typedef __int64 int64;
+typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
-#error Do not know how to define a 32-bit integer quantity on your system
+# error Do not know how to define a 32-bit integer quantity on your system
#endif
-}
+} // namespace gflags
-#define GFLAGS_DLL_DECLARE_FLAG /* rewritten to be non-empty in windows dir */
namespace fLS {
@@ -80,7 +101,8 @@ namespace fLS {
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
-}
+} // namespace fLS
+
#define DECLARE_VARIABLE(type, shorttype, name) \
/* We always want to import declared variables, dll or no */ \
@@ -91,22 +113,24 @@ typedef std::string clstring;
DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(name) \
- DECLARE_VARIABLE(::google::int32, I, name)
+ DECLARE_VARIABLE(::gflags::int32, I, name)
#define DECLARE_int64(name) \
- DECLARE_VARIABLE(::google::int64, I64, name)
+ DECLARE_VARIABLE(::gflags::int64, I64, name)
#define DECLARE_uint64(name) \
- DECLARE_VARIABLE(::google::uint64, U64, name)
+ DECLARE_VARIABLE(::gflags::uint64, U64, name)
#define DECLARE_double(name) \
DECLARE_VARIABLE(double, D, name)
#define DECLARE_string(name) \
- namespace fLS { \
- using ::fLS::clstring; \
+ /* We always want to import declared variables, dll or no */ \
+ namespace fLS { \
+ using ::fLS::clstring; \
extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
- } \
+ } \
using fLS::FLAGS_##name
-#endif // BASE_COMMANDLINEFLAGS_DECLARE_H_
+
+#endif // GFLAGS_DECLARE_H_
diff --git a/extern/libmv/third_party/gflags/gflags_completions.cc b/extern/libmv/third_party/gflags/gflags_completions.cc
index f46a2e0814e..3a476230ff9 100644
--- a/extern/libmv/third_party/gflags/gflags_completions.cc
+++ b/extern/libmv/third_party/gflags/gflags_completions.cc
@@ -48,6 +48,7 @@
#include "config.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // for strlen
@@ -57,17 +58,13 @@
#include <utility>
#include <vector>
-#include "gflags/gflags_completions.h"
-#include "gflags/gflags.h"
+#include "gflags.h"
#include "util.h"
using std::set;
using std::string;
using std::vector;
-#ifndef PATH_SEPARATOR
-#define PATH_SEPARATOR '/'
-#endif
DEFINE_string(tab_completion_word, "",
"If non-empty, HandleCommandLineCompletions() will hijack the "
@@ -76,7 +73,9 @@ DEFINE_string(tab_completion_word, "",
DEFINE_int32(tab_completion_columns, 80,
"Number of columns to use in output for tab completion");
-_START_GOOGLE_NAMESPACE_
+
+namespace GFLAGS_NAMESPACE {
+
namespace {
// Function prototypes and Type forward declarations. Code may be
@@ -766,4 +765,5 @@ void HandleCommandLineCompletions(void) {
gflags_exitfunc(0);
}
-_END_GOOGLE_NAMESPACE_
+
+} // namespace GFLAGS_NAMESPACE
diff --git a/extern/libmv/third_party/gflags/gflags_reporting.cc b/extern/libmv/third_party/gflags/gflags_reporting.cc
index c74bcc8d762..9cc41a7488c 100644
--- a/extern/libmv/third_party/gflags/gflags_reporting.cc
+++ b/extern/libmv/third_party/gflags/gflags_reporting.cc
@@ -48,40 +48,32 @@
// called after all flag-values have been assigned, that is, after
// parsing the command-line.
-#include "config.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <string>
#include <vector>
-#include "gflags/gflags.h"
-#include "gflags/gflags_completions.h"
+
+#include "config.h"
+#include "gflags.h"
+#include "gflags_completions.h"
#include "util.h"
-#ifndef PATH_SEPARATOR
-#define PATH_SEPARATOR '/'
-#endif
// The 'reporting' flags. They all call gflags_exitfunc().
-DEFINE_bool(help, false,
- "show help on all flags [tip: all flags can have two dashes]");
-DEFINE_bool(helpfull, false,
- "show help on all flags -- same as -help");
-DEFINE_bool(helpshort, false,
- "show help on only the main module for this program");
-DEFINE_string(helpon, "",
- "show help on the modules named by this flag value");
-DEFINE_string(helpmatch, "",
- "show help on modules whose name contains the specified substr");
-DEFINE_bool(helppackage, false,
- "show help on all modules in the main package");
-DEFINE_bool(helpxml, false,
- "produce an xml version of help");
-DEFINE_bool(version, false,
- "show version and build info and exit");
-
-_START_GOOGLE_NAMESPACE_
+DEFINE_bool (help, false, "show help on all flags [tip: all flags can have two dashes]");
+DEFINE_bool (helpfull, false, "show help on all flags -- same as -help");
+DEFINE_bool (helpshort, false, "show help on only the main module for this program");
+DEFINE_string(helpon, "", "show help on the modules named by this flag value");
+DEFINE_string(helpmatch, "", "show help on modules whose name contains the specified substr");
+DEFINE_bool (helppackage, false, "show help on all modules in the main package");
+DEFINE_bool (helpxml, false, "produce an xml version of help");
+DEFINE_bool (version, false, "show version and build info and exit");
+
+
+namespace GFLAGS_NAMESPACE {
+
using std::string;
using std::vector;
@@ -254,7 +246,7 @@ static bool FileMatchesSubstring(const string& filename,
// the string to be at the beginning of a directory component.
// That should match the first directory component as well, so
// we allow '/foo' to match a filename of 'foo'.
- if (!target->empty() && (*target)[0] == '/' &&
+ if (!target->empty() && (*target)[0] == PATH_SEPARATOR &&
strncmp(filename.c_str(), target->c_str() + 1,
strlen(target->c_str() + 1)) == 0)
return true;
@@ -360,7 +352,8 @@ static void ShowVersion() {
static void AppendPrognameStrings(vector<string>* substrings,
const char* progname) {
- string r("/");
+ string r("");
+ r += PATH_SEPARATOR;
r += progname;
substrings->push_back(r + ".");
substrings->push_back(r + "-main.");
@@ -395,7 +388,7 @@ void HandleCommandLineHelpFlags() {
gflags_exitfunc(1);
} else if (!FLAGS_helpon.empty()) {
- string restrict = "/" + FLAGS_helpon + ".";
+ string restrict = PATH_SEPARATOR + FLAGS_helpon + ".";
ShowUsageWithFlagsRestrict(progname, restrict.c_str());
gflags_exitfunc(1);
@@ -417,7 +410,7 @@ void HandleCommandLineHelpFlags() {
++flag) {
if (!FileMatchesSubstring(flag->filename, substrings))
continue;
- const string package = Dirname(flag->filename) + "/";
+ const string package = Dirname(flag->filename) + PATH_SEPARATOR;
if (package != last_package) {
ShowUsageWithFlagsRestrict(progname, package.c_str());
VLOG(7) << "Found package: " << package;
@@ -444,4 +437,5 @@ void HandleCommandLineHelpFlags() {
}
}
-_END_GOOGLE_NAMESPACE_
+
+} // namespace GFLAGS_NAMESPACE
diff --git a/extern/libmv/third_party/gflags/mutex.h b/extern/libmv/third_party/gflags/mutex.h
index 7c3c060a043..0bdd9d5f2a5 100644
--- a/extern/libmv/third_party/gflags/mutex.h
+++ b/extern/libmv/third_party/gflags/mutex.h
@@ -32,11 +32,6 @@
// A simple mutex wrapper, supporting locks and read-write locks.
// You should assume the locks are *not* re-entrant.
//
-// To use: you should define the following macros in your configure.ac:
-// ACX_PTHREAD
-// AC_RWLOCK
-// The latter is defined in ../autoconf.
-//
// This class is meant to be internal-only and should be wrapped by an
// internal namespace. Before you use this module, please give the
// name of your internal namespace for this module. Or, if you want
@@ -108,14 +103,14 @@
// weird to a Mutex's memory after it is destroyed, but for a
// static global variable, that's pretty safe.
-#ifndef GOOGLE_MUTEX_H_
-#define GOOGLE_MUTEX_H_
+#ifndef GFLAGS_MUTEX_H_
+#define GFLAGS_MUTEX_H_
-#include "config.h" // to figure out pthreads support
+#include "gflags_declare.h" // to figure out pthreads support
#if defined(NO_THREADS)
- typedef int MutexType; // to keep a lock-count
-#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+ typedef int MutexType; // to keep a lock-count
+#elif defined(OS_WINDOWS)
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN // We only need minimal includes
# endif
@@ -232,7 +227,7 @@ bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; }
void Mutex::ReaderLock() { assert(++mutex_ > 0); }
void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
-#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+#elif defined(OS_WINDOWS)
Mutex::Mutex() : destroy_(true) {
InitializeCriticalSection(&mutex_);
@@ -353,4 +348,4 @@ using namespace MUTEX_NAMESPACE;
#undef MUTEX_NAMESPACE
-#endif /* #define GOOGLE_MUTEX_H__ */
+#endif /* #define GFLAGS_MUTEX_H__ */
diff --git a/extern/libmv/third_party/gflags/util.h b/extern/libmv/third_party/gflags/util.h
index 8e2b1b89525..366e1be22e2 100644
--- a/extern/libmv/third_party/gflags/util.h
+++ b/extern/libmv/third_party/gflags/util.h
@@ -34,48 +34,53 @@
#ifndef GFLAGS_UTIL_H_
#define GFLAGS_UTIL_H_
-#include <assert.h>
#include "config.h"
+
+#include <assert.h>
+#include <config.h>
#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
+# include <inttypes.h>
#endif
#include <stdarg.h> // for va_*
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
+#include <errno.h>
#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif // for mkdir()
+# include <sys/stat.h> // for mkdir
+#endif
+
+
+namespace GFLAGS_NAMESPACE {
-_START_GOOGLE_NAMESPACE_
// This is used for unittests for death-testing. It is defined in gflags.cc.
extern GFLAGS_DLL_DECL void (*gflags_exitfunc)(int);
-// Work properly if either strtoll or strtoq is on this system
-#ifdef HAVE_STRTOLL
-# define strto64 strtoll
-# define strtou64 strtoull
-#elif HAVE_STRTOQ
-# define strto64 strtoq
-# define strtou64 strtouq
-#else
+// Work properly if either strtoll or strtoq is on this system.
+#if defined(strtoll) || defined(HAVE_STRTOLL)
+# define strto64 strtoll
+# define strtou64 strtoull
+#elif defined(HAVE_STRTOQ)
+# define strto64 strtoq
+# define strtou64 strtouq
// Neither strtoll nor strtoq are defined. I hope strtol works!
-# define strto64 strtol
-# define strtou64 strtoul
+#else
+# define strto64 strtol
+# define strtou64 strtoul
#endif
-// If we have inttypes.h, it will have defined PRId32/etc for us. If
-// not, take our best guess.
+// If we have inttypes.h, it will have defined PRId32/etc for us.
+// If not, take our best guess.
#ifndef PRId32
-# define PRId32 "d"
+# define PRId32 "d"
#endif
#ifndef PRId64
-# define PRId64 "lld"
+# define PRId64 "lld"
#endif
#ifndef PRIu64
-# define PRIu64 "llu"
+# define PRIu64 "llu"
#endif
typedef signed char int8;
@@ -230,37 +235,36 @@ class Test {};
#if defined(__MINGW32__)
#include <io.h>
inline void MakeTmpdir(std::string* path) {
+ if (!path->empty()) {
+ path->append("/gflags_unittest_testdir");
+ int err = mkdir(path->c_str());
+ if (err == 0 || errno == EEXIST) return;
+ }
// I had trouble creating a directory in /tmp from mingw
- *path = "./gflags_unittest_testdir";
- mkdir(path->c_str()); // mingw has a weird one-arg mkdir
+ *path = "./gflags_unittest";
+ mkdir(path->c_str());
}
#elif defined(_MSC_VER)
#include <direct.h>
-#include <windows.h>
inline void MakeTmpdir(std::string* path) {
+ if (!path->empty()) {
+ int err = _mkdir(path->c_str());
+ if (err == 0 || errno == EEXIST) return;
+ }
char tmppath_buffer[1024];
int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer);
assert(tmppath_len > 0 && tmppath_len < sizeof(tmppath_buffer));
assert(tmppath_buffer[tmppath_len - 1] == '\\'); // API guarantees it
- *path = std::string(tmppath_buffer) + "gflags_unittest_testdir";
+ *path = std::string(tmppath_buffer) + "gflags_unittest";
_mkdir(path->c_str());
}
-// Windows is missing random bits like strcasecmp, strtoll, strtoull, and
-// snprintf in the usual locations. Put them somewhere sensible.
-//
-// TODO(keir): Get the upstream Windows port and use that instead.
-#define snprintf _snprintf
-#undef strtoint64
-#define strtoint64 _strtoi64
-#undef strtouint64
-#define strtouint64 _strtoui64
-#define strcasecmp _stricmp
-#define va_copy(dst, src) ((dst) = (src))
-#define strto64 _strtoi64
-#define strtou64 _strtoui64
#else
inline void MakeTmpdir(std::string* path) {
- mkdir(path->c_str(), 0755);
+ if (!path->empty()) {
+ int err = mkdir(path->c_str(), 0755);
+ if (err == 0 || errno == EEXIST) return;
+ }
+ mkdir("/tmp/gflags_unittest", 0755);
}
#endif
@@ -278,7 +282,7 @@ inline void InternalStringPrintf(std::string* output, const char* format,
int bytes_written = vsnprintf(space, sizeof(space), format, backup_ap);
va_end(backup_ap);
- if ((bytes_written >= 0) && (bytes_written < sizeof(space))) {
+ if ((bytes_written >= 0) && (static_cast<size_t>(bytes_written) < sizeof(space))) {
output->append(space, bytes_written);
return;
}
@@ -334,6 +338,36 @@ inline std::string StringPrintf(const char* format, ...) {
return output;
}
-_END_GOOGLE_NAMESPACE_
+inline bool SafeGetEnv(const char *varname, std::string &valstr)
+{
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ char *val;
+ size_t sz;
+ if (_dupenv_s(&val, &sz, varname) != 0 || !val) return false;
+ valstr = val;
+ free(val);
+#else
+ const char * const val = getenv(varname);
+ if (!val) return false;
+ valstr = val;
+#endif
+ return true;
+}
+
+inline int SafeFOpen(FILE **fp, const char* fname, const char *mode)
+{
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ return fopen_s(fp, fname, mode);
+#else
+ assert(fp != NULL);
+ *fp = fopen(fname, mode);
+ // errno only guaranteed to be set on failure
+ return ((*fp == NULL) ? errno : 0);
+#endif
+}
+
+
+} // namespace GFLAGS_NAMESPACE
+
#endif // GFLAGS_UTIL_H_
diff --git a/extern/libmv/third_party/gflags/windows_port.cc b/extern/libmv/third_party/gflags/windows_port.cc
new file mode 100644
index 00000000000..1f40458e888
--- /dev/null
+++ b/extern/libmv/third_party/gflags/windows_port.cc
@@ -0,0 +1,71 @@
+/* Copyright (c) 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Craig Silverstein
+ */
+
+#ifndef _WIN32
+# error You should only be including windows/port.cc in a windows environment!
+#endif
+
+#include <string.h> // for strlen(), memset(), memcmp()
+#include <assert.h>
+#include <stdarg.h> // for va_list, va_start, va_end
+#include <windows.h>
+
+#include "windows_port.h"
+
+// These call the windows _vsnprintf, but always NUL-terminate.
+#if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4996) // ignore _vsnprintf security warning
+#endif
+int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
+ if (size == 0) // not even room for a \0?
+ return -1; // not what C99 says to do, but what windows does
+ str[size-1] = '\0';
+ return _vsnprintf(str, size-1, format, ap);
+}
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+int snprintf(char *str, size_t size, const char *format, ...) {
+ int r;
+ va_list ap;
+ va_start(ap, format);
+ r = vsnprintf(str, size, format, ap);
+ va_end(ap);
+ return r;
+}
+
+#endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
diff --git a/extern/libmv/third_party/gflags/windows_port.h b/extern/libmv/third_party/gflags/windows_port.h
new file mode 100644
index 00000000000..c8ff24f8f00
--- /dev/null
+++ b/extern/libmv/third_party/gflags/windows_port.h
@@ -0,0 +1,127 @@
+/* Copyright (c) 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Craig Silverstein
+ *
+ * These are some portability typedefs and defines to make it a bit
+ * easier to compile this code under VC++.
+ *
+ * Several of these are taken from glib:
+ * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
+ */
+
+#ifndef GFLAGS_WINDOWS_PORT_H_
+#define GFLAGS_WINDOWS_PORT_H_
+
+#include "config.h"
+
+// This must be defined before the windows.h is included.
+// It's needed for mutex.h, to give access to the TryLock method.
+# if !defined(_WIN32_WINNT) && !(defined( __MINGW32__) || defined(__MINGW64__))
+# define _WIN32_WINNT 0x0400
+# endif
+// We always want minimal includes
+#ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <direct.h> /* for mkdir */
+#include <stdlib.h> /* for _putenv, getenv */
+#include <stdio.h> /* need this to override stdio's snprintf, also defines _unlink used by unit tests */
+#include <stdarg.h> /* util.h uses va_copy */
+#include <string.h> /* for _stricmp and _strdup */
+
+/* We can't just use _vsnprintf and _snprintf as drop-in-replacements,
+ * because they don't always NUL-terminate. :-( We also can't use the
+ * name vsnprintf, since windows defines that (but not snprintf (!)).
+ */
+#if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
+extern GFLAGS_DLL_DECL int snprintf(char *str, size_t size,
+ const char *format, ...);
+extern int GFLAGS_DLL_DECL safe_vsnprintf(char *str, size_t size,
+ const char *format, va_list ap);
+#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap)
+#define va_copy(dst, src) (dst) = (src)
+#endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4996) // ignore getenv security warning
+#endif
+inline void setenv(const char* name, const char* value, int) {
+ // In windows, it's impossible to set a variable to the empty string.
+ // We handle this by setting it to "0" and the NUL-ing out the \0.
+ // That is, we putenv("FOO=0") and then find out where in memory the
+ // putenv wrote "FOO=0", and change it in-place to "FOO=\0".
+ // c.f. http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/environ.cpp?r1=611451&r2=637508&pathrev=637508
+ static const char* const kFakeZero = "0";
+ if (*value == '\0')
+ value = kFakeZero;
+ // Apparently the semantics of putenv() is that the input
+ // must live forever, so we leak memory here. :-(
+ const size_t nameval_len = strlen(name) + 1 + strlen(value) + 1;
+ char* nameval = reinterpret_cast<char*>(malloc(nameval_len));
+ snprintf(nameval, nameval_len, "%s=%s", name, value);
+ _putenv(nameval);
+ if (value == kFakeZero) {
+ nameval[nameval_len - 2] = '\0'; // works when putenv() makes no copy
+ if (*getenv(name) != '\0')
+ *getenv(name) = '\0'; // works when putenv() copies nameval
+ }
+}
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+#define strcasecmp _stricmp
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+#define strdup _strdup
+#define unlink _unlink
+#endif
+
+#define PRId32 "d"
+#define PRIu32 "u"
+#define PRId64 "I64d"
+#define PRIu64 "I64u"
+
+#if !defined(__MINGW32__) && !defined(__MINGW64__)
+#define strtoq _strtoi64
+#define strtouq _strtoui64
+#define strtoll _strtoi64
+#define strtoull _strtoui64
+#define atoll _atoi64
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+#endif /* GFLAGS_WINDOWS_PORT_H_ */
diff --git a/extern/libmv/third_party/glog/README.libmv b/extern/libmv/third_party/glog/README.libmv
index eb4b2ea3379..10e51fa6df4 100644
--- a/extern/libmv/third_party/glog/README.libmv
+++ b/extern/libmv/third_party/glog/README.libmv
@@ -1,7 +1,7 @@
Project: Google Logging
URL: http://code.google.com/p/google-glog/
License: New BSD
-Upstream version: 0.3.3, r139
+Upstream version: 0.3.3, r143
Local modifications:
* Added per-platform config.h files so no configuration-time
checks for functions and so are needed.
diff --git a/extern/libmv/third_party/glog/src/demangle.cc b/extern/libmv/third_party/glog/src/demangle.cc
index 0daf30893b3..e858181a68f 100644
--- a/extern/libmv/third_party/glog/src/demangle.cc
+++ b/extern/libmv/third_party/glog/src/demangle.cc
@@ -167,7 +167,7 @@ static size_t StrLen(const char *str) {
// Returns true if "str" has at least "n" characters remaining.
static bool AtLeastNumCharsRemaining(const char *str, int n) {
for (int i = 0; i < n; ++i) {
- if (str == '\0') {
+ if (str[i] == '\0') {
return false;
}
}
@@ -223,9 +223,6 @@ static bool ParseTwoCharToken(State *state, const char *two_char_token) {
// Returns true and advances "mangled_cur" if we find any character in
// "char_class" at "mangled_cur" position.
static bool ParseCharClass(State *state, const char *char_class) {
- if (state->mangled_cur == '\0') {
- return false;
- }
const char *p = char_class;
for (; *p != '\0'; ++p) {
if (state->mangled_cur[0] == *p) {
diff --git a/extern/libmv/third_party/glog/src/logging.cc b/extern/libmv/third_party/glog/src/logging.cc
index 5e2ce61c9c9..75047353535 100644
--- a/extern/libmv/third_party/glog/src/logging.cc
+++ b/extern/libmv/third_party/glog/src/logging.cc
@@ -31,6 +31,7 @@
#include "utilities.h"
+#include <algorithm>
#include <assert.h>
#include <iomanip>
#include <string>
@@ -181,6 +182,10 @@ GLOG_DEFINE_string(log_backtrace_at, "",
#define PATH_SEPARATOR '/'
#ifndef HAVE_PREAD
+#if defined(OS_WINDOWS)
+#include <BaseTsd.h>
+#define ssize_t SSIZE_T
+#endif
static ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
off_t orig_offset = lseek(fd, 0, SEEK_CUR);
if (orig_offset == (off_t)-1)
diff --git a/extern/libmv/third_party/glog/src/symbolize.cc b/extern/libmv/third_party/glog/src/symbolize.cc
index 18bbccf3072..b25f7479d0d 100644
--- a/extern/libmv/third_party/glog/src/symbolize.cc
+++ b/extern/libmv/third_party/glog/src/symbolize.cc
@@ -45,6 +45,12 @@
// some functions which are not guaranteed to be so, such as memchr()
// and memmove(). We assume they are async-signal-safe.
//
+// Additional header can be specified by the GLOG_BUILD_CONFIG_INCLUDE
+// macro to add platform specific defines (e.g. OS_OPENBSD).
+
+#ifdef GLOG_BUILD_CONFIG_INCLUDE
+#include GLOG_BUILD_CONFIG_INCLUDE
+#endif // GLOG_BUILD_CONFIG_INCLUDE
#include "utilities.h"
@@ -74,6 +80,13 @@ void InstallSymbolizeCallback(SymbolizeCallback callback) {
g_symbolize_callback = callback;
}
+static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback =
+ NULL;
+void InstallSymbolizeOpenObjectFileCallback(
+ SymbolizeOpenObjectFileCallback callback) {
+ g_symbolize_open_object_file_callback = callback;
+}
+
// This function wraps the Demangle function to provide an interface
// where the input symbol is demangled in-place.
// To keep stack consumption low, we would like this function to not
@@ -95,11 +108,14 @@ _END_GOOGLE_NAMESPACE_
#if defined(__ELF__)
#include <dlfcn.h>
+#if defined(OS_OPENBSD)
+#include <sys/exec_elf.h>
+#else
#include <elf.h>
+#endif
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
-#include <link.h> // For ElfW() macro.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -123,7 +139,7 @@ _START_GOOGLE_NAMESPACE_
// success, return the number of bytes read. Otherwise, return -1.
static ssize_t ReadPersistent(const int fd, void *buf, const size_t count) {
SAFE_ASSERT(fd >= 0);
- SAFE_ASSERT(count >= 0 && count <= std::numeric_limits<ssize_t>::max());
+ SAFE_ASSERT(count <= std::numeric_limits<ssize_t>::max());
char *buf0 = reinterpret_cast<char *>(buf);
ssize_t num_bytes = 0;
while (num_bytes < count) {
@@ -326,31 +342,29 @@ static bool GetSymbolFromObjectFile(const int fd, uint64_t pc,
ElfW(Shdr) symtab, strtab;
// Consult a regular symbol table first.
- if (!GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
- SHT_SYMTAB, &symtab)) {
- return false;
- }
- if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
- symtab.sh_link * sizeof(symtab))) {
- return false;
- }
- if (FindSymbol(pc, fd, out, out_size, symbol_offset,
- &strtab, &symtab)) {
- return true; // Found the symbol in a regular symbol table.
+ if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
+ SHT_SYMTAB, &symtab)) {
+ if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
+ symtab.sh_link * sizeof(symtab))) {
+ return false;
+ }
+ if (FindSymbol(pc, fd, out, out_size, symbol_offset,
+ &strtab, &symtab)) {
+ return true; // Found the symbol in a regular symbol table.
+ }
}
// If the symbol is not found, then consult a dynamic symbol table.
- if (!GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
- SHT_DYNSYM, &symtab)) {
- return false;
- }
- if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
- symtab.sh_link * sizeof(symtab))) {
- return false;
- }
- if (FindSymbol(pc, fd, out, out_size, symbol_offset,
- &strtab, &symtab)) {
- return true; // Found the symbol in a dynamic symbol table.
+ if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
+ SHT_DYNSYM, &symtab)) {
+ if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
+ symtab.sh_link * sizeof(symtab))) {
+ return false;
+ }
+ if (FindSymbol(pc, fd, out, out_size, symbol_offset,
+ &strtab, &symtab)) {
+ return true; // Found the symbol in a dynamic symbol table.
+ }
}
return false;
@@ -481,13 +495,20 @@ static char *GetHex(const char *start, const char *end, uint64_t *hex) {
return const_cast<char *>(p);
}
-// Search for the object file (from /proc/self/maps) that contains
-// the specified pc. If found, open this file and return the file handle,
-// and also set start_address to the start address of where this object
-// file is mapped to in memory. Otherwise, return -1.
+// Searches for the object file (from /proc/self/maps) that contains
+// the specified pc. If found, sets |start_address| to the start address
+// of where this object file is mapped in memory, sets the module base
+// address into |base_address|, copies the object file name into
+// |out_file_name|, and attempts to open the object file. If the object
+// file is opened successfully, returns the file descriptor. Otherwise,
+// returns -1. |out_file_name_size| is the size of the file name buffer
+// (including the null-terminator).
static ATTRIBUTE_NOINLINE int
OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
- uint64_t &start_address) {
+ uint64_t &start_address,
+ uint64_t &base_address,
+ char *out_file_name,
+ int out_file_name_size) {
int object_fd;
// Open /proc/self/maps.
@@ -501,8 +522,10 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
// Iterate over maps and look for the map containing the pc. Then
// look into the symbol tables inside.
char buf[1024]; // Big enough for line of sane /proc/self/maps
+ int num_maps = 0;
LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf));
while (true) {
+ num_maps++;
const char *cursor;
const char *eol;
if (!reader.ReadLine(&cursor, &eol)) { // EOF or malformed line.
@@ -552,14 +575,35 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
}
++cursor; // Skip ' '.
- // Skip to file name. "cursor" now points to file offset. We need to
- // skip at least three spaces for file offset, dev, and inode.
+ // Read file offset.
+ uint64_t file_offset;
+ cursor = GetHex(cursor, eol, &file_offset);
+ if (cursor == eol || *cursor != ' ') {
+ return -1; // Malformed line.
+ }
+ ++cursor; // Skip ' '.
+
+ // Don't subtract 'start_address' from the first entry:
+ // * If a binary is compiled w/o -pie, then the first entry in
+ // process maps is likely the binary itself (all dynamic libs
+ // are mapped higher in address space). For such a binary,
+ // instruction offset in binary coincides with the actual
+ // instruction address in virtual memory (as code section
+ // is mapped to a fixed memory range).
+ // * If a binary is compiled with -pie, all the modules are
+ // mapped high at address space (in particular, higher than
+ // shadow memory of the tool), so the module can't be the
+ // first entry.
+ base_address = ((num_maps == 1) ? 0U : start_address) - file_offset;
+
+ // Skip to file name. "cursor" now points to dev. We need to
+ // skip at least two spaces for dev and inode.
int num_spaces = 0;
while (cursor < eol) {
if (*cursor == ' ') {
++num_spaces;
- } else if (num_spaces >= 3) {
- // The first non-space character after skipping three spaces
+ } else if (num_spaces >= 2) {
+ // The first non-space character after skipping two spaces
// is the beginning of the file name.
break;
}
@@ -572,12 +616,105 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
// Finally, "cursor" now points to file name of our interest.
NO_INTR(object_fd = open(cursor, O_RDONLY));
if (object_fd < 0) {
+ // Failed to open object file. Copy the object file name to
+ // |out_file_name|.
+ strncpy(out_file_name, cursor, out_file_name_size);
+ // Making sure |out_file_name| is always null-terminated.
+ out_file_name[out_file_name_size - 1] = '\0';
return -1;
}
return object_fd;
}
}
+// POSIX doesn't define any async-signal safe function for converting
+// an integer to ASCII. We'll have to define our own version.
+// itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the
+// conversion was successful or NULL otherwise. It never writes more than "sz"
+// bytes. Output will be truncated as needed, and a NUL character is always
+// appended.
+// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc.
+char *itoa_r(intptr_t i, char *buf, size_t sz, int base, size_t padding) {
+ // Make sure we can write at least one NUL byte.
+ size_t n = 1;
+ if (n > sz)
+ return NULL;
+
+ if (base < 2 || base > 16) {
+ buf[0] = '\000';
+ return NULL;
+ }
+
+ char *start = buf;
+
+ uintptr_t j = i;
+
+ // Handle negative numbers (only for base 10).
+ if (i < 0 && base == 10) {
+ j = -i;
+
+ // Make sure we can write the '-' character.
+ if (++n > sz) {
+ buf[0] = '\000';
+ return NULL;
+ }
+ *start++ = '-';
+ }
+
+ // Loop until we have converted the entire number. Output at least one
+ // character (i.e. '0').
+ char *ptr = start;
+ do {
+ // Make sure there is still enough space left in our output buffer.
+ if (++n > sz) {
+ buf[0] = '\000';
+ return NULL;
+ }
+
+ // Output the next digit.
+ *ptr++ = "0123456789abcdef"[j % base];
+ j /= base;
+
+ if (padding > 0)
+ padding--;
+ } while (j > 0 || padding > 0);
+
+ // Terminate the output with a NUL character.
+ *ptr = '\000';
+
+ // Conversion to ASCII actually resulted in the digits being in reverse
+ // order. We can't easily generate them in forward order, as we can't tell
+ // the number of characters needed until we are done converting.
+ // So, now, we reverse the string (except for the possible "-" sign).
+ while (--ptr > start) {
+ char ch = *ptr;
+ *ptr = *start;
+ *start++ = ch;
+ }
+ return buf;
+}
+
+// Safely appends string |source| to string |dest|. Never writes past the
+// buffer size |dest_size| and guarantees that |dest| is null-terminated.
+void SafeAppendString(const char* source, char* dest, int dest_size) {
+ int dest_string_length = strlen(dest);
+ SAFE_ASSERT(dest_string_length < dest_size);
+ dest += dest_string_length;
+ dest_size -= dest_string_length;
+ strncpy(dest, source, dest_size);
+ // Making sure |dest| is always null-terminated.
+ dest[dest_size - 1] = '\0';
+}
+
+// Converts a 64-bit value into a hex string, and safely appends it to |dest|.
+// Never writes past the buffer size |dest_size| and guarantees that |dest| is
+// null-terminated.
+void SafeAppendHexNumber(uint64_t value, char* dest, int dest_size) {
+ // 64-bit numbers in hex can have up to 16 digits.
+ char buf[17] = {'\0'};
+ SafeAppendString(itoa_r(value, buf, sizeof(buf), 16, 0), dest, dest_size);
+}
+
// The implementation of our symbolization routine. If it
// successfully finds the symbol containing "pc" and obtains the
// symbol name, returns true and write the symbol name to "out".
@@ -590,10 +727,40 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
int out_size) {
uint64_t pc0 = reinterpret_cast<uintptr_t>(pc);
uint64_t start_address = 0;
+ uint64_t base_address = 0;
+ int object_fd = -1;
- int object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0,
- start_address);
- if (object_fd == -1) {
+ if (out_size < 1) {
+ return false;
+ }
+ out[0] = '\0';
+ SafeAppendString("(", out, out_size);
+
+ if (g_symbolize_open_object_file_callback) {
+ object_fd = g_symbolize_open_object_file_callback(pc0, start_address,
+ base_address, out + 1,
+ out_size - 1);
+ } else {
+ object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0, start_address,
+ base_address,
+ out + 1,
+ out_size - 1);
+ }
+
+ // Check whether a file name was returned.
+ if (object_fd < 0) {
+ if (out[1]) {
+ // The object file containing PC was determined successfully however the
+ // object file was not opened successfully. This is still considered
+ // success because the object file name and offset are known and tools
+ // like asan_symbolize.py can be used for the symbolization.
+ out[out_size - 1] = '\0'; // Making sure |out| is always null-terminated.
+ SafeAppendString("+0x", out, out_size);
+ SafeAppendHexNumber(pc0 - base_address, out, out_size);
+ SafeAppendString(")", out, out_size);
+ return true;
+ }
+ // Failed to determine the object file containing PC. Bail out.
return false;
}
FileDescriptor wrapped_object_fd(object_fd);
diff --git a/extern/libmv/third_party/glog/src/symbolize.h b/extern/libmv/third_party/glog/src/symbolize.h
index 1ebe4dd94a2..f617184249c 100644
--- a/extern/libmv/third_party/glog/src/symbolize.h
+++ b/extern/libmv/third_party/glog/src/symbolize.h
@@ -60,9 +60,26 @@
#ifdef HAVE_SYMBOLIZE
-#if defined(__ELF__) // defined by gcc on Linux
+#if defined(__ELF__) // defined by gcc
+#if defined(__OpenBSD__)
+#include <sys/exec_elf.h>
+#else
#include <elf.h>
+#endif
+
+#if !defined(ANDROID)
#include <link.h> // For ElfW() macro.
+#endif
+
+// For systems where SIZEOF_VOID_P is not defined, determine it
+// based on __LP64__ (defined by gcc on 64-bit systems)
+#if !defined(SIZEOF_VOID_P)
+# if defined(__LP64__)
+# define SIZEOF_VOID_P 8
+# else
+# define SIZEOF_VOID_P 4
+# endif
+#endif
// If there is no ElfW macro, let's define it by ourself.
#ifndef ElfW
@@ -88,6 +105,10 @@ _END_GOOGLE_NAMESPACE_
_START_GOOGLE_NAMESPACE_
+// Restrictions on the callbacks that follow:
+// - The callbacks must not use heaps but only use stacks.
+// - The callbacks must be async-signal-safe.
+
// Installs a callback function, which will be called right before a symbol name
// is printed. The callback is intended to be used for showing a file name and a
// line number preceding a symbol name.
@@ -99,6 +120,24 @@ typedef int (*SymbolizeCallback)(int fd, void *pc, char *out, size_t out_size,
uint64 relocation);
void InstallSymbolizeCallback(SymbolizeCallback callback);
+// Installs a callback function, which will be called instead of
+// OpenObjectFileContainingPcAndGetStartAddress. The callback is expected
+// to searches for the object file (from /proc/self/maps) that contains
+// the specified pc. If found, sets |start_address| to the start address
+// of where this object file is mapped in memory, sets the module base
+// address into |base_address|, copies the object file name into
+// |out_file_name|, and attempts to open the object file. If the object
+// file is opened successfully, returns the file descriptor. Otherwise,
+// returns -1. |out_file_name_size| is the size of the file name buffer
+// (including the null-terminator).
+typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc,
+ uint64_t &start_address,
+ uint64_t &base_address,
+ char *out_file_name,
+ int out_file_name_size);
+void InstallSymbolizeOpenObjectFileCallback(
+ SymbolizeOpenObjectFileCallback callback);
+
_END_GOOGLE_NAMESPACE_
#endif
diff --git a/extern/lzo/CMakeLists.txt b/extern/lzo/CMakeLists.txt
index 5172a96e599..23bbf268cc6 100644
--- a/extern/lzo/CMakeLists.txt
+++ b/extern/lzo/CMakeLists.txt
@@ -23,6 +23,8 @@
#
# ***** END GPL LICENSE BLOCK *****
+remove_strict_flags()
+
set(INC
)
diff --git a/extern/sdlew/CMakeLists.txt b/extern/sdlew/CMakeLists.txt
new file mode 100644
index 00000000000..8571ad9251d
--- /dev/null
+++ b/extern/sdlew/CMakeLists.txt
@@ -0,0 +1,40 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Jacques Beaurain.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+ include
+)
+
+set(INC_SYS
+
+)
+
+set(SRC
+ include/sdlew.h
+ src/sdlew.c
+)
+
+blender_add_lib(extern_sdlew "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/extern/sdlew/SConscript b/extern/sdlew/SConscript
new file mode 100644
index 00000000000..287f9c09ec8
--- /dev/null
+++ b/extern/sdlew/SConscript
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2014, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Sergey Sharybin.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+Import ('env')
+
+sources = env.Glob('src/sdlew.c')
+
+incs = 'include'
+defs = []
+
+env.BlenderLib ('extern_sdlew', sources, Split(incs), defines=defs, libtype=['extern'], priority = [999])
diff --git a/extern/sdlew/auto/sdlew_gen.sh b/extern/sdlew/auto/sdlew_gen.sh
new file mode 100755
index 00000000000..36a2d939d20
--- /dev/null
+++ b/extern/sdlew/auto/sdlew_gen.sh
@@ -0,0 +1,250 @@
+#!/bin/bash
+
+SDL="SDL2"
+INCLUDE_DIR="/usr/include/${SDL}"
+SCRIPT=`realpath -s $0`
+DIR=`dirname $SCRIPT`
+DIR=`dirname $DIR`
+
+mkdir -p $DIR/include/${SDL}
+mkdir -p $DIR/src
+
+rm -rf $DIR/include/${SDL}/*.h
+rm -rf $DIR/src/sdlew.c
+
+echo "Generating sdlew headers..."
+
+UNSUPPORTED="SDL_MemoryBarrierRelease SDL_MemoryBarrierAcquire SDL_AtomicCAS SDL_AtomicCASPtr \
+ SDL_iPhoneSetAnimationCallback SDL_iPhoneSetEventPump SDL_AndroidGetJNIEnv SDL_AndroidGetActivity \
+ SDL_AndroidGetActivity SDL_AndroidGetInternalStoragePath SDL_AndroidGetExternalStorageState \
+ SDL_AndroidGetExternalStoragePath SDL_CreateShapedWindow SDL_IsShapedWindow tSDL_SetWindowShape \
+ SDL_GetShapedWindowMode"
+
+for header in $INCLUDE_DIR/*; do
+ filename=`basename $header`
+ cat $header \
+ | sed -r 's/extern DECLSPEC ((const )?[a-z0-9_]+(\s\*)?)\s?SDLCALL /typedef \1 SDLCALL t/i' \
+ > $DIR/include/${SDL}/$filename
+
+ line_num=`cat $DIR/include/${SDL}/$filename | grep -n "Ends C function" | cut -d : -f 1`
+ if [ ! -z "$line_num" ]; then
+ functions=`grep -E 'typedef [A-Za-z0-9_ \*]+ SDLCALL' $DIR/include/${SDL}/$filename \
+ | sed -r 's/typedef [A-Za-z0-9_ \*]+ SDLCALL t([a-z0-9_]+).*/extern t\1 *\1;/i'`
+ functions=`echo "${functions}" | sed -e 's/[\/&]/\\\&/g'`
+ echo "$functions" | while read function; do
+ if [ -z "$function" ]; then
+ continue;
+ fi
+ func_name=`echo $function | cut -d '*' -f 2 | sed -r 's/;//'`
+ if [ ! -z "`echo "$UNSUPPORTED" | grep $func_name`" ]; then
+ continue;
+ fi
+ if [ "$func_name" == "SDL_memcpy" ]; then
+ line_num=`cat $DIR/include/${SDL}/$filename | grep -n "SDL_memcpy4" | cut -d : -f 1`
+ sed -ri "${line_num}s/(.*)/${function}\n\1/" $DIR/include/${SDL}/$filename
+ else
+ sed -ri "${line_num}s/(.*)/${function}\n\1/" $DIR/include/${SDL}/$filename
+ fi
+ line_num=`cat $DIR/include/${SDL}/$filename | grep -n "Ends C function" | cut -d : -f 1`
+ done
+ line_num=`cat $DIR/include/${SDL}/$filename | grep -n "Ends C function" | cut -d : -f 1`
+ sed -ri "${line_num}s/(.*)/\n\1/" $DIR/include/${SDL}/$filename
+ fi
+
+ if [ $filename == "SDL_stdinc.h" ]; then
+ cat $header | grep -E '#if(def)? (defined\()?HAVE_' | sed -r 's/#if(def)? //' | while read check; do
+ func_names=`cat $DIR/include/${SDL}/$filename \
+ | grep -A 8 "$check\$" \
+ | grep -v struct \
+ | grep 'typedef' \
+ | sed -r 's/typedef [a-z0-9_ \*]+ SDLCALL ([a-z0-9_]+).*/\1/i'`
+ full_check=`echo "${check}" | sed -e 's/[\/&]/\\\&/g'`
+ if [ ! -z "`echo $full_check | grep defined`" ]; then
+ full_check="#if !($full_check)"
+ else
+ full_check="#ifndef $full_check"
+ fi
+ for func_name in $func_names; do
+ line_num=`grep -n "extern ${func_name} \*" $DIR/include/${SDL}/$filename | cut -d : -f 1`
+ let prev_num=line_num-1
+ if [ -z "`cat $DIR/include/${SDL}/$filename | head -n $prev_num | tail -n 1 | grep '#if'`" ]; then
+ sed -ri "${line_num}s/(.*)/$full_check \/* GEN_CHECK_MARKER *\/\n\1\n#endif \/* GEN_CHECK_MARKER *\//" $DIR/include/${SDL}/$filename
+ fi
+ done
+ done
+ fi
+done
+
+cat << EOF > $DIR/include/sdlew.h
+/*
+ * Copyright 2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#ifndef __SDL_EW_H__
+#define __SDL_EW_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ SDLEW_SUCCESS = 0,
+ SDLEW_ERROR_OPEN_FAILED = -1,
+ SDLEW_ERROR_ATEXIT_FAILED = -2,
+ SDLEW_ERROR_VERSION = -3,
+};
+
+int sdlewInit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SDL_EW_H__ */
+EOF
+
+echo "Generating sdlew sources..."
+
+cat << EOF > $DIR/src/sdlew.c
+/*
+ * Copyright 2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#ifdef _MSC_VER
+# define snprintf _snprintf
+# define popen _popen
+# define pclose _pclose
+# define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include "sdlew.h"
+
+#include "${SDL}/SDL.h"
+#include "${SDL}/SDL_syswm.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN
+# define VC_EXTRALEAN
+# include <windows.h>
+
+/* Utility macros. */
+
+typedef HMODULE DynamicLibrary;
+
+# define dynamic_library_open(path) LoadLibrary(path)
+# define dynamic_library_close(lib) FreeLibrary(lib)
+# define dynamic_library_find(lib, symbol) GetProcAddress(lib, symbol)
+#else
+# include <dlfcn.h>
+
+typedef void* DynamicLibrary;
+
+# define dynamic_library_open(path) dlopen(path, RTLD_NOW)
+# define dynamic_library_close(lib) dlclose(lib)
+# define dynamic_library_find(lib, symbol) dlsym(lib, symbol)
+#endif
+
+#define SDL_LIBRARY_FIND_CHECKED(name) \
+ name = (t##name *)dynamic_library_find(lib, #name); \
+ assert(name);
+
+#define SDL_LIBRARY_FIND(name) \
+ name = (t##name *)dynamic_library_find(lib, #name);
+
+static DynamicLibrary lib;
+
+EOF
+
+content=`grep --no-filename -ER "extern tSDL|GEN_CHECK_MARKER" $DIR/include/${SDL}/`
+
+echo "$content" | sed -r 's/extern t([a-z0-9_]+).*/t\1 *\1;/gi' >> $DIR/src/sdlew.c
+
+cat << EOF >> $DIR/src/sdlew.c
+
+static void sdlewExit(void) {
+ if(lib != NULL) {
+ /* Ignore errors. */
+ dynamic_library_close(lib);
+ lib = NULL;
+ }
+}
+
+/* Implementation function. */
+int sdlewInit(void) {
+ /* Library paths. */
+#ifdef _WIN32
+ /* Expected in c:/windows/system or similar, no path needed. */
+ const char *path = "SDL2.dll";
+#elif defined(__APPLE__)
+ /* Default installation path. */
+ const char *path = "/usr/local/cuda/lib/libSDL2.dylib";
+#else
+ const char *path = "libSDL2.so";
+#endif
+ static int initialized = 0;
+ static int result = 0;
+ int error;
+
+ if (initialized) {
+ return result;
+ }
+
+ initialized = 1;
+
+ error = atexit(sdlewExit);
+ if (error) {
+ result = SDLEW_ERROR_ATEXIT_FAILED;
+ return result;
+ }
+
+ /* Load library. */
+ lib = dynamic_library_open(path);
+
+ if (lib == NULL) {
+ result = SDLEW_ERROR_OPEN_FAILED;
+ return result;
+ }
+
+EOF
+
+echo "$content" | sed -r 's/extern t([a-z0-9_]+).*/ SDL_LIBRARY_FIND(\1);/gi' >> $DIR/src/sdlew.c
+
+cat << EOF >> $DIR/src/sdlew.c
+
+ result = SDLEW_SUCCESS;
+
+ return result;
+}
+EOF
+
+sed -i 's/\s\/\* GEN_CHECK_MARKER \*\///g' $DIR/src/sdlew.c
+sed -i 's/\s\/\* GEN_CHECK_MARKER \*\///g' $DIR/include/${SDL}/SDL_stdinc.h
diff --git a/extern/sdlew/auto/strip_comments.sh b/extern/sdlew/auto/strip_comments.sh
new file mode 100755
index 00000000000..c89224c3d56
--- /dev/null
+++ b/extern/sdlew/auto/strip_comments.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+SDL="SDL2"
+INCLUDE_DIR="/usr/include/${SDL}"
+SCRIPT=`realpath -s $0`
+DIR=`dirname $SCRIPT`
+DIR=`dirname $DIR`
+
+for f in $DIR/include/${SDL}/*.h; do
+ file_name=`basename $f`
+ echo "Striping $file_name..."
+ sed -r ':a; s%(.*)/\*.*\*/%\1%; ta; /\/\*/ !b; N; ba' -i $f
+ sed 's/[ \t]*$//' -i $f
+ sed '/^$/N;/^\n$/D' -i $f
+done
diff --git a/extern/sdlew/include/SDL2/SDL.h b/extern/sdlew/include/SDL2/SDL.h
new file mode 100644
index 00000000000..1dc71e9e765
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL.h
@@ -0,0 +1,73 @@
+
+#ifndef _SDL_H
+#define _SDL_H
+
+#include "SDL_main.h"
+#include "SDL_stdinc.h"
+#include "SDL_assert.h"
+#include "SDL_atomic.h"
+#include "SDL_audio.h"
+#include "SDL_clipboard.h"
+#include "SDL_cpuinfo.h"
+#include "SDL_endian.h"
+#include "SDL_error.h"
+#include "SDL_events.h"
+#include "SDL_joystick.h"
+#include "SDL_gamecontroller.h"
+#include "SDL_haptic.h"
+#include "SDL_hints.h"
+#include "SDL_loadso.h"
+#include "SDL_log.h"
+#include "SDL_messagebox.h"
+#include "SDL_mutex.h"
+#include "SDL_power.h"
+#include "SDL_render.h"
+#include "SDL_rwops.h"
+#include "SDL_system.h"
+#include "SDL_thread.h"
+#include "SDL_timer.h"
+#include "SDL_version.h"
+#include "SDL_video.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL_INIT_TIMER 0x00000001
+#define SDL_INIT_AUDIO 0x00000010
+#define SDL_INIT_VIDEO 0x00000020
+#define SDL_INIT_JOYSTICK 0x00000200
+#define SDL_INIT_HAPTIC 0x00001000
+#define SDL_INIT_GAMECONTROLLER 0x00002000
+#define SDL_INIT_EVENTS 0x00004000
+#define SDL_INIT_NOPARACHUTE 0x00100000
+#define SDL_INIT_EVERYTHING ( \
+ SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \
+ SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER \
+ )
+
+typedef int SDLCALL tSDL_Init(Uint32 flags);
+
+typedef int SDLCALL tSDL_InitSubSystem(Uint32 flags);
+
+typedef void SDLCALL tSDL_QuitSubSystem(Uint32 flags);
+
+typedef Uint32 SDLCALL tSDL_WasInit(Uint32 flags);
+
+typedef void SDLCALL tSDL_Quit(void);
+
+extern tSDL_Init *SDL_Init;
+extern tSDL_InitSubSystem *SDL_InitSubSystem;
+extern tSDL_QuitSubSystem *SDL_QuitSubSystem;
+extern tSDL_WasInit *SDL_WasInit;
+extern tSDL_Quit *SDL_Quit;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_assert.h b/extern/sdlew/include/SDL2/SDL_assert.h
new file mode 100644
index 00000000000..aa7b3ee2c25
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_assert.h
@@ -0,0 +1,140 @@
+
+#ifndef _SDL_assert_h
+#define _SDL_assert_h
+
+#include "SDL_config.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SDL_ASSERT_LEVEL
+#ifdef SDL_DEFAULT_ASSERT_LEVEL
+#define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL
+#elif defined(_DEBUG) || defined(DEBUG) || \
+ (defined(__GNUC__) && !defined(__OPTIMIZE__))
+#define SDL_ASSERT_LEVEL 2
+#else
+#define SDL_ASSERT_LEVEL 1
+#endif
+#endif
+
+#if defined(_MSC_VER)
+
+ extern void __cdecl __debugbreak(void);
+ #define SDL_TriggerBreakpoint() __debugbreak()
+#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
+ #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
+#elif defined(HAVE_SIGNAL_H)
+ #include <signal.h>
+ #define SDL_TriggerBreakpoint() raise(SIGTRAP)
+#else
+
+ #define SDL_TriggerBreakpoint()
+#endif
+
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# define SDL_FUNCTION __func__
+#elif ((__GNUC__ >= 2) || defined(_MSC_VER))
+# define SDL_FUNCTION __FUNCTION__
+#else
+# define SDL_FUNCTION "???"
+#endif
+#define SDL_FILE __FILE__
+#define SDL_LINE __LINE__
+
+#define SDL_disabled_assert(condition) \
+ do { (void) sizeof ((condition)); } while (0)
+
+typedef enum
+{
+ SDL_ASSERTION_RETRY,
+ SDL_ASSERTION_BREAK,
+ SDL_ASSERTION_ABORT,
+ SDL_ASSERTION_IGNORE,
+ SDL_ASSERTION_ALWAYS_IGNORE
+} SDL_assert_state;
+
+typedef struct SDL_assert_data
+{
+ int always_ignore;
+ unsigned int trigger_count;
+ const char *condition;
+ const char *filename;
+ int linenum;
+ const char *function;
+ const struct SDL_assert_data *next;
+} SDL_assert_data;
+
+#if (SDL_ASSERT_LEVEL > 0)
+
+typedef SDL_assert_state SDLCALL tSDL_ReportAssertion(SDL_assert_data *,
+ const char *,
+ const char *, int);
+
+#define SDL_enabled_assert(condition) \
+ do { \
+ while ( !(condition) ) { \
+ static struct SDL_assert_data assert_data = { \
+ 0, 0, #condition, 0, 0, 0, 0 \
+ }; \
+ const SDL_assert_state state = SDL_ReportAssertion(&assert_data, \
+ SDL_FUNCTION, \
+ SDL_FILE, \
+ SDL_LINE); \
+ if (state == SDL_ASSERTION_RETRY) { \
+ continue; \
+ } else if (state == SDL_ASSERTION_BREAK) { \
+ SDL_TriggerBreakpoint(); \
+ } \
+ break; \
+ } \
+ } while (0)
+
+#endif
+
+#if SDL_ASSERT_LEVEL == 0
+# define SDL_assert(condition) SDL_disabled_assert(condition)
+# define SDL_assert_release(condition) SDL_disabled_assert(condition)
+# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
+#elif SDL_ASSERT_LEVEL == 1
+# define SDL_assert(condition) SDL_disabled_assert(condition)
+# define SDL_assert_release(condition) SDL_enabled_assert(condition)
+# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
+#elif SDL_ASSERT_LEVEL == 2
+# define SDL_assert(condition) SDL_enabled_assert(condition)
+# define SDL_assert_release(condition) SDL_enabled_assert(condition)
+# define SDL_assert_paranoid(condition) SDL_disabled_assert(condition)
+#elif SDL_ASSERT_LEVEL == 3
+# define SDL_assert(condition) SDL_enabled_assert(condition)
+# define SDL_assert_release(condition) SDL_enabled_assert(condition)
+# define SDL_assert_paranoid(condition) SDL_enabled_assert(condition)
+#else
+# error Unknown assertion level.
+#endif
+
+typedef SDL_assert_state (SDLCALL *SDL_AssertionHandler)(
+ const SDL_assert_data* data, void* userdata);
+
+typedef void SDLCALL tSDL_SetAssertionHandler(
+ SDL_AssertionHandler handler,
+ void *userdata);
+
+typedef const SDL_assert_data * SDLCALL tSDL_GetAssertionReport(void);
+
+typedef void SDLCALL tSDL_ResetAssertionReport(void);
+
+extern tSDL_ReportAssertion *SDL_ReportAssertion;
+extern tSDL_SetAssertionHandler *SDL_SetAssertionHandler;
+extern tSDL_GetAssertionReport *SDL_GetAssertionReport;
+extern tSDL_ResetAssertionReport *SDL_ResetAssertionReport;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_atomic.h b/extern/sdlew/include/SDL2/SDL_atomic.h
new file mode 100644
index 00000000000..6531a3e7115
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_atomic.h
@@ -0,0 +1,185 @@
+
+#ifndef _SDL_atomic_h_
+#define _SDL_atomic_h_
+
+#include "SDL_stdinc.h"
+#include "SDL_platform.h"
+
+#include "begin_code.h"
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+#include <intrin.h>
+#define HAVE_MSC_ATOMICS 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int SDL_SpinLock;
+
+typedef SDL_bool SDLCALL tSDL_AtomicTryLock(SDL_SpinLock *lock);
+
+typedef void SDLCALL tSDL_AtomicLock(SDL_SpinLock *lock);
+
+typedef void SDLCALL tSDL_AtomicUnlock(SDL_SpinLock *lock);
+
+#if defined(_MSC_VER) && (_MSC_VER > 1200)
+void _ReadWriteBarrier(void);
+#pragma intrinsic(_ReadWriteBarrier)
+#define SDL_CompilerBarrier() _ReadWriteBarrier()
+#elif defined(__GNUC__)
+#define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory")
+#else
+#define SDL_CompilerBarrier() \
+{ SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); }
+#endif
+
+#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
+#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory")
+#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory")
+#elif defined(__GNUC__) && defined(__arm__)
+#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
+#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory")
+#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory")
+#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
+#ifdef __thumb__
+
+typedef void SDLCALL tSDL_MemoryBarrierRelease();
+typedef void SDLCALL tSDL_MemoryBarrierAcquire();
+#else
+#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
+#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
+#endif
+#else
+#define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("" : : : "memory")
+#define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory")
+#endif
+#else
+
+#define SDL_MemoryBarrierRelease() SDL_CompilerBarrier()
+#define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier()
+#endif
+
+#if defined(SDL_ATOMIC_DISABLED) && SDL_ATOMIC_DISABLED
+#define SDL_DISABLE_ATOMIC_INLINE
+#endif
+#ifndef SDL_DISABLE_ATOMIC_INLINE
+
+#ifdef HAVE_MSC_ATOMICS
+
+#define SDL_AtomicSet(a, v) _InterlockedExchange((long*)&(a)->value, (v))
+#define SDL_AtomicAdd(a, v) _InterlockedExchangeAdd((long*)&(a)->value, (v))
+#define SDL_AtomicCAS(a, oldval, newval) (_InterlockedCompareExchange((long*)&(a)->value, (newval), (oldval)) == (oldval))
+#define SDL_AtomicSetPtr(a, v) _InterlockedExchangePointer((a), (v))
+#if _M_IX86
+#define SDL_AtomicCASPtr(a, oldval, newval) (_InterlockedCompareExchange((long*)(a), (long)(newval), (long)(oldval)) == (long)(oldval))
+#else
+#define SDL_AtomicCASPtr(a, oldval, newval) (_InterlockedCompareExchangePointer((a), (newval), (oldval)) == (oldval))
+#endif
+
+#elif defined(__MACOSX__)
+#include <libkern/OSAtomic.h>
+
+#define SDL_AtomicCAS(a, oldval, newval) OSAtomicCompareAndSwap32Barrier((oldval), (newval), &(a)->value)
+#ifdef __LP64__
+#define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap64Barrier((int64_t)(oldval), (int64_t)(newval), (int64_t*)(a))
+#else
+#define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap32Barrier((int32_t)(oldval), (int32_t)(newval), (int32_t*)(a))
+#endif
+
+#elif defined(HAVE_GCC_ATOMICS)
+
+#define SDL_AtomicSet(a, v) __sync_lock_test_and_set(&(a)->value, v)
+#define SDL_AtomicAdd(a, v) __sync_fetch_and_add(&(a)->value, v)
+#define SDL_AtomicSetPtr(a, v) __sync_lock_test_and_set(a, v)
+#define SDL_AtomicCAS(a, oldval, newval) __sync_bool_compare_and_swap(&(a)->value, oldval, newval)
+#define SDL_AtomicCASPtr(a, oldval, newval) __sync_bool_compare_and_swap(a, oldval, newval)
+
+#endif
+
+#endif
+
+#ifndef SDL_atomic_t_defined
+typedef struct { int value; } SDL_atomic_t;
+#endif
+
+#ifndef SDL_AtomicCAS
+typedef SDL_bool SDLCALL tSDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval);
+#endif
+
+#ifndef SDL_AtomicSet
+SDL_FORCE_INLINE int SDL_AtomicSet(SDL_atomic_t *a, int v)
+{
+ int value;
+ do {
+ value = a->value;
+ } while (!SDL_AtomicCAS(a, value, v));
+ return value;
+}
+#endif
+
+#ifndef SDL_AtomicGet
+SDL_FORCE_INLINE int SDL_AtomicGet(SDL_atomic_t *a)
+{
+ int value = a->value;
+ SDL_CompilerBarrier();
+ return value;
+}
+#endif
+
+#ifndef SDL_AtomicAdd
+SDL_FORCE_INLINE int SDL_AtomicAdd(SDL_atomic_t *a, int v)
+{
+ int value;
+ do {
+ value = a->value;
+ } while (!SDL_AtomicCAS(a, value, (value + v)));
+ return value;
+}
+#endif
+
+#ifndef SDL_AtomicIncRef
+#define SDL_AtomicIncRef(a) SDL_AtomicAdd(a, 1)
+#endif
+
+#ifndef SDL_AtomicDecRef
+#define SDL_AtomicDecRef(a) (SDL_AtomicAdd(a, -1) == 1)
+#endif
+
+#ifndef SDL_AtomicCASPtr
+typedef SDL_bool SDLCALL tSDL_AtomicCASPtr(void* *a, void *oldval, void *newval);
+#endif
+
+#ifndef SDL_AtomicSetPtr
+SDL_FORCE_INLINE void* SDL_AtomicSetPtr(void* *a, void* v)
+{
+ void* value;
+ do {
+ value = *a;
+ } while (!SDL_AtomicCASPtr(a, value, v));
+ return value;
+}
+#endif
+
+#ifndef SDL_AtomicGetPtr
+SDL_FORCE_INLINE void* SDL_AtomicGetPtr(void* *a)
+{
+ void* value = *a;
+ SDL_CompilerBarrier();
+ return value;
+}
+#endif
+
+extern tSDL_AtomicTryLock *SDL_AtomicTryLock;
+extern tSDL_AtomicLock *SDL_AtomicLock;
+extern tSDL_AtomicUnlock *SDL_AtomicUnlock;
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_audio.h b/extern/sdlew/include/SDL2/SDL_audio.h
new file mode 100644
index 00000000000..707c5d5d4dc
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_audio.h
@@ -0,0 +1,222 @@
+
+#ifndef _SDL_audio_h
+#define _SDL_audio_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_endian.h"
+#include "SDL_mutex.h"
+#include "SDL_thread.h"
+#include "SDL_rwops.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef Uint16 SDL_AudioFormat;
+
+#define SDL_AUDIO_MASK_BITSIZE (0xFF)
+#define SDL_AUDIO_MASK_DATATYPE (1<<8)
+#define SDL_AUDIO_MASK_ENDIAN (1<<12)
+#define SDL_AUDIO_MASK_SIGNED (1<<15)
+#define SDL_AUDIO_BITSIZE(x) (x & SDL_AUDIO_MASK_BITSIZE)
+#define SDL_AUDIO_ISFLOAT(x) (x & SDL_AUDIO_MASK_DATATYPE)
+#define SDL_AUDIO_ISBIGENDIAN(x) (x & SDL_AUDIO_MASK_ENDIAN)
+#define SDL_AUDIO_ISSIGNED(x) (x & SDL_AUDIO_MASK_SIGNED)
+#define SDL_AUDIO_ISINT(x) (!SDL_AUDIO_ISFLOAT(x))
+#define SDL_AUDIO_ISLITTLEENDIAN(x) (!SDL_AUDIO_ISBIGENDIAN(x))
+#define SDL_AUDIO_ISUNSIGNED(x) (!SDL_AUDIO_ISSIGNED(x))
+
+#define AUDIO_U8 0x0008
+#define AUDIO_S8 0x8008
+#define AUDIO_U16LSB 0x0010
+#define AUDIO_S16LSB 0x8010
+#define AUDIO_U16MSB 0x1010
+#define AUDIO_S16MSB 0x9010
+#define AUDIO_U16 AUDIO_U16LSB
+#define AUDIO_S16 AUDIO_S16LSB
+
+#define AUDIO_S32LSB 0x8020
+#define AUDIO_S32MSB 0x9020
+#define AUDIO_S32 AUDIO_S32LSB
+
+#define AUDIO_F32LSB 0x8120
+#define AUDIO_F32MSB 0x9120
+#define AUDIO_F32 AUDIO_F32LSB
+
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+#define AUDIO_U16SYS AUDIO_U16LSB
+#define AUDIO_S16SYS AUDIO_S16LSB
+#define AUDIO_S32SYS AUDIO_S32LSB
+#define AUDIO_F32SYS AUDIO_F32LSB
+#else
+#define AUDIO_U16SYS AUDIO_U16MSB
+#define AUDIO_S16SYS AUDIO_S16MSB
+#define AUDIO_S32SYS AUDIO_S32MSB
+#define AUDIO_F32SYS AUDIO_F32MSB
+#endif
+
+#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001
+#define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002
+#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004
+#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE)
+
+typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream,
+ int len);
+
+typedef struct SDL_AudioSpec
+{
+ int freq;
+ SDL_AudioFormat format;
+ Uint8 channels;
+ Uint8 silence;
+ Uint16 samples;
+ Uint16 padding;
+ Uint32 size;
+ SDL_AudioCallback callback;
+ void *userdata;
+} SDL_AudioSpec;
+
+struct SDL_AudioCVT;
+typedef void (SDLCALL * SDL_AudioFilter) (struct SDL_AudioCVT * cvt,
+ SDL_AudioFormat format);
+
+#ifdef __GNUC__
+
+#define SDL_AUDIOCVT_PACKED __attribute__((packed))
+#else
+#define SDL_AUDIOCVT_PACKED
+#endif
+
+typedef struct SDL_AudioCVT
+{
+ int needed;
+ SDL_AudioFormat src_format;
+ SDL_AudioFormat dst_format;
+ double rate_incr;
+ Uint8 *buf;
+ int len;
+ int len_cvt;
+ int len_mult;
+ double len_ratio;
+ SDL_AudioFilter filters[10];
+ int filter_index;
+} SDL_AUDIOCVT_PACKED SDL_AudioCVT;
+
+typedef int SDLCALL tSDL_GetNumAudioDrivers(void);
+typedef const char * SDLCALL tSDL_GetAudioDriver(int index);
+
+typedef int SDLCALL tSDL_AudioInit(const char *driver_name);
+typedef void SDLCALL tSDL_AudioQuit(void);
+
+typedef const char * SDLCALL tSDL_GetCurrentAudioDriver(void);
+
+typedef int SDLCALL tSDL_OpenAudio(SDL_AudioSpec * desired,
+ SDL_AudioSpec * obtained);
+
+typedef Uint32 SDL_AudioDeviceID;
+
+typedef int SDLCALL tSDL_GetNumAudioDevices(int iscapture);
+
+typedef const char * SDLCALL tSDL_GetAudioDeviceName(int index,
+ int iscapture);
+
+typedef SDL_AudioDeviceID SDLCALL tSDL_OpenAudioDevice(const char
+ *device,
+ int iscapture,
+ const
+ SDL_AudioSpec *
+ desired,
+ SDL_AudioSpec *
+ obtained,
+ int
+ allowed_changes);
+
+typedef enum
+{
+ SDL_AUDIO_STOPPED = 0,
+ SDL_AUDIO_PLAYING,
+ SDL_AUDIO_PAUSED
+} SDL_AudioStatus;
+typedef SDL_AudioStatus SDLCALL tSDL_GetAudioStatus(void);
+
+extern DECLSPEC SDL_AudioStatus SDLCALL
+SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev);
+
+typedef void SDLCALL tSDL_PauseAudio(int pause_on);
+typedef void SDLCALL tSDL_PauseAudioDevice(SDL_AudioDeviceID dev,
+ int pause_on);
+
+typedef SDL_AudioSpec * SDLCALL tSDL_LoadWAV_RW(SDL_RWops * src,
+ int freesrc,
+ SDL_AudioSpec * spec,
+ Uint8 ** audio_buf,
+ Uint32 * audio_len);
+
+#define SDL_LoadWAV(file, spec, audio_buf, audio_len) \
+ SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len)
+
+typedef void SDLCALL tSDL_FreeWAV(Uint8 * audio_buf);
+
+typedef int SDLCALL tSDL_BuildAudioCVT(SDL_AudioCVT * cvt,
+ SDL_AudioFormat src_format,
+ Uint8 src_channels,
+ int src_rate,
+ SDL_AudioFormat dst_format,
+ Uint8 dst_channels,
+ int dst_rate);
+
+typedef int SDLCALL tSDL_ConvertAudio(SDL_AudioCVT * cvt);
+
+#define SDL_MIX_MAXVOLUME 128
+
+typedef void SDLCALL tSDL_MixAudio(Uint8 * dst, const Uint8 * src,
+ Uint32 len, int volume);
+
+typedef void SDLCALL tSDL_MixAudioFormat(Uint8 * dst,
+ const Uint8 * src,
+ SDL_AudioFormat format,
+ Uint32 len, int volume);
+
+typedef void SDLCALL tSDL_LockAudio(void);
+typedef void SDLCALL tSDL_LockAudioDevice(SDL_AudioDeviceID dev);
+typedef void SDLCALL tSDL_UnlockAudio(void);
+typedef void SDLCALL tSDL_UnlockAudioDevice(SDL_AudioDeviceID dev);
+
+typedef void SDLCALL tSDL_CloseAudio(void);
+typedef void SDLCALL tSDL_CloseAudioDevice(SDL_AudioDeviceID dev);
+
+extern tSDL_GetNumAudioDrivers *SDL_GetNumAudioDrivers;
+extern tSDL_GetAudioDriver *SDL_GetAudioDriver;
+extern tSDL_AudioInit *SDL_AudioInit;
+extern tSDL_AudioQuit *SDL_AudioQuit;
+extern tSDL_GetCurrentAudioDriver *SDL_GetCurrentAudioDriver;
+extern tSDL_OpenAudio *SDL_OpenAudio;
+extern tSDL_GetNumAudioDevices *SDL_GetNumAudioDevices;
+extern tSDL_GetAudioDeviceName *SDL_GetAudioDeviceName;
+extern tSDL_OpenAudioDevice *SDL_OpenAudioDevice;
+extern tSDL_GetAudioStatus *SDL_GetAudioStatus;
+extern tSDL_PauseAudio *SDL_PauseAudio;
+extern tSDL_PauseAudioDevice *SDL_PauseAudioDevice;
+extern tSDL_LoadWAV_RW *SDL_LoadWAV_RW;
+extern tSDL_FreeWAV *SDL_FreeWAV;
+extern tSDL_BuildAudioCVT *SDL_BuildAudioCVT;
+extern tSDL_ConvertAudio *SDL_ConvertAudio;
+extern tSDL_MixAudio *SDL_MixAudio;
+extern tSDL_MixAudioFormat *SDL_MixAudioFormat;
+extern tSDL_LockAudio *SDL_LockAudio;
+extern tSDL_LockAudioDevice *SDL_LockAudioDevice;
+extern tSDL_UnlockAudio *SDL_UnlockAudio;
+extern tSDL_UnlockAudioDevice *SDL_UnlockAudioDevice;
+extern tSDL_CloseAudio *SDL_CloseAudio;
+extern tSDL_CloseAudioDevice *SDL_CloseAudioDevice;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_bits.h b/extern/sdlew/include/SDL2/SDL_bits.h
new file mode 100644
index 00000000000..bb98c7d4144
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_bits.h
@@ -0,0 +1,53 @@
+
+#ifndef _SDL_bits_h
+#define _SDL_bits_h
+
+#include "SDL_stdinc.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SDL_FORCE_INLINE int
+SDL_MostSignificantBitIndex32(Uint32 x)
+{
+#if defined(__GNUC__) && __GNUC__ >= 4
+
+ if (x == 0) {
+ return -1;
+ }
+ return 31 - __builtin_clz(x);
+#else
+
+ const Uint32 b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
+ const int S[] = {1, 2, 4, 8, 16};
+
+ int msbIndex = 0;
+ int i;
+
+ if (x == 0) {
+ return -1;
+ }
+
+ for (i = 4; i >= 0; i--)
+ {
+ if (x & b[i])
+ {
+ x >>= S[i];
+ msbIndex |= S[i];
+ }
+ }
+
+ return msbIndex;
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_blendmode.h b/extern/sdlew/include/SDL2/SDL_blendmode.h
new file mode 100644
index 00000000000..3baa1e376f1
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_blendmode.h
@@ -0,0 +1,25 @@
+
+#ifndef _SDL_blendmode_h
+#define _SDL_blendmode_h
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ SDL_BLENDMODE_NONE = 0x00000000,
+ SDL_BLENDMODE_BLEND = 0x00000001,
+ SDL_BLENDMODE_ADD = 0x00000002,
+ SDL_BLENDMODE_MOD = 0x00000004
+} SDL_BlendMode;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_clipboard.h b/extern/sdlew/include/SDL2/SDL_clipboard.h
new file mode 100644
index 00000000000..61db474487e
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_clipboard.h
@@ -0,0 +1,29 @@
+
+#ifndef _SDL_clipboard_h
+#define _SDL_clipboard_h
+
+#include "SDL_stdinc.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int SDLCALL tSDL_SetClipboardText(const char *text);
+
+typedef char * SDLCALL tSDL_GetClipboardText(void);
+
+typedef SDL_bool SDLCALL tSDL_HasClipboardText(void);
+
+extern tSDL_SetClipboardText *SDL_SetClipboardText;
+extern tSDL_GetClipboardText *SDL_GetClipboardText;
+extern tSDL_HasClipboardText *SDL_HasClipboardText;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_config.h b/extern/sdlew/include/SDL2/SDL_config.h
new file mode 100644
index 00000000000..e7b0feef95c
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_config.h
@@ -0,0 +1,175 @@
+
+#ifndef _SDL_config_h
+#define _SDL_config_h
+
+#include "SDL_platform.h"
+
+#ifdef _MSC_VER
+#error You should run hg revert SDL_config.h
+#endif
+
+#ifdef __LP64__
+#define SIZEOF_VOIDP 8
+#else
+#define SIZEOF_VOIDP 4
+#endif
+#define HAVE_GCC_ATOMICS 1
+
+#define HAVE_PTHREAD_SPINLOCK 1
+
+#define HAVE_LIBC 1
+#if HAVE_LIBC
+
+#define HAVE_ALLOCA_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_STDIO_H 1
+#define STDC_HEADERS 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STDARG_H 1
+#define HAVE_MALLOC_H 1
+#define HAVE_MEMORY_H 1
+#define HAVE_STRING_H 1
+#define HAVE_STRINGS_H 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_CTYPE_H 1
+#define HAVE_MATH_H 1
+#define HAVE_ICONV_H 1
+#define HAVE_SIGNAL_H 1
+
+#define HAVE_LIBUDEV_H 1
+#define HAVE_DBUS_DBUS_H 1
+
+#define HAVE_MALLOC 1
+#define HAVE_CALLOC 1
+#define HAVE_REALLOC 1
+#define HAVE_FREE 1
+#define HAVE_ALLOCA 1
+#ifndef __WIN32__
+#define HAVE_GETENV 1
+#define HAVE_SETENV 1
+#define HAVE_PUTENV 1
+#define HAVE_UNSETENV 1
+#endif
+#define HAVE_QSORT 1
+#define HAVE_ABS 1
+#define HAVE_BCOPY 1
+#define HAVE_MEMSET 1
+#define HAVE_MEMCPY 1
+#define HAVE_MEMMOVE 1
+#define HAVE_MEMCMP 1
+#define HAVE_STRLEN 1
+
+#define HAVE_STRDUP 1
+
+#define HAVE_STRCHR 1
+#define HAVE_STRRCHR 1
+#define HAVE_STRSTR 1
+
+#define HAVE_STRTOL 1
+#define HAVE_STRTOUL 1
+
+#define HAVE_STRTOLL 1
+#define HAVE_STRTOULL 1
+#define HAVE_STRTOD 1
+#define HAVE_ATOI 1
+#define HAVE_ATOF 1
+#define HAVE_STRCMP 1
+#define HAVE_STRNCMP 1
+
+#define HAVE_STRCASECMP 1
+
+#define HAVE_STRNCASECMP 1
+#define HAVE_SSCANF 1
+#define HAVE_SNPRINTF 1
+#define HAVE_VSNPRINTF 1
+#define HAVE_M_PI
+#define HAVE_ATAN 1
+#define HAVE_ATAN2 1
+#define HAVE_CEIL 1
+#define HAVE_COPYSIGN 1
+#define HAVE_COS 1
+#define HAVE_COSF 1
+#define HAVE_FABS 1
+#define HAVE_FLOOR 1
+#define HAVE_LOG 1
+#define HAVE_POW 1
+#define HAVE_SCALBN 1
+#define HAVE_SIN 1
+#define HAVE_SINF 1
+#define HAVE_SQRT 1
+#define HAVE_FSEEKO 1
+#define HAVE_FSEEKO64 1
+#define HAVE_SIGACTION 1
+#define HAVE_SA_SIGACTION 1
+#define HAVE_SETJMP 1
+#define HAVE_NANOSLEEP 1
+#define HAVE_SYSCONF 1
+
+#define HAVE_CLOCK_GETTIME 1
+
+#define HAVE_MPROTECT 1
+#define HAVE_ICONV 1
+#define HAVE_PTHREAD_SETNAME_NP 1
+
+#define HAVE_SEM_TIMEDWAIT 1
+
+#else
+#define HAVE_STDARG_H 1
+#define HAVE_STDDEF_H 1
+#define HAVE_STDINT_H 1
+#endif
+
+#define SDL_LOADSO_DISABLED 1
+
+#define SDL_AUDIO_DRIVER_ALSA 1
+
+#define SDL_AUDIO_DRIVER_PULSEAUDIO 1
+
+#define SDL_AUDIO_DRIVER_DISK 1
+#define SDL_AUDIO_DRIVER_DUMMY 1
+
+#define SDL_AUDIO_DRIVER_OSS 1
+
+#define SDL_INPUT_LINUXEV 1
+#define SDL_INPUT_TSLIB 1
+
+#define SDL_JOYSTICK_LINUX 1
+
+#define SDL_HAPTIC_LINUX 1
+
+#define SDL_LOADSO_DLOPEN 1
+
+#define SDL_THREAD_PTHREAD 1
+#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1
+
+#define SDL_TIMER_UNIX 1
+
+#define SDL_VIDEO_DRIVER_DUMMY 1
+
+#define SDL_VIDEO_DRIVER_X11 1
+
+#define SDL_VIDEO_DRIVER_X11_XCURSOR 1
+#define SDL_VIDEO_DRIVER_X11_XINERAMA 1
+#define SDL_VIDEO_DRIVER_X11_XINPUT2 1
+#define SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1
+#define SDL_VIDEO_DRIVER_X11_XRANDR 1
+#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1
+#define SDL_VIDEO_DRIVER_X11_XSHAPE 1
+#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1
+#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1
+
+#define SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY 1
+#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1
+
+#define SDL_VIDEO_RENDER_OGL 1
+
+#define SDL_VIDEO_OPENGL 1
+
+#define SDL_VIDEO_OPENGL_GLX 1
+
+#define SDL_POWER_LINUX 1
+
+#define SDL_ASSEMBLY_ROUTINES 1
+
+#endif
diff --git a/extern/sdlew/include/SDL2/SDL_cpuinfo.h b/extern/sdlew/include/SDL2/SDL_cpuinfo.h
new file mode 100644
index 00000000000..830f8d537dd
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_cpuinfo.h
@@ -0,0 +1,86 @@
+
+#ifndef _SDL_cpuinfo_h
+#define _SDL_cpuinfo_h
+
+#include "SDL_stdinc.h"
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+#include <intrin.h>
+#ifndef _WIN64
+#define __MMX__
+#define __3dNOW__
+#endif
+#define __SSE__
+#define __SSE2__
+#elif defined(__MINGW64_VERSION_MAJOR)
+#include <intrin.h>
+#else
+#ifdef __ALTIVEC__
+#if HAVE_ALTIVEC_H && !defined(__APPLE_ALTIVEC__)
+#include <altivec.h>
+#undef pixel
+#endif
+#endif
+#ifdef __MMX__
+#include <mmintrin.h>
+#endif
+#ifdef __3dNOW__
+#include <mm3dnow.h>
+#endif
+#ifdef __SSE__
+#include <xmmintrin.h>
+#endif
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+#endif
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL_CACHELINE_SIZE 128
+
+typedef int SDLCALL tSDL_GetCPUCount(void);
+
+typedef int SDLCALL tSDL_GetCPUCacheLineSize(void);
+
+typedef SDL_bool SDLCALL tSDL_HasRDTSC(void);
+
+typedef SDL_bool SDLCALL tSDL_HasAltiVec(void);
+
+typedef SDL_bool SDLCALL tSDL_HasMMX(void);
+
+typedef SDL_bool SDLCALL tSDL_Has3DNow(void);
+
+typedef SDL_bool SDLCALL tSDL_HasSSE(void);
+
+typedef SDL_bool SDLCALL tSDL_HasSSE2(void);
+
+typedef SDL_bool SDLCALL tSDL_HasSSE3(void);
+
+typedef SDL_bool SDLCALL tSDL_HasSSE41(void);
+
+typedef SDL_bool SDLCALL tSDL_HasSSE42(void);
+
+extern tSDL_GetCPUCount *SDL_GetCPUCount;
+extern tSDL_GetCPUCacheLineSize *SDL_GetCPUCacheLineSize;
+extern tSDL_HasRDTSC *SDL_HasRDTSC;
+extern tSDL_HasAltiVec *SDL_HasAltiVec;
+extern tSDL_HasMMX *SDL_HasMMX;
+extern tSDL_Has3DNow *SDL_Has3DNow;
+extern tSDL_HasSSE *SDL_HasSSE;
+extern tSDL_HasSSE2 *SDL_HasSSE2;
+extern tSDL_HasSSE3 *SDL_HasSSE3;
+extern tSDL_HasSSE41 *SDL_HasSSE41;
+extern tSDL_HasSSE42 *SDL_HasSSE42;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_endian.h b/extern/sdlew/include/SDL2/SDL_endian.h
new file mode 100644
index 00000000000..f039f0ebdec
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_endian.h
@@ -0,0 +1,193 @@
+
+#ifndef _SDL_endian_h
+#define _SDL_endian_h
+
+#include "SDL_stdinc.h"
+
+#define SDL_LIL_ENDIAN 1234
+#define SDL_BIG_ENDIAN 4321
+
+#ifndef SDL_BYTEORDER
+#ifdef __linux__
+#include <endian.h>
+#define SDL_BYTEORDER __BYTE_ORDER
+#else
+#if defined(__hppa__) || \
+ defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
+ (defined(__MIPS__) && defined(__MISPEB__)) || \
+ defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
+ defined(__sparc__)
+#define SDL_BYTEORDER SDL_BIG_ENDIAN
+#else
+#define SDL_BYTEORDER SDL_LIL_ENDIAN
+#endif
+#endif
+#endif
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__GNUC__) && defined(__i386__) && \
+ !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 )
+SDL_FORCE_INLINE Uint16
+SDL_Swap16(Uint16 x)
+{
+ __asm__("xchgb %b0,%h0": "=q"(x):"0"(x));
+ return x;
+}
+#elif defined(__GNUC__) && defined(__x86_64__)
+SDL_FORCE_INLINE Uint16
+SDL_Swap16(Uint16 x)
+{
+ __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x));
+ return x;
+}
+#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
+SDL_FORCE_INLINE Uint16
+SDL_Swap16(Uint16 x)
+{
+ int result;
+
+ __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x));
+ return (Uint16)result;
+}
+#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__)
+SDL_FORCE_INLINE Uint16
+SDL_Swap16(Uint16 x)
+{
+ __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc");
+ return x;
+}
+#else
+SDL_FORCE_INLINE Uint16
+SDL_Swap16(Uint16 x)
+{
+ return SDL_static_cast(Uint16, ((x << 8) | (x >> 8)));
+}
+#endif
+
+#if defined(__GNUC__) && defined(__i386__)
+SDL_FORCE_INLINE Uint32
+SDL_Swap32(Uint32 x)
+{
+ __asm__("bswap %0": "=r"(x):"0"(x));
+ return x;
+}
+#elif defined(__GNUC__) && defined(__x86_64__)
+SDL_FORCE_INLINE Uint32
+SDL_Swap32(Uint32 x)
+{
+ __asm__("bswapl %0": "=r"(x):"0"(x));
+ return x;
+}
+#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
+SDL_FORCE_INLINE Uint32
+SDL_Swap32(Uint32 x)
+{
+ Uint32 result;
+
+ __asm__("rlwimi %0,%2,24,16,23": "=&r"(result):"0"(x >> 24), "r"(x));
+ __asm__("rlwimi %0,%2,8,8,15": "=&r"(result):"0"(result), "r"(x));
+ __asm__("rlwimi %0,%2,24,0,7": "=&r"(result):"0"(result), "r"(x));
+ return result;
+}
+#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__)
+SDL_FORCE_INLINE Uint32
+SDL_Swap32(Uint32 x)
+{
+ __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc");
+ return x;
+}
+#else
+SDL_FORCE_INLINE Uint32
+SDL_Swap32(Uint32 x)
+{
+ return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) |
+ ((x >> 8) & 0x0000FF00) | (x >> 24)));
+}
+#endif
+
+#if defined(__GNUC__) && defined(__i386__)
+SDL_FORCE_INLINE Uint64
+SDL_Swap64(Uint64 x)
+{
+ union
+ {
+ struct
+ {
+ Uint32 a, b;
+ } s;
+ Uint64 u;
+ } v;
+ v.u = x;
+ __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1": "=r"(v.s.a), "=r"(v.s.b):"0"(v.s.a),
+ "1"(v.s.
+ b));
+ return v.u;
+}
+#elif defined(__GNUC__) && defined(__x86_64__)
+SDL_FORCE_INLINE Uint64
+SDL_Swap64(Uint64 x)
+{
+ __asm__("bswapq %0": "=r"(x):"0"(x));
+ return x;
+}
+#else
+SDL_FORCE_INLINE Uint64
+SDL_Swap64(Uint64 x)
+{
+ Uint32 hi, lo;
+
+ lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
+ x >>= 32;
+ hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
+ x = SDL_Swap32(lo);
+ x <<= 32;
+ x |= SDL_Swap32(hi);
+ return (x);
+}
+#endif
+
+SDL_FORCE_INLINE float
+SDL_SwapFloat(float x)
+{
+ union
+ {
+ float f;
+ Uint32 ui32;
+ } swapper;
+ swapper.f = x;
+ swapper.ui32 = SDL_Swap32(swapper.ui32);
+ return swapper.f;
+}
+
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+#define SDL_SwapLE16(X) (X)
+#define SDL_SwapLE32(X) (X)
+#define SDL_SwapLE64(X) (X)
+#define SDL_SwapFloatLE(X) (X)
+#define SDL_SwapBE16(X) SDL_Swap16(X)
+#define SDL_SwapBE32(X) SDL_Swap32(X)
+#define SDL_SwapBE64(X) SDL_Swap64(X)
+#define SDL_SwapFloatBE(X) SDL_SwapFloat(X)
+#else
+#define SDL_SwapLE16(X) SDL_Swap16(X)
+#define SDL_SwapLE32(X) SDL_Swap32(X)
+#define SDL_SwapLE64(X) SDL_Swap64(X)
+#define SDL_SwapFloatLE(X) SDL_SwapFloat(X)
+#define SDL_SwapBE16(X) (X)
+#define SDL_SwapBE32(X) (X)
+#define SDL_SwapBE64(X) (X)
+#define SDL_SwapFloatBE(X) (X)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_error.h b/extern/sdlew/include/SDL2/SDL_error.h
new file mode 100644
index 00000000000..8bef6c109be
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_error.h
@@ -0,0 +1,43 @@
+
+#ifndef _SDL_error_h
+#define _SDL_error_h
+
+#include "SDL_stdinc.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int SDLCALL tSDL_SetError(const char *fmt, ...);
+typedef const char * SDLCALL tSDL_GetError(void);
+typedef void SDLCALL tSDL_ClearError(void);
+
+#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM)
+#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED)
+#define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param))
+typedef enum
+{
+ SDL_ENOMEM,
+ SDL_EFREAD,
+ SDL_EFWRITE,
+ SDL_EFSEEK,
+ SDL_UNSUPPORTED,
+ SDL_LASTERROR
+} SDL_errorcode;
+
+typedef int SDLCALL tSDL_Error(SDL_errorcode code);
+
+extern tSDL_SetError *SDL_SetError;
+extern tSDL_GetError *SDL_GetError;
+extern tSDL_ClearError *SDL_ClearError;
+extern tSDL_Error *SDL_Error;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_events.h b/extern/sdlew/include/SDL2/SDL_events.h
new file mode 100644
index 00000000000..41a0b479703
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_events.h
@@ -0,0 +1,446 @@
+
+#ifndef _SDL_events_h
+#define _SDL_events_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_video.h"
+#include "SDL_keyboard.h"
+#include "SDL_mouse.h"
+#include "SDL_joystick.h"
+#include "SDL_gamecontroller.h"
+#include "SDL_quit.h"
+#include "SDL_gesture.h"
+#include "SDL_touch.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL_RELEASED 0
+#define SDL_PRESSED 1
+
+typedef enum
+{
+ SDL_FIRSTEVENT = 0,
+
+ SDL_QUIT = 0x100,
+
+ SDL_APP_TERMINATING,
+ SDL_APP_LOWMEMORY,
+ SDL_APP_WILLENTERBACKGROUND,
+ SDL_APP_DIDENTERBACKGROUND,
+ SDL_APP_WILLENTERFOREGROUND,
+ SDL_APP_DIDENTERFOREGROUND,
+
+ SDL_WINDOWEVENT = 0x200,
+ SDL_SYSWMEVENT,
+
+ SDL_KEYDOWN = 0x300,
+ SDL_KEYUP,
+ SDL_TEXTEDITING,
+ SDL_TEXTINPUT,
+
+ SDL_MOUSEMOTION = 0x400,
+ SDL_MOUSEBUTTONDOWN,
+ SDL_MOUSEBUTTONUP,
+ SDL_MOUSEWHEEL,
+
+ SDL_JOYAXISMOTION = 0x600,
+ SDL_JOYBALLMOTION,
+ SDL_JOYHATMOTION,
+ SDL_JOYBUTTONDOWN,
+ SDL_JOYBUTTONUP,
+ SDL_JOYDEVICEADDED,
+ SDL_JOYDEVICEREMOVED,
+
+ SDL_CONTROLLERAXISMOTION = 0x650,
+ SDL_CONTROLLERBUTTONDOWN,
+ SDL_CONTROLLERBUTTONUP,
+ SDL_CONTROLLERDEVICEADDED,
+ SDL_CONTROLLERDEVICEREMOVED,
+ SDL_CONTROLLERDEVICEREMAPPED,
+
+ SDL_FINGERDOWN = 0x700,
+ SDL_FINGERUP,
+ SDL_FINGERMOTION,
+
+ SDL_DOLLARGESTURE = 0x800,
+ SDL_DOLLARRECORD,
+ SDL_MULTIGESTURE,
+
+ SDL_CLIPBOARDUPDATE = 0x900,
+
+ SDL_DROPFILE = 0x1000,
+
+ SDL_USEREVENT = 0x8000,
+
+ SDL_LASTEVENT = 0xFFFF
+} SDL_EventType;
+
+typedef struct SDL_CommonEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+} SDL_CommonEvent;
+
+typedef struct SDL_WindowEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ Uint8 event;
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+ Sint32 data1;
+ Sint32 data2;
+} SDL_WindowEvent;
+
+typedef struct SDL_KeyboardEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ Uint8 state;
+ Uint8 repeat;
+ Uint8 padding2;
+ Uint8 padding3;
+ SDL_Keysym keysym;
+} SDL_KeyboardEvent;
+
+#define SDL_TEXTEDITINGEVENT_TEXT_SIZE (32)
+
+typedef struct SDL_TextEditingEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
+ Sint32 start;
+ Sint32 length;
+} SDL_TextEditingEvent;
+
+#define SDL_TEXTINPUTEVENT_TEXT_SIZE (32)
+
+typedef struct SDL_TextInputEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
+} SDL_TextInputEvent;
+
+typedef struct SDL_MouseMotionEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ Uint32 which;
+ Uint32 state;
+ Sint32 x;
+ Sint32 y;
+ Sint32 xrel;
+ Sint32 yrel;
+} SDL_MouseMotionEvent;
+
+typedef struct SDL_MouseButtonEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ Uint32 which;
+ Uint8 button;
+ Uint8 state;
+ Uint8 padding1;
+ Uint8 padding2;
+ Sint32 x;
+ Sint32 y;
+} SDL_MouseButtonEvent;
+
+typedef struct SDL_MouseWheelEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ Uint32 which;
+ Sint32 x;
+ Sint32 y;
+} SDL_MouseWheelEvent;
+
+typedef struct SDL_JoyAxisEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ SDL_JoystickID which;
+ Uint8 axis;
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+ Sint16 value;
+ Uint16 padding4;
+} SDL_JoyAxisEvent;
+
+typedef struct SDL_JoyBallEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ SDL_JoystickID which;
+ Uint8 ball;
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+ Sint16 xrel;
+ Sint16 yrel;
+} SDL_JoyBallEvent;
+
+typedef struct SDL_JoyHatEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ SDL_JoystickID which;
+ Uint8 hat;
+ Uint8 value;
+ Uint8 padding1;
+ Uint8 padding2;
+} SDL_JoyHatEvent;
+
+typedef struct SDL_JoyButtonEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ SDL_JoystickID which;
+ Uint8 button;
+ Uint8 state;
+ Uint8 padding1;
+ Uint8 padding2;
+} SDL_JoyButtonEvent;
+
+typedef struct SDL_JoyDeviceEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ Sint32 which;
+} SDL_JoyDeviceEvent;
+
+typedef struct SDL_ControllerAxisEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ SDL_JoystickID which;
+ Uint8 axis;
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
+ Sint16 value;
+ Uint16 padding4;
+} SDL_ControllerAxisEvent;
+
+typedef struct SDL_ControllerButtonEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ SDL_JoystickID which;
+ Uint8 button;
+ Uint8 state;
+ Uint8 padding1;
+ Uint8 padding2;
+} SDL_ControllerButtonEvent;
+
+typedef struct SDL_ControllerDeviceEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ Sint32 which;
+} SDL_ControllerDeviceEvent;
+
+typedef struct SDL_TouchFingerEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ SDL_TouchID touchId;
+ SDL_FingerID fingerId;
+ float x;
+ float y;
+ float dx;
+ float dy;
+ float pressure;
+} SDL_TouchFingerEvent;
+
+typedef struct SDL_MultiGestureEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ SDL_TouchID touchId;
+ float dTheta;
+ float dDist;
+ float x;
+ float y;
+ Uint16 numFingers;
+ Uint16 padding;
+} SDL_MultiGestureEvent;
+
+typedef struct SDL_DollarGestureEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ SDL_TouchID touchId;
+ SDL_GestureID gestureId;
+ Uint32 numFingers;
+ float error;
+ float x;
+ float y;
+} SDL_DollarGestureEvent;
+
+typedef struct SDL_DropEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ char *file;
+} SDL_DropEvent;
+
+typedef struct SDL_QuitEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+} SDL_QuitEvent;
+
+typedef struct SDL_OSEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+} SDL_OSEvent;
+
+typedef struct SDL_UserEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ Uint32 windowID;
+ Sint32 code;
+ void *data1;
+ void *data2;
+} SDL_UserEvent;
+
+struct SDL_SysWMmsg;
+typedef struct SDL_SysWMmsg SDL_SysWMmsg;
+
+typedef struct SDL_SysWMEvent
+{
+ Uint32 type;
+ Uint32 timestamp;
+ SDL_SysWMmsg *msg;
+} SDL_SysWMEvent;
+
+typedef union SDL_Event
+{
+ Uint32 type;
+ SDL_CommonEvent common;
+ SDL_WindowEvent window;
+ SDL_KeyboardEvent key;
+ SDL_TextEditingEvent edit;
+ SDL_TextInputEvent text;
+ SDL_MouseMotionEvent motion;
+ SDL_MouseButtonEvent button;
+ SDL_MouseWheelEvent wheel;
+ SDL_JoyAxisEvent jaxis;
+ SDL_JoyBallEvent jball;
+ SDL_JoyHatEvent jhat;
+ SDL_JoyButtonEvent jbutton;
+ SDL_JoyDeviceEvent jdevice;
+ SDL_ControllerAxisEvent caxis;
+ SDL_ControllerButtonEvent cbutton;
+ SDL_ControllerDeviceEvent cdevice;
+ SDL_QuitEvent quit;
+ SDL_UserEvent user;
+ SDL_SysWMEvent syswm;
+ SDL_TouchFingerEvent tfinger;
+ SDL_MultiGestureEvent mgesture;
+ SDL_DollarGestureEvent dgesture;
+ SDL_DropEvent drop;
+
+ Uint8 padding[56];
+} SDL_Event;
+
+typedef void SDLCALL tSDL_PumpEvents(void);
+
+typedef enum
+{
+ SDL_ADDEVENT,
+ SDL_PEEKEVENT,
+ SDL_GETEVENT
+} SDL_eventaction;
+
+typedef int SDLCALL tSDL_PeepEvents(SDL_Event * events, int numevents,
+ SDL_eventaction action,
+ Uint32 minType, Uint32 maxType);
+
+typedef SDL_bool SDLCALL tSDL_HasEvent(Uint32 type);
+typedef SDL_bool SDLCALL tSDL_HasEvents(Uint32 minType, Uint32 maxType);
+
+typedef void SDLCALL tSDL_FlushEvent(Uint32 type);
+typedef void SDLCALL tSDL_FlushEvents(Uint32 minType, Uint32 maxType);
+
+typedef int SDLCALL tSDL_PollEvent(SDL_Event * event);
+
+typedef int SDLCALL tSDL_WaitEvent(SDL_Event * event);
+
+typedef int SDLCALL tSDL_WaitEventTimeout(SDL_Event * event,
+ int timeout);
+
+typedef int SDLCALL tSDL_PushEvent(SDL_Event * event);
+
+typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event);
+
+typedef void SDLCALL tSDL_SetEventFilter(SDL_EventFilter filter,
+ void *userdata);
+
+typedef SDL_bool SDLCALL tSDL_GetEventFilter(SDL_EventFilter * filter,
+ void **userdata);
+
+typedef void SDLCALL tSDL_AddEventWatch(SDL_EventFilter filter,
+ void *userdata);
+
+typedef void SDLCALL tSDL_DelEventWatch(SDL_EventFilter filter,
+ void *userdata);
+
+typedef void SDLCALL tSDL_FilterEvents(SDL_EventFilter filter,
+ void *userdata);
+
+#define SDL_QUERY -1
+#define SDL_IGNORE 0
+#define SDL_DISABLE 0
+#define SDL_ENABLE 1
+
+typedef Uint8 SDLCALL tSDL_EventState(Uint32 type, int state);
+
+#define SDL_GetEventState(type) SDL_EventState(type, SDL_QUERY)
+
+typedef Uint32 SDLCALL tSDL_RegisterEvents(int numevents);
+
+extern tSDL_PumpEvents *SDL_PumpEvents;
+extern tSDL_PeepEvents *SDL_PeepEvents;
+extern tSDL_HasEvent *SDL_HasEvent;
+extern tSDL_HasEvents *SDL_HasEvents;
+extern tSDL_FlushEvent *SDL_FlushEvent;
+extern tSDL_FlushEvents *SDL_FlushEvents;
+extern tSDL_PollEvent *SDL_PollEvent;
+extern tSDL_WaitEvent *SDL_WaitEvent;
+extern tSDL_WaitEventTimeout *SDL_WaitEventTimeout;
+extern tSDL_PushEvent *SDL_PushEvent;
+extern tSDL_SetEventFilter *SDL_SetEventFilter;
+extern tSDL_GetEventFilter *SDL_GetEventFilter;
+extern tSDL_AddEventWatch *SDL_AddEventWatch;
+extern tSDL_DelEventWatch *SDL_DelEventWatch;
+extern tSDL_FilterEvents *SDL_FilterEvents;
+extern tSDL_EventState *SDL_EventState;
+extern tSDL_RegisterEvents *SDL_RegisterEvents;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_gamecontroller.h b/extern/sdlew/include/SDL2/SDL_gamecontroller.h
new file mode 100644
index 00000000000..baed2bd173a
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_gamecontroller.h
@@ -0,0 +1,143 @@
+
+#ifndef _SDL_gamecontroller_h
+#define _SDL_gamecontroller_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_joystick.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _SDL_GameController;
+typedef struct _SDL_GameController SDL_GameController;
+
+typedef enum
+{
+ SDL_CONTROLLER_BINDTYPE_NONE = 0,
+ SDL_CONTROLLER_BINDTYPE_BUTTON,
+ SDL_CONTROLLER_BINDTYPE_AXIS,
+ SDL_CONTROLLER_BINDTYPE_HAT
+} SDL_GameControllerBindType;
+
+typedef struct SDL_GameControllerButtonBind
+{
+ SDL_GameControllerBindType bindType;
+ union
+ {
+ int button;
+ int axis;
+ struct {
+ int hat;
+ int hat_mask;
+ } hat;
+ } value;
+
+} SDL_GameControllerButtonBind;
+
+typedef int SDLCALL tSDL_GameControllerAddMapping( const char* mappingString );
+
+typedef char * SDLCALL tSDL_GameControllerMappingForGUID( SDL_JoystickGUID guid );
+
+typedef char * SDLCALL tSDL_GameControllerMapping( SDL_GameController * gamecontroller );
+
+typedef SDL_bool SDLCALL tSDL_IsGameController(int joystick_index);
+
+typedef const char * SDLCALL tSDL_GameControllerNameForIndex(int joystick_index);
+
+typedef SDL_GameController * SDLCALL tSDL_GameControllerOpen(int joystick_index);
+
+typedef const char * SDLCALL tSDL_GameControllerName(SDL_GameController *gamecontroller);
+
+typedef SDL_bool SDLCALL tSDL_GameControllerGetAttached(SDL_GameController *gamecontroller);
+
+typedef SDL_Joystick * SDLCALL tSDL_GameControllerGetJoystick(SDL_GameController *gamecontroller);
+
+typedef int SDLCALL tSDL_GameControllerEventState(int state);
+
+typedef void SDLCALL tSDL_GameControllerUpdate(void);
+
+typedef enum
+{
+ SDL_CONTROLLER_AXIS_INVALID = -1,
+ SDL_CONTROLLER_AXIS_LEFTX,
+ SDL_CONTROLLER_AXIS_LEFTY,
+ SDL_CONTROLLER_AXIS_RIGHTX,
+ SDL_CONTROLLER_AXIS_RIGHTY,
+ SDL_CONTROLLER_AXIS_TRIGGERLEFT,
+ SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
+ SDL_CONTROLLER_AXIS_MAX
+} SDL_GameControllerAxis;
+
+typedef SDL_GameControllerAxis SDLCALL tSDL_GameControllerGetAxisFromString(const char *pchString);
+
+extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis);
+
+extern DECLSPEC SDL_GameControllerButtonBind SDLCALL
+SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller,
+ SDL_GameControllerAxis axis);
+
+extern DECLSPEC Sint16 SDLCALL
+SDL_GameControllerGetAxis(SDL_GameController *gamecontroller,
+ SDL_GameControllerAxis axis);
+
+typedef enum
+{
+ SDL_CONTROLLER_BUTTON_INVALID = -1,
+ SDL_CONTROLLER_BUTTON_A,
+ SDL_CONTROLLER_BUTTON_B,
+ SDL_CONTROLLER_BUTTON_X,
+ SDL_CONTROLLER_BUTTON_Y,
+ SDL_CONTROLLER_BUTTON_BACK,
+ SDL_CONTROLLER_BUTTON_GUIDE,
+ SDL_CONTROLLER_BUTTON_START,
+ SDL_CONTROLLER_BUTTON_LEFTSTICK,
+ SDL_CONTROLLER_BUTTON_RIGHTSTICK,
+ SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
+ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
+ SDL_CONTROLLER_BUTTON_DPAD_UP,
+ SDL_CONTROLLER_BUTTON_DPAD_DOWN,
+ SDL_CONTROLLER_BUTTON_DPAD_LEFT,
+ SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
+ SDL_CONTROLLER_BUTTON_MAX
+} SDL_GameControllerButton;
+
+typedef SDL_GameControllerButton SDLCALL tSDL_GameControllerGetButtonFromString(const char *pchString);
+
+extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForButton(SDL_GameControllerButton button);
+
+extern DECLSPEC SDL_GameControllerButtonBind SDLCALL
+SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller,
+ SDL_GameControllerButton button);
+
+typedef Uint8 SDLCALL tSDL_GameControllerGetButton(SDL_GameController *gamecontroller,
+ SDL_GameControllerButton button);
+
+typedef void SDLCALL tSDL_GameControllerClose(SDL_GameController *gamecontroller);
+
+extern tSDL_GameControllerAddMapping *SDL_GameControllerAddMapping;
+extern tSDL_GameControllerMappingForGUID *SDL_GameControllerMappingForGUID;
+extern tSDL_GameControllerMapping *SDL_GameControllerMapping;
+extern tSDL_IsGameController *SDL_IsGameController;
+extern tSDL_GameControllerNameForIndex *SDL_GameControllerNameForIndex;
+extern tSDL_GameControllerOpen *SDL_GameControllerOpen;
+extern tSDL_GameControllerName *SDL_GameControllerName;
+extern tSDL_GameControllerGetAttached *SDL_GameControllerGetAttached;
+extern tSDL_GameControllerGetJoystick *SDL_GameControllerGetJoystick;
+extern tSDL_GameControllerEventState *SDL_GameControllerEventState;
+extern tSDL_GameControllerUpdate *SDL_GameControllerUpdate;
+extern tSDL_GameControllerGetAxisFromString *SDL_GameControllerGetAxisFromString;
+extern tSDL_GameControllerGetButtonFromString *SDL_GameControllerGetButtonFromString;
+extern tSDL_GameControllerGetButton *SDL_GameControllerGetButton;
+extern tSDL_GameControllerClose *SDL_GameControllerClose;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_gesture.h b/extern/sdlew/include/SDL2/SDL_gesture.h
new file mode 100644
index 00000000000..9909d9d13d1
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_gesture.h
@@ -0,0 +1,38 @@
+
+#ifndef _SDL_gesture_h
+#define _SDL_gesture_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_video.h"
+
+#include "SDL_touch.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef Sint64 SDL_GestureID;
+
+typedef int SDLCALL tSDL_RecordGesture(SDL_TouchID touchId);
+
+typedef int SDLCALL tSDL_SaveAllDollarTemplates(SDL_RWops *src);
+
+typedef int SDLCALL tSDL_SaveDollarTemplate(SDL_GestureID gestureId,SDL_RWops *src);
+
+typedef int SDLCALL tSDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src);
+
+extern tSDL_RecordGesture *SDL_RecordGesture;
+extern tSDL_SaveAllDollarTemplates *SDL_SaveAllDollarTemplates;
+extern tSDL_SaveDollarTemplate *SDL_SaveDollarTemplate;
+extern tSDL_LoadDollarTemplates *SDL_LoadDollarTemplates;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_haptic.h b/extern/sdlew/include/SDL2/SDL_haptic.h
new file mode 100644
index 00000000000..88fee82e549
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_haptic.h
@@ -0,0 +1,302 @@
+
+#ifndef _SDL_haptic_h
+#define _SDL_haptic_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_joystick.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _SDL_Haptic;
+typedef struct _SDL_Haptic SDL_Haptic;
+
+#define SDL_HAPTIC_CONSTANT (1<<0)
+
+#define SDL_HAPTIC_SINE (1<<1)
+
+#define SDL_HAPTIC_LEFTRIGHT (1<<2)
+
+#define SDL_HAPTIC_TRIANGLE (1<<3)
+
+#define SDL_HAPTIC_SAWTOOTHUP (1<<4)
+
+#define SDL_HAPTIC_SAWTOOTHDOWN (1<<5)
+
+#define SDL_HAPTIC_RAMP (1<<6)
+
+#define SDL_HAPTIC_SPRING (1<<7)
+
+#define SDL_HAPTIC_DAMPER (1<<8)
+
+#define SDL_HAPTIC_INERTIA (1<<9)
+
+#define SDL_HAPTIC_FRICTION (1<<10)
+
+#define SDL_HAPTIC_CUSTOM (1<<11)
+
+#define SDL_HAPTIC_GAIN (1<<12)
+
+#define SDL_HAPTIC_AUTOCENTER (1<<13)
+
+#define SDL_HAPTIC_STATUS (1<<14)
+
+#define SDL_HAPTIC_PAUSE (1<<15)
+
+#define SDL_HAPTIC_POLAR 0
+
+#define SDL_HAPTIC_CARTESIAN 1
+
+#define SDL_HAPTIC_SPHERICAL 2
+
+#define SDL_HAPTIC_INFINITY 4294967295U
+
+typedef struct SDL_HapticDirection
+{
+ Uint8 type;
+ Sint32 dir[3];
+} SDL_HapticDirection;
+
+typedef struct SDL_HapticConstant
+{
+
+ Uint16 type;
+ SDL_HapticDirection direction;
+
+ Uint32 length;
+ Uint16 delay;
+
+ Uint16 button;
+ Uint16 interval;
+
+ Sint16 level;
+
+ Uint16 attack_length;
+ Uint16 attack_level;
+ Uint16 fade_length;
+ Uint16 fade_level;
+} SDL_HapticConstant;
+
+typedef struct SDL_HapticPeriodic
+{
+
+ Uint16 type;
+ SDL_HapticDirection direction;
+
+ Uint32 length;
+ Uint16 delay;
+
+ Uint16 button;
+ Uint16 interval;
+
+ Uint16 period;
+ Sint16 magnitude;
+ Sint16 offset;
+ Uint16 phase;
+
+ Uint16 attack_length;
+ Uint16 attack_level;
+ Uint16 fade_length;
+ Uint16 fade_level;
+} SDL_HapticPeriodic;
+
+typedef struct SDL_HapticCondition
+{
+
+ Uint16 type;
+ SDL_HapticDirection direction;
+
+ Uint32 length;
+ Uint16 delay;
+
+ Uint16 button;
+ Uint16 interval;
+
+ Uint16 right_sat[3];
+ Uint16 left_sat[3];
+ Sint16 right_coeff[3];
+ Sint16 left_coeff[3];
+ Uint16 deadband[3];
+ Sint16 center[3];
+} SDL_HapticCondition;
+
+typedef struct SDL_HapticRamp
+{
+
+ Uint16 type;
+ SDL_HapticDirection direction;
+
+ Uint32 length;
+ Uint16 delay;
+
+ Uint16 button;
+ Uint16 interval;
+
+ Sint16 start;
+ Sint16 end;
+
+ Uint16 attack_length;
+ Uint16 attack_level;
+ Uint16 fade_length;
+ Uint16 fade_level;
+} SDL_HapticRamp;
+
+typedef struct SDL_HapticLeftRight
+{
+
+ Uint16 type;
+
+ Uint32 length;
+
+ Uint16 large_magnitude;
+ Uint16 small_magnitude;
+} SDL_HapticLeftRight;
+
+typedef struct SDL_HapticCustom
+{
+
+ Uint16 type;
+ SDL_HapticDirection direction;
+
+ Uint32 length;
+ Uint16 delay;
+
+ Uint16 button;
+ Uint16 interval;
+
+ Uint8 channels;
+ Uint16 period;
+ Uint16 samples;
+ Uint16 *data;
+
+ Uint16 attack_length;
+ Uint16 attack_level;
+ Uint16 fade_length;
+ Uint16 fade_level;
+} SDL_HapticCustom;
+
+typedef union SDL_HapticEffect
+{
+
+ Uint16 type;
+ SDL_HapticConstant constant;
+ SDL_HapticPeriodic periodic;
+ SDL_HapticCondition condition;
+ SDL_HapticRamp ramp;
+ SDL_HapticLeftRight leftright;
+ SDL_HapticCustom custom;
+} SDL_HapticEffect;
+
+typedef int SDLCALL tSDL_NumHaptics(void);
+
+typedef const char * SDLCALL tSDL_HapticName(int device_index);
+
+typedef SDL_Haptic * SDLCALL tSDL_HapticOpen(int device_index);
+
+typedef int SDLCALL tSDL_HapticOpened(int device_index);
+
+typedef int SDLCALL tSDL_HapticIndex(SDL_Haptic * haptic);
+
+typedef int SDLCALL tSDL_MouseIsHaptic(void);
+
+typedef SDL_Haptic * SDLCALL tSDL_HapticOpenFromMouse(void);
+
+typedef int SDLCALL tSDL_JoystickIsHaptic(SDL_Joystick * joystick);
+
+typedef SDL_Haptic * SDLCALL tSDL_HapticOpenFromJoystick(SDL_Joystick *
+ joystick);
+
+typedef void SDLCALL tSDL_HapticClose(SDL_Haptic * haptic);
+
+typedef int SDLCALL tSDL_HapticNumEffects(SDL_Haptic * haptic);
+
+typedef int SDLCALL tSDL_HapticNumEffectsPlaying(SDL_Haptic * haptic);
+
+extern DECLSPEC unsigned int SDLCALL SDL_HapticQuery(SDL_Haptic * haptic);
+
+typedef int SDLCALL tSDL_HapticNumAxes(SDL_Haptic * haptic);
+
+typedef int SDLCALL tSDL_HapticEffectSupported(SDL_Haptic * haptic,
+ SDL_HapticEffect *
+ effect);
+
+typedef int SDLCALL tSDL_HapticNewEffect(SDL_Haptic * haptic,
+ SDL_HapticEffect * effect);
+
+typedef int SDLCALL tSDL_HapticUpdateEffect(SDL_Haptic * haptic,
+ int effect,
+ SDL_HapticEffect * data);
+
+typedef int SDLCALL tSDL_HapticRunEffect(SDL_Haptic * haptic,
+ int effect,
+ Uint32 iterations);
+
+typedef int SDLCALL tSDL_HapticStopEffect(SDL_Haptic * haptic,
+ int effect);
+
+typedef void SDLCALL tSDL_HapticDestroyEffect(SDL_Haptic * haptic,
+ int effect);
+
+typedef int SDLCALL tSDL_HapticGetEffectStatus(SDL_Haptic * haptic,
+ int effect);
+
+typedef int SDLCALL tSDL_HapticSetGain(SDL_Haptic * haptic, int gain);
+
+typedef int SDLCALL tSDL_HapticSetAutocenter(SDL_Haptic * haptic,
+ int autocenter);
+
+typedef int SDLCALL tSDL_HapticPause(SDL_Haptic * haptic);
+
+typedef int SDLCALL tSDL_HapticUnpause(SDL_Haptic * haptic);
+
+typedef int SDLCALL tSDL_HapticStopAll(SDL_Haptic * haptic);
+
+typedef int SDLCALL tSDL_HapticRumbleSupported(SDL_Haptic * haptic);
+
+typedef int SDLCALL tSDL_HapticRumbleInit(SDL_Haptic * haptic);
+
+typedef int SDLCALL tSDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length );
+
+typedef int SDLCALL tSDL_HapticRumbleStop(SDL_Haptic * haptic);
+
+extern tSDL_NumHaptics *SDL_NumHaptics;
+extern tSDL_HapticName *SDL_HapticName;
+extern tSDL_HapticOpen *SDL_HapticOpen;
+extern tSDL_HapticOpened *SDL_HapticOpened;
+extern tSDL_HapticIndex *SDL_HapticIndex;
+extern tSDL_MouseIsHaptic *SDL_MouseIsHaptic;
+extern tSDL_HapticOpenFromMouse *SDL_HapticOpenFromMouse;
+extern tSDL_JoystickIsHaptic *SDL_JoystickIsHaptic;
+extern tSDL_HapticOpenFromJoystick *SDL_HapticOpenFromJoystick;
+extern tSDL_HapticClose *SDL_HapticClose;
+extern tSDL_HapticNumEffects *SDL_HapticNumEffects;
+extern tSDL_HapticNumEffectsPlaying *SDL_HapticNumEffectsPlaying;
+extern tSDL_HapticNumAxes *SDL_HapticNumAxes;
+extern tSDL_HapticEffectSupported *SDL_HapticEffectSupported;
+extern tSDL_HapticNewEffect *SDL_HapticNewEffect;
+extern tSDL_HapticUpdateEffect *SDL_HapticUpdateEffect;
+extern tSDL_HapticRunEffect *SDL_HapticRunEffect;
+extern tSDL_HapticStopEffect *SDL_HapticStopEffect;
+extern tSDL_HapticDestroyEffect *SDL_HapticDestroyEffect;
+extern tSDL_HapticGetEffectStatus *SDL_HapticGetEffectStatus;
+extern tSDL_HapticSetGain *SDL_HapticSetGain;
+extern tSDL_HapticSetAutocenter *SDL_HapticSetAutocenter;
+extern tSDL_HapticPause *SDL_HapticPause;
+extern tSDL_HapticUnpause *SDL_HapticUnpause;
+extern tSDL_HapticStopAll *SDL_HapticStopAll;
+extern tSDL_HapticRumbleSupported *SDL_HapticRumbleSupported;
+extern tSDL_HapticRumbleInit *SDL_HapticRumbleInit;
+extern tSDL_HapticRumblePlay *SDL_HapticRumblePlay;
+extern tSDL_HapticRumbleStop *SDL_HapticRumbleStop;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_hints.h b/extern/sdlew/include/SDL2/SDL_hints.h
new file mode 100644
index 00000000000..fbf9307d4d8
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_hints.h
@@ -0,0 +1,87 @@
+
+#ifndef _SDL_hints_h
+#define _SDL_hints_h
+
+#include "SDL_stdinc.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL_HINT_FRAMEBUFFER_ACCELERATION "SDL_FRAMEBUFFER_ACCELERATION"
+
+#define SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER"
+
+#define SDL_HINT_RENDER_OPENGL_SHADERS "SDL_RENDER_OPENGL_SHADERS"
+
+#define SDL_HINT_RENDER_SCALE_QUALITY "SDL_RENDER_SCALE_QUALITY"
+
+#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC"
+
+#define SDL_HINT_VIDEO_X11_XVIDMODE "SDL_VIDEO_X11_XVIDMODE"
+
+#define SDL_HINT_VIDEO_X11_XINERAMA "SDL_VIDEO_X11_XINERAMA"
+
+#define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR"
+
+#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD"
+
+#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS"
+
+#define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED"
+
+#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"
+
+#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED"
+
+#define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG"
+
+#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"
+
+#define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST"
+
+#define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION"
+
+typedef enum
+{
+ SDL_HINT_DEFAULT,
+ SDL_HINT_NORMAL,
+ SDL_HINT_OVERRIDE
+} SDL_HintPriority;
+
+typedef SDL_bool SDLCALL tSDL_SetHintWithPriority(const char *name,
+ const char *value,
+ SDL_HintPriority priority);
+
+typedef SDL_bool SDLCALL tSDL_SetHint(const char *name,
+ const char *value);
+
+typedef const char * SDLCALL tSDL_GetHint(const char *name);
+
+typedef void (*SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue);
+typedef void SDLCALL tSDL_AddHintCallback(const char *name,
+ SDL_HintCallback callback,
+ void *userdata);
+
+typedef void SDLCALL tSDL_DelHintCallback(const char *name,
+ SDL_HintCallback callback,
+ void *userdata);
+
+typedef void SDLCALL tSDL_ClearHints(void);
+
+extern tSDL_SetHintWithPriority *SDL_SetHintWithPriority;
+extern tSDL_SetHint *SDL_SetHint;
+extern tSDL_GetHint *SDL_GetHint;
+extern tSDL_AddHintCallback *SDL_AddHintCallback;
+extern tSDL_DelHintCallback *SDL_DelHintCallback;
+extern tSDL_ClearHints *SDL_ClearHints;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_joystick.h b/extern/sdlew/include/SDL2/SDL_joystick.h
new file mode 100644
index 00000000000..16e4d5ec312
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_joystick.h
@@ -0,0 +1,106 @@
+
+#ifndef _SDL_joystick_h
+#define _SDL_joystick_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _SDL_Joystick;
+typedef struct _SDL_Joystick SDL_Joystick;
+
+typedef struct {
+ Uint8 data[16];
+} SDL_JoystickGUID;
+
+typedef Sint32 SDL_JoystickID;
+
+typedef int SDLCALL tSDL_NumJoysticks(void);
+
+typedef const char * SDLCALL tSDL_JoystickNameForIndex(int device_index);
+
+typedef SDL_Joystick * SDLCALL tSDL_JoystickOpen(int device_index);
+
+typedef const char * SDLCALL tSDL_JoystickName(SDL_Joystick * joystick);
+
+typedef SDL_JoystickGUID SDLCALL tSDL_JoystickGetDeviceGUID(int device_index);
+
+typedef SDL_JoystickGUID SDLCALL tSDL_JoystickGetGUID(SDL_Joystick * joystick);
+
+extern DECLSPEC void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID);
+
+typedef SDL_JoystickGUID SDLCALL tSDL_JoystickGetGUIDFromString(const char *pchGUID);
+
+typedef SDL_bool SDLCALL tSDL_JoystickGetAttached(SDL_Joystick * joystick);
+
+typedef SDL_JoystickID SDLCALL tSDL_JoystickInstanceID(SDL_Joystick * joystick);
+
+typedef int SDLCALL tSDL_JoystickNumAxes(SDL_Joystick * joystick);
+
+typedef int SDLCALL tSDL_JoystickNumBalls(SDL_Joystick * joystick);
+
+typedef int SDLCALL tSDL_JoystickNumHats(SDL_Joystick * joystick);
+
+typedef int SDLCALL tSDL_JoystickNumButtons(SDL_Joystick * joystick);
+
+typedef void SDLCALL tSDL_JoystickUpdate(void);
+
+typedef int SDLCALL tSDL_JoystickEventState(int state);
+
+typedef Sint16 SDLCALL tSDL_JoystickGetAxis(SDL_Joystick * joystick,
+ int axis);
+
+#define SDL_HAT_CENTERED 0x00
+#define SDL_HAT_UP 0x01
+#define SDL_HAT_RIGHT 0x02
+#define SDL_HAT_DOWN 0x04
+#define SDL_HAT_LEFT 0x08
+#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP)
+#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN)
+#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP)
+#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN)
+
+typedef Uint8 SDLCALL tSDL_JoystickGetHat(SDL_Joystick * joystick,
+ int hat);
+
+typedef int SDLCALL tSDL_JoystickGetBall(SDL_Joystick * joystick,
+ int ball, int *dx, int *dy);
+
+typedef Uint8 SDLCALL tSDL_JoystickGetButton(SDL_Joystick * joystick,
+ int button);
+
+typedef void SDLCALL tSDL_JoystickClose(SDL_Joystick * joystick);
+
+extern tSDL_NumJoysticks *SDL_NumJoysticks;
+extern tSDL_JoystickNameForIndex *SDL_JoystickNameForIndex;
+extern tSDL_JoystickOpen *SDL_JoystickOpen;
+extern tSDL_JoystickName *SDL_JoystickName;
+extern tSDL_JoystickGetDeviceGUID *SDL_JoystickGetDeviceGUID;
+extern tSDL_JoystickGetGUID *SDL_JoystickGetGUID;
+extern tSDL_JoystickGetGUIDFromString *SDL_JoystickGetGUIDFromString;
+extern tSDL_JoystickGetAttached *SDL_JoystickGetAttached;
+extern tSDL_JoystickInstanceID *SDL_JoystickInstanceID;
+extern tSDL_JoystickNumAxes *SDL_JoystickNumAxes;
+extern tSDL_JoystickNumBalls *SDL_JoystickNumBalls;
+extern tSDL_JoystickNumHats *SDL_JoystickNumHats;
+extern tSDL_JoystickNumButtons *SDL_JoystickNumButtons;
+extern tSDL_JoystickUpdate *SDL_JoystickUpdate;
+extern tSDL_JoystickEventState *SDL_JoystickEventState;
+extern tSDL_JoystickGetAxis *SDL_JoystickGetAxis;
+extern tSDL_JoystickGetHat *SDL_JoystickGetHat;
+extern tSDL_JoystickGetBall *SDL_JoystickGetBall;
+extern tSDL_JoystickGetButton *SDL_JoystickGetButton;
+extern tSDL_JoystickClose *SDL_JoystickClose;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_keyboard.h b/extern/sdlew/include/SDL2/SDL_keyboard.h
new file mode 100644
index 00000000000..c2517b4f665
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_keyboard.h
@@ -0,0 +1,79 @@
+
+#ifndef _SDL_keyboard_h
+#define _SDL_keyboard_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_keycode.h"
+#include "SDL_video.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SDL_Keysym
+{
+ SDL_Scancode scancode;
+ SDL_Keycode sym;
+ Uint16 mod;
+ Uint32 unused;
+} SDL_Keysym;
+
+typedef SDL_Window * SDLCALL tSDL_GetKeyboardFocus(void);
+
+typedef const Uint8 * SDLCALL tSDL_GetKeyboardState(int *numkeys);
+
+typedef SDL_Keymod SDLCALL tSDL_GetModState(void);
+
+typedef void SDLCALL tSDL_SetModState(SDL_Keymod modstate);
+
+typedef SDL_Keycode SDLCALL tSDL_GetKeyFromScancode(SDL_Scancode scancode);
+
+typedef SDL_Scancode SDLCALL tSDL_GetScancodeFromKey(SDL_Keycode key);
+
+typedef const char * SDLCALL tSDL_GetScancodeName(SDL_Scancode scancode);
+
+typedef SDL_Scancode SDLCALL tSDL_GetScancodeFromName(const char *name);
+
+typedef const char * SDLCALL tSDL_GetKeyName(SDL_Keycode key);
+
+typedef SDL_Keycode SDLCALL tSDL_GetKeyFromName(const char *name);
+
+typedef void SDLCALL tSDL_StartTextInput(void);
+
+typedef SDL_bool SDLCALL tSDL_IsTextInputActive(void);
+
+typedef void SDLCALL tSDL_StopTextInput(void);
+
+typedef void SDLCALL tSDL_SetTextInputRect(SDL_Rect *rect);
+
+typedef SDL_bool SDLCALL tSDL_HasScreenKeyboardSupport(void);
+
+typedef SDL_bool SDLCALL tSDL_IsScreenKeyboardShown(SDL_Window *window);
+
+extern tSDL_GetKeyboardFocus *SDL_GetKeyboardFocus;
+extern tSDL_GetKeyboardState *SDL_GetKeyboardState;
+extern tSDL_GetModState *SDL_GetModState;
+extern tSDL_SetModState *SDL_SetModState;
+extern tSDL_GetKeyFromScancode *SDL_GetKeyFromScancode;
+extern tSDL_GetScancodeFromKey *SDL_GetScancodeFromKey;
+extern tSDL_GetScancodeName *SDL_GetScancodeName;
+extern tSDL_GetScancodeFromName *SDL_GetScancodeFromName;
+extern tSDL_GetKeyName *SDL_GetKeyName;
+extern tSDL_GetKeyFromName *SDL_GetKeyFromName;
+extern tSDL_StartTextInput *SDL_StartTextInput;
+extern tSDL_IsTextInputActive *SDL_IsTextInputActive;
+extern tSDL_StopTextInput *SDL_StopTextInput;
+extern tSDL_SetTextInputRect *SDL_SetTextInputRect;
+extern tSDL_HasScreenKeyboardSupport *SDL_HasScreenKeyboardSupport;
+extern tSDL_IsScreenKeyboardShown *SDL_IsScreenKeyboardShown;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_keycode.h b/extern/sdlew/include/SDL2/SDL_keycode.h
new file mode 100644
index 00000000000..28bc1bafb41
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_keycode.h
@@ -0,0 +1,301 @@
+
+#ifndef _SDL_keycode_h
+#define _SDL_keycode_h
+
+#include "SDL_stdinc.h"
+#include "SDL_scancode.h"
+
+typedef Sint32 SDL_Keycode;
+
+#define SDLK_SCANCODE_MASK (1<<30)
+#define SDL_SCANCODE_TO_KEYCODE(X) (X | SDLK_SCANCODE_MASK)
+
+enum
+{
+ SDLK_UNKNOWN = 0,
+
+ SDLK_RETURN = '\r',
+ SDLK_ESCAPE = '\033',
+ SDLK_BACKSPACE = '\b',
+ SDLK_TAB = '\t',
+ SDLK_SPACE = ' ',
+ SDLK_EXCLAIM = '!',
+ SDLK_QUOTEDBL = '"',
+ SDLK_HASH = '#',
+ SDLK_PERCENT = '%',
+ SDLK_DOLLAR = '$',
+ SDLK_AMPERSAND = '&',
+ SDLK_QUOTE = '\'',
+ SDLK_LEFTPAREN = '(',
+ SDLK_RIGHTPAREN = ')',
+ SDLK_ASTERISK = '*',
+ SDLK_PLUS = '+',
+ SDLK_COMMA = ',',
+ SDLK_MINUS = '-',
+ SDLK_PERIOD = '.',
+ SDLK_SLASH = '/',
+ SDLK_0 = '0',
+ SDLK_1 = '1',
+ SDLK_2 = '2',
+ SDLK_3 = '3',
+ SDLK_4 = '4',
+ SDLK_5 = '5',
+ SDLK_6 = '6',
+ SDLK_7 = '7',
+ SDLK_8 = '8',
+ SDLK_9 = '9',
+ SDLK_COLON = ':',
+ SDLK_SEMICOLON = ';',
+ SDLK_LESS = '<',
+ SDLK_EQUALS = '=',
+ SDLK_GREATER = '>',
+ SDLK_QUESTION = '?',
+ SDLK_AT = '@',
+
+ SDLK_LEFTBRACKET = '[',
+ SDLK_BACKSLASH = '\\',
+ SDLK_RIGHTBRACKET = ']',
+ SDLK_CARET = '^',
+ SDLK_UNDERSCORE = '_',
+ SDLK_BACKQUOTE = '`',
+ SDLK_a = 'a',
+ SDLK_b = 'b',
+ SDLK_c = 'c',
+ SDLK_d = 'd',
+ SDLK_e = 'e',
+ SDLK_f = 'f',
+ SDLK_g = 'g',
+ SDLK_h = 'h',
+ SDLK_i = 'i',
+ SDLK_j = 'j',
+ SDLK_k = 'k',
+ SDLK_l = 'l',
+ SDLK_m = 'm',
+ SDLK_n = 'n',
+ SDLK_o = 'o',
+ SDLK_p = 'p',
+ SDLK_q = 'q',
+ SDLK_r = 'r',
+ SDLK_s = 's',
+ SDLK_t = 't',
+ SDLK_u = 'u',
+ SDLK_v = 'v',
+ SDLK_w = 'w',
+ SDLK_x = 'x',
+ SDLK_y = 'y',
+ SDLK_z = 'z',
+
+ SDLK_CAPSLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CAPSLOCK),
+
+ SDLK_F1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1),
+ SDLK_F2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F2),
+ SDLK_F3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F3),
+ SDLK_F4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F4),
+ SDLK_F5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F5),
+ SDLK_F6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F6),
+ SDLK_F7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F7),
+ SDLK_F8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F8),
+ SDLK_F9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F9),
+ SDLK_F10 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F10),
+ SDLK_F11 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F11),
+ SDLK_F12 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F12),
+
+ SDLK_PRINTSCREEN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRINTSCREEN),
+ SDLK_SCROLLLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SCROLLLOCK),
+ SDLK_PAUSE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAUSE),
+ SDLK_INSERT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT),
+ SDLK_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME),
+ SDLK_PAGEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP),
+ SDLK_DELETE = '\177',
+ SDLK_END = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END),
+ SDLK_PAGEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN),
+ SDLK_RIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT),
+ SDLK_LEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LEFT),
+ SDLK_DOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DOWN),
+ SDLK_UP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UP),
+
+ SDLK_NUMLOCKCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_NUMLOCKCLEAR),
+ SDLK_KP_DIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DIVIDE),
+ SDLK_KP_MULTIPLY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MULTIPLY),
+ SDLK_KP_MINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MINUS),
+ SDLK_KP_PLUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUS),
+ SDLK_KP_ENTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_ENTER),
+ SDLK_KP_1 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_1),
+ SDLK_KP_2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_2),
+ SDLK_KP_3 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_3),
+ SDLK_KP_4 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_4),
+ SDLK_KP_5 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_5),
+ SDLK_KP_6 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_6),
+ SDLK_KP_7 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_7),
+ SDLK_KP_8 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_8),
+ SDLK_KP_9 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_9),
+ SDLK_KP_0 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_0),
+ SDLK_KP_PERIOD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERIOD),
+
+ SDLK_APPLICATION = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APPLICATION),
+ SDLK_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_POWER),
+ SDLK_KP_EQUALS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALS),
+ SDLK_F13 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F13),
+ SDLK_F14 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F14),
+ SDLK_F15 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F15),
+ SDLK_F16 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F16),
+ SDLK_F17 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F17),
+ SDLK_F18 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F18),
+ SDLK_F19 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F19),
+ SDLK_F20 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F20),
+ SDLK_F21 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F21),
+ SDLK_F22 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F22),
+ SDLK_F23 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F23),
+ SDLK_F24 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F24),
+ SDLK_EXECUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXECUTE),
+ SDLK_HELP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HELP),
+ SDLK_MENU = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MENU),
+ SDLK_SELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SELECT),
+ SDLK_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_STOP),
+ SDLK_AGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AGAIN),
+ SDLK_UNDO = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_UNDO),
+ SDLK_CUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CUT),
+ SDLK_COPY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COPY),
+ SDLK_PASTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PASTE),
+ SDLK_FIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_FIND),
+ SDLK_MUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MUTE),
+ SDLK_VOLUMEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEUP),
+ SDLK_VOLUMEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_VOLUMEDOWN),
+ SDLK_KP_COMMA = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COMMA),
+ SDLK_KP_EQUALSAS400 =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EQUALSAS400),
+
+ SDLK_ALTERASE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ALTERASE),
+ SDLK_SYSREQ = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SYSREQ),
+ SDLK_CANCEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CANCEL),
+ SDLK_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEAR),
+ SDLK_PRIOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PRIOR),
+ SDLK_RETURN2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RETURN2),
+ SDLK_SEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SEPARATOR),
+ SDLK_OUT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OUT),
+ SDLK_OPER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_OPER),
+ SDLK_CLEARAGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CLEARAGAIN),
+ SDLK_CRSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CRSEL),
+ SDLK_EXSEL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EXSEL),
+
+ SDLK_KP_00 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_00),
+ SDLK_KP_000 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_000),
+ SDLK_THOUSANDSSEPARATOR =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_THOUSANDSSEPARATOR),
+ SDLK_DECIMALSEPARATOR =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DECIMALSEPARATOR),
+ SDLK_CURRENCYUNIT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYUNIT),
+ SDLK_CURRENCYSUBUNIT =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CURRENCYSUBUNIT),
+ SDLK_KP_LEFTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTPAREN),
+ SDLK_KP_RIGHTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTPAREN),
+ SDLK_KP_LEFTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LEFTBRACE),
+ SDLK_KP_RIGHTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_RIGHTBRACE),
+ SDLK_KP_TAB = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_TAB),
+ SDLK_KP_BACKSPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BACKSPACE),
+ SDLK_KP_A = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_A),
+ SDLK_KP_B = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_B),
+ SDLK_KP_C = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_C),
+ SDLK_KP_D = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_D),
+ SDLK_KP_E = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_E),
+ SDLK_KP_F = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_F),
+ SDLK_KP_XOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_XOR),
+ SDLK_KP_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_POWER),
+ SDLK_KP_PERCENT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PERCENT),
+ SDLK_KP_LESS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_LESS),
+ SDLK_KP_GREATER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_GREATER),
+ SDLK_KP_AMPERSAND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AMPERSAND),
+ SDLK_KP_DBLAMPERSAND =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLAMPERSAND),
+ SDLK_KP_VERTICALBAR =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_VERTICALBAR),
+ SDLK_KP_DBLVERTICALBAR =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DBLVERTICALBAR),
+ SDLK_KP_COLON = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_COLON),
+ SDLK_KP_HASH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HASH),
+ SDLK_KP_SPACE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_SPACE),
+ SDLK_KP_AT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_AT),
+ SDLK_KP_EXCLAM = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_EXCLAM),
+ SDLK_KP_MEMSTORE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSTORE),
+ SDLK_KP_MEMRECALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMRECALL),
+ SDLK_KP_MEMCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMCLEAR),
+ SDLK_KP_MEMADD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMADD),
+ SDLK_KP_MEMSUBTRACT =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMSUBTRACT),
+ SDLK_KP_MEMMULTIPLY =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMMULTIPLY),
+ SDLK_KP_MEMDIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_MEMDIVIDE),
+ SDLK_KP_PLUSMINUS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_PLUSMINUS),
+ SDLK_KP_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEAR),
+ SDLK_KP_CLEARENTRY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_CLEARENTRY),
+ SDLK_KP_BINARY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_BINARY),
+ SDLK_KP_OCTAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_OCTAL),
+ SDLK_KP_DECIMAL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_DECIMAL),
+ SDLK_KP_HEXADECIMAL =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KP_HEXADECIMAL),
+
+ SDLK_LCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LCTRL),
+ SDLK_LSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LSHIFT),
+ SDLK_LALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LALT),
+ SDLK_LGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_LGUI),
+ SDLK_RCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RCTRL),
+ SDLK_RSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RSHIFT),
+ SDLK_RALT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RALT),
+ SDLK_RGUI = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RGUI),
+
+ SDLK_MODE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MODE),
+
+ SDLK_AUDIONEXT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIONEXT),
+ SDLK_AUDIOPREV = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPREV),
+ SDLK_AUDIOSTOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOSTOP),
+ SDLK_AUDIOPLAY = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOPLAY),
+ SDLK_AUDIOMUTE = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOMUTE),
+ SDLK_MEDIASELECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MEDIASELECT),
+ SDLK_WWW = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_WWW),
+ SDLK_MAIL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_MAIL),
+ SDLK_CALCULATOR = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALCULATOR),
+ SDLK_COMPUTER = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_COMPUTER),
+ SDLK_AC_SEARCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_SEARCH),
+ SDLK_AC_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_HOME),
+ SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BACK),
+ SDLK_AC_FORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_FORWARD),
+ SDLK_AC_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_STOP),
+ SDLK_AC_REFRESH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_REFRESH),
+ SDLK_AC_BOOKMARKS = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AC_BOOKMARKS),
+
+ SDLK_BRIGHTNESSDOWN =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSDOWN),
+ SDLK_BRIGHTNESSUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_BRIGHTNESSUP),
+ SDLK_DISPLAYSWITCH = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_DISPLAYSWITCH),
+ SDLK_KBDILLUMTOGGLE =
+ SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMTOGGLE),
+ SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMDOWN),
+ SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_KBDILLUMUP),
+ SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_EJECT),
+ SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SLEEP)
+};
+
+typedef enum
+{
+ KMOD_NONE = 0x0000,
+ KMOD_LSHIFT = 0x0001,
+ KMOD_RSHIFT = 0x0002,
+ KMOD_LCTRL = 0x0040,
+ KMOD_RCTRL = 0x0080,
+ KMOD_LALT = 0x0100,
+ KMOD_RALT = 0x0200,
+ KMOD_LGUI = 0x0400,
+ KMOD_RGUI = 0x0800,
+ KMOD_NUM = 0x1000,
+ KMOD_CAPS = 0x2000,
+ KMOD_MODE = 0x4000,
+ KMOD_RESERVED = 0x8000
+} SDL_Keymod;
+
+#define KMOD_CTRL (KMOD_LCTRL|KMOD_RCTRL)
+#define KMOD_SHIFT (KMOD_LSHIFT|KMOD_RSHIFT)
+#define KMOD_ALT (KMOD_LALT|KMOD_RALT)
+#define KMOD_GUI (KMOD_LGUI|KMOD_RGUI)
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_loadso.h b/extern/sdlew/include/SDL2/SDL_loadso.h
new file mode 100644
index 00000000000..942f096a360
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_loadso.h
@@ -0,0 +1,31 @@
+
+#ifndef _SDL_loadso_h
+#define _SDL_loadso_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void * SDLCALL tSDL_LoadObject(const char *sofile);
+
+typedef void * SDLCALL tSDL_LoadFunction(void *handle,
+ const char *name);
+
+typedef void SDLCALL tSDL_UnloadObject(void *handle);
+
+extern tSDL_LoadObject *SDL_LoadObject;
+extern tSDL_LoadFunction *SDL_LoadFunction;
+extern tSDL_UnloadObject *SDL_UnloadObject;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_log.h b/extern/sdlew/include/SDL2/SDL_log.h
new file mode 100644
index 00000000000..3add97a00f3
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_log.h
@@ -0,0 +1,111 @@
+
+#ifndef _SDL_log_h
+#define _SDL_log_h
+
+#include "SDL_stdinc.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL_MAX_LOG_MESSAGE 4096
+
+enum
+{
+ SDL_LOG_CATEGORY_APPLICATION,
+ SDL_LOG_CATEGORY_ERROR,
+ SDL_LOG_CATEGORY_ASSERT,
+ SDL_LOG_CATEGORY_SYSTEM,
+ SDL_LOG_CATEGORY_AUDIO,
+ SDL_LOG_CATEGORY_VIDEO,
+ SDL_LOG_CATEGORY_RENDER,
+ SDL_LOG_CATEGORY_INPUT,
+ SDL_LOG_CATEGORY_TEST,
+
+ SDL_LOG_CATEGORY_RESERVED1,
+ SDL_LOG_CATEGORY_RESERVED2,
+ SDL_LOG_CATEGORY_RESERVED3,
+ SDL_LOG_CATEGORY_RESERVED4,
+ SDL_LOG_CATEGORY_RESERVED5,
+ SDL_LOG_CATEGORY_RESERVED6,
+ SDL_LOG_CATEGORY_RESERVED7,
+ SDL_LOG_CATEGORY_RESERVED8,
+ SDL_LOG_CATEGORY_RESERVED9,
+ SDL_LOG_CATEGORY_RESERVED10,
+
+ SDL_LOG_CATEGORY_CUSTOM
+};
+
+typedef enum
+{
+ SDL_LOG_PRIORITY_VERBOSE = 1,
+ SDL_LOG_PRIORITY_DEBUG,
+ SDL_LOG_PRIORITY_INFO,
+ SDL_LOG_PRIORITY_WARN,
+ SDL_LOG_PRIORITY_ERROR,
+ SDL_LOG_PRIORITY_CRITICAL,
+ SDL_NUM_LOG_PRIORITIES
+} SDL_LogPriority;
+
+typedef void SDLCALL tSDL_LogSetAllPriority(SDL_LogPriority priority);
+
+typedef void SDLCALL tSDL_LogSetPriority(int category,
+ SDL_LogPriority priority);
+
+typedef SDL_LogPriority SDLCALL tSDL_LogGetPriority(int category);
+
+typedef void SDLCALL tSDL_LogResetPriorities(void);
+
+typedef void SDLCALL tSDL_Log(const char *fmt, ...);
+
+typedef void SDLCALL tSDL_LogVerbose(int category, const char *fmt, ...);
+
+typedef void SDLCALL tSDL_LogDebug(int category, const char *fmt, ...);
+
+typedef void SDLCALL tSDL_LogInfo(int category, const char *fmt, ...);
+
+typedef void SDLCALL tSDL_LogWarn(int category, const char *fmt, ...);
+
+typedef void SDLCALL tSDL_LogError(int category, const char *fmt, ...);
+
+typedef void SDLCALL tSDL_LogCritical(int category, const char *fmt, ...);
+
+typedef void SDLCALL tSDL_LogMessage(int category,
+ SDL_LogPriority priority,
+ const char *fmt, ...);
+
+typedef void SDLCALL tSDL_LogMessageV(int category,
+ SDL_LogPriority priority,
+ const char *fmt, va_list ap);
+
+typedef void (*SDL_LogOutputFunction)(void *userdata, int category, SDL_LogPriority priority, const char *message);
+
+typedef void SDLCALL tSDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata);
+
+typedef void SDLCALL tSDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata);
+
+extern tSDL_LogSetAllPriority *SDL_LogSetAllPriority;
+extern tSDL_LogSetPriority *SDL_LogSetPriority;
+extern tSDL_LogGetPriority *SDL_LogGetPriority;
+extern tSDL_LogResetPriorities *SDL_LogResetPriorities;
+extern tSDL_Log *SDL_Log;
+extern tSDL_LogVerbose *SDL_LogVerbose;
+extern tSDL_LogDebug *SDL_LogDebug;
+extern tSDL_LogInfo *SDL_LogInfo;
+extern tSDL_LogWarn *SDL_LogWarn;
+extern tSDL_LogError *SDL_LogError;
+extern tSDL_LogCritical *SDL_LogCritical;
+extern tSDL_LogMessage *SDL_LogMessage;
+extern tSDL_LogMessageV *SDL_LogMessageV;
+extern tSDL_LogGetOutputFunction *SDL_LogGetOutputFunction;
+extern tSDL_LogSetOutputFunction *SDL_LogSetOutputFunction;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_main.h b/extern/sdlew/include/SDL2/SDL_main.h
new file mode 100644
index 00000000000..9f7386af065
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_main.h
@@ -0,0 +1,56 @@
+
+#ifndef _SDL_main_h
+#define _SDL_main_h
+
+#include "SDL_stdinc.h"
+
+#ifndef SDL_MAIN_HANDLED
+#if defined(__WIN32__)
+
+#define SDL_MAIN_AVAILABLE
+
+#elif defined(__IPHONEOS__)
+
+#define SDL_MAIN_NEEDED
+
+#elif defined(__ANDROID__)
+
+#define SDL_MAIN_NEEDED
+
+#endif
+#endif
+
+#ifdef __cplusplus
+#define C_LINKAGE "C"
+#else
+#define C_LINKAGE
+#endif
+
+#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE)
+#define main SDL_main
+#endif
+
+extern C_LINKAGE int SDL_main(int argc, char *argv[]);
+
+#include "begin_code.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern DECLSPEC void SDL_SetMainReady(void);
+
+#ifdef __WIN32__
+
+typedef int SDLCALL tSDL_RegisterApp(char *name, Uint32 style,
+ void *hInst);
+typedef void SDLCALL tSDL_UnregisterApp(void);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_messagebox.h b/extern/sdlew/include/SDL2/SDL_messagebox.h
new file mode 100644
index 00000000000..378d5d94868
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_messagebox.h
@@ -0,0 +1,80 @@
+
+#ifndef _SDL_messagebox_h
+#define _SDL_messagebox_h
+
+#include "SDL_stdinc.h"
+#include "SDL_video.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ SDL_MESSAGEBOX_ERROR = 0x00000010,
+ SDL_MESSAGEBOX_WARNING = 0x00000020,
+ SDL_MESSAGEBOX_INFORMATION = 0x00000040
+} SDL_MessageBoxFlags;
+
+typedef enum
+{
+ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001,
+ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002
+} SDL_MessageBoxButtonFlags;
+
+typedef struct
+{
+ Uint32 flags;
+ int buttonid;
+ const char * text;
+} SDL_MessageBoxButtonData;
+
+typedef struct
+{
+ Uint8 r, g, b;
+} SDL_MessageBoxColor;
+
+typedef enum
+{
+ SDL_MESSAGEBOX_COLOR_BACKGROUND,
+ SDL_MESSAGEBOX_COLOR_TEXT,
+ SDL_MESSAGEBOX_COLOR_BUTTON_BORDER,
+ SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND,
+ SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
+ SDL_MESSAGEBOX_COLOR_MAX
+} SDL_MessageBoxColorType;
+
+typedef struct
+{
+ SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX];
+} SDL_MessageBoxColorScheme;
+
+typedef struct
+{
+ Uint32 flags;
+ SDL_Window *window;
+ const char *title;
+ const char *message;
+
+ int numbuttons;
+ const SDL_MessageBoxButtonData *buttons;
+
+ const SDL_MessageBoxColorScheme *colorScheme;
+} SDL_MessageBoxData;
+
+typedef int SDLCALL tSDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+typedef int SDLCALL tSDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window);
+
+extern tSDL_ShowMessageBox *SDL_ShowMessageBox;
+extern tSDL_ShowSimpleMessageBox *SDL_ShowSimpleMessageBox;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_mouse.h b/extern/sdlew/include/SDL2/SDL_mouse.h
new file mode 100644
index 00000000000..e6700a405ee
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_mouse.h
@@ -0,0 +1,101 @@
+
+#ifndef _SDL_mouse_h
+#define _SDL_mouse_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_video.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SDL_Cursor SDL_Cursor;
+
+typedef enum
+{
+ SDL_SYSTEM_CURSOR_ARROW,
+ SDL_SYSTEM_CURSOR_IBEAM,
+ SDL_SYSTEM_CURSOR_WAIT,
+ SDL_SYSTEM_CURSOR_CROSSHAIR,
+ SDL_SYSTEM_CURSOR_WAITARROW,
+ SDL_SYSTEM_CURSOR_SIZENWSE,
+ SDL_SYSTEM_CURSOR_SIZENESW,
+ SDL_SYSTEM_CURSOR_SIZEWE,
+ SDL_SYSTEM_CURSOR_SIZENS,
+ SDL_SYSTEM_CURSOR_SIZEALL,
+ SDL_SYSTEM_CURSOR_NO,
+ SDL_SYSTEM_CURSOR_HAND,
+ SDL_NUM_SYSTEM_CURSORS
+} SDL_SystemCursor;
+
+typedef SDL_Window * SDLCALL tSDL_GetMouseFocus(void);
+
+typedef Uint32 SDLCALL tSDL_GetMouseState(int *x, int *y);
+
+typedef Uint32 SDLCALL tSDL_GetRelativeMouseState(int *x, int *y);
+
+typedef void SDLCALL tSDL_WarpMouseInWindow(SDL_Window * window,
+ int x, int y);
+
+typedef int SDLCALL tSDL_SetRelativeMouseMode(SDL_bool enabled);
+
+typedef SDL_bool SDLCALL tSDL_GetRelativeMouseMode(void);
+
+typedef SDL_Cursor * SDLCALL tSDL_CreateCursor(const Uint8 * data,
+ const Uint8 * mask,
+ int w, int h, int hot_x,
+ int hot_y);
+
+typedef SDL_Cursor * SDLCALL tSDL_CreateColorCursor(SDL_Surface *surface,
+ int hot_x,
+ int hot_y);
+
+typedef SDL_Cursor * SDLCALL tSDL_CreateSystemCursor(SDL_SystemCursor id);
+
+typedef void SDLCALL tSDL_SetCursor(SDL_Cursor * cursor);
+
+typedef SDL_Cursor * SDLCALL tSDL_GetCursor(void);
+
+typedef SDL_Cursor * SDLCALL tSDL_GetDefaultCursor(void);
+
+typedef void SDLCALL tSDL_FreeCursor(SDL_Cursor * cursor);
+
+typedef int SDLCALL tSDL_ShowCursor(int toggle);
+
+#define SDL_BUTTON(X) (1 << ((X)-1))
+#define SDL_BUTTON_LEFT 1
+#define SDL_BUTTON_MIDDLE 2
+#define SDL_BUTTON_RIGHT 3
+#define SDL_BUTTON_X1 4
+#define SDL_BUTTON_X2 5
+#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT)
+#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE)
+#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT)
+#define SDL_BUTTON_X1MASK SDL_BUTTON(SDL_BUTTON_X1)
+#define SDL_BUTTON_X2MASK SDL_BUTTON(SDL_BUTTON_X2)
+
+extern tSDL_GetMouseFocus *SDL_GetMouseFocus;
+extern tSDL_GetMouseState *SDL_GetMouseState;
+extern tSDL_GetRelativeMouseState *SDL_GetRelativeMouseState;
+extern tSDL_WarpMouseInWindow *SDL_WarpMouseInWindow;
+extern tSDL_SetRelativeMouseMode *SDL_SetRelativeMouseMode;
+extern tSDL_GetRelativeMouseMode *SDL_GetRelativeMouseMode;
+extern tSDL_CreateCursor *SDL_CreateCursor;
+extern tSDL_CreateColorCursor *SDL_CreateColorCursor;
+extern tSDL_CreateSystemCursor *SDL_CreateSystemCursor;
+extern tSDL_SetCursor *SDL_SetCursor;
+extern tSDL_GetCursor *SDL_GetCursor;
+extern tSDL_GetDefaultCursor *SDL_GetDefaultCursor;
+extern tSDL_FreeCursor *SDL_FreeCursor;
+extern tSDL_ShowCursor *SDL_ShowCursor;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_mutex.h b/extern/sdlew/include/SDL2/SDL_mutex.h
new file mode 100644
index 00000000000..ddfc5730349
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_mutex.h
@@ -0,0 +1,91 @@
+
+#ifndef _SDL_mutex_h
+#define _SDL_mutex_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL_MUTEX_TIMEDOUT 1
+
+#define SDL_MUTEX_MAXWAIT (~(Uint32)0)
+
+struct SDL_mutex;
+typedef struct SDL_mutex SDL_mutex;
+
+typedef SDL_mutex * SDLCALL tSDL_CreateMutex(void);
+
+#define SDL_mutexP(m) SDL_LockMutex(m)
+typedef int SDLCALL tSDL_LockMutex(SDL_mutex * mutex);
+
+typedef int SDLCALL tSDL_TryLockMutex(SDL_mutex * mutex);
+
+#define SDL_mutexV(m) SDL_UnlockMutex(m)
+typedef int SDLCALL tSDL_UnlockMutex(SDL_mutex * mutex);
+
+typedef void SDLCALL tSDL_DestroyMutex(SDL_mutex * mutex);
+
+struct SDL_semaphore;
+typedef struct SDL_semaphore SDL_sem;
+
+typedef SDL_sem * SDLCALL tSDL_CreateSemaphore(Uint32 initial_value);
+
+typedef void SDLCALL tSDL_DestroySemaphore(SDL_sem * sem);
+
+typedef int SDLCALL tSDL_SemWait(SDL_sem * sem);
+
+typedef int SDLCALL tSDL_SemTryWait(SDL_sem * sem);
+
+typedef int SDLCALL tSDL_SemWaitTimeout(SDL_sem * sem, Uint32 ms);
+
+typedef int SDLCALL tSDL_SemPost(SDL_sem * sem);
+
+typedef Uint32 SDLCALL tSDL_SemValue(SDL_sem * sem);
+
+struct SDL_cond;
+typedef struct SDL_cond SDL_cond;
+
+typedef SDL_cond * SDLCALL tSDL_CreateCond(void);
+
+typedef void SDLCALL tSDL_DestroyCond(SDL_cond * cond);
+
+typedef int SDLCALL tSDL_CondSignal(SDL_cond * cond);
+
+typedef int SDLCALL tSDL_CondBroadcast(SDL_cond * cond);
+
+typedef int SDLCALL tSDL_CondWait(SDL_cond * cond, SDL_mutex * mutex);
+
+typedef int SDLCALL tSDL_CondWaitTimeout(SDL_cond * cond,
+ SDL_mutex * mutex, Uint32 ms);
+
+extern tSDL_CreateMutex *SDL_CreateMutex;
+extern tSDL_LockMutex *SDL_LockMutex;
+extern tSDL_TryLockMutex *SDL_TryLockMutex;
+extern tSDL_UnlockMutex *SDL_UnlockMutex;
+extern tSDL_DestroyMutex *SDL_DestroyMutex;
+extern tSDL_CreateSemaphore *SDL_CreateSemaphore;
+extern tSDL_DestroySemaphore *SDL_DestroySemaphore;
+extern tSDL_SemWait *SDL_SemWait;
+extern tSDL_SemTryWait *SDL_SemTryWait;
+extern tSDL_SemWaitTimeout *SDL_SemWaitTimeout;
+extern tSDL_SemPost *SDL_SemPost;
+extern tSDL_SemValue *SDL_SemValue;
+extern tSDL_CreateCond *SDL_CreateCond;
+extern tSDL_DestroyCond *SDL_DestroyCond;
+extern tSDL_CondSignal *SDL_CondSignal;
+extern tSDL_CondBroadcast *SDL_CondBroadcast;
+extern tSDL_CondWait *SDL_CondWait;
+extern tSDL_CondWaitTimeout *SDL_CondWaitTimeout;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_name.h b/extern/sdlew/include/SDL2/SDL_name.h
new file mode 100644
index 00000000000..49e800a4ed9
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_name.h
@@ -0,0 +1,11 @@
+
+#ifndef _SDLname_h_
+#define _SDLname_h_
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define NeedFunctionPrototypes 1
+#endif
+
+#define SDL_NAME(X) SDL_##X
+
+#endif
diff --git a/extern/sdlew/include/SDL2/SDL_opengl.h b/extern/sdlew/include/SDL2/SDL_opengl.h
new file mode 100644
index 00000000000..da242f25394
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_opengl.h
@@ -0,0 +1,10607 @@
+
+#ifndef _SDL_opengl_h
+#define _SDL_opengl_h
+
+#include "SDL_config.h"
+
+#ifndef __IPHONEOS__
+
+#ifdef __WIN32__
+#define WIN32_LEAN_AND_MEAN
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include <windows.h>
+#endif
+
+#ifdef __glext_h_
+
+#define NO_SDL_GLEXT
+#endif
+#ifndef NO_SDL_GLEXT
+#define __glext_h_
+#endif
+#if defined(__MACOSX__)
+#include <OpenGL/gl.h>
+#define __X_GL_H
+#else
+#include <GL/gl.h>
+#endif
+#ifndef NO_SDL_GLEXT
+#undef __glext_h_
+#endif
+
+#if !defined(NO_SDL_GLEXT) && !defined(GL_GLEXT_LEGACY)
+#ifndef __glext_h_
+#define __glext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GL_GLEXT_VERSION 64
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+#ifndef GL_VERSION_1_2
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#endif
+
+#ifndef GL_VERSION_1_2_DEPRECATED
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#define GL_SINGLE_COLOR 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#endif
+
+#ifndef GL_ARB_imaging
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_FUNC_ADD 0x8006
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_BLEND_EQUATION 0x8009
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#endif
+
+#ifndef GL_ARB_imaging_DEPRECATED
+#define GL_CONVOLUTION_1D 0x8010
+#define GL_CONVOLUTION_2D 0x8011
+#define GL_SEPARABLE_2D 0x8012
+#define GL_CONVOLUTION_BORDER_MODE 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS 0x8015
+#define GL_REDUCE 0x8016
+#define GL_CONVOLUTION_FORMAT 0x8017
+#define GL_CONVOLUTION_WIDTH 0x8018
+#define GL_CONVOLUTION_HEIGHT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
+#define GL_HISTOGRAM 0x8024
+#define GL_PROXY_HISTOGRAM 0x8025
+#define GL_HISTOGRAM_WIDTH 0x8026
+#define GL_HISTOGRAM_FORMAT 0x8027
+#define GL_HISTOGRAM_RED_SIZE 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
+#define GL_HISTOGRAM_SINK 0x802D
+#define GL_MINMAX 0x802E
+#define GL_MINMAX_FORMAT 0x802F
+#define GL_MINMAX_SINK 0x8030
+#define GL_TABLE_TOO_LARGE 0x8031
+#define GL_COLOR_MATRIX 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB
+#define GL_COLOR_TABLE 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
+#define GL_PROXY_COLOR_TABLE 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define GL_COLOR_TABLE_SCALE 0x80D6
+#define GL_COLOR_TABLE_BIAS 0x80D7
+#define GL_COLOR_TABLE_FORMAT 0x80D8
+#define GL_COLOR_TABLE_WIDTH 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
+#define GL_CONSTANT_BORDER 0x8151
+#define GL_REPLICATE_BORDER 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR 0x8154
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_MULTISAMPLE 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_CLAMP_TO_BORDER 0x812D
+#endif
+
+#ifndef GL_VERSION_1_3_DEPRECATED
+#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define GL_MAX_TEXTURE_UNITS 0x84E2
+#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
+#define GL_MULTISAMPLE_BIT 0x20000000
+#define GL_NORMAL_MAP 0x8511
+#define GL_REFLECTION_MAP 0x8512
+#define GL_COMPRESSED_ALPHA 0x84E9
+#define GL_COMPRESSED_LUMINANCE 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+#define GL_COMPRESSED_INTENSITY 0x84EC
+#define GL_COMBINE 0x8570
+#define GL_COMBINE_RGB 0x8571
+#define GL_COMBINE_ALPHA 0x8572
+#define GL_SOURCE0_RGB 0x8580
+#define GL_SOURCE1_RGB 0x8581
+#define GL_SOURCE2_RGB 0x8582
+#define GL_SOURCE0_ALPHA 0x8588
+#define GL_SOURCE1_ALPHA 0x8589
+#define GL_SOURCE2_ALPHA 0x858A
+#define GL_OPERAND0_RGB 0x8590
+#define GL_OPERAND1_RGB 0x8591
+#define GL_OPERAND2_RGB 0x8592
+#define GL_OPERAND0_ALPHA 0x8598
+#define GL_OPERAND1_ALPHA 0x8599
+#define GL_OPERAND2_ALPHA 0x859A
+#define GL_RGB_SCALE 0x8573
+#define GL_ADD_SIGNED 0x8574
+#define GL_INTERPOLATE 0x8575
+#define GL_SUBTRACT 0x84E7
+#define GL_CONSTANT 0x8576
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PREVIOUS 0x8578
+#define GL_DOT3_RGB 0x86AE
+#define GL_DOT3_RGBA 0x86AF
+#endif
+
+#ifndef GL_VERSION_1_4
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_LOD_BIAS 0x8501
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#endif
+
+#ifndef GL_VERSION_1_4_DEPRECATED
+#define GL_POINT_SIZE_MIN 0x8126
+#define GL_POINT_SIZE_MAX 0x8127
+#define GL_POINT_DISTANCE_ATTENUATION 0x8129
+#define GL_GENERATE_MIPMAP 0x8191
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_FOG_COORDINATE_SOURCE 0x8450
+#define GL_FOG_COORDINATE 0x8451
+#define GL_FRAGMENT_DEPTH 0x8452
+#define GL_CURRENT_FOG_COORDINATE 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456
+#define GL_FOG_COORDINATE_ARRAY 0x8457
+#define GL_COLOR_SUM 0x8458
+#define GL_CURRENT_SECONDARY_COLOR 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
+#define GL_SECONDARY_COLOR_ARRAY 0x845E
+#define GL_TEXTURE_FILTER_CONTROL 0x8500
+#define GL_DEPTH_TEXTURE_MODE 0x884B
+#define GL_COMPARE_R_TO_TEXTURE 0x884E
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_READ_ONLY 0x88B8
+#define GL_WRITE_ONLY 0x88B9
+#define GL_READ_WRITE 0x88BA
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_SAMPLES_PASSED 0x8914
+#endif
+
+#ifndef GL_VERSION_1_5_DEPRECATED
+#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
+#define GL_FOG_COORD_SRC 0x8450
+#define GL_FOG_COORD 0x8451
+#define GL_CURRENT_FOG_COORD 0x8453
+#define GL_FOG_COORD_ARRAY_TYPE 0x8454
+#define GL_FOG_COORD_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORD_ARRAY_POINTER 0x8456
+#define GL_FOG_COORD_ARRAY 0x8457
+#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D
+#define GL_SRC0_RGB 0x8580
+#define GL_SRC1_RGB 0x8581
+#define GL_SRC2_RGB 0x8582
+#define GL_SRC0_ALPHA 0x8588
+#define GL_SRC1_ALPHA 0x8589
+#define GL_SRC2_ALPHA 0x858A
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_DELETE_STATUS 0x8B80
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#endif
+
+#ifndef GL_VERSION_2_0_DEPRECATED
+#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
+#define GL_POINT_SPRITE 0x8861
+#define GL_COORD_REPLACE 0x8862
+#define GL_MAX_TEXTURE_COORDS 0x8871
+#endif
+
+#ifndef GL_VERSION_2_1
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB_ALPHA 0x8C42
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#endif
+
+#ifndef GL_VERSION_2_1_DEPRECATED
+#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F
+#define GL_SLUMINANCE_ALPHA 0x8C44
+#define GL_SLUMINANCE8_ALPHA8 0x8C45
+#define GL_SLUMINANCE 0x8C46
+#define GL_SLUMINANCE8 0x8C47
+#define GL_COMPRESSED_SLUMINANCE 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B
+#endif
+
+#ifndef GL_VERSION_3_0
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_CLIP_DISTANCE0 0x3000
+#define GL_CLIP_DISTANCE1 0x3001
+#define GL_CLIP_DISTANCE2 0x3002
+#define GL_CLIP_DISTANCE3 0x3003
+#define GL_CLIP_DISTANCE4 0x3004
+#define GL_CLIP_DISTANCE5 0x3005
+#define GL_CLIP_DISTANCE6 0x3006
+#define GL_CLIP_DISTANCE7 0x3007
+#define GL_MAX_CLIP_DISTANCES 0x0D32
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_DEPTH_BUFFER 0x8223
+#define GL_STENCIL_BUFFER 0x8224
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RG 0x8226
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_CLAMP_READ_COLOR 0x891C
+#define GL_FIXED_ONLY 0x891D
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_TEXTURE_1D_ARRAY 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_GREEN_INTEGER 0x8D95
+#define GL_BLUE_INTEGER 0x8D96
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_BGR_INTEGER 0x8D9A
+#define GL_BGRA_INTEGER 0x8D9B
+#define GL_SAMPLER_1D_ARRAY 0x8DC0
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_1D 0x8DC9
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_QUERY_WAIT 0x8E13
+#define GL_QUERY_NO_WAIT 0x8E14
+#define GL_QUERY_BY_REGION_WAIT 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+
+#endif
+
+#ifndef GL_VERSION_3_0_DEPRECATED
+#define GL_CLAMP_VERTEX_COLOR 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR 0x891B
+#define GL_ALPHA_INTEGER 0x8D97
+
+#endif
+
+#ifndef GL_VERSION_3_1
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_RED_SNORM 0x8F90
+#define GL_RG_SNORM 0x8F91
+#define GL_RGB_SNORM 0x8F92
+#define GL_RGBA_SNORM 0x8F93
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM 0x8F98
+#define GL_RG16_SNORM 0x8F99
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+
+#endif
+
+#ifndef GL_VERSION_3_3
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+
+#endif
+
+#ifndef GL_VERSION_4_0
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+
+#endif
+
+#ifndef GL_VERSION_4_1
+
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_TEXTURE0_ARB 0x84C0
+#define GL_TEXTURE1_ARB 0x84C1
+#define GL_TEXTURE2_ARB 0x84C2
+#define GL_TEXTURE3_ARB 0x84C3
+#define GL_TEXTURE4_ARB 0x84C4
+#define GL_TEXTURE5_ARB 0x84C5
+#define GL_TEXTURE6_ARB 0x84C6
+#define GL_TEXTURE7_ARB 0x84C7
+#define GL_TEXTURE8_ARB 0x84C8
+#define GL_TEXTURE9_ARB 0x84C9
+#define GL_TEXTURE10_ARB 0x84CA
+#define GL_TEXTURE11_ARB 0x84CB
+#define GL_TEXTURE12_ARB 0x84CC
+#define GL_TEXTURE13_ARB 0x84CD
+#define GL_TEXTURE14_ARB 0x84CE
+#define GL_TEXTURE15_ARB 0x84CF
+#define GL_TEXTURE16_ARB 0x84D0
+#define GL_TEXTURE17_ARB 0x84D1
+#define GL_TEXTURE18_ARB 0x84D2
+#define GL_TEXTURE19_ARB 0x84D3
+#define GL_TEXTURE20_ARB 0x84D4
+#define GL_TEXTURE21_ARB 0x84D5
+#define GL_TEXTURE22_ARB 0x84D6
+#define GL_TEXTURE23_ARB 0x84D7
+#define GL_TEXTURE24_ARB 0x84D8
+#define GL_TEXTURE25_ARB 0x84D9
+#define GL_TEXTURE26_ARB 0x84DA
+#define GL_TEXTURE27_ARB 0x84DB
+#define GL_TEXTURE28_ARB 0x84DC
+#define GL_TEXTURE29_ARB 0x84DD
+#define GL_TEXTURE30_ARB 0x84DE
+#define GL_TEXTURE31_ARB 0x84DF
+#define GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
+#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_MULTISAMPLE_ARB 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F
+#define GL_SAMPLE_COVERAGE_ARB 0x80A0
+#define GL_SAMPLE_BUFFERS_ARB 0x80A8
+#define GL_SAMPLES_ARB 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB
+#define GL_MULTISAMPLE_BIT_ARB 0x20000000
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_NORMAL_MAP_ARB 0x8511
+#define GL_REFLECTION_MAP_ARB 0x8512
+#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_COMPRESSED_ALPHA_ARB 0x84E9
+#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
+#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
+#define GL_COMPRESSED_RGB_ARB 0x84ED
+#define GL_COMPRESSED_RGBA_ARB 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
+#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_ARB 0x812D
+#endif
+
+#ifndef GL_ARB_point_parameters
+#define GL_POINT_SIZE_MIN_ARB 0x8126
+#define GL_POINT_SIZE_MAX_ARB 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_MAX_VERTEX_UNITS_ARB 0x86A4
+#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5
+#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6
+#define GL_VERTEX_BLEND_ARB 0x86A7
+#define GL_CURRENT_WEIGHT_ARB 0x86A8
+#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA
+#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB
+#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC
+#define GL_WEIGHT_ARRAY_ARB 0x86AD
+#define GL_MODELVIEW0_ARB 0x1700
+#define GL_MODELVIEW1_ARB 0x850A
+#define GL_MODELVIEW2_ARB 0x8722
+#define GL_MODELVIEW3_ARB 0x8723
+#define GL_MODELVIEW4_ARB 0x8724
+#define GL_MODELVIEW5_ARB 0x8725
+#define GL_MODELVIEW6_ARB 0x8726
+#define GL_MODELVIEW7_ARB 0x8727
+#define GL_MODELVIEW8_ARB 0x8728
+#define GL_MODELVIEW9_ARB 0x8729
+#define GL_MODELVIEW10_ARB 0x872A
+#define GL_MODELVIEW11_ARB 0x872B
+#define GL_MODELVIEW12_ARB 0x872C
+#define GL_MODELVIEW13_ARB 0x872D
+#define GL_MODELVIEW14_ARB 0x872E
+#define GL_MODELVIEW15_ARB 0x872F
+#define GL_MODELVIEW16_ARB 0x8730
+#define GL_MODELVIEW17_ARB 0x8731
+#define GL_MODELVIEW18_ARB 0x8732
+#define GL_MODELVIEW19_ARB 0x8733
+#define GL_MODELVIEW20_ARB 0x8734
+#define GL_MODELVIEW21_ARB 0x8735
+#define GL_MODELVIEW22_ARB 0x8736
+#define GL_MODELVIEW23_ARB 0x8737
+#define GL_MODELVIEW24_ARB 0x8738
+#define GL_MODELVIEW25_ARB 0x8739
+#define GL_MODELVIEW26_ARB 0x873A
+#define GL_MODELVIEW27_ARB 0x873B
+#define GL_MODELVIEW28_ARB 0x873C
+#define GL_MODELVIEW29_ARB 0x873D
+#define GL_MODELVIEW30_ARB 0x873E
+#define GL_MODELVIEW31_ARB 0x873F
+#endif
+
+#ifndef GL_ARB_matrix_palette
+#define GL_MATRIX_PALETTE_ARB 0x8840
+#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841
+#define GL_MAX_PALETTE_MATRICES_ARB 0x8842
+#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843
+#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844
+#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845
+#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846
+#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848
+#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849
+#endif
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_COMBINE_ARB 0x8570
+#define GL_COMBINE_RGB_ARB 0x8571
+#define GL_COMBINE_ALPHA_ARB 0x8572
+#define GL_SOURCE0_RGB_ARB 0x8580
+#define GL_SOURCE1_RGB_ARB 0x8581
+#define GL_SOURCE2_RGB_ARB 0x8582
+#define GL_SOURCE0_ALPHA_ARB 0x8588
+#define GL_SOURCE1_ALPHA_ARB 0x8589
+#define GL_SOURCE2_ALPHA_ARB 0x858A
+#define GL_OPERAND0_RGB_ARB 0x8590
+#define GL_OPERAND1_RGB_ARB 0x8591
+#define GL_OPERAND2_RGB_ARB 0x8592
+#define GL_OPERAND0_ALPHA_ARB 0x8598
+#define GL_OPERAND1_ALPHA_ARB 0x8599
+#define GL_OPERAND2_ALPHA_ARB 0x859A
+#define GL_RGB_SCALE_ARB 0x8573
+#define GL_ADD_SIGNED_ARB 0x8574
+#define GL_INTERPOLATE_ARB 0x8575
+#define GL_SUBTRACT_ARB 0x84E7
+#define GL_CONSTANT_ARB 0x8576
+#define GL_PRIMARY_COLOR_ARB 0x8577
+#define GL_PREVIOUS_ARB 0x8578
+#endif
+
+#ifndef GL_ARB_texture_env_crossbar
+#endif
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_DOT3_RGB_ARB 0x86AE
+#define GL_DOT3_RGBA_ARB 0x86AF
+#endif
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_ARB 0x8370
+#endif
+
+#ifndef GL_ARB_depth_texture
+#define GL_DEPTH_COMPONENT16_ARB 0x81A5
+#define GL_DEPTH_COMPONENT24_ARB 0x81A6
+#define GL_DEPTH_COMPONENT32_ARB 0x81A7
+#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A
+#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B
+#endif
+
+#ifndef GL_ARB_shadow
+#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
+#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
+#endif
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF
+#endif
+
+#ifndef GL_ARB_window_pos
+#endif
+
+#ifndef GL_ARB_vertex_program
+#define GL_COLOR_SUM_ARB 0x8458
+#define GL_VERTEX_PROGRAM_ARB 0x8620
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626
+#define GL_PROGRAM_LENGTH_ARB 0x8627
+#define GL_PROGRAM_STRING_ARB 0x8628
+#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
+#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F
+#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
+#define GL_CURRENT_MATRIX_ARB 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
+#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B
+#define GL_PROGRAM_BINDING_ARB 0x8677
+#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
+#define GL_PROGRAM_ERROR_STRING_ARB 0x8874
+#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
+#define GL_PROGRAM_FORMAT_ARB 0x8876
+#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0
+#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1
+#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
+#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
+#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4
+#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5
+#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
+#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
+#define GL_PROGRAM_PARAMETERS_ARB 0x88A8
+#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9
+#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA
+#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
+#define GL_PROGRAM_ATTRIBS_ARB 0x88AC
+#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD
+#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE
+#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
+#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0
+#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
+#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
+#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
+#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
+#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
+#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
+#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
+#define GL_MATRIX0_ARB 0x88C0
+#define GL_MATRIX1_ARB 0x88C1
+#define GL_MATRIX2_ARB 0x88C2
+#define GL_MATRIX3_ARB 0x88C3
+#define GL_MATRIX4_ARB 0x88C4
+#define GL_MATRIX5_ARB 0x88C5
+#define GL_MATRIX6_ARB 0x88C6
+#define GL_MATRIX7_ARB 0x88C7
+#define GL_MATRIX8_ARB 0x88C8
+#define GL_MATRIX9_ARB 0x88C9
+#define GL_MATRIX10_ARB 0x88CA
+#define GL_MATRIX11_ARB 0x88CB
+#define GL_MATRIX12_ARB 0x88CC
+#define GL_MATRIX13_ARB 0x88CD
+#define GL_MATRIX14_ARB 0x88CE
+#define GL_MATRIX15_ARB 0x88CF
+#define GL_MATRIX16_ARB 0x88D0
+#define GL_MATRIX17_ARB 0x88D1
+#define GL_MATRIX18_ARB 0x88D2
+#define GL_MATRIX19_ARB 0x88D3
+#define GL_MATRIX20_ARB 0x88D4
+#define GL_MATRIX21_ARB 0x88D5
+#define GL_MATRIX22_ARB 0x88D6
+#define GL_MATRIX23_ARB 0x88D7
+#define GL_MATRIX24_ARB 0x88D8
+#define GL_MATRIX25_ARB 0x88D9
+#define GL_MATRIX26_ARB 0x88DA
+#define GL_MATRIX27_ARB 0x88DB
+#define GL_MATRIX28_ARB 0x88DC
+#define GL_MATRIX29_ARB 0x88DD
+#define GL_MATRIX30_ARB 0x88DE
+#define GL_MATRIX31_ARB 0x88DF
+#endif
+
+#ifndef GL_ARB_fragment_program
+#define GL_FRAGMENT_PROGRAM_ARB 0x8804
+#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805
+#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806
+#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807
+#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
+#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
+#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
+#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
+#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
+#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
+#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
+#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
+#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
+#define GL_MAX_TEXTURE_COORDS_ARB 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_BUFFER_SIZE_ARB 0x8764
+#define GL_BUFFER_USAGE_ARB 0x8765
+#define GL_ARRAY_BUFFER_ARB 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
+#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
+#define GL_READ_ONLY_ARB 0x88B8
+#define GL_WRITE_ONLY_ARB 0x88B9
+#define GL_READ_WRITE_ARB 0x88BA
+#define GL_BUFFER_ACCESS_ARB 0x88BB
+#define GL_BUFFER_MAPPED_ARB 0x88BC
+#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
+#define GL_STREAM_DRAW_ARB 0x88E0
+#define GL_STREAM_READ_ARB 0x88E1
+#define GL_STREAM_COPY_ARB 0x88E2
+#define GL_STATIC_DRAW_ARB 0x88E4
+#define GL_STATIC_READ_ARB 0x88E5
+#define GL_STATIC_COPY_ARB 0x88E6
+#define GL_DYNAMIC_DRAW_ARB 0x88E8
+#define GL_DYNAMIC_READ_ARB 0x88E9
+#define GL_DYNAMIC_COPY_ARB 0x88EA
+#endif
+
+#ifndef GL_ARB_occlusion_query
+#define GL_QUERY_COUNTER_BITS_ARB 0x8864
+#define GL_CURRENT_QUERY_ARB 0x8865
+#define GL_QUERY_RESULT_ARB 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
+#define GL_SAMPLES_PASSED_ARB 0x8914
+#endif
+
+#ifndef GL_ARB_shader_objects
+#define GL_PROGRAM_OBJECT_ARB 0x8B40
+#define GL_SHADER_OBJECT_ARB 0x8B48
+#define GL_OBJECT_TYPE_ARB 0x8B4E
+#define GL_OBJECT_SUBTYPE_ARB 0x8B4F
+#define GL_FLOAT_VEC2_ARB 0x8B50
+#define GL_FLOAT_VEC3_ARB 0x8B51
+#define GL_FLOAT_VEC4_ARB 0x8B52
+#define GL_INT_VEC2_ARB 0x8B53
+#define GL_INT_VEC3_ARB 0x8B54
+#define GL_INT_VEC4_ARB 0x8B55
+#define GL_BOOL_ARB 0x8B56
+#define GL_BOOL_VEC2_ARB 0x8B57
+#define GL_BOOL_VEC3_ARB 0x8B58
+#define GL_BOOL_VEC4_ARB 0x8B59
+#define GL_FLOAT_MAT2_ARB 0x8B5A
+#define GL_FLOAT_MAT3_ARB 0x8B5B
+#define GL_FLOAT_MAT4_ARB 0x8B5C
+#define GL_SAMPLER_1D_ARB 0x8B5D
+#define GL_SAMPLER_2D_ARB 0x8B5E
+#define GL_SAMPLER_3D_ARB 0x8B5F
+#define GL_SAMPLER_CUBE_ARB 0x8B60
+#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61
+#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64
+#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80
+#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81
+#define GL_OBJECT_LINK_STATUS_ARB 0x8B82
+#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83
+#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84
+#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85
+#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86
+#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87
+#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88
+#endif
+
+#ifndef GL_ARB_vertex_shader
+#define GL_VERTEX_SHADER_ARB 0x8B31
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A
+#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D
+#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89
+#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
+#endif
+
+#ifndef GL_ARB_fragment_shader
+#define GL_FRAGMENT_SHADER_ARB 0x8B30
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B
+#endif
+
+#ifndef GL_ARB_shading_language_100
+#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
+#endif
+
+#ifndef GL_ARB_texture_non_power_of_two
+#endif
+
+#ifndef GL_ARB_point_sprite
+#define GL_POINT_SPRITE_ARB 0x8861
+#define GL_COORD_REPLACE_ARB 0x8862
+#endif
+
+#ifndef GL_ARB_fragment_program_shadow
+#endif
+
+#ifndef GL_ARB_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_ARB 0x8824
+#define GL_DRAW_BUFFER0_ARB 0x8825
+#define GL_DRAW_BUFFER1_ARB 0x8826
+#define GL_DRAW_BUFFER2_ARB 0x8827
+#define GL_DRAW_BUFFER3_ARB 0x8828
+#define GL_DRAW_BUFFER4_ARB 0x8829
+#define GL_DRAW_BUFFER5_ARB 0x882A
+#define GL_DRAW_BUFFER6_ARB 0x882B
+#define GL_DRAW_BUFFER7_ARB 0x882C
+#define GL_DRAW_BUFFER8_ARB 0x882D
+#define GL_DRAW_BUFFER9_ARB 0x882E
+#define GL_DRAW_BUFFER10_ARB 0x882F
+#define GL_DRAW_BUFFER11_ARB 0x8830
+#define GL_DRAW_BUFFER12_ARB 0x8831
+#define GL_DRAW_BUFFER13_ARB 0x8832
+#define GL_DRAW_BUFFER14_ARB 0x8833
+#define GL_DRAW_BUFFER15_ARB 0x8834
+#endif
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#endif
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_RGBA_FLOAT_MODE_ARB 0x8820
+#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B
+#define GL_CLAMP_READ_COLOR_ARB 0x891C
+#define GL_FIXED_ONLY_ARB 0x891D
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_HALF_FLOAT_ARB 0x140B
+#endif
+
+#ifndef GL_ARB_texture_float
+#define GL_TEXTURE_RED_TYPE_ARB 0x8C10
+#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11
+#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13
+#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15
+#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16
+#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17
+#define GL_RGBA32F_ARB 0x8814
+#define GL_RGB32F_ARB 0x8815
+#define GL_ALPHA32F_ARB 0x8816
+#define GL_INTENSITY32F_ARB 0x8817
+#define GL_LUMINANCE32F_ARB 0x8818
+#define GL_LUMINANCE_ALPHA32F_ARB 0x8819
+#define GL_RGBA16F_ARB 0x881A
+#define GL_RGB16F_ARB 0x881B
+#define GL_ALPHA16F_ARB 0x881C
+#define GL_INTENSITY16F_ARB 0x881D
+#define GL_LUMINANCE16F_ARB 0x881E
+#define GL_LUMINANCE_ALPHA16F_ARB 0x881F
+#endif
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
+#endif
+
+#ifndef GL_ARB_depth_buffer_float
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#endif
+
+#ifndef GL_ARB_draw_instanced
+#endif
+
+#ifndef GL_ARB_framebuffer_object
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_STENCIL_INDEX1 0x8D46
+#define GL_STENCIL_INDEX4 0x8D47
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_STENCIL_INDEX16 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+#endif
+
+#ifndef GL_ARB_framebuffer_object_DEPRECATED
+#define GL_INDEX 0x8222
+#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE 0x8C15
+#endif
+
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#endif
+
+#ifndef GL_ARB_geometry_shader4
+#define GL_LINES_ADJACENCY_ARB 0x000A
+#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B
+#define GL_TRIANGLES_ADJACENCY_ARB 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D
+#define GL_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9
+#define GL_GEOMETRY_SHADER_ARB 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1
+
+#endif
+
+#ifndef GL_ARB_half_float_vertex
+#define GL_HALF_FLOAT 0x140B
+#endif
+
+#ifndef GL_ARB_instanced_arrays
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE
+#endif
+
+#ifndef GL_ARB_map_buffer_range
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#endif
+
+#ifndef GL_ARB_texture_buffer_object
+#define GL_TEXTURE_BUFFER_ARB 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E
+#endif
+
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+#endif
+
+#ifndef GL_ARB_texture_rg
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_R16 0x822A
+#define GL_RG8 0x822B
+#define GL_RG16 0x822C
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#endif
+
+#ifndef GL_ARB_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#endif
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#endif
+
+#ifndef GL_ARB_compatibility
+
+#endif
+
+#ifndef GL_ARB_copy_buffer
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#endif
+
+#ifndef GL_ARB_shader_texture_lod
+#endif
+
+#ifndef GL_ARB_depth_clamp
+#define GL_DEPTH_CLAMP 0x864F
+#endif
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#endif
+
+#ifndef GL_ARB_fragment_coord_conventions
+#endif
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_PROVOKING_VERTEX 0x8E4F
+#endif
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#endif
+
+#ifndef GL_ARB_sync
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#endif
+
+#ifndef GL_ARB_texture_multisample
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#endif
+
+#ifndef GL_ARB_vertex_array_bgra
+
+#endif
+
+#ifndef GL_ARB_draw_buffers_blend
+#endif
+
+#ifndef GL_ARB_sample_shading
+#define GL_SAMPLE_SHADING_ARB 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37
+#endif
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
+#endif
+
+#ifndef GL_ARB_texture_gather
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F
+#endif
+
+#ifndef GL_ARB_texture_query_lod
+#endif
+
+#ifndef GL_ARB_shading_language_include
+#define GL_SHADER_INCLUDE_ARB 0x8DAE
+#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9
+#define GL_NAMED_STRING_TYPE_ARB 0x8DEA
+#endif
+
+#ifndef GL_ARB_texture_compression_bptc
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
+#endif
+
+#ifndef GL_ARB_blend_func_extended
+#define GL_SRC1_COLOR 0x88F9
+
+#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+#endif
+
+#ifndef GL_ARB_explicit_attrib_location
+#endif
+
+#ifndef GL_ARB_occlusion_query2
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#endif
+
+#ifndef GL_ARB_sampler_objects
+#define GL_SAMPLER_BINDING 0x8919
+#endif
+
+#ifndef GL_ARB_shader_bit_encoding
+#endif
+
+#ifndef GL_ARB_texture_rgb10_a2ui
+#define GL_RGB10_A2UI 0x906F
+#endif
+
+#ifndef GL_ARB_texture_swizzle
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#endif
+
+#ifndef GL_ARB_timer_query
+#define GL_TIME_ELAPSED 0x88BF
+#define GL_TIMESTAMP 0x8E28
+#endif
+
+#ifndef GL_ARB_vertex_type_2_10_10_10_rev
+
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#endif
+
+#ifndef GL_ARB_draw_indirect
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#endif
+
+#ifndef GL_ARB_gpu_shader5
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+
+#endif
+
+#ifndef GL_ARB_gpu_shader_fp64
+
+#define GL_DOUBLE_VEC2 0x8FFC
+#define GL_DOUBLE_VEC3 0x8FFD
+#define GL_DOUBLE_VEC4 0x8FFE
+#define GL_DOUBLE_MAT2 0x8F46
+#define GL_DOUBLE_MAT3 0x8F47
+#define GL_DOUBLE_MAT4 0x8F48
+#define GL_DOUBLE_MAT2x3 0x8F49
+#define GL_DOUBLE_MAT2x4 0x8F4A
+#define GL_DOUBLE_MAT3x2 0x8F4B
+#define GL_DOUBLE_MAT3x4 0x8F4C
+#define GL_DOUBLE_MAT4x2 0x8F4D
+#define GL_DOUBLE_MAT4x3 0x8F4E
+#endif
+
+#ifndef GL_ARB_shader_subroutine
+#define GL_ACTIVE_SUBROUTINES 0x8DE5
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_MAX_SUBROUTINES 0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
+
+#endif
+
+#ifndef GL_ARB_tessellation_shader
+#define GL_PATCHES 0x000E
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+
+#define GL_ISOLINES 0x8E7A
+
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRACTIONAL_EVEN 0x8E7C
+
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#endif
+
+#ifndef GL_ARB_texture_buffer_object_rgb32
+
+#endif
+
+#ifndef GL_ARB_transform_feedback2
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#endif
+
+#ifndef GL_ARB_transform_feedback3
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+#endif
+
+#ifndef GL_ARB_ES2_compatibility
+#define GL_FIXED 0x140C
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#endif
+
+#ifndef GL_ARB_get_program_binary
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#endif
+
+#ifndef GL_ARB_separate_shader_objects
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#endif
+
+#ifndef GL_ARB_shader_precision
+#endif
+
+#ifndef GL_ARB_vertex_attrib_64bit
+
+#endif
+
+#ifndef GL_ARB_viewport_array
+
+#define GL_MAX_VIEWPORTS 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_UNDEFINED_VERTEX 0x8260
+
+#endif
+
+#ifndef GL_ARB_cl_event
+#define GL_SYNC_CL_EVENT_ARB 0x8240
+#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241
+#endif
+
+#ifndef GL_ARB_debug_output
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
+#define GL_DEBUG_SOURCE_API_ARB 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A
+#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B
+#define GL_DEBUG_TYPE_ERROR_ARB 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
+#define GL_DEBUG_TYPE_OTHER_ARB 0x8251
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
+#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148
+#endif
+
+#ifndef GL_ARB_robustness
+
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GL_NO_RESET_NOTIFICATION_ARB 0x8261
+#endif
+
+#ifndef GL_ARB_shader_stencil_export
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_ABGR_EXT 0x8000
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_CONSTANT_COLOR_EXT 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002
+#define GL_CONSTANT_ALPHA_EXT 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004
+#define GL_BLEND_COLOR_EXT 0x8005
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_POLYGON_OFFSET_EXT 0x8037
+#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038
+#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_ALPHA4_EXT 0x803B
+#define GL_ALPHA8_EXT 0x803C
+#define GL_ALPHA12_EXT 0x803D
+#define GL_ALPHA16_EXT 0x803E
+#define GL_LUMINANCE4_EXT 0x803F
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE12_EXT 0x8041
+#define GL_LUMINANCE16_EXT 0x8042
+#define GL_LUMINANCE4_ALPHA4_EXT 0x8043
+#define GL_LUMINANCE6_ALPHA2_EXT 0x8044
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_LUMINANCE12_ALPHA4_EXT 0x8046
+#define GL_LUMINANCE12_ALPHA12_EXT 0x8047
+#define GL_LUMINANCE16_ALPHA16_EXT 0x8048
+#define GL_INTENSITY_EXT 0x8049
+#define GL_INTENSITY4_EXT 0x804A
+#define GL_INTENSITY8_EXT 0x804B
+#define GL_INTENSITY12_EXT 0x804C
+#define GL_INTENSITY16_EXT 0x804D
+#define GL_RGB2_EXT 0x804E
+#define GL_RGB4_EXT 0x804F
+#define GL_RGB5_EXT 0x8050
+#define GL_RGB8_EXT 0x8051
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB12_EXT 0x8053
+#define GL_RGB16_EXT 0x8054
+#define GL_RGBA2_EXT 0x8055
+#define GL_RGBA4_EXT 0x8056
+#define GL_RGB5_A1_EXT 0x8057
+#define GL_RGBA8_EXT 0x8058
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGBA12_EXT 0x805A
+#define GL_RGBA16_EXT 0x805B
+#define GL_TEXTURE_RED_SIZE_EXT 0x805C
+#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D
+#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E
+#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061
+#define GL_REPLACE_EXT 0x8062
+#define GL_PROXY_TEXTURE_1D_EXT 0x8063
+#define GL_PROXY_TEXTURE_2D_EXT 0x8064
+#define GL_TEXTURE_TOO_LARGE_EXT 0x8065
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_PACK_SKIP_IMAGES_EXT 0x806B
+#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C
+#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E
+#define GL_TEXTURE_3D_EXT 0x806F
+#define GL_PROXY_TEXTURE_3D_EXT 0x8070
+#define GL_TEXTURE_DEPTH_EXT 0x8071
+#define GL_TEXTURE_WRAP_R_EXT 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_FILTER4_SGIS 0x8146
+#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147
+#endif
+
+#ifndef GL_EXT_subtexture
+#endif
+
+#ifndef GL_EXT_copy_texture
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_HISTOGRAM_EXT 0x8024
+#define GL_PROXY_HISTOGRAM_EXT 0x8025
+#define GL_HISTOGRAM_WIDTH_EXT 0x8026
+#define GL_HISTOGRAM_FORMAT_EXT 0x8027
+#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C
+#define GL_HISTOGRAM_SINK_EXT 0x802D
+#define GL_MINMAX_EXT 0x802E
+#define GL_MINMAX_FORMAT_EXT 0x802F
+#define GL_MINMAX_SINK_EXT 0x8030
+#define GL_TABLE_TOO_LARGE_EXT 0x8031
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_CONVOLUTION_1D_EXT 0x8010
+#define GL_CONVOLUTION_2D_EXT 0x8011
+#define GL_SEPARABLE_2D_EXT 0x8012
+#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015
+#define GL_REDUCE_EXT 0x8016
+#define GL_CONVOLUTION_FORMAT_EXT 0x8017
+#define GL_CONVOLUTION_WIDTH_EXT 0x8018
+#define GL_CONVOLUTION_HEIGHT_EXT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_COLOR_MATRIX_SGI 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_COLOR_TABLE_SGI 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2
+#define GL_PROXY_COLOR_TABLE_SGI 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5
+#define GL_COLOR_TABLE_SCALE_SGI 0x80D6
+#define GL_COLOR_TABLE_BIAS_SGI 0x80D7
+#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8
+#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_PIXEL_TEXTURE_SGIS 0x8353
+#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354
+#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355
+#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_PIXEL_TEX_GEN_SGIX 0x8139
+#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130
+#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131
+#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132
+#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133
+#define GL_TEXTURE_4D_SGIS 0x8134
+#define GL_PROXY_TEXTURE_4D_SGIS 0x8135
+#define GL_TEXTURE_4DSIZE_SGIS 0x8136
+#define GL_TEXTURE_WRAP_Q_SGIS 0x8137
+#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138
+#define GL_TEXTURE_4D_BINDING_SGIS 0x814F
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC
+#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_CMYK_EXT 0x800C
+#define GL_CMYKA_EXT 0x800D
+#define GL_PACK_CMYK_HINT_EXT 0x800E
+#define GL_UNPACK_CMYK_HINT_EXT 0x800F
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_TEXTURE_PRIORITY_EXT 0x8066
+#define GL_TEXTURE_RESIDENT_EXT 0x8067
+#define GL_TEXTURE_1D_BINDING_EXT 0x8068
+#define GL_TEXTURE_2D_BINDING_EXT 0x8069
+#define GL_TEXTURE_3D_BINDING_EXT 0x806A
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095
+#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096
+#define GL_LINEAR_DETAIL_SGIS 0x8097
+#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098
+#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099
+#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A
+#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B
+#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_LINEAR_SHARPEN_SGIS 0x80AD
+#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE
+#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF
+#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_TEXTURE_MIN_LOD_SGIS 0x813A
+#define GL_TEXTURE_MAX_LOD_SGIS 0x813B
+#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C
+#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_MULTISAMPLE_SGIS 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F
+#define GL_SAMPLE_MASK_SGIS 0x80A0
+#define GL_1PASS_SGIS 0x80A1
+#define GL_2PASS_0_SGIS 0x80A2
+#define GL_2PASS_1_SGIS 0x80A3
+#define GL_4PASS_0_SGIS 0x80A4
+#define GL_4PASS_1_SGIS 0x80A5
+#define GL_4PASS_2_SGIS 0x80A6
+#define GL_4PASS_3_SGIS 0x80A7
+#define GL_SAMPLE_BUFFERS_SGIS 0x80A8
+#define GL_SAMPLES_SGIS 0x80A9
+#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA
+#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB
+#define GL_SAMPLE_PATTERN_SGIS 0x80AC
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_RESCALE_NORMAL_EXT 0x803A
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_VERTEX_ARRAY_EXT 0x8074
+#define GL_NORMAL_ARRAY_EXT 0x8075
+#define GL_COLOR_ARRAY_EXT 0x8076
+#define GL_INDEX_ARRAY_EXT 0x8077
+#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078
+#define GL_EDGE_FLAG_ARRAY_EXT 0x8079
+#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A
+#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B
+#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C
+#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D
+#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E
+#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F
+#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080
+#define GL_COLOR_ARRAY_SIZE_EXT 0x8081
+#define GL_COLOR_ARRAY_TYPE_EXT 0x8082
+#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083
+#define GL_COLOR_ARRAY_COUNT_EXT 0x8084
+#define GL_INDEX_ARRAY_TYPE_EXT 0x8085
+#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086
+#define GL_INDEX_ARRAY_COUNT_EXT 0x8087
+#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A
+#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B
+#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C
+#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D
+#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E
+#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F
+#define GL_COLOR_ARRAY_POINTER_EXT 0x8090
+#define GL_INDEX_ARRAY_POINTER_EXT 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_GENERATE_MIPMAP_SGIS 0x8191
+#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170
+#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171
+#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172
+#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173
+#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174
+#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175
+#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176
+#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177
+#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178
+#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D
+#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E
+#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_TEXTURE_COMPARE_SGIX 0x819A
+#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B
+#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C
+#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_CLAMP_TO_EDGE_SGIS 0x812F
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_SGIS 0x812D
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_FUNC_ADD_EXT 0x8006
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#define GL_BLEND_EQUATION_EXT 0x8009
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_FUNC_SUBTRACT_EXT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_INTERLACE_SGIX 0x8094
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E
+#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F
+#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140
+#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141
+#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142
+#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143
+#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144
+#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145
+#endif
+
+#ifndef GL_SGIS_texture_select
+#define GL_DUAL_ALPHA4_SGIS 0x8110
+#define GL_DUAL_ALPHA8_SGIS 0x8111
+#define GL_DUAL_ALPHA12_SGIS 0x8112
+#define GL_DUAL_ALPHA16_SGIS 0x8113
+#define GL_DUAL_LUMINANCE4_SGIS 0x8114
+#define GL_DUAL_LUMINANCE8_SGIS 0x8115
+#define GL_DUAL_LUMINANCE12_SGIS 0x8116
+#define GL_DUAL_LUMINANCE16_SGIS 0x8117
+#define GL_DUAL_INTENSITY4_SGIS 0x8118
+#define GL_DUAL_INTENSITY8_SGIS 0x8119
+#define GL_DUAL_INTENSITY12_SGIS 0x811A
+#define GL_DUAL_INTENSITY16_SGIS 0x811B
+#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C
+#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D
+#define GL_QUAD_ALPHA4_SGIS 0x811E
+#define GL_QUAD_ALPHA8_SGIS 0x811F
+#define GL_QUAD_LUMINANCE4_SGIS 0x8120
+#define GL_QUAD_LUMINANCE8_SGIS 0x8121
+#define GL_QUAD_INTENSITY4_SGIS 0x8122
+#define GL_QUAD_INTENSITY8_SGIS 0x8123
+#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124
+#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SPRITE_SGIX 0x8148
+#define GL_SPRITE_MODE_SGIX 0x8149
+#define GL_SPRITE_AXIS_SGIX 0x814A
+#define GL_SPRITE_TRANSLATION_SGIX 0x814B
+#define GL_SPRITE_AXIAL_SGIX 0x814C
+#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D
+#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_POINT_SIZE_MIN_EXT 0x8126
+#define GL_POINT_SIZE_MAX_EXT 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
+#define GL_DISTANCE_ATTENUATION_EXT 0x8129
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_POINT_SIZE_MIN_SGIS 0x8126
+#define GL_POINT_SIZE_MAX_SGIS 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128
+#define GL_DISTANCE_ATTENUATION_SGIS 0x8129
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180
+#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179
+#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A
+#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B
+#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_FRAMEZOOM_SGIX 0x818B
+#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C
+#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#endif
+
+#ifndef GL_FfdMaskSGIX
+#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001
+#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194
+#define GL_TEXTURE_DEFORMATION_SGIX 0x8195
+#define GL_DEFORMATIONS_MASK_SGIX 0x8196
+#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_REFERENCE_PLANE_SGIX 0x817D
+#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_DEPTH_COMPONENT16_SGIX 0x81A5
+#define GL_DEPTH_COMPONENT24_SGIX 0x81A6
+#define GL_DEPTH_COMPONENT32_SGIX 0x81A7
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_FOG_FUNC_SGIS 0x812A
+#define GL_FOG_FUNC_POINTS_SGIS 0x812B
+#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_FOG_OFFSET_SGIX 0x8198
+#define GL_FOG_OFFSET_VALUE_SGIX 0x8199
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_IMAGE_SCALE_X_HP 0x8155
+#define GL_IMAGE_SCALE_Y_HP 0x8156
+#define GL_IMAGE_TRANSLATE_X_HP 0x8157
+#define GL_IMAGE_TRANSLATE_Y_HP 0x8158
+#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159
+#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A
+#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B
+#define GL_IMAGE_MAG_FILTER_HP 0x815C
+#define GL_IMAGE_MIN_FILTER_HP 0x815D
+#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E
+#define GL_CUBIC_HP 0x815F
+#define GL_AVERAGE_HP 0x8160
+#define GL_IMAGE_TRANSFORM_2D_HP 0x8161
+#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162
+#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_IGNORE_BORDER_HP 0x8150
+#define GL_CONSTANT_BORDER_HP 0x8151
+#define GL_REPLICATE_BORDER_HP 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154
+#endif
+
+#ifndef GL_INGR_palette_buffer
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE
+#endif
+
+#ifndef GL_EXT_color_subtable
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_VERTEX_DATA_HINT_PGI 0x1A22A
+#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B
+#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C
+#define GL_MAX_VERTEX_HINT_PGI 0x1A22D
+#define GL_COLOR3_BIT_PGI 0x00010000
+#define GL_COLOR4_BIT_PGI 0x00020000
+#define GL_EDGEFLAG_BIT_PGI 0x00040000
+#define GL_INDEX_BIT_PGI 0x00080000
+#define GL_MAT_AMBIENT_BIT_PGI 0x00100000
+#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000
+#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000
+#define GL_MAT_EMISSION_BIT_PGI 0x00800000
+#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000
+#define GL_MAT_SHININESS_BIT_PGI 0x02000000
+#define GL_MAT_SPECULAR_BIT_PGI 0x04000000
+#define GL_NORMAL_BIT_PGI 0x08000000
+#define GL_TEXCOORD1_BIT_PGI 0x10000000
+#define GL_TEXCOORD2_BIT_PGI 0x20000000
+#define GL_TEXCOORD3_BIT_PGI 0x40000000
+#define GL_TEXCOORD4_BIT_PGI 0x80000000
+#define GL_VERTEX23_BIT_PGI 0x00000004
+#define GL_VERTEX4_BIT_PGI 0x00000008
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8
+#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD
+#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE
+#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202
+#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203
+#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204
+#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C
+#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D
+#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E
+#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F
+#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210
+#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211
+#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216
+#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217
+#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218
+#define GL_FULL_STIPPLE_HINT_PGI 0x1A219
+#define GL_CLIP_NEAR_HINT_PGI 0x1A220
+#define GL_CLIP_FAR_HINT_PGI 0x1A221
+#define GL_WIDE_LINE_HINT_PGI 0x1A222
+#define GL_BACK_NORMALS_HINT_PGI 0x1A223
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_LIST_PRIORITY_SGIX 0x8182
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_IR_INSTRUMENT1_SGIX 0x817F
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E
+#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F
+#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SHADOW_AMBIENT_SGIX 0x80BF
+#endif
+
+#ifndef GL_EXT_index_texture
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_INDEX_MATERIAL_EXT 0x81B8
+#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9
+#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_INDEX_TEST_EXT 0x81B5
+#define GL_INDEX_TEST_FUNC_EXT 0x81B6
+#define GL_INDEX_TEST_REF_EXT 0x81B7
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_IUI_V2F_EXT 0x81AD
+#define GL_IUI_V3F_EXT 0x81AE
+#define GL_IUI_N3F_V2F_EXT 0x81AF
+#define GL_IUI_N3F_V3F_EXT 0x81B0
+#define GL_T2F_IUI_V2F_EXT 0x81B1
+#define GL_T2F_IUI_V3F_EXT 0x81B2
+#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3
+#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8
+#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_CULL_VERTEX_EXT 0x81AA
+#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB
+#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_YCRCB_422_SGIX 0x81BB
+#define GL_YCRCB_444_SGIX 0x81BC
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_FRAGMENT_LIGHTING_SGIX 0x8400
+#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401
+#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402
+#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403
+#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404
+#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405
+#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406
+#define GL_LIGHT_ENV_MODE_SGIX 0x8407
+#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408
+#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409
+#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A
+#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B
+#define GL_FRAGMENT_LIGHT0_SGIX 0x840C
+#define GL_FRAGMENT_LIGHT1_SGIX 0x840D
+#define GL_FRAGMENT_LIGHT2_SGIX 0x840E
+#define GL_FRAGMENT_LIGHT3_SGIX 0x840F
+#define GL_FRAGMENT_LIGHT4_SGIX 0x8410
+#define GL_FRAGMENT_LIGHT5_SGIX 0x8411
+#define GL_FRAGMENT_LIGHT6_SGIX 0x8412
+#define GL_FRAGMENT_LIGHT7_SGIX 0x8413
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167
+#define GL_TEXTURE_POST_SPECULAR_HP 0x8168
+#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8
+#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_PHONG_WIN 0x80EA
+#define GL_PHONG_HINT_WIN 0x80EB
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_FRAGMENT_MATERIAL_EXT 0x8349
+#define GL_FRAGMENT_NORMAL_EXT 0x834A
+#define GL_FRAGMENT_COLOR_EXT 0x834C
+#define GL_ATTENUATION_EXT 0x834D
+#define GL_SHADOW_ATTENUATION_EXT 0x834E
+#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F
+#define GL_TEXTURE_LIGHT_EXT 0x8350
+#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351
+#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352
+
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_ALPHA_MIN_SGIX 0x8320
+#define GL_ALPHA_MAX_SGIX 0x8321
+#endif
+
+#ifndef GL_SGIX_impact_pixel_texture
+#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184
+#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185
+#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186
+#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187
+#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188
+#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189
+#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_BGR_EXT 0x80E0
+#define GL_BGRA_EXT 0x80E1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_ASYNC_MARKER_SGIX 0x8329
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C
+#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D
+#define GL_ASYNC_READ_PIXELS_SGIX 0x835E
+#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F
+#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360
+#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_ASYNC_HISTOGRAM_SGIX 0x832C
+#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D
+#endif
+
+#ifndef GL_INTEL_texture_scissor
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_PARALLEL_ARRAYS_INTEL 0x83F4
+#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5
+#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6
+#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7
+#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_OCCLUSION_TEST_HP 0x8165
+#define GL_OCCLUSION_TEST_RESULT_HP 0x8166
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330
+#define GL_PIXEL_MAG_FILTER_EXT 0x8331
+#define GL_PIXEL_MIN_FILTER_EXT 0x8332
+#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333
+#define GL_CUBIC_EXT 0x8334
+#define GL_AVERAGE_EXT 0x8335
+#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336
+#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337
+#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8
+#define GL_SINGLE_COLOR_EXT 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_COLOR_SUM_EXT 0x8458
+#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_PERTURB_EXT 0x85AE
+#define GL_TEXTURE_NORMAL_EXT 0x85AF
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
+#define GL_FOG_COORDINATE_EXT 0x8451
+#define GL_FRAGMENT_DEPTH_EXT 0x8452
+#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
+#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_SCREEN_COORDINATES_REND 0x8490
+#define GL_INVERTED_SCREEN_W_REND 0x8491
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_TANGENT_ARRAY_EXT 0x8439
+#define GL_BINORMAL_ARRAY_EXT 0x843A
+#define GL_CURRENT_TANGENT_EXT 0x843B
+#define GL_CURRENT_BINORMAL_EXT 0x843C
+#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E
+#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F
+#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440
+#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441
+#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442
+#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443
+#define GL_MAP1_TANGENT_EXT 0x8444
+#define GL_MAP2_TANGENT_EXT 0x8445
+#define GL_MAP1_BINORMAL_EXT 0x8446
+#define GL_MAP2_BINORMAL_EXT 0x8447
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_COMBINE_EXT 0x8570
+#define GL_COMBINE_RGB_EXT 0x8571
+#define GL_COMBINE_ALPHA_EXT 0x8572
+#define GL_RGB_SCALE_EXT 0x8573
+#define GL_ADD_SIGNED_EXT 0x8574
+#define GL_INTERPOLATE_EXT 0x8575
+#define GL_CONSTANT_EXT 0x8576
+#define GL_PRIMARY_COLOR_EXT 0x8577
+#define GL_PREVIOUS_EXT 0x8578
+#define GL_SOURCE0_RGB_EXT 0x8580
+#define GL_SOURCE1_RGB_EXT 0x8581
+#define GL_SOURCE2_RGB_EXT 0x8582
+#define GL_SOURCE0_ALPHA_EXT 0x8588
+#define GL_SOURCE1_ALPHA_EXT 0x8589
+#define GL_SOURCE2_ALPHA_EXT 0x858A
+#define GL_OPERAND0_RGB_EXT 0x8590
+#define GL_OPERAND1_RGB_EXT 0x8591
+#define GL_OPERAND2_RGB_EXT 0x8592
+#define GL_OPERAND0_ALPHA_EXT 0x8598
+#define GL_OPERAND1_ALPHA_EXT 0x8599
+#define GL_OPERAND2_ALPHA_EXT 0x859A
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_TRANSFORM_HINT_APPLE 0x85B1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_FOG_SCALE_SGIX 0x81FC
+#define GL_FOG_SCALE_VALUE_SGIX 0x81FD
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5
+#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_GLOBAL_ALPHA_SUN 0x81D9
+#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_RESTART_SUN 0x0001
+#define GL_REPLACE_MIDDLE_SUN 0x0002
+#define GL_REPLACE_OLDEST_SUN 0x0003
+#define GL_TRIANGLE_LIST_SUN 0x81D7
+#define GL_REPLACEMENT_CODE_SUN 0x81D8
+#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0
+#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1
+#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2
+#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3
+#define GL_R1UI_V3F_SUN 0x85C4
+#define GL_R1UI_C4UB_V3F_SUN 0x85C5
+#define GL_R1UI_C3F_V3F_SUN 0x85C6
+#define GL_R1UI_N3F_V3F_SUN 0x85C7
+#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8
+#define GL_R1UI_T2F_V3F_SUN 0x85C9
+#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA
+#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB
+#endif
+
+#ifndef GL_SUN_vertex
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_BLEND_DST_RGB_EXT 0x80C8
+#define GL_BLEND_SRC_RGB_EXT 0x80C9
+#define GL_BLEND_DST_ALPHA_EXT 0x80CA
+#define GL_BLEND_SRC_ALPHA_EXT 0x80CB
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_RED_MIN_CLAMP_INGR 0x8560
+#define GL_GREEN_MIN_CLAMP_INGR 0x8561
+#define GL_BLUE_MIN_CLAMP_INGR 0x8562
+#define GL_ALPHA_MIN_CLAMP_INGR 0x8563
+#define GL_RED_MAX_CLAMP_INGR 0x8564
+#define GL_GREEN_MAX_CLAMP_INGR 0x8565
+#define GL_BLUE_MAX_CLAMP_INGR 0x8566
+#define GL_ALPHA_MAX_CLAMP_INGR 0x8567
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INTERLACE_READ_INGR 0x8568
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_INCR_WRAP_EXT 0x8507
+#define GL_DECR_WRAP_EXT 0x8508
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_422_EXT 0x80CC
+#define GL_422_REV_EXT 0x80CD
+#define GL_422_AVERAGE_EXT 0x80CE
+#define GL_422_REV_AVERAGE_EXT 0x80CF
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NORMAL_MAP_NV 0x8511
+#define GL_REFLECTION_MAP_NV 0x8512
+#endif
+
+#ifndef GL_EXT_texture_cube_map
+#define GL_NORMAL_MAP_EXT 0x8511
+#define GL_REFLECTION_MAP_EXT 0x8512
+#define GL_TEXTURE_CUBE_MAP_EXT 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_WRAP_BORDER_SUN 0x81D4
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH
+#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502
+#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX
+#define GL_MODELVIEW1_MATRIX_EXT 0x8506
+#define GL_VERTEX_WEIGHTING_EXT 0x8509
+#define GL_MODELVIEW0_EXT GL_MODELVIEW
+#define GL_MODELVIEW1_EXT 0x850A
+#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B
+#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C
+#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D
+#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E
+#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F
+#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_MAX_SHININESS_NV 0x8504
+#define GL_MAX_SPOT_EXPONENT_NV 0x8505
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_NV 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E
+#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
+#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_REGISTER_COMBINERS_NV 0x8522
+#define GL_VARIABLE_A_NV 0x8523
+#define GL_VARIABLE_B_NV 0x8524
+#define GL_VARIABLE_C_NV 0x8525
+#define GL_VARIABLE_D_NV 0x8526
+#define GL_VARIABLE_E_NV 0x8527
+#define GL_VARIABLE_F_NV 0x8528
+#define GL_VARIABLE_G_NV 0x8529
+#define GL_CONSTANT_COLOR0_NV 0x852A
+#define GL_CONSTANT_COLOR1_NV 0x852B
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_SPARE0_NV 0x852E
+#define GL_SPARE1_NV 0x852F
+#define GL_DISCARD_NV 0x8530
+#define GL_E_TIMES_F_NV 0x8531
+#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532
+#define GL_UNSIGNED_IDENTITY_NV 0x8536
+#define GL_UNSIGNED_INVERT_NV 0x8537
+#define GL_EXPAND_NORMAL_NV 0x8538
+#define GL_EXPAND_NEGATE_NV 0x8539
+#define GL_HALF_BIAS_NORMAL_NV 0x853A
+#define GL_HALF_BIAS_NEGATE_NV 0x853B
+#define GL_SIGNED_IDENTITY_NV 0x853C
+#define GL_SIGNED_NEGATE_NV 0x853D
+#define GL_SCALE_BY_TWO_NV 0x853E
+#define GL_SCALE_BY_FOUR_NV 0x853F
+#define GL_SCALE_BY_ONE_HALF_NV 0x8540
+#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541
+#define GL_COMBINER_INPUT_NV 0x8542
+#define GL_COMBINER_MAPPING_NV 0x8543
+#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544
+#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545
+#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546
+#define GL_COMBINER_MUX_SUM_NV 0x8547
+#define GL_COMBINER_SCALE_NV 0x8548
+#define GL_COMBINER_BIAS_NV 0x8549
+#define GL_COMBINER_AB_OUTPUT_NV 0x854A
+#define GL_COMBINER_CD_OUTPUT_NV 0x854B
+#define GL_COMBINER_SUM_OUTPUT_NV 0x854C
+#define GL_MAX_GENERAL_COMBINERS_NV 0x854D
+#define GL_NUM_GENERAL_COMBINERS_NV 0x854E
+#define GL_COLOR_SUM_CLAMP_NV 0x854F
+#define GL_COMBINER0_NV 0x8550
+#define GL_COMBINER1_NV 0x8551
+#define GL_COMBINER2_NV 0x8552
+#define GL_COMBINER3_NV 0x8553
+#define GL_COMBINER4_NV 0x8554
+#define GL_COMBINER5_NV 0x8555
+#define GL_COMBINER6_NV 0x8556
+#define GL_COMBINER7_NV 0x8557
+
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_FOG_DISTANCE_MODE_NV 0x855A
+#define GL_EYE_RADIAL_NV 0x855B
+#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C
+
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_EMBOSS_LIGHT_NV 0x855D
+#define GL_EMBOSS_CONSTANT_NV 0x855E
+#define GL_EMBOSS_MAP_NV 0x855F
+#endif
+
+#ifndef GL_NV_blend_square
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_COMBINE4_NV 0x8503
+#define GL_SOURCE3_RGB_NV 0x8583
+#define GL_SOURCE3_ALPHA_NV 0x858B
+#define GL_OPERAND3_RGB_NV 0x8593
+#define GL_OPERAND3_ALPHA_NV 0x859B
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#endif
+
+#ifndef GL_MESA_window_pos
+#endif
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_CULL_VERTEX_IBM 103050
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_VERTEX_ARRAY_LIST_IBM 103070
+#define GL_NORMAL_ARRAY_LIST_IBM 103071
+#define GL_COLOR_ARRAY_LIST_IBM 103072
+#define GL_INDEX_ARRAY_LIST_IBM 103073
+#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074
+#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075
+#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076
+#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077
+#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080
+#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081
+#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082
+#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083
+#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084
+#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085
+#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086
+#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0
+#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1
+#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2
+#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3
+#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_YCRCB_SGIX 0x8318
+#define GL_YCRCBA_SGIX 0x8319
+#endif
+
+#ifndef GL_SGI_depth_pass_instrument
+#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310
+#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311
+#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0
+#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_MULTISAMPLE_3DFX 0x86B2
+#define GL_SAMPLE_BUFFERS_3DFX 0x86B3
+#define GL_SAMPLES_3DFX 0x86B4
+#define GL_MULTISAMPLE_BIT_3DFX 0x20000000
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#define GL_SAMPLE_MASK_EXT 0x80A0
+#define GL_1PASS_EXT 0x80A1
+#define GL_2PASS_0_EXT 0x80A2
+#define GL_2PASS_1_EXT 0x80A3
+#define GL_4PASS_0_EXT 0x80A4
+#define GL_4PASS_1_EXT 0x80A5
+#define GL_4PASS_2_EXT 0x80A6
+#define GL_4PASS_3_EXT 0x80A7
+#define GL_SAMPLE_BUFFERS_EXT 0x80A8
+#define GL_SAMPLES_EXT 0x80A9
+#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA
+#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB
+#define GL_SAMPLE_PATTERN_EXT 0x80AC
+#define GL_MULTISAMPLE_BIT_EXT 0x20000000
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_CONVOLUTION_HINT_SGIX 0x8316
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_PACK_RESAMPLE_SGIX 0x842C
+#define GL_UNPACK_RESAMPLE_SGIX 0x842D
+#define GL_RESAMPLE_REPLICATE_SGIX 0x842E
+#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F
+#define GL_RESAMPLE_DECIMATE_SGIX 0x8430
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0
+#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1
+#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2
+#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3
+#define GL_EYE_POINT_SGIS 0x81F4
+#define GL_OBJECT_POINT_SGIS 0x81F5
+#define GL_EYE_LINE_SGIS 0x81F6
+#define GL_OBJECT_LINE_SGIS 0x81F7
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF
+#endif
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_DOT3_RGB_EXT 0x8740
+#define GL_DOT3_RGBA_EXT 0x8741
+#endif
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_MIRROR_CLAMP_ATI 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743
+#endif
+
+#ifndef GL_NV_fence
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+#endif
+
+#ifndef GL_IBM_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_IBM 0x8370
+#endif
+
+#ifndef GL_NV_evaluators
+#define GL_EVAL_2D_NV 0x86C0
+#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1
+#define GL_MAP_TESSELLATION_NV 0x86C2
+#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3
+#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4
+#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5
+#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6
+#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7
+#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8
+#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9
+#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA
+#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB
+#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC
+#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD
+#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE
+#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF
+#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0
+#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1
+#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2
+#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3
+#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4
+#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5
+#define GL_MAX_MAP_TESSELLATION_NV 0x86D6
+#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7
+#endif
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_DEPTH_STENCIL_NV 0x84F9
+#define GL_UNSIGNED_INT_24_8_NV 0x84FA
+#endif
+
+#ifndef GL_NV_register_combiners2
+#define GL_PER_STAGE_CONSTANTS_NV 0x8535
+#endif
+
+#ifndef GL_NV_texture_compression_vtc
+#endif
+
+#ifndef GL_NV_texture_rectangle
+#define GL_TEXTURE_RECTANGLE_NV 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8
+#endif
+
+#ifndef GL_NV_texture_shader
+#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C
+#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D
+#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E
+#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9
+#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA
+#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB
+#define GL_DSDT_MAG_INTENSITY_NV 0x86DC
+#define GL_SHADER_CONSISTENT_NV 0x86DD
+#define GL_TEXTURE_SHADER_NV 0x86DE
+#define GL_SHADER_OPERATION_NV 0x86DF
+#define GL_CULL_MODES_NV 0x86E0
+#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1
+#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2
+#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3
+#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV
+#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV
+#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV
+#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4
+#define GL_CONST_EYE_NV 0x86E5
+#define GL_PASS_THROUGH_NV 0x86E6
+#define GL_CULL_FRAGMENT_NV 0x86E7
+#define GL_OFFSET_TEXTURE_2D_NV 0x86E8
+#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9
+#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA
+#define GL_DOT_PRODUCT_NV 0x86EC
+#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED
+#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE
+#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0
+#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1
+#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2
+#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3
+#define GL_HILO_NV 0x86F4
+#define GL_DSDT_NV 0x86F5
+#define GL_DSDT_MAG_NV 0x86F6
+#define GL_DSDT_MAG_VIB_NV 0x86F7
+#define GL_HILO16_NV 0x86F8
+#define GL_SIGNED_HILO_NV 0x86F9
+#define GL_SIGNED_HILO16_NV 0x86FA
+#define GL_SIGNED_RGBA_NV 0x86FB
+#define GL_SIGNED_RGBA8_NV 0x86FC
+#define GL_SIGNED_RGB_NV 0x86FE
+#define GL_SIGNED_RGB8_NV 0x86FF
+#define GL_SIGNED_LUMINANCE_NV 0x8701
+#define GL_SIGNED_LUMINANCE8_NV 0x8702
+#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
+#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
+#define GL_SIGNED_ALPHA_NV 0x8705
+#define GL_SIGNED_ALPHA8_NV 0x8706
+#define GL_SIGNED_INTENSITY_NV 0x8707
+#define GL_SIGNED_INTENSITY8_NV 0x8708
+#define GL_DSDT8_NV 0x8709
+#define GL_DSDT8_MAG8_NV 0x870A
+#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
+#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
+#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+#define GL_HI_SCALE_NV 0x870E
+#define GL_LO_SCALE_NV 0x870F
+#define GL_DS_SCALE_NV 0x8710
+#define GL_DT_SCALE_NV 0x8711
+#define GL_MAGNITUDE_SCALE_NV 0x8712
+#define GL_VIBRANCE_SCALE_NV 0x8713
+#define GL_HI_BIAS_NV 0x8714
+#define GL_LO_BIAS_NV 0x8715
+#define GL_DS_BIAS_NV 0x8716
+#define GL_DT_BIAS_NV 0x8717
+#define GL_MAGNITUDE_BIAS_NV 0x8718
+#define GL_VIBRANCE_BIAS_NV 0x8719
+#define GL_TEXTURE_BORDER_VALUES_NV 0x871A
+#define GL_TEXTURE_HI_SIZE_NV 0x871B
+#define GL_TEXTURE_LO_SIZE_NV 0x871C
+#define GL_TEXTURE_DS_SIZE_NV 0x871D
+#define GL_TEXTURE_DT_SIZE_NV 0x871E
+#define GL_TEXTURE_MAG_SIZE_NV 0x871F
+#endif
+
+#ifndef GL_NV_texture_shader2
+#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF
+#endif
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533
+#endif
+
+#ifndef GL_NV_vertex_program
+#define GL_VERTEX_PROGRAM_NV 0x8620
+#define GL_VERTEX_STATE_PROGRAM_NV 0x8621
+#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623
+#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624
+#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625
+#define GL_CURRENT_ATTRIB_NV 0x8626
+#define GL_PROGRAM_LENGTH_NV 0x8627
+#define GL_PROGRAM_STRING_NV 0x8628
+#define GL_MODELVIEW_PROJECTION_NV 0x8629
+#define GL_IDENTITY_NV 0x862A
+#define GL_INVERSE_NV 0x862B
+#define GL_TRANSPOSE_NV 0x862C
+#define GL_INVERSE_TRANSPOSE_NV 0x862D
+#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E
+#define GL_MAX_TRACK_MATRICES_NV 0x862F
+#define GL_MATRIX0_NV 0x8630
+#define GL_MATRIX1_NV 0x8631
+#define GL_MATRIX2_NV 0x8632
+#define GL_MATRIX3_NV 0x8633
+#define GL_MATRIX4_NV 0x8634
+#define GL_MATRIX5_NV 0x8635
+#define GL_MATRIX6_NV 0x8636
+#define GL_MATRIX7_NV 0x8637
+#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640
+#define GL_CURRENT_MATRIX_NV 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643
+#define GL_PROGRAM_PARAMETER_NV 0x8644
+#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645
+#define GL_PROGRAM_TARGET_NV 0x8646
+#define GL_PROGRAM_RESIDENT_NV 0x8647
+#define GL_TRACK_MATRIX_NV 0x8648
+#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649
+#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A
+#define GL_PROGRAM_ERROR_POSITION_NV 0x864B
+#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650
+#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651
+#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652
+#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653
+#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654
+#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655
+#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656
+#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657
+#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658
+#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659
+#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A
+#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B
+#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C
+#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D
+#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E
+#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F
+#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660
+#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661
+#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662
+#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663
+#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664
+#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665
+#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666
+#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667
+#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668
+#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669
+#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A
+#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B
+#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C
+#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D
+#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E
+#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F
+#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670
+#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671
+#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672
+#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673
+#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674
+#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675
+#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676
+#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677
+#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678
+#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679
+#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A
+#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B
+#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C
+#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D
+#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E
+#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F
+#endif
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369
+#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A
+#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B
+#endif
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SCALEBIAS_HINT_SGIX 0x8322
+#endif
+
+#ifndef GL_OML_interlace
+#define GL_INTERLACE_OML 0x8980
+#define GL_INTERLACE_READ_OML 0x8981
+#endif
+
+#ifndef GL_OML_subsample
+#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982
+#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983
+#endif
+
+#ifndef GL_OML_resample
+#define GL_PACK_RESAMPLE_OML 0x8984
+#define GL_UNPACK_RESAMPLE_OML 0x8985
+#define GL_RESAMPLE_REPLICATE_OML 0x8986
+#define GL_RESAMPLE_ZERO_FILL_OML 0x8987
+#define GL_RESAMPLE_AVERAGE_OML 0x8988
+#define GL_RESAMPLE_DECIMATE_OML 0x8989
+#endif
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E
+#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F
+#endif
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_BUMP_ROT_MATRIX_ATI 0x8775
+#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776
+#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777
+#define GL_BUMP_TEX_UNITS_ATI 0x8778
+#define GL_DUDV_ATI 0x8779
+#define GL_DU8DV8_ATI 0x877A
+#define GL_BUMP_ENVMAP_ATI 0x877B
+#define GL_BUMP_TARGET_ATI 0x877C
+#endif
+
+#ifndef GL_ATI_fragment_shader
+#define GL_FRAGMENT_SHADER_ATI 0x8920
+#define GL_REG_0_ATI 0x8921
+#define GL_REG_1_ATI 0x8922
+#define GL_REG_2_ATI 0x8923
+#define GL_REG_3_ATI 0x8924
+#define GL_REG_4_ATI 0x8925
+#define GL_REG_5_ATI 0x8926
+#define GL_REG_6_ATI 0x8927
+#define GL_REG_7_ATI 0x8928
+#define GL_REG_8_ATI 0x8929
+#define GL_REG_9_ATI 0x892A
+#define GL_REG_10_ATI 0x892B
+#define GL_REG_11_ATI 0x892C
+#define GL_REG_12_ATI 0x892D
+#define GL_REG_13_ATI 0x892E
+#define GL_REG_14_ATI 0x892F
+#define GL_REG_15_ATI 0x8930
+#define GL_REG_16_ATI 0x8931
+#define GL_REG_17_ATI 0x8932
+#define GL_REG_18_ATI 0x8933
+#define GL_REG_19_ATI 0x8934
+#define GL_REG_20_ATI 0x8935
+#define GL_REG_21_ATI 0x8936
+#define GL_REG_22_ATI 0x8937
+#define GL_REG_23_ATI 0x8938
+#define GL_REG_24_ATI 0x8939
+#define GL_REG_25_ATI 0x893A
+#define GL_REG_26_ATI 0x893B
+#define GL_REG_27_ATI 0x893C
+#define GL_REG_28_ATI 0x893D
+#define GL_REG_29_ATI 0x893E
+#define GL_REG_30_ATI 0x893F
+#define GL_REG_31_ATI 0x8940
+#define GL_CON_0_ATI 0x8941
+#define GL_CON_1_ATI 0x8942
+#define GL_CON_2_ATI 0x8943
+#define GL_CON_3_ATI 0x8944
+#define GL_CON_4_ATI 0x8945
+#define GL_CON_5_ATI 0x8946
+#define GL_CON_6_ATI 0x8947
+#define GL_CON_7_ATI 0x8948
+#define GL_CON_8_ATI 0x8949
+#define GL_CON_9_ATI 0x894A
+#define GL_CON_10_ATI 0x894B
+#define GL_CON_11_ATI 0x894C
+#define GL_CON_12_ATI 0x894D
+#define GL_CON_13_ATI 0x894E
+#define GL_CON_14_ATI 0x894F
+#define GL_CON_15_ATI 0x8950
+#define GL_CON_16_ATI 0x8951
+#define GL_CON_17_ATI 0x8952
+#define GL_CON_18_ATI 0x8953
+#define GL_CON_19_ATI 0x8954
+#define GL_CON_20_ATI 0x8955
+#define GL_CON_21_ATI 0x8956
+#define GL_CON_22_ATI 0x8957
+#define GL_CON_23_ATI 0x8958
+#define GL_CON_24_ATI 0x8959
+#define GL_CON_25_ATI 0x895A
+#define GL_CON_26_ATI 0x895B
+#define GL_CON_27_ATI 0x895C
+#define GL_CON_28_ATI 0x895D
+#define GL_CON_29_ATI 0x895E
+#define GL_CON_30_ATI 0x895F
+#define GL_CON_31_ATI 0x8960
+#define GL_MOV_ATI 0x8961
+#define GL_ADD_ATI 0x8963
+#define GL_MUL_ATI 0x8964
+#define GL_SUB_ATI 0x8965
+#define GL_DOT3_ATI 0x8966
+#define GL_DOT4_ATI 0x8967
+#define GL_MAD_ATI 0x8968
+#define GL_LERP_ATI 0x8969
+#define GL_CND_ATI 0x896A
+#define GL_CND0_ATI 0x896B
+#define GL_DOT2_ADD_ATI 0x896C
+#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D
+#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E
+#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F
+#define GL_NUM_PASSES_ATI 0x8970
+#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971
+#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972
+#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973
+#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974
+#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975
+#define GL_SWIZZLE_STR_ATI 0x8976
+#define GL_SWIZZLE_STQ_ATI 0x8977
+#define GL_SWIZZLE_STR_DR_ATI 0x8978
+#define GL_SWIZZLE_STQ_DQ_ATI 0x8979
+#define GL_SWIZZLE_STRQ_ATI 0x897A
+#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B
+#define GL_RED_BIT_ATI 0x00000001
+#define GL_GREEN_BIT_ATI 0x00000002
+#define GL_BLUE_BIT_ATI 0x00000004
+#define GL_2X_BIT_ATI 0x00000001
+#define GL_4X_BIT_ATI 0x00000002
+#define GL_8X_BIT_ATI 0x00000004
+#define GL_HALF_BIT_ATI 0x00000008
+#define GL_QUARTER_BIT_ATI 0x00000010
+#define GL_EIGHTH_BIT_ATI 0x00000020
+#define GL_SATURATE_BIT_ATI 0x00000040
+#define GL_COMP_BIT_ATI 0x00000002
+#define GL_NEGATE_BIT_ATI 0x00000004
+#define GL_BIAS_BIT_ATI 0x00000008
+#endif
+
+#ifndef GL_ATI_pn_triangles
+#define GL_PN_TRIANGLES_ATI 0x87F0
+#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
+#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2
+#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3
+#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
+#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
+#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
+#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
+#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
+#endif
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_STATIC_ATI 0x8760
+#define GL_DYNAMIC_ATI 0x8761
+#define GL_PRESERVE_ATI 0x8762
+#define GL_DISCARD_ATI 0x8763
+#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764
+#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765
+#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766
+#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767
+#endif
+
+#ifndef GL_EXT_vertex_shader
+#define GL_VERTEX_SHADER_EXT 0x8780
+#define GL_VERTEX_SHADER_BINDING_EXT 0x8781
+#define GL_OP_INDEX_EXT 0x8782
+#define GL_OP_NEGATE_EXT 0x8783
+#define GL_OP_DOT3_EXT 0x8784
+#define GL_OP_DOT4_EXT 0x8785
+#define GL_OP_MUL_EXT 0x8786
+#define GL_OP_ADD_EXT 0x8787
+#define GL_OP_MADD_EXT 0x8788
+#define GL_OP_FRAC_EXT 0x8789
+#define GL_OP_MAX_EXT 0x878A
+#define GL_OP_MIN_EXT 0x878B
+#define GL_OP_SET_GE_EXT 0x878C
+#define GL_OP_SET_LT_EXT 0x878D
+#define GL_OP_CLAMP_EXT 0x878E
+#define GL_OP_FLOOR_EXT 0x878F
+#define GL_OP_ROUND_EXT 0x8790
+#define GL_OP_EXP_BASE_2_EXT 0x8791
+#define GL_OP_LOG_BASE_2_EXT 0x8792
+#define GL_OP_POWER_EXT 0x8793
+#define GL_OP_RECIP_EXT 0x8794
+#define GL_OP_RECIP_SQRT_EXT 0x8795
+#define GL_OP_SUB_EXT 0x8796
+#define GL_OP_CROSS_PRODUCT_EXT 0x8797
+#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798
+#define GL_OP_MOV_EXT 0x8799
+#define GL_OUTPUT_VERTEX_EXT 0x879A
+#define GL_OUTPUT_COLOR0_EXT 0x879B
+#define GL_OUTPUT_COLOR1_EXT 0x879C
+#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D
+#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E
+#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F
+#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0
+#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1
+#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2
+#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3
+#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4
+#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5
+#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6
+#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7
+#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8
+#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9
+#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA
+#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB
+#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC
+#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD
+#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE
+#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF
+#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0
+#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1
+#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2
+#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3
+#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4
+#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5
+#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6
+#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7
+#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8
+#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9
+#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA
+#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB
+#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC
+#define GL_OUTPUT_FOG_EXT 0x87BD
+#define GL_SCALAR_EXT 0x87BE
+#define GL_VECTOR_EXT 0x87BF
+#define GL_MATRIX_EXT 0x87C0
+#define GL_VARIANT_EXT 0x87C1
+#define GL_INVARIANT_EXT 0x87C2
+#define GL_LOCAL_CONSTANT_EXT 0x87C3
+#define GL_LOCAL_EXT 0x87C4
+#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5
+#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6
+#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7
+#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8
+#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE
+#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF
+#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0
+#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1
+#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2
+#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3
+#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4
+#define GL_X_EXT 0x87D5
+#define GL_Y_EXT 0x87D6
+#define GL_Z_EXT 0x87D7
+#define GL_W_EXT 0x87D8
+#define GL_NEGATIVE_X_EXT 0x87D9
+#define GL_NEGATIVE_Y_EXT 0x87DA
+#define GL_NEGATIVE_Z_EXT 0x87DB
+#define GL_NEGATIVE_W_EXT 0x87DC
+#define GL_ZERO_EXT 0x87DD
+#define GL_ONE_EXT 0x87DE
+#define GL_NEGATIVE_ONE_EXT 0x87DF
+#define GL_NORMALIZED_RANGE_EXT 0x87E0
+#define GL_FULL_RANGE_EXT 0x87E1
+#define GL_CURRENT_VERTEX_EXT 0x87E2
+#define GL_MVP_MATRIX_EXT 0x87E3
+#define GL_VARIANT_VALUE_EXT 0x87E4
+#define GL_VARIANT_DATATYPE_EXT 0x87E5
+#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6
+#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7
+#define GL_VARIANT_ARRAY_EXT 0x87E8
+#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9
+#define GL_INVARIANT_VALUE_EXT 0x87EA
+#define GL_INVARIANT_DATATYPE_EXT 0x87EB
+#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC
+#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED
+#endif
+
+#ifndef GL_ATI_vertex_streams
+#define GL_MAX_VERTEX_STREAMS_ATI 0x876B
+#define GL_VERTEX_STREAM0_ATI 0x876C
+#define GL_VERTEX_STREAM1_ATI 0x876D
+#define GL_VERTEX_STREAM2_ATI 0x876E
+#define GL_VERTEX_STREAM3_ATI 0x876F
+#define GL_VERTEX_STREAM4_ATI 0x8770
+#define GL_VERTEX_STREAM5_ATI 0x8771
+#define GL_VERTEX_STREAM6_ATI 0x8772
+#define GL_VERTEX_STREAM7_ATI 0x8773
+#define GL_VERTEX_SOURCE_ATI 0x8774
+#endif
+
+#ifndef GL_ATI_element_array
+#define GL_ELEMENT_ARRAY_ATI 0x8768
+#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769
+#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A
+#endif
+
+#ifndef GL_SUN_mesh_array
+#define GL_QUAD_MESH_SUN 0x8614
+#define GL_TRIANGLE_MESH_SUN 0x8615
+#endif
+
+#ifndef GL_SUN_slice_accum
+#define GL_SLICE_ACCUM_SUN 0x85CC
+#endif
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534
+#endif
+
+#ifndef GL_NV_depth_clamp
+#define GL_DEPTH_CLAMP_NV 0x864F
+#endif
+
+#ifndef GL_NV_occlusion_query
+#define GL_PIXEL_COUNTER_BITS_NV 0x8864
+#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865
+#define GL_PIXEL_COUNT_NV 0x8866
+#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867
+#endif
+
+#ifndef GL_NV_point_sprite
+#define GL_POINT_SPRITE_NV 0x8861
+#define GL_COORD_REPLACE_NV 0x8862
+#define GL_POINT_SPRITE_R_MODE_NV 0x8863
+#endif
+
+#ifndef GL_NV_texture_shader3
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853
+#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854
+#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857
+#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858
+#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859
+#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A
+#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B
+#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C
+#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D
+#define GL_HILO8_NV 0x885E
+#define GL_SIGNED_HILO8_NV 0x885F
+#define GL_FORCE_BLUE_TO_ONE_NV 0x8860
+#endif
+
+#ifndef GL_NV_vertex_program1_1
+#endif
+
+#ifndef GL_EXT_shadow_funcs
+#endif
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
+#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
+#endif
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200
+#endif
+
+#ifndef GL_APPLE_client_storage
+#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2
+#endif
+
+#ifndef GL_APPLE_element_array
+#define GL_ELEMENT_ARRAY_APPLE 0x8A0C
+#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D
+#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E
+#endif
+
+#ifndef GL_APPLE_fence
+#define GL_DRAW_PIXELS_APPLE 0x8A0A
+#define GL_FENCE_APPLE 0x8A0B
+#endif
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5
+#endif
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E
+#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F
+#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521
+#define GL_STORAGE_CLIENT_APPLE 0x85B4
+#define GL_STORAGE_CACHED_APPLE 0x85BE
+#define GL_STORAGE_SHARED_APPLE 0x85BF
+#endif
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_YCBCR_422_APPLE 0x85B9
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#endif
+
+#ifndef GL_S3_s3tc
+#define GL_RGB_S3TC 0x83A0
+#define GL_RGB4_S3TC 0x83A1
+#define GL_RGBA_S3TC 0x83A2
+#define GL_RGBA4_S3TC 0x83A3
+#endif
+
+#ifndef GL_ATI_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_ATI 0x8824
+#define GL_DRAW_BUFFER0_ATI 0x8825
+#define GL_DRAW_BUFFER1_ATI 0x8826
+#define GL_DRAW_BUFFER2_ATI 0x8827
+#define GL_DRAW_BUFFER3_ATI 0x8828
+#define GL_DRAW_BUFFER4_ATI 0x8829
+#define GL_DRAW_BUFFER5_ATI 0x882A
+#define GL_DRAW_BUFFER6_ATI 0x882B
+#define GL_DRAW_BUFFER7_ATI 0x882C
+#define GL_DRAW_BUFFER8_ATI 0x882D
+#define GL_DRAW_BUFFER9_ATI 0x882E
+#define GL_DRAW_BUFFER10_ATI 0x882F
+#define GL_DRAW_BUFFER11_ATI 0x8830
+#define GL_DRAW_BUFFER12_ATI 0x8831
+#define GL_DRAW_BUFFER13_ATI 0x8832
+#define GL_DRAW_BUFFER14_ATI 0x8833
+#define GL_DRAW_BUFFER15_ATI 0x8834
+#endif
+
+#ifndef GL_ATI_pixel_format_float
+#define GL_TYPE_RGBA_FLOAT_ATI 0x8820
+#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
+#endif
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_MODULATE_ADD_ATI 0x8744
+#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
+#define GL_MODULATE_SUBTRACT_ATI 0x8746
+#endif
+
+#ifndef GL_ATI_texture_float
+#define GL_RGBA_FLOAT32_ATI 0x8814
+#define GL_RGB_FLOAT32_ATI 0x8815
+#define GL_ALPHA_FLOAT32_ATI 0x8816
+#define GL_INTENSITY_FLOAT32_ATI 0x8817
+#define GL_LUMINANCE_FLOAT32_ATI 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819
+#define GL_RGBA_FLOAT16_ATI 0x881A
+#define GL_RGB_FLOAT16_ATI 0x881B
+#define GL_ALPHA_FLOAT16_ATI 0x881C
+#define GL_INTENSITY_FLOAT16_ATI 0x881D
+#define GL_LUMINANCE_FLOAT16_ATI 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F
+#endif
+
+#ifndef GL_NV_float_buffer
+#define GL_FLOAT_R_NV 0x8880
+#define GL_FLOAT_RG_NV 0x8881
+#define GL_FLOAT_RGB_NV 0x8882
+#define GL_FLOAT_RGBA_NV 0x8883
+#define GL_FLOAT_R16_NV 0x8884
+#define GL_FLOAT_R32_NV 0x8885
+#define GL_FLOAT_RG16_NV 0x8886
+#define GL_FLOAT_RG32_NV 0x8887
+#define GL_FLOAT_RGB16_NV 0x8888
+#define GL_FLOAT_RGB32_NV 0x8889
+#define GL_FLOAT_RGBA16_NV 0x888A
+#define GL_FLOAT_RGBA32_NV 0x888B
+#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C
+#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D
+#define GL_FLOAT_RGBA_MODE_NV 0x888E
+#endif
+
+#ifndef GL_NV_fragment_program
+#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868
+#define GL_FRAGMENT_PROGRAM_NV 0x8870
+#define GL_MAX_TEXTURE_COORDS_NV 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872
+#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873
+#define GL_PROGRAM_ERROR_STRING_NV 0x8874
+#endif
+
+#ifndef GL_NV_half_float
+#define GL_HALF_FLOAT_NV 0x140B
+#endif
+
+#ifndef GL_NV_pixel_data_range
+#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878
+#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879
+#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A
+#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B
+#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C
+#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D
+#endif
+
+#ifndef GL_NV_primitive_restart
+#define GL_PRIMITIVE_RESTART_NV 0x8558
+#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559
+#endif
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F
+#endif
+
+#ifndef GL_NV_vertex_program2
+#endif
+
+#ifndef GL_ATI_map_object_buffer
+#endif
+
+#ifndef GL_ATI_separate_stencil
+#define GL_STENCIL_BACK_FUNC_ATI 0x8800
+#define GL_STENCIL_BACK_FAIL_ATI 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803
+#endif
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#endif
+
+#ifndef GL_OES_read_format
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B
+#endif
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890
+#define GL_DEPTH_BOUNDS_EXT 0x8891
+#endif
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_MIRROR_CLAMP_EXT 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
+#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
+#endif
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_BLEND_EQUATION_RGB_EXT 0x8009
+#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D
+#endif
+
+#ifndef GL_MESA_pack_invert
+#define GL_PACK_INVERT_MESA 0x8758
+#endif
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB
+#define GL_YCBCR_MESA 0x8757
+#endif
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF
+#endif
+
+#ifndef GL_NV_fragment_program_option
+#endif
+
+#ifndef GL_NV_fragment_program2
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5
+#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6
+#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7
+#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8
+#endif
+
+#ifndef GL_NV_vertex_program2_option
+
+#endif
+
+#ifndef GL_NV_vertex_program3
+
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
+#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
+#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
+#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
+#define GL_FRAMEBUFFER_EXT 0x8D40
+#define GL_RENDERBUFFER_EXT 0x8D41
+#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
+#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
+#define GL_STENCIL_INDEX1_EXT 0x8D46
+#define GL_STENCIL_INDEX4_EXT 0x8D47
+#define GL_STENCIL_INDEX8_EXT 0x8D48
+#define GL_STENCIL_INDEX16_EXT 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
+#endif
+
+#ifndef GL_GREMEDY_string_marker
+#endif
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_DEPTH_STENCIL_EXT 0x84F9
+#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
+#define GL_DEPTH24_STENCIL8_EXT 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
+#endif
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_STENCIL_TAG_BITS_EXT 0x88F2
+#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3
+#endif
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB8_EXT 0x8C41
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
+#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
+#define GL_SLUMINANCE_EXT 0x8C46
+#define GL_SLUMINANCE8_EXT 0x8C47
+#define GL_COMPRESSED_SRGB_EXT 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
+#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#endif
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT
+#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+#endif
+
+#ifndef GL_MESAX_texture_stack
+#define GL_TEXTURE_1D_STACK_MESAX 0x8759
+#define GL_TEXTURE_2D_STACK_MESAX 0x875A
+#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B
+#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C
+#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D
+#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E
+#endif
+
+#ifndef GL_EXT_timer_query
+#define GL_TIME_ELAPSED_EXT 0x88BF
+#endif
+
+#ifndef GL_EXT_gpu_program_parameters
+#endif
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12
+#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13
+#endif
+
+#ifndef GL_NV_gpu_program4
+#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905
+#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906
+#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907
+#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908
+#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909
+#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5
+#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6
+#endif
+
+#ifndef GL_NV_geometry_program4
+#define GL_LINES_ADJACENCY_EXT 0x000A
+#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B
+#define GL_TRIANGLES_ADJACENCY_EXT 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D
+#define GL_GEOMETRY_PROGRAM_NV 0x8C26
+#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27
+#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28
+#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
+#define GL_PROGRAM_POINT_SIZE_EXT 0x8642
+#endif
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE
+#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+
+#endif
+
+#ifndef GL_NV_vertex_program4
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD
+#endif
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0
+#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1
+#define GL_SAMPLER_BUFFER_EXT 0x8DC2
+#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5
+#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6
+#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7
+#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8
+#define GL_INT_SAMPLER_1D_EXT 0x8DC9
+#define GL_INT_SAMPLER_2D_EXT 0x8DCA
+#define GL_INT_SAMPLER_3D_EXT 0x8DCB
+#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC
+#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD
+#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF
+#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+#endif
+
+#ifndef GL_EXT_draw_instanced
+#endif
+
+#ifndef GL_EXT_packed_float
+#define GL_R11F_G11F_B10F_EXT 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B
+#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C
+#endif
+
+#ifndef GL_EXT_texture_array
+#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19
+#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D
+#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF
+#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E
+
+#endif
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_TEXTURE_BUFFER_EXT 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E
+#endif
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
+#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
+#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
+#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
+#endif
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#endif
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_RGB9_E5_EXT 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F
+#endif
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_DEPTH_COMPONENT32F_NV 0x8DAB
+#define GL_DEPTH32F_STENCIL8_NV 0x8DAC
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
+#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF
+#endif
+
+#ifndef GL_NV_fragment_program4
+#endif
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
+#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10
+#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
+#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+#endif
+
+#ifndef GL_NV_geometry_shader4
+#endif
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1
+#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2
+#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3
+#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4
+#endif
+
+#ifndef GL_EXT_draw_buffers2
+#endif
+
+#ifndef GL_NV_transform_feedback
+#define GL_BACK_PRIMARY_COLOR_NV 0x8C77
+#define GL_BACK_SECONDARY_COLOR_NV 0x8C78
+#define GL_TEXTURE_COORD_NV 0x8C79
+#define GL_CLIP_DISTANCE_NV 0x8C7A
+#define GL_VERTEX_ID_NV 0x8C7B
+#define GL_PRIMITIVE_ID_NV 0x8C7C
+#define GL_GENERIC_ATTRIB_NV 0x8C7D
+#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80
+#define GL_ACTIVE_VARYINGS_NV 0x8C81
+#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85
+#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86
+#define GL_PRIMITIVES_GENERATED_NV 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88
+#define GL_RASTERIZER_DISCARD_NV 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C
+#define GL_SEPARATE_ATTRIBS_NV 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F
+#define GL_LAYER_NV 0x8DAA
+#define GL_NEXT_BUFFER_NV -2
+#define GL_SKIP_COMPONENTS4_NV -3
+#define GL_SKIP_COMPONENTS3_NV -4
+#define GL_SKIP_COMPONENTS2_NV -5
+#define GL_SKIP_COMPONENTS1_NV -6
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2
+#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3
+#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4
+#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED
+#define GL_UNIFORM_BUFFER_EXT 0x8DEE
+#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF
+#endif
+
+#ifndef GL_EXT_texture_integer
+#define GL_RGBA32UI_EXT 0x8D70
+#define GL_RGB32UI_EXT 0x8D71
+#define GL_ALPHA32UI_EXT 0x8D72
+#define GL_INTENSITY32UI_EXT 0x8D73
+#define GL_LUMINANCE32UI_EXT 0x8D74
+#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75
+#define GL_RGBA16UI_EXT 0x8D76
+#define GL_RGB16UI_EXT 0x8D77
+#define GL_ALPHA16UI_EXT 0x8D78
+#define GL_INTENSITY16UI_EXT 0x8D79
+#define GL_LUMINANCE16UI_EXT 0x8D7A
+#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B
+#define GL_RGBA8UI_EXT 0x8D7C
+#define GL_RGB8UI_EXT 0x8D7D
+#define GL_ALPHA8UI_EXT 0x8D7E
+#define GL_INTENSITY8UI_EXT 0x8D7F
+#define GL_LUMINANCE8UI_EXT 0x8D80
+#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81
+#define GL_RGBA32I_EXT 0x8D82
+#define GL_RGB32I_EXT 0x8D83
+#define GL_ALPHA32I_EXT 0x8D84
+#define GL_INTENSITY32I_EXT 0x8D85
+#define GL_LUMINANCE32I_EXT 0x8D86
+#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87
+#define GL_RGBA16I_EXT 0x8D88
+#define GL_RGB16I_EXT 0x8D89
+#define GL_ALPHA16I_EXT 0x8D8A
+#define GL_INTENSITY16I_EXT 0x8D8B
+#define GL_LUMINANCE16I_EXT 0x8D8C
+#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D
+#define GL_RGBA8I_EXT 0x8D8E
+#define GL_RGB8I_EXT 0x8D8F
+#define GL_ALPHA8I_EXT 0x8D90
+#define GL_INTENSITY8I_EXT 0x8D91
+#define GL_LUMINANCE8I_EXT 0x8D92
+#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93
+#define GL_RED_INTEGER_EXT 0x8D94
+#define GL_GREEN_INTEGER_EXT 0x8D95
+#define GL_BLUE_INTEGER_EXT 0x8D96
+#define GL_ALPHA_INTEGER_EXT 0x8D97
+#define GL_RGB_INTEGER_EXT 0x8D98
+#define GL_RGBA_INTEGER_EXT 0x8D99
+#define GL_BGR_INTEGER_EXT 0x8D9A
+#define GL_BGRA_INTEGER_EXT 0x8D9B
+#define GL_LUMINANCE_INTEGER_EXT 0x8D9C
+#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D
+#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E
+#endif
+
+#ifndef GL_GREMEDY_frame_terminator
+#endif
+
+#ifndef GL_NV_conditional_render
+#define GL_QUERY_WAIT_NV 0x8E13
+#define GL_QUERY_NO_WAIT_NV 0x8E14
+#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16
+#endif
+
+#ifndef GL_NV_present_video
+#define GL_FRAME_NV 0x8E26
+#define GL_FIELDS_NV 0x8E27
+#define GL_CURRENT_TIME_NV 0x8E28
+#define GL_NUM_FILL_STREAMS_NV 0x8E29
+#define GL_PRESENT_TIME_NV 0x8E2A
+#define GL_PRESENT_DURATION_NV 0x8E2B
+#endif
+
+#ifndef GL_EXT_transform_feedback
+#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F
+#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C
+#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D
+#define GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88
+#define GL_RASTERIZER_DISCARD_EXT 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76
+#endif
+
+#ifndef GL_EXT_direct_state_access
+#define GL_PROGRAM_MATRIX_EXT 0x8E2D
+#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E
+#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F
+#endif
+
+#ifndef GL_EXT_vertex_array_bgra
+
+#endif
+
+#ifndef GL_EXT_texture_swizzle
+#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42
+#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43
+#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44
+#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46
+#endif
+
+#ifndef GL_NV_explicit_multisample
+#define GL_SAMPLE_POSITION_NV 0x8E50
+#define GL_SAMPLE_MASK_NV 0x8E51
+#define GL_SAMPLE_MASK_VALUE_NV 0x8E52
+#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53
+#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54
+#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55
+#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56
+#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57
+#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58
+#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59
+#endif
+
+#ifndef GL_NV_transform_feedback2
+#define GL_TRANSFORM_FEEDBACK_NV 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25
+#endif
+
+#ifndef GL_ATI_meminfo
+#define GL_VBO_FREE_MEMORY_ATI 0x87FB
+#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
+#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
+#endif
+
+#ifndef GL_AMD_performance_monitor
+#define GL_COUNTER_TYPE_AMD 0x8BC0
+#define GL_COUNTER_RANGE_AMD 0x8BC1
+#define GL_UNSIGNED_INT64_AMD 0x8BC2
+#define GL_PERCENTAGE_AMD 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define GL_PERFMON_RESULT_AMD 0x8BC6
+#endif
+
+#ifndef GL_AMD_texture_texture4
+#endif
+
+#ifndef GL_AMD_vertex_shader_tesselator
+#define GL_SAMPLER_BUFFER_AMD 0x9001
+#define GL_INT_SAMPLER_BUFFER_AMD 0x9002
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003
+#define GL_TESSELLATION_MODE_AMD 0x9004
+#define GL_TESSELLATION_FACTOR_AMD 0x9005
+#define GL_DISCRETE_AMD 0x9006
+#define GL_CONTINUOUS_AMD 0x9007
+#endif
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_PROVOKING_VERTEX_EXT 0x8E4F
+#endif
+
+#ifndef GL_EXT_texture_snorm
+#define GL_ALPHA_SNORM 0x9010
+#define GL_LUMINANCE_SNORM 0x9011
+#define GL_LUMINANCE_ALPHA_SNORM 0x9012
+#define GL_INTENSITY_SNORM 0x9013
+#define GL_ALPHA8_SNORM 0x9014
+#define GL_LUMINANCE8_SNORM 0x9015
+#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016
+#define GL_INTENSITY8_SNORM 0x9017
+#define GL_ALPHA16_SNORM 0x9018
+#define GL_LUMINANCE16_SNORM 0x9019
+#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A
+#define GL_INTENSITY16_SNORM 0x901B
+
+#endif
+
+#ifndef GL_AMD_draw_buffers_blend
+#endif
+
+#ifndef GL_APPLE_texture_range
+#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7
+#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8
+#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
+#define GL_STORAGE_PRIVATE_APPLE 0x85BD
+
+#endif
+
+#ifndef GL_APPLE_float_pixels
+#define GL_HALF_APPLE 0x140B
+#define GL_RGBA_FLOAT32_APPLE 0x8814
+#define GL_RGB_FLOAT32_APPLE 0x8815
+#define GL_ALPHA_FLOAT32_APPLE 0x8816
+#define GL_INTENSITY_FLOAT32_APPLE 0x8817
+#define GL_LUMINANCE_FLOAT32_APPLE 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819
+#define GL_RGBA_FLOAT16_APPLE 0x881A
+#define GL_RGB_FLOAT16_APPLE 0x881B
+#define GL_ALPHA_FLOAT16_APPLE 0x881C
+#define GL_INTENSITY_FLOAT16_APPLE 0x881D
+#define GL_LUMINANCE_FLOAT16_APPLE 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F
+#define GL_COLOR_FLOAT_APPLE 0x8A0F
+#endif
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00
+#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01
+#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02
+#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03
+#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04
+#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05
+#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06
+#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07
+#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08
+#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09
+#endif
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14
+#endif
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_BUFFER_OBJECT_APPLE 0x85B3
+#define GL_RELEASED_APPLE 0x8A19
+#define GL_VOLATILE_APPLE 0x8A1A
+#define GL_RETAINED_APPLE 0x8A1B
+#define GL_UNDEFINED_APPLE 0x8A1C
+#define GL_PURGEABLE_APPLE 0x8A1D
+#endif
+
+#ifndef GL_APPLE_row_bytes
+#define GL_PACK_ROW_BYTES_APPLE 0x8A15
+#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16
+#endif
+
+#ifndef GL_APPLE_rgb_422
+#define GL_RGB_422_APPLE 0x8A1F
+
+#endif
+
+#ifndef GL_NV_video_capture
+#define GL_VIDEO_BUFFER_NV 0x9020
+#define GL_VIDEO_BUFFER_BINDING_NV 0x9021
+#define GL_FIELD_UPPER_NV 0x9022
+#define GL_FIELD_LOWER_NV 0x9023
+#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024
+#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025
+#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026
+#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027
+#define GL_VIDEO_BUFFER_PITCH_NV 0x9028
+#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029
+#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A
+#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B
+#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C
+#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D
+#define GL_PARTIAL_SUCCESS_NV 0x902E
+#define GL_SUCCESS_NV 0x902F
+#define GL_FAILURE_NV 0x9030
+#define GL_YCBYCR8_422_NV 0x9031
+#define GL_YCBAYCR8A_4224_NV 0x9032
+#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033
+#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034
+#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035
+#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036
+#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037
+#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038
+#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039
+#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A
+#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B
+#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C
+#endif
+
+#ifndef GL_NV_copy_image
+#endif
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_ACTIVE_PROGRAM_EXT 0x8B8D
+#endif
+
+#ifndef GL_NV_parameter_buffer_object2
+#endif
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D
+#define GL_GPU_ADDRESS_NV 0x8F34
+#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35
+#endif
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E
+#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F
+#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20
+#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21
+#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22
+#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23
+#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24
+#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25
+#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26
+#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27
+#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28
+#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29
+#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A
+#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B
+#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C
+#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D
+#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E
+#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F
+#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30
+#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31
+#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32
+#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33
+#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40
+#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41
+#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42
+#endif
+
+#ifndef GL_NV_texture_barrier
+#endif
+
+#ifndef GL_AMD_shader_stencil_export
+#endif
+
+#ifndef GL_AMD_seamless_cubemap_per_texture
+
+#endif
+
+#ifndef GL_AMD_conservative_depth
+#endif
+
+#ifndef GL_EXT_shader_image_load_store
+#define GL_MAX_IMAGE_UNITS_EXT 0x8F38
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39
+#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A
+#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B
+#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C
+#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D
+#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E
+#define GL_IMAGE_1D_EXT 0x904C
+#define GL_IMAGE_2D_EXT 0x904D
+#define GL_IMAGE_3D_EXT 0x904E
+#define GL_IMAGE_2D_RECT_EXT 0x904F
+#define GL_IMAGE_CUBE_EXT 0x9050
+#define GL_IMAGE_BUFFER_EXT 0x9051
+#define GL_IMAGE_1D_ARRAY_EXT 0x9052
+#define GL_IMAGE_2D_ARRAY_EXT 0x9053
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
+#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056
+#define GL_INT_IMAGE_1D_EXT 0x9057
+#define GL_INT_IMAGE_2D_EXT 0x9058
+#define GL_INT_IMAGE_3D_EXT 0x9059
+#define GL_INT_IMAGE_2D_RECT_EXT 0x905A
+#define GL_INT_IMAGE_CUBE_EXT 0x905B
+#define GL_INT_IMAGE_BUFFER_EXT 0x905C
+#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D
+#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
+#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061
+#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C
+#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D
+#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002
+#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020
+#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000
+#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF
+#endif
+
+#ifndef GL_EXT_vertex_attrib_64bit
+
+#define GL_DOUBLE_VEC2_EXT 0x8FFC
+#define GL_DOUBLE_VEC3_EXT 0x8FFD
+#define GL_DOUBLE_VEC4_EXT 0x8FFE
+#define GL_DOUBLE_MAT2_EXT 0x8F46
+#define GL_DOUBLE_MAT3_EXT 0x8F47
+#define GL_DOUBLE_MAT4_EXT 0x8F48
+#define GL_DOUBLE_MAT2x3_EXT 0x8F49
+#define GL_DOUBLE_MAT2x4_EXT 0x8F4A
+#define GL_DOUBLE_MAT3x2_EXT 0x8F4B
+#define GL_DOUBLE_MAT3x4_EXT 0x8F4C
+#define GL_DOUBLE_MAT4x2_EXT 0x8F4D
+#define GL_DOUBLE_MAT4x3_EXT 0x8F4E
+#endif
+
+#ifndef GL_NV_gpu_program5
+#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C
+#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D
+#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44
+#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45
+#endif
+
+#ifndef GL_NV_gpu_shader5
+#define GL_INT64_NV 0x140E
+#define GL_UNSIGNED_INT64_NV 0x140F
+#define GL_INT8_NV 0x8FE0
+#define GL_INT8_VEC2_NV 0x8FE1
+#define GL_INT8_VEC3_NV 0x8FE2
+#define GL_INT8_VEC4_NV 0x8FE3
+#define GL_INT16_NV 0x8FE4
+#define GL_INT16_VEC2_NV 0x8FE5
+#define GL_INT16_VEC3_NV 0x8FE6
+#define GL_INT16_VEC4_NV 0x8FE7
+#define GL_INT64_VEC2_NV 0x8FE9
+#define GL_INT64_VEC3_NV 0x8FEA
+#define GL_INT64_VEC4_NV 0x8FEB
+#define GL_UNSIGNED_INT8_NV 0x8FEC
+#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED
+#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE
+#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF
+#define GL_UNSIGNED_INT16_NV 0x8FF0
+#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
+#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
+#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
+#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7
+#define GL_FLOAT16_NV 0x8FF8
+#define GL_FLOAT16_VEC2_NV 0x8FF9
+#define GL_FLOAT16_VEC3_NV 0x8FFA
+#define GL_FLOAT16_VEC4_NV 0x8FFB
+
+#endif
+
+#ifndef GL_NV_shader_buffer_store
+#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010
+
+#endif
+
+#ifndef GL_NV_tessellation_program5
+#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8
+#define GL_TESS_CONTROL_PROGRAM_NV 0x891E
+#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F
+#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74
+#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75
+#endif
+
+#ifndef GL_NV_vertex_attrib_integer_64bit
+
+#endif
+
+#ifndef GL_NV_multisample_coverage
+#define GL_COVERAGE_SAMPLES_NV 0x80A9
+#define GL_COLOR_SAMPLES_NV 0x8E20
+#endif
+
+#ifndef GL_AMD_name_gen_delete
+#define GL_DATA_BUFFER_AMD 0x9151
+#define GL_PERFORMANCE_MONITOR_AMD 0x9152
+#define GL_QUERY_OBJECT_AMD 0x9153
+#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154
+#define GL_SAMPLER_OBJECT_AMD 0x9155
+#endif
+
+#ifndef GL_AMD_debug_output
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147
+#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148
+#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149
+#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A
+#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B
+#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C
+#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D
+#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E
+#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F
+#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150
+#endif
+
+#ifndef GL_NV_vdpau_interop
+#define GL_SURFACE_STATE_NV 0x86EB
+#define GL_SURFACE_REGISTERED_NV 0x86FD
+#define GL_SURFACE_MAPPED_NV 0x8700
+#define GL_WRITE_DISCARD_NV 0x88BE
+#endif
+
+#ifndef GL_AMD_transform_feedback3_lines_triangles
+#endif
+
+#include <stddef.h>
+#ifndef GL_VERSION_2_0
+
+typedef char GLchar;
+#endif
+
+#ifndef GL_VERSION_1_5
+
+#if defined(__APPLE__)
+typedef long GLintptr;
+typedef long GLsizeiptr;
+#else
+typedef ptrdiff_t GLintptr;
+typedef ptrdiff_t GLsizeiptr;
+#endif
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+
+#if defined(__APPLE__)
+typedef long GLintptrARB;
+typedef long GLsizeiptrARB;
+#else
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+#endif
+#endif
+
+#ifndef GL_ARB_shader_objects
+
+typedef char GLcharARB;
+#if defined(__APPLE__)
+typedef void *GLhandleARB;
+#else
+typedef unsigned int GLhandleARB;
+#endif
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+typedef unsigned short GLhalfARB;
+#endif
+
+#ifndef GL_NV_half_float
+typedef unsigned short GLhalfNV;
+#endif
+
+#ifndef GLEXT_64_TYPES_DEFINED
+
+#define GLEXT_64_TYPES_DEFINED
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+#elif defined(__sun__) || defined(__digital__)
+#include <inttypes.h>
+#if defined(__STDC__)
+#if defined(__arch64__) || defined(_LP64)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif
+#endif
+#elif defined( __VMS ) || defined(__sgi)
+#include <inttypes.h>
+#elif defined(__SCO__) || defined(__USLC__)
+#include <stdint.h>
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include <stdint.h>
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+
+#include <inttypes.h>
+#endif
+#endif
+
+#ifndef GL_EXT_timer_query
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+#endif
+
+#ifndef GL_ARB_sync
+typedef int64_t GLint64;
+typedef uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+#endif
+
+#ifndef GL_ARB_cl_event
+
+struct _cl_context;
+struct _cl_event;
+#endif
+
+#ifndef GL_ARB_debug_output
+typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+#endif
+
+#ifndef GL_AMD_debug_output
+typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+#endif
+
+#ifndef GL_NV_vdpau_interop
+typedef GLintptr GLvdpauSurfaceNV;
+#endif
+
+#ifndef GL_VERSION_1_2
+#define GL_VERSION_1_2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GLAPI void APIENTRY glBlendEquation (GLenum mode);
+GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_VERSION_1_2_DEPRECATED
+#define GL_VERSION_1_2_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, GLvoid *table);
+GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params);
+GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params);
+GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, GLvoid *image);
+GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glResetHistogram (GLenum target);
+GLAPI void APIENTRY glResetMinmax (GLenum target);
+#endif
+typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target);
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_VERSION_1_3 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveTexture (GLenum texture);
+GLAPI void APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, GLvoid *img);
+#endif
+typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
+#endif
+
+#ifndef GL_VERSION_1_3_DEPRECATED
+#define GL_VERSION_1_3_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClientActiveTexture (GLenum texture);
+GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s);
+GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s);
+GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s);
+GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s);
+GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t);
+GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t);
+GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t);
+GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t);
+GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r);
+GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r);
+GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q);
+GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m);
+GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m);
+GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m);
+GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m);
+#endif
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+#endif
+
+#ifndef GL_VERSION_1_4
+#define GL_VERSION_1_4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param);
+GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params);
+#endif
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_VERSION_1_4_DEPRECATED
+#define GL_VERSION_1_4_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogCoordf (GLfloat coord);
+GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord);
+GLAPI void APIENTRY glFogCoordd (GLdouble coord);
+GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord);
+GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue);
+GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v);
+GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue);
+GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v);
+GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue);
+GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v);
+GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue);
+GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v);
+GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue);
+GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v);
+GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue);
+GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v);
+GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue);
+GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v);
+GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue);
+GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v);
+GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2iv (const GLint *v);
+GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2sv (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3iv (const GLint *v);
+GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3sv (const GLshort *v);
+#endif
+typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord);
+typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_VERSION_1_5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsQuery (GLuint id);
+GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id);
+GLAPI void APIENTRY glEndQuery (GLenum target);
+GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer);
+GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapBuffer (GLenum target, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target);
+GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_VERSION_2_0 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs);
+GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader);
+GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
+GLAPI void APIENTRY glCompileShader (GLuint shader);
+GLAPI GLuint APIENTRY glCreateProgram (void);
+GLAPI GLuint APIENTRY glCreateShader (GLenum type);
+GLAPI void APIENTRY glDeleteProgram (GLuint program);
+GLAPI void APIENTRY glDeleteShader (GLuint shader);
+GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader);
+GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index);
+GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index);
+GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj);
+GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
+GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgram (GLuint program);
+GLAPI GLboolean APIENTRY glIsShader (GLuint shader);
+GLAPI void APIENTRY glLinkProgram (GLuint program);
+GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+GLAPI void APIENTRY glUseProgram (GLuint program);
+GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0);
+GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glUniform1i (GLint location, GLint v0);
+GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glValidateProgram (GLuint program);
+GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+#endif
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);
+typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj);
+typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
+typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_VERSION_2_1
+#define GL_VERSION_2_1 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif
+
+#ifndef GL_VERSION_3_0
+#define GL_VERSION_3_0 1
+
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data);
+GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data);
+GLAPI void APIENTRY glEnablei (GLenum target, GLuint index);
+GLAPI void APIENTRY glDisablei (GLenum target, GLuint index);
+GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index);
+GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedback (void);
+GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp);
+GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode);
+GLAPI void APIENTRY glEndConditionalRender (void);
+GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x);
+GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y);
+GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x);
+GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y);
+GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z);
+GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params);
+GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0);
+GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value);
+GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value);
+GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GLAPI const GLubyte * APIENTRY glGetStringi (GLenum name, GLuint index);
+#endif
+typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index);
+typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp);
+typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode);
+typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
+#endif
+
+#ifndef GL_VERSION_3_1
+#define GL_VERSION_3_1 1
+
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index);
+#endif
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index);
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_VERSION_3_2 1
+
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);
+GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+
+#ifndef GL_VERSION_3_3
+#define GL_VERSION_3_3 1
+
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);
+#endif
+
+#ifndef GL_VERSION_4_0
+#define GL_VERSION_4_0 1
+
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMinSampleShading (GLclampf value);
+GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLclampf value);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+
+#ifndef GL_VERSION_4_1
+#define GL_VERSION_4_1 1
+
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_ARB_multitexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveTextureARB (GLenum texture);
+GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture);
+GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s);
+GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s);
+GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s);
+GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s);
+GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t);
+GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t);
+GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t);
+GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t);
+GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r);
+GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r);
+GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q);
+GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v);
+#endif
+typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_ARB_transpose_matrix 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m);
+GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m);
+GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m);
+GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m);
+#endif
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_ARB_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleCoverageARB (GLclampf value, GLboolean invert);
+#endif
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert);
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#define GL_ARB_texture_env_add 1
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_ARB_texture_cube_map 1
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_ARB_texture_compression 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, GLvoid *img);
+#endif
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img);
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_ARB_texture_border_clamp 1
+#endif
+
+#ifndef GL_ARB_point_parameters
+#define GL_ARB_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params);
+#endif
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_ARB_vertex_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights);
+GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights);
+GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights);
+GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights);
+GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights);
+GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights);
+GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights);
+GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights);
+GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexBlendARB (GLint count);
+#endif
+typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights);
+typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights);
+typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights);
+typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights);
+typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights);
+typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count);
+#endif
+
+#ifndef GL_ARB_matrix_palette
+#define GL_ARB_matrix_palette 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index);
+GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices);
+GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices);
+GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices);
+GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_ARB_texture_env_combine 1
+#endif
+
+#ifndef GL_ARB_texture_env_crossbar
+#define GL_ARB_texture_env_crossbar 1
+#endif
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_ARB_texture_env_dot3 1
+#endif
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_ARB_texture_mirrored_repeat 1
+#endif
+
+#ifndef GL_ARB_depth_texture
+#define GL_ARB_depth_texture 1
+#endif
+
+#ifndef GL_ARB_shadow
+#define GL_ARB_shadow 1
+#endif
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_ARB_shadow_ambient 1
+#endif
+
+#ifndef GL_ARB_window_pos
+#define GL_ARB_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v);
+GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v);
+GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v);
+#endif
+typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_ARB_vertex_program
+#define GL_ARB_vertex_program 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index);
+GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index);
+GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program);
+GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs);
+GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, GLvoid *string);
+GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program);
+#endif
+
+#ifndef GL_ARB_fragment_program
+#define GL_ARB_fragment_program 1
+
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_ARB_vertex_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer);
+GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers);
+GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers);
+GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer);
+GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum target, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target);
+GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
+typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_ARB_occlusion_query
+#define GL_ARB_occlusion_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id);
+GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id);
+GLAPI void APIENTRY glEndQueryARB (GLenum target);
+GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params);
+#endif
+typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_ARB_shader_objects
+#define GL_ARB_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj);
+GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname);
+GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj);
+GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType);
+GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
+GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj);
+GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void);
+GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj);
+GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj);
+GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj);
+GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj);
+GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0);
+GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0);
+GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
+GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj);
+GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name);
+GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params);
+GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params);
+GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
+#endif
+typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj);
+typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname);
+typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj);
+typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
+typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
+typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
+typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
+typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
+typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params);
+typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
+#endif
+
+#ifndef GL_ARB_vertex_shader
+#define GL_ARB_vertex_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name);
+GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name);
+#endif
+typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
+#endif
+
+#ifndef GL_ARB_fragment_shader
+#define GL_ARB_fragment_shader 1
+#endif
+
+#ifndef GL_ARB_shading_language_100
+#define GL_ARB_shading_language_100 1
+#endif
+
+#ifndef GL_ARB_texture_non_power_of_two
+#define GL_ARB_texture_non_power_of_two 1
+#endif
+
+#ifndef GL_ARB_point_sprite
+#define GL_ARB_point_sprite 1
+#endif
+
+#ifndef GL_ARB_fragment_program_shadow
+#define GL_ARB_fragment_program_shadow 1
+#endif
+
+#ifndef GL_ARB_draw_buffers
+#define GL_ARB_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs);
+#endif
+typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_ARB_texture_rectangle 1
+#endif
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_ARB_color_buffer_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp);
+#endif
+typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp);
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_ARB_half_float_pixel 1
+#endif
+
+#ifndef GL_ARB_texture_float
+#define GL_ARB_texture_float 1
+#endif
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_ARB_pixel_buffer_object 1
+#endif
+
+#ifndef GL_ARB_depth_buffer_float
+#define GL_ARB_depth_buffer_float 1
+#endif
+
+#ifndef GL_ARB_draw_instanced
+#define GL_ARB_draw_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_ARB_framebuffer_object
+#define GL_ARB_framebuffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
+GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
+GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer);
+GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
+GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
+GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target);
+GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateMipmap (GLenum target);
+GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+#endif
+typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+#endif
+
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_ARB_framebuffer_sRGB 1
+#endif
+
+#ifndef GL_ARB_geometry_shader4
+#define GL_ARB_geometry_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value);
+GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+
+#ifndef GL_ARB_half_float_vertex
+#define GL_ARB_half_float_vertex 1
+#endif
+
+#ifndef GL_ARB_instanced_arrays
+#define GL_ARB_instanced_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor);
+#endif
+
+#ifndef GL_ARB_map_buffer_range
+#define GL_ARB_map_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLvoid* APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif
+
+#ifndef GL_ARB_texture_buffer_object
+#define GL_ARB_texture_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_ARB_texture_compression_rgtc 1
+#endif
+
+#ifndef GL_ARB_texture_rg
+#define GL_ARB_texture_rg 1
+#endif
+
+#ifndef GL_ARB_vertex_array_object
+#define GL_ARB_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindVertexArray (GLuint array);
+GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
+GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array);
+#endif
+typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
+typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array);
+#endif
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_ARB_uniform_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices);
+GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);
+GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);
+GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+#endif
+typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);
+typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+#endif
+
+#ifndef GL_ARB_compatibility
+#define GL_ARB_compatibility 1
+#endif
+
+#ifndef GL_ARB_copy_buffer
+#define GL_ARB_copy_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif
+typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif
+
+#ifndef GL_ARB_shader_texture_lod
+#define GL_ARB_shader_texture_lod 1
+#endif
+
+#ifndef GL_ARB_depth_clamp
+#define GL_ARB_depth_clamp 1
+#endif
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#define GL_ARB_draw_elements_base_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
+GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+#endif
+typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+#endif
+
+#ifndef GL_ARB_fragment_coord_conventions
+#define GL_ARB_fragment_coord_conventions 1
+#endif
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_ARB_provoking_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProvokingVertex (GLenum mode);
+#endif
+typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_ARB_seamless_cube_map 1
+#endif
+
+#ifndef GL_ARB_sync
+#define GL_ARB_sync 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags);
+GLAPI GLboolean APIENTRY glIsSync (GLsync sync);
+GLAPI void APIENTRY glDeleteSync (GLsync sync);
+GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif
+typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync);
+typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
+typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif
+
+#ifndef GL_ARB_texture_multisample
+#define GL_ARB_texture_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val);
+GLAPI void APIENTRY glSampleMaski (GLuint index, GLbitfield mask);
+#endif
+typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask);
+#endif
+
+#ifndef GL_ARB_vertex_array_bgra
+#define GL_ARB_vertex_array_bgra 1
+#endif
+
+#ifndef GL_ARB_draw_buffers_blend
+#define GL_ARB_draw_buffers_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+
+#ifndef GL_ARB_sample_shading
+#define GL_ARB_sample_shading 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMinSampleShadingARB (GLclampf value);
+#endif
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value);
+#endif
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_ARB_texture_cube_map_array 1
+#endif
+
+#ifndef GL_ARB_texture_gather
+#define GL_ARB_texture_gather 1
+#endif
+
+#ifndef GL_ARB_texture_query_lod
+#define GL_ARB_texture_query_lod 1
+#endif
+
+#ifndef GL_ARB_shading_language_include
+#define GL_ARB_shading_language_include 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);
+GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name);
+GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length);
+GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name);
+GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);
+GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params);
+#endif
+typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);
+typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);
+typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length);
+typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);
+typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_texture_compression_bptc
+#define GL_ARB_texture_compression_bptc 1
+#endif
+
+#ifndef GL_ARB_blend_func_extended
+#define GL_ARB_blend_func_extended 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name);
+#endif
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name);
+#endif
+
+#ifndef GL_ARB_explicit_attrib_location
+#define GL_ARB_explicit_attrib_location 1
+#endif
+
+#ifndef GL_ARB_occlusion_query2
+#define GL_ARB_occlusion_query2 1
+#endif
+
+#ifndef GL_ARB_sampler_objects
+#define GL_ARB_sampler_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);
+GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);
+GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler);
+GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler);
+GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
+GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param);
+GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param);
+GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param);
+GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param);
+GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);
+typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);
+typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler);
+typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_ARB_texture_rgb10_a2ui
+#define GL_ARB_texture_rgb10_a2ui 1
+#endif
+
+#ifndef GL_ARB_texture_swizzle
+#define GL_ARB_texture_swizzle 1
+#endif
+
+#ifndef GL_ARB_timer_query
+#define GL_ARB_timer_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target);
+GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params);
+#endif
+typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params);
+#endif
+
+#ifndef GL_ARB_vertex_type_2_10_10_10_rev
+#define GL_ARB_vertex_type_2_10_10_10_rev 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+#endif
+
+#ifndef GL_ARB_draw_indirect
+#define GL_ARB_draw_indirect 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const GLvoid *indirect);
+GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect);
+#endif
+typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const GLvoid *indirect);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const GLvoid *indirect);
+#endif
+
+#ifndef GL_ARB_gpu_shader5
+#define GL_ARB_gpu_shader5 1
+#endif
+
+#ifndef GL_ARB_gpu_shader_fp64
+#define GL_ARB_gpu_shader_fp64 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x);
+GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params);
+#endif
+typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x);
+typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_shader_subroutine
+#define GL_ARB_shader_subroutine 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name);
+GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name);
+GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);
+GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices);
+GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params);
+GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values);
+#endif
+typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name);
+typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices);
+typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values);
+#endif
+
+#ifndef GL_ARB_tessellation_shader
+#define GL_ARB_tessellation_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value);
+GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values);
+#endif
+typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value);
+typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values);
+#endif
+
+#ifndef GL_ARB_texture_buffer_object_rgb32
+#define GL_ARB_texture_buffer_object_rgb32 1
+#endif
+
+#ifndef GL_ARB_transform_feedback2
+#define GL_ARB_transform_feedback2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids);
+GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids);
+GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id);
+GLAPI void APIENTRY glPauseTransformFeedback (void);
+GLAPI void APIENTRY glResumeTransformFeedback (void);
+GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id);
+#endif
+typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids);
+typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id);
+#endif
+
+#ifndef GL_ARB_transform_feedback3
+#define GL_ARB_transform_feedback3 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream);
+GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id);
+GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index);
+GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params);
+#endif
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream);
+typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_ES2_compatibility
+#define GL_ARB_ES2_compatibility 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReleaseShaderCompiler (void);
+GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length);
+GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+GLAPI void APIENTRY glDepthRangef (GLclampf n, GLclampf f);
+GLAPI void APIENTRY glClearDepthf (GLclampf d);
+#endif
+typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length);
+typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f);
+typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLclampf d);
+#endif
+
+#ifndef GL_ARB_get_program_binary
+#define GL_ARB_get_program_binary 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length);
+GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);
+#endif
+typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
+#endif
+
+#ifndef GL_ARB_separate_shader_objects
+#define GL_ARB_separate_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program);
+GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program);
+GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar* *strings);
+GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines);
+GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines);
+GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params);
+GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0);
+GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0);
+GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0);
+GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0);
+GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1);
+GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
+GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif
+typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* *strings);
+typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines);
+typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif
+
+#ifndef GL_ARB_vertex_attrib_64bit
+#define GL_ARB_vertex_attrib_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_viewport_array
+#define GL_ARB_viewport_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v);
+GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLclampd *v);
+GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLclampd n, GLclampd f);
+GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data);
+GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data);
+#endif
+typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v);
+typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd *v);
+typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f);
+typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);
+#endif
+
+#ifndef GL_ARB_cl_event
+#define GL_ARB_cl_event 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context * context, struct _cl_event * event, GLbitfield flags);
+#endif
+typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context * context, struct _cl_event * event, GLbitfield flags);
+#endif
+
+#ifndef GL_ARB_debug_output
+#define GL_ARB_debug_output 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const GLvoid *userParam);
+GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+#endif
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid *userParam);
+typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+#endif
+
+#ifndef GL_ARB_robustness
+#define GL_ARB_robustness 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void);
+GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v);
+GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v);
+GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v);
+GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values);
+GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values);
+GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values);
+GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern);
+GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table);
+GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image);
+GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img);
+GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
+GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img);
+GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);
+#endif
+typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void);
+typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v);
+typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v);
+typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values);
+typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern);
+typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img);
+typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
+typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img);
+typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_shader_stencil_export
+#define GL_ARB_shader_stencil_export 1
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_EXT_abgr 1
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_EXT_blend_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendColorEXT (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+#endif
+typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_EXT_polygon_offset 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias);
+#endif
+typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias);
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_EXT_texture 1
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_EXT_texture3D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_SGIS_texture_filter4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights);
+GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights);
+#endif
+typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights);
+typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights);
+#endif
+
+#ifndef GL_EXT_subtexture
+#define GL_EXT_subtexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_EXT_copy_texture
+#define GL_EXT_copy_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_EXT_histogram 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glResetHistogramEXT (GLenum target);
+GLAPI void APIENTRY glResetMinmaxEXT (GLenum target);
+#endif
+typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_EXT_convolution 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params);
+GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params);
+GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *image);
+GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+#endif
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_SGI_color_matrix 1
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_SGI_color_table 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, GLvoid *table);
+GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params);
+#endif
+typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_SGIX_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode);
+#endif
+typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_SGIS_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param);
+GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params);
+#endif
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_SGIS_texture4D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_SGI_texture_color_table 1
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_EXT_cmyka 1
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_EXT_texture_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences);
+GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture);
+GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures);
+GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures);
+GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture);
+GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+#endif
+typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences);
+typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures);
+typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures);
+typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture);
+typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_SGIS_detail_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points);
+#endif
+typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_SGIS_sharpen_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points);
+#endif
+typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_EXT_packed_pixels 1
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_SGIS_texture_lod 1
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_SGIS_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern);
+#endif
+typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_EXT_rescale_normal 1
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_EXT_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glArrayElementEXT (GLint i);
+GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count);
+GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer);
+GLAPI void APIENTRY glGetPointervEXT (GLenum pname, GLvoid* *params);
+GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+#endif
+typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i);
+typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer);
+typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params);
+typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#define GL_EXT_misc_attribute 1
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_SGIS_generate_mipmap 1
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_SGIX_clipmap 1
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_SGIX_shadow 1
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_SGIS_texture_edge_clamp 1
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_SGIS_texture_border_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationEXT (GLenum mode);
+#endif
+typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_EXT_blend_subtract 1
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#define GL_EXT_blend_logic_op 1
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_SGIX_interlace 1
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_SGIX_pixel_tiles 1
+#endif
+
+#ifndef GL_SGIX_texture_select
+#define GL_SGIX_texture_select 1
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SGIX_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param);
+GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params);
+#endif
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_SGIX_texture_multi_buffer 1
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_EXT_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params);
+#endif
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_SGIS_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params);
+#endif
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_SGIX_instruments 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLint APIENTRY glGetInstrumentsSGIX (void);
+GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer);
+GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p);
+GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker);
+GLAPI void APIENTRY glStartInstrumentsSGIX (void);
+GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker);
+#endif
+typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer);
+typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p);
+typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker);
+typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker);
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_SGIX_texture_scale_bias 1
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_SGIX_framezoom 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFrameZoomSGIX (GLint factor);
+#endif
+typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor);
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#define GL_SGIX_tag_sample_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTagSampleBufferSGIX (void);
+#endif
+typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_SGIX_polynomial_ffd 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points);
+GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points);
+GLAPI void APIENTRY glDeformSGIX (GLbitfield mask);
+GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask);
+#endif
+typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points);
+typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points);
+typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask);
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_SGIX_reference_plane 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation);
+#endif
+typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation);
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#define GL_SGIX_flush_raster 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFlushRasterSGIX (void);
+#endif
+typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_SGIX_depth_texture 1
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_SGIS_fog_function 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points);
+#endif
+typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points);
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_SGIX_fog_offset 1
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_HP_image_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params);
+#endif
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_HP_convolution_border_modes 1
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_SGIX_texture_add_env 1
+#endif
+
+#ifndef GL_EXT_color_subtable
+#define GL_EXT_color_subtable 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+#endif
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_PGI_vertex_hints 1
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PGI_misc_hints 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode);
+#endif
+typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode);
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_EXT_paletted_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, GLvoid *data);
+GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+#endif
+typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_EXT_clip_volume_hint 1
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_SGIX_list_priority 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params);
+GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param);
+GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params);
+#endif
+typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_SGIX_ir_instrument1 1
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_SGIX_calligraphic_fragment 1
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_SGIX_texture_lod_bias 1
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SGIX_shadow_ambient 1
+#endif
+
+#ifndef GL_EXT_index_texture
+#define GL_EXT_index_texture 1
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_EXT_index_material 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode);
+#endif
+typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_EXT_index_func 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref);
+#endif
+typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref);
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_EXT_index_array_formats 1
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_EXT_compiled_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
+GLAPI void APIENTRY glUnlockArraysEXT (void);
+#endif
+typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void);
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_EXT_cull_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params);
+#endif
+typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_SGIX_ycrcb 1
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_SGIX_fragment_lighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode);
+GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params);
+GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param);
+#endif
+typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_IBM_rasterpos_clip 1
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_HP_texture_lighting 1
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_EXT_draw_range_elements 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+#endif
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_WIN_phong_shading 1
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_WIN_specular_fog 1
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_EXT_light_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glApplyTextureEXT (GLenum mode);
+GLAPI void APIENTRY glTextureLightEXT (GLenum pname);
+GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode);
+#endif
+typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname);
+typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_SGIX_blend_alpha_minmax 1
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_EXT_bgra 1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_SGIX_async 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker);
+GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp);
+GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp);
+GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range);
+GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range);
+GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker);
+#endif
+typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker);
+typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp);
+typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp);
+typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range);
+typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range);
+typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker);
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_SGIX_async_pixel 1
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_SGIX_async_histogram 1
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_INTEL_parallel_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_HP_occlusion_test 1
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_EXT_pixel_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params);
+#endif
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#define GL_EXT_pixel_transform_color_table 1
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_EXT_shared_texture_palette 1
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_EXT_separate_specular_color 1
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_EXT_secondary_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue);
+GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue);
+GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue);
+GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue);
+GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v);
+GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue);
+GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v);
+GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue);
+GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v);
+GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue);
+GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v);
+GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue);
+GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v);
+GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_EXT_texture_perturb_normal 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureNormalEXT (GLenum mode);
+#endif
+typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_EXT_fog_coord 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord);
+GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord);
+GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord);
+GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord);
+GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_REND_screen_coordinates 1
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_EXT_coordinate_frame 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz);
+GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz);
+GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz);
+GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz);
+GLAPI void APIENTRY glTangent3ivEXT (const GLint *v);
+GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz);
+GLAPI void APIENTRY glTangent3svEXT (const GLshort *v);
+GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz);
+GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz);
+GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz);
+GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz);
+GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v);
+GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz);
+GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v);
+GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz);
+typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz);
+typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz);
+typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz);
+typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz);
+typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz);
+typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz);
+typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz);
+typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz);
+typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz);
+typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_EXT_texture_env_combine 1
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_APPLE_specular_vector 1
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_APPLE_transform_hint 1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_SGIX_fog_scale 1
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_SUNX_constant_data 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFinishTextureSUNX (void);
+#endif
+typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void);
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_SUN_global_alpha 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor);
+GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor);
+GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor);
+GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor);
+GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor);
+GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor);
+GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor);
+GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor);
+#endif
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor);
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_SUN_triangle_list 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code);
+GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code);
+GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code);
+GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code);
+GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code);
+GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code);
+GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const GLvoid* *pointer);
+#endif
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_SUN_vertex
+#define GL_SUN_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+#endif
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_EXT_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_blend_func_separate
+#define GL_INGR_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_INGR_color_clamp 1
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INGR_interlace_read 1
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_EXT_stencil_wrap 1
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_EXT_422_pixels 1
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NV_texgen_reflection 1
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_SUN_convolution_border_modes 1
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#define GL_EXT_texture_env_add 1
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_EXT_vertex_weighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight);
+GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight);
+GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_NV_light_max_exponent 1
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_NV_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFlushVertexArrayRangeNV (void);
+GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const GLvoid *pointer);
+#endif
+typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void);
+typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_NV_register_combiners 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param);
+GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params);
+#endif
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_NV_fog_distance 1
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_NV_texgen_emboss 1
+#endif
+
+#ifndef GL_NV_blend_square
+#define GL_NV_blend_square 1
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_NV_texture_env_combine4 1
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#define GL_MESA_resize_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glResizeBuffersMESA (void);
+#endif
+typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void);
+#endif
+
+#ifndef GL_MESA_window_pos
+#define GL_MESA_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v);
+GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v);
+#endif
+typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_IBM_cull_vertex 1
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#define GL_IBM_multimode_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride);
+#endif
+typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride);
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_IBM_vertex_array_lists 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+#endif
+typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_SGIX_subsample 1
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_SGIX_ycrcba 1
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#define GL_SGIX_ycrcb_subsample 1
+#endif
+
+#ifndef GL_SGIX_depth_pass_instrument
+#define GL_SGIX_depth_pass_instrument 1
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_3DFX_texture_compression_FXT1 1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_3DFX_multisample 1
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#define GL_3DFX_tbuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask);
+#endif
+typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask);
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_EXT_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern);
+#endif
+typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_SGIX_vertex_preclip 1
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_SGIX_convolution_accuracy 1
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_SGIX_resample 1
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_SGIS_point_line_texgen 1
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_SGIS_texture_color_mask 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+#endif
+typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+#endif
+
+#ifndef GL_SGIX_igloo_interface
+#define GL_SGIX_igloo_interface 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const GLvoid *params);
+#endif
+typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params);
+#endif
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_EXT_texture_env_dot3 1
+#endif
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_ATI_texture_mirror_once 1
+#endif
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences);
+GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences);
+GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence);
+GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence);
+GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params);
+GLAPI void APIENTRY glFinishFenceNV (GLuint fence);
+GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition);
+#endif
+typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#endif
+
+#ifndef GL_NV_evaluators
+#define GL_NV_evaluators 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points);
+GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points);
+GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode);
+#endif
+typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points);
+typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points);
+typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode);
+#endif
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_NV_packed_depth_stencil 1
+#endif
+
+#ifndef GL_NV_register_combiners2
+#define GL_NV_register_combiners2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params);
+#endif
+typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_NV_texture_compression_vtc
+#define GL_NV_texture_compression_vtc 1
+#endif
+
+#ifndef GL_NV_texture_rectangle
+#define GL_NV_texture_rectangle 1
+#endif
+
+#ifndef GL_NV_texture_shader
+#define GL_NV_texture_shader 1
+#endif
+
+#ifndef GL_NV_texture_shader2
+#define GL_NV_texture_shader2 1
+#endif
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_NV_vertex_array_range2 1
+#endif
+
+#ifndef GL_NV_vertex_program
+#define GL_NV_vertex_program 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences);
+GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params);
+GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs);
+GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program);
+GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id);
+GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLuint count, const GLdouble *v);
+GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLuint count, const GLfloat *v);
+GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v);
+#endif
+typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences);
+typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs);
+typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program);
+typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v);
+#endif
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_SGIX_texture_coordinate_clamp 1
+#endif
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SGIX_scalebias_hint 1
+#endif
+
+#ifndef GL_OML_interlace
+#define GL_OML_interlace 1
+#endif
+
+#ifndef GL_OML_subsample
+#define GL_OML_subsample 1
+#endif
+
+#ifndef GL_OML_resample
+#define GL_OML_resample 1
+#endif
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_NV_copy_depth_to_color 1
+#endif
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_ATI_envmap_bumpmap 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param);
+GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param);
+GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param);
+GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param);
+#endif
+typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param);
+typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param);
+typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param);
+#endif
+
+#ifndef GL_ATI_fragment_shader
+#define GL_ATI_fragment_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range);
+GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id);
+GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id);
+GLAPI void APIENTRY glBeginFragmentShaderATI (void);
+GLAPI void APIENTRY glEndFragmentShaderATI (void);
+GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle);
+GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle);
+GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value);
+#endif
+typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range);
+typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void);
+typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void);
+typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle);
+typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value);
+#endif
+
+#ifndef GL_ATI_pn_triangles
+#define GL_ATI_pn_triangles 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param);
+GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param);
+#endif
+typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param);
+#endif
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_ATI_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const GLvoid *pointer, GLenum usage);
+GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve);
+GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params);
+GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params);
+#endif
+typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage);
+typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve);
+typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_EXT_vertex_shader
+#define GL_EXT_vertex_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginVertexShaderEXT (void);
+GLAPI void APIENTRY glEndVertexShaderEXT (void);
+GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id);
+GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range);
+GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id);
+GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1);
+GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num);
+GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num);
+GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components);
+GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const GLvoid *addr);
+GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const GLvoid *addr);
+GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr);
+GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr);
+GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr);
+GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr);
+GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr);
+GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr);
+GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr);
+GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr);
+GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const GLvoid *addr);
+GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id);
+GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id);
+GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value);
+GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value);
+GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value);
+GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value);
+GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value);
+GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap);
+GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, GLvoid* *data);
+GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+#endif
+typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void);
+typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void);
+typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id);
+typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range);
+typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1);
+typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components);
+typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr);
+typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr);
+typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr);
+typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr);
+typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr);
+typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr);
+typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr);
+typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr);
+typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value);
+typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap);
+typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+#endif
+
+#ifndef GL_ATI_vertex_streams
+#define GL_ATI_vertex_streams 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x);
+GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x);
+GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x);
+GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x);
+GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y);
+GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz);
+GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords);
+GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz);
+GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz);
+GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz);
+GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz);
+GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream);
+GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param);
+GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream);
+typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param);
+#endif
+
+#ifndef GL_ATI_element_array
+#define GL_ATI_element_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glElementPointerATI (GLenum type, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count);
+GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count);
+#endif
+typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count);
+#endif
+
+#ifndef GL_SUN_mesh_array
+#define GL_SUN_mesh_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width);
+#endif
+typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width);
+#endif
+
+#ifndef GL_SUN_slice_accum
+#define GL_SUN_slice_accum 1
+#endif
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_NV_multisample_filter_hint 1
+#endif
+
+#ifndef GL_NV_depth_clamp
+#define GL_NV_depth_clamp 1
+#endif
+
+#ifndef GL_NV_occlusion_query
+#define GL_NV_occlusion_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id);
+GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id);
+GLAPI void APIENTRY glEndOcclusionQueryNV (void);
+GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params);
+#endif
+typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void);
+typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_NV_point_sprite
+#define GL_NV_point_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param);
+GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params);
+#endif
+typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_NV_texture_shader3
+#define GL_NV_texture_shader3 1
+#endif
+
+#ifndef GL_NV_vertex_program1_1
+#define GL_NV_vertex_program1_1 1
+#endif
+
+#ifndef GL_EXT_shadow_funcs
+#define GL_EXT_shadow_funcs 1
+#endif
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_EXT_stencil_two_side 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face);
+#endif
+typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
+#endif
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_ATI_text_fragment_shader 1
+#endif
+
+#ifndef GL_APPLE_client_storage
+#define GL_APPLE_client_storage 1
+#endif
+
+#ifndef GL_APPLE_element_array
+#define GL_APPLE_element_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count);
+GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount);
+#endif
+typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount);
+#endif
+
+#ifndef GL_APPLE_fence
+#define GL_APPLE_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences);
+GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences);
+GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence);
+GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name);
+GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name);
+#endif
+typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences);
+typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences);
+typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name);
+typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name);
+#endif
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_APPLE_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array);
+GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays);
+GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays);
+GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array);
+#endif
+typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array);
+typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays);
+typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array);
+#endif
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_APPLE_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_APPLE_ycbcr_422 1
+#endif
+
+#ifndef GL_S3_s3tc
+#define GL_S3_s3tc 1
+#endif
+
+#ifndef GL_ATI_draw_buffers
+#define GL_ATI_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs);
+#endif
+typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+#ifndef GL_ATI_pixel_format_float
+#define GL_ATI_pixel_format_float 1
+
+#endif
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_ATI_texture_env_combine3 1
+#endif
+
+#ifndef GL_ATI_texture_float
+#define GL_ATI_texture_float 1
+#endif
+
+#ifndef GL_NV_float_buffer
+#define GL_NV_float_buffer 1
+#endif
+
+#ifndef GL_NV_fragment_program
+#define GL_NV_fragment_program 1
+
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v);
+GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v);
+GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params);
+GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params);
+#endif
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v);
+typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params);
+#endif
+
+#ifndef GL_NV_half_float
+#define GL_NV_half_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y);
+GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z);
+GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz);
+GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha);
+GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s);
+GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t);
+GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r);
+GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s);
+GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t);
+GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r);
+GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog);
+GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog);
+GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight);
+GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight);
+GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x);
+GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y);
+GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z);
+GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+#endif
+typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y);
+typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z);
+typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz);
+typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha);
+typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s);
+typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t);
+typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r);
+typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog);
+typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+#endif
+
+#ifndef GL_NV_pixel_data_range
+#define GL_NV_pixel_data_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target);
+#endif
+typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target);
+#endif
+
+#ifndef GL_NV_primitive_restart
+#define GL_NV_primitive_restart 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPrimitiveRestartNV (void);
+GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index);
+#endif
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void);
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index);
+#endif
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_NV_texture_expand_normal 1
+#endif
+
+#ifndef GL_NV_vertex_program2
+#define GL_NV_vertex_program2 1
+#endif
+
+#ifndef GL_ATI_map_object_buffer
+#define GL_ATI_map_object_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer);
+#endif
+typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+#endif
+
+#ifndef GL_ATI_separate_stencil
+#define GL_ATI_separate_stencil 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+#endif
+typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+#endif
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#define GL_ATI_vertex_attrib_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_OES_read_format
+#define GL_OES_read_format 1
+#endif
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_EXT_depth_bounds_test 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax);
+#endif
+typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax);
+#endif
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_EXT_texture_mirror_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_EXT_blend_equation_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha);
+#endif
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+#ifndef GL_MESA_pack_invert
+#define GL_MESA_pack_invert 1
+#endif
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_MESA_ycbcr_texture 1
+#endif
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_EXT_pixel_buffer_object 1
+#endif
+
+#ifndef GL_NV_fragment_program_option
+#define GL_NV_fragment_program_option 1
+#endif
+
+#ifndef GL_NV_fragment_program2
+#define GL_NV_fragment_program2 1
+#endif
+
+#ifndef GL_NV_vertex_program2_option
+#define GL_NV_vertex_program2_option 1
+#endif
+
+#ifndef GL_NV_vertex_program3
+#define GL_NV_vertex_program3 1
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_EXT_framebuffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer);
+GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers);
+GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers);
+GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer);
+GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer);
+GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers);
+GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers);
+GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target);
+GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target);
+#endif
+typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_GREMEDY_string_marker
+#define GL_GREMEDY_string_marker 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const GLvoid *string);
+#endif
+typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string);
+#endif
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_EXT_packed_depth_stencil 1
+#endif
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_EXT_stencil_clear_tag 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag);
+#endif
+typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag);
+#endif
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_EXT_texture_sRGB 1
+#endif
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_EXT_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_EXT_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_MESAX_texture_stack
+#define GL_MESAX_texture_stack 1
+#endif
+
+#ifndef GL_EXT_timer_query
+#define GL_EXT_timer_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64EXT *params);
+#endif
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params);
+#endif
+
+#ifndef GL_EXT_gpu_program_parameters
+#define GL_EXT_gpu_program_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+#endif
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+#endif
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_APPLE_flush_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size);
+#endif
+typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size);
+#endif
+
+#ifndef GL_NV_gpu_program4
+#define GL_NV_gpu_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params);
+GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params);
+#endif
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params);
+#endif
+
+#ifndef GL_NV_geometry_program4
+#define GL_NV_geometry_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit);
+GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_EXT_geometry_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value);
+#endif
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+#endif
+
+#ifndef GL_NV_vertex_program4
+#define GL_NV_vertex_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x);
+GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y);
+GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x);
+GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y);
+GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z);
+GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_EXT_gpu_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params);
+GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0);
+GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value);
+#endif
+typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+#endif
+
+#ifndef GL_EXT_draw_instanced
+#define GL_EXT_draw_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_packed_float
+#define GL_EXT_packed_float 1
+#endif
+
+#ifndef GL_EXT_texture_array
+#define GL_EXT_texture_array 1
+#endif
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_EXT_texture_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_EXT_texture_compression_latc 1
+#endif
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc 1
+#endif
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_EXT_texture_shared_exponent 1
+#endif
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_NV_depth_buffer_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glClearDepthdNV (GLdouble depth);
+GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax);
+#endif
+typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth);
+typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax);
+#endif
+
+#ifndef GL_NV_fragment_program4
+#define GL_NV_fragment_program4 1
+#endif
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_NV_framebuffer_multisample_coverage 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef GL_NV_geometry_shader4
+#define GL_NV_geometry_shader4 1
+#endif
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_NV_parameter_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+#endif
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+#endif
+
+#ifndef GL_EXT_draw_buffers2
+#define GL_EXT_draw_buffers2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data);
+GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data);
+GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index);
+GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index);
+GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index);
+#endif
+typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index);
+#endif
+
+#ifndef GL_NV_transform_feedback
+#define GL_NV_transform_feedback 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedbackNV (void);
+GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode);
+GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name);
+GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location);
+GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode);
+#endif
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode);
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_EXT_bindable_uniform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer);
+GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location);
+GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location);
+#endif
+typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location);
+typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location);
+#endif
+
+#ifndef GL_EXT_texture_integer
+#define GL_EXT_texture_integer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha);
+GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+#endif
+typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha);
+typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+#endif
+
+#ifndef GL_GREMEDY_frame_terminator
+#define GL_GREMEDY_frame_terminator 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFrameTerminatorGREMEDY (void);
+#endif
+typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void);
+#endif
+
+#ifndef GL_NV_conditional_render
+#define GL_NV_conditional_render 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode);
+GLAPI void APIENTRY glEndConditionalRenderNV (void);
+#endif
+typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode);
+typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void);
+#endif
+
+#ifndef GL_NV_present_video
+#define GL_NV_present_video 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
+GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
+GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params);
+#endif
+typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
+typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
+typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params);
+#endif
+
+#ifndef GL_EXT_transform_feedback
+#define GL_EXT_transform_feedback 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedbackEXT (void);
+GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+#endif
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+#endif
+
+#ifndef GL_EXT_direct_state_access
+#define GL_EXT_direct_state_access 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask);
+GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask);
+GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glMatrixPopEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixPushEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);
+GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);
+GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture);
+GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index);
+GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index);
+GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
+GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);
+GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data);
+GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data);
+GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, GLvoid* *data);
+GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, GLvoid *img);
+GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, GLvoid *img);
+GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, GLvoid *string);
+GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params);
+GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0);
+GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0);
+GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0);
+GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer);
+GLAPI GLvoid* APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length);
+GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, GLvoid* *params);
+GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data);
+GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params);
+GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target);
+GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target);
+GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target);
+GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode);
+GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs);
+GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode);
+GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);
+GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x);
+GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+#endif
+typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
+typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data);
+typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid* *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, GLvoid *img);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, GLvoid *img);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, GLvoid *string);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer);
+typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, GLvoid* *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data);
+typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params);
+typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target);
+typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);
+typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+#endif
+
+#ifndef GL_EXT_vertex_array_bgra
+#define GL_EXT_vertex_array_bgra 1
+#endif
+
+#ifndef GL_EXT_texture_swizzle
+#define GL_EXT_texture_swizzle 1
+#endif
+
+#ifndef GL_NV_explicit_multisample
+#define GL_NV_explicit_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val);
+GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask);
+GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer);
+#endif
+typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask);
+typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer);
+#endif
+
+#ifndef GL_NV_transform_feedback2
+#define GL_NV_transform_feedback2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids);
+GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids);
+GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id);
+GLAPI void APIENTRY glPauseTransformFeedbackNV (void);
+GLAPI void APIENTRY glResumeTransformFeedbackNV (void);
+GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id);
+#endif
+typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids);
+typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id);
+#endif
+
+#ifndef GL_ATI_meminfo
+#define GL_ATI_meminfo 1
+#endif
+
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor);
+GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor);
+GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+
+#ifndef GL_AMD_texture_texture4
+#define GL_AMD_texture_texture4 1
+#endif
+
+#ifndef GL_AMD_vertex_shader_tesselator
+#define GL_AMD_vertex_shader_tesselator 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor);
+GLAPI void APIENTRY glTessellationModeAMD (GLenum mode);
+#endif
+typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor);
+typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_EXT_provoking_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode);
+#endif
+typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_texture_snorm
+#define GL_EXT_texture_snorm 1
+#endif
+
+#ifndef GL_AMD_draw_buffers_blend
+#define GL_AMD_draw_buffers_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+#endif
+typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+#ifndef GL_APPLE_texture_range
+#define GL_APPLE_texture_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const GLvoid *pointer);
+GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_APPLE_float_pixels
+#define GL_APPLE_float_pixels 1
+#endif
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_APPLE_vertex_program_evaluators 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname);
+GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname);
+GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname);
+GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+#endif
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+#endif
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_APPLE_aux_depth_stencil 1
+#endif
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_APPLE_object_purgeable 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option);
+GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option);
+GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params);
+#endif
+typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_APPLE_row_bytes
+#define GL_APPLE_row_bytes 1
+#endif
+
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+#endif
+
+#ifndef GL_NV_video_capture
+#define GL_NV_video_capture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot);
+GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
+GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
+GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot);
+GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params);
+GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time);
+GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params);
+#endif
+typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
+typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params);
+typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params);
+#endif
+
+#ifndef GL_NV_copy_image
+#define GL_NV_copy_image 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program);
+GLAPI void APIENTRY glActiveProgramEXT (GLuint program);
+GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string);
+#endif
+typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program);
+typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string);
+#endif
+
+#ifndef GL_NV_parameter_buffer_object2
+#define GL_NV_parameter_buffer_object2 1
+#endif
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_NV_shader_buffer_load 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access);
+GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target);
+GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target);
+GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access);
+GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer);
+GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer);
+GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result);
+GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value);
+GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params);
+GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value);
+GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access);
+typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access);
+typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer);
+typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result);
+typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value);
+typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_NV_vertex_buffer_unified_memory 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride);
+GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result);
+#endif
+typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result);
+#endif
+
+#ifndef GL_NV_texture_barrier
+#define GL_NV_texture_barrier 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureBarrierNV (void);
+#endif
+typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void);
+#endif
+
+#ifndef GL_AMD_shader_stencil_export
+#define GL_AMD_shader_stencil_export 1
+#endif
+
+#ifndef GL_AMD_seamless_cubemap_per_texture
+#define GL_AMD_seamless_cubemap_per_texture 1
+#endif
+
+#ifndef GL_AMD_conservative_depth
+#define GL_AMD_conservative_depth 1
+#endif
+
+#ifndef GL_EXT_shader_image_load_store
+#define GL_EXT_shader_image_load_store 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format);
+GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers);
+#endif
+typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format);
+typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers);
+#endif
+
+#ifndef GL_EXT_vertex_attrib_64bit
+#define GL_EXT_vertex_attrib_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+#endif
+
+#ifndef GL_NV_gpu_program5
+#define GL_NV_gpu_program5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param);
+#endif
+typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param);
+#endif
+
+#ifndef GL_NV_gpu_shader5
+#define GL_NV_gpu_shader5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x);
+GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x);
+GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params);
+GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x);
+GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x);
+GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x);
+typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+
+#ifndef GL_NV_shader_buffer_store
+#define GL_NV_shader_buffer_store 1
+#endif
+
+#ifndef GL_NV_tessellation_program5
+#define GL_NV_tessellation_program5 1
+#endif
+
+#ifndef GL_NV_vertex_attrib_integer_64bit
+#define GL_NV_vertex_attrib_integer_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x);
+GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x);
+GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride);
+#endif
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+#endif
+
+#ifndef GL_NV_multisample_coverage
+#define GL_NV_multisample_coverage 1
+#endif
+
+#ifndef GL_AMD_name_gen_delete
+#define GL_AMD_name_gen_delete 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names);
+GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names);
+GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name);
+#endif
+typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names);
+typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names);
+typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name);
+#endif
+
+#ifndef GL_AMD_debug_output
+#define GL_AMD_debug_output 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf);
+GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, GLvoid *userParam);
+GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
+#endif
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, GLvoid *userParam);
+typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
+#endif
+
+#ifndef GL_NV_vdpau_interop
+#define GL_NV_vdpau_interop 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVDPAUInitNV (const GLvoid *vdpDevice, const GLvoid *getProcAddress);
+GLAPI void APIENTRY glVDPAUFiniNV (void);
+GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+GLAPI void APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface);
+GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface);
+GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access);
+GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces);
+GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces);
+#endif
+typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const GLvoid *vdpDevice, const GLvoid *getProcAddress);
+typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void);
+typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef void (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface);
+typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface);
+typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access);
+typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces);
+typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces);
+#endif
+
+#ifndef GL_AMD_transform_feedback3_lines_triangles
+#define GL_AMD_transform_feedback3_lines_triangles 1
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+#endif
+
+#endif
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_opengles.h b/extern/sdlew/include/SDL2/SDL_opengles.h
new file mode 100644
index 00000000000..f55a8630835
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_opengles.h
@@ -0,0 +1,12 @@
+
+#ifdef __IPHONEOS__
+#include <OpenGLES/ES1/gl.h>
+#include <OpenGLES/ES1/glext.h>
+#else
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
diff --git a/extern/sdlew/include/SDL2/SDL_opengles2.h b/extern/sdlew/include/SDL2/SDL_opengles2.h
new file mode 100644
index 00000000000..87a92612369
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_opengles2.h
@@ -0,0 +1,12 @@
+
+#ifdef __IPHONEOS__
+#include <OpenGLES/ES2/gl.h>
+#include <OpenGLES/ES2/glext.h>
+#else
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
diff --git a/extern/sdlew/include/SDL2/SDL_pixels.h b/extern/sdlew/include/SDL2/SDL_pixels.h
new file mode 100644
index 00000000000..bc919d38155
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_pixels.h
@@ -0,0 +1,320 @@
+
+#ifndef _SDL_pixels_h
+#define _SDL_pixels_h
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL_ALPHA_OPAQUE 255
+#define SDL_ALPHA_TRANSPARENT 0
+
+enum
+{
+ SDL_PIXELTYPE_UNKNOWN,
+ SDL_PIXELTYPE_INDEX1,
+ SDL_PIXELTYPE_INDEX4,
+ SDL_PIXELTYPE_INDEX8,
+ SDL_PIXELTYPE_PACKED8,
+ SDL_PIXELTYPE_PACKED16,
+ SDL_PIXELTYPE_PACKED32,
+ SDL_PIXELTYPE_ARRAYU8,
+ SDL_PIXELTYPE_ARRAYU16,
+ SDL_PIXELTYPE_ARRAYU32,
+ SDL_PIXELTYPE_ARRAYF16,
+ SDL_PIXELTYPE_ARRAYF32
+};
+
+enum
+{
+ SDL_BITMAPORDER_NONE,
+ SDL_BITMAPORDER_4321,
+ SDL_BITMAPORDER_1234
+};
+
+enum
+{
+ SDL_PACKEDORDER_NONE,
+ SDL_PACKEDORDER_XRGB,
+ SDL_PACKEDORDER_RGBX,
+ SDL_PACKEDORDER_ARGB,
+ SDL_PACKEDORDER_RGBA,
+ SDL_PACKEDORDER_XBGR,
+ SDL_PACKEDORDER_BGRX,
+ SDL_PACKEDORDER_ABGR,
+ SDL_PACKEDORDER_BGRA
+};
+
+enum
+{
+ SDL_ARRAYORDER_NONE,
+ SDL_ARRAYORDER_RGB,
+ SDL_ARRAYORDER_RGBA,
+ SDL_ARRAYORDER_ARGB,
+ SDL_ARRAYORDER_BGR,
+ SDL_ARRAYORDER_BGRA,
+ SDL_ARRAYORDER_ABGR
+};
+
+enum
+{
+ SDL_PACKEDLAYOUT_NONE,
+ SDL_PACKEDLAYOUT_332,
+ SDL_PACKEDLAYOUT_4444,
+ SDL_PACKEDLAYOUT_1555,
+ SDL_PACKEDLAYOUT_5551,
+ SDL_PACKEDLAYOUT_565,
+ SDL_PACKEDLAYOUT_8888,
+ SDL_PACKEDLAYOUT_2101010,
+ SDL_PACKEDLAYOUT_1010102
+};
+
+#define SDL_DEFINE_PIXELFOURCC(A, B, C, D) SDL_FOURCC(A, B, C, D)
+
+#define SDL_DEFINE_PIXELFORMAT(type, order, layout, bits, bytes) \
+ ((1 << 28) | ((type) << 24) | ((order) << 20) | ((layout) << 16) | \
+ ((bits) << 8) | ((bytes) << 0))
+
+#define SDL_PIXELFLAG(X) (((X) >> 28) & 0x0F)
+#define SDL_PIXELTYPE(X) (((X) >> 24) & 0x0F)
+#define SDL_PIXELORDER(X) (((X) >> 20) & 0x0F)
+#define SDL_PIXELLAYOUT(X) (((X) >> 16) & 0x0F)
+#define SDL_BITSPERPIXEL(X) (((X) >> 8) & 0xFF)
+#define SDL_BYTESPERPIXEL(X) \
+ (SDL_ISPIXELFORMAT_FOURCC(X) ? \
+ ((((X) == SDL_PIXELFORMAT_YUY2) || \
+ ((X) == SDL_PIXELFORMAT_UYVY) || \
+ ((X) == SDL_PIXELFORMAT_YVYU)) ? 2 : 1) : (((X) >> 0) & 0xFF))
+
+#define SDL_ISPIXELFORMAT_INDEXED(format) \
+ (!SDL_ISPIXELFORMAT_FOURCC(format) && \
+ ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX1) || \
+ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX4) || \
+ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX8)))
+
+#define SDL_ISPIXELFORMAT_ALPHA(format) \
+ (!SDL_ISPIXELFORMAT_FOURCC(format) && \
+ ((SDL_PIXELORDER(format) == SDL_PACKEDORDER_ARGB) || \
+ (SDL_PIXELORDER(format) == SDL_PACKEDORDER_RGBA) || \
+ (SDL_PIXELORDER(format) == SDL_PACKEDORDER_ABGR) || \
+ (SDL_PIXELORDER(format) == SDL_PACKEDORDER_BGRA)))
+
+#define SDL_ISPIXELFORMAT_FOURCC(format) \
+ ((format) && (SDL_PIXELFLAG(format) != 1))
+
+enum
+{
+ SDL_PIXELFORMAT_UNKNOWN,
+ SDL_PIXELFORMAT_INDEX1LSB =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0,
+ 1, 0),
+ SDL_PIXELFORMAT_INDEX1MSB =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0,
+ 1, 0),
+ SDL_PIXELFORMAT_INDEX4LSB =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0,
+ 4, 0),
+ SDL_PIXELFORMAT_INDEX4MSB =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0,
+ 4, 0),
+ SDL_PIXELFORMAT_INDEX8 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1),
+ SDL_PIXELFORMAT_RGB332 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB,
+ SDL_PACKEDLAYOUT_332, 8, 1),
+ SDL_PIXELFORMAT_RGB444 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
+ SDL_PACKEDLAYOUT_4444, 12, 2),
+ SDL_PIXELFORMAT_RGB555 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
+ SDL_PACKEDLAYOUT_1555, 15, 2),
+ SDL_PIXELFORMAT_BGR555 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR,
+ SDL_PACKEDLAYOUT_1555, 15, 2),
+ SDL_PIXELFORMAT_ARGB4444 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB,
+ SDL_PACKEDLAYOUT_4444, 16, 2),
+ SDL_PIXELFORMAT_RGBA4444 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA,
+ SDL_PACKEDLAYOUT_4444, 16, 2),
+ SDL_PIXELFORMAT_ABGR4444 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR,
+ SDL_PACKEDLAYOUT_4444, 16, 2),
+ SDL_PIXELFORMAT_BGRA4444 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA,
+ SDL_PACKEDLAYOUT_4444, 16, 2),
+ SDL_PIXELFORMAT_ARGB1555 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB,
+ SDL_PACKEDLAYOUT_1555, 16, 2),
+ SDL_PIXELFORMAT_RGBA5551 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA,
+ SDL_PACKEDLAYOUT_5551, 16, 2),
+ SDL_PIXELFORMAT_ABGR1555 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR,
+ SDL_PACKEDLAYOUT_1555, 16, 2),
+ SDL_PIXELFORMAT_BGRA5551 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA,
+ SDL_PACKEDLAYOUT_5551, 16, 2),
+ SDL_PIXELFORMAT_RGB565 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
+ SDL_PACKEDLAYOUT_565, 16, 2),
+ SDL_PIXELFORMAT_BGR565 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR,
+ SDL_PACKEDLAYOUT_565, 16, 2),
+ SDL_PIXELFORMAT_RGB24 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0,
+ 24, 3),
+ SDL_PIXELFORMAT_BGR24 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0,
+ 24, 3),
+ SDL_PIXELFORMAT_RGB888 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB,
+ SDL_PACKEDLAYOUT_8888, 24, 4),
+ SDL_PIXELFORMAT_RGBX8888 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX,
+ SDL_PACKEDLAYOUT_8888, 24, 4),
+ SDL_PIXELFORMAT_BGR888 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR,
+ SDL_PACKEDLAYOUT_8888, 24, 4),
+ SDL_PIXELFORMAT_BGRX8888 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX,
+ SDL_PACKEDLAYOUT_8888, 24, 4),
+ SDL_PIXELFORMAT_ARGB8888 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB,
+ SDL_PACKEDLAYOUT_8888, 32, 4),
+ SDL_PIXELFORMAT_RGBA8888 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA,
+ SDL_PACKEDLAYOUT_8888, 32, 4),
+ SDL_PIXELFORMAT_ABGR8888 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR,
+ SDL_PACKEDLAYOUT_8888, 32, 4),
+ SDL_PIXELFORMAT_BGRA8888 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA,
+ SDL_PACKEDLAYOUT_8888, 32, 4),
+ SDL_PIXELFORMAT_ARGB2101010 =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB,
+ SDL_PACKEDLAYOUT_2101010, 32, 4),
+
+ SDL_PIXELFORMAT_YV12 =
+ SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'),
+ SDL_PIXELFORMAT_IYUV =
+ SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V'),
+ SDL_PIXELFORMAT_YUY2 =
+ SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2'),
+ SDL_PIXELFORMAT_UYVY =
+ SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y'),
+ SDL_PIXELFORMAT_YVYU =
+ SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U')
+};
+
+typedef struct SDL_Color
+{
+ Uint8 r;
+ Uint8 g;
+ Uint8 b;
+ Uint8 a;
+} SDL_Color;
+#define SDL_Colour SDL_Color
+
+typedef struct SDL_Palette
+{
+ int ncolors;
+ SDL_Color *colors;
+ Uint32 version;
+ int refcount;
+} SDL_Palette;
+
+typedef struct SDL_PixelFormat
+{
+ Uint32 format;
+ SDL_Palette *palette;
+ Uint8 BitsPerPixel;
+ Uint8 BytesPerPixel;
+ Uint8 padding[2];
+ Uint32 Rmask;
+ Uint32 Gmask;
+ Uint32 Bmask;
+ Uint32 Amask;
+ Uint8 Rloss;
+ Uint8 Gloss;
+ Uint8 Bloss;
+ Uint8 Aloss;
+ Uint8 Rshift;
+ Uint8 Gshift;
+ Uint8 Bshift;
+ Uint8 Ashift;
+ int refcount;
+ struct SDL_PixelFormat *next;
+} SDL_PixelFormat;
+
+extern DECLSPEC const char* SDLCALL SDL_GetPixelFormatName(Uint32 format);
+
+typedef SDL_bool SDLCALL tSDL_PixelFormatEnumToMasks(Uint32 format,
+ int *bpp,
+ Uint32 * Rmask,
+ Uint32 * Gmask,
+ Uint32 * Bmask,
+ Uint32 * Amask);
+
+typedef Uint32 SDLCALL tSDL_MasksToPixelFormatEnum(int bpp,
+ Uint32 Rmask,
+ Uint32 Gmask,
+ Uint32 Bmask,
+ Uint32 Amask);
+
+typedef SDL_PixelFormat * SDLCALL tSDL_AllocFormat(Uint32 pixel_format);
+
+typedef void SDLCALL tSDL_FreeFormat(SDL_PixelFormat *format);
+
+typedef SDL_Palette * SDLCALL tSDL_AllocPalette(int ncolors);
+
+typedef int SDLCALL tSDL_SetPixelFormatPalette(SDL_PixelFormat * format,
+ SDL_Palette *palette);
+
+typedef int SDLCALL tSDL_SetPaletteColors(SDL_Palette * palette,
+ const SDL_Color * colors,
+ int firstcolor, int ncolors);
+
+typedef void SDLCALL tSDL_FreePalette(SDL_Palette * palette);
+
+typedef Uint32 SDLCALL tSDL_MapRGB(const SDL_PixelFormat * format,
+ Uint8 r, Uint8 g, Uint8 b);
+
+typedef Uint32 SDLCALL tSDL_MapRGBA(const SDL_PixelFormat * format,
+ Uint8 r, Uint8 g, Uint8 b,
+ Uint8 a);
+
+typedef void SDLCALL tSDL_GetRGB(Uint32 pixel,
+ const SDL_PixelFormat * format,
+ Uint8 * r, Uint8 * g, Uint8 * b);
+
+typedef void SDLCALL tSDL_GetRGBA(Uint32 pixel,
+ const SDL_PixelFormat * format,
+ Uint8 * r, Uint8 * g, Uint8 * b,
+ Uint8 * a);
+
+typedef void SDLCALL tSDL_CalculateGammaRamp(float gamma, Uint16 * ramp);
+
+extern tSDL_PixelFormatEnumToMasks *SDL_PixelFormatEnumToMasks;
+extern tSDL_MasksToPixelFormatEnum *SDL_MasksToPixelFormatEnum;
+extern tSDL_AllocFormat *SDL_AllocFormat;
+extern tSDL_FreeFormat *SDL_FreeFormat;
+extern tSDL_AllocPalette *SDL_AllocPalette;
+extern tSDL_SetPixelFormatPalette *SDL_SetPixelFormatPalette;
+extern tSDL_SetPaletteColors *SDL_SetPaletteColors;
+extern tSDL_FreePalette *SDL_FreePalette;
+extern tSDL_MapRGB *SDL_MapRGB;
+extern tSDL_MapRGBA *SDL_MapRGBA;
+extern tSDL_GetRGB *SDL_GetRGB;
+extern tSDL_GetRGBA *SDL_GetRGBA;
+extern tSDL_CalculateGammaRamp *SDL_CalculateGammaRamp;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_platform.h b/extern/sdlew/include/SDL2/SDL_platform.h
new file mode 100644
index 00000000000..6f18a970e4f
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_platform.h
@@ -0,0 +1,122 @@
+
+#ifndef _SDL_platform_h
+#define _SDL_platform_h
+
+#if defined(_AIX)
+#undef __AIX__
+#define __AIX__ 1
+#endif
+#if defined(__BEOS__)
+#undef __BEOS__
+#define __BEOS__ 1
+#endif
+#if defined(__HAIKU__)
+#undef __HAIKU__
+#define __HAIKU__ 1
+#endif
+#if defined(bsdi) || defined(__bsdi) || defined(__bsdi__)
+#undef __BSDI__
+#define __BSDI__ 1
+#endif
+#if defined(_arch_dreamcast)
+#undef __DREAMCAST__
+#define __DREAMCAST__ 1
+#endif
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+#undef __FREEBSD__
+#define __FREEBSD__ 1
+#endif
+#if defined(hpux) || defined(__hpux) || defined(__hpux__)
+#undef __HPUX__
+#define __HPUX__ 1
+#endif
+#if defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE)
+#undef __IRIX__
+#define __IRIX__ 1
+#endif
+#if defined(linux) || defined(__linux) || defined(__linux__)
+#undef __LINUX__
+#define __LINUX__ 1
+#endif
+#if defined(ANDROID)
+#undef __ANDROID__
+#undef __LINUX__
+#define __ANDROID__ 1
+#endif
+
+#if defined(__APPLE__)
+
+#include "AvailabilityMacros.h"
+#include "TargetConditionals.h"
+#if TARGET_OS_IPHONE
+
+#undef __IPHONEOS__
+#define __IPHONEOS__ 1
+#undef __MACOSX__
+#else
+
+#undef __MACOSX__
+#define __MACOSX__ 1
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
+# error SDL for Mac OS X only supports deploying on 10.5 and above.
+#endif
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
+# error SDL for Mac OS X must be built with a 10.6 SDK or above.
+#endif
+#endif
+#endif
+
+#if defined(__NetBSD__)
+#undef __NETBSD__
+#define __NETBSD__ 1
+#endif
+#if defined(__OpenBSD__)
+#undef __OPENBSD__
+#define __OPENBSD__ 1
+#endif
+#if defined(__OS2__)
+#undef __OS2__
+#define __OS2__ 1
+#endif
+#if defined(osf) || defined(__osf) || defined(__osf__) || defined(_OSF_SOURCE)
+#undef __OSF__
+#define __OSF__ 1
+#endif
+#if defined(__QNXNTO__)
+#undef __QNXNTO__
+#define __QNXNTO__ 1
+#endif
+#if defined(riscos) || defined(__riscos) || defined(__riscos__)
+#undef __RISCOS__
+#define __RISCOS__ 1
+#endif
+#if defined(__SVR4)
+#undef __SOLARIS__
+#define __SOLARIS__ 1
+#endif
+#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
+#undef __WIN32__
+#define __WIN32__ 1
+#endif
+#if defined(__PSP__)
+#undef __PSP__
+#define __PSP__ 1
+#endif
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef const char * SDLCALL tSDL_GetPlatform (void);
+
+extern tSDL_GetPlatform *SDL_GetPlatform;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_power.h b/extern/sdlew/include/SDL2/SDL_power.h
new file mode 100644
index 00000000000..00d63072e7c
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_power.h
@@ -0,0 +1,32 @@
+
+#ifndef _SDL_power_h
+#define _SDL_power_h
+
+#include "SDL_stdinc.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ SDL_POWERSTATE_UNKNOWN,
+ SDL_POWERSTATE_ON_BATTERY,
+ SDL_POWERSTATE_NO_BATTERY,
+ SDL_POWERSTATE_CHARGING,
+ SDL_POWERSTATE_CHARGED
+} SDL_PowerState;
+
+typedef SDL_PowerState SDLCALL tSDL_GetPowerInfo(int *secs, int *pct);
+
+extern tSDL_GetPowerInfo *SDL_GetPowerInfo;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_quit.h b/extern/sdlew/include/SDL2/SDL_quit.h
new file mode 100644
index 00000000000..a91450ec793
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_quit.h
@@ -0,0 +1,11 @@
+
+#ifndef _SDL_quit_h
+#define _SDL_quit_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#define SDL_QuitRequested() \
+ (SDL_PumpEvents(), (SDL_PeepEvents(NULL,0,SDL_PEEKEVENT,SDL_QUIT,SDL_QUIT) > 0))
+
+#endif
diff --git a/extern/sdlew/include/SDL2/SDL_rect.h b/extern/sdlew/include/SDL2/SDL_rect.h
new file mode 100644
index 00000000000..36e0eb3eca1
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_rect.h
@@ -0,0 +1,72 @@
+
+#ifndef _SDL_rect_h
+#define _SDL_rect_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_pixels.h"
+#include "SDL_rwops.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ int x;
+ int y;
+} SDL_Point;
+
+typedef struct SDL_Rect
+{
+ int x, y;
+ int w, h;
+} SDL_Rect;
+
+SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
+{
+ return ((!r) || (r->w <= 0) || (r->h <= 0)) ? SDL_TRUE : SDL_FALSE;
+}
+
+SDL_FORCE_INLINE SDL_bool SDL_RectEquals(const SDL_Rect *a, const SDL_Rect *b)
+{
+ return (a && b && (a->x == b->x) && (a->y == b->y) &&
+ (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE;
+}
+
+typedef SDL_bool SDLCALL tSDL_HasIntersection(const SDL_Rect * A,
+ const SDL_Rect * B);
+
+typedef SDL_bool SDLCALL tSDL_IntersectRect(const SDL_Rect * A,
+ const SDL_Rect * B,
+ SDL_Rect * result);
+
+typedef void SDLCALL tSDL_UnionRect(const SDL_Rect * A,
+ const SDL_Rect * B,
+ SDL_Rect * result);
+
+typedef SDL_bool SDLCALL tSDL_EnclosePoints(const SDL_Point * points,
+ int count,
+ const SDL_Rect * clip,
+ SDL_Rect * result);
+
+typedef SDL_bool SDLCALL tSDL_IntersectRectAndLine(const SDL_Rect *
+ rect, int *X1,
+ int *Y1, int *X2,
+ int *Y2);
+
+extern tSDL_HasIntersection *SDL_HasIntersection;
+extern tSDL_IntersectRect *SDL_IntersectRect;
+extern tSDL_UnionRect *SDL_UnionRect;
+extern tSDL_EnclosePoints *SDL_EnclosePoints;
+extern tSDL_IntersectRectAndLine *SDL_IntersectRectAndLine;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_render.h b/extern/sdlew/include/SDL2/SDL_render.h
new file mode 100644
index 00000000000..a68f47cec0d
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_render.h
@@ -0,0 +1,280 @@
+
+#ifndef _SDL_render_h
+#define _SDL_render_h
+
+#include "SDL_stdinc.h"
+#include "SDL_rect.h"
+#include "SDL_video.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ SDL_RENDERER_SOFTWARE = 0x00000001,
+ SDL_RENDERER_ACCELERATED = 0x00000002,
+ SDL_RENDERER_PRESENTVSYNC = 0x00000004,
+ SDL_RENDERER_TARGETTEXTURE = 0x00000008
+} SDL_RendererFlags;
+
+typedef struct SDL_RendererInfo
+{
+ const char *name;
+ Uint32 flags;
+ Uint32 num_texture_formats;
+ Uint32 texture_formats[16];
+ int max_texture_width;
+ int max_texture_height;
+} SDL_RendererInfo;
+
+typedef enum
+{
+ SDL_TEXTUREACCESS_STATIC,
+ SDL_TEXTUREACCESS_STREAMING,
+ SDL_TEXTUREACCESS_TARGET
+} SDL_TextureAccess;
+
+typedef enum
+{
+ SDL_TEXTUREMODULATE_NONE = 0x00000000,
+ SDL_TEXTUREMODULATE_COLOR = 0x00000001,
+ SDL_TEXTUREMODULATE_ALPHA = 0x00000002
+} SDL_TextureModulate;
+
+typedef enum
+{
+ SDL_FLIP_NONE = 0x00000000,
+ SDL_FLIP_HORIZONTAL = 0x00000001,
+ SDL_FLIP_VERTICAL = 0x00000002
+} SDL_RendererFlip;
+
+struct SDL_Renderer;
+typedef struct SDL_Renderer SDL_Renderer;
+
+struct SDL_Texture;
+typedef struct SDL_Texture SDL_Texture;
+
+typedef int SDLCALL tSDL_GetNumRenderDrivers(void);
+
+typedef int SDLCALL tSDL_GetRenderDriverInfo(int index,
+ SDL_RendererInfo * info);
+
+typedef int SDLCALL tSDL_CreateWindowAndRenderer(
+ int width, int height, Uint32 window_flags,
+ SDL_Window **window, SDL_Renderer **renderer);
+
+typedef SDL_Renderer * SDLCALL tSDL_CreateRenderer(SDL_Window * window,
+ int index, Uint32 flags);
+
+typedef SDL_Renderer * SDLCALL tSDL_CreateSoftwareRenderer(SDL_Surface * surface);
+
+typedef SDL_Renderer * SDLCALL tSDL_GetRenderer(SDL_Window * window);
+
+typedef int SDLCALL tSDL_GetRendererInfo(SDL_Renderer * renderer,
+ SDL_RendererInfo * info);
+
+typedef int SDLCALL tSDL_GetRendererOutputSize(SDL_Renderer * renderer,
+ int *w, int *h);
+
+typedef SDL_Texture * SDLCALL tSDL_CreateTexture(SDL_Renderer * renderer,
+ Uint32 format,
+ int access, int w,
+ int h);
+
+typedef SDL_Texture * SDLCALL tSDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface);
+
+typedef int SDLCALL tSDL_QueryTexture(SDL_Texture * texture,
+ Uint32 * format, int *access,
+ int *w, int *h);
+
+typedef int SDLCALL tSDL_SetTextureColorMod(SDL_Texture * texture,
+ Uint8 r, Uint8 g, Uint8 b);
+
+typedef int SDLCALL tSDL_GetTextureColorMod(SDL_Texture * texture,
+ Uint8 * r, Uint8 * g,
+ Uint8 * b);
+
+typedef int SDLCALL tSDL_SetTextureAlphaMod(SDL_Texture * texture,
+ Uint8 alpha);
+
+typedef int SDLCALL tSDL_GetTextureAlphaMod(SDL_Texture * texture,
+ Uint8 * alpha);
+
+typedef int SDLCALL tSDL_SetTextureBlendMode(SDL_Texture * texture,
+ SDL_BlendMode blendMode);
+
+typedef int SDLCALL tSDL_GetTextureBlendMode(SDL_Texture * texture,
+ SDL_BlendMode *blendMode);
+
+typedef int SDLCALL tSDL_UpdateTexture(SDL_Texture * texture,
+ const SDL_Rect * rect,
+ const void *pixels, int pitch);
+
+typedef int SDLCALL tSDL_LockTexture(SDL_Texture * texture,
+ const SDL_Rect * rect,
+ void **pixels, int *pitch);
+
+typedef void SDLCALL tSDL_UnlockTexture(SDL_Texture * texture);
+
+typedef SDL_bool SDLCALL tSDL_RenderTargetSupported(SDL_Renderer *renderer);
+
+typedef int SDLCALL tSDL_SetRenderTarget(SDL_Renderer *renderer,
+ SDL_Texture *texture);
+
+typedef SDL_Texture * SDLCALL tSDL_GetRenderTarget(SDL_Renderer *renderer);
+
+typedef int SDLCALL tSDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h);
+
+typedef void SDLCALL tSDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h);
+
+typedef int SDLCALL tSDL_RenderSetViewport(SDL_Renderer * renderer,
+ const SDL_Rect * rect);
+
+typedef void SDLCALL tSDL_RenderGetViewport(SDL_Renderer * renderer,
+ SDL_Rect * rect);
+
+typedef int SDLCALL tSDL_RenderSetClipRect(SDL_Renderer * renderer,
+ const SDL_Rect * rect);
+
+typedef void SDLCALL tSDL_RenderGetClipRect(SDL_Renderer * renderer,
+ SDL_Rect * rect);
+
+typedef int SDLCALL tSDL_RenderSetScale(SDL_Renderer * renderer,
+ float scaleX, float scaleY);
+
+typedef void SDLCALL tSDL_RenderGetScale(SDL_Renderer * renderer,
+ float *scaleX, float *scaleY);
+
+extern DECLSPEC int SDL_SetRenderDrawColor(SDL_Renderer * renderer,
+ Uint8 r, Uint8 g, Uint8 b,
+ Uint8 a);
+
+extern DECLSPEC int SDL_GetRenderDrawColor(SDL_Renderer * renderer,
+ Uint8 * r, Uint8 * g, Uint8 * b,
+ Uint8 * a);
+
+typedef int SDLCALL tSDL_SetRenderDrawBlendMode(SDL_Renderer * renderer,
+ SDL_BlendMode blendMode);
+
+typedef int SDLCALL tSDL_GetRenderDrawBlendMode(SDL_Renderer * renderer,
+ SDL_BlendMode *blendMode);
+
+typedef int SDLCALL tSDL_RenderClear(SDL_Renderer * renderer);
+
+typedef int SDLCALL tSDL_RenderDrawPoint(SDL_Renderer * renderer,
+ int x, int y);
+
+typedef int SDLCALL tSDL_RenderDrawPoints(SDL_Renderer * renderer,
+ const SDL_Point * points,
+ int count);
+
+typedef int SDLCALL tSDL_RenderDrawLine(SDL_Renderer * renderer,
+ int x1, int y1, int x2, int y2);
+
+typedef int SDLCALL tSDL_RenderDrawLines(SDL_Renderer * renderer,
+ const SDL_Point * points,
+ int count);
+
+typedef int SDLCALL tSDL_RenderDrawRect(SDL_Renderer * renderer,
+ const SDL_Rect * rect);
+
+typedef int SDLCALL tSDL_RenderDrawRects(SDL_Renderer * renderer,
+ const SDL_Rect * rects,
+ int count);
+
+typedef int SDLCALL tSDL_RenderFillRect(SDL_Renderer * renderer,
+ const SDL_Rect * rect);
+
+typedef int SDLCALL tSDL_RenderFillRects(SDL_Renderer * renderer,
+ const SDL_Rect * rects,
+ int count);
+
+typedef int SDLCALL tSDL_RenderCopy(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ const SDL_Rect * srcrect,
+ const SDL_Rect * dstrect);
+
+typedef int SDLCALL tSDL_RenderCopyEx(SDL_Renderer * renderer,
+ SDL_Texture * texture,
+ const SDL_Rect * srcrect,
+ const SDL_Rect * dstrect,
+ const double angle,
+ const SDL_Point *center,
+ const SDL_RendererFlip flip);
+
+typedef int SDLCALL tSDL_RenderReadPixels(SDL_Renderer * renderer,
+ const SDL_Rect * rect,
+ Uint32 format,
+ void *pixels, int pitch);
+
+typedef void SDLCALL tSDL_RenderPresent(SDL_Renderer * renderer);
+
+typedef void SDLCALL tSDL_DestroyTexture(SDL_Texture * texture);
+
+typedef void SDLCALL tSDL_DestroyRenderer(SDL_Renderer * renderer);
+
+typedef int SDLCALL tSDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh);
+
+typedef int SDLCALL tSDL_GL_UnbindTexture(SDL_Texture *texture);
+
+extern tSDL_GetNumRenderDrivers *SDL_GetNumRenderDrivers;
+extern tSDL_GetRenderDriverInfo *SDL_GetRenderDriverInfo;
+extern tSDL_CreateWindowAndRenderer *SDL_CreateWindowAndRenderer;
+extern tSDL_CreateRenderer *SDL_CreateRenderer;
+extern tSDL_CreateSoftwareRenderer *SDL_CreateSoftwareRenderer;
+extern tSDL_GetRenderer *SDL_GetRenderer;
+extern tSDL_GetRendererInfo *SDL_GetRendererInfo;
+extern tSDL_GetRendererOutputSize *SDL_GetRendererOutputSize;
+extern tSDL_CreateTexture *SDL_CreateTexture;
+extern tSDL_CreateTextureFromSurface *SDL_CreateTextureFromSurface;
+extern tSDL_QueryTexture *SDL_QueryTexture;
+extern tSDL_SetTextureColorMod *SDL_SetTextureColorMod;
+extern tSDL_GetTextureColorMod *SDL_GetTextureColorMod;
+extern tSDL_SetTextureAlphaMod *SDL_SetTextureAlphaMod;
+extern tSDL_GetTextureAlphaMod *SDL_GetTextureAlphaMod;
+extern tSDL_SetTextureBlendMode *SDL_SetTextureBlendMode;
+extern tSDL_GetTextureBlendMode *SDL_GetTextureBlendMode;
+extern tSDL_UpdateTexture *SDL_UpdateTexture;
+extern tSDL_LockTexture *SDL_LockTexture;
+extern tSDL_UnlockTexture *SDL_UnlockTexture;
+extern tSDL_RenderTargetSupported *SDL_RenderTargetSupported;
+extern tSDL_SetRenderTarget *SDL_SetRenderTarget;
+extern tSDL_GetRenderTarget *SDL_GetRenderTarget;
+extern tSDL_RenderSetLogicalSize *SDL_RenderSetLogicalSize;
+extern tSDL_RenderGetLogicalSize *SDL_RenderGetLogicalSize;
+extern tSDL_RenderSetViewport *SDL_RenderSetViewport;
+extern tSDL_RenderGetViewport *SDL_RenderGetViewport;
+extern tSDL_RenderSetClipRect *SDL_RenderSetClipRect;
+extern tSDL_RenderGetClipRect *SDL_RenderGetClipRect;
+extern tSDL_RenderSetScale *SDL_RenderSetScale;
+extern tSDL_RenderGetScale *SDL_RenderGetScale;
+extern tSDL_SetRenderDrawBlendMode *SDL_SetRenderDrawBlendMode;
+extern tSDL_GetRenderDrawBlendMode *SDL_GetRenderDrawBlendMode;
+extern tSDL_RenderClear *SDL_RenderClear;
+extern tSDL_RenderDrawPoint *SDL_RenderDrawPoint;
+extern tSDL_RenderDrawPoints *SDL_RenderDrawPoints;
+extern tSDL_RenderDrawLine *SDL_RenderDrawLine;
+extern tSDL_RenderDrawLines *SDL_RenderDrawLines;
+extern tSDL_RenderDrawRect *SDL_RenderDrawRect;
+extern tSDL_RenderDrawRects *SDL_RenderDrawRects;
+extern tSDL_RenderFillRect *SDL_RenderFillRect;
+extern tSDL_RenderFillRects *SDL_RenderFillRects;
+extern tSDL_RenderCopy *SDL_RenderCopy;
+extern tSDL_RenderCopyEx *SDL_RenderCopyEx;
+extern tSDL_RenderReadPixels *SDL_RenderReadPixels;
+extern tSDL_RenderPresent *SDL_RenderPresent;
+extern tSDL_DestroyTexture *SDL_DestroyTexture;
+extern tSDL_DestroyRenderer *SDL_DestroyRenderer;
+extern tSDL_GL_BindTexture *SDL_GL_BindTexture;
+extern tSDL_GL_UnbindTexture *SDL_GL_UnbindTexture;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_revision.h b/extern/sdlew/include/SDL2/SDL_revision.h
new file mode 100644
index 00000000000..2d57530ee69
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_revision.h
@@ -0,0 +1,2 @@
+#define SDL_REVISION "hg-7633:d6a8fa507a45"
+#define SDL_REVISION_NUMBER 7633
diff --git a/extern/sdlew/include/SDL2/SDL_rwops.h b/extern/sdlew/include/SDL2/SDL_rwops.h
new file mode 100644
index 00000000000..6129ffb4825
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_rwops.h
@@ -0,0 +1,162 @@
+
+#ifndef _SDL_rwops_h
+#define _SDL_rwops_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL_RWOPS_UNKNOWN 0
+#define SDL_RWOPS_WINFILE 1
+#define SDL_RWOPS_STDFILE 2
+#define SDL_RWOPS_JNIFILE 3
+#define SDL_RWOPS_MEMORY 4
+#define SDL_RWOPS_MEMORY_RO 5
+
+typedef struct SDL_RWops
+{
+
+ Sint64 (SDLCALL * size) (struct SDL_RWops * context);
+
+ Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset,
+ int whence);
+
+ size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr,
+ size_t size, size_t maxnum);
+
+ size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr,
+ size_t size, size_t num);
+
+ int (SDLCALL * close) (struct SDL_RWops * context);
+
+ Uint32 type;
+ union
+ {
+#if defined(ANDROID)
+ struct
+ {
+ void *fileNameRef;
+ void *inputStreamRef;
+ void *readableByteChannelRef;
+ void *readMethod;
+ void *assetFileDescriptorRef;
+ long position;
+ long size;
+ long offset;
+ int fd;
+ } androidio;
+#elif defined(__WIN32__)
+ struct
+ {
+ SDL_bool append;
+ void *h;
+ struct
+ {
+ void *data;
+ size_t size;
+ size_t left;
+ } buffer;
+ } windowsio;
+#endif
+
+#ifdef HAVE_STDIO_H
+ struct
+ {
+ SDL_bool autoclose;
+ FILE *fp;
+ } stdio;
+#endif
+ struct
+ {
+ Uint8 *base;
+ Uint8 *here;
+ Uint8 *stop;
+ } mem;
+ struct
+ {
+ void *data1;
+ void *data2;
+ } unknown;
+ } hidden;
+
+} SDL_RWops;
+
+typedef SDL_RWops * SDLCALL tSDL_RWFromFile(const char *file,
+ const char *mode);
+
+#ifdef HAVE_STDIO_H
+typedef SDL_RWops * SDLCALL tSDL_RWFromFP(FILE * fp,
+ SDL_bool autoclose);
+#else
+typedef SDL_RWops * SDLCALL tSDL_RWFromFP(void * fp,
+ SDL_bool autoclose);
+#endif
+
+typedef SDL_RWops * SDLCALL tSDL_RWFromMem(void *mem, int size);
+typedef SDL_RWops * SDLCALL tSDL_RWFromConstMem(const void *mem,
+ int size);
+
+typedef SDL_RWops * SDLCALL tSDL_AllocRW(void);
+typedef void SDLCALL tSDL_FreeRW(SDL_RWops * area);
+
+#define RW_SEEK_SET 0
+#define RW_SEEK_CUR 1
+#define RW_SEEK_END 2
+
+#define SDL_RWsize(ctx) (ctx)->size(ctx)
+#define SDL_RWseek(ctx, offset, whence) (ctx)->seek(ctx, offset, whence)
+#define SDL_RWtell(ctx) (ctx)->seek(ctx, 0, RW_SEEK_CUR)
+#define SDL_RWread(ctx, ptr, size, n) (ctx)->read(ctx, ptr, size, n)
+#define SDL_RWwrite(ctx, ptr, size, n) (ctx)->write(ctx, ptr, size, n)
+#define SDL_RWclose(ctx) (ctx)->close(ctx)
+
+typedef Uint8 SDLCALL tSDL_ReadU8(SDL_RWops * src);
+typedef Uint16 SDLCALL tSDL_ReadLE16(SDL_RWops * src);
+typedef Uint16 SDLCALL tSDL_ReadBE16(SDL_RWops * src);
+typedef Uint32 SDLCALL tSDL_ReadLE32(SDL_RWops * src);
+typedef Uint32 SDLCALL tSDL_ReadBE32(SDL_RWops * src);
+typedef Uint64 SDLCALL tSDL_ReadLE64(SDL_RWops * src);
+typedef Uint64 SDLCALL tSDL_ReadBE64(SDL_RWops * src);
+
+typedef size_t SDLCALL tSDL_WriteU8(SDL_RWops * dst, Uint8 value);
+typedef size_t SDLCALL tSDL_WriteLE16(SDL_RWops * dst, Uint16 value);
+typedef size_t SDLCALL tSDL_WriteBE16(SDL_RWops * dst, Uint16 value);
+typedef size_t SDLCALL tSDL_WriteLE32(SDL_RWops * dst, Uint32 value);
+typedef size_t SDLCALL tSDL_WriteBE32(SDL_RWops * dst, Uint32 value);
+typedef size_t SDLCALL tSDL_WriteLE64(SDL_RWops * dst, Uint64 value);
+typedef size_t SDLCALL tSDL_WriteBE64(SDL_RWops * dst, Uint64 value);
+
+extern tSDL_RWFromFile *SDL_RWFromFile;
+extern tSDL_RWFromFP *SDL_RWFromFP;
+extern tSDL_RWFromFP *SDL_RWFromFP;
+extern tSDL_RWFromMem *SDL_RWFromMem;
+extern tSDL_RWFromConstMem *SDL_RWFromConstMem;
+extern tSDL_AllocRW *SDL_AllocRW;
+extern tSDL_FreeRW *SDL_FreeRW;
+extern tSDL_ReadU8 *SDL_ReadU8;
+extern tSDL_ReadLE16 *SDL_ReadLE16;
+extern tSDL_ReadBE16 *SDL_ReadBE16;
+extern tSDL_ReadLE32 *SDL_ReadLE32;
+extern tSDL_ReadBE32 *SDL_ReadBE32;
+extern tSDL_ReadLE64 *SDL_ReadLE64;
+extern tSDL_ReadBE64 *SDL_ReadBE64;
+extern tSDL_WriteU8 *SDL_WriteU8;
+extern tSDL_WriteLE16 *SDL_WriteLE16;
+extern tSDL_WriteBE16 *SDL_WriteBE16;
+extern tSDL_WriteLE32 *SDL_WriteLE32;
+extern tSDL_WriteBE32 *SDL_WriteBE32;
+extern tSDL_WriteLE64 *SDL_WriteLE64;
+extern tSDL_WriteBE64 *SDL_WriteBE64;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_scancode.h b/extern/sdlew/include/SDL2/SDL_scancode.h
new file mode 100644
index 00000000000..558f29c6bd9
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_scancode.h
@@ -0,0 +1,273 @@
+
+#ifndef _SDL_scancode_h
+#define _SDL_scancode_h
+
+#include "SDL_stdinc.h"
+
+typedef enum
+{
+ SDL_SCANCODE_UNKNOWN = 0,
+
+ SDL_SCANCODE_A = 4,
+ SDL_SCANCODE_B = 5,
+ SDL_SCANCODE_C = 6,
+ SDL_SCANCODE_D = 7,
+ SDL_SCANCODE_E = 8,
+ SDL_SCANCODE_F = 9,
+ SDL_SCANCODE_G = 10,
+ SDL_SCANCODE_H = 11,
+ SDL_SCANCODE_I = 12,
+ SDL_SCANCODE_J = 13,
+ SDL_SCANCODE_K = 14,
+ SDL_SCANCODE_L = 15,
+ SDL_SCANCODE_M = 16,
+ SDL_SCANCODE_N = 17,
+ SDL_SCANCODE_O = 18,
+ SDL_SCANCODE_P = 19,
+ SDL_SCANCODE_Q = 20,
+ SDL_SCANCODE_R = 21,
+ SDL_SCANCODE_S = 22,
+ SDL_SCANCODE_T = 23,
+ SDL_SCANCODE_U = 24,
+ SDL_SCANCODE_V = 25,
+ SDL_SCANCODE_W = 26,
+ SDL_SCANCODE_X = 27,
+ SDL_SCANCODE_Y = 28,
+ SDL_SCANCODE_Z = 29,
+
+ SDL_SCANCODE_1 = 30,
+ SDL_SCANCODE_2 = 31,
+ SDL_SCANCODE_3 = 32,
+ SDL_SCANCODE_4 = 33,
+ SDL_SCANCODE_5 = 34,
+ SDL_SCANCODE_6 = 35,
+ SDL_SCANCODE_7 = 36,
+ SDL_SCANCODE_8 = 37,
+ SDL_SCANCODE_9 = 38,
+ SDL_SCANCODE_0 = 39,
+
+ SDL_SCANCODE_RETURN = 40,
+ SDL_SCANCODE_ESCAPE = 41,
+ SDL_SCANCODE_BACKSPACE = 42,
+ SDL_SCANCODE_TAB = 43,
+ SDL_SCANCODE_SPACE = 44,
+
+ SDL_SCANCODE_MINUS = 45,
+ SDL_SCANCODE_EQUALS = 46,
+ SDL_SCANCODE_LEFTBRACKET = 47,
+ SDL_SCANCODE_RIGHTBRACKET = 48,
+ SDL_SCANCODE_BACKSLASH = 49,
+ SDL_SCANCODE_NONUSHASH = 50,
+ SDL_SCANCODE_SEMICOLON = 51,
+ SDL_SCANCODE_APOSTROPHE = 52,
+ SDL_SCANCODE_GRAVE = 53,
+ SDL_SCANCODE_COMMA = 54,
+ SDL_SCANCODE_PERIOD = 55,
+ SDL_SCANCODE_SLASH = 56,
+
+ SDL_SCANCODE_CAPSLOCK = 57,
+
+ SDL_SCANCODE_F1 = 58,
+ SDL_SCANCODE_F2 = 59,
+ SDL_SCANCODE_F3 = 60,
+ SDL_SCANCODE_F4 = 61,
+ SDL_SCANCODE_F5 = 62,
+ SDL_SCANCODE_F6 = 63,
+ SDL_SCANCODE_F7 = 64,
+ SDL_SCANCODE_F8 = 65,
+ SDL_SCANCODE_F9 = 66,
+ SDL_SCANCODE_F10 = 67,
+ SDL_SCANCODE_F11 = 68,
+ SDL_SCANCODE_F12 = 69,
+
+ SDL_SCANCODE_PRINTSCREEN = 70,
+ SDL_SCANCODE_SCROLLLOCK = 71,
+ SDL_SCANCODE_PAUSE = 72,
+ SDL_SCANCODE_INSERT = 73,
+ SDL_SCANCODE_HOME = 74,
+ SDL_SCANCODE_PAGEUP = 75,
+ SDL_SCANCODE_DELETE = 76,
+ SDL_SCANCODE_END = 77,
+ SDL_SCANCODE_PAGEDOWN = 78,
+ SDL_SCANCODE_RIGHT = 79,
+ SDL_SCANCODE_LEFT = 80,
+ SDL_SCANCODE_DOWN = 81,
+ SDL_SCANCODE_UP = 82,
+
+ SDL_SCANCODE_NUMLOCKCLEAR = 83,
+ SDL_SCANCODE_KP_DIVIDE = 84,
+ SDL_SCANCODE_KP_MULTIPLY = 85,
+ SDL_SCANCODE_KP_MINUS = 86,
+ SDL_SCANCODE_KP_PLUS = 87,
+ SDL_SCANCODE_KP_ENTER = 88,
+ SDL_SCANCODE_KP_1 = 89,
+ SDL_SCANCODE_KP_2 = 90,
+ SDL_SCANCODE_KP_3 = 91,
+ SDL_SCANCODE_KP_4 = 92,
+ SDL_SCANCODE_KP_5 = 93,
+ SDL_SCANCODE_KP_6 = 94,
+ SDL_SCANCODE_KP_7 = 95,
+ SDL_SCANCODE_KP_8 = 96,
+ SDL_SCANCODE_KP_9 = 97,
+ SDL_SCANCODE_KP_0 = 98,
+ SDL_SCANCODE_KP_PERIOD = 99,
+
+ SDL_SCANCODE_NONUSBACKSLASH = 100,
+ SDL_SCANCODE_APPLICATION = 101,
+ SDL_SCANCODE_POWER = 102,
+ SDL_SCANCODE_KP_EQUALS = 103,
+ SDL_SCANCODE_F13 = 104,
+ SDL_SCANCODE_F14 = 105,
+ SDL_SCANCODE_F15 = 106,
+ SDL_SCANCODE_F16 = 107,
+ SDL_SCANCODE_F17 = 108,
+ SDL_SCANCODE_F18 = 109,
+ SDL_SCANCODE_F19 = 110,
+ SDL_SCANCODE_F20 = 111,
+ SDL_SCANCODE_F21 = 112,
+ SDL_SCANCODE_F22 = 113,
+ SDL_SCANCODE_F23 = 114,
+ SDL_SCANCODE_F24 = 115,
+ SDL_SCANCODE_EXECUTE = 116,
+ SDL_SCANCODE_HELP = 117,
+ SDL_SCANCODE_MENU = 118,
+ SDL_SCANCODE_SELECT = 119,
+ SDL_SCANCODE_STOP = 120,
+ SDL_SCANCODE_AGAIN = 121,
+ SDL_SCANCODE_UNDO = 122,
+ SDL_SCANCODE_CUT = 123,
+ SDL_SCANCODE_COPY = 124,
+ SDL_SCANCODE_PASTE = 125,
+ SDL_SCANCODE_FIND = 126,
+ SDL_SCANCODE_MUTE = 127,
+ SDL_SCANCODE_VOLUMEUP = 128,
+ SDL_SCANCODE_VOLUMEDOWN = 129,
+
+ SDL_SCANCODE_KP_COMMA = 133,
+ SDL_SCANCODE_KP_EQUALSAS400 = 134,
+
+ SDL_SCANCODE_INTERNATIONAL1 = 135,
+ SDL_SCANCODE_INTERNATIONAL2 = 136,
+ SDL_SCANCODE_INTERNATIONAL3 = 137,
+ SDL_SCANCODE_INTERNATIONAL4 = 138,
+ SDL_SCANCODE_INTERNATIONAL5 = 139,
+ SDL_SCANCODE_INTERNATIONAL6 = 140,
+ SDL_SCANCODE_INTERNATIONAL7 = 141,
+ SDL_SCANCODE_INTERNATIONAL8 = 142,
+ SDL_SCANCODE_INTERNATIONAL9 = 143,
+ SDL_SCANCODE_LANG1 = 144,
+ SDL_SCANCODE_LANG2 = 145,
+ SDL_SCANCODE_LANG3 = 146,
+ SDL_SCANCODE_LANG4 = 147,
+ SDL_SCANCODE_LANG5 = 148,
+ SDL_SCANCODE_LANG6 = 149,
+ SDL_SCANCODE_LANG7 = 150,
+ SDL_SCANCODE_LANG8 = 151,
+ SDL_SCANCODE_LANG9 = 152,
+
+ SDL_SCANCODE_ALTERASE = 153,
+ SDL_SCANCODE_SYSREQ = 154,
+ SDL_SCANCODE_CANCEL = 155,
+ SDL_SCANCODE_CLEAR = 156,
+ SDL_SCANCODE_PRIOR = 157,
+ SDL_SCANCODE_RETURN2 = 158,
+ SDL_SCANCODE_SEPARATOR = 159,
+ SDL_SCANCODE_OUT = 160,
+ SDL_SCANCODE_OPER = 161,
+ SDL_SCANCODE_CLEARAGAIN = 162,
+ SDL_SCANCODE_CRSEL = 163,
+ SDL_SCANCODE_EXSEL = 164,
+
+ SDL_SCANCODE_KP_00 = 176,
+ SDL_SCANCODE_KP_000 = 177,
+ SDL_SCANCODE_THOUSANDSSEPARATOR = 178,
+ SDL_SCANCODE_DECIMALSEPARATOR = 179,
+ SDL_SCANCODE_CURRENCYUNIT = 180,
+ SDL_SCANCODE_CURRENCYSUBUNIT = 181,
+ SDL_SCANCODE_KP_LEFTPAREN = 182,
+ SDL_SCANCODE_KP_RIGHTPAREN = 183,
+ SDL_SCANCODE_KP_LEFTBRACE = 184,
+ SDL_SCANCODE_KP_RIGHTBRACE = 185,
+ SDL_SCANCODE_KP_TAB = 186,
+ SDL_SCANCODE_KP_BACKSPACE = 187,
+ SDL_SCANCODE_KP_A = 188,
+ SDL_SCANCODE_KP_B = 189,
+ SDL_SCANCODE_KP_C = 190,
+ SDL_SCANCODE_KP_D = 191,
+ SDL_SCANCODE_KP_E = 192,
+ SDL_SCANCODE_KP_F = 193,
+ SDL_SCANCODE_KP_XOR = 194,
+ SDL_SCANCODE_KP_POWER = 195,
+ SDL_SCANCODE_KP_PERCENT = 196,
+ SDL_SCANCODE_KP_LESS = 197,
+ SDL_SCANCODE_KP_GREATER = 198,
+ SDL_SCANCODE_KP_AMPERSAND = 199,
+ SDL_SCANCODE_KP_DBLAMPERSAND = 200,
+ SDL_SCANCODE_KP_VERTICALBAR = 201,
+ SDL_SCANCODE_KP_DBLVERTICALBAR = 202,
+ SDL_SCANCODE_KP_COLON = 203,
+ SDL_SCANCODE_KP_HASH = 204,
+ SDL_SCANCODE_KP_SPACE = 205,
+ SDL_SCANCODE_KP_AT = 206,
+ SDL_SCANCODE_KP_EXCLAM = 207,
+ SDL_SCANCODE_KP_MEMSTORE = 208,
+ SDL_SCANCODE_KP_MEMRECALL = 209,
+ SDL_SCANCODE_KP_MEMCLEAR = 210,
+ SDL_SCANCODE_KP_MEMADD = 211,
+ SDL_SCANCODE_KP_MEMSUBTRACT = 212,
+ SDL_SCANCODE_KP_MEMMULTIPLY = 213,
+ SDL_SCANCODE_KP_MEMDIVIDE = 214,
+ SDL_SCANCODE_KP_PLUSMINUS = 215,
+ SDL_SCANCODE_KP_CLEAR = 216,
+ SDL_SCANCODE_KP_CLEARENTRY = 217,
+ SDL_SCANCODE_KP_BINARY = 218,
+ SDL_SCANCODE_KP_OCTAL = 219,
+ SDL_SCANCODE_KP_DECIMAL = 220,
+ SDL_SCANCODE_KP_HEXADECIMAL = 221,
+
+ SDL_SCANCODE_LCTRL = 224,
+ SDL_SCANCODE_LSHIFT = 225,
+ SDL_SCANCODE_LALT = 226,
+ SDL_SCANCODE_LGUI = 227,
+ SDL_SCANCODE_RCTRL = 228,
+ SDL_SCANCODE_RSHIFT = 229,
+ SDL_SCANCODE_RALT = 230,
+ SDL_SCANCODE_RGUI = 231,
+
+ SDL_SCANCODE_MODE = 257,
+
+ SDL_SCANCODE_AUDIONEXT = 258,
+ SDL_SCANCODE_AUDIOPREV = 259,
+ SDL_SCANCODE_AUDIOSTOP = 260,
+ SDL_SCANCODE_AUDIOPLAY = 261,
+ SDL_SCANCODE_AUDIOMUTE = 262,
+ SDL_SCANCODE_MEDIASELECT = 263,
+ SDL_SCANCODE_WWW = 264,
+ SDL_SCANCODE_MAIL = 265,
+ SDL_SCANCODE_CALCULATOR = 266,
+ SDL_SCANCODE_COMPUTER = 267,
+ SDL_SCANCODE_AC_SEARCH = 268,
+ SDL_SCANCODE_AC_HOME = 269,
+ SDL_SCANCODE_AC_BACK = 270,
+ SDL_SCANCODE_AC_FORWARD = 271,
+ SDL_SCANCODE_AC_STOP = 272,
+ SDL_SCANCODE_AC_REFRESH = 273,
+ SDL_SCANCODE_AC_BOOKMARKS = 274,
+
+ SDL_SCANCODE_BRIGHTNESSDOWN = 275,
+ SDL_SCANCODE_BRIGHTNESSUP = 276,
+ SDL_SCANCODE_DISPLAYSWITCH = 277,
+ SDL_SCANCODE_KBDILLUMTOGGLE = 278,
+ SDL_SCANCODE_KBDILLUMDOWN = 279,
+ SDL_SCANCODE_KBDILLUMUP = 280,
+ SDL_SCANCODE_EJECT = 281,
+ SDL_SCANCODE_SLEEP = 282,
+
+ SDL_SCANCODE_APP1 = 283,
+ SDL_SCANCODE_APP2 = 284,
+
+ SDL_NUM_SCANCODES = 512
+} SDL_Scancode;
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_shape.h b/extern/sdlew/include/SDL2/SDL_shape.h
new file mode 100644
index 00000000000..781e3d8eb3d
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_shape.h
@@ -0,0 +1,60 @@
+
+#ifndef _SDL_shape_h
+#define _SDL_shape_h
+
+#include "SDL_stdinc.h"
+#include "SDL_pixels.h"
+#include "SDL_rect.h"
+#include "SDL_surface.h"
+#include "SDL_video.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL_NONSHAPEABLE_WINDOW -1
+#define SDL_INVALID_SHAPE_ARGUMENT -2
+#define SDL_WINDOW_LACKS_SHAPE -3
+
+typedef SDL_Window * SDLCALL tSDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags);
+
+typedef SDL_bool SDLCALL tSDL_IsShapedWindow(const SDL_Window *window);
+
+typedef enum {
+
+ ShapeModeDefault,
+
+ ShapeModeBinarizeAlpha,
+
+ ShapeModeReverseBinarizeAlpha,
+
+ ShapeModeColorKey
+} WindowShapeMode;
+
+#define SDL_SHAPEMODEALPHA(mode) (mode == ShapeModeDefault || mode == ShapeModeBinarizeAlpha || mode == ShapeModeReverseBinarizeAlpha)
+
+typedef union {
+
+ Uint8 binarizationCutoff;
+ SDL_Color colorKey;
+} SDL_WindowShapeParams;
+
+typedef struct SDL_WindowShapeMode {
+
+ WindowShapeMode mode;
+
+ SDL_WindowShapeParams parameters;
+} SDL_WindowShapeMode;
+
+typedef int SDLCALL tSDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode);
+
+typedef int SDLCALL tSDL_GetShapedWindowMode(SDL_Window *window,SDL_WindowShapeMode *shape_mode);
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
diff --git a/extern/sdlew/include/SDL2/SDL_stdinc.h b/extern/sdlew/include/SDL2/SDL_stdinc.h
new file mode 100644
index 00000000000..a67bcaccb9f
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_stdinc.h
@@ -0,0 +1,378 @@
+
+#ifndef _SDL_stdinc_h
+#define _SDL_stdinc_h
+
+#include "SDL_config.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if defined(STDC_HEADERS)
+# include <stdlib.h>
+# include <stddef.h>
+# include <stdarg.h>
+#else
+# if defined(HAVE_STDLIB_H)
+# include <stdlib.h>
+# elif defined(HAVE_MALLOC_H)
+# include <malloc.h>
+# endif
+# if defined(HAVE_STDDEF_H)
+# include <stddef.h>
+# endif
+# if defined(HAVE_STDARG_H)
+# include <stdarg.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+# include <stdint.h>
+#endif
+#ifdef HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+#ifdef HAVE_MATH_H
+# include <math.h>
+#endif
+#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H)
+# include <iconv.h>
+#endif
+
+#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0]))
+#define SDL_TABLESIZE(table) SDL_arraysize(table)
+
+#ifdef __cplusplus
+#define SDL_reinterpret_cast(type, expression) reinterpret_cast<type>(expression)
+#define SDL_static_cast(type, expression) static_cast<type>(expression)
+#define SDL_const_cast(type, expression) const_cast<type>(expression)
+#else
+#define SDL_reinterpret_cast(type, expression) ((type)(expression))
+#define SDL_static_cast(type, expression) ((type)(expression))
+#define SDL_const_cast(type, expression) ((type)(expression))
+#endif
+
+#define SDL_FOURCC(A, B, C, D) \
+ ((SDL_static_cast(Uint32, SDL_static_cast(Uint8, (A))) << 0) | \
+ (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (B))) << 8) | \
+ (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (C))) << 16) | \
+ (SDL_static_cast(Uint32, SDL_static_cast(Uint8, (D))) << 24))
+
+typedef enum
+{
+ SDL_FALSE = 0,
+ SDL_TRUE = 1
+} SDL_bool;
+
+typedef int8_t Sint8;
+
+typedef uint8_t Uint8;
+
+typedef int16_t Sint16;
+
+typedef uint16_t Uint16;
+
+typedef int32_t Sint32;
+
+typedef uint32_t Uint32;
+
+typedef int64_t Sint64;
+
+typedef uint64_t Uint64;
+
+#define SDL_COMPILE_TIME_ASSERT(name, x) \
+ typedef int SDL_dummy_ ## name[(x) * 2 - 1]
+
+#ifndef DOXYGEN_SHOULD_IGNORE_THIS
+SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1);
+SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1);
+SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2);
+SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2);
+SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4);
+SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4);
+SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8);
+SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8);
+#endif
+
+#ifndef DOXYGEN_SHOULD_IGNORE_THIS
+#if !defined(__ANDROID__)
+
+typedef enum
+{
+ DUMMY_ENUM_VALUE
+} SDL_DUMMY_ENUM;
+
+SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int));
+#endif
+#endif
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(HAVE_ALLOCA) && !defined(alloca)
+# if defined(HAVE_ALLOCA_H)
+# include <alloca.h>
+# elif defined(__GNUC__)
+# define alloca __builtin_alloca
+# elif defined(_MSC_VER)
+# include <malloc.h>
+# define alloca _alloca
+# elif defined(__WATCOMC__)
+# include <malloc.h>
+# elif defined(__BORLANDC__)
+# include <malloc.h>
+# elif defined(__DMC__)
+# include <stdlib.h>
+# elif defined(__AIX__)
+#pragma alloca
+# elif defined(__MRC__)
+void *alloca(unsigned);
+# else
+char *alloca();
+# endif
+#endif
+#ifdef HAVE_ALLOCA
+#define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count))
+#define SDL_stack_free(data)
+#else
+#define SDL_stack_alloc(type, count) (type*)SDL_malloc(sizeof(type)*(count))
+#define SDL_stack_free(data) SDL_free(data)
+#endif
+
+typedef void * SDLCALL tSDL_malloc(size_t size);
+typedef void * SDLCALL tSDL_calloc(size_t nmemb, size_t size);
+typedef void * SDLCALL tSDL_realloc(void *mem, size_t size);
+typedef void SDLCALL tSDL_free(void *mem);
+
+typedef char * SDLCALL tSDL_getenv(const char *name);
+typedef int SDLCALL tSDL_setenv(const char *name, const char *value, int overwrite);
+
+typedef void SDLCALL tSDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *));
+
+typedef int SDLCALL tSDL_abs(int x);
+
+#define SDL_min(x, y) (((x) < (y)) ? (x) : (y))
+#define SDL_max(x, y) (((x) > (y)) ? (x) : (y))
+
+typedef int SDLCALL tSDL_isdigit(int x);
+typedef int SDLCALL tSDL_isspace(int x);
+typedef int SDLCALL tSDL_toupper(int x);
+typedef int SDLCALL tSDL_tolower(int x);
+
+typedef void * SDLCALL tSDL_memset(void *dst, int c, size_t len);
+
+#define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x)))
+#define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x)))
+
+SDL_FORCE_INLINE void SDL_memset4(void *dst, int val, size_t dwords)
+{
+#if defined(__GNUC__) && defined(i386)
+ int u0, u1, u2;
+ __asm__ __volatile__ (
+ "cld \n\t"
+ "rep ; stosl \n\t"
+ : "=&D" (u0), "=&a" (u1), "=&c" (u2)
+ : "0" (dst), "1" (val), "2" (SDL_static_cast(Uint32, dwords))
+ : "memory"
+ );
+#else
+ size_t _n = (dwords + 3) / 4;
+ Uint32 *_p = SDL_static_cast(Uint32 *, dst);
+ Uint32 _val = (val);
+ if (dwords == 0)
+ return;
+ switch (dwords % 4)
+ {
+ case 0: do { *_p++ = _val;
+ case 3: *_p++ = _val;
+ case 2: *_p++ = _val;
+ case 1: *_p++ = _val;
+ } while ( --_n );
+ }
+#endif
+}
+
+typedef void * SDLCALL tSDL_memcpy(void *dst, const void *src, size_t len);
+
+extern tSDL_memcpy *SDL_memcpy;
+SDL_FORCE_INLINE void *SDL_memcpy4(void *dst, const void *src, size_t dwords)
+{
+ return SDL_memcpy(dst, src, dwords * 4);
+}
+
+typedef void * SDLCALL tSDL_memmove(void *dst, const void *src, size_t len);
+typedef int SDLCALL tSDL_memcmp(const void *s1, const void *s2, size_t len);
+
+typedef size_t SDLCALL tSDL_wcslen(const wchar_t *wstr);
+typedef size_t SDLCALL tSDL_wcslcpy(wchar_t *dst, const wchar_t *src, size_t maxlen);
+typedef size_t SDLCALL tSDL_wcslcat(wchar_t *dst, const wchar_t *src, size_t maxlen);
+
+typedef size_t SDLCALL tSDL_strlen(const char *str);
+typedef size_t SDLCALL tSDL_strlcpy(char *dst, const char *src, size_t maxlen);
+typedef size_t SDLCALL tSDL_utf8strlcpy(char *dst, const char *src, size_t dst_bytes);
+typedef size_t SDLCALL tSDL_strlcat(char *dst, const char *src, size_t maxlen);
+typedef char * SDLCALL tSDL_strdup(const char *str);
+typedef char * SDLCALL tSDL_strrev(char *str);
+typedef char * SDLCALL tSDL_strupr(char *str);
+typedef char * SDLCALL tSDL_strlwr(char *str);
+typedef char * SDLCALL tSDL_strchr(const char *str, int c);
+typedef char * SDLCALL tSDL_strrchr(const char *str, int c);
+typedef char * SDLCALL tSDL_strstr(const char *haystack, const char *needle);
+
+typedef char * SDLCALL tSDL_itoa(int value, char *str, int radix);
+typedef char * SDLCALL tSDL_uitoa(unsigned int value, char *str, int radix);
+typedef char * SDLCALL tSDL_ltoa(long value, char *str, int radix);
+typedef char * SDLCALL tSDL_ultoa(unsigned long value, char *str, int radix);
+typedef char * SDLCALL tSDL_lltoa(Sint64 value, char *str, int radix);
+typedef char * SDLCALL tSDL_ulltoa(Uint64 value, char *str, int radix);
+
+typedef int SDLCALL tSDL_atoi(const char *str);
+typedef double SDLCALL tSDL_atof(const char *str);
+typedef long SDLCALL tSDL_strtol(const char *str, char **endp, int base);
+extern DECLSPEC unsigned long SDLCALL SDL_strtoul(const char *str, char **endp, int base);
+typedef Sint64 SDLCALL tSDL_strtoll(const char *str, char **endp, int base);
+typedef Uint64 SDLCALL tSDL_strtoull(const char *str, char **endp, int base);
+typedef double SDLCALL tSDL_strtod(const char *str, char **endp);
+
+typedef int SDLCALL tSDL_strcmp(const char *str1, const char *str2);
+typedef int SDLCALL tSDL_strncmp(const char *str1, const char *str2, size_t maxlen);
+typedef int SDLCALL tSDL_strcasecmp(const char *str1, const char *str2);
+typedef int SDLCALL tSDL_strncasecmp(const char *str1, const char *str2, size_t len);
+
+typedef int SDLCALL tSDL_sscanf(const char *text, const char *fmt, ...);
+typedef int SDLCALL tSDL_snprintf(char *text, size_t maxlen, const char *fmt, ...);
+typedef int SDLCALL tSDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap);
+
+#ifndef HAVE_M_PI
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338327950288
+#endif
+#endif
+
+typedef double SDLCALL tSDL_atan(double x);
+typedef double SDLCALL tSDL_atan2(double x, double y);
+typedef double SDLCALL tSDL_ceil(double x);
+typedef double SDLCALL tSDL_copysign(double x, double y);
+typedef double SDLCALL tSDL_cos(double x);
+typedef float SDLCALL tSDL_cosf(float x);
+typedef double SDLCALL tSDL_fabs(double x);
+typedef double SDLCALL tSDL_floor(double x);
+typedef double SDLCALL tSDL_log(double x);
+typedef double SDLCALL tSDL_pow(double x, double y);
+typedef double SDLCALL tSDL_scalbn(double x, int n);
+typedef double SDLCALL tSDL_sin(double x);
+typedef float SDLCALL tSDL_sinf(float x);
+typedef double SDLCALL tSDL_sqrt(double x);
+
+#define SDL_ICONV_ERROR (size_t)-1
+#define SDL_ICONV_E2BIG (size_t)-2
+#define SDL_ICONV_EILSEQ (size_t)-3
+#define SDL_ICONV_EINVAL (size_t)-4
+
+typedef struct _SDL_iconv_t *SDL_iconv_t;
+typedef SDL_iconv_t SDLCALL tSDL_iconv_open(const char *tocode,
+ const char *fromcode);
+typedef int SDLCALL tSDL_iconv_close(SDL_iconv_t cd);
+typedef size_t SDLCALL tSDL_iconv(SDL_iconv_t cd, const char **inbuf,
+ size_t * inbytesleft, char **outbuf,
+ size_t * outbytesleft);
+
+typedef char * SDLCALL tSDL_iconv_string(const char *tocode,
+ const char *fromcode,
+ const char *inbuf,
+ size_t inbytesleft);
+#define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1)
+#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2-INTERNAL", "UTF-8", S, SDL_strlen(S)+1)
+#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4-INTERNAL", "UTF-8", S, SDL_strlen(S)+1)
+
+#ifndef HAVE_ALLOCA
+extern tSDL_malloc *SDL_malloc;
+#endif
+extern tSDL_calloc *SDL_calloc;
+extern tSDL_realloc *SDL_realloc;
+extern tSDL_free *SDL_free;
+extern tSDL_getenv *SDL_getenv;
+extern tSDL_setenv *SDL_setenv;
+extern tSDL_qsort *SDL_qsort;
+extern tSDL_abs *SDL_abs;
+extern tSDL_isdigit *SDL_isdigit;
+extern tSDL_isspace *SDL_isspace;
+extern tSDL_toupper *SDL_toupper;
+extern tSDL_tolower *SDL_tolower;
+extern tSDL_memset *SDL_memset;
+extern tSDL_memmove *SDL_memmove;
+extern tSDL_memcmp *SDL_memcmp;
+extern tSDL_wcslen *SDL_wcslen;
+extern tSDL_wcslcpy *SDL_wcslcpy;
+extern tSDL_wcslcat *SDL_wcslcat;
+extern tSDL_strlen *SDL_strlen;
+extern tSDL_strlcpy *SDL_strlcpy;
+extern tSDL_utf8strlcpy *SDL_utf8strlcpy;
+extern tSDL_strlcat *SDL_strlcat;
+extern tSDL_strdup *SDL_strdup;
+extern tSDL_strrev *SDL_strrev;
+extern tSDL_strupr *SDL_strupr;
+extern tSDL_strlwr *SDL_strlwr;
+extern tSDL_strchr *SDL_strchr;
+extern tSDL_strrchr *SDL_strrchr;
+extern tSDL_strstr *SDL_strstr;
+extern tSDL_itoa *SDL_itoa;
+extern tSDL_uitoa *SDL_uitoa;
+extern tSDL_ltoa *SDL_ltoa;
+extern tSDL_ultoa *SDL_ultoa;
+extern tSDL_lltoa *SDL_lltoa;
+extern tSDL_ulltoa *SDL_ulltoa;
+extern tSDL_atoi *SDL_atoi;
+extern tSDL_atof *SDL_atof;
+extern tSDL_strtol *SDL_strtol;
+extern tSDL_strtoll *SDL_strtoll;
+extern tSDL_strtoull *SDL_strtoull;
+extern tSDL_strtod *SDL_strtod;
+extern tSDL_strcmp *SDL_strcmp;
+extern tSDL_strncmp *SDL_strncmp;
+extern tSDL_strcasecmp *SDL_strcasecmp;
+extern tSDL_strncasecmp *SDL_strncasecmp;
+extern tSDL_sscanf *SDL_sscanf;
+extern tSDL_snprintf *SDL_snprintf;
+extern tSDL_vsnprintf *SDL_vsnprintf;
+extern tSDL_atan *SDL_atan;
+extern tSDL_atan2 *SDL_atan2;
+extern tSDL_ceil *SDL_ceil;
+extern tSDL_copysign *SDL_copysign;
+extern tSDL_cos *SDL_cos;
+extern tSDL_cosf *SDL_cosf;
+extern tSDL_fabs *SDL_fabs;
+extern tSDL_floor *SDL_floor;
+extern tSDL_log *SDL_log;
+extern tSDL_pow *SDL_pow;
+extern tSDL_scalbn *SDL_scalbn;
+extern tSDL_sin *SDL_sin;
+extern tSDL_sinf *SDL_sinf;
+extern tSDL_sqrt *SDL_sqrt;
+extern tSDL_iconv_open *SDL_iconv_open;
+extern tSDL_iconv_close *SDL_iconv_close;
+extern tSDL_iconv *SDL_iconv;
+extern tSDL_iconv_string *SDL_iconv_string;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_surface.h b/extern/sdlew/include/SDL2/SDL_surface.h
new file mode 100644
index 00000000000..5125eee4402
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_surface.h
@@ -0,0 +1,190 @@
+
+#ifndef _SDL_surface_h
+#define _SDL_surface_h
+
+#include "SDL_stdinc.h"
+#include "SDL_pixels.h"
+#include "SDL_rect.h"
+#include "SDL_blendmode.h"
+#include "SDL_rwops.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDL_SWSURFACE 0
+#define SDL_PREALLOC 0x00000001
+#define SDL_RLEACCEL 0x00000002
+#define SDL_DONTFREE 0x00000004
+
+#define SDL_MUSTLOCK(S) (((S)->flags & SDL_RLEACCEL) != 0)
+
+typedef struct SDL_Surface
+{
+ Uint32 flags;
+ SDL_PixelFormat *format;
+ int w, h;
+ int pitch;
+ void *pixels;
+
+ void *userdata;
+
+ int locked;
+ void *lock_data;
+
+ SDL_Rect clip_rect;
+
+ struct SDL_BlitMap *map;
+
+ int refcount;
+} SDL_Surface;
+
+typedef int (*SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect,
+ struct SDL_Surface * dst, SDL_Rect * dstrect);
+
+typedef SDL_Surface * SDLCALL tSDL_CreateRGBSurface
+ (Uint32 flags, int width, int height, int depth,
+ Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
+typedef SDL_Surface * SDLCALL tSDL_CreateRGBSurfaceFrom(void *pixels,
+ int width,
+ int height,
+ int depth,
+ int pitch,
+ Uint32 Rmask,
+ Uint32 Gmask,
+ Uint32 Bmask,
+ Uint32 Amask);
+typedef void SDLCALL tSDL_FreeSurface(SDL_Surface * surface);
+
+typedef int SDLCALL tSDL_SetSurfacePalette(SDL_Surface * surface,
+ SDL_Palette * palette);
+
+typedef int SDLCALL tSDL_LockSurface(SDL_Surface * surface);
+
+typedef void SDLCALL tSDL_UnlockSurface(SDL_Surface * surface);
+
+typedef SDL_Surface * SDLCALL tSDL_LoadBMP_RW(SDL_RWops * src,
+ int freesrc);
+
+#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1)
+
+typedef int SDLCALL tSDL_SaveBMP_RW
+ (SDL_Surface * surface, SDL_RWops * dst, int freedst);
+
+#define SDL_SaveBMP(surface, file) \
+ SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1)
+
+typedef int SDLCALL tSDL_SetSurfaceRLE(SDL_Surface * surface,
+ int flag);
+
+typedef int SDLCALL tSDL_SetColorKey(SDL_Surface * surface,
+ int flag, Uint32 key);
+
+typedef int SDLCALL tSDL_GetColorKey(SDL_Surface * surface,
+ Uint32 * key);
+
+typedef int SDLCALL tSDL_SetSurfaceColorMod(SDL_Surface * surface,
+ Uint8 r, Uint8 g, Uint8 b);
+
+typedef int SDLCALL tSDL_GetSurfaceColorMod(SDL_Surface * surface,
+ Uint8 * r, Uint8 * g,
+ Uint8 * b);
+
+typedef int SDLCALL tSDL_SetSurfaceAlphaMod(SDL_Surface * surface,
+ Uint8 alpha);
+
+typedef int SDLCALL tSDL_GetSurfaceAlphaMod(SDL_Surface * surface,
+ Uint8 * alpha);
+
+typedef int SDLCALL tSDL_SetSurfaceBlendMode(SDL_Surface * surface,
+ SDL_BlendMode blendMode);
+
+typedef int SDLCALL tSDL_GetSurfaceBlendMode(SDL_Surface * surface,
+ SDL_BlendMode *blendMode);
+
+typedef SDL_bool SDLCALL tSDL_SetClipRect(SDL_Surface * surface,
+ const SDL_Rect * rect);
+
+typedef void SDLCALL tSDL_GetClipRect(SDL_Surface * surface,
+ SDL_Rect * rect);
+
+typedef SDL_Surface * SDLCALL tSDL_ConvertSurface
+ (SDL_Surface * src, SDL_PixelFormat * fmt, Uint32 flags);
+typedef SDL_Surface * SDLCALL tSDL_ConvertSurfaceFormat
+ (SDL_Surface * src, Uint32 pixel_format, Uint32 flags);
+
+typedef int SDLCALL tSDL_ConvertPixels(int width, int height,
+ Uint32 src_format,
+ const void * src, int src_pitch,
+ Uint32 dst_format,
+ void * dst, int dst_pitch);
+
+typedef int SDLCALL tSDL_FillRect
+ (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color);
+typedef int SDLCALL tSDL_FillRects
+ (SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color);
+
+#define SDL_BlitSurface SDL_UpperBlit
+
+typedef int SDLCALL tSDL_UpperBlit
+ (SDL_Surface * src, const SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect);
+
+typedef int SDLCALL tSDL_LowerBlit
+ (SDL_Surface * src, SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect);
+
+typedef int SDLCALL tSDL_SoftStretch(SDL_Surface * src,
+ const SDL_Rect * srcrect,
+ SDL_Surface * dst,
+ const SDL_Rect * dstrect);
+
+#define SDL_BlitScaled SDL_UpperBlitScaled
+
+typedef int SDLCALL tSDL_UpperBlitScaled
+ (SDL_Surface * src, const SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect);
+
+typedef int SDLCALL tSDL_LowerBlitScaled
+ (SDL_Surface * src, SDL_Rect * srcrect,
+ SDL_Surface * dst, SDL_Rect * dstrect);
+
+extern tSDL_CreateRGBSurface *SDL_CreateRGBSurface;
+extern tSDL_CreateRGBSurfaceFrom *SDL_CreateRGBSurfaceFrom;
+extern tSDL_FreeSurface *SDL_FreeSurface;
+extern tSDL_SetSurfacePalette *SDL_SetSurfacePalette;
+extern tSDL_LockSurface *SDL_LockSurface;
+extern tSDL_UnlockSurface *SDL_UnlockSurface;
+extern tSDL_LoadBMP_RW *SDL_LoadBMP_RW;
+extern tSDL_SaveBMP_RW *SDL_SaveBMP_RW;
+extern tSDL_SetSurfaceRLE *SDL_SetSurfaceRLE;
+extern tSDL_SetColorKey *SDL_SetColorKey;
+extern tSDL_GetColorKey *SDL_GetColorKey;
+extern tSDL_SetSurfaceColorMod *SDL_SetSurfaceColorMod;
+extern tSDL_GetSurfaceColorMod *SDL_GetSurfaceColorMod;
+extern tSDL_SetSurfaceAlphaMod *SDL_SetSurfaceAlphaMod;
+extern tSDL_GetSurfaceAlphaMod *SDL_GetSurfaceAlphaMod;
+extern tSDL_SetSurfaceBlendMode *SDL_SetSurfaceBlendMode;
+extern tSDL_GetSurfaceBlendMode *SDL_GetSurfaceBlendMode;
+extern tSDL_SetClipRect *SDL_SetClipRect;
+extern tSDL_GetClipRect *SDL_GetClipRect;
+extern tSDL_ConvertSurface *SDL_ConvertSurface;
+extern tSDL_ConvertSurfaceFormat *SDL_ConvertSurfaceFormat;
+extern tSDL_ConvertPixels *SDL_ConvertPixels;
+extern tSDL_FillRect *SDL_FillRect;
+extern tSDL_FillRects *SDL_FillRects;
+extern tSDL_UpperBlit *SDL_UpperBlit;
+extern tSDL_LowerBlit *SDL_LowerBlit;
+extern tSDL_SoftStretch *SDL_SoftStretch;
+extern tSDL_UpperBlitScaled *SDL_UpperBlitScaled;
+extern tSDL_LowerBlitScaled *SDL_LowerBlitScaled;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_system.h b/extern/sdlew/include/SDL2/SDL_system.h
new file mode 100644
index 00000000000..57fbb4d08e2
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_system.h
@@ -0,0 +1,48 @@
+
+#ifndef _SDL_system_h
+#define _SDL_system_h
+
+#include "SDL_stdinc.h"
+
+#if defined(__IPHONEOS__) && __IPHONEOS__
+#include "SDL_video.h"
+#include "SDL_keyboard.h"
+#endif
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__IPHONEOS__) && __IPHONEOS__
+
+typedef int SDLCALL tSDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam);
+typedef void SDLCALL tSDL_iPhoneSetEventPump(SDL_bool enabled);
+
+#endif
+
+#if defined(__ANDROID__) && __ANDROID__
+
+typedef void * SDLCALL tSDL_AndroidGetJNIEnv();
+
+typedef void * SDLCALL tSDL_AndroidGetActivity();
+
+#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01
+#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02
+
+typedef const char * SDLCALL tSDL_AndroidGetInternalStoragePath();
+
+typedef int SDLCALL tSDL_AndroidGetExternalStorageState();
+
+typedef const char * SDLCALL tSDL_AndroidGetExternalStoragePath();
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_syswm.h b/extern/sdlew/include/SDL2/SDL_syswm.h
new file mode 100644
index 00000000000..7c4bc3188bc
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_syswm.h
@@ -0,0 +1,171 @@
+
+#ifndef _SDL_syswm_h
+#define _SDL_syswm_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_video.h"
+#include "SDL_version.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SDL_PROTOTYPES_ONLY
+struct SDL_SysWMinfo;
+#else
+
+#if defined(SDL_VIDEO_DRIVER_WINDOWS)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#if defined(SDL_VIDEO_DRIVER_X11)
+#if defined(__APPLE__) && defined(__MACH__)
+
+#define Cursor X11Cursor
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#if defined(__APPLE__) && defined(__MACH__)
+
+#undef Cursor
+#endif
+
+#endif
+
+#if defined(SDL_VIDEO_DRIVER_DIRECTFB)
+#include <directfb.h>
+#endif
+
+#if defined(SDL_VIDEO_DRIVER_COCOA)
+#ifdef __OBJC__
+#include <Cocoa/Cocoa.h>
+#else
+typedef struct _NSWindow NSWindow;
+#endif
+#endif
+
+#if defined(SDL_VIDEO_DRIVER_UIKIT)
+#ifdef __OBJC__
+#include <UIKit/UIKit.h>
+#else
+typedef struct _UIWindow UIWindow;
+#endif
+#endif
+
+typedef enum
+{
+ SDL_SYSWM_UNKNOWN,
+ SDL_SYSWM_WINDOWS,
+ SDL_SYSWM_X11,
+ SDL_SYSWM_DIRECTFB,
+ SDL_SYSWM_COCOA,
+ SDL_SYSWM_UIKIT,
+} SDL_SYSWM_TYPE;
+
+struct SDL_SysWMmsg
+{
+ SDL_version version;
+ SDL_SYSWM_TYPE subsystem;
+ union
+ {
+#if defined(SDL_VIDEO_DRIVER_WINDOWS)
+ struct {
+ HWND hwnd;
+ UINT msg;
+ WPARAM wParam;
+ LPARAM lParam;
+ } win;
+#endif
+#if defined(SDL_VIDEO_DRIVER_X11)
+ struct {
+ XEvent event;
+ } x11;
+#endif
+#if defined(SDL_VIDEO_DRIVER_DIRECTFB)
+ struct {
+ DFBEvent event;
+ } dfb;
+#endif
+#if defined(SDL_VIDEO_DRIVER_COCOA)
+ struct
+ {
+
+ } cocoa;
+#endif
+#if defined(SDL_VIDEO_DRIVER_UIKIT)
+ struct
+ {
+
+ } uikit;
+#endif
+
+ int dummy;
+ } msg;
+};
+
+struct SDL_SysWMinfo
+{
+ SDL_version version;
+ SDL_SYSWM_TYPE subsystem;
+ union
+ {
+#if defined(SDL_VIDEO_DRIVER_WINDOWS)
+ struct
+ {
+ HWND window;
+ } win;
+#endif
+#if defined(SDL_VIDEO_DRIVER_X11)
+ struct
+ {
+ Display *display;
+ Window window;
+ } x11;
+#endif
+#if defined(SDL_VIDEO_DRIVER_DIRECTFB)
+ struct
+ {
+ IDirectFB *dfb;
+ IDirectFBWindow *window;
+ IDirectFBSurface *surface;
+ } dfb;
+#endif
+#if defined(SDL_VIDEO_DRIVER_COCOA)
+ struct
+ {
+ NSWindow *window;
+ } cocoa;
+#endif
+#if defined(SDL_VIDEO_DRIVER_UIKIT)
+ struct
+ {
+ UIWindow *window;
+ } uikit;
+#endif
+
+ int dummy;
+ } info;
+};
+
+#endif
+
+typedef struct SDL_SysWMinfo SDL_SysWMinfo;
+
+typedef SDL_bool SDLCALL tSDL_GetWindowWMInfo(SDL_Window * window,
+ SDL_SysWMinfo * info);
+
+extern tSDL_GetWindowWMInfo *SDL_GetWindowWMInfo;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test.h b/extern/sdlew/include/SDL2/SDL_test.h
new file mode 100644
index 00000000000..b2032dae5e4
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test.h
@@ -0,0 +1,32 @@
+
+#ifndef _SDL_test_h
+#define _SDL_test_h
+
+#include "SDL.h"
+#include "SDL_test_common.h"
+#include "SDL_test_font.h"
+#include "SDL_test_random.h"
+#include "SDL_test_fuzzer.h"
+#include "SDL_test_crc32.h"
+#include "SDL_test_md5.h"
+#include "SDL_test_log.h"
+#include "SDL_test_assert.h"
+#include "SDL_test_harness.h"
+#include "SDL_test_images.h"
+#include "SDL_test_compare.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDLTEST_MAX_LOGMESSAGE_LENGTH 3584
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_assert.h b/extern/sdlew/include/SDL2/SDL_test_assert.h
new file mode 100644
index 00000000000..2c91c422ed1
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_assert.h
@@ -0,0 +1,33 @@
+
+#ifndef _SDL_test_assert_h
+#define _SDL_test_assert_h
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ASSERT_FAIL 0
+
+#define ASSERT_PASS 1
+
+void SDLTest_Assert(int assertCondition, const char *assertDescription, ...);
+
+int SDLTest_AssertCheck(int assertCondition, const char *assertDescription, ...);
+
+void SDLTest_AssertPass(const char *assertDescription, ...);
+
+void SDLTest_ResetAssertSummary();
+
+void SDLTest_LogAssertSummary();
+
+int SDLTest_AssertSummaryToTestResult();
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_common.h b/extern/sdlew/include/SDL2/SDL_test_common.h
new file mode 100644
index 00000000000..53b455eec90
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_common.h
@@ -0,0 +1,103 @@
+
+#ifndef _SDL_test_common_h
+#define _SDL_test_common_h
+
+#include "SDL.h"
+
+#if defined(__PSP__)
+#define DEFAULT_WINDOW_WIDTH 480
+#define DEFAULT_WINDOW_HEIGHT 272
+#else
+#define DEFAULT_WINDOW_WIDTH 640
+#define DEFAULT_WINDOW_HEIGHT 480
+#endif
+
+#define VERBOSE_VIDEO 0x00000001
+#define VERBOSE_MODES 0x00000002
+#define VERBOSE_RENDER 0x00000004
+#define VERBOSE_EVENT 0x00000008
+#define VERBOSE_AUDIO 0x00000010
+
+typedef struct
+{
+
+ char **argv;
+ Uint32 flags;
+ Uint32 verbose;
+
+ const char *videodriver;
+ int display;
+ const char *window_title;
+ const char *window_icon;
+ Uint32 window_flags;
+ int window_x;
+ int window_y;
+ int window_w;
+ int window_h;
+ int window_minW;
+ int window_minH;
+ int window_maxW;
+ int window_maxH;
+ int logical_w;
+ int logical_h;
+ float scale;
+ int depth;
+ int refresh_rate;
+ int num_windows;
+ SDL_Window **windows;
+
+ const char *renderdriver;
+ Uint32 render_flags;
+ SDL_bool skip_renderer;
+ SDL_Renderer **renderers;
+
+ const char *audiodriver;
+ SDL_AudioSpec audiospec;
+
+ int gl_red_size;
+ int gl_green_size;
+ int gl_blue_size;
+ int gl_alpha_size;
+ int gl_buffer_size;
+ int gl_depth_size;
+ int gl_stencil_size;
+ int gl_double_buffer;
+ int gl_accum_red_size;
+ int gl_accum_green_size;
+ int gl_accum_blue_size;
+ int gl_accum_alpha_size;
+ int gl_stereo;
+ int gl_multisamplebuffers;
+ int gl_multisamplesamples;
+ int gl_retained_backing;
+ int gl_accelerated;
+ int gl_major_version;
+ int gl_minor_version;
+ int gl_debug;
+} SDLTest_CommonState;
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, Uint32 flags);
+
+int SDLTest_CommonArg(SDLTest_CommonState * state, int index);
+
+const char *SDLTest_CommonUsage(SDLTest_CommonState * state);
+
+SDL_bool SDLTest_CommonInit(SDLTest_CommonState * state);
+
+void SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done);
+
+void SDLTest_CommonQuit(SDLTest_CommonState * state);
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_compare.h b/extern/sdlew/include/SDL2/SDL_test_compare.h
new file mode 100644
index 00000000000..fc3536f5a10
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_compare.h
@@ -0,0 +1,23 @@
+
+#ifndef _SDL_test_compare_h
+#define _SDL_test_compare_h
+
+#include "SDL.h"
+
+#include "SDL_test_images.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error);
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_crc32.h b/extern/sdlew/include/SDL2/SDL_test_crc32.h
new file mode 100644
index 00000000000..31d76b51616
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_crc32.h
@@ -0,0 +1,44 @@
+
+#ifndef _SDL_test_crc32_h
+#define _SDL_test_crc32_h
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CrcUint32
+ #define CrcUint32 unsigned int
+#endif
+#ifndef CrcUint8
+ #define CrcUint8 unsigned char
+#endif
+
+#ifdef ORIGINAL_METHOD
+ #define CRC32_POLY 0x04c11db7
+#else
+ #define CRC32_POLY 0xEDB88320
+#endif
+
+ typedef struct {
+ CrcUint32 crc32_table[256];
+ } SDLTest_Crc32Context;
+
+ int SDLTest_Crc32Init(SDLTest_Crc32Context * crcContext);
+
+int SDLTest_crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32);
+
+int SDLTest_Crc32CalcStart(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32);
+int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32);
+int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32);
+
+int SDLTest_Crc32Done(SDLTest_Crc32Context * crcContext);
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_font.h b/extern/sdlew/include/SDL2/SDL_test_font.h
new file mode 100644
index 00000000000..b016486b649
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_font.h
@@ -0,0 +1,19 @@
+
+#ifndef _SDL_test_font_h
+#define _SDL_test_font_h
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int SDLTest_DrawString(SDL_Renderer * renderer, int x, int y, const char *s);
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_fuzzer.h b/extern/sdlew/include/SDL2/SDL_test_fuzzer.h
new file mode 100644
index 00000000000..6935affc963
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_fuzzer.h
@@ -0,0 +1,69 @@
+
+#ifndef _SDL_test_fuzzer_h
+#define _SDL_test_fuzzer_h
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void SDLTest_FuzzerInit(Uint64 execKey);
+
+Uint8 SDLTest_RandomUint8();
+
+Sint8 SDLTest_RandomSint8();
+
+Uint16 SDLTest_RandomUint16();
+
+Sint16 SDLTest_RandomSint16();
+
+Sint32 SDLTest_RandomSint32();
+
+Uint32 SDLTest_RandomUint32();
+
+Uint64 SDLTest_RandomUint64();
+
+Sint64 SDLTest_RandomSint64();
+
+float SDLTest_RandomUnitFloat();
+
+double SDLTest_RandomUnitDouble();
+
+float SDLTest_RandomFloat();
+
+double SDLTest_RandomDouble();
+
+Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain);
+
+Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain);
+
+Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain);
+
+Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain);
+
+Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain);
+
+Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain);
+
+Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain);
+
+Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain);
+
+Sint32 SDLTest_RandomIntegerInRange(Sint32 min, Sint32 max);
+
+char * SDLTest_RandomAsciiString();
+
+char * SDLTest_RandomAsciiStringWithMaximumLength(int maxLength);
+
+char * SDLTest_RandomAsciiStringOfSize(int size);
+
+int SDLTest_GetFuzzerInvocationCount();
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_harness.h b/extern/sdlew/include/SDL2/SDL_test_harness.h
new file mode 100644
index 00000000000..4ec6dc45a81
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_harness.h
@@ -0,0 +1,67 @@
+
+#ifndef _SDL_test_harness_h
+#define _SDL_test_harness_h
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//! Definitions for test case structures
+#define TEST_ENABLED 1
+#define TEST_DISABLED 0
+
+//! Definition of all the possible test return values of the test case method
+#define TEST_ABORTED -1
+#define TEST_STARTED 0
+#define TEST_COMPLETED 1
+#define TEST_SKIPPED 2
+
+//! Definition of all the possible test results for the harness
+#define TEST_RESULT_PASSED 0
+#define TEST_RESULT_FAILED 1
+#define TEST_RESULT_NO_ASSERT 2
+#define TEST_RESULT_SKIPPED 3
+#define TEST_RESULT_SETUP_FAILURE 4
+
+//!< Function pointer to a test case setup function (run before every test)
+typedef void (*SDLTest_TestCaseSetUpFp)(void *arg);
+
+//!< Function pointer to a test case function
+typedef int (*SDLTest_TestCaseFp)(void *arg);
+
+//!< Function pointer to a test case teardown function (run after every test)
+typedef void (*SDLTest_TestCaseTearDownFp)(void *arg);
+
+typedef struct SDLTest_TestCaseReference {
+
+ SDLTest_TestCaseFp testCase;
+
+ char *name;
+
+ char *description;
+
+ int enabled;
+} SDLTest_TestCaseReference;
+
+typedef struct SDLTest_TestSuiteReference {
+
+ char *name;
+
+ SDLTest_TestCaseSetUpFp testSetUp;
+
+ const SDLTest_TestCaseReference **testCases;
+
+ SDLTest_TestCaseTearDownFp testTearDown;
+} SDLTest_TestSuiteReference;
+
+int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *userRunSeed, Uint64 userExecKey, const char *filter, int testIterations);
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_images.h b/extern/sdlew/include/SDL2/SDL_test_images.h
new file mode 100644
index 00000000000..545dd186078
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_images.h
@@ -0,0 +1,38 @@
+
+#ifndef _SDL_test_images_h
+#define _SDL_test_images_h
+
+#include "SDL.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SDLTest_SurfaceImage_s {
+ int width;
+ int height;
+ unsigned int bytes_per_pixel;
+ const char *pixel_data;
+} SDLTest_SurfaceImage_t;
+
+SDL_Surface *SDLTest_ImageBlit();
+SDL_Surface *SDLTest_ImageBlitColor();
+SDL_Surface *SDLTest_ImageBlitAlpha();
+SDL_Surface *SDLTest_ImageBlitBlendAdd();
+SDL_Surface *SDLTest_ImageBlitBlend();
+SDL_Surface *SDLTest_ImageBlitBlendMod();
+SDL_Surface *SDLTest_ImageBlitBlendNone();
+SDL_Surface *SDLTest_ImageBlitBlendAll();
+SDL_Surface *SDLTest_ImageFace();
+SDL_Surface *SDLTest_ImagePrimitives();
+SDL_Surface *SDLTest_ImagePrimitivesBlend();
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_log.h b/extern/sdlew/include/SDL2/SDL_test_log.h
new file mode 100644
index 00000000000..084942a5774
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_log.h
@@ -0,0 +1,21 @@
+
+#ifndef _SDL_test_log_h
+#define _SDL_test_log_h
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void SDLTest_Log(const char *fmt, ...);
+
+void SDLTest_LogError(const char *fmt, ...);
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_md5.h b/extern/sdlew/include/SDL2/SDL_test_md5.h
new file mode 100644
index 00000000000..9e149cc1f65
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_md5.h
@@ -0,0 +1,33 @@
+
+#ifndef _SDL_test_md5_h
+#define _SDL_test_md5_h
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef unsigned long int MD5UINT4;
+
+ typedef struct {
+ MD5UINT4 i[2];
+ MD5UINT4 buf[4];
+ unsigned char in[64];
+ unsigned char digest[16];
+ } SDLTest_Md5Context;
+
+ void SDLTest_Md5Init(SDLTest_Md5Context * mdContext);
+
+ void SDLTest_Md5Update(SDLTest_Md5Context * mdContext, unsigned char *inBuf,
+ unsigned int inLen);
+
+ void SDLTest_Md5Final(SDLTest_Md5Context * mdContext);
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_test_random.h b/extern/sdlew/include/SDL2/SDL_test_random.h
new file mode 100644
index 00000000000..61a0c1b7a09
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_test_random.h
@@ -0,0 +1,34 @@
+
+#ifndef _SDL_test_random_h
+#define _SDL_test_random_h
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDLTest_RandomInt(c) ((int)SDLTest_Random(c))
+
+ typedef struct {
+ unsigned int a;
+ unsigned int x;
+ unsigned int c;
+ unsigned int ah;
+ unsigned int al;
+ } SDLTest_RandomContext;
+
+ void SDLTest_RandomInit(SDLTest_RandomContext * rndContext, unsigned int xi,
+ unsigned int ci);
+
+ void SDLTest_RandomInitTime(SDLTest_RandomContext *rndContext);
+
+ unsigned int SDLTest_Random(SDLTest_RandomContext *rndContext);
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_thread.h b/extern/sdlew/include/SDL2/SDL_thread.h
new file mode 100644
index 00000000000..d7662713e51
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_thread.h
@@ -0,0 +1,90 @@
+
+#ifndef _SDL_thread_h
+#define _SDL_thread_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "SDL_atomic.h"
+#include "SDL_mutex.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct SDL_Thread;
+typedef struct SDL_Thread SDL_Thread;
+
+typedef unsigned long SDL_threadID;
+
+typedef unsigned int SDL_TLSID;
+
+typedef enum {
+ SDL_THREAD_PRIORITY_LOW,
+ SDL_THREAD_PRIORITY_NORMAL,
+ SDL_THREAD_PRIORITY_HIGH
+} SDL_ThreadPriority;
+
+typedef int (SDLCALL * SDL_ThreadFunction) (void *data);
+
+#if defined(__WIN32__) && !defined(HAVE_LIBC)
+
+#define SDL_PASSED_BEGINTHREAD_ENDTHREAD
+#include <process.h>
+
+typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned,
+ unsigned (__stdcall *
+ func) (void
+ *),
+ void *arg, unsigned,
+ unsigned *threadID);
+typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code);
+
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
+ pfnSDL_CurrentBeginThread pfnBeginThread,
+ pfnSDL_CurrentEndThread pfnEndThread);
+
+#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
+
+#else
+
+extern DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
+
+#endif
+
+typedef const char * SDLCALL tSDL_GetThreadName(SDL_Thread *thread);
+
+typedef SDL_threadID SDLCALL tSDL_ThreadID(void);
+
+typedef SDL_threadID SDLCALL tSDL_GetThreadID(SDL_Thread * thread);
+
+typedef int SDLCALL tSDL_SetThreadPriority(SDL_ThreadPriority priority);
+
+typedef void SDLCALL tSDL_WaitThread(SDL_Thread * thread, int *status);
+
+typedef SDL_TLSID SDLCALL tSDL_TLSCreate(void);
+
+typedef void * SDLCALL tSDL_TLSGet(SDL_TLSID id);
+
+typedef int SDLCALL tSDL_TLSSet(SDL_TLSID id, const void *value, void (*destructor)(void*));
+
+extern tSDL_GetThreadName *SDL_GetThreadName;
+extern tSDL_ThreadID *SDL_ThreadID;
+extern tSDL_GetThreadID *SDL_GetThreadID;
+extern tSDL_SetThreadPriority *SDL_SetThreadPriority;
+extern tSDL_WaitThread *SDL_WaitThread;
+extern tSDL_TLSCreate *SDL_TLSCreate;
+extern tSDL_TLSGet *SDL_TLSGet;
+extern tSDL_TLSSet *SDL_TLSSet;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_timer.h b/extern/sdlew/include/SDL2/SDL_timer.h
new file mode 100644
index 00000000000..bfaee50f6e1
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_timer.h
@@ -0,0 +1,45 @@
+
+#ifndef _SDL_timer_h
+#define _SDL_timer_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef Uint32 SDLCALL tSDL_GetTicks(void);
+
+typedef Uint64 SDLCALL tSDL_GetPerformanceCounter(void);
+
+typedef Uint64 SDLCALL tSDL_GetPerformanceFrequency(void);
+
+typedef void SDLCALL tSDL_Delay(Uint32 ms);
+
+typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param);
+
+typedef int SDL_TimerID;
+
+typedef SDL_TimerID SDLCALL tSDL_AddTimer(Uint32 interval,
+ SDL_TimerCallback callback,
+ void *param);
+
+typedef SDL_bool SDLCALL tSDL_RemoveTimer(SDL_TimerID id);
+
+extern tSDL_GetTicks *SDL_GetTicks;
+extern tSDL_GetPerformanceCounter *SDL_GetPerformanceCounter;
+extern tSDL_GetPerformanceFrequency *SDL_GetPerformanceFrequency;
+extern tSDL_Delay *SDL_Delay;
+extern tSDL_AddTimer *SDL_AddTimer;
+extern tSDL_RemoveTimer *SDL_RemoveTimer;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_touch.h b/extern/sdlew/include/SDL2/SDL_touch.h
new file mode 100644
index 00000000000..bd8ded65748
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_touch.h
@@ -0,0 +1,47 @@
+
+#ifndef _SDL_touch_h
+#define _SDL_touch_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+#include "SDL_video.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef Sint64 SDL_TouchID;
+typedef Sint64 SDL_FingerID;
+
+typedef struct SDL_Finger
+{
+ SDL_FingerID id;
+ float x;
+ float y;
+ float pressure;
+} SDL_Finger;
+
+#define SDL_TOUCH_MOUSEID ((Uint32)-1)
+
+typedef int SDLCALL tSDL_GetNumTouchDevices(void);
+
+typedef SDL_TouchID SDLCALL tSDL_GetTouchDevice(int index);
+
+typedef int SDLCALL tSDL_GetNumTouchFingers(SDL_TouchID touchID);
+
+typedef SDL_Finger * SDLCALL tSDL_GetTouchFinger(SDL_TouchID touchID, int index);
+
+extern tSDL_GetNumTouchDevices *SDL_GetNumTouchDevices;
+extern tSDL_GetTouchDevice *SDL_GetTouchDevice;
+extern tSDL_GetNumTouchFingers *SDL_GetNumTouchFingers;
+extern tSDL_GetTouchFinger *SDL_GetTouchFinger;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_types.h b/extern/sdlew/include/SDL2/SDL_types.h
new file mode 100644
index 00000000000..8ac56b71f2c
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_types.h
@@ -0,0 +1,2 @@
+
+#include "SDL_stdinc.h"
diff --git a/extern/sdlew/include/SDL2/SDL_version.h b/extern/sdlew/include/SDL2/SDL_version.h
new file mode 100644
index 00000000000..0156f77daea
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_version.h
@@ -0,0 +1,56 @@
+
+#ifndef _SDL_version_h
+#define _SDL_version_h
+
+#include "SDL_stdinc.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SDL_version
+{
+ Uint8 major;
+ Uint8 minor;
+ Uint8 patch;
+} SDL_version;
+
+#define SDL_MAJOR_VERSION 2
+#define SDL_MINOR_VERSION 0
+#define SDL_PATCHLEVEL 0
+
+#define SDL_VERSION(x) \
+{ \
+ (x)->major = SDL_MAJOR_VERSION; \
+ (x)->minor = SDL_MINOR_VERSION; \
+ (x)->patch = SDL_PATCHLEVEL; \
+}
+
+#define SDL_VERSIONNUM(X, Y, Z) \
+ ((X)*1000 + (Y)*100 + (Z))
+
+#define SDL_COMPILEDVERSION \
+ SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL)
+
+#define SDL_VERSION_ATLEAST(X, Y, Z) \
+ (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z))
+
+typedef void SDLCALL tSDL_GetVersion(SDL_version * ver);
+
+typedef const char * SDLCALL tSDL_GetRevision(void);
+
+typedef int SDLCALL tSDL_GetRevisionNumber(void);
+
+extern tSDL_GetVersion *SDL_GetVersion;
+extern tSDL_GetRevision *SDL_GetRevision;
+extern tSDL_GetRevisionNumber *SDL_GetRevisionNumber;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/SDL_video.h b/extern/sdlew/include/SDL2/SDL_video.h
new file mode 100644
index 00000000000..0a97ea45915
--- /dev/null
+++ b/extern/sdlew/include/SDL2/SDL_video.h
@@ -0,0 +1,367 @@
+
+#ifndef _SDL_video_h
+#define _SDL_video_h
+
+#include "SDL_stdinc.h"
+#include "SDL_pixels.h"
+#include "SDL_rect.h"
+#include "SDL_surface.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ Uint32 format;
+ int w;
+ int h;
+ int refresh_rate;
+ void *driverdata;
+} SDL_DisplayMode;
+
+typedef struct SDL_Window SDL_Window;
+
+typedef enum
+{
+ SDL_WINDOW_FULLSCREEN = 0x00000001,
+ SDL_WINDOW_OPENGL = 0x00000002,
+ SDL_WINDOW_SHOWN = 0x00000004,
+ SDL_WINDOW_HIDDEN = 0x00000008,
+ SDL_WINDOW_BORDERLESS = 0x00000010,
+ SDL_WINDOW_RESIZABLE = 0x00000020,
+ SDL_WINDOW_MINIMIZED = 0x00000040,
+ SDL_WINDOW_MAXIMIZED = 0x00000080,
+ SDL_WINDOW_INPUT_GRABBED = 0x00000100,
+ SDL_WINDOW_INPUT_FOCUS = 0x00000200,
+ SDL_WINDOW_MOUSE_FOCUS = 0x00000400,
+ SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
+ SDL_WINDOW_FOREIGN = 0x00000800
+} SDL_WindowFlags;
+
+#define SDL_WINDOWPOS_UNDEFINED_MASK 0x1FFF0000
+#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X) (SDL_WINDOWPOS_UNDEFINED_MASK|(X))
+#define SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED_DISPLAY(0)
+#define SDL_WINDOWPOS_ISUNDEFINED(X) \
+ (((X)&0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK)
+
+#define SDL_WINDOWPOS_CENTERED_MASK 0x2FFF0000
+#define SDL_WINDOWPOS_CENTERED_DISPLAY(X) (SDL_WINDOWPOS_CENTERED_MASK|(X))
+#define SDL_WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED_DISPLAY(0)
+#define SDL_WINDOWPOS_ISCENTERED(X) \
+ (((X)&0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK)
+
+typedef enum
+{
+ SDL_WINDOWEVENT_NONE,
+ SDL_WINDOWEVENT_SHOWN,
+ SDL_WINDOWEVENT_HIDDEN,
+ SDL_WINDOWEVENT_EXPOSED,
+ SDL_WINDOWEVENT_MOVED,
+ SDL_WINDOWEVENT_RESIZED,
+ SDL_WINDOWEVENT_SIZE_CHANGED,
+ SDL_WINDOWEVENT_MINIMIZED,
+ SDL_WINDOWEVENT_MAXIMIZED,
+ SDL_WINDOWEVENT_RESTORED,
+ SDL_WINDOWEVENT_ENTER,
+ SDL_WINDOWEVENT_LEAVE,
+ SDL_WINDOWEVENT_FOCUS_GAINED,
+ SDL_WINDOWEVENT_FOCUS_LOST,
+ SDL_WINDOWEVENT_CLOSE
+} SDL_WindowEventID;
+
+typedef void *SDL_GLContext;
+
+typedef enum
+{
+ SDL_GL_RED_SIZE,
+ SDL_GL_GREEN_SIZE,
+ SDL_GL_BLUE_SIZE,
+ SDL_GL_ALPHA_SIZE,
+ SDL_GL_BUFFER_SIZE,
+ SDL_GL_DOUBLEBUFFER,
+ SDL_GL_DEPTH_SIZE,
+ SDL_GL_STENCIL_SIZE,
+ SDL_GL_ACCUM_RED_SIZE,
+ SDL_GL_ACCUM_GREEN_SIZE,
+ SDL_GL_ACCUM_BLUE_SIZE,
+ SDL_GL_ACCUM_ALPHA_SIZE,
+ SDL_GL_STEREO,
+ SDL_GL_MULTISAMPLEBUFFERS,
+ SDL_GL_MULTISAMPLESAMPLES,
+ SDL_GL_ACCELERATED_VISUAL,
+ SDL_GL_RETAINED_BACKING,
+ SDL_GL_CONTEXT_MAJOR_VERSION,
+ SDL_GL_CONTEXT_MINOR_VERSION,
+ SDL_GL_CONTEXT_EGL,
+ SDL_GL_CONTEXT_FLAGS,
+ SDL_GL_CONTEXT_PROFILE_MASK,
+ SDL_GL_SHARE_WITH_CURRENT_CONTEXT
+} SDL_GLattr;
+
+typedef enum
+{
+ SDL_GL_CONTEXT_PROFILE_CORE = 0x0001,
+ SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002,
+ SDL_GL_CONTEXT_PROFILE_ES = 0x0004
+} SDL_GLprofile;
+
+typedef enum
+{
+ SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001,
+ SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002,
+ SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004,
+ SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008
+} SDL_GLcontextFlag;
+
+typedef int SDLCALL tSDL_GetNumVideoDrivers(void);
+
+typedef const char * SDLCALL tSDL_GetVideoDriver(int index);
+
+typedef int SDLCALL tSDL_VideoInit(const char *driver_name);
+
+typedef void SDLCALL tSDL_VideoQuit(void);
+
+typedef const char * SDLCALL tSDL_GetCurrentVideoDriver(void);
+
+typedef int SDLCALL tSDL_GetNumVideoDisplays(void);
+
+typedef const char * SDLCALL tSDL_GetDisplayName(int displayIndex);
+
+typedef int SDLCALL tSDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect);
+
+typedef int SDLCALL tSDL_GetNumDisplayModes(int displayIndex);
+
+typedef int SDLCALL tSDL_GetDisplayMode(int displayIndex, int modeIndex,
+ SDL_DisplayMode * mode);
+
+typedef int SDLCALL tSDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode);
+
+typedef int SDLCALL tSDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode);
+
+typedef SDL_DisplayMode * SDLCALL tSDL_GetClosestDisplayMode(int displayIndex, const SDL_DisplayMode * mode, SDL_DisplayMode * closest);
+
+typedef int SDLCALL tSDL_GetWindowDisplayIndex(SDL_Window * window);
+
+typedef int SDLCALL tSDL_SetWindowDisplayMode(SDL_Window * window,
+ const SDL_DisplayMode
+ * mode);
+
+typedef int SDLCALL tSDL_GetWindowDisplayMode(SDL_Window * window,
+ SDL_DisplayMode * mode);
+
+typedef Uint32 SDLCALL tSDL_GetWindowPixelFormat(SDL_Window * window);
+
+typedef SDL_Window * SDLCALL tSDL_CreateWindow(const char *title,
+ int x, int y, int w,
+ int h, Uint32 flags);
+
+typedef SDL_Window * SDLCALL tSDL_CreateWindowFrom(const void *data);
+
+typedef Uint32 SDLCALL tSDL_GetWindowID(SDL_Window * window);
+
+typedef SDL_Window * SDLCALL tSDL_GetWindowFromID(Uint32 id);
+
+typedef Uint32 SDLCALL tSDL_GetWindowFlags(SDL_Window * window);
+
+typedef void SDLCALL tSDL_SetWindowTitle(SDL_Window * window,
+ const char *title);
+
+typedef const char * SDLCALL tSDL_GetWindowTitle(SDL_Window * window);
+
+typedef void SDLCALL tSDL_SetWindowIcon(SDL_Window * window,
+ SDL_Surface * icon);
+
+extern DECLSPEC void* SDLCALL SDL_SetWindowData(SDL_Window * window,
+ const char *name,
+ void *userdata);
+
+typedef void * SDLCALL tSDL_GetWindowData(SDL_Window * window,
+ const char *name);
+
+typedef void SDLCALL tSDL_SetWindowPosition(SDL_Window * window,
+ int x, int y);
+
+typedef void SDLCALL tSDL_GetWindowPosition(SDL_Window * window,
+ int *x, int *y);
+
+typedef void SDLCALL tSDL_SetWindowSize(SDL_Window * window, int w,
+ int h);
+
+typedef void SDLCALL tSDL_GetWindowSize(SDL_Window * window, int *w,
+ int *h);
+
+typedef void SDLCALL tSDL_SetWindowMinimumSize(SDL_Window * window,
+ int min_w, int min_h);
+
+typedef void SDLCALL tSDL_GetWindowMinimumSize(SDL_Window * window,
+ int *w, int *h);
+
+typedef void SDLCALL tSDL_SetWindowMaximumSize(SDL_Window * window,
+ int max_w, int max_h);
+
+typedef void SDLCALL tSDL_GetWindowMaximumSize(SDL_Window * window,
+ int *w, int *h);
+
+typedef void SDLCALL tSDL_SetWindowBordered(SDL_Window * window,
+ SDL_bool bordered);
+
+typedef void SDLCALL tSDL_ShowWindow(SDL_Window * window);
+
+typedef void SDLCALL tSDL_HideWindow(SDL_Window * window);
+
+typedef void SDLCALL tSDL_RaiseWindow(SDL_Window * window);
+
+typedef void SDLCALL tSDL_MaximizeWindow(SDL_Window * window);
+
+typedef void SDLCALL tSDL_MinimizeWindow(SDL_Window * window);
+
+typedef void SDLCALL tSDL_RestoreWindow(SDL_Window * window);
+
+typedef int SDLCALL tSDL_SetWindowFullscreen(SDL_Window * window,
+ Uint32 flags);
+
+typedef SDL_Surface * SDLCALL tSDL_GetWindowSurface(SDL_Window * window);
+
+typedef int SDLCALL tSDL_UpdateWindowSurface(SDL_Window * window);
+
+typedef int SDLCALL tSDL_UpdateWindowSurfaceRects(SDL_Window * window,
+ const SDL_Rect * rects,
+ int numrects);
+
+typedef void SDLCALL tSDL_SetWindowGrab(SDL_Window * window,
+ SDL_bool grabbed);
+
+typedef SDL_bool SDLCALL tSDL_GetWindowGrab(SDL_Window * window);
+
+typedef int SDLCALL tSDL_SetWindowBrightness(SDL_Window * window, float brightness);
+
+typedef float SDLCALL tSDL_GetWindowBrightness(SDL_Window * window);
+
+typedef int SDLCALL tSDL_SetWindowGammaRamp(SDL_Window * window,
+ const Uint16 * red,
+ const Uint16 * green,
+ const Uint16 * blue);
+
+typedef int SDLCALL tSDL_GetWindowGammaRamp(SDL_Window * window,
+ Uint16 * red,
+ Uint16 * green,
+ Uint16 * blue);
+
+typedef void SDLCALL tSDL_DestroyWindow(SDL_Window * window);
+
+typedef SDL_bool SDLCALL tSDL_IsScreenSaverEnabled(void);
+
+typedef void SDLCALL tSDL_EnableScreenSaver(void);
+
+typedef void SDLCALL tSDL_DisableScreenSaver(void);
+
+typedef int SDLCALL tSDL_GL_LoadLibrary(const char *path);
+
+typedef void * SDLCALL tSDL_GL_GetProcAddress(const char *proc);
+
+typedef void SDLCALL tSDL_GL_UnloadLibrary(void);
+
+typedef SDL_bool SDLCALL tSDL_GL_ExtensionSupported(const char
+ *extension);
+
+typedef int SDLCALL tSDL_GL_SetAttribute(SDL_GLattr attr, int value);
+
+typedef int SDLCALL tSDL_GL_GetAttribute(SDL_GLattr attr, int *value);
+
+typedef SDL_GLContext SDLCALL tSDL_GL_CreateContext(SDL_Window *
+ window);
+
+typedef int SDLCALL tSDL_GL_MakeCurrent(SDL_Window * window,
+ SDL_GLContext context);
+
+extern DECLSPEC SDL_Window* SDLCALL SDL_GL_GetCurrentWindow(void);
+
+typedef SDL_GLContext SDLCALL tSDL_GL_GetCurrentContext(void);
+
+typedef int SDLCALL tSDL_GL_SetSwapInterval(int interval);
+
+typedef int SDLCALL tSDL_GL_GetSwapInterval(void);
+
+typedef void SDLCALL tSDL_GL_SwapWindow(SDL_Window * window);
+
+typedef void SDLCALL tSDL_GL_DeleteContext(SDL_GLContext context);
+
+extern tSDL_GetNumVideoDrivers *SDL_GetNumVideoDrivers;
+extern tSDL_GetVideoDriver *SDL_GetVideoDriver;
+extern tSDL_VideoInit *SDL_VideoInit;
+extern tSDL_VideoQuit *SDL_VideoQuit;
+extern tSDL_GetCurrentVideoDriver *SDL_GetCurrentVideoDriver;
+extern tSDL_GetNumVideoDisplays *SDL_GetNumVideoDisplays;
+extern tSDL_GetDisplayName *SDL_GetDisplayName;
+extern tSDL_GetDisplayBounds *SDL_GetDisplayBounds;
+extern tSDL_GetNumDisplayModes *SDL_GetNumDisplayModes;
+extern tSDL_GetDisplayMode *SDL_GetDisplayMode;
+extern tSDL_GetDesktopDisplayMode *SDL_GetDesktopDisplayMode;
+extern tSDL_GetCurrentDisplayMode *SDL_GetCurrentDisplayMode;
+extern tSDL_GetClosestDisplayMode *SDL_GetClosestDisplayMode;
+extern tSDL_GetWindowDisplayIndex *SDL_GetWindowDisplayIndex;
+extern tSDL_SetWindowDisplayMode *SDL_SetWindowDisplayMode;
+extern tSDL_GetWindowDisplayMode *SDL_GetWindowDisplayMode;
+extern tSDL_GetWindowPixelFormat *SDL_GetWindowPixelFormat;
+extern tSDL_CreateWindow *SDL_CreateWindow;
+extern tSDL_CreateWindowFrom *SDL_CreateWindowFrom;
+extern tSDL_GetWindowID *SDL_GetWindowID;
+extern tSDL_GetWindowFromID *SDL_GetWindowFromID;
+extern tSDL_GetWindowFlags *SDL_GetWindowFlags;
+extern tSDL_SetWindowTitle *SDL_SetWindowTitle;
+extern tSDL_GetWindowTitle *SDL_GetWindowTitle;
+extern tSDL_SetWindowIcon *SDL_SetWindowIcon;
+extern tSDL_GetWindowData *SDL_GetWindowData;
+extern tSDL_SetWindowPosition *SDL_SetWindowPosition;
+extern tSDL_GetWindowPosition *SDL_GetWindowPosition;
+extern tSDL_SetWindowSize *SDL_SetWindowSize;
+extern tSDL_GetWindowSize *SDL_GetWindowSize;
+extern tSDL_SetWindowMinimumSize *SDL_SetWindowMinimumSize;
+extern tSDL_GetWindowMinimumSize *SDL_GetWindowMinimumSize;
+extern tSDL_SetWindowMaximumSize *SDL_SetWindowMaximumSize;
+extern tSDL_GetWindowMaximumSize *SDL_GetWindowMaximumSize;
+extern tSDL_SetWindowBordered *SDL_SetWindowBordered;
+extern tSDL_ShowWindow *SDL_ShowWindow;
+extern tSDL_HideWindow *SDL_HideWindow;
+extern tSDL_RaiseWindow *SDL_RaiseWindow;
+extern tSDL_MaximizeWindow *SDL_MaximizeWindow;
+extern tSDL_MinimizeWindow *SDL_MinimizeWindow;
+extern tSDL_RestoreWindow *SDL_RestoreWindow;
+extern tSDL_SetWindowFullscreen *SDL_SetWindowFullscreen;
+extern tSDL_GetWindowSurface *SDL_GetWindowSurface;
+extern tSDL_UpdateWindowSurface *SDL_UpdateWindowSurface;
+extern tSDL_UpdateWindowSurfaceRects *SDL_UpdateWindowSurfaceRects;
+extern tSDL_SetWindowGrab *SDL_SetWindowGrab;
+extern tSDL_GetWindowGrab *SDL_GetWindowGrab;
+extern tSDL_SetWindowBrightness *SDL_SetWindowBrightness;
+extern tSDL_GetWindowBrightness *SDL_GetWindowBrightness;
+extern tSDL_SetWindowGammaRamp *SDL_SetWindowGammaRamp;
+extern tSDL_GetWindowGammaRamp *SDL_GetWindowGammaRamp;
+extern tSDL_DestroyWindow *SDL_DestroyWindow;
+extern tSDL_IsScreenSaverEnabled *SDL_IsScreenSaverEnabled;
+extern tSDL_EnableScreenSaver *SDL_EnableScreenSaver;
+extern tSDL_DisableScreenSaver *SDL_DisableScreenSaver;
+extern tSDL_GL_LoadLibrary *SDL_GL_LoadLibrary;
+extern tSDL_GL_GetProcAddress *SDL_GL_GetProcAddress;
+extern tSDL_GL_UnloadLibrary *SDL_GL_UnloadLibrary;
+extern tSDL_GL_ExtensionSupported *SDL_GL_ExtensionSupported;
+extern tSDL_GL_SetAttribute *SDL_GL_SetAttribute;
+extern tSDL_GL_GetAttribute *SDL_GL_GetAttribute;
+extern tSDL_GL_CreateContext *SDL_GL_CreateContext;
+extern tSDL_GL_MakeCurrent *SDL_GL_MakeCurrent;
+extern tSDL_GL_GetCurrentContext *SDL_GL_GetCurrentContext;
+extern tSDL_GL_SetSwapInterval *SDL_GL_SetSwapInterval;
+extern tSDL_GL_GetSwapInterval *SDL_GL_GetSwapInterval;
+extern tSDL_GL_SwapWindow *SDL_GL_SwapWindow;
+extern tSDL_GL_DeleteContext *SDL_GL_DeleteContext;
+
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif
+
diff --git a/extern/sdlew/include/SDL2/begin_code.h b/extern/sdlew/include/SDL2/begin_code.h
new file mode 100644
index 00000000000..8922c000c5f
--- /dev/null
+++ b/extern/sdlew/include/SDL2/begin_code.h
@@ -0,0 +1,107 @@
+
+#ifdef _begin_code_h
+#error Nested inclusion of begin_code.h
+#endif
+#define _begin_code_h
+
+#ifndef DECLSPEC
+# if defined(__BEOS__) || defined(__HAIKU__)
+# if defined(__GNUC__)
+# define DECLSPEC __declspec(dllexport)
+# else
+# define DECLSPEC __declspec(export)
+# endif
+# elif defined(__WIN32__)
+# ifdef __BORLANDC__
+# ifdef BUILD_SDL
+# define DECLSPEC
+# else
+# define DECLSPEC __declspec(dllimport)
+# endif
+# else
+# define DECLSPEC __declspec(dllexport)
+# endif
+# else
+# if defined(__GNUC__) && __GNUC__ >= 4
+# define DECLSPEC __attribute__ ((visibility("default")))
+# else
+# define DECLSPEC
+# endif
+# endif
+#endif
+
+#ifndef SDLCALL
+#if defined(__WIN32__) && !defined(__GNUC__)
+#define SDLCALL __cdecl
+#else
+#define SDLCALL
+#endif
+#endif
+
+#ifdef __SYMBIAN32__
+#undef DECLSPEC
+#define DECLSPEC
+#endif
+
+#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__)
+#ifdef _MSC_VER
+#pragma warning(disable: 4103)
+#endif
+#ifdef __BORLANDC__
+#pragma nopackwarning
+#endif
+#ifdef _M_X64
+
+#pragma pack(push,8)
+#else
+#pragma pack(push,4)
+#endif
+#endif
+
+#ifndef SDL_INLINE_OKAY
+#ifdef __GNUC__
+#define SDL_INLINE_OKAY
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__) || \
+ defined(__DMC__) || defined(__SC__) || \
+ defined(__WATCOMC__) || defined(__LCC__) || \
+ defined(__DECC)
+#ifndef __inline__
+#define __inline__ __inline
+#endif
+#define SDL_INLINE_OKAY
+#else
+#if !defined(__MRC__) && !defined(_SGI_SOURCE)
+#ifndef __inline__
+#define __inline__ inline
+#endif
+#define SDL_INLINE_OKAY
+#endif
+#endif
+#endif
+#endif
+
+#ifndef SDL_INLINE_OKAY
+#define __inline__
+#endif
+
+#ifndef SDL_FORCE_INLINE
+#if defined(_MSC_VER)
+#define SDL_FORCE_INLINE __forceinline
+#elif ( (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) )
+#define SDL_FORCE_INLINE __attribute__((always_inline)) static inline
+#else
+#define SDL_FORCE_INLINE static __inline__
+#endif
+#endif
+
+#if !defined(__MACH__)
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+#endif
diff --git a/extern/sdlew/include/SDL2/close_code.h b/extern/sdlew/include/SDL2/close_code.h
new file mode 100644
index 00000000000..7a1e48c0539
--- /dev/null
+++ b/extern/sdlew/include/SDL2/close_code.h
@@ -0,0 +1,9 @@
+
+#undef _begin_code_h
+
+#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__WATCOMC__) || defined(__BORLANDC__)
+#ifdef __BORLANDC__
+#pragma nopackwarning
+#endif
+#pragma pack(pop)
+#endif
diff --git a/intern/cycles/util/util_dynlib.h b/extern/sdlew/include/sdlew.h
index b30cf98c1b9..dde3d70ab31 100644
--- a/intern/cycles/util/util_dynlib.h
+++ b/extern/sdlew/include/sdlew.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2013 Blender Foundation
+ * Copyright 2014 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,18 +14,24 @@
* limitations under the License
*/
-#ifndef __UTIL_DYNLIB_H__
-#define __UTIL_DYNLIB_H__
+#ifndef __SDL_EW_H__
+#define __SDL_EW_H__
-CCL_NAMESPACE_BEGIN
+#ifdef __cplusplus
+extern "C" {
+#endif
-struct DynamicLibrary;
+enum {
+ SDLEW_SUCCESS = 0,
+ SDLEW_ERROR_OPEN_FAILED = -1,
+ SDLEW_ERROR_ATEXIT_FAILED = -2,
+ SDLEW_ERROR_VERSION = -3,
+};
-DynamicLibrary *dynamic_library_open(const char *name);
-void *dynamic_library_find(DynamicLibrary *lib, const char *name);
-void dynamic_library_close(DynamicLibrary *lib);
+int sdlewInit(void);
-CCL_NAMESPACE_END
-
-#endif /* __UTIL_DYNLIB_H__ */
+#ifdef __cplusplus
+}
+#endif
+#endif /* __SDL_EW_H__ */
diff --git a/extern/sdlew/src/sdlew.c b/extern/sdlew/src/sdlew.c
new file mode 100644
index 00000000000..3b19f0cef47
--- /dev/null
+++ b/extern/sdlew/src/sdlew.c
@@ -0,0 +1,1112 @@
+/*
+ * Copyright 2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#ifdef _MSC_VER
+# define snprintf _snprintf
+# define popen _popen
+# define pclose _pclose
+# define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include "sdlew.h"
+
+#include "SDL2/SDL.h"
+#include "SDL2/SDL_syswm.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN
+# define VC_EXTRALEAN
+# include <windows.h>
+
+/* Utility macros. */
+
+typedef HMODULE DynamicLibrary;
+
+# define dynamic_library_open(path) LoadLibrary(path)
+# define dynamic_library_close(lib) FreeLibrary(lib)
+# define dynamic_library_find(lib, symbol) GetProcAddress(lib, symbol)
+#else
+# include <dlfcn.h>
+
+typedef void* DynamicLibrary;
+
+# define dynamic_library_open(path) dlopen(path, RTLD_NOW)
+# define dynamic_library_close(lib) dlclose(lib)
+# define dynamic_library_find(lib, symbol) dlsym(lib, symbol)
+#endif
+
+#define SDL_LIBRARY_FIND_CHECKED(name) name = (t##name *)dynamic_library_find(lib, #name); assert(name);
+
+#define SDL_LIBRARY_FIND(name) name = (t##name *)dynamic_library_find(lib, #name);
+
+static DynamicLibrary lib;
+
+tSDL_GetPlatform *SDL_GetPlatform;
+tSDL_memcpy *SDL_memcpy;
+#ifndef HAVE_ALLOCA
+tSDL_malloc *SDL_malloc;
+#endif
+tSDL_calloc *SDL_calloc;
+tSDL_realloc *SDL_realloc;
+tSDL_free *SDL_free;
+tSDL_getenv *SDL_getenv;
+tSDL_setenv *SDL_setenv;
+tSDL_qsort *SDL_qsort;
+tSDL_abs *SDL_abs;
+tSDL_isdigit *SDL_isdigit;
+tSDL_isspace *SDL_isspace;
+tSDL_toupper *SDL_toupper;
+tSDL_tolower *SDL_tolower;
+tSDL_memset *SDL_memset;
+tSDL_memmove *SDL_memmove;
+tSDL_memcmp *SDL_memcmp;
+tSDL_wcslen *SDL_wcslen;
+tSDL_wcslcpy *SDL_wcslcpy;
+tSDL_wcslcat *SDL_wcslcat;
+tSDL_strlen *SDL_strlen;
+tSDL_strlcpy *SDL_strlcpy;
+tSDL_utf8strlcpy *SDL_utf8strlcpy;
+tSDL_strlcat *SDL_strlcat;
+tSDL_strdup *SDL_strdup;
+tSDL_strrev *SDL_strrev;
+tSDL_strupr *SDL_strupr;
+tSDL_strlwr *SDL_strlwr;
+tSDL_strchr *SDL_strchr;
+tSDL_strrchr *SDL_strrchr;
+tSDL_strstr *SDL_strstr;
+tSDL_itoa *SDL_itoa;
+tSDL_uitoa *SDL_uitoa;
+tSDL_ltoa *SDL_ltoa;
+tSDL_ultoa *SDL_ultoa;
+tSDL_lltoa *SDL_lltoa;
+tSDL_ulltoa *SDL_ulltoa;
+tSDL_atoi *SDL_atoi;
+tSDL_atof *SDL_atof;
+tSDL_strtol *SDL_strtol;
+tSDL_strtoll *SDL_strtoll;
+tSDL_strtoull *SDL_strtoull;
+tSDL_strtod *SDL_strtod;
+tSDL_strcmp *SDL_strcmp;
+tSDL_strncmp *SDL_strncmp;
+tSDL_strcasecmp *SDL_strcasecmp;
+tSDL_strncasecmp *SDL_strncasecmp;
+tSDL_sscanf *SDL_sscanf;
+tSDL_snprintf *SDL_snprintf;
+tSDL_vsnprintf *SDL_vsnprintf;
+tSDL_atan *SDL_atan;
+tSDL_atan2 *SDL_atan2;
+tSDL_ceil *SDL_ceil;
+tSDL_copysign *SDL_copysign;
+tSDL_cos *SDL_cos;
+tSDL_cosf *SDL_cosf;
+tSDL_fabs *SDL_fabs;
+tSDL_floor *SDL_floor;
+tSDL_log *SDL_log;
+tSDL_pow *SDL_pow;
+tSDL_scalbn *SDL_scalbn;
+tSDL_sin *SDL_sin;
+tSDL_sinf *SDL_sinf;
+tSDL_sqrt *SDL_sqrt;
+tSDL_iconv_open *SDL_iconv_open;
+tSDL_iconv_close *SDL_iconv_close;
+tSDL_iconv *SDL_iconv;
+tSDL_iconv_string *SDL_iconv_string;
+tSDL_GetNumRenderDrivers *SDL_GetNumRenderDrivers;
+tSDL_GetRenderDriverInfo *SDL_GetRenderDriverInfo;
+tSDL_CreateWindowAndRenderer *SDL_CreateWindowAndRenderer;
+tSDL_CreateRenderer *SDL_CreateRenderer;
+tSDL_CreateSoftwareRenderer *SDL_CreateSoftwareRenderer;
+tSDL_GetRenderer *SDL_GetRenderer;
+tSDL_GetRendererInfo *SDL_GetRendererInfo;
+tSDL_GetRendererOutputSize *SDL_GetRendererOutputSize;
+tSDL_CreateTexture *SDL_CreateTexture;
+tSDL_CreateTextureFromSurface *SDL_CreateTextureFromSurface;
+tSDL_QueryTexture *SDL_QueryTexture;
+tSDL_SetTextureColorMod *SDL_SetTextureColorMod;
+tSDL_GetTextureColorMod *SDL_GetTextureColorMod;
+tSDL_SetTextureAlphaMod *SDL_SetTextureAlphaMod;
+tSDL_GetTextureAlphaMod *SDL_GetTextureAlphaMod;
+tSDL_SetTextureBlendMode *SDL_SetTextureBlendMode;
+tSDL_GetTextureBlendMode *SDL_GetTextureBlendMode;
+tSDL_UpdateTexture *SDL_UpdateTexture;
+tSDL_LockTexture *SDL_LockTexture;
+tSDL_UnlockTexture *SDL_UnlockTexture;
+tSDL_RenderTargetSupported *SDL_RenderTargetSupported;
+tSDL_SetRenderTarget *SDL_SetRenderTarget;
+tSDL_GetRenderTarget *SDL_GetRenderTarget;
+tSDL_RenderSetLogicalSize *SDL_RenderSetLogicalSize;
+tSDL_RenderGetLogicalSize *SDL_RenderGetLogicalSize;
+tSDL_RenderSetViewport *SDL_RenderSetViewport;
+tSDL_RenderGetViewport *SDL_RenderGetViewport;
+tSDL_RenderSetClipRect *SDL_RenderSetClipRect;
+tSDL_RenderGetClipRect *SDL_RenderGetClipRect;
+tSDL_RenderSetScale *SDL_RenderSetScale;
+tSDL_RenderGetScale *SDL_RenderGetScale;
+tSDL_SetRenderDrawBlendMode *SDL_SetRenderDrawBlendMode;
+tSDL_GetRenderDrawBlendMode *SDL_GetRenderDrawBlendMode;
+tSDL_RenderClear *SDL_RenderClear;
+tSDL_RenderDrawPoint *SDL_RenderDrawPoint;
+tSDL_RenderDrawPoints *SDL_RenderDrawPoints;
+tSDL_RenderDrawLine *SDL_RenderDrawLine;
+tSDL_RenderDrawLines *SDL_RenderDrawLines;
+tSDL_RenderDrawRect *SDL_RenderDrawRect;
+tSDL_RenderDrawRects *SDL_RenderDrawRects;
+tSDL_RenderFillRect *SDL_RenderFillRect;
+tSDL_RenderFillRects *SDL_RenderFillRects;
+tSDL_RenderCopy *SDL_RenderCopy;
+tSDL_RenderCopyEx *SDL_RenderCopyEx;
+tSDL_RenderReadPixels *SDL_RenderReadPixels;
+tSDL_RenderPresent *SDL_RenderPresent;
+tSDL_DestroyTexture *SDL_DestroyTexture;
+tSDL_DestroyRenderer *SDL_DestroyRenderer;
+tSDL_GL_BindTexture *SDL_GL_BindTexture;
+tSDL_GL_UnbindTexture *SDL_GL_UnbindTexture;
+tSDL_LoadObject *SDL_LoadObject;
+tSDL_LoadFunction *SDL_LoadFunction;
+tSDL_UnloadObject *SDL_UnloadObject;
+tSDL_ReportAssertion *SDL_ReportAssertion;
+tSDL_SetAssertionHandler *SDL_SetAssertionHandler;
+tSDL_GetAssertionReport *SDL_GetAssertionReport;
+tSDL_ResetAssertionReport *SDL_ResetAssertionReport;
+tSDL_AtomicTryLock *SDL_AtomicTryLock;
+tSDL_AtomicLock *SDL_AtomicLock;
+tSDL_AtomicUnlock *SDL_AtomicUnlock;
+tSDL_HasIntersection *SDL_HasIntersection;
+tSDL_IntersectRect *SDL_IntersectRect;
+tSDL_UnionRect *SDL_UnionRect;
+tSDL_EnclosePoints *SDL_EnclosePoints;
+tSDL_IntersectRectAndLine *SDL_IntersectRectAndLine;
+tSDL_LogSetAllPriority *SDL_LogSetAllPriority;
+tSDL_LogSetPriority *SDL_LogSetPriority;
+tSDL_LogGetPriority *SDL_LogGetPriority;
+tSDL_LogResetPriorities *SDL_LogResetPriorities;
+tSDL_Log *SDL_Log;
+tSDL_LogVerbose *SDL_LogVerbose;
+tSDL_LogDebug *SDL_LogDebug;
+tSDL_LogInfo *SDL_LogInfo;
+tSDL_LogWarn *SDL_LogWarn;
+tSDL_LogError *SDL_LogError;
+tSDL_LogCritical *SDL_LogCritical;
+tSDL_LogMessage *SDL_LogMessage;
+tSDL_LogMessageV *SDL_LogMessageV;
+tSDL_LogGetOutputFunction *SDL_LogGetOutputFunction;
+tSDL_LogSetOutputFunction *SDL_LogSetOutputFunction;
+tSDL_CreateMutex *SDL_CreateMutex;
+tSDL_LockMutex *SDL_LockMutex;
+tSDL_TryLockMutex *SDL_TryLockMutex;
+tSDL_UnlockMutex *SDL_UnlockMutex;
+tSDL_DestroyMutex *SDL_DestroyMutex;
+tSDL_CreateSemaphore *SDL_CreateSemaphore;
+tSDL_DestroySemaphore *SDL_DestroySemaphore;
+tSDL_SemWait *SDL_SemWait;
+tSDL_SemTryWait *SDL_SemTryWait;
+tSDL_SemWaitTimeout *SDL_SemWaitTimeout;
+tSDL_SemPost *SDL_SemPost;
+tSDL_SemValue *SDL_SemValue;
+tSDL_CreateCond *SDL_CreateCond;
+tSDL_DestroyCond *SDL_DestroyCond;
+tSDL_CondSignal *SDL_CondSignal;
+tSDL_CondBroadcast *SDL_CondBroadcast;
+tSDL_CondWait *SDL_CondWait;
+tSDL_CondWaitTimeout *SDL_CondWaitTimeout;
+tSDL_CreateRGBSurface *SDL_CreateRGBSurface;
+tSDL_CreateRGBSurfaceFrom *SDL_CreateRGBSurfaceFrom;
+tSDL_FreeSurface *SDL_FreeSurface;
+tSDL_SetSurfacePalette *SDL_SetSurfacePalette;
+tSDL_LockSurface *SDL_LockSurface;
+tSDL_UnlockSurface *SDL_UnlockSurface;
+tSDL_LoadBMP_RW *SDL_LoadBMP_RW;
+tSDL_SaveBMP_RW *SDL_SaveBMP_RW;
+tSDL_SetSurfaceRLE *SDL_SetSurfaceRLE;
+tSDL_SetColorKey *SDL_SetColorKey;
+tSDL_GetColorKey *SDL_GetColorKey;
+tSDL_SetSurfaceColorMod *SDL_SetSurfaceColorMod;
+tSDL_GetSurfaceColorMod *SDL_GetSurfaceColorMod;
+tSDL_SetSurfaceAlphaMod *SDL_SetSurfaceAlphaMod;
+tSDL_GetSurfaceAlphaMod *SDL_GetSurfaceAlphaMod;
+tSDL_SetSurfaceBlendMode *SDL_SetSurfaceBlendMode;
+tSDL_GetSurfaceBlendMode *SDL_GetSurfaceBlendMode;
+tSDL_SetClipRect *SDL_SetClipRect;
+tSDL_GetClipRect *SDL_GetClipRect;
+tSDL_ConvertSurface *SDL_ConvertSurface;
+tSDL_ConvertSurfaceFormat *SDL_ConvertSurfaceFormat;
+tSDL_ConvertPixels *SDL_ConvertPixels;
+tSDL_FillRect *SDL_FillRect;
+tSDL_FillRects *SDL_FillRects;
+tSDL_UpperBlit *SDL_UpperBlit;
+tSDL_LowerBlit *SDL_LowerBlit;
+tSDL_SoftStretch *SDL_SoftStretch;
+tSDL_UpperBlitScaled *SDL_UpperBlitScaled;
+tSDL_LowerBlitScaled *SDL_LowerBlitScaled;
+tSDL_PumpEvents *SDL_PumpEvents;
+tSDL_PeepEvents *SDL_PeepEvents;
+tSDL_HasEvent *SDL_HasEvent;
+tSDL_HasEvents *SDL_HasEvents;
+tSDL_FlushEvent *SDL_FlushEvent;
+tSDL_FlushEvents *SDL_FlushEvents;
+tSDL_PollEvent *SDL_PollEvent;
+tSDL_WaitEvent *SDL_WaitEvent;
+tSDL_WaitEventTimeout *SDL_WaitEventTimeout;
+tSDL_PushEvent *SDL_PushEvent;
+tSDL_SetEventFilter *SDL_SetEventFilter;
+tSDL_GetEventFilter *SDL_GetEventFilter;
+tSDL_AddEventWatch *SDL_AddEventWatch;
+tSDL_DelEventWatch *SDL_DelEventWatch;
+tSDL_FilterEvents *SDL_FilterEvents;
+tSDL_EventState *SDL_EventState;
+tSDL_RegisterEvents *SDL_RegisterEvents;
+tSDL_GetMouseFocus *SDL_GetMouseFocus;
+tSDL_GetMouseState *SDL_GetMouseState;
+tSDL_GetRelativeMouseState *SDL_GetRelativeMouseState;
+tSDL_WarpMouseInWindow *SDL_WarpMouseInWindow;
+tSDL_SetRelativeMouseMode *SDL_SetRelativeMouseMode;
+tSDL_GetRelativeMouseMode *SDL_GetRelativeMouseMode;
+tSDL_CreateCursor *SDL_CreateCursor;
+tSDL_CreateColorCursor *SDL_CreateColorCursor;
+tSDL_CreateSystemCursor *SDL_CreateSystemCursor;
+tSDL_SetCursor *SDL_SetCursor;
+tSDL_GetCursor *SDL_GetCursor;
+tSDL_GetDefaultCursor *SDL_GetDefaultCursor;
+tSDL_FreeCursor *SDL_FreeCursor;
+tSDL_ShowCursor *SDL_ShowCursor;
+tSDL_GetThreadName *SDL_GetThreadName;
+tSDL_ThreadID *SDL_ThreadID;
+tSDL_GetThreadID *SDL_GetThreadID;
+tSDL_SetThreadPriority *SDL_SetThreadPriority;
+tSDL_WaitThread *SDL_WaitThread;
+tSDL_TLSCreate *SDL_TLSCreate;
+tSDL_TLSGet *SDL_TLSGet;
+tSDL_TLSSet *SDL_TLSSet;
+tSDL_GetKeyboardFocus *SDL_GetKeyboardFocus;
+tSDL_GetKeyboardState *SDL_GetKeyboardState;
+tSDL_GetModState *SDL_GetModState;
+tSDL_SetModState *SDL_SetModState;
+tSDL_GetKeyFromScancode *SDL_GetKeyFromScancode;
+tSDL_GetScancodeFromKey *SDL_GetScancodeFromKey;
+tSDL_GetScancodeName *SDL_GetScancodeName;
+tSDL_GetScancodeFromName *SDL_GetScancodeFromName;
+tSDL_GetKeyName *SDL_GetKeyName;
+tSDL_GetKeyFromName *SDL_GetKeyFromName;
+tSDL_StartTextInput *SDL_StartTextInput;
+tSDL_IsTextInputActive *SDL_IsTextInputActive;
+tSDL_StopTextInput *SDL_StopTextInput;
+tSDL_SetTextInputRect *SDL_SetTextInputRect;
+tSDL_HasScreenKeyboardSupport *SDL_HasScreenKeyboardSupport;
+tSDL_IsScreenKeyboardShown *SDL_IsScreenKeyboardShown;
+tSDL_GameControllerAddMapping *SDL_GameControllerAddMapping;
+tSDL_GameControllerMappingForGUID *SDL_GameControllerMappingForGUID;
+tSDL_GameControllerMapping *SDL_GameControllerMapping;
+tSDL_IsGameController *SDL_IsGameController;
+tSDL_GameControllerNameForIndex *SDL_GameControllerNameForIndex;
+tSDL_GameControllerOpen *SDL_GameControllerOpen;
+tSDL_GameControllerName *SDL_GameControllerName;
+tSDL_GameControllerGetAttached *SDL_GameControllerGetAttached;
+tSDL_GameControllerGetJoystick *SDL_GameControllerGetJoystick;
+tSDL_GameControllerEventState *SDL_GameControllerEventState;
+tSDL_GameControllerUpdate *SDL_GameControllerUpdate;
+tSDL_GameControllerGetAxisFromString *SDL_GameControllerGetAxisFromString;
+tSDL_GameControllerGetButtonFromString *SDL_GameControllerGetButtonFromString;
+tSDL_GameControllerGetButton *SDL_GameControllerGetButton;
+tSDL_GameControllerClose *SDL_GameControllerClose;
+tSDL_GetNumAudioDrivers *SDL_GetNumAudioDrivers;
+tSDL_GetAudioDriver *SDL_GetAudioDriver;
+tSDL_AudioInit *SDL_AudioInit;
+tSDL_AudioQuit *SDL_AudioQuit;
+tSDL_GetCurrentAudioDriver *SDL_GetCurrentAudioDriver;
+tSDL_OpenAudio *SDL_OpenAudio;
+tSDL_GetNumAudioDevices *SDL_GetNumAudioDevices;
+tSDL_GetAudioDeviceName *SDL_GetAudioDeviceName;
+tSDL_OpenAudioDevice *SDL_OpenAudioDevice;
+tSDL_GetAudioStatus *SDL_GetAudioStatus;
+tSDL_PauseAudio *SDL_PauseAudio;
+tSDL_PauseAudioDevice *SDL_PauseAudioDevice;
+tSDL_LoadWAV_RW *SDL_LoadWAV_RW;
+tSDL_FreeWAV *SDL_FreeWAV;
+tSDL_BuildAudioCVT *SDL_BuildAudioCVT;
+tSDL_ConvertAudio *SDL_ConvertAudio;
+tSDL_MixAudio *SDL_MixAudio;
+tSDL_MixAudioFormat *SDL_MixAudioFormat;
+tSDL_LockAudio *SDL_LockAudio;
+tSDL_LockAudioDevice *SDL_LockAudioDevice;
+tSDL_UnlockAudio *SDL_UnlockAudio;
+tSDL_UnlockAudioDevice *SDL_UnlockAudioDevice;
+tSDL_CloseAudio *SDL_CloseAudio;
+tSDL_CloseAudioDevice *SDL_CloseAudioDevice;
+tSDL_GetNumVideoDrivers *SDL_GetNumVideoDrivers;
+tSDL_GetVideoDriver *SDL_GetVideoDriver;
+tSDL_VideoInit *SDL_VideoInit;
+tSDL_VideoQuit *SDL_VideoQuit;
+tSDL_GetCurrentVideoDriver *SDL_GetCurrentVideoDriver;
+tSDL_GetNumVideoDisplays *SDL_GetNumVideoDisplays;
+tSDL_GetDisplayName *SDL_GetDisplayName;
+tSDL_GetDisplayBounds *SDL_GetDisplayBounds;
+tSDL_GetNumDisplayModes *SDL_GetNumDisplayModes;
+tSDL_GetDisplayMode *SDL_GetDisplayMode;
+tSDL_GetDesktopDisplayMode *SDL_GetDesktopDisplayMode;
+tSDL_GetCurrentDisplayMode *SDL_GetCurrentDisplayMode;
+tSDL_GetClosestDisplayMode *SDL_GetClosestDisplayMode;
+tSDL_GetWindowDisplayIndex *SDL_GetWindowDisplayIndex;
+tSDL_SetWindowDisplayMode *SDL_SetWindowDisplayMode;
+tSDL_GetWindowDisplayMode *SDL_GetWindowDisplayMode;
+tSDL_GetWindowPixelFormat *SDL_GetWindowPixelFormat;
+tSDL_CreateWindow *SDL_CreateWindow;
+tSDL_CreateWindowFrom *SDL_CreateWindowFrom;
+tSDL_GetWindowID *SDL_GetWindowID;
+tSDL_GetWindowFromID *SDL_GetWindowFromID;
+tSDL_GetWindowFlags *SDL_GetWindowFlags;
+tSDL_SetWindowTitle *SDL_SetWindowTitle;
+tSDL_GetWindowTitle *SDL_GetWindowTitle;
+tSDL_SetWindowIcon *SDL_SetWindowIcon;
+tSDL_GetWindowData *SDL_GetWindowData;
+tSDL_SetWindowPosition *SDL_SetWindowPosition;
+tSDL_GetWindowPosition *SDL_GetWindowPosition;
+tSDL_SetWindowSize *SDL_SetWindowSize;
+tSDL_GetWindowSize *SDL_GetWindowSize;
+tSDL_SetWindowMinimumSize *SDL_SetWindowMinimumSize;
+tSDL_GetWindowMinimumSize *SDL_GetWindowMinimumSize;
+tSDL_SetWindowMaximumSize *SDL_SetWindowMaximumSize;
+tSDL_GetWindowMaximumSize *SDL_GetWindowMaximumSize;
+tSDL_SetWindowBordered *SDL_SetWindowBordered;
+tSDL_ShowWindow *SDL_ShowWindow;
+tSDL_HideWindow *SDL_HideWindow;
+tSDL_RaiseWindow *SDL_RaiseWindow;
+tSDL_MaximizeWindow *SDL_MaximizeWindow;
+tSDL_MinimizeWindow *SDL_MinimizeWindow;
+tSDL_RestoreWindow *SDL_RestoreWindow;
+tSDL_SetWindowFullscreen *SDL_SetWindowFullscreen;
+tSDL_GetWindowSurface *SDL_GetWindowSurface;
+tSDL_UpdateWindowSurface *SDL_UpdateWindowSurface;
+tSDL_UpdateWindowSurfaceRects *SDL_UpdateWindowSurfaceRects;
+tSDL_SetWindowGrab *SDL_SetWindowGrab;
+tSDL_GetWindowGrab *SDL_GetWindowGrab;
+tSDL_SetWindowBrightness *SDL_SetWindowBrightness;
+tSDL_GetWindowBrightness *SDL_GetWindowBrightness;
+tSDL_SetWindowGammaRamp *SDL_SetWindowGammaRamp;
+tSDL_GetWindowGammaRamp *SDL_GetWindowGammaRamp;
+tSDL_DestroyWindow *SDL_DestroyWindow;
+tSDL_IsScreenSaverEnabled *SDL_IsScreenSaverEnabled;
+tSDL_EnableScreenSaver *SDL_EnableScreenSaver;
+tSDL_DisableScreenSaver *SDL_DisableScreenSaver;
+tSDL_GL_LoadLibrary *SDL_GL_LoadLibrary;
+tSDL_GL_GetProcAddress *SDL_GL_GetProcAddress;
+tSDL_GL_UnloadLibrary *SDL_GL_UnloadLibrary;
+tSDL_GL_ExtensionSupported *SDL_GL_ExtensionSupported;
+tSDL_GL_SetAttribute *SDL_GL_SetAttribute;
+tSDL_GL_GetAttribute *SDL_GL_GetAttribute;
+tSDL_GL_CreateContext *SDL_GL_CreateContext;
+tSDL_GL_MakeCurrent *SDL_GL_MakeCurrent;
+tSDL_GL_GetCurrentContext *SDL_GL_GetCurrentContext;
+tSDL_GL_SetSwapInterval *SDL_GL_SetSwapInterval;
+tSDL_GL_GetSwapInterval *SDL_GL_GetSwapInterval;
+tSDL_GL_SwapWindow *SDL_GL_SwapWindow;
+tSDL_GL_DeleteContext *SDL_GL_DeleteContext;
+tSDL_RWFromFile *SDL_RWFromFile;
+tSDL_RWFromFP *SDL_RWFromFP;
+tSDL_RWFromFP *SDL_RWFromFP;
+tSDL_RWFromMem *SDL_RWFromMem;
+tSDL_RWFromConstMem *SDL_RWFromConstMem;
+tSDL_AllocRW *SDL_AllocRW;
+tSDL_FreeRW *SDL_FreeRW;
+tSDL_ReadU8 *SDL_ReadU8;
+tSDL_ReadLE16 *SDL_ReadLE16;
+tSDL_ReadBE16 *SDL_ReadBE16;
+tSDL_ReadLE32 *SDL_ReadLE32;
+tSDL_ReadBE32 *SDL_ReadBE32;
+tSDL_ReadLE64 *SDL_ReadLE64;
+tSDL_ReadBE64 *SDL_ReadBE64;
+tSDL_WriteU8 *SDL_WriteU8;
+tSDL_WriteLE16 *SDL_WriteLE16;
+tSDL_WriteBE16 *SDL_WriteBE16;
+tSDL_WriteLE32 *SDL_WriteLE32;
+tSDL_WriteBE32 *SDL_WriteBE32;
+tSDL_WriteLE64 *SDL_WriteLE64;
+tSDL_WriteBE64 *SDL_WriteBE64;
+tSDL_Init *SDL_Init;
+tSDL_InitSubSystem *SDL_InitSubSystem;
+tSDL_QuitSubSystem *SDL_QuitSubSystem;
+tSDL_WasInit *SDL_WasInit;
+tSDL_Quit *SDL_Quit;
+tSDL_GetVersion *SDL_GetVersion;
+tSDL_GetRevision *SDL_GetRevision;
+tSDL_GetRevisionNumber *SDL_GetRevisionNumber;
+tSDL_GetTicks *SDL_GetTicks;
+tSDL_GetPerformanceCounter *SDL_GetPerformanceCounter;
+tSDL_GetPerformanceFrequency *SDL_GetPerformanceFrequency;
+tSDL_Delay *SDL_Delay;
+tSDL_AddTimer *SDL_AddTimer;
+tSDL_RemoveTimer *SDL_RemoveTimer;
+tSDL_SetHintWithPriority *SDL_SetHintWithPriority;
+tSDL_SetHint *SDL_SetHint;
+tSDL_GetHint *SDL_GetHint;
+tSDL_AddHintCallback *SDL_AddHintCallback;
+tSDL_DelHintCallback *SDL_DelHintCallback;
+tSDL_ClearHints *SDL_ClearHints;
+tSDL_NumJoysticks *SDL_NumJoysticks;
+tSDL_JoystickNameForIndex *SDL_JoystickNameForIndex;
+tSDL_JoystickOpen *SDL_JoystickOpen;
+tSDL_JoystickName *SDL_JoystickName;
+tSDL_JoystickGetDeviceGUID *SDL_JoystickGetDeviceGUID;
+tSDL_JoystickGetGUID *SDL_JoystickGetGUID;
+tSDL_JoystickGetGUIDFromString *SDL_JoystickGetGUIDFromString;
+tSDL_JoystickGetAttached *SDL_JoystickGetAttached;
+tSDL_JoystickInstanceID *SDL_JoystickInstanceID;
+tSDL_JoystickNumAxes *SDL_JoystickNumAxes;
+tSDL_JoystickNumBalls *SDL_JoystickNumBalls;
+tSDL_JoystickNumHats *SDL_JoystickNumHats;
+tSDL_JoystickNumButtons *SDL_JoystickNumButtons;
+tSDL_JoystickUpdate *SDL_JoystickUpdate;
+tSDL_JoystickEventState *SDL_JoystickEventState;
+tSDL_JoystickGetAxis *SDL_JoystickGetAxis;
+tSDL_JoystickGetHat *SDL_JoystickGetHat;
+tSDL_JoystickGetBall *SDL_JoystickGetBall;
+tSDL_JoystickGetButton *SDL_JoystickGetButton;
+tSDL_JoystickClose *SDL_JoystickClose;
+tSDL_RecordGesture *SDL_RecordGesture;
+tSDL_SaveAllDollarTemplates *SDL_SaveAllDollarTemplates;
+tSDL_SaveDollarTemplate *SDL_SaveDollarTemplate;
+tSDL_LoadDollarTemplates *SDL_LoadDollarTemplates;
+tSDL_NumHaptics *SDL_NumHaptics;
+tSDL_HapticName *SDL_HapticName;
+tSDL_HapticOpen *SDL_HapticOpen;
+tSDL_HapticOpened *SDL_HapticOpened;
+tSDL_HapticIndex *SDL_HapticIndex;
+tSDL_MouseIsHaptic *SDL_MouseIsHaptic;
+tSDL_HapticOpenFromMouse *SDL_HapticOpenFromMouse;
+tSDL_JoystickIsHaptic *SDL_JoystickIsHaptic;
+tSDL_HapticOpenFromJoystick *SDL_HapticOpenFromJoystick;
+tSDL_HapticClose *SDL_HapticClose;
+tSDL_HapticNumEffects *SDL_HapticNumEffects;
+tSDL_HapticNumEffectsPlaying *SDL_HapticNumEffectsPlaying;
+tSDL_HapticNumAxes *SDL_HapticNumAxes;
+tSDL_HapticEffectSupported *SDL_HapticEffectSupported;
+tSDL_HapticNewEffect *SDL_HapticNewEffect;
+tSDL_HapticUpdateEffect *SDL_HapticUpdateEffect;
+tSDL_HapticRunEffect *SDL_HapticRunEffect;
+tSDL_HapticStopEffect *SDL_HapticStopEffect;
+tSDL_HapticDestroyEffect *SDL_HapticDestroyEffect;
+tSDL_HapticGetEffectStatus *SDL_HapticGetEffectStatus;
+tSDL_HapticSetGain *SDL_HapticSetGain;
+tSDL_HapticSetAutocenter *SDL_HapticSetAutocenter;
+tSDL_HapticPause *SDL_HapticPause;
+tSDL_HapticUnpause *SDL_HapticUnpause;
+tSDL_HapticStopAll *SDL_HapticStopAll;
+tSDL_HapticRumbleSupported *SDL_HapticRumbleSupported;
+tSDL_HapticRumbleInit *SDL_HapticRumbleInit;
+tSDL_HapticRumblePlay *SDL_HapticRumblePlay;
+tSDL_HapticRumbleStop *SDL_HapticRumbleStop;
+tSDL_ShowMessageBox *SDL_ShowMessageBox;
+tSDL_ShowSimpleMessageBox *SDL_ShowSimpleMessageBox;
+tSDL_PixelFormatEnumToMasks *SDL_PixelFormatEnumToMasks;
+tSDL_MasksToPixelFormatEnum *SDL_MasksToPixelFormatEnum;
+tSDL_AllocFormat *SDL_AllocFormat;
+tSDL_FreeFormat *SDL_FreeFormat;
+tSDL_AllocPalette *SDL_AllocPalette;
+tSDL_SetPixelFormatPalette *SDL_SetPixelFormatPalette;
+tSDL_SetPaletteColors *SDL_SetPaletteColors;
+tSDL_FreePalette *SDL_FreePalette;
+tSDL_MapRGB *SDL_MapRGB;
+tSDL_MapRGBA *SDL_MapRGBA;
+tSDL_GetRGB *SDL_GetRGB;
+tSDL_GetRGBA *SDL_GetRGBA;
+tSDL_CalculateGammaRamp *SDL_CalculateGammaRamp;
+tSDL_GetPowerInfo *SDL_GetPowerInfo;
+tSDL_GetCPUCount *SDL_GetCPUCount;
+tSDL_GetCPUCacheLineSize *SDL_GetCPUCacheLineSize;
+tSDL_HasRDTSC *SDL_HasRDTSC;
+tSDL_HasAltiVec *SDL_HasAltiVec;
+tSDL_HasMMX *SDL_HasMMX;
+tSDL_Has3DNow *SDL_Has3DNow;
+tSDL_HasSSE *SDL_HasSSE;
+tSDL_HasSSE2 *SDL_HasSSE2;
+tSDL_HasSSE3 *SDL_HasSSE3;
+tSDL_HasSSE41 *SDL_HasSSE41;
+tSDL_HasSSE42 *SDL_HasSSE42;
+tSDL_GetNumTouchDevices *SDL_GetNumTouchDevices;
+tSDL_GetTouchDevice *SDL_GetTouchDevice;
+tSDL_GetNumTouchFingers *SDL_GetNumTouchFingers;
+tSDL_GetTouchFinger *SDL_GetTouchFinger;
+tSDL_SetError *SDL_SetError;
+tSDL_GetError *SDL_GetError;
+tSDL_ClearError *SDL_ClearError;
+tSDL_Error *SDL_Error;
+tSDL_SetClipboardText *SDL_SetClipboardText;
+tSDL_GetClipboardText *SDL_GetClipboardText;
+tSDL_HasClipboardText *SDL_HasClipboardText;
+tSDL_GetWindowWMInfo *SDL_GetWindowWMInfo;
+
+static void sdlewExit(void) {
+ if(lib != NULL) {
+ /* Ignore errors. */
+ dynamic_library_close(lib);
+ lib = NULL;
+ }
+}
+
+/* Implementation function. */
+int sdlewInit(void) {
+ /* Library paths. */
+#ifdef _WIN32
+ /* Expected in c:/windows/system or similar, no path needed. */
+ const char *paths[] = {"SDL2.dll", NULL};
+#elif defined(__APPLE__)
+ /* Default installation path. */
+ const char *paths[] = {"/usr/local/cuda/lib/libSDL2.dylib", NULL};
+#else
+ const char *paths[] = {"libSDL2.so",
+ "libSDL2-2.0.so.0",
+ "libSDL.so",
+ NULL};
+#endif
+ static int initialized = 0;
+ static int result = 0;
+ int a, error;
+ SDL_version version;
+
+ if (initialized) {
+ return result;
+ }
+
+ initialized = 1;
+
+ error = atexit(sdlewExit);
+ if (error) {
+ result = SDLEW_ERROR_ATEXIT_FAILED;
+ return result;
+ }
+
+ /* Load library. */
+ for (a = 0; paths[a] != NULL && lib == NULL; ++a) {
+ lib = dynamic_library_open(paths[a]);
+ }
+
+ if (lib == NULL) {
+ result = SDLEW_ERROR_OPEN_FAILED;
+ return result;
+ }
+
+ SDL_LIBRARY_FIND(SDL_GetPlatform);
+ SDL_LIBRARY_FIND(SDL_memcpy);
+#ifndef HAVE_ALLOCA
+ SDL_LIBRARY_FIND(SDL_malloc);
+#endif
+ SDL_LIBRARY_FIND(SDL_calloc);
+ SDL_LIBRARY_FIND(SDL_realloc);
+ SDL_LIBRARY_FIND(SDL_free);
+ SDL_LIBRARY_FIND(SDL_getenv);
+ SDL_LIBRARY_FIND(SDL_setenv);
+ SDL_LIBRARY_FIND(SDL_qsort);
+ SDL_LIBRARY_FIND(SDL_abs);
+ SDL_LIBRARY_FIND(SDL_isdigit);
+ SDL_LIBRARY_FIND(SDL_isspace);
+ SDL_LIBRARY_FIND(SDL_toupper);
+ SDL_LIBRARY_FIND(SDL_tolower);
+ SDL_LIBRARY_FIND(SDL_memset);
+ SDL_LIBRARY_FIND(SDL_memmove);
+ SDL_LIBRARY_FIND(SDL_memcmp);
+ SDL_LIBRARY_FIND(SDL_wcslen);
+ SDL_LIBRARY_FIND(SDL_wcslcpy);
+ SDL_LIBRARY_FIND(SDL_wcslcat);
+ SDL_LIBRARY_FIND(SDL_strlen);
+ SDL_LIBRARY_FIND(SDL_strlcpy);
+ SDL_LIBRARY_FIND(SDL_utf8strlcpy);
+ SDL_LIBRARY_FIND(SDL_strlcat);
+ SDL_LIBRARY_FIND(SDL_strdup);
+ SDL_LIBRARY_FIND(SDL_strrev);
+ SDL_LIBRARY_FIND(SDL_strupr);
+ SDL_LIBRARY_FIND(SDL_strlwr);
+ SDL_LIBRARY_FIND(SDL_strchr);
+ SDL_LIBRARY_FIND(SDL_strrchr);
+ SDL_LIBRARY_FIND(SDL_strstr);
+ SDL_LIBRARY_FIND(SDL_itoa);
+ SDL_LIBRARY_FIND(SDL_uitoa);
+ SDL_LIBRARY_FIND(SDL_ltoa);
+ SDL_LIBRARY_FIND(SDL_ultoa);
+ SDL_LIBRARY_FIND(SDL_lltoa);
+ SDL_LIBRARY_FIND(SDL_ulltoa);
+ SDL_LIBRARY_FIND(SDL_atoi);
+ SDL_LIBRARY_FIND(SDL_atof);
+ SDL_LIBRARY_FIND(SDL_strtol);
+ SDL_LIBRARY_FIND(SDL_strtoll);
+ SDL_LIBRARY_FIND(SDL_strtoull);
+ SDL_LIBRARY_FIND(SDL_strtod);
+ SDL_LIBRARY_FIND(SDL_strcmp);
+ SDL_LIBRARY_FIND(SDL_strncmp);
+ SDL_LIBRARY_FIND(SDL_strcasecmp);
+ SDL_LIBRARY_FIND(SDL_strncasecmp);
+ SDL_LIBRARY_FIND(SDL_sscanf);
+ SDL_LIBRARY_FIND(SDL_snprintf);
+ SDL_LIBRARY_FIND(SDL_vsnprintf);
+ SDL_LIBRARY_FIND(SDL_atan);
+ SDL_LIBRARY_FIND(SDL_atan2);
+ SDL_LIBRARY_FIND(SDL_ceil);
+ SDL_LIBRARY_FIND(SDL_copysign);
+ SDL_LIBRARY_FIND(SDL_cos);
+ SDL_LIBRARY_FIND(SDL_cosf);
+ SDL_LIBRARY_FIND(SDL_fabs);
+ SDL_LIBRARY_FIND(SDL_floor);
+ SDL_LIBRARY_FIND(SDL_log);
+ SDL_LIBRARY_FIND(SDL_pow);
+ SDL_LIBRARY_FIND(SDL_scalbn);
+ SDL_LIBRARY_FIND(SDL_sin);
+ SDL_LIBRARY_FIND(SDL_sinf);
+ SDL_LIBRARY_FIND(SDL_sqrt);
+ SDL_LIBRARY_FIND(SDL_iconv_open);
+ SDL_LIBRARY_FIND(SDL_iconv_close);
+ SDL_LIBRARY_FIND(SDL_iconv);
+ SDL_LIBRARY_FIND(SDL_iconv_string);
+ SDL_LIBRARY_FIND(SDL_GetNumRenderDrivers);
+ SDL_LIBRARY_FIND(SDL_GetRenderDriverInfo);
+ SDL_LIBRARY_FIND(SDL_CreateWindowAndRenderer);
+ SDL_LIBRARY_FIND(SDL_CreateRenderer);
+ SDL_LIBRARY_FIND(SDL_CreateSoftwareRenderer);
+ SDL_LIBRARY_FIND(SDL_GetRenderer);
+ SDL_LIBRARY_FIND(SDL_GetRendererInfo);
+ SDL_LIBRARY_FIND(SDL_GetRendererOutputSize);
+ SDL_LIBRARY_FIND(SDL_CreateTexture);
+ SDL_LIBRARY_FIND(SDL_CreateTextureFromSurface);
+ SDL_LIBRARY_FIND(SDL_QueryTexture);
+ SDL_LIBRARY_FIND(SDL_SetTextureColorMod);
+ SDL_LIBRARY_FIND(SDL_GetTextureColorMod);
+ SDL_LIBRARY_FIND(SDL_SetTextureAlphaMod);
+ SDL_LIBRARY_FIND(SDL_GetTextureAlphaMod);
+ SDL_LIBRARY_FIND(SDL_SetTextureBlendMode);
+ SDL_LIBRARY_FIND(SDL_GetTextureBlendMode);
+ SDL_LIBRARY_FIND(SDL_UpdateTexture);
+ SDL_LIBRARY_FIND(SDL_LockTexture);
+ SDL_LIBRARY_FIND(SDL_UnlockTexture);
+ SDL_LIBRARY_FIND(SDL_RenderTargetSupported);
+ SDL_LIBRARY_FIND(SDL_SetRenderTarget);
+ SDL_LIBRARY_FIND(SDL_GetRenderTarget);
+ SDL_LIBRARY_FIND(SDL_RenderSetLogicalSize);
+ SDL_LIBRARY_FIND(SDL_RenderGetLogicalSize);
+ SDL_LIBRARY_FIND(SDL_RenderSetViewport);
+ SDL_LIBRARY_FIND(SDL_RenderGetViewport);
+ SDL_LIBRARY_FIND(SDL_RenderSetClipRect);
+ SDL_LIBRARY_FIND(SDL_RenderGetClipRect);
+ SDL_LIBRARY_FIND(SDL_RenderSetScale);
+ SDL_LIBRARY_FIND(SDL_RenderGetScale);
+ SDL_LIBRARY_FIND(SDL_SetRenderDrawBlendMode);
+ SDL_LIBRARY_FIND(SDL_GetRenderDrawBlendMode);
+ SDL_LIBRARY_FIND(SDL_RenderClear);
+ SDL_LIBRARY_FIND(SDL_RenderDrawPoint);
+ SDL_LIBRARY_FIND(SDL_RenderDrawPoints);
+ SDL_LIBRARY_FIND(SDL_RenderDrawLine);
+ SDL_LIBRARY_FIND(SDL_RenderDrawLines);
+ SDL_LIBRARY_FIND(SDL_RenderDrawRect);
+ SDL_LIBRARY_FIND(SDL_RenderDrawRects);
+ SDL_LIBRARY_FIND(SDL_RenderFillRect);
+ SDL_LIBRARY_FIND(SDL_RenderFillRects);
+ SDL_LIBRARY_FIND(SDL_RenderCopy);
+ SDL_LIBRARY_FIND(SDL_RenderCopyEx);
+ SDL_LIBRARY_FIND(SDL_RenderReadPixels);
+ SDL_LIBRARY_FIND(SDL_RenderPresent);
+ SDL_LIBRARY_FIND(SDL_DestroyTexture);
+ SDL_LIBRARY_FIND(SDL_DestroyRenderer);
+ SDL_LIBRARY_FIND(SDL_GL_BindTexture);
+ SDL_LIBRARY_FIND(SDL_GL_UnbindTexture);
+ SDL_LIBRARY_FIND(SDL_LoadObject);
+ SDL_LIBRARY_FIND(SDL_LoadFunction);
+ SDL_LIBRARY_FIND(SDL_UnloadObject);
+ SDL_LIBRARY_FIND(SDL_ReportAssertion);
+ SDL_LIBRARY_FIND(SDL_SetAssertionHandler);
+ SDL_LIBRARY_FIND(SDL_GetAssertionReport);
+ SDL_LIBRARY_FIND(SDL_ResetAssertionReport);
+ SDL_LIBRARY_FIND(SDL_AtomicTryLock);
+ SDL_LIBRARY_FIND(SDL_AtomicLock);
+ SDL_LIBRARY_FIND(SDL_AtomicUnlock);
+ SDL_LIBRARY_FIND(SDL_HasIntersection);
+ SDL_LIBRARY_FIND(SDL_IntersectRect);
+ SDL_LIBRARY_FIND(SDL_UnionRect);
+ SDL_LIBRARY_FIND(SDL_EnclosePoints);
+ SDL_LIBRARY_FIND(SDL_IntersectRectAndLine);
+ SDL_LIBRARY_FIND(SDL_LogSetAllPriority);
+ SDL_LIBRARY_FIND(SDL_LogSetPriority);
+ SDL_LIBRARY_FIND(SDL_LogGetPriority);
+ SDL_LIBRARY_FIND(SDL_LogResetPriorities);
+ SDL_LIBRARY_FIND(SDL_Log);
+ SDL_LIBRARY_FIND(SDL_LogVerbose);
+ SDL_LIBRARY_FIND(SDL_LogDebug);
+ SDL_LIBRARY_FIND(SDL_LogInfo);
+ SDL_LIBRARY_FIND(SDL_LogWarn);
+ SDL_LIBRARY_FIND(SDL_LogError);
+ SDL_LIBRARY_FIND(SDL_LogCritical);
+ SDL_LIBRARY_FIND(SDL_LogMessage);
+ SDL_LIBRARY_FIND(SDL_LogMessageV);
+ SDL_LIBRARY_FIND(SDL_LogGetOutputFunction);
+ SDL_LIBRARY_FIND(SDL_LogSetOutputFunction);
+ SDL_LIBRARY_FIND(SDL_CreateMutex);
+ SDL_LIBRARY_FIND(SDL_LockMutex);
+ SDL_LIBRARY_FIND(SDL_TryLockMutex);
+ SDL_LIBRARY_FIND(SDL_UnlockMutex);
+ SDL_LIBRARY_FIND(SDL_DestroyMutex);
+ SDL_LIBRARY_FIND(SDL_CreateSemaphore);
+ SDL_LIBRARY_FIND(SDL_DestroySemaphore);
+ SDL_LIBRARY_FIND(SDL_SemWait);
+ SDL_LIBRARY_FIND(SDL_SemTryWait);
+ SDL_LIBRARY_FIND(SDL_SemWaitTimeout);
+ SDL_LIBRARY_FIND(SDL_SemPost);
+ SDL_LIBRARY_FIND(SDL_SemValue);
+ SDL_LIBRARY_FIND(SDL_CreateCond);
+ SDL_LIBRARY_FIND(SDL_DestroyCond);
+ SDL_LIBRARY_FIND(SDL_CondSignal);
+ SDL_LIBRARY_FIND(SDL_CondBroadcast);
+ SDL_LIBRARY_FIND(SDL_CondWait);
+ SDL_LIBRARY_FIND(SDL_CondWaitTimeout);
+ SDL_LIBRARY_FIND(SDL_CreateRGBSurface);
+ SDL_LIBRARY_FIND(SDL_CreateRGBSurfaceFrom);
+ SDL_LIBRARY_FIND(SDL_FreeSurface);
+ SDL_LIBRARY_FIND(SDL_SetSurfacePalette);
+ SDL_LIBRARY_FIND(SDL_LockSurface);
+ SDL_LIBRARY_FIND(SDL_UnlockSurface);
+ SDL_LIBRARY_FIND(SDL_LoadBMP_RW);
+ SDL_LIBRARY_FIND(SDL_SaveBMP_RW);
+ SDL_LIBRARY_FIND(SDL_SetSurfaceRLE);
+ SDL_LIBRARY_FIND(SDL_SetColorKey);
+ SDL_LIBRARY_FIND(SDL_GetColorKey);
+ SDL_LIBRARY_FIND(SDL_SetSurfaceColorMod);
+ SDL_LIBRARY_FIND(SDL_GetSurfaceColorMod);
+ SDL_LIBRARY_FIND(SDL_SetSurfaceAlphaMod);
+ SDL_LIBRARY_FIND(SDL_GetSurfaceAlphaMod);
+ SDL_LIBRARY_FIND(SDL_SetSurfaceBlendMode);
+ SDL_LIBRARY_FIND(SDL_GetSurfaceBlendMode);
+ SDL_LIBRARY_FIND(SDL_SetClipRect);
+ SDL_LIBRARY_FIND(SDL_GetClipRect);
+ SDL_LIBRARY_FIND(SDL_ConvertSurface);
+ SDL_LIBRARY_FIND(SDL_ConvertSurfaceFormat);
+ SDL_LIBRARY_FIND(SDL_ConvertPixels);
+ SDL_LIBRARY_FIND(SDL_FillRect);
+ SDL_LIBRARY_FIND(SDL_FillRects);
+ SDL_LIBRARY_FIND(SDL_UpperBlit);
+ SDL_LIBRARY_FIND(SDL_LowerBlit);
+ SDL_LIBRARY_FIND(SDL_SoftStretch);
+ SDL_LIBRARY_FIND(SDL_UpperBlitScaled);
+ SDL_LIBRARY_FIND(SDL_LowerBlitScaled);
+ SDL_LIBRARY_FIND(SDL_PumpEvents);
+ SDL_LIBRARY_FIND(SDL_PeepEvents);
+ SDL_LIBRARY_FIND(SDL_HasEvent);
+ SDL_LIBRARY_FIND(SDL_HasEvents);
+ SDL_LIBRARY_FIND(SDL_FlushEvent);
+ SDL_LIBRARY_FIND(SDL_FlushEvents);
+ SDL_LIBRARY_FIND(SDL_PollEvent);
+ SDL_LIBRARY_FIND(SDL_WaitEvent);
+ SDL_LIBRARY_FIND(SDL_WaitEventTimeout);
+ SDL_LIBRARY_FIND(SDL_PushEvent);
+ SDL_LIBRARY_FIND(SDL_SetEventFilter);
+ SDL_LIBRARY_FIND(SDL_GetEventFilter);
+ SDL_LIBRARY_FIND(SDL_AddEventWatch);
+ SDL_LIBRARY_FIND(SDL_DelEventWatch);
+ SDL_LIBRARY_FIND(SDL_FilterEvents);
+ SDL_LIBRARY_FIND(SDL_EventState);
+ SDL_LIBRARY_FIND(SDL_RegisterEvents);
+ SDL_LIBRARY_FIND(SDL_GetMouseFocus);
+ SDL_LIBRARY_FIND(SDL_GetMouseState);
+ SDL_LIBRARY_FIND(SDL_GetRelativeMouseState);
+ SDL_LIBRARY_FIND(SDL_WarpMouseInWindow);
+ SDL_LIBRARY_FIND(SDL_SetRelativeMouseMode);
+ SDL_LIBRARY_FIND(SDL_GetRelativeMouseMode);
+ SDL_LIBRARY_FIND(SDL_CreateCursor);
+ SDL_LIBRARY_FIND(SDL_CreateColorCursor);
+ SDL_LIBRARY_FIND(SDL_CreateSystemCursor);
+ SDL_LIBRARY_FIND(SDL_SetCursor);
+ SDL_LIBRARY_FIND(SDL_GetCursor);
+ SDL_LIBRARY_FIND(SDL_GetDefaultCursor);
+ SDL_LIBRARY_FIND(SDL_FreeCursor);
+ SDL_LIBRARY_FIND(SDL_ShowCursor);
+ SDL_LIBRARY_FIND(SDL_GetThreadName);
+ SDL_LIBRARY_FIND(SDL_ThreadID);
+ SDL_LIBRARY_FIND(SDL_GetThreadID);
+ SDL_LIBRARY_FIND(SDL_SetThreadPriority);
+ SDL_LIBRARY_FIND(SDL_WaitThread);
+ SDL_LIBRARY_FIND(SDL_TLSCreate);
+ SDL_LIBRARY_FIND(SDL_TLSGet);
+ SDL_LIBRARY_FIND(SDL_TLSSet);
+ SDL_LIBRARY_FIND(SDL_GetKeyboardFocus);
+ SDL_LIBRARY_FIND(SDL_GetKeyboardState);
+ SDL_LIBRARY_FIND(SDL_GetModState);
+ SDL_LIBRARY_FIND(SDL_SetModState);
+ SDL_LIBRARY_FIND(SDL_GetKeyFromScancode);
+ SDL_LIBRARY_FIND(SDL_GetScancodeFromKey);
+ SDL_LIBRARY_FIND(SDL_GetScancodeName);
+ SDL_LIBRARY_FIND(SDL_GetScancodeFromName);
+ SDL_LIBRARY_FIND(SDL_GetKeyName);
+ SDL_LIBRARY_FIND(SDL_GetKeyFromName);
+ SDL_LIBRARY_FIND(SDL_StartTextInput);
+ SDL_LIBRARY_FIND(SDL_IsTextInputActive);
+ SDL_LIBRARY_FIND(SDL_StopTextInput);
+ SDL_LIBRARY_FIND(SDL_SetTextInputRect);
+ SDL_LIBRARY_FIND(SDL_HasScreenKeyboardSupport);
+ SDL_LIBRARY_FIND(SDL_IsScreenKeyboardShown);
+ SDL_LIBRARY_FIND(SDL_GameControllerAddMapping);
+ SDL_LIBRARY_FIND(SDL_GameControllerMappingForGUID);
+ SDL_LIBRARY_FIND(SDL_GameControllerMapping);
+ SDL_LIBRARY_FIND(SDL_IsGameController);
+ SDL_LIBRARY_FIND(SDL_GameControllerNameForIndex);
+ SDL_LIBRARY_FIND(SDL_GameControllerOpen);
+ SDL_LIBRARY_FIND(SDL_GameControllerName);
+ SDL_LIBRARY_FIND(SDL_GameControllerGetAttached);
+ SDL_LIBRARY_FIND(SDL_GameControllerGetJoystick);
+ SDL_LIBRARY_FIND(SDL_GameControllerEventState);
+ SDL_LIBRARY_FIND(SDL_GameControllerUpdate);
+ SDL_LIBRARY_FIND(SDL_GameControllerGetAxisFromString);
+ SDL_LIBRARY_FIND(SDL_GameControllerGetButtonFromString);
+ SDL_LIBRARY_FIND(SDL_GameControllerGetButton);
+ SDL_LIBRARY_FIND(SDL_GameControllerClose);
+ SDL_LIBRARY_FIND(SDL_GetNumAudioDrivers);
+ SDL_LIBRARY_FIND(SDL_GetAudioDriver);
+ SDL_LIBRARY_FIND(SDL_AudioInit);
+ SDL_LIBRARY_FIND(SDL_AudioQuit);
+ SDL_LIBRARY_FIND(SDL_GetCurrentAudioDriver);
+ SDL_LIBRARY_FIND(SDL_OpenAudio);
+ SDL_LIBRARY_FIND(SDL_GetNumAudioDevices);
+ SDL_LIBRARY_FIND(SDL_GetAudioDeviceName);
+ SDL_LIBRARY_FIND(SDL_OpenAudioDevice);
+ SDL_LIBRARY_FIND(SDL_GetAudioStatus);
+ SDL_LIBRARY_FIND(SDL_PauseAudio);
+ SDL_LIBRARY_FIND(SDL_PauseAudioDevice);
+ SDL_LIBRARY_FIND(SDL_LoadWAV_RW);
+ SDL_LIBRARY_FIND(SDL_FreeWAV);
+ SDL_LIBRARY_FIND(SDL_BuildAudioCVT);
+ SDL_LIBRARY_FIND(SDL_ConvertAudio);
+ SDL_LIBRARY_FIND(SDL_MixAudio);
+ SDL_LIBRARY_FIND(SDL_MixAudioFormat);
+ SDL_LIBRARY_FIND(SDL_LockAudio);
+ SDL_LIBRARY_FIND(SDL_LockAudioDevice);
+ SDL_LIBRARY_FIND(SDL_UnlockAudio);
+ SDL_LIBRARY_FIND(SDL_UnlockAudioDevice);
+ SDL_LIBRARY_FIND(SDL_CloseAudio);
+ SDL_LIBRARY_FIND(SDL_CloseAudioDevice);
+ SDL_LIBRARY_FIND(SDL_GetNumVideoDrivers);
+ SDL_LIBRARY_FIND(SDL_GetVideoDriver);
+ SDL_LIBRARY_FIND(SDL_VideoInit);
+ SDL_LIBRARY_FIND(SDL_VideoQuit);
+ SDL_LIBRARY_FIND(SDL_GetCurrentVideoDriver);
+ SDL_LIBRARY_FIND(SDL_GetNumVideoDisplays);
+ SDL_LIBRARY_FIND(SDL_GetDisplayName);
+ SDL_LIBRARY_FIND(SDL_GetDisplayBounds);
+ SDL_LIBRARY_FIND(SDL_GetNumDisplayModes);
+ SDL_LIBRARY_FIND(SDL_GetDisplayMode);
+ SDL_LIBRARY_FIND(SDL_GetDesktopDisplayMode);
+ SDL_LIBRARY_FIND(SDL_GetCurrentDisplayMode);
+ SDL_LIBRARY_FIND(SDL_GetClosestDisplayMode);
+ SDL_LIBRARY_FIND(SDL_GetWindowDisplayIndex);
+ SDL_LIBRARY_FIND(SDL_SetWindowDisplayMode);
+ SDL_LIBRARY_FIND(SDL_GetWindowDisplayMode);
+ SDL_LIBRARY_FIND(SDL_GetWindowPixelFormat);
+ SDL_LIBRARY_FIND(SDL_CreateWindow);
+ SDL_LIBRARY_FIND(SDL_CreateWindowFrom);
+ SDL_LIBRARY_FIND(SDL_GetWindowID);
+ SDL_LIBRARY_FIND(SDL_GetWindowFromID);
+ SDL_LIBRARY_FIND(SDL_GetWindowFlags);
+ SDL_LIBRARY_FIND(SDL_SetWindowTitle);
+ SDL_LIBRARY_FIND(SDL_GetWindowTitle);
+ SDL_LIBRARY_FIND(SDL_SetWindowIcon);
+ SDL_LIBRARY_FIND(SDL_GetWindowData);
+ SDL_LIBRARY_FIND(SDL_SetWindowPosition);
+ SDL_LIBRARY_FIND(SDL_GetWindowPosition);
+ SDL_LIBRARY_FIND(SDL_SetWindowSize);
+ SDL_LIBRARY_FIND(SDL_GetWindowSize);
+ SDL_LIBRARY_FIND(SDL_SetWindowMinimumSize);
+ SDL_LIBRARY_FIND(SDL_GetWindowMinimumSize);
+ SDL_LIBRARY_FIND(SDL_SetWindowMaximumSize);
+ SDL_LIBRARY_FIND(SDL_GetWindowMaximumSize);
+ SDL_LIBRARY_FIND(SDL_SetWindowBordered);
+ SDL_LIBRARY_FIND(SDL_ShowWindow);
+ SDL_LIBRARY_FIND(SDL_HideWindow);
+ SDL_LIBRARY_FIND(SDL_RaiseWindow);
+ SDL_LIBRARY_FIND(SDL_MaximizeWindow);
+ SDL_LIBRARY_FIND(SDL_MinimizeWindow);
+ SDL_LIBRARY_FIND(SDL_RestoreWindow);
+ SDL_LIBRARY_FIND(SDL_SetWindowFullscreen);
+ SDL_LIBRARY_FIND(SDL_GetWindowSurface);
+ SDL_LIBRARY_FIND(SDL_UpdateWindowSurface);
+ SDL_LIBRARY_FIND(SDL_UpdateWindowSurfaceRects);
+ SDL_LIBRARY_FIND(SDL_SetWindowGrab);
+ SDL_LIBRARY_FIND(SDL_GetWindowGrab);
+ SDL_LIBRARY_FIND(SDL_SetWindowBrightness);
+ SDL_LIBRARY_FIND(SDL_GetWindowBrightness);
+ SDL_LIBRARY_FIND(SDL_SetWindowGammaRamp);
+ SDL_LIBRARY_FIND(SDL_GetWindowGammaRamp);
+ SDL_LIBRARY_FIND(SDL_DestroyWindow);
+ SDL_LIBRARY_FIND(SDL_IsScreenSaverEnabled);
+ SDL_LIBRARY_FIND(SDL_EnableScreenSaver);
+ SDL_LIBRARY_FIND(SDL_DisableScreenSaver);
+ SDL_LIBRARY_FIND(SDL_GL_LoadLibrary);
+ SDL_LIBRARY_FIND(SDL_GL_GetProcAddress);
+ SDL_LIBRARY_FIND(SDL_GL_UnloadLibrary);
+ SDL_LIBRARY_FIND(SDL_GL_ExtensionSupported);
+ SDL_LIBRARY_FIND(SDL_GL_SetAttribute);
+ SDL_LIBRARY_FIND(SDL_GL_GetAttribute);
+ SDL_LIBRARY_FIND(SDL_GL_CreateContext);
+ SDL_LIBRARY_FIND(SDL_GL_MakeCurrent);
+ SDL_LIBRARY_FIND(SDL_GL_GetCurrentContext);
+ SDL_LIBRARY_FIND(SDL_GL_SetSwapInterval);
+ SDL_LIBRARY_FIND(SDL_GL_GetSwapInterval);
+ SDL_LIBRARY_FIND(SDL_GL_SwapWindow);
+ SDL_LIBRARY_FIND(SDL_GL_DeleteContext);
+ SDL_LIBRARY_FIND(SDL_RWFromFile);
+ SDL_LIBRARY_FIND(SDL_RWFromFP);
+ SDL_LIBRARY_FIND(SDL_RWFromFP);
+ SDL_LIBRARY_FIND(SDL_RWFromMem);
+ SDL_LIBRARY_FIND(SDL_RWFromConstMem);
+ SDL_LIBRARY_FIND(SDL_AllocRW);
+ SDL_LIBRARY_FIND(SDL_FreeRW);
+ SDL_LIBRARY_FIND(SDL_ReadU8);
+ SDL_LIBRARY_FIND(SDL_ReadLE16);
+ SDL_LIBRARY_FIND(SDL_ReadBE16);
+ SDL_LIBRARY_FIND(SDL_ReadLE32);
+ SDL_LIBRARY_FIND(SDL_ReadBE32);
+ SDL_LIBRARY_FIND(SDL_ReadLE64);
+ SDL_LIBRARY_FIND(SDL_ReadBE64);
+ SDL_LIBRARY_FIND(SDL_WriteU8);
+ SDL_LIBRARY_FIND(SDL_WriteLE16);
+ SDL_LIBRARY_FIND(SDL_WriteBE16);
+ SDL_LIBRARY_FIND(SDL_WriteLE32);
+ SDL_LIBRARY_FIND(SDL_WriteBE32);
+ SDL_LIBRARY_FIND(SDL_WriteLE64);
+ SDL_LIBRARY_FIND(SDL_WriteBE64);
+ SDL_LIBRARY_FIND(SDL_Init);
+ SDL_LIBRARY_FIND(SDL_InitSubSystem);
+ SDL_LIBRARY_FIND(SDL_QuitSubSystem);
+ SDL_LIBRARY_FIND(SDL_WasInit);
+ SDL_LIBRARY_FIND(SDL_Quit);
+ SDL_LIBRARY_FIND(SDL_GetVersion);
+ SDL_LIBRARY_FIND(SDL_GetRevision);
+ SDL_LIBRARY_FIND(SDL_GetRevisionNumber);
+ SDL_LIBRARY_FIND(SDL_GetTicks);
+ SDL_LIBRARY_FIND(SDL_GetPerformanceCounter);
+ SDL_LIBRARY_FIND(SDL_GetPerformanceFrequency);
+ SDL_LIBRARY_FIND(SDL_Delay);
+ SDL_LIBRARY_FIND(SDL_AddTimer);
+ SDL_LIBRARY_FIND(SDL_RemoveTimer);
+ SDL_LIBRARY_FIND(SDL_SetHintWithPriority);
+ SDL_LIBRARY_FIND(SDL_SetHint);
+ SDL_LIBRARY_FIND(SDL_GetHint);
+ SDL_LIBRARY_FIND(SDL_AddHintCallback);
+ SDL_LIBRARY_FIND(SDL_DelHintCallback);
+ SDL_LIBRARY_FIND(SDL_ClearHints);
+ SDL_LIBRARY_FIND(SDL_NumJoysticks);
+ SDL_LIBRARY_FIND(SDL_JoystickNameForIndex);
+ SDL_LIBRARY_FIND(SDL_JoystickOpen);
+ SDL_LIBRARY_FIND(SDL_JoystickName);
+ SDL_LIBRARY_FIND(SDL_JoystickGetDeviceGUID);
+ SDL_LIBRARY_FIND(SDL_JoystickGetGUID);
+ SDL_LIBRARY_FIND(SDL_JoystickGetGUIDFromString);
+ SDL_LIBRARY_FIND(SDL_JoystickGetAttached);
+ SDL_LIBRARY_FIND(SDL_JoystickInstanceID);
+ SDL_LIBRARY_FIND(SDL_JoystickNumAxes);
+ SDL_LIBRARY_FIND(SDL_JoystickNumBalls);
+ SDL_LIBRARY_FIND(SDL_JoystickNumHats);
+ SDL_LIBRARY_FIND(SDL_JoystickNumButtons);
+ SDL_LIBRARY_FIND(SDL_JoystickUpdate);
+ SDL_LIBRARY_FIND(SDL_JoystickEventState);
+ SDL_LIBRARY_FIND(SDL_JoystickGetAxis);
+ SDL_LIBRARY_FIND(SDL_JoystickGetHat);
+ SDL_LIBRARY_FIND(SDL_JoystickGetBall);
+ SDL_LIBRARY_FIND(SDL_JoystickGetButton);
+ SDL_LIBRARY_FIND(SDL_JoystickClose);
+ SDL_LIBRARY_FIND(SDL_RecordGesture);
+ SDL_LIBRARY_FIND(SDL_SaveAllDollarTemplates);
+ SDL_LIBRARY_FIND(SDL_SaveDollarTemplate);
+ SDL_LIBRARY_FIND(SDL_LoadDollarTemplates);
+ SDL_LIBRARY_FIND(SDL_NumHaptics);
+ SDL_LIBRARY_FIND(SDL_HapticName);
+ SDL_LIBRARY_FIND(SDL_HapticOpen);
+ SDL_LIBRARY_FIND(SDL_HapticOpened);
+ SDL_LIBRARY_FIND(SDL_HapticIndex);
+ SDL_LIBRARY_FIND(SDL_MouseIsHaptic);
+ SDL_LIBRARY_FIND(SDL_HapticOpenFromMouse);
+ SDL_LIBRARY_FIND(SDL_JoystickIsHaptic);
+ SDL_LIBRARY_FIND(SDL_HapticOpenFromJoystick);
+ SDL_LIBRARY_FIND(SDL_HapticClose);
+ SDL_LIBRARY_FIND(SDL_HapticNumEffects);
+ SDL_LIBRARY_FIND(SDL_HapticNumEffectsPlaying);
+ SDL_LIBRARY_FIND(SDL_HapticNumAxes);
+ SDL_LIBRARY_FIND(SDL_HapticEffectSupported);
+ SDL_LIBRARY_FIND(SDL_HapticNewEffect);
+ SDL_LIBRARY_FIND(SDL_HapticUpdateEffect);
+ SDL_LIBRARY_FIND(SDL_HapticRunEffect);
+ SDL_LIBRARY_FIND(SDL_HapticStopEffect);
+ SDL_LIBRARY_FIND(SDL_HapticDestroyEffect);
+ SDL_LIBRARY_FIND(SDL_HapticGetEffectStatus);
+ SDL_LIBRARY_FIND(SDL_HapticSetGain);
+ SDL_LIBRARY_FIND(SDL_HapticSetAutocenter);
+ SDL_LIBRARY_FIND(SDL_HapticPause);
+ SDL_LIBRARY_FIND(SDL_HapticUnpause);
+ SDL_LIBRARY_FIND(SDL_HapticStopAll);
+ SDL_LIBRARY_FIND(SDL_HapticRumbleSupported);
+ SDL_LIBRARY_FIND(SDL_HapticRumbleInit);
+ SDL_LIBRARY_FIND(SDL_HapticRumblePlay);
+ SDL_LIBRARY_FIND(SDL_HapticRumbleStop);
+ SDL_LIBRARY_FIND(SDL_ShowMessageBox);
+ SDL_LIBRARY_FIND(SDL_ShowSimpleMessageBox);
+ SDL_LIBRARY_FIND(SDL_PixelFormatEnumToMasks);
+ SDL_LIBRARY_FIND(SDL_MasksToPixelFormatEnum);
+ SDL_LIBRARY_FIND(SDL_AllocFormat);
+ SDL_LIBRARY_FIND(SDL_FreeFormat);
+ SDL_LIBRARY_FIND(SDL_AllocPalette);
+ SDL_LIBRARY_FIND(SDL_SetPixelFormatPalette);
+ SDL_LIBRARY_FIND(SDL_SetPaletteColors);
+ SDL_LIBRARY_FIND(SDL_FreePalette);
+ SDL_LIBRARY_FIND(SDL_MapRGB);
+ SDL_LIBRARY_FIND(SDL_MapRGBA);
+ SDL_LIBRARY_FIND(SDL_GetRGB);
+ SDL_LIBRARY_FIND(SDL_GetRGBA);
+ SDL_LIBRARY_FIND(SDL_CalculateGammaRamp);
+ SDL_LIBRARY_FIND(SDL_GetPowerInfo);
+ SDL_LIBRARY_FIND(SDL_GetCPUCount);
+ SDL_LIBRARY_FIND(SDL_GetCPUCacheLineSize);
+ SDL_LIBRARY_FIND(SDL_HasRDTSC);
+ SDL_LIBRARY_FIND(SDL_HasAltiVec);
+ SDL_LIBRARY_FIND(SDL_HasMMX);
+ SDL_LIBRARY_FIND(SDL_Has3DNow);
+ SDL_LIBRARY_FIND(SDL_HasSSE);
+ SDL_LIBRARY_FIND(SDL_HasSSE2);
+ SDL_LIBRARY_FIND(SDL_HasSSE3);
+ SDL_LIBRARY_FIND(SDL_HasSSE41);
+ SDL_LIBRARY_FIND(SDL_HasSSE42);
+ SDL_LIBRARY_FIND(SDL_GetNumTouchDevices);
+ SDL_LIBRARY_FIND(SDL_GetTouchDevice);
+ SDL_LIBRARY_FIND(SDL_GetNumTouchFingers);
+ SDL_LIBRARY_FIND(SDL_GetTouchFinger);
+ SDL_LIBRARY_FIND(SDL_SetError);
+ SDL_LIBRARY_FIND(SDL_GetError);
+ SDL_LIBRARY_FIND(SDL_ClearError);
+ SDL_LIBRARY_FIND(SDL_Error);
+ SDL_LIBRARY_FIND(SDL_SetClipboardText);
+ SDL_LIBRARY_FIND(SDL_GetClipboardText);
+ SDL_LIBRARY_FIND(SDL_HasClipboardText);
+ SDL_LIBRARY_FIND(SDL_GetWindowWMInfo);
+
+ if (SDL_GetVersion == NULL) {
+ result = SDLEW_ERROR_VERSION;
+ }
+ else {
+ SDL_GetVersion(&version);
+ if(version.major < 2) {
+ result = SDLEW_ERROR_VERSION;
+ }
+ else {
+ result = SDLEW_SUCCESS;
+ }
+ }
+
+ return result;
+}
diff --git a/extern/sdlew/src/sdlew.map b/extern/sdlew/src/sdlew.map
new file mode 100644
index 00000000000..3fb0a6f0fc9
--- /dev/null
+++ b/extern/sdlew/src/sdlew.map
@@ -0,0 +1,7 @@
+{
+global:
+ *;
+local:
+ *SDL*;
+};
+
diff --git a/intern/atomic/atomic_ops.h b/intern/atomic/atomic_ops.h
index f63ff630c40..06a5c8d834e 100644
--- a/intern/atomic/atomic_ops.h
+++ b/intern/atomic/atomic_ops.h
@@ -34,6 +34,11 @@
#if defined (__APPLE__)
# include <libkern/OSAtomic.h>
#elif defined(_MSC_VER)
+# define NOGDI
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
+# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#elif defined(__arm__)
/* Attempt to fix compilation error on Debian armel kernel.
@@ -97,13 +102,13 @@ atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
ATOMIC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
- return InterlockedExchangeAdd64(p, x);
+ return InterlockedExchangeAdd64((int64_t *)p, (int64_t)x);
}
ATOMIC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
- return InterlockedExchangeAdd64(p, -((int64_t)x));
+ return InterlockedExchangeAdd64((int64_t *)p, -((int64_t)x));
}
ATOMIC_INLINE uint64_t
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
index b00289b3fae..dc019c1f245 100644
--- a/intern/audaspace/Python/AUD_PyAPI.cpp
+++ b/intern/audaspace/Python/AUD_PyAPI.cpp
@@ -2588,7 +2588,7 @@ Device_set_listener_orientation(Device *self, PyObject *args, void* nothing)
PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
"The speed of sound of the device.\n"
- "The speed of sound in air is typically 343 m/s.");
+ "The speed of sound in air is typically 343.3 m/s.");
static PyObject *
Device_get_speed_of_sound(Device *self, void* nothing)
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index aa82e1da678..45d72ccb50e 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -46,6 +46,7 @@
#include <cstring>
#include <cmath>
#include <sstream>
+#include <iostream>
#include "AUD_NULLDevice.h"
#include "AUD_I3DDevice.h"
@@ -75,6 +76,7 @@
#include "AUD_MutexLock.h"
#ifdef WITH_SDL
+#include <SDL.h>
#include "AUD_SDLDevice.h"
#endif
@@ -143,8 +145,14 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
break;
#ifdef WITH_SDL
case AUD_SDL_DEVICE:
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
- break;
+ if (SDL_Init == (void *)0) {
+ printf("Warning: SDL libraries are not installed\n");
+ // No break, fall through to default, to return false
+ }
+ else {
+ dev = boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
+ break;
+ }
#endif
#ifdef WITH_OPENAL
case AUD_OPENAL_DEVICE:
@@ -162,7 +170,7 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
else
#endif
if (!AUD_jack_supported()) {
- printf("Warning: Jack cllient not installed\n");
+ printf("Warning: Jack client not installed\n");
// No break, fall through to default, to return false
}
else {
@@ -310,8 +318,9 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound *sound)
info.length = reader->getLength() / (float) info.specs.rate;
}
}
- catch(AUD_Exception&)
+ catch(AUD_Exception &ae)
{
+ std::cout << ae.str << std::endl;
}
return info;
@@ -1077,7 +1086,7 @@ int AUD_doesPlayback()
return -1;
}
-int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second)
+int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second, short *interrupt)
{
AUD_DeviceSpecs specs;
sample_t *buf;
@@ -1100,6 +1109,9 @@ int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_pe
for (int i = 0; i < length; i++) {
len = floor(samplejump * (i+1)) - floor(samplejump * i);
+ if (*interrupt) {
+ return 0;
+ }
aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
buf = aBuffer.getBuffer();
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index 64a3d06bd5f..657d4e6fd02 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -646,7 +646,7 @@ extern int AUD_doesPlayback(void);
* \param samples_per_second How many samples to read per second of the sound.
* \return How many samples really have been read. Always <= length.
*/
-extern int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second);
+extern int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second, short *interrupt);
/**
* Copies a sound.
diff --git a/intern/audaspace/intern/AUD_Sequencer.cpp b/intern/audaspace/intern/AUD_Sequencer.cpp
index 6c5e48c73f0..ddcf97e2ea1 100644
--- a/intern/audaspace/intern/AUD_Sequencer.cpp
+++ b/intern/audaspace/intern/AUD_Sequencer.cpp
@@ -39,7 +39,7 @@ AUD_Sequencer::AUD_Sequencer(AUD_Specs specs, float fps, bool muted) :
m_id(0),
m_muted(muted),
m_fps(fps),
- m_speed_of_sound(434),
+ m_speed_of_sound(343.3f),
m_doppler_factor(1),
m_distance_model(AUD_DISTANCE_MODEL_INVERSE_CLAMPED),
m_volume(1, 1.0f),
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.cpp b/intern/audaspace/intern/AUD_SequencerHandle.cpp
index 135c960471c..aa742f7b8db 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.cpp
+++ b/intern/audaspace/intern/AUD_SequencerHandle.cpp
@@ -31,18 +31,99 @@
#include "AUD_ReadDevice.h"
#include "AUD_MutexLock.h"
+#define KEEP_TIME 10
+
+void AUD_SequencerHandle::start()
+{
+ // we already tried to start, aborting
+ if(!m_valid)
+ return;
+
+ // in case the sound is playing, we need to stop first
+ stop();
+
+ AUD_MutexLock lock(*m_entry);
+
+ // let's try playing
+ if(m_entry->m_sound.get())
+ {
+ try
+ {
+ m_handle = m_device.play(m_entry->m_sound, true);
+ m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle);
+ }
+ catch(AUD_Exception&)
+ {
+ // handle stays invalid in case we get an exception
+ }
+
+ // after starting we have to set the properties, so let's ensure that
+ m_status--;
+ }
+
+ // if the sound could not be played, we invalidate
+ m_valid = m_handle.get();
+}
+
+bool AUD_SequencerHandle::updatePosition(float position)
+{
+ AUD_MutexLock lock(*m_entry);
+
+ if(m_handle.get())
+ {
+ // we currently have a handle, let's check where we are
+ if(position >= m_entry->m_end)
+ {
+ if(position >= m_entry->m_end + KEEP_TIME)
+ // far end, stopping
+ stop();
+ else
+ {
+ // close end, just pausing
+ m_handle->pause();
+ return true;
+ }
+ }
+ else if(position >= m_entry->m_begin)
+ {
+ // inside, resuming
+ m_handle->resume();
+ return true;
+ }
+ else
+ {
+ if(position < m_entry->m_begin - KEEP_TIME)
+ // far beginning, stopping
+ stop();
+ else
+ {
+ // close beginning, just pausing
+ m_handle->pause();
+ return true;
+ }
+ }
+ }
+ else
+ {
+ // we don't have a handle, let's start if we should be playing
+ if(position >= m_entry->m_begin && position <= m_entry->m_end)
+ {
+ start();
+ return m_valid;
+ }
+ }
+
+ return false;
+}
+
AUD_SequencerHandle::AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> entry, AUD_ReadDevice& device) :
m_entry(entry),
+ m_valid(true),
m_status(0),
m_pos_status(0),
m_sound_status(0),
m_device(device)
{
- if(entry->m_sound.get())
- {
- m_handle = device.play(entry->m_sound, true);
- m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle);
- }
}
AUD_SequencerHandle::~AUD_SequencerHandle()
@@ -63,101 +144,116 @@ void AUD_SequencerHandle::stop()
{
if(m_handle.get())
m_handle->stop();
+ m_handle = boost::shared_ptr<AUD_IHandle>();
+ m_3dhandle = boost::shared_ptr<AUD_I3DHandle>();
}
void AUD_SequencerHandle::update(float position, float frame, float fps)
{
- if(m_handle.get())
+ if(m_sound_status != m_entry->m_sound_status)
{
- AUD_MutexLock lock(*m_entry);
- if(position >= m_entry->m_end)
- m_handle->pause();
- else if(position >= m_entry->m_begin)
- m_handle->resume();
+ // if a new sound has been set, it's possible to get valid again!
+ m_sound_status = m_entry->m_sound_status;
+ m_valid = true;
- if(m_sound_status != m_entry->m_sound_status)
- {
- if(m_handle.get())
- m_handle->stop();
-
- if(m_entry->m_sound.get())
- {
- m_handle = m_device.play(m_entry->m_sound, true);
- m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle);
- }
+ // stop whatever sound has been playing
+ stop();
- m_sound_status = m_entry->m_sound_status;
- m_pos_status--;
- m_status--;
- }
+ // seek starts and seeks to the correct position
+ if(!seek(position))
+ // no handle, aborting
+ return;
+ }
+ else
+ {
+ if(!m_valid)
+ // invalid, aborting
+ return;
- if(m_pos_status != m_entry->m_pos_status)
+ if(m_handle.get())
{
- seek(position);
-
- m_pos_status = m_entry->m_pos_status;
+ // we have a handle, let's update the position
+ if(!updatePosition(position))
+ // lost handle, aborting
+ return;
}
-
- if(m_status != m_entry->m_status)
+ else
{
- m_3dhandle->setRelative(m_entry->m_relative);
- m_3dhandle->setVolumeMaximum(m_entry->m_volume_max);
- m_3dhandle->setVolumeMinimum(m_entry->m_volume_min);
- m_3dhandle->setDistanceMaximum(m_entry->m_distance_max);
- m_3dhandle->setDistanceReference(m_entry->m_distance_reference);
- m_3dhandle->setAttenuation(m_entry->m_attenuation);
- m_3dhandle->setConeAngleOuter(m_entry->m_cone_angle_outer);
- m_3dhandle->setConeAngleInner(m_entry->m_cone_angle_inner);
- m_3dhandle->setConeVolumeOuter(m_entry->m_cone_volume_outer);
-
- m_status = m_entry->m_status;
+ // we don't have a handle, let's see if we can start
+ if(!seek(position))
+ return;
}
+ }
- float value;
+ AUD_MutexLock lock(*m_entry);
+ if(m_pos_status != m_entry->m_pos_status)
+ {
+ m_pos_status = m_entry->m_pos_status;
- m_entry->m_volume.read(frame, &value);
- m_handle->setVolume(value);
- m_entry->m_pitch.read(frame, &value);
- m_handle->setPitch(value);
- m_entry->m_panning.read(frame, &value);
- AUD_SoftwareDevice::setPanning(m_handle.get(), value);
+ // position changed, need to seek
+ if(!seek(position))
+ // lost handle, aborting
+ return;
+ }
- AUD_Vector3 v, v2;
- AUD_Quaternion q;
+ // so far everything alright and handle is there, let's keep going
- m_entry->m_orientation.read(frame, q.get());
- m_3dhandle->setSourceOrientation(q);
- m_entry->m_location.read(frame, v.get());
- m_3dhandle->setSourceLocation(v);
- m_entry->m_location.read(frame + 1, v2.get());
- v2 -= v;
- m_3dhandle->setSourceVelocity(v2 * fps);
+ if(m_status != m_entry->m_status)
+ {
+ m_status = m_entry->m_status;
- if(m_entry->m_muted)
- m_handle->setVolume(0);
+ m_3dhandle->setRelative(m_entry->m_relative);
+ m_3dhandle->setVolumeMaximum(m_entry->m_volume_max);
+ m_3dhandle->setVolumeMinimum(m_entry->m_volume_min);
+ m_3dhandle->setDistanceMaximum(m_entry->m_distance_max);
+ m_3dhandle->setDistanceReference(m_entry->m_distance_reference);
+ m_3dhandle->setAttenuation(m_entry->m_attenuation);
+ m_3dhandle->setConeAngleOuter(m_entry->m_cone_angle_outer);
+ m_3dhandle->setConeAngleInner(m_entry->m_cone_angle_inner);
+ m_3dhandle->setConeVolumeOuter(m_entry->m_cone_volume_outer);
}
+
+ float value;
+
+ m_entry->m_volume.read(frame, &value);
+ m_handle->setVolume(value);
+ m_entry->m_pitch.read(frame, &value);
+ m_handle->setPitch(value);
+ m_entry->m_panning.read(frame, &value);
+ AUD_SoftwareDevice::setPanning(m_handle.get(), value);
+
+ AUD_Vector3 v, v2;
+ AUD_Quaternion q;
+
+ m_entry->m_orientation.read(frame, q.get());
+ m_3dhandle->setSourceOrientation(q);
+ m_entry->m_location.read(frame, v.get());
+ m_3dhandle->setSourceLocation(v);
+ m_entry->m_location.read(frame + 1, v2.get());
+ v2 -= v;
+ m_3dhandle->setSourceVelocity(v2 * fps);
+
+ if(m_entry->m_muted)
+ m_handle->setVolume(0);
}
-void AUD_SequencerHandle::seek(float position)
+bool AUD_SequencerHandle::seek(float position)
{
- if(m_handle.get())
- {
- AUD_MutexLock lock(*m_entry);
- if(position >= m_entry->m_end)
- {
- m_handle->pause();
- return;
- }
+ if(!m_valid)
+ // sound not valid, aborting
+ return false;
- float seekpos = position - m_entry->m_begin;
- if(seekpos < 0)
- seekpos = 0;
- seekpos += m_entry->m_skip;
- m_handle->setPitch(1.0f);
- m_handle->seek(seekpos);
- if(position < m_entry->m_begin)
- m_handle->pause();
- else
- m_handle->resume();
- }
+ if(!updatePosition(position))
+ // no handle, aborting
+ return false;
+
+ AUD_MutexLock lock(*m_entry);
+ float seekpos = position - m_entry->m_begin;
+ if(seekpos < 0)
+ seekpos = 0;
+ seekpos += m_entry->m_skip;
+ m_handle->setPitch(1.0f);
+ m_handle->seek(seekpos);
+
+ return true;
}
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.h b/intern/audaspace/intern/AUD_SequencerHandle.h
index 881bbdd43dc..306df4a84b9 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.h
+++ b/intern/audaspace/intern/AUD_SequencerHandle.h
@@ -51,6 +51,9 @@ private:
/// The 3D handle in the read device.
boost::shared_ptr<AUD_I3DHandle> m_3dhandle;
+ /// Whether the sound is playable.
+ bool m_valid;
+
/// The last read status from the entry.
int m_status;
@@ -63,6 +66,18 @@ private:
/// The read device this handle is played on.
AUD_ReadDevice& m_device;
+ /**
+ * Starts playing back the handle.
+ */
+ void start();
+
+ /**
+ * Updates the handle state depending on position.
+ * \param position Current playback position in seconds.
+ * \return Whether the handle is valid.
+ */
+ bool updatePosition(float position);
+
public:
/**
* Creates a new sequenced handle.
@@ -99,8 +114,9 @@ public:
/**
* Seeks the handle to a specific time position.
* \param position The time to seek to.
+ * \return Whether the handle is valid.
*/
- void seek(float position);
+ bool seek(float position);
};
#endif //__AUD_SEQUENCERHANDLE_H__
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index 6ffa5e1fcae..c4277a6d02e 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -705,7 +705,7 @@ void AUD_SoftwareDevice::create()
m_playback = false;
m_volume = 1.0f;
m_mixer = boost::shared_ptr<AUD_Mixer>(new AUD_Mixer(m_specs));
- m_speed_of_sound = 343.0f;
+ m_speed_of_sound = 343.3f;
m_doppler_factor = 1.0f;
m_distance_model = AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
m_flags = 0;
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 7de1182282d..2ba6af48d0d 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -16,8 +16,12 @@ include(cmake/external_libs.cmake)
if(NOT WITH_CPU_SSE)
set(CXX_HAS_SSE FALSE)
+ set(CXX_HAS_AVX FALSE)
+ set(CXX_HAS_AVX2 FALSE)
elseif(WIN32 AND MSVC)
set(CXX_HAS_SSE TRUE)
+ set(CXX_HAS_AVX TRUE)
+ set(CXX_HAS_AVX2 TRUE)
# /arch:AVX for VC2012 and above
if(NOT MSVC_VERSION LESS 1700)
@@ -49,21 +53,33 @@ elseif(WIN32 AND MSVC)
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /Ox")
elseif(CMAKE_COMPILER_IS_GNUCC)
check_cxx_compiler_flag(-msse CXX_HAS_SSE)
+ check_cxx_compiler_flag(-mavx CXX_HAS_AVX)
+ check_cxx_compiler_flag(-mavx2 CXX_HAS_AVX2)
if(CXX_HAS_SSE)
set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2 -mfpmath=sse")
set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse")
set(CYCLES_SSE41_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mfpmath=sse")
+ endif()
+ if(CXX_HAS_AVX)
set(CYCLES_AVX_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mavx -mfpmath=sse")
+ endif()
+ if(CXX_HAS_AVX2)
set(CYCLES_AVX2_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mavx -mavx2 -mfma -mlzcnt -mbmi -mbmi2 -mfpmath=sse")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
check_cxx_compiler_flag(-msse CXX_HAS_SSE)
+ check_cxx_compiler_flag(-mavx CXX_HAS_AVX)
+ check_cxx_compiler_flag(-mavx2 CXX_HAS_AVX2)
if(CXX_HAS_SSE)
set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2")
set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3")
set(CYCLES_SSE41_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1")
+ endif()
+ if(CXX_HAS_AVX)
set(CYCLES_AVX_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mavx")
+ endif()
+ if(CXX_HAS_AVX2)
set(CYCLES_AVX2_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -msse4.1 -mavx -mavx2 -mfma -mlzcnt -mbmi -mbmi2")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
@@ -74,11 +90,17 @@ if(CXX_HAS_SSE)
-DWITH_KERNEL_SSE2
-DWITH_KERNEL_SSE3
-DWITH_KERNEL_SSE41
- -DWITH_KERNEL_AVX
- -DWITH_KERNEL_AVX2
)
endif()
+if(CXX_HAS_AVX)
+ add_definitions(-DWITH_KERNEL_AVX)
+endif()
+
+if(CXX_HAS_AVX2)
+ add_definitions(-DWITH_KERNEL_AVX2)
+endif()
+
if(WITH_CYCLES_OSL)
if(WIN32 AND MSVC)
set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
@@ -120,7 +142,7 @@ if(WITH_CYCLES_OSL)
add_definitions(-DOSL_STATIC_LIBRARY)
include_directories(
SYSTEM
- ${OSL_INCLUDES}
+ ${OSL_INCLUDE_DIR}
)
endif()
@@ -134,19 +156,12 @@ add_definitions(
if(WITH_CYCLES_LOGGING)
add_definitions(-DWITH_CYCLES_LOGGING)
add_definitions(-DGOOGLE_GLOG_DLL_DECL=)
- if(WIN32)
- include_directories(
- SYSTEM
- ../../extern/libmv/third_party/glog/src/windows
- ../../extern/libmv/third_party/gflags
- )
- else()
- include_directories(
- SYSTEM
- ../../extern/libmv/third_party/glog/src
- ../../extern/libmv/third_party/gflags
- )
- endif()
+ add_definitions(-DCYCLES_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
+ include_directories(
+ SYSTEM
+ ${GLOG_INCLUDE_DIRS}
+ ${GFLAGS_INCLUDE_DIRS}
+ )
endif()
# Debugging capabilities (debug passes etc).
@@ -161,8 +176,14 @@ include_directories(
${OPENIMAGEIO_INCLUDE_DIRS}/OpenImageIO
${OPENEXR_INCLUDE_DIR}
${OPENEXR_INCLUDE_DIRS}
+ ${PUGIXML_INCLUDE_DIR}
)
+if(CYCLES_STANDALONE_REPOSITORY)
+ include_directories(../third_party/atomic)
+else()
+ include_directories(../atomic)
+endif()
# Warnings
if(CMAKE_COMPILER_IS_GNUCXX)
diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript
index b399844534d..9cbdb93ce85 100644
--- a/intern/cycles/SConscript
+++ b/intern/cycles/SConscript
@@ -62,12 +62,24 @@ if env['WITH_BF_CYCLES_OSL']:
if env['WITH_BF_CYCLES_DEBUG']:
defs.append('WITH_CYCLES_DEBUG')
+if env['WITH_BF_CYCLES_LOGGING']:
+ defs.append('WITH_CYCLES_LOGGING')
+ defs.append('GOOGLE_GLOG_DLL_DECL=')
+ defs.append('CYCLES_GFLAGS_NAMESPACE=gflags')
+ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+ incs.append('#extern/libmv/third_party/glog/src/windows')
+ incs.append('#extern/libmv/third_party/gflags')
+ else:
+ incs.append('#extern/libmv/third_party/glog/src')
+ incs.append('#extern/libmv/third_party/gflags')
+
incs.extend('. bvh render device kernel kernel/osl kernel/svm util subd'.split())
incs.extend('#intern/guardedalloc #source/blender/makesrna #source/blender/makesdna #source/blender/blenlib'.split())
incs.extend('#source/blender/blenloader ../../source/blender/makesrna/intern'.split())
incs.append(env['BF_GLEW_INC'])
incs.append('#/intern/glew-mx')
+incs.append('#/intern/atomic')
incs.append('#intern/mikktspace')
incs.extend('#extern/glew/include #extern/clew/include #extern/cuew/include #intern/mikktspace'.split())
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index c8464899725..b000266cac2 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -12,6 +12,8 @@ set(INC
set(INC_SYS
)
+# NOTE: LIBRARIES contains all the libraries which are common
+# across release and debug build types, stored in a linking order.
set(LIBRARIES
cycles_device
cycles_kernel
@@ -19,39 +21,85 @@ set(LIBRARIES
cycles_bvh
cycles_subd
cycles_util
- ${BOOST_LIBRARIES}
- ${OPENEXR_LIBRARIES}
${BLENDER_GL_LIBRARIES}
- bf_intern_glew_mx
${CYCLES_APP_GLEW_LIBRARY}
- ${OPENIMAGEIO_LIBRARIES}
${PNG_LIBRARIES}
${JPEG_LIBRARIES}
${ZLIB_LIBRARIES}
${TIFF_LIBRARY}
+ ${PTHREADS_LIBRARIES}
extern_clew
extern_cuew
)
-add_definitions(${GL_DEFINITIONS})
-
-if(WIN32)
- list(APPEND LIBRARIES ${PTHREADS_LIBRARIES})
+if(WITH_CYCLES_OSL)
+ list(APPEND LIBRARIES cycles_kernel_osl)
endif()
-link_directories(${OPENIMAGEIO_LIBPATH} ${BOOST_LIBPATH} ${PNG_LIBPATH} ${JPEG_LIBPATH} ${ZLIB_LIBPATH} ${TIFF_LIBPATH})
+if(CYCLES_STANDALONE_REPOSITORY)
+ if(WITH_CYCLES_LOGGING)
+ list(APPEND LIBRARIES
+ ${GLOG_LIBRARIES}
+ ${GFLAGS_LIBRARIES}
+ )
+ endif()
+else()
+ list(APPEND LIBRARIES bf_intern_glew_mx)
+ if(WITH_CYCLES_LOGGING)
+ list(APPEND LIBRARIES extern_glog)
+ endif()
+endif()
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
list(APPEND LIBRARIES ${GLUT_LIBRARIES})
endif()
-if(WITH_CYCLES_OSL)
- list(APPEND LIBRARIES cycles_kernel_osl ${OSL_LIBRARIES} ${LLVM_LIBRARY})
-endif()
+# Common configuration.
+
+link_directories(${OPENIMAGEIO_LIBPATH}
+ ${BOOST_LIBPATH}
+ ${PNG_LIBPATH}
+ ${JPEG_LIBPATH}
+ ${ZLIB_LIBPATH}
+ ${TIFF_LIBPATH}
+ ${OPENEXR_LIBPATH})
+
+add_definitions(${GL_DEFINITIONS})
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
+# Make sure given target is linked against proper libraries
+# which varies across debug and release build types.
+#
+# This will also make sure dependencies of that libraries
+# are sent to the linker after them.
+#
+# TODO(sergey): Think of a better place for this?
+macro(cycles_target_link_libraries target)
+ target_link_libraries(${target} ${LIBRARIES})
+ if(WITH_CYCLES_OSL)
+ target_link_libraries_decoupled(${target} OSL_LIBRARIES)
+ if(MSVC)
+ target_link_libraries_debug(${target} "${LLVM_LIBRARIES_DEBUG}")
+ target_link_libraries_optimized(${target} "${LLVM_LIBRARIES}")
+ else()
+ target_link_libraries(${target} ${LLVM_LIBRARIES})
+ endif()
+ endif()
+ target_link_libraries_decoupled(${target} OPENIMAGEIO_LIBRARIES)
+ target_link_libraries_decoupled(${target} OPENEXR_LIBRARIES)
+ target_link_libraries(
+ ${target}
+ ${PUGIXML_LIBRARIES}
+ ${BOOST_LIBRARIES}
+ ${CMAKE_DL_LIBS}
+ ${PLATFORM_LINKLIBS}
+ )
+endmacro()
+
+# Application build targets
+
if(WITH_CYCLES_STANDALONE)
set(SRC
cycles_standalone.cpp
@@ -59,8 +107,7 @@ if(WITH_CYCLES_STANDALONE)
cycles_xml.h
)
add_executable(cycles ${SRC})
- list(APPEND LIBRARIES ${PLATFORM_LINKLIBS})
- target_link_libraries(cycles ${LIBRARIES} ${CMAKE_DL_LIBS})
+ cycles_target_link_libraries(cycles)
if(UNIX AND NOT APPLE)
set_target_properties(cycles PROPERTIES INSTALL_RPATH $ORIGIN/lib)
@@ -73,11 +120,10 @@ if(WITH_CYCLES_NETWORK)
cycles_server.cpp
)
add_executable(cycles_server ${SRC})
- target_link_libraries(cycles_server ${LIBRARIES} ${CMAKE_DL_LIBS})
+ cycles_target_link_libraries(cycles_server)
if(UNIX AND NOT APPLE)
set_target_properties(cycles_server PROPERTIES INSTALL_RPATH $ORIGIN/lib)
endif()
unset(SRC)
endif()
-
diff --git a/intern/cycles/app/cycles_server.cpp b/intern/cycles/app/cycles_server.cpp
index f4cacb2d001..3d5b237eec1 100644
--- a/intern/cycles/app/cycles_server.cpp
+++ b/intern/cycles/app/cycles_server.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdio.h>
@@ -29,13 +29,14 @@ using namespace ccl;
int main(int argc, const char **argv)
{
+ util_logging_init(argv[0]);
path_init();
/* device types */
string devicelist = "";
string devicename = "cpu";
- bool list = false;
- int threads = 0;
+ bool list = false, debug = false;
+ int threads = 0, verbosity = 1;
vector<DeviceType>& types = Device::available_types();
@@ -53,6 +54,10 @@ int main(int argc, const char **argv)
"--device %s", &devicename, ("Devices to use: " + devicelist).c_str(),
"--list-devices", &list, "List information about all available devices",
"--threads %d", &threads, "Number of threads to use for CPU device",
+#ifdef WITH_CYCLES_LOGGING
+ "--debug", &debug, "Enable debug logging",
+ "--verbose %d", &verbosity, "Set verbosity of the logger",
+#endif
NULL);
if(ap.parse(argc, argv) < 0) {
@@ -60,7 +65,13 @@ int main(int argc, const char **argv)
ap.usage();
exit(EXIT_FAILURE);
}
- else if(list) {
+
+ if (debug) {
+ util_logging_start();
+ util_logging_verbosity_set(verbosity);
+ }
+
+ if(list) {
vector<DeviceInfo>& devices = Device::available_devices();
printf("Devices:\n");
diff --git a/intern/cycles/app/cycles_standalone.cpp b/intern/cycles/app/cycles_standalone.cpp
index 90333eb3fc5..42c339f56e5 100644
--- a/intern/cycles/app/cycles_standalone.cpp
+++ b/intern/cycles/app/cycles_standalone.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdio.h>
@@ -25,6 +25,7 @@
#include "util_args.h"
#include "util_foreach.h"
#include "util_function.h"
+#include "util_logging.h"
#include "util_path.h"
#include "util_progress.h"
#include "util_string.h"
@@ -70,12 +71,12 @@ static void session_print(const string& str)
static void session_print_status()
{
int sample, tile;
- double total_time, sample_time;
+ double total_time, sample_time, render_time;
string status, substatus;
/* get status */
sample = options.session->progress.get_sample();
- options.session->progress.get_tile(tile, total_time, sample_time);
+ options.session->progress.get_tile(tile, total_time, sample_time, render_time);
options.session->progress.get_status(status, substatus);
if(substatus != "")
@@ -165,11 +166,11 @@ static void display_info(Progress& progress)
last = elapsed;
int sample, tile;
- double total_time, sample_time;
+ double total_time, sample_time, render_time;
string status, substatus;
sample = progress.get_sample();
- progress.get_tile(tile, total_time, sample_time);
+ progress.get_tile(tile, total_time, sample_time, render_time);
progress.get_status(status, substatus);
if(substatus != "")
@@ -319,6 +320,11 @@ static void options_parse(int argc, const char **argv)
vector<DeviceType>& types = Device::available_types();
+ /* TODO(sergey): Here's a feedback loop happens: on the one hand we want
+ * the device list to be printed in help message, on the other hand logging
+ * is not initialized yet so we wouldn't have debug log happening in the
+ * device initialization.
+ */
foreach(DeviceType type, types) {
if(device_names != "")
device_names += ", ";
@@ -331,7 +337,8 @@ static void options_parse(int argc, const char **argv)
/* parse options */
ArgParse ap;
- bool help = false;
+ bool help = false, debug = false;
+ int verbosity = 1;
ap.options ("Usage: cycles [options] file.xml",
"%*", files_parse, "",
@@ -347,6 +354,10 @@ static void options_parse(int argc, const char **argv)
"--width %d", &options.width, "Window width in pixel",
"--height %d", &options.height, "Window height in pixel",
"--list-devices", &list, "List information about all available devices",
+#ifdef WITH_CYCLES_LOGGING
+ "--debug", &debug, "Enable debug logging",
+ "--verbose %d", &verbosity, "Set verbosity of the logger",
+#endif
"--help", &help, "Print help message",
NULL);
@@ -355,7 +366,13 @@ static void options_parse(int argc, const char **argv)
ap.usage();
exit(EXIT_FAILURE);
}
- else if(list) {
+
+ if (debug) {
+ util_logging_start();
+ util_logging_verbosity_set(verbosity);
+ }
+
+ if(list) {
vector<DeviceInfo>& devices = Device::available_devices();
printf("Devices:\n");
@@ -435,6 +452,7 @@ using namespace ccl;
int main(int argc, const char **argv)
{
+ util_logging_init(argv[0]);
path_init();
options_parse(argc, argv);
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index 431796e106b..05e34387eb7 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdio.h>
@@ -299,7 +299,6 @@ static void xml_read_integrator(const XMLReadState& state, pugi::xml_node node)
xml_read_bool(&integrator->transparent_shadows, node, "transparent_shadows");
/* Volume */
- xml_read_int(&integrator->volume_homogeneous_sampling, node, "volume_homogeneous_sampling");
xml_read_float(&integrator->volume_step_size, node, "volume_step_size");
xml_read_int(&integrator->volume_max_steps, node, "volume_max_steps");
@@ -803,7 +802,17 @@ static void xml_read_shader(const XMLReadState& state, pugi::xml_node node)
xml_read_string(&shader->name, node, "name");
xml_read_bool(&shader->use_mis, node, "use_mis");
xml_read_bool(&shader->use_transparent_shadow, node, "use_transparent_shadow");
+
+ /* Volume */
xml_read_bool(&shader->heterogeneous_volume, node, "heterogeneous_volume");
+ xml_read_int(&shader->volume_interpolation_method, node, "volume_interpolation_method");
+
+ if(xml_equal_string(node, "volume_sampling_method", "distance"))
+ shader->volume_sampling_method = VOLUME_SAMPLING_DISTANCE;
+ else if(xml_equal_string(node, "volume_sampling_method", "equiangular"))
+ shader->volume_sampling_method = VOLUME_SAMPLING_EQUIANGULAR;
+ else if(xml_equal_string(node, "volume_sampling_method", "multiple_importance"))
+ shader->volume_sampling_method = VOLUME_SAMPLING_MULTIPLE_IMPORTANCE;
xml_read_shader_graph(state, shader, node);
state.scene->shaders.push_back(shader);
@@ -816,6 +825,14 @@ static void xml_read_background(const XMLReadState& state, pugi::xml_node node)
Shader *shader = state.scene->shaders[state.scene->default_background];
xml_read_bool(&shader->heterogeneous_volume, node, "heterogeneous_volume");
+ xml_read_int(&shader->volume_interpolation_method, node, "volume_interpolation_method");
+
+ if(xml_equal_string(node, "volume_sampling_method", "distance"))
+ shader->volume_sampling_method = VOLUME_SAMPLING_DISTANCE;
+ else if(xml_equal_string(node, "volume_sampling_method", "equiangular"))
+ shader->volume_sampling_method = VOLUME_SAMPLING_EQUIANGULAR;
+ else if(xml_equal_string(node, "volume_sampling_method", "multiple_importance"))
+ shader->volume_sampling_method = VOLUME_SAMPLING_MULTIPLE_IMPORTANCE;
xml_read_shader_graph(state, shader, node);
}
diff --git a/intern/cycles/app/cycles_xml.h b/intern/cycles/app/cycles_xml.h
index 96bc79c35d8..6a48980d8ea 100644
--- a/intern/cycles/app/cycles_xml.h
+++ b/intern/cycles/app/cycles_xml.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __CYCLES_XML_H__
diff --git a/intern/cycles/app/io_export_cycles_xml.py b/intern/cycles/app/io_export_cycles_xml.py
index ad8fb9d3dd3..7d6d85f88af 100644
--- a/intern/cycles/app/io_export_cycles_xml.py
+++ b/intern/cycles/app/io_export_cycles_xml.py
@@ -11,7 +11,7 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
-# limitations under the License
+# limitations under the License.
#
# XML exporter for generating test files, not intended for end users
diff --git a/intern/cycles/blender/CCL_api.h b/intern/cycles/blender/CCL_api.h
index cfd0c3ef264..d3a68c4db4f 100644
--- a/intern/cycles/blender/CCL_api.h
+++ b/intern/cycles/blender/CCL_api.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __CCL_API_H__
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index e1d592d32b4..fff9ed20bba 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -17,7 +17,7 @@ set(INC
set(INC_SYS
${PYTHON_INCLUDE_DIRS}
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_DIR}
)
set(SRC
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 8c60ea31053..5b0c6a84bb5 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -11,7 +11,7 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
-# limitations under the License
+# limitations under the License.
#
# <pep8 compliant>
@@ -50,20 +50,17 @@ class CyclesRender(bpy.types.RenderEngine):
# final render
def update(self, data, scene):
- if self.is_preview:
- if not self.session:
+ if not self.session:
+ if self.is_preview:
cscene = bpy.context.scene.cycles
use_osl = cscene.shading_system and cscene.device == 'CPU'
engine.create(self, data, scene,
None, None, None, use_osl)
- else:
- if not self.session:
- engine.create(self, data, scene)
else:
- engine.reset(self, data, scene)
-
- engine.update(self, data, scene)
+ engine.create(self, data, scene)
+ else:
+ engine.reset(self, data, scene)
def render(self, scene):
engine.render(self)
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 18235eca790..e50a8e45b52 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -11,7 +11,7 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
-# limitations under the License
+# limitations under the License.
#
# <pep8 compliant>
@@ -25,7 +25,7 @@ def init():
path = os.path.dirname(__file__)
user_path = os.path.dirname(os.path.abspath(bpy.utils.user_resource('CONFIG', '')))
- _cycles.init(path, user_path)
+ _cycles.init(path, user_path, bpy.app.background)
def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=False):
@@ -100,3 +100,8 @@ def with_osl():
def with_network():
import _cycles
return _cycles.with_network
+
+
+def system_info():
+ import _cycles
+ return _cycles.system_info()
diff --git a/intern/cycles/blender/addon/osl.py b/intern/cycles/blender/addon/osl.py
index c5f9d93013e..f4aaaab5eab 100644
--- a/intern/cycles/blender/addon/osl.py
+++ b/intern/cycles/blender/addon/osl.py
@@ -11,7 +11,7 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
-# limitations under the License
+# limitations under the License.
#
# <pep8 compliant>
diff --git a/intern/cycles/blender/addon/presets.py b/intern/cycles/blender/addon/presets.py
index 2ec65d7183a..f97b51b629d 100644
--- a/intern/cycles/blender/addon/presets.py
+++ b/intern/cycles/blender/addon/presets.py
@@ -11,7 +11,7 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
-# limitations under the License
+# limitations under the License.
#
# <pep8 compliant>
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 05a6f70d423..a86f162ae5f 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -11,7 +11,7 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
-# limitations under the License
+# limitations under the License.
#
# <pep8 compliant>
@@ -58,7 +58,7 @@ enum_filter_types = (
enum_aperture_types = (
('RADIUS', "Radius", "Directly change the size of the aperture"),
- ('FSTOP', "F/stop", "Change the size of the aperture by f/stops"),
+ ('FSTOP', "F-stop", "Change the size of the aperture by f-stop"),
)
enum_panorama_types = (
@@ -116,7 +116,7 @@ enum_volume_sampling = (
enum_volume_interpolation = (
('LINEAR', "Linear", "Good smoothness and speed"),
- ('CUBIC', 'Cubic', 'Smoothed high quality interpolation, but slower')
+ ('CUBIC', "Cubic", "Smoothed high quality interpolation, but slower")
)
@@ -350,7 +350,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Distance between volume shader samples when rendering the volume "
"(lower values give more accurate and detailed results, but also increased render time)",
default=0.1,
- min=0.0000001, max=100000.0
+ min=0.0000001, max=100000.0, soft_min=0.01, soft_max=1.0
)
cls.volume_max_steps = IntProperty(
@@ -481,7 +481,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
name="Bake Type",
default='COMBINED',
description="Type of pass to bake",
- items = (
+ items=(
('COMBINED', "Combined", ""),
('AO', "Ambient Occlusion", ""),
('SHADOW', "Shadow", ""),
@@ -522,13 +522,13 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
cls.aperture_type = EnumProperty(
name="Aperture Type",
- description="Use F/stop number or aperture radius",
+ description="Use f-stop number or aperture radius",
items=enum_aperture_types,
default='RADIUS',
)
cls.aperture_fstop = FloatProperty(
- name="Aperture F/stop",
- description="F/stop ratio (lower numbers give more defocus, higher numbers give a sharper image)",
+ name="Aperture f-stop",
+ description="F-stop ratio (lower numbers give more defocus, higher numbers give a sharper image)",
min=0.0, soft_min=0.1, soft_max=64.0,
default=5.6,
step=10,
@@ -582,6 +582,34 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
min=0.01, soft_max=15.0, max=100.0,
default=10.5,
)
+ cls.latitude_min = FloatProperty(
+ name="Min Latitude",
+ description="Minimum latitude (vertical angle) for the equirectangular lens",
+ min=-0.5 * math.pi, max=0.5 * math.pi,
+ subtype='ANGLE',
+ default=-0.5 * math.pi,
+ )
+ cls.latitude_max = FloatProperty(
+ name="Max Latitude",
+ description="Maximum latitude (vertical angle) for the equirectangular lens",
+ min=-0.5 * math.pi, max=0.5 * math.pi,
+ subtype='ANGLE',
+ default=0.5 * math.pi,
+ )
+ cls.longitude_min = FloatProperty(
+ name="Min Longitude",
+ description="Minimum longitude (horizontal angle) for the equirectangular lens",
+ min=-math.pi, max=math.pi,
+ subtype='ANGLE',
+ default=-math.pi,
+ )
+ cls.longitude_max = FloatProperty(
+ name="Max Longitude",
+ description="Maximum longitude (horizontal angle) for the equirectangular lens",
+ min=-math.pi, max=math.pi,
+ subtype='ANGLE',
+ default=math.pi,
+ )
@classmethod
def unregister(cls):
@@ -624,7 +652,7 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
cls.volume_interpolation = EnumProperty(
name="Volume Interpolation",
- description="Interpolation method to use for volumes",
+ description="Interpolation method to use for smoke/fire volumes",
items=enum_volume_interpolation,
default='LINEAR',
)
@@ -653,6 +681,12 @@ class CyclesLampSettings(bpy.types.PropertyGroup):
min=1, max=10000,
default=1,
)
+ cls.max_bounces = IntProperty(
+ name="Max Bounces",
+ description="Maximum number of bounces the light will contribute to the render",
+ min=0, max=1024,
+ default=1024,
+ )
cls.use_multiple_importance_sampling = BoolProperty(
name="Multiple Importance Sample",
description="Use multiple importance sampling for the lamp, "
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 6a08b47b01f..63518d7fdb6 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -11,7 +11,7 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
-# limitations under the License
+# limitations under the License.
#
# <pep8 compliant>
@@ -37,7 +37,7 @@ class CYCLES_MT_integrator_presets(Menu):
draw = Menu.draw_preset
-class CyclesButtonsPanel():
+class CyclesButtonsPanel:
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "render"
@@ -445,6 +445,7 @@ class CyclesCamera_PT_dof(CyclesButtonsPanel, Panel):
cam = context.camera
ccam = cam.cycles
+ dof_options = cam.gpu_dof
split = layout.split()
@@ -455,6 +456,7 @@ class CyclesCamera_PT_dof(CyclesButtonsPanel, Panel):
sub = col.row()
sub.active = cam.dof_object is None
sub.prop(cam, "dof_distance", text="Distance")
+ col.prop(dof_options, "fstop")
col = split.column()
@@ -729,11 +731,11 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel):
if cscene.progressive == 'BRANCHED_PATH':
col.prop(clamp, "samples")
+ col.prop(clamp, "max_bounces")
col = split.column()
col.prop(clamp, "cast_shadow")
-
- layout.prop(clamp, "use_multiple_importance_sampling")
+ col.prop(clamp, "use_multiple_importance_sampling", text="Multiple Importance")
if lamp.type == 'HEMI':
layout.label(text="Not supported, interpreted as sun lamp")
@@ -1020,17 +1022,6 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
cmat = mat.cycles
split = layout.split()
-
- col = split.column(align=True)
- col.prop(mat, "diffuse_color", text="Viewport Color")
- col.prop(mat, "alpha")
-
- col = split.column(align=True)
- col.label()
- col.prop(mat, "pass_index")
-
- split = layout.split()
-
col = split.column()
col.label(text="Surface:")
col.prop(cmat, "sample_as_light", text="Multiple Importance")
@@ -1044,6 +1035,22 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
col.prop(cmat, "volume_interpolation", text="")
col.prop(cmat, "homogeneous_volume", text="Homogeneous")
+ layout.separator()
+ split = layout.split()
+
+ col = split.column(align=True)
+ col.label("Viewport Color:")
+ col.prop(mat, "diffuse_color", text="")
+ col.prop(mat, "alpha")
+
+ col.separator()
+ col.prop(mat, "pass_index")
+
+ col = split.column(align=True)
+ col.label("Viewport Specular:")
+ col.prop(mat, "specular_color", text="")
+ col.prop(mat, "specular_hardness", text="Hardness")
+
class CyclesTexture_PT_context(CyclesButtonsPanel, Panel):
bl_label = ""
@@ -1412,6 +1419,7 @@ def get_panels():
"DATA_PT_vertex_colors",
"DATA_PT_camera",
"DATA_PT_camera_display",
+ "DATA_PT_camera_safe_areas",
"DATA_PT_lens",
"DATA_PT_speaker",
"DATA_PT_distance",
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index eaeec703ff5..2fbb01ba5b8 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -11,7 +11,7 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
-# limitations under the License
+# limitations under the License.
#
# <pep8 compliant>
@@ -21,6 +21,85 @@ import bpy
from bpy.app.handlers import persistent
+def check_is_new_shading_ntree(node_tree):
+ for node in node_tree.nodes:
+ # If material has any node with ONLY new shading system
+ # compatibility then it's considered a Cycles material
+ # and versioning code would need to perform on it.
+ #
+ # We can not check for whether NEW_SHADING in compatibility
+ # because some nodes could have compatibility with both old
+ # and new shading system and they can't be used for any
+ # decision here.
+ if node.shading_compatibility == {'NEW_SHADING'}:
+ return True
+
+ # If node is only compatible with old shading system
+ # then material can not be Cycles material and we
+ # can stopiterating nodes now.
+ if node.shading_compatibility == {'OLD_SHADING'}:
+ return False
+ return False
+
+
+def check_is_new_shading_material(material):
+ if not material.node_tree:
+ return False
+ return check_is_new_shading_ntree(material.node_tree)
+
+
+def check_is_new_shading_world(world):
+ if not world.node_tree:
+ return False
+ return check_is_new_shading_ntree(world.node_tree)
+
+
+def check_is_new_shading_lamp(lamp):
+ if not lamp.node_tree:
+ return False
+ return check_is_new_shading_ntree(lamp.node_tree)
+
+
+def foreach_notree_node(nodetree, callback, traversed):
+ if nodetree in traversed:
+ return
+ traversed.add(nodetree)
+ for node in nodetree.nodes:
+ callback(node)
+ if node.bl_idname == 'ShaderNodeGroup':
+ foreach_notree_node(node.node_tree, callback, traversed)
+
+
+def foreach_cycles_node(callback):
+ traversed = set()
+ for material in bpy.data.materials:
+ if check_is_new_shading_material(material):
+ foreach_notree_node(material.node_tree,
+ callback,
+ traversed)
+ for world in bpy.data.worlds:
+ if check_is_new_shading_world(world):
+ foreach_notree_node(world.node_tree,
+ callback,
+ traversed)
+ for lamp in bpy.data.lamps:
+ if check_is_new_shading_world(lamp):
+ foreach_notree_node(lamp.node_tree,
+ callback,
+ traversed)
+
+
+def mapping_node_order_flip(node):
+ """
+ Flip euler order of mapping shader node
+ """
+ if node.bl_idname == 'ShaderNodeMapping':
+ rot = node.rotation.copy()
+ rot.order = 'ZYX'
+ quat = rot.to_quaternion()
+ node.rotation = quat.to_euler('XYZ')
+
+
@persistent
def do_versions(self):
# We don't modify startup file because it assumes to
@@ -57,3 +136,7 @@ def do_versions(self):
cscene.caustics_reflective = False
cscene.caustics_refractive = False
+
+ # Euler order was ZYX in previous versions.
+ if bpy.data.version <= (2, 73, 4):
+ foreach_cycles_node(mapping_node_order_flip)
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index ce8c64c4819..dee9ee09fc6 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "camera.h"
@@ -20,6 +20,8 @@
#include "blender_sync.h"
#include "blender_util.h"
+#include "util_logging.h"
+
CCL_NAMESPACE_BEGIN
/* Blender Camera Intermediate: we first convert both the offline and 3d view
@@ -51,6 +53,10 @@ struct BlenderCamera {
PanoramaType panorama_type;
float fisheye_fov;
float fisheye_lens;
+ float latitude_min;
+ float latitude_max;
+ float longitude_min;
+ float longitude_max;
enum { AUTO, HORIZONTAL, VERTICAL } sensor_fit;
float sensor_width;
@@ -61,6 +67,7 @@ struct BlenderCamera {
BoundBox2D border;
BoundBox2D pano_viewplane;
+ BoundBox2D viewport_camera_border;
Transform matrix;
};
@@ -80,6 +87,8 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render
bcam->border.top = 1.0f;
bcam->pano_viewplane.right = 1.0f;
bcam->pano_viewplane.top = 1.0f;
+ bcam->viewport_camera_border.right = 1.0f;
+ bcam->viewport_camera_border.top = 1.0f;
/* render resolution */
bcam->full_width = render_resolution_x(b_render);
@@ -145,6 +154,10 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, boo
bcam->fisheye_fov = RNA_float_get(&ccamera, "fisheye_fov");
bcam->fisheye_lens = RNA_float_get(&ccamera, "fisheye_lens");
+ bcam->latitude_min = RNA_float_get(&ccamera, "latitude_min");
+ bcam->latitude_max = RNA_float_get(&ccamera, "latitude_max");
+ bcam->longitude_min = RNA_float_get(&ccamera, "longitude_min");
+ bcam->longitude_max = RNA_float_get(&ccamera, "longitude_max");
bcam->ortho_scale = b_camera.ortho_scale();
@@ -330,6 +343,11 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
cam->panorama_type = bcam->panorama_type;
cam->fisheye_fov = bcam->fisheye_fov;
cam->fisheye_lens = bcam->fisheye_lens;
+ cam->latitude_min = bcam->latitude_min;
+ cam->latitude_max = bcam->latitude_max;
+
+ cam->longitude_min = bcam->longitude_min;
+ cam->longitude_max = bcam->longitude_max;
/* anamorphic lens bokeh */
cam->aperture_ratio = bcam->aperture_ratio;
@@ -350,6 +368,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
/* border */
cam->border = bcam->border;
+ cam->viewport_camera_border = bcam->viewport_camera_border;
/* set update flag */
if(cam->modified(prevcam))
@@ -400,6 +419,7 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time)
tfm = blender_camera_matrix(tfm, cam->type);
if(tfm != cam->matrix) {
+ VLOG(1) << "Camera " << b_ob.name() << " motion detected.";
if(motion_time == -1.0f) {
cam->motion.pre = tfm;
cam->use_motion = true;
@@ -500,6 +520,25 @@ static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_
*cam_box = cam * (1.0f/cam_aspect);
}
+static void blender_camera_border_subset(BL::RenderSettings b_render,
+ BL::Scene b_scene,
+ BL::SpaceView3D b_v3d,
+ BL::RegionView3D b_rv3d,
+ BL::Object b_ob,
+ int width, int height,
+ const BoundBox2D &border,
+ BoundBox2D *result)
+{
+ /* Determine camera viewport subset. */
+ BoundBox2D view_box, cam_box;
+ blender_camera_view_subset(b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height,
+ &view_box, &cam_box);
+
+ /* Determine viewport subset matching given border. */
+ cam_box = cam_box.make_relative_to(view_box);
+ *result = cam_box.subset(border);
+}
+
static void blender_camera_border(BlenderCamera *bcam, BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height)
{
@@ -518,32 +557,45 @@ static void blender_camera_border(BlenderCamera *bcam, BL::RenderSettings b_rend
bcam->border.right = b_v3d.render_border_max_x();
bcam->border.bottom = b_v3d.render_border_min_y();
bcam->border.top = b_v3d.render_border_max_y();
-
- return;
}
- }
- else if(!b_render.use_border())
return;
+ }
BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera();
if(!b_ob)
return;
+ /* Determine camera border inside the viewport. */
+ BoundBox2D full_border;
+ blender_camera_border_subset(b_render,
+ b_scene,
+ b_v3d,
+ b_rv3d,
+ b_ob,
+ width, height,
+ full_border,
+ &bcam->viewport_camera_border);
+
+ if(!b_render.use_border()) {
+ return;
+ }
+
bcam->border.left = b_render.border_min_x();
bcam->border.right = b_render.border_max_x();
bcam->border.bottom = b_render.border_min_y();
bcam->border.top = b_render.border_max_y();
- /* determine camera viewport subset */
- BoundBox2D view_box, cam_box;
-
- blender_camera_view_subset(b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height,
- &view_box, &cam_box);
-
- /* determine viewport subset matching camera border */
- cam_box = cam_box.make_relative_to(view_box);
- bcam->border = cam_box.subset(bcam->border).clamp();
+ /* Determine viewport subset matching camera border. */
+ blender_camera_border_subset(b_render,
+ b_scene,
+ b_v3d,
+ b_rv3d,
+ b_ob,
+ width, height,
+ bcam->border,
+ &bcam->border);
+ bcam->border.clamp();
}
void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height)
@@ -571,10 +623,12 @@ BufferParams BlenderSync::get_buffer_params(BL::RenderSettings b_render, BL::Sce
if(use_border) {
/* border render */
- params.full_x = (int)(cam->border.left * (float)width);
- params.full_y = (int)(cam->border.bottom * (float)height);
- params.width = (int)(cam->border.right * (float)width) - params.full_x;
- params.height = (int)(cam->border.top * (float)height) - params.full_y;
+ /* the viewport may offset the border outside the view */
+ BoundBox2D border = cam->border.clamp();
+ params.full_x = (int)(border.left * (float)width);
+ params.full_y = (int)(border.bottom * (float)height);
+ params.width = (int)(border.right * (float)width) - params.full_x;
+ params.height = (int)(border.top * (float)height) - params.full_y;
/* survive in case border goes out of view or becomes too small */
params.width = max(params.width, 1);
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 8cfaea59a06..72023d7e69b 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "attribute.h"
@@ -25,6 +25,7 @@
#include "blender_util.h"
#include "util_foreach.h"
+#include "util_logging.h"
CCL_NAMESPACE_BEGIN
@@ -140,7 +141,6 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
int mi = clamp(b_part.material()-1, 0, mesh->used_shaders.size()-1);
int shader = mesh->used_shaders[mi];
int draw_step = background ? b_part.render_step() : b_part.draw_step();
- int ren_step = (int)powf(2.0f, (float)draw_step);
int totparts = b_psys.particles.length();
int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);
int totcurves = totchild;
@@ -151,6 +151,10 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
if(totcurves == 0)
continue;
+ int ren_step = (1 << draw_step) + 1;
+ if (b_part.kink() == BL::ParticleSettings::kink_SPIRAL)
+ ren_step += b_part.kink_extra_steps();
+
PointerRNA cpsys = RNA_pointer_get(&b_part.ptr, "cycles");
CData->psys_firstcurve.push_back(curvenum);
@@ -172,8 +176,8 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
CData->curve_firstkey.reserve(CData->curve_firstkey.size() + num_add);
CData->curve_keynum.reserve(CData->curve_keynum.size() + num_add);
CData->curve_length.reserve(CData->curve_length.size() + num_add);
- CData->curvekey_co.reserve(CData->curvekey_co.size() + num_add*(ren_step+1));
- CData->curvekey_time.reserve(CData->curvekey_time.size() + num_add*(ren_step+1));
+ CData->curvekey_co.reserve(CData->curvekey_co.size() + num_add*ren_step);
+ CData->curvekey_time.reserve(CData->curvekey_time.size() + num_add*ren_step);
for(; pa_no < totparts+totchild; pa_no++) {
int keynum = 0;
@@ -181,7 +185,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
float curve_length = 0.0f;
float3 pcKey;
- for(int step_no = 0; step_no <= ren_step; step_no++) {
+ for(int step_no = 0; step_no < ren_step; step_no++) {
float nco[3];
b_psys.co_hair(*b_ob, pa_no, step_no, nco);
float3 cKey = make_float3(nco[0], nco[1], nco[2]);
@@ -195,9 +199,9 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
CData->curvekey_co.push_back(cKey);
CData->curvekey_time.push_back(curve_length);
pcKey = cKey;
- keyno++;
keynum++;
}
+ keyno += keynum;
CData->curve_keynum.push_back(keynum);
CData->curve_length.push_back(curve_length);
@@ -577,6 +581,10 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
}
}
+ if (num_curves > 0) {
+ VLOG(1) << "Exporting curve segments for mesh " << mesh->name;
+ }
+
mesh->curve_keys.reserve(mesh->curve_keys.size() + num_keys);
mesh->curves.reserve(mesh->curves.size() + num_curves);
@@ -612,9 +620,9 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
}
}
- /* check allocation*/
+ /* check allocation */
if((mesh->curve_keys.size() != num_keys) || (mesh->curves.size() != num_curves)) {
- /* allocation failed -> clear data */
+ VLOG(1) << "Allocation failed, clearing data";
mesh->curve_keys.clear();
mesh->curves.clear();
mesh->curve_attributes.clear();
@@ -623,12 +631,16 @@ void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData)
static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int time_index)
{
+ VLOG(1) << "Exporting curve motion segments for mesh " << mesh->name
+ << ", time index " << time_index;
+
/* find attribute */
Attribute *attr_mP = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
bool new_attribute = false;
/* add new attribute if it doesn't exist already */
if(!attr_mP) {
+ VLOG(1) << "Creating new motion vertex position attribute";
attr_mP = mesh->curve_attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
new_attribute = true;
}
@@ -675,9 +687,12 @@ static void ExportCurveSegmentsMotion(Scene *scene, Mesh *mesh, ParticleCurveDat
if(new_attribute) {
if(i != numkeys || !have_motion) {
/* no motion, remove attributes again */
+ VLOG(1) << "No motion, removing attribute";
mesh->curve_attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
}
else if(time_index > 0) {
+ VLOG(1) << "Filling in new motion vertex position for time_index "
+ << time_index;
/* motion, fill up previous steps that we might have skipped because
* they had no motion, but we need them anyway now */
for(int step = 0; step < time_index; step++) {
@@ -786,30 +801,38 @@ void BlenderSync::sync_curve_settings()
curve_system_manager->subdivisions = get_int(csscene, "subdivisions");
curve_system_manager->use_backfacing = !get_boolean(csscene, "cull_backfacing");
- if(curve_system_manager->primitive == CURVE_TRIANGLES && curve_system_manager->curve_shape == CURVE_RIBBON) {
- /* camera facing planes */
- curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES;
- curve_system_manager->resolution = 1;
- }
- else if(curve_system_manager->primitive == CURVE_TRIANGLES && curve_system_manager->curve_shape == CURVE_THICK) {
+ /* Triangles */
+ if(curve_system_manager->primitive == CURVE_TRIANGLES) {
/* camera facing planes */
- curve_system_manager->triangle_method = CURVE_TESSELATED_TRIANGLES;
- }
- else if(curve_system_manager->primitive == CURVE_LINE_SEGMENTS && curve_system_manager->curve_shape == CURVE_RIBBON) {
- /* tangent shading */
- curve_system_manager->line_method = CURVE_UNCORRECTED;
- curve_system_manager->use_encasing = true;
- curve_system_manager->use_backfacing = false;
- curve_system_manager->use_tangent_normal_geometry = true;
+ if(curve_system_manager->curve_shape == CURVE_RIBBON) {
+ curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES;
+ curve_system_manager->resolution = 1;
+ }
+ else if(curve_system_manager->curve_shape == CURVE_THICK) {
+ curve_system_manager->triangle_method = CURVE_TESSELATED_TRIANGLES;
+ }
}
- else if(curve_system_manager->primitive == CURVE_LINE_SEGMENTS && curve_system_manager->curve_shape == CURVE_THICK) {
- curve_system_manager->line_method = CURVE_ACCURATE;
- curve_system_manager->use_encasing = false;
- curve_system_manager->use_tangent_normal_geometry = false;
+ /* Line Segments */
+ else if(curve_system_manager->primitive == CURVE_LINE_SEGMENTS) {
+ if(curve_system_manager->curve_shape == CURVE_RIBBON) {
+ /* tangent shading */
+ curve_system_manager->line_method = CURVE_UNCORRECTED;
+ curve_system_manager->use_encasing = true;
+ curve_system_manager->use_backfacing = false;
+ curve_system_manager->use_tangent_normal_geometry = true;
+ }
+ else if(curve_system_manager->curve_shape == CURVE_THICK) {
+ curve_system_manager->line_method = CURVE_ACCURATE;
+ curve_system_manager->use_encasing = false;
+ curve_system_manager->use_tangent_normal_geometry = false;
+ }
}
- else if(curve_system_manager->primitive == CURVE_SEGMENTS && curve_system_manager->curve_shape == CURVE_RIBBON) {
- curve_system_manager->primitive = CURVE_RIBBONS;
- curve_system_manager->use_backfacing = false;
+ /* Curve Segments */
+ else if(curve_system_manager->primitive == CURVE_SEGMENTS) {
+ if(curve_system_manager->curve_shape == CURVE_RIBBON) {
+ curve_system_manager->primitive = CURVE_RIBBONS;
+ curve_system_manager->use_backfacing = false;
+ }
}
if(curve_system_manager->modified_mesh(prev_curve_system_manager)) {
diff --git a/intern/cycles/blender/blender_logging.cpp b/intern/cycles/blender/blender_logging.cpp
index d3f1accf099..f4f86929168 100644
--- a/intern/cycles/blender/blender_logging.cpp
+++ b/intern/cycles/blender/blender_logging.cpp
@@ -11,55 +11,23 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "CCL_api.h"
-
-#include <stdio.h>
-
#include "util_logging.h"
-#ifdef _MSC_VER
-# define snprintf _snprintf
-#endif
-
void CCL_init_logging(const char *argv0)
{
-#ifdef WITH_CYCLES_LOGGING
- /* Make it so FATAL messages are always print into console. */
- char severity_fatal[32];
- snprintf(severity_fatal, sizeof(severity_fatal), "%d",
- google::GLOG_FATAL);
-
- google::InitGoogleLogging(argv0);
- google::SetCommandLineOption("logtostderr", "1");
- google::SetCommandLineOption("v", "0");
- google::SetCommandLineOption("stderrthreshold", severity_fatal);
- google::SetCommandLineOption("minloglevel", severity_fatal);
-#else
- (void) argv0;
-#endif
+ ccl::util_logging_init(argv0);
}
void CCL_start_debug_logging(void)
{
-#ifdef WITH_CYCLES_LOGGING
- google::SetCommandLineOption("logtostderr", "1");
- google::SetCommandLineOption("v", "2");
- google::SetCommandLineOption("stderrthreshold", "1");
- google::SetCommandLineOption("minloglevel", "0");
-#endif
+ ccl::util_logging_start();
}
void CCL_logging_verbosity_set(int verbosity)
{
-#ifdef WITH_CYCLES_LOGGING
- char val[10];
- snprintf(val, sizeof(val), "%d", verbosity);
-
- google::SetCommandLineOption("v", val);
-#else
- (void) verbosity;
-#endif
+ ccl::util_logging_verbosity_set(verbosity);
}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index a5e4b7bd2ae..c70ffea39c3 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
@@ -20,6 +20,7 @@
#include "scene.h"
#include "blender_sync.h"
+#include "blender_session.h"
#include "blender_util.h"
#include "subd_mesh.h"
@@ -27,6 +28,8 @@
#include "subd_split.h"
#include "util_foreach.h"
+#include "util_logging.h"
+#include "util_math.h"
#include "mikktspace.h"
@@ -104,7 +107,9 @@ static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float
int vert_idx = userdata->mesh.tessfaces[face_num].vertices()[vert_num];
float3 orco =
get_float3(userdata->mesh.vertices[vert_idx].undeformed_co());
- map_to_sphere(&uv[0], &uv[1], orco[0], orco[1], orco[2]);
+ float2 tmp = map_to_sphere(make_float3(orco[0], orco[1], orco[2]));
+ uv[0] = tmp.x;
+ uv[1] = tmp.y;
}
}
@@ -135,7 +140,7 @@ static void mikk_set_tangent_space(const SMikkTSpaceContext *context, const floa
userdata->tangent[face*4 + vert] = make_float4(T[0], T[1], T[2], sign);
}
-static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer *b_layer, Mesh *mesh, vector<int>& nverts, bool need_sign, bool active_render)
+static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer *b_layer, Mesh *mesh, const vector<int>& nverts, bool need_sign, bool active_render)
{
/* setup userdata */
MikkUserData userdata(b_mesh, b_layer, nverts.size());
@@ -256,6 +261,167 @@ static void create_mesh_volume_attributes(Scene *scene, BL::Object b_ob, Mesh *m
create_mesh_volume_attribute(b_ob, mesh, scene->image_manager, ATTR_STD_VOLUME_VELOCITY, frame);
}
+/* Create vertex color attributes. */
+static void attr_create_vertex_color(Scene *scene,
+ Mesh *mesh,
+ BL::Mesh b_mesh,
+ const vector<int>& nverts)
+{
+ BL::Mesh::tessface_vertex_colors_iterator l;
+ for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) {
+ if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
+
+ Attribute *attr = mesh->attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
+
+ BL::MeshColorLayer::data_iterator c;
+ uchar4 *cdata = attr->data_uchar4();
+ size_t i = 0;
+
+ for(l->data.begin(c); c != l->data.end(); ++c, ++i) {
+ cdata[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1())));
+ cdata[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2())));
+ cdata[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3())));
+
+ if(nverts[i] == 4) {
+ cdata[3] = cdata[0];
+ cdata[4] = cdata[2];
+ cdata[5] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4())));
+ cdata += 6;
+ }
+ else
+ cdata += 3;
+ }
+ }
+}
+
+/* Create uv map attributes. */
+static void attr_create_uv_map(Scene *scene,
+ Mesh *mesh,
+ BL::Mesh b_mesh,
+ const vector<int>& nverts)
+{
+ if (b_mesh.tessface_uv_textures.length() != 0) {
+ BL::Mesh::tessface_uv_textures_iterator l;
+
+ for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
+ bool active_render = l->active_render();
+ AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
+ ustring name = ustring(l->name().c_str());
+
+ /* UV map */
+ if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
+ Attribute *attr;
+
+ if(active_render)
+ attr = mesh->attributes.add(std, name);
+ else
+ attr = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
+
+ BL::MeshTextureFaceLayer::data_iterator t;
+ float3 *fdata = attr->data_float3();
+ size_t i = 0;
+
+ for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
+ fdata[0] = get_float3(t->uv1());
+ fdata[1] = get_float3(t->uv2());
+ fdata[2] = get_float3(t->uv3());
+ fdata += 3;
+
+ if(nverts[i] == 4) {
+ fdata[0] = get_float3(t->uv1());
+ fdata[1] = get_float3(t->uv3());
+ fdata[2] = get_float3(t->uv4());
+ fdata += 3;
+ }
+ }
+ }
+
+ /* UV tangent */
+ std = (active_render)? ATTR_STD_UV_TANGENT: ATTR_STD_NONE;
+ name = ustring((string(l->name().c_str()) + ".tangent").c_str());
+
+ if(mesh->need_attribute(scene, name) || (active_render && mesh->need_attribute(scene, std))) {
+ std = (active_render)? ATTR_STD_UV_TANGENT_SIGN: ATTR_STD_NONE;
+ name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
+ bool need_sign = (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std));
+
+ mikk_compute_tangents(b_mesh, &(*l), mesh, nverts, need_sign, active_render);
+ }
+ }
+ }
+ else if(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
+ bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
+ mikk_compute_tangents(b_mesh, NULL, mesh, nverts, need_sign, true);
+ }
+}
+
+/* Create vertex pointiness attributes. */
+static void attr_create_pointiness(Scene *scene,
+ Mesh *mesh,
+ BL::Mesh b_mesh)
+{
+ if(mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
+ const int numverts = b_mesh.vertices.length();
+ Attribute *attr = mesh->attributes.add(ATTR_STD_POINTINESS);
+ float *data = attr->data_float();
+ int *counter = new int[numverts];
+ float *raw_data = new float[numverts];
+ float3 *edge_accum = new float3[numverts];
+
+ /* Calculate pointiness using single ring neighborhood. */
+ memset(counter, 0, sizeof(int) * numverts);
+ memset(raw_data, 0, sizeof(float) * numverts);
+ memset(edge_accum, 0, sizeof(float3) * numverts);
+ BL::Mesh::edges_iterator e;
+ int i = 0;
+ for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
+ int v0 = b_mesh.edges[i].vertices()[0],
+ v1 = b_mesh.edges[i].vertices()[1];
+ float3 co0 = get_float3(b_mesh.vertices[v0].co()),
+ co1 = get_float3(b_mesh.vertices[v1].co());
+ float3 edge = normalize(co1 - co0);
+ edge_accum[v0] += edge;
+ edge_accum[v1] += -edge;
+ ++counter[v0];
+ ++counter[v1];
+ }
+ i = 0;
+ BL::Mesh::vertices_iterator v;
+ for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++i) {
+ if(counter[i] > 0) {
+ float3 normal = get_float3(b_mesh.vertices[i].normal());
+ float angle = safe_acosf(dot(normal, edge_accum[i] / counter[i]));
+ raw_data[i] = angle * M_1_PI_F;
+ }
+ else {
+ raw_data[i] = 0.0f;
+ }
+ }
+
+ /* Blur vertices to approximate 2 ring neighborhood. */
+ memset(counter, 0, sizeof(int) * numverts);
+ memcpy(data, raw_data, sizeof(float) * numverts);
+ i = 0;
+ for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
+ int v0 = b_mesh.edges[i].vertices()[0],
+ v1 = b_mesh.edges[i].vertices()[1];
+ data[v0] += raw_data[v1];
+ data[v1] += raw_data[v0];
+ ++counter[v0];
+ ++counter[v1];
+ }
+ for(i = 0; i < numverts; ++i) {
+ data[i] /= counter[i] + 1;
+ }
+
+ delete [] counter;
+ delete [] raw_data;
+ delete [] edge_accum;
+ }
+}
+
/* Create Mesh */
static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders)
@@ -303,6 +469,9 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
generated[i++] = get_float3(v->undeformed_co())*size - loc;
}
+ /* Create needed vertex attributes. */
+ attr_create_pointiness(scene, mesh, b_mesh);
+
/* create faces */
vector<int> nverts(numfaces);
int fi = 0, ti = 0;
@@ -312,7 +481,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
int n = (vi[3] == 0)? 3: 4;
int mi = clamp(f->material_index(), 0, used_shaders.size()-1);
int shader = used_shaders[mi];
- bool smooth = f->use_smooth();
+ bool smooth = f->use_smooth() || use_loop_normals;
/* split vertices if normal is different
*
@@ -354,92 +523,11 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
nverts[fi] = n;
}
- /* create vertex color attributes */
- {
- BL::Mesh::tessface_vertex_colors_iterator l;
-
- for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) {
- if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
- continue;
-
- Attribute *attr = mesh->attributes.add(
- ustring(l->name().c_str()), TypeDesc::TypeColor, ATTR_ELEMENT_CORNER_BYTE);
-
- BL::MeshColorLayer::data_iterator c;
- uchar4 *cdata = attr->data_uchar4();
- size_t i = 0;
-
- for(l->data.begin(c); c != l->data.end(); ++c, ++i) {
- cdata[0] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color1())));
- cdata[1] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color2())));
- cdata[2] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color3())));
-
- if(nverts[i] == 4) {
- cdata[3] = cdata[0];
- cdata[4] = cdata[2];
- cdata[5] = color_float_to_byte(color_srgb_to_scene_linear(get_float3(c->color4())));
- cdata += 6;
- }
- else
- cdata += 3;
- }
- }
- }
-
- /* create uv map attributes */
- if (b_mesh.tessface_uv_textures.length() != 0) {
- BL::Mesh::tessface_uv_textures_iterator l;
-
- for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
- bool active_render = l->active_render();
- AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
- ustring name = ustring(l->name().c_str());
-
- /* UV map */
- if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
- Attribute *attr;
-
- if(active_render)
- attr = mesh->attributes.add(std, name);
- else
- attr = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
-
- BL::MeshTextureFaceLayer::data_iterator t;
- float3 *fdata = attr->data_float3();
- size_t i = 0;
-
- for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
- fdata[0] = get_float3(t->uv1());
- fdata[1] = get_float3(t->uv2());
- fdata[2] = get_float3(t->uv3());
- fdata += 3;
-
- if(nverts[i] == 4) {
- fdata[0] = get_float3(t->uv1());
- fdata[1] = get_float3(t->uv3());
- fdata[2] = get_float3(t->uv4());
- fdata += 3;
- }
- }
- }
-
- /* UV tangent */
- std = (active_render)? ATTR_STD_UV_TANGENT: ATTR_STD_NONE;
- name = ustring((string(l->name().c_str()) + ".tangent").c_str());
-
- if(mesh->need_attribute(scene, name) || (active_render && mesh->need_attribute(scene, std))) {
- std = (active_render)? ATTR_STD_UV_TANGENT_SIGN: ATTR_STD_NONE;
- name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
- bool need_sign = (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std));
-
- mikk_compute_tangents(b_mesh, &(*l), mesh, nverts, need_sign, active_render);
- }
- }
- }
- else if(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT)) {
- bool need_sign = mesh->need_attribute(scene, ATTR_STD_UV_TANGENT_SIGN);
- mikk_compute_tangents(b_mesh, NULL, mesh, nverts, need_sign, true);
- }
+ /* Create all needed attributes.
+ * The calculate functions will check whether they're needed or not.
+ */
+ attr_create_vertex_color(scene, mesh, b_mesh, nverts);
+ attr_create_uv_map(scene, mesh, b_mesh, nverts);
/* for volume objects, create a matrix to transform from object space to
* mesh texture space. this does not work with deformations but that can
@@ -501,6 +589,14 @@ static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, PointerR
Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris)
{
+ /* When viewport display is not needed during render we can force some
+ * caches to be releases from blender side in order to reduce peak memory
+ * footprint during synchronization process.
+ */
+ const bool is_interface_locked = b_engine.render() &&
+ b_engine.render().use_lock_interface();
+ const bool can_free_caches = BlenderSession::headless || is_interface_locked;
+
/* test if we can instance or if the object is modified */
BL::ID b_ob_data = b_ob.data();
BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob_data;
@@ -594,6 +690,10 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
if(render_layer.use_hair)
sync_curves(mesh, b_mesh, b_ob, false);
+ if(can_free_caches) {
+ b_ob.cache_release();
+ }
+
/* free derived mesh */
b_data.meshes.remove(b_mesh);
}
@@ -761,11 +861,13 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Object *object, float motion
if(new_attribute) {
if(i != numverts || memcmp(mP, &mesh->verts[0], sizeof(float3)*numverts) == 0) {
/* no motion, remove attributes again */
+ VLOG(1) << "No actual deformation motion for object " << b_ob.name();
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
if(attr_mN)
mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL);
}
else if(time_index > 0) {
+ VLOG(1) << "Filling deformation motion for object " << b_ob.name();
/* motion, fill up previous steps that we might have skipped because
* they had no motion, but we need them anyway now */
float3 *P = &mesh->verts[0];
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 1e07c5f9c96..e827d46223b 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "camera.h"
@@ -30,6 +30,7 @@
#include "util_foreach.h"
#include "util_hash.h"
+#include "util_logging.h"
CCL_NAMESPACE_BEGIN
@@ -168,6 +169,8 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
else
light->samples = samples;
+ light->max_bounces = get_int(clamp, "max_bounces");
+
/* visibility */
uint visibility = object_ray_visibility(b_ob);
light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
@@ -249,6 +252,7 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
if(object && (scene->need_motion() == Scene::MOTION_PASS || object_use_motion(b_ob))) {
/* object transformation */
if(tfm != object->tfm) {
+ VLOG(1) << "Object " << b_ob.name() << " motion detected.";
if(motion_time == -1.0f) {
object->motion.pre = tfm;
object->use_motion = true;
@@ -410,9 +414,17 @@ static bool object_render_hide(BL::Object b_ob, bool top_level, bool parent_hide
/* hide original object for duplis */
BL::Object parent = b_ob.parent();
- if(parent && object_render_hide_original(b_ob.type(), parent.dupli_type()))
- if(parent_hide)
- hide_as_dupli_child_original = true;
+ while(parent) {
+ if(object_render_hide_original(b_ob.type(),
+ parent.dupli_type()))
+ {
+ if(parent_hide) {
+ hide_as_dupli_child_original = true;
+ break;
+ }
+ }
+ parent = parent.parent();
+ }
hide_triangles = hide_emitter;
@@ -458,10 +470,10 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
BL::Scene::object_bases_iterator b_base;
BL::Scene b_sce = b_scene;
/* modifier result type (not exposed as enum in C++ API)
- * 1 : DAG_EVAL_PREVIEW
- * 2 : DAG_EVAL_RENDER
- */
- int dupli_settings = preview ? 1 : 2;
+ * 1 : DAG_EVAL_PREVIEW
+ * 2 : DAG_EVAL_RENDER
+ */
+ int dupli_settings = preview ? 1 : 2;
bool cancel = false;
diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp
index 5b2782ec2ac..2785cfa9634 100644
--- a/intern/cycles/blender/blender_particles.cpp
+++ b/intern/cycles/blender/blender_particles.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "mesh.h"
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 8e5a6c13f44..292af14c63a 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <Python.h>
@@ -73,8 +73,9 @@ static const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
static PyObject *init_func(PyObject *self, PyObject *args)
{
PyObject *path, *user_path;
+ int headless;
- if(!PyArg_ParseTuple(args, "OO", &path, &user_path)) {
+ if(!PyArg_ParseTuple(args, "OOi", &path, &user_path, &headless)) {
return NULL;
}
@@ -84,6 +85,8 @@ static PyObject *init_func(PyObject *self, PyObject *args)
Py_XDECREF(path_coerce);
Py_XDECREF(user_path_coerce);
+ BlenderSession::headless = headless;
+
Py_RETURN_NONE;
}
@@ -92,8 +95,11 @@ static PyObject *create_func(PyObject *self, PyObject *args)
PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
int preview_osl;
- if(!PyArg_ParseTuple(args, "OOOOOOOi", &pyengine, &pyuserpref, &pydata, &pyscene, &pyregion, &pyv3d, &pyrv3d, &preview_osl))
+ if(!PyArg_ParseTuple(args, "OOOOOOOi", &pyengine, &pyuserpref, &pydata, &pyscene,
+ &pyregion, &pyv3d, &pyrv3d, &preview_osl))
+ {
return NULL;
+ }
/* RNA */
PointerRNA engineptr;
@@ -105,7 +111,7 @@ static PyObject *create_func(PyObject *self, PyObject *args)
BL::UserPreferences userpref(userprefptr);
PointerRNA dataptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr);
+ RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
BL::BlendData data(dataptr);
PointerRNA sceneptr;
@@ -113,15 +119,15 @@ static PyObject *create_func(PyObject *self, PyObject *args)
BL::Scene scene(sceneptr);
PointerRNA regionptr;
- RNA_id_pointer_create((ID*)pylong_as_voidptr_typesafe(pyregion), &regionptr);
+ RNA_pointer_create(NULL, &RNA_Region, pylong_as_voidptr_typesafe(pyregion), &regionptr);
BL::Region region(regionptr);
PointerRNA v3dptr;
- RNA_id_pointer_create((ID*)pylong_as_voidptr_typesafe(pyv3d), &v3dptr);
+ RNA_pointer_create(NULL, &RNA_SpaceView3D, pylong_as_voidptr_typesafe(pyv3d), &v3dptr);
BL::SpaceView3D v3d(v3dptr);
PointerRNA rv3dptr;
- RNA_id_pointer_create((ID*)pylong_as_voidptr_typesafe(pyrv3d), &rv3dptr);
+ RNA_pointer_create(NULL, &RNA_RegionView3D, pylong_as_voidptr_typesafe(pyrv3d), &rv3dptr);
BL::RegionView3D rv3d(rv3dptr);
/* create session */
@@ -196,7 +202,7 @@ static PyObject *bake_func(PyObject *self, PyObject *args)
void *b_result = PyLong_AsVoidPtr(pyresult);
PointerRNA bakepixelptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pypixel_array), &bakepixelptr);
+ RNA_pointer_create(NULL, &RNA_BakePixel, PyLong_AsVoidPtr(pypixel_array), &bakepixelptr);
BL::BakePixel b_bake_pixel(bakepixelptr);
python_thread_state_save(&session->python_thread_state);
@@ -238,7 +244,7 @@ static PyObject *reset_func(PyObject *self, PyObject *args)
BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
PointerRNA dataptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr);
+ RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
BL::BlendData b_data(dataptr);
PointerRNA sceneptr;
@@ -385,13 +391,7 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
/* find socket socket */
BL::NodeSocket b_sock(PointerRNA_NULL);
if (param->isoutput) {
-#if OSL_LIBRARY_VERSION_CODE < 10500
- b_sock = b_node.outputs[param->name];
-#else
b_sock = b_node.outputs[param->name.string()];
-#endif
-
-
/* remove if type no longer matches */
if(b_sock && b_sock.bl_idname() != socket_type) {
b_node.outputs.remove(b_sock);
@@ -399,12 +399,7 @@ static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
}
}
else {
-#if OSL_LIBRARY_VERSION_CODE < 10500
- b_sock = b_node.inputs[param->name];
-#else
b_sock = b_node.inputs[param->name.string()];
-#endif
-
/* remove if type no longer matches */
if(b_sock && b_sock.bl_idname() != socket_type) {
b_node.inputs.remove(b_sock);
@@ -484,6 +479,12 @@ static PyObject *osl_compile_func(PyObject *self, PyObject *args)
}
#endif
+static PyObject *system_info_func(PyObject *self, PyObject *value)
+{
+ string system_info = Device::device_capabilities();
+ return PyUnicode_FromString(system_info.c_str());
+}
+
static PyMethodDef methods[] = {
{"init", init_func, METH_VARARGS, ""},
{"create", create_func, METH_VARARGS, ""},
@@ -498,6 +499,7 @@ static PyMethodDef methods[] = {
{"osl_compile", osl_compile_func, METH_VARARGS, ""},
#endif
{"available_devices", available_devices_func, METH_NOARGS, ""},
+ {"system_info", system_info_func, METH_NOARGS, ""},
{NULL, NULL, 0, NULL},
};
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 57ffea4b1a9..e61203d807a 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdlib.h>
@@ -41,6 +41,8 @@
CCL_NAMESPACE_BEGIN
+bool BlenderSession::headless = false;
+
BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_,
BL::BlendData b_data_, BL::Scene b_scene_)
: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_render(b_engine_.render()), b_scene(b_scene_),
@@ -86,12 +88,14 @@ void BlenderSession::create()
void BlenderSession::create_session()
{
- SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
+ bool is_cpu = session_params.device.type == DEVICE_CPU;
+ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background, is_cpu);
bool session_pause = BlenderSync::get_session_pause(b_scene, background);
/* reset status/progress */
last_status = "";
+ last_error = "";
last_progress = -1.0f;
start_resize_time = 0.0;
@@ -111,7 +115,7 @@ void BlenderSession::create_session()
session->set_pause(session_pause);
/* create sync */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU);
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, is_cpu);
if(b_v3d) {
if(session_pause == false) {
@@ -141,8 +145,9 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
b_render = b_engine.render();
b_scene = b_scene_;
- SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
+ const bool is_cpu = session_params.device.type == DEVICE_CPU;
+ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background, is_cpu);
width = render_resolution_x(b_render);
height = render_resolution_y(b_render);
@@ -173,7 +178,7 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
session->stats.mem_peak = session->stats.mem_used;
/* sync object should be re-created */
- sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU);
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, is_cpu);
/* for final render we will do full data sync per render layer, only
* do some basic syncing here, no objects or materials for speed */
@@ -640,8 +645,9 @@ void BlenderSession::synchronize()
return;
/* on session/scene parameter changes, we recreate session entirely */
- SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
+ const bool is_cpu = session_params.device.type == DEVICE_CPU;
+ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background, is_cpu);
bool session_pause = BlenderSync::get_session_pause(b_scene, background);
if(session->params.modified(session_params) ||
@@ -774,19 +780,23 @@ void BlenderSession::get_status(string& status, string& substatus)
session->progress.get_status(status, substatus);
}
-void BlenderSession::get_progress(float& progress, double& total_time)
+void BlenderSession::get_progress(float& progress, double& total_time, double& render_time)
{
double tile_time;
int tile, sample, samples_per_tile;
int tile_total = session->tile_manager.state.num_tiles;
+ int samples = session->tile_manager.state.sample + 1;
+ int total_samples = session->tile_manager.num_samples;
- session->progress.get_tile(tile, total_time, tile_time);
+ session->progress.get_tile(tile, total_time, render_time, tile_time);
sample = session->progress.get_sample();
samples_per_tile = session->tile_manager.num_samples;
- if(samples_per_tile && tile_total)
+ if(background && samples_per_tile && tile_total)
progress = ((float)sample / (float)(tile_total * samples_per_tile));
+ else if(!background && samples > 0 && total_samples != USHRT_MAX)
+ progress = ((float)samples) / total_samples;
else
progress = 0.0;
}
@@ -816,22 +826,18 @@ void BlenderSession::update_status_progress()
string timestatus, status, substatus;
string scene = "";
float progress;
- double total_time, remaining_time = 0;
+ double total_time, remaining_time = 0, render_time;
char time_str[128];
float mem_used = (float)session->stats.mem_used / 1024.0f / 1024.0f;
float mem_peak = (float)session->stats.mem_peak / 1024.0f / 1024.0f;
- int samples = session->tile_manager.state.sample + 1;
- int total_samples = session->tile_manager.num_samples;
get_status(status, substatus);
- get_progress(progress, total_time);
+ get_progress(progress, total_time, render_time);
-
+ if(progress > 0)
+ remaining_time = (1.0 - (double)progress) * (render_time / (double)progress);
if(background) {
- if(progress>0)
- remaining_time = (1.0 - (double)progress) * (total_time / (double)progress);
-
scene += " | " + b_scene.name();
if(b_rlay_name != "")
scene += ", " + b_rlay_name;
@@ -839,16 +845,13 @@ void BlenderSession::update_status_progress()
else {
BLI_timestr(total_time, time_str, sizeof(time_str));
timestatus = "Time:" + string(time_str) + " | ";
-
- if(samples > 0 && total_samples != USHRT_MAX)
- remaining_time = (total_samples - samples) * (total_time / samples);
}
-
- if(remaining_time>0) {
+
+ if(remaining_time > 0) {
BLI_timestr(remaining_time, time_str, sizeof(time_str));
timestatus += "Remaining:" + string(time_str) + " | ";
}
-
+
timestatus += string_printf("Mem:%.2fM, Peak:%.2fM", (double)mem_used, (double)mem_peak);
if(status.size() > 0)
@@ -865,6 +868,21 @@ void BlenderSession::update_status_progress()
b_engine.update_progress(progress);
last_progress = progress;
}
+
+ if (session->progress.get_error()) {
+ string error = session->progress.get_error_message();
+ if(error != last_error) {
+ /* TODO(sergey): Currently C++ RNA API doesn't let us to
+ * use mnemonic name for the variable. Would be nice to
+ * have this figured out.
+ *
+ * For until then, 1 << 5 means RPT_ERROR.
+ */
+ b_engine.report(1 << 5, error.c_str());
+ b_engine.error_set(error.c_str());
+ last_error = error;
+ }
+ }
}
void BlenderSession::tag_update()
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index ac685118b3d..c8070286006 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __BLENDER_SESSION_H__
@@ -70,12 +70,13 @@ public:
void tag_redraw();
void tag_update();
void get_status(string& status, string& substatus);
- void get_progress(float& progress, double& total_time);
+ void get_progress(float& progress, double& total_time, double& render_time);
void test_cancel();
void update_status_progress();
void update_bake_progress();
bool background;
+ static bool headless;
Session *session;
Scene *scene;
BlenderSync *sync;
@@ -91,6 +92,7 @@ public:
string b_rlay_name;
string last_status;
+ string last_error;
float last_progress;
int width, height;
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 27c2e9e9ae8..baf79a78987 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "background.h"
@@ -687,6 +687,10 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
TextureCoordinateNode *tex_coord = new TextureCoordinateNode();
tex_coord->from_dupli = b_tex_coord_node.from_dupli();
+ if(b_tex_coord_node.object()) {
+ tex_coord->use_transform = true;
+ tex_coord->ob_tfm = get_transform(b_tex_coord_node.object().matrix_world());
+ }
node = tex_coord;
}
else if (b_node.is_a(&RNA_ShaderNodeTexSky)) {
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 2ac90b34fd7..985a3cd3d5a 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "background.h"
@@ -30,6 +30,7 @@
#include "device.h"
#include "blender_sync.h"
+#include "blender_session.h"
#include "blender_util.h"
#include "util_debug.h"
@@ -70,10 +71,18 @@ bool BlenderSync::sync_recalc()
* so we can do it later on if doing it immediate is not suitable */
BL::BlendData::materials_iterator b_mat;
-
- for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat)
- if(b_mat->is_updated() || (b_mat->node_tree() && b_mat->node_tree().is_updated()))
+ bool has_updated_objects = b_data.objects.is_updated();
+ for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
+ if(b_mat->is_updated() || (b_mat->node_tree() && b_mat->node_tree().is_updated())) {
shader_map.set_recalc(*b_mat);
+ }
+ else {
+ Shader *shader = shader_map.find(*b_mat);
+ if(has_updated_objects && shader != NULL && shader->has_object_dependency) {
+ shader_map.set_recalc(*b_mat);
+ }
+ }
+ }
BL::BlendData::lamps_iterator b_lamp;
@@ -353,7 +362,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer)
/* Scene Parameters */
-SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background)
+SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background, bool is_cpu)
{
BL::RenderSettings r = b_scene.render();
SceneParams params;
@@ -378,6 +387,16 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background)
else
params.persistent_data = false;
+#if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
+ if(is_cpu) {
+ params.use_qbvh = system_cpu_support_sse2();
+ }
+ else
+#endif
+ {
+ params.use_qbvh = false;
+ }
+
return params;
}
@@ -389,7 +408,10 @@ bool BlenderSync::get_session_pause(BL::Scene b_scene, bool background)
return (background)? false: get_boolean(cscene, "preview_pause");
}
-SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::UserPreferences b_userpref, BL::Scene b_scene, bool background)
+SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine,
+ BL::UserPreferences b_userpref,
+ BL::Scene b_scene,
+ bool background)
{
SessionParams params;
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@@ -478,8 +500,13 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
params.tile_size = make_int2(tile_x, tile_y);
}
-
- params.tile_order = (TileOrder)RNA_enum_get(&cscene, "tile_order");
+
+ if(BlenderSession::headless == false) {
+ params.tile_order = (TileOrder)RNA_enum_get(&cscene, "tile_order");
+ }
+ else {
+ params.tile_order = TILE_BOTTOM_TO_TOP;
+ }
params.start_resolution = get_int(cscene, "preview_start_resolution");
@@ -515,7 +542,24 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
params.shadingsystem = SHADINGSYSTEM_OSL;
/* color managagement */
- params.display_buffer_linear = GLEW_ARB_half_float_pixel && b_engine.support_display_space_shader(b_scene);
+#ifdef GLEW_MX
+ /* When using GLEW MX we need to check whether we've got an OpenGL
+ * context for current window. This is because command line rendering
+ * doesn't have OpenGL context actually.
+ */
+ if(glewGetContext() != NULL)
+#endif
+ {
+ params.display_buffer_linear = GLEW_ARB_half_float_pixel &&
+ b_engine.support_display_space_shader(b_scene);
+ }
+
+ if(b_engine.is_preview()) {
+ /* For preview rendering we're using same timeout as
+ * blender's job update.
+ */
+ params.progressive_update_timeout = 0.1;
+ }
return params;
}
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 9c4175ef690..6a320ac8085 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __BLENDER_SYNC_H__
@@ -62,8 +62,11 @@ public:
int get_layer_bound_samples() { return render_layer.bound_samples; }
/* get parameters */
- static SceneParams get_scene_params(BL::Scene b_scene, bool background);
- static SessionParams get_session_params(BL::RenderEngine b_engine, BL::UserPreferences b_userpref, BL::Scene b_scene, bool background);
+ static SceneParams get_scene_params(BL::Scene b_scene, bool background, bool is_cpu);
+ static SessionParams get_session_params(BL::RenderEngine b_engine,
+ BL::UserPreferences b_userpref,
+ BL::Scene b_scene,
+ bool background);
static bool get_session_pause(BL::Scene b_scene, bool background);
static BufferParams get_buffer_params(BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height);
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 35e417d8069..9f7181cc564 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __BLENDER_UTIL_H__
@@ -45,9 +45,9 @@ static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, BL:
BL::Mesh me = data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, false, calc_undeformed);
if ((bool)me) {
if (me.use_auto_smooth()) {
- me.calc_normals_split(me.auto_smooth_angle());
+ me.calc_normals_split();
}
- me.calc_tessface();
+ me.calc_tessface(true);
}
return me;
}
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 15bd814b8d5..9fa602f0952 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -205,6 +205,9 @@ void BVH::build(Progress& progress)
pack.prim_type = prim_type;
pack.prim_index = prim_index;
pack.prim_object = prim_object;
+ prim_type.free_memory();
+ prim_index.free_memory();
+ prim_object.free_memory();
/* compute SAH */
if(!params.top_level)
@@ -226,9 +229,8 @@ void BVH::build(Progress& progress)
/* pack nodes */
progress.set_substatus("Packing BVH nodes");
- array<int> tmp_prim_object = pack.prim_object;
- pack_nodes(tmp_prim_object, root);
-
+ pack_nodes(root);
+
/* free build nodes */
root->deleteSubtree();
@@ -263,11 +265,9 @@ void BVH::refit(Progress& progress)
void BVH::pack_triangle(int idx, float4 woop[3])
{
int tob = pack.prim_object[idx];
+ assert(tob >= 0 && tob < objects.size());
const Mesh *mesh = objects[tob]->mesh;
- if(mesh->has_motion_blur())
- return;
-
int tidx = pack.prim_index[idx];
const int *vidx = mesh->triangles[tidx].v;
const float3* vpos = &mesh->verts[0];
@@ -275,68 +275,13 @@ void BVH::pack_triangle(int idx, float4 woop[3])
float3 v1 = vpos[vidx[1]];
float3 v2 = vpos[vidx[2]];
- float3 r0 = v0 - v2;
- float3 r1 = v1 - v2;
- float3 r2 = cross(r0, r1);
-
- if(is_zero(r0) || is_zero(r1) || is_zero(r2)) {
- /* degenerate */
- woop[0] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- woop[1] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- woop[2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- else {
- Transform t = make_transform(
- r0.x, r1.x, r2.x, v2.x,
- r0.y, r1.y, r2.y, v2.y,
- r0.z, r1.z, r2.z, v2.z,
- 0.0f, 0.0f, 0.0f, 1.0f);
-
- t = transform_inverse(t);
-
- woop[0] = make_float4(t.z.x, t.z.y, t.z.z, -t.z.w);
- woop[1] = make_float4(t.x.x, t.x.y, t.x.z, t.x.w);
- woop[2] = make_float4(t.y.x, t.y.y, t.y.z, t.y.w);
- }
+ woop[0] = float3_to_float4(v0);
+ woop[1] = float3_to_float4(v1);
+ woop[2] = float3_to_float4(v2);
}
/* Curves*/
-void BVH::pack_curve_segment(int idx, float4 woop[3])
-{
- int tob = pack.prim_object[idx];
- const Mesh *mesh = objects[tob]->mesh;
- int tidx = pack.prim_index[idx];
- int segment = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[idx]);
- int k0 = mesh->curves[tidx].first_key + segment;
- int k1 = mesh->curves[tidx].first_key + segment + 1;
- float3 v0 = float4_to_float3(mesh->curve_keys[k0]);
- float3 v1 = float4_to_float3(mesh->curve_keys[k1]);
-
- float3 d0 = v1 - v0;
- float l = len(d0);
-
- /*Plan
- *Transform tfm = make_transform(
- * location <3> , l,
- * extra curve data <3> , StrID,
- * nextkey, flags/tip?, 0, 0);
- */
- float3 tg0 = make_float3(1.0f, 0.0f, 0.0f);
- float3 tg1 = make_float3(1.0f, 0.0f, 0.0f);
-
- Transform tfm = make_transform(
- tg0.x, tg0.y, tg0.z, l,
- tg1.x, tg1.y, tg1.z, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 1);
-
- woop[0] = tfm.x;
- woop[1] = tfm.y;
- woop[2] = tfm.z;
-
-}
-
void BVH::pack_primitives()
{
int nsize = TRI_NODE_SIZE;
@@ -351,11 +296,14 @@ void BVH::pack_primitives()
if(pack.prim_index[i] != -1) {
float4 woop[3];
- if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
- pack_curve_segment(i, woop);
- else
+ if(pack.prim_type[i] & PRIMITIVE_TRIANGLE) {
pack_triangle(i, woop);
-
+ }
+ else {
+ /* Avoid use of uninitialized memory. */
+ memset(&woop, 0, sizeof(woop));
+ }
+
memcpy(&pack.tri_woop[i * nsize], woop, sizeof(float4)*3);
int tob = pack.prim_object[i];
@@ -418,7 +366,7 @@ void BVH::pack_instances(size_t nodes_size)
if(mesh_map.find(mesh) == mesh_map.end()) {
prim_index_size += bvh->pack.prim_index.size();
tri_woop_size += bvh->pack.tri_woop.size();
- nodes_size += bvh->pack.nodes.size()*nsize;
+ nodes_size += bvh->pack.nodes.size();
mesh_map[mesh] = 1;
}
@@ -506,10 +454,13 @@ void BVH::pack_instances(size_t nodes_size)
/* merge nodes */
if(bvh->pack.nodes.size()) {
- size_t nsize_bbox = (use_qbvh)? nsize-2: nsize-1;
+ /* For QBVH we're packing a child bbox into 6 float4,
+ * and for regular BVH they're packed into 3 float4.
+ */
+ size_t nsize_bbox = (use_qbvh)? 6: 3;
int4 *bvh_nodes = &bvh->pack.nodes[0];
size_t bvh_nodes_size = bvh->pack.nodes.size();
- int *bvh_is_leaf = (bvh->pack.is_leaf.size() != 0) ? &bvh->pack.is_leaf[0] : NULL;
+ bool *bvh_is_leaf = (bvh->pack.is_leaf.size() != 0) ? &bvh->pack.is_leaf[0] : NULL;
for(size_t i = 0, j = 0; i < bvh_nodes_size; i+=nsize, j++) {
memcpy(pack_nodes + pack_nodes_offset, bvh_nodes + i, nsize_bbox*sizeof(int4));
@@ -533,8 +484,12 @@ void BVH::pack_instances(size_t nodes_size)
pack_nodes[pack_nodes_offset + nsize_bbox] = data;
- if(use_qbvh)
- pack_nodes[pack_nodes_offset + nsize_bbox+1] = bvh_nodes[i + nsize_bbox+1];
+ /* Usually this copies nothing, but we better
+ * be prepared for possible node size extension.
+ */
+ memcpy(&pack_nodes[pack_nodes_offset + nsize_bbox+1],
+ &bvh_nodes[i + nsize_bbox+1],
+ sizeof(int4) * (nsize - (nsize_bbox+1)));
pack_nodes_offset += nsize;
}
@@ -554,12 +509,20 @@ RegularBVH::RegularBVH(const BVHParams& params_, const vector<Object*>& objects_
void RegularBVH::pack_leaf(const BVHStackEntry& e, const LeafNode *leaf)
{
- if(leaf->num_triangles() == 1 && pack.prim_index[leaf->m_lo] == -1)
+ if(leaf->num_triangles() == 1 && pack.prim_index[leaf->m_lo] == -1) {
/* object */
- pack_node(e.idx, leaf->m_bounds, leaf->m_bounds, ~(leaf->m_lo), 0, leaf->m_visibility, leaf->m_visibility);
- else
- /* triangle */
- pack_node(e.idx, leaf->m_bounds, leaf->m_bounds, leaf->m_lo, leaf->m_hi, leaf->m_visibility, leaf->m_visibility);
+ pack_node(e.idx, leaf->m_bounds, leaf->m_bounds, ~(leaf->m_lo), 0,
+ leaf->m_visibility, leaf->m_visibility);
+ }
+ else {
+ int prim_type = leaf->num_triangles() ? pack.prim_type[leaf->m_lo] : 0;
+ /* Triangle/curve primitive leaf. */
+ pack_node(e.idx, leaf->m_bounds, leaf->m_bounds,
+ leaf->m_lo, leaf->m_hi,
+ leaf->m_visibility,
+ prim_type);
+ }
+
}
void RegularBVH::pack_inner(const BVHStackEntry& e, const BVHStackEntry& e0, const BVHStackEntry& e1)
@@ -580,7 +543,7 @@ void RegularBVH::pack_node(int idx, const BoundBox& b0, const BoundBox& b1, int
memcpy(&pack.nodes[idx * BVH_NODE_SIZE], data, sizeof(int4)*BVH_NODE_SIZE);
}
-void RegularBVH::pack_nodes(const array<int>& prims, const BVHNode *root)
+void RegularBVH::pack_nodes(const BVHNode *root)
{
size_t node_size = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
@@ -636,7 +599,7 @@ void RegularBVH::refit_nodes()
void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
{
- int4 *data = &pack.nodes[idx*4];
+ int4 *data = &pack.nodes[idx*BVH_NODE_SIZE];
int c0 = data[3].x;
int c1 = data[3].y;
@@ -707,7 +670,7 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility
visibility |= ob->visibility;
}
- pack_node(idx, bbox, bbox, c0, c1, visibility, visibility);
+ pack_node(idx, bbox, bbox, c0, c1, visibility, data[3].w);
}
else {
/* refit inner node, set bbox from children */
@@ -731,8 +694,6 @@ QBVH::QBVH(const BVHParams& params_, const vector<Object*>& objects_)
: BVH(params_, objects_)
{
params.use_qbvh = true;
-
- /* todo: use visibility */
}
void QBVH::pack_leaf(const BVHStackEntry& e, const LeafNode *leaf)
@@ -751,6 +712,10 @@ void QBVH::pack_leaf(const BVHStackEntry& e, const LeafNode *leaf)
data[6].x = __int_as_float(leaf->m_lo);
data[6].y = __int_as_float(leaf->m_hi);
}
+ data[6].z = __uint_as_float(leaf->m_visibility);
+ if(leaf->num_triangles() != 0) {
+ data[6].w = __uint_as_float(pack.prim_type[leaf->m_lo]);
+ }
memcpy(&pack.nodes[e.idx * BVH_QNODE_SIZE], data, sizeof(float4)*BVH_QNODE_SIZE);
}
@@ -771,20 +736,22 @@ void QBVH::pack_inner(const BVHStackEntry& e, const BVHStackEntry *en, int num)
data[5][i] = bb_max.z;
data[6][i] = __int_as_float(en[i].encodeIdx());
- data[7][i] = 0.0f;
}
for(int i = num; i < 4; i++) {
- data[0][i] = 0.0f;
- data[1][i] = 0.0f;
- data[2][i] = 0.0f;
+ /* We store BB which would never be recorded as intersection
+ * so kernel might safely assume there are always 4 child nodes.
+ */
+ data[0][i] = FLT_MAX;
+ data[1][i] = -FLT_MAX;
- data[3][i] = 0.0f;
- data[4][i] = 0.0f;
- data[5][i] = 0.0f;
+ data[2][i] = FLT_MAX;
+ data[3][i] = -FLT_MAX;
+
+ data[4][i] = FLT_MAX;
+ data[5][i] = -FLT_MAX;
data[6][i] = __int_as_float(0);
- data[7][i] = 0.0f;
}
memcpy(&pack.nodes[e.idx * BVH_QNODE_SIZE], data, sizeof(float4)*BVH_QNODE_SIZE);
@@ -792,9 +759,9 @@ void QBVH::pack_inner(const BVHStackEntry& e, const BVHStackEntry *en, int num)
/* Quad SIMD Nodes */
-void QBVH::pack_nodes(const array<int>& prims, const BVHNode *root)
+void QBVH::pack_nodes(const BVHNode *root)
{
- size_t node_size = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
+ size_t node_size = root->getSubtreeSize(BVH_STAT_QNODE_COUNT);
/* resize arrays */
pack.nodes.clear();
@@ -865,8 +832,138 @@ void QBVH::pack_nodes(const array<int>& prims, const BVHNode *root)
void QBVH::refit_nodes()
{
- assert(0); /* todo */
+ assert(!params.top_level);
+
+ BoundBox bbox = BoundBox::empty;
+ uint visibility = 0;
+ refit_node(0, (pack.is_leaf[0])? true: false, bbox, visibility);
}
-CCL_NAMESPACE_END
+void QBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
+{
+ int4 *data = &pack.nodes[idx*BVH_QNODE_SIZE];
+ int4 c = data[6];
+ if(leaf) {
+ /* Refit leaf node. */
+ for(int prim = c.x; prim < c.y; prim++) {
+ int pidx = pack.prim_index[prim];
+ int tob = pack.prim_object[prim];
+ Object *ob = objects[tob];
+ if(pidx == -1) {
+ /* Object instance. */
+ bbox.grow(ob->bounds);
+ }
+ else {
+ /* Primitives. */
+ const Mesh *mesh = ob->mesh;
+
+ if(pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
+ /* Curves. */
+ int str_offset = (params.top_level)? mesh->curve_offset: 0;
+ const Mesh::Curve& curve = mesh->curves[pidx - str_offset];
+ int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
+
+ curve.bounds_grow(k, &mesh->curve_keys[0], bbox);
+
+ visibility |= PATH_RAY_CURVE;
+
+ /* Motion curves. */
+ if(mesh->use_motion_blur) {
+ Attribute *attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if(attr) {
+ size_t mesh_size = mesh->curve_keys.size();
+ size_t steps = mesh->motion_steps - 1;
+ float4 *key_steps = attr->data_float4();
+
+ for (size_t i = 0; i < steps; i++)
+ curve.bounds_grow(k, key_steps + i*mesh_size, bbox);
+ }
+ }
+ }
+ else {
+ /* Triangles. */
+ int tri_offset = (params.top_level)? mesh->tri_offset: 0;
+ const Mesh::Triangle& triangle = mesh->triangles[pidx - tri_offset];
+ const float3 *vpos = &mesh->verts[0];
+
+ triangle.bounds_grow(vpos, bbox);
+
+ /* Motion triangles. */
+ if(mesh->use_motion_blur) {
+ Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+
+ if(attr) {
+ size_t mesh_size = mesh->verts.size();
+ size_t steps = mesh->motion_steps - 1;
+ float3 *vert_steps = attr->data_float3();
+
+ for (size_t i = 0; i < steps; i++)
+ triangle.bounds_grow(vert_steps + i*mesh_size, bbox);
+ }
+ }
+ }
+ }
+
+ visibility |= ob->visibility;
+ }
+
+ /* TODO(sergey): This is actually a copy of pack_leaf(),
+ * but this chunk of code only knows actual data and has
+ * no idea about BVHNode.
+ *
+ * Would be nice to de-duplicate code, but trying to make
+ * making code more general ends up in much nastier code
+ * in my opinion so far.
+ *
+ * Same applies to the inner nodes case below.
+ */
+ float4 leaf_data[BVH_QNODE_SIZE];
+ memset(leaf_data, 0, sizeof(leaf_data));
+ leaf_data[6].x = __int_as_float(c.x);
+ leaf_data[6].y = __int_as_float(c.y);
+ leaf_data[6].z = __uint_as_float(visibility);
+ leaf_data[6].w = __uint_as_float(c.w);
+ memcpy(&pack.nodes[idx * BVH_QNODE_SIZE],
+ leaf_data,
+ sizeof(float4)*BVH_QNODE_SIZE);
+ }
+ else {
+ /* Refit inner node, set bbox from children. */
+ BoundBox child_bbox[4] = {BoundBox::empty,
+ BoundBox::empty,
+ BoundBox::empty,
+ BoundBox::empty};
+ uint child_visibility[4] = {0};
+ int num_nodes = 0;
+
+ for(int i = 0; i < 4; ++i) {
+ if(c[i] != 0) {
+ refit_node((c[i] < 0)? -c[i]-1: c[i], (c[i] < 0),
+ child_bbox[i], child_visibility[i]);
+ ++num_nodes;
+ bbox.grow(child_bbox[i]);
+ visibility |= child_visibility[i];
+ }
+ }
+
+ float4 inner_data[BVH_QNODE_SIZE];
+ for(int i = 0; i < 4; ++i) {
+ float3 bb_min = child_bbox[i].min;
+ float3 bb_max = child_bbox[i].max;
+ inner_data[0][i] = bb_min.x;
+ inner_data[1][i] = bb_max.x;
+ inner_data[2][i] = bb_min.y;
+ inner_data[3][i] = bb_max.y;
+ inner_data[4][i] = bb_min.z;
+ inner_data[5][i] = bb_max.z;
+ inner_data[6][i] = __int_as_float(c[i]);
+ }
+ memcpy(&pack.nodes[idx * BVH_QNODE_SIZE],
+ inner_data,
+ sizeof(float4)*BVH_QNODE_SIZE);
+ }
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 5fcaaaa988c..40f039541eb 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -36,7 +36,7 @@ class Object;
class Progress;
#define BVH_NODE_SIZE 4
-#define BVH_QNODE_SIZE 8
+#define BVH_QNODE_SIZE 7
#define BVH_ALIGN 4096
#define TRI_NODE_SIZE 3
@@ -63,7 +63,7 @@ struct PackedBVH {
array<int> prim_object;
/* quick array to lookup if a node is a leaf, not used for traversal, only
* for instance BVH merging */
- array<int> is_leaf;
+ array<bool> is_leaf;
/* index of the root node. */
int root_index;
@@ -106,13 +106,12 @@ protected:
/* triangles and strands*/
void pack_primitives();
void pack_triangle(int idx, float4 woop[3]);
- void pack_curve_segment(int idx, float4 woop[3]);
/* merge instance BVH's */
void pack_instances(size_t nodes_size);
/* for subclasses to implement */
- virtual void pack_nodes(const array<int>& prims, const BVHNode *root) = 0;
+ virtual void pack_nodes(const BVHNode *root) = 0;
virtual void refit_nodes() = 0;
};
@@ -127,7 +126,7 @@ protected:
RegularBVH(const BVHParams& params, const vector<Object*>& objects);
/* pack */
- void pack_nodes(const array<int>& prims, const BVHNode *root);
+ void pack_nodes(const BVHNode *root);
void pack_leaf(const BVHStackEntry& e, const LeafNode *leaf);
void pack_inner(const BVHStackEntry& e, const BVHStackEntry& e0, const BVHStackEntry& e1);
void pack_node(int idx, const BoundBox& b0, const BoundBox& b1, int c0, int c1, uint visibility0, uint visibility1);
@@ -148,12 +147,13 @@ protected:
QBVH(const BVHParams& params, const vector<Object*>& objects);
/* pack */
- void pack_nodes(const array<int>& prims, const BVHNode *root);
+ void pack_nodes(const BVHNode *root);
void pack_leaf(const BVHStackEntry& e, const LeafNode *leaf);
void pack_inner(const BVHStackEntry& e, const BVHStackEntry *en, int num);
/* refit */
void refit_nodes();
+ void refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index eb4cca92b6b..4ce8f787169 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -28,11 +28,27 @@
#include "util_debug.h"
#include "util_foreach.h"
+#include "util_logging.h"
#include "util_progress.h"
#include "util_time.h"
CCL_NAMESPACE_BEGIN
+#if !defined(__KERNEL_SSE2__)
+/* TODO(sergey): Move to some generic header so all code
+ * can use bitscan on non-SSE processors.
+ */
+ccl_device_inline int bitscan(int value)
+{
+ assert(value != 0);
+ int bit = 0;
+ while (value >>= 1) {
+ ++bit;
+ }
+ return bit;
+}
+#endif
+
/* BVH Build Task */
class BVHBuildTask : public Task {
@@ -223,7 +239,8 @@ BVHNode* BVHBuild::run()
spatial_right_bounds.resize(max(root.size(), (int)BVHParams::NUM_SPATIAL_BINS) - 1);
/* init progress updates */
- progress_start_time = time_dt();
+ double build_start_time;
+ build_start_time = progress_start_time = time_dt();
progress_count = 0;
progress_total = references.size();
progress_original_total = progress_total;
@@ -251,13 +268,23 @@ BVHNode* BVHBuild::run()
if(progress.get_cancel()) {
rootnode->deleteSubtree();
rootnode = NULL;
+ VLOG(1) << "BVH build cancelled.";
}
else if(!params.use_spatial_split) {
/*rotate(rootnode, 4, 5);*/
rootnode->update_visibility();
+ VLOG(1) << "BVH build statistics:\n"
+ << " Build time: " << time_dt() - build_start_time << "\n"
+ << " Total number of nodes: "
+ << rootnode->getSubtreeSize(BVH_STAT_NODE_COUNT) << "\n"
+ << " Number of inner nodes: "
+ << rootnode->getSubtreeSize(BVH_STAT_INNER_COUNT) << "\n"
+ << " Number of leaf nodes: "
+ << rootnode->getSubtreeSize(BVH_STAT_LEAF_COUNT) << "\n";
}
}
+
return rootnode;
}
@@ -308,17 +335,22 @@ bool BVHBuild::range_within_max_leaf_size(const BVHRange& range)
size_t num_triangles = 0;
size_t num_curves = 0;
+ size_t num_motion_curves = 0;
for(int i = 0; i < size; i++) {
BVHReference& ref = references[range.start() + i];
- if(ref.prim_type() & PRIMITIVE_ALL_CURVE)
+ if(ref.prim_type() & PRIMITIVE_CURVE)
num_curves++;
+ if(ref.prim_type() & PRIMITIVE_MOTION_CURVE)
+ num_motion_curves++;
else if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE)
num_triangles++;
}
- return (num_triangles < params.max_triangle_leaf_size) && (num_curves < params.max_curve_leaf_size);
+ return (num_triangles < params.max_triangle_leaf_size) &&
+ (num_curves < params.max_curve_leaf_size) &&
+ (num_motion_curves < params.max_curve_leaf_size);
}
/* multithreaded binning builder */
@@ -394,7 +426,7 @@ BVHNode* BVHBuild::build_node(const BVHRange& range, int level)
progress_total += left.size() + right.size() - range.size();
size_t total = progress_total;
- /* leaft node */
+ /* left node */
BVHNode *leftnode = build_node(left, level + 1);
/* right node (modify start for splits) */
@@ -443,61 +475,120 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
}
}
-BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
+BVHNode *BVHBuild::create_primitive_leaf_node(const int *p_type,
+ const int *p_index,
+ const int *p_object,
+ const BoundBox& bounds,
+ uint visibility,
+ int start,
+ int num)
{
- vector<int>& p_type = prim_type;
- vector<int>& p_index = prim_index;
- vector<int>& p_object = prim_object;
- BoundBox bounds = BoundBox::empty;
- int num = 0, ob_num = 0;
- uint visibility = 0;
+ for(int i = 0; i < num; ++i) {
+ if(start + i == prim_index.size()) {
+ assert(params.use_spatial_split);
+ prim_type.push_back(p_type[i]);
+ prim_index.push_back(p_index[i]);
+ prim_object.push_back(p_object[i]);
+ }
+ else {
+ prim_type[start + i] = p_type[i];
+ prim_index[start + i] = p_index[i];
+ prim_object[start + i] = p_object[i];
+ }
+ }
+ return new LeafNode(bounds, visibility, start, start + num);
+}
+BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
+{
+ /* TODO(sergey): Consider writing own allocator which would
+ * not do heap allocation if number of elements is relatively small.
+ */
+ vector<int> p_type[PRIMITIVE_NUM_TOTAL];
+ vector<int> p_index[PRIMITIVE_NUM_TOTAL];
+ vector<int> p_object[PRIMITIVE_NUM_TOTAL];
+ uint visibility[PRIMITIVE_NUM_TOTAL] = {0};
+ /* NOTE: Keep initializtion in sync with actual number of primitives. */
+ BoundBox bounds[PRIMITIVE_NUM_TOTAL] = {BoundBox::empty,
+ BoundBox::empty,
+ BoundBox::empty,
+ BoundBox::empty};
+ int ob_num = 0;
+
+ /* Fill in per-type type/index array. */
for(int i = 0; i < range.size(); i++) {
BVHReference& ref = references[range.start() + i];
-
if(ref.prim_index() != -1) {
- if(range.start() + num == prim_index.size()) {
- assert(params.use_spatial_split);
+ int type_index = bitscan(ref.prim_type() & PRIMITIVE_ALL);
+ p_type[type_index].push_back(ref.prim_type());
+ p_index[type_index].push_back(ref.prim_index());
+ p_object[type_index].push_back(ref.prim_object());
- p_type.push_back(ref.prim_type());
- p_index.push_back(ref.prim_index());
- p_object.push_back(ref.prim_object());
- }
- else {
- p_type[range.start() + num] = ref.prim_type();
- p_index[range.start() + num] = ref.prim_index();
- p_object[range.start() + num] = ref.prim_object();
- }
-
- bounds.grow(ref.bounds());
- visibility |= objects[ref.prim_object()]->visibility;
- num++;
+ bounds[type_index].grow(ref.bounds());
+ visibility[type_index] |= objects[ref.prim_object()]->visibility;
}
else {
- if(ob_num < i)
+ if(ob_num < i) {
references[range.start() + ob_num] = ref;
+ }
ob_num++;
}
}
- BVHNode *leaf = NULL;
-
- if(num > 0) {
- leaf = new LeafNode(bounds, visibility, range.start(), range.start() + num);
+ /* Create leaf nodes for every existing primitive. */
+ BVHNode *leaves[PRIMITIVE_NUM_TOTAL + 1] = {NULL};
+ int num_leaves = 0;
+ int start = range.start();
+ for(int i = 0; i < PRIMITIVE_NUM_TOTAL; ++i) {
+ int num = (int)p_type[i].size();
+ if(num != 0) {
+ assert(p_type[i].size() == p_index[i].size());
+ assert(p_type[i].size() == p_object[i].size());
+ leaves[num_leaves] = create_primitive_leaf_node(&p_type[i][0],
+ &p_index[i][0],
+ &p_object[i][0],
+ bounds[i],
+ visibility[i],
+ start,
+ num);
+ ++num_leaves;
+ start += num;
+ }
+ }
- if(num == range.size())
- return leaf;
+ /* Create leaf node for object. */
+ if(num_leaves == 0 || ob_num) {
+ /* Only create object leaf nodes if there are objects or no other
+ * nodes created.
+ */
+ const BVHReference *ref = (ob_num)? &references[range.start()]: NULL;
+ leaves[num_leaves] = create_object_leaf_nodes(ref, start, ob_num);
+ ++num_leaves;
}
- /* while there may be multiple triangles in a leaf, for object primitives
- * we want there to be the only one, so we keep splitting */
- const BVHReference *ref = (ob_num)? &references[range.start()]: NULL;
- BVHNode *oleaf = create_object_leaf_nodes(ref, range.start() + num, ob_num);
-
- if(leaf)
- return new InnerNode(range.bounds(), leaf, oleaf);
- else
- return oleaf;
+ if(num_leaves == 1) {
+ /* Simplest case: single leaf, just return it.
+ * In all the rest cases we'll be creating intermediate inner node with
+ * an appropriate bounding box.
+ */
+ return leaves[0];
+ }
+ else if(num_leaves == 2) {
+ return new InnerNode(range.bounds(), leaves[0], leaves[1]);
+ }
+ else if(num_leaves == 3) {
+ BoundBox inner_bounds = merge(bounds[1], bounds[2]);
+ BVHNode *inner = new InnerNode(inner_bounds, leaves[1], leaves[2]);
+ return new InnerNode(range.bounds(), leaves[0], inner);
+ } else /*if(num_leaves == 4)*/ {
+ /* Shpuld be doing more branches if more primitive types added. */
+ assert(num_leaves == 4);
+ BoundBox inner_bounds_a = merge(bounds[0], bounds[1]);
+ BoundBox inner_bounds_b = merge(bounds[2], bounds[3]);
+ BVHNode *inner_a = new InnerNode(inner_bounds_a, leaves[0], leaves[1]);
+ BVHNode *inner_b = new InnerNode(inner_bounds_b, leaves[2], leaves[3]);
+ return new InnerNode(range.bounds(), inner_a, inner_b);
+ }
}
/* Tree Rotations */
@@ -582,4 +673,3 @@ void BVHBuild::rotate(BVHNode *node, int max_depth)
}
CCL_NAMESPACE_END
-
diff --git a/intern/cycles/bvh/bvh_build.h b/intern/cycles/bvh/bvh_build.h
index a6b9916de9b..294c5a1758d 100644
--- a/intern/cycles/bvh/bvh_build.h
+++ b/intern/cycles/bvh/bvh_build.h
@@ -70,6 +70,15 @@ protected:
BVHNode *create_leaf_node(const BVHRange& range);
BVHNode *create_object_leaf_nodes(const BVHReference *ref, int start, int num);
+ /* Leaf node type splitting. */
+ BVHNode *create_primitive_leaf_node(const int *p_type,
+ const int *p_index,
+ const int *p_object,
+ const BoundBox& bounds,
+ uint visibility,
+ int start,
+ int nun);
+
bool range_within_max_leaf_size(const BVHRange& range);
/* threads */
@@ -116,4 +125,3 @@ protected:
CCL_NAMESPACE_END
#endif /* __BVH_BUILD_H__ */
-
diff --git a/intern/cycles/bvh/bvh_node.cpp b/intern/cycles/bvh/bvh_node.cpp
index 7cc9bd333b0..8294690da7d 100644
--- a/intern/cycles/bvh/bvh_node.cpp
+++ b/intern/cycles/bvh/bvh_node.cpp
@@ -47,6 +47,20 @@ int BVHNode::getSubtreeSize(BVH_STAT stat) const
case BVH_STAT_CHILDNODE_COUNT:
cnt = num_children();
break;
+ case BVH_STAT_QNODE_COUNT:
+ cnt = 1;
+ for(int i = 0; i < num_children(); i++) {
+ BVHNode *node = get_child(i);
+ if(node->is_leaf()) {
+ cnt += 1;
+ }
+ else {
+ for(int j = 0; j < node->num_children(); j++) {
+ cnt += node->get_child(j)->getSubtreeSize(stat);
+ }
+ }
+ }
+ return cnt;
default:
assert(0); /* unknown mode */
}
diff --git a/intern/cycles/bvh/bvh_node.h b/intern/cycles/bvh/bvh_node.h
index a0d10a46bfc..1656bb367a4 100644
--- a/intern/cycles/bvh/bvh_node.h
+++ b/intern/cycles/bvh/bvh_node.h
@@ -30,7 +30,8 @@ enum BVH_STAT
BVH_STAT_INNER_COUNT,
BVH_STAT_LEAF_COUNT,
BVH_STAT_TRIANGLE_COUNT,
- BVH_STAT_CHILDNODE_COUNT
+ BVH_STAT_CHILDNODE_COUNT,
+ BVH_STAT_QNODE_COUNT,
};
class BVHParams;
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index e073b69472e..99bfd9449da 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -28,7 +28,7 @@ class BVHParams
{
public:
/* spatial split area threshold */
- int use_spatial_split;
+ bool use_spatial_split;
float spatial_split_alpha;
/* SAH costs */
@@ -41,15 +41,13 @@ public:
int max_curve_leaf_size;
/* object or mesh level bvh */
- int top_level;
+ bool top_level;
/* disk cache */
- int use_cache;
+ bool use_cache;
/* QBVH */
- int use_qbvh;
-
- int pad;
+ bool use_qbvh;
/* fixed parameters */
enum {
@@ -75,7 +73,6 @@ public:
top_level = false;
use_cache = false;
use_qbvh = false;
- pad = false;
}
/* SAH costs */
@@ -115,6 +112,11 @@ public:
__forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
__forceinline int prim_type() const { return type; }
+ BVHReference& operator=(const BVHReference &arg) {
+ memcpy(this, &arg, sizeof(BVHReference));
+ return *this;
+ }
+
protected:
BoundBox rbounds;
uint type;
diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake
index 4f02b93f04a..d7c59f42a5e 100644
--- a/intern/cycles/cmake/external_libs.cmake
+++ b/intern/cycles/cmake/external_libs.cmake
@@ -1,4 +1,13 @@
###########################################################################
+# Precompiled libraries tips and hints, for find_package().
+
+if(CYCLES_STANDALONE_REPOSITORY)
+ if(APPLE OR WIN32)
+ include(precompiled_libs)
+ endif()
+endif()
+
+###########################################################################
# GLUT
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
@@ -16,6 +25,11 @@ endif()
###########################################################################
# GLEW
+# Workaround for unconventional variable name use in Blender.
+if(NOT CYCLES_STANDALONE_REPOSITORY)
+ set(GLEW_INCLUDE_DIR "${GLEW_INCLUDE_PATH}")
+endif()
+
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
set(CYCLES_APP_GLEW_LIBRARY ${BLENDER_GLEW_LIBRARIES})
endif()
@@ -32,3 +46,96 @@ if(WITH_CYCLES_CUDA_BINARIES)
set(WITH_CYCLES_CUDA_BINARIES OFF)
endif()
endif()
+
+# Packages which are being found by Blender when building from inside Blender
+# source code. but which we need to take care of when building Cycles from a
+# standalone repository
+if(CYCLES_STANDALONE_REPOSITORY)
+ # PThreads
+ # TODO(sergey): Bloody exception, handled in precompiled_libs.cmake.
+ if(NOT WIN32)
+ set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+ find_package(Threads REQUIRED)
+ set(PTHREADS_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
+ endif()
+
+ ####
+ # OpenGL
+
+ # TODO(sergey): We currently re-use the same variable name as we use
+ # in Blender. Ideally we need to make it CYCLES_GL_LIBRARIES.
+ find_package(OpenGL REQUIRED)
+ find_package(GLEW REQUIRED)
+ list(APPEND BLENDER_GL_LIBRARIES
+ "${OPENGL_gl_LIBRARY}"
+ "${OPENGL_glu_LIBRARY}"
+ "${GLEW_LIBRARY}"
+ )
+
+ ####
+ # OpenImageIO
+ find_package(OpenImageIO REQUIRED)
+ if(OPENIMAGEIO_PUGIXML_FOUND)
+ set(PUGIXML_INCLUDE_DIR "${OPENIMAGEIO_INCLUDE_DIR/OpenImageIO}")
+ set(PUGIXML_LIBRARIES "")
+ else()
+ find_package(PugiXML REQUIRED)
+ endif()
+
+ # OIIO usually depends on OpenEXR, so find this library
+ # but don't make it required.
+ find_package(OpenEXR)
+
+ ####
+ # Boost
+ set(__boost_packages filesystem regex system thread date_time)
+ if(WITH_CYCLES_NETWORK)
+ list(APPEND __boost_packages serialization)
+ endif()
+ if(WITH_CYCLES_OSL)
+ # TODO(sergey): This is because of the way how our precompiled
+ # libraries works, could be different for someone's else libs..
+ if(APPLE OR MSVC)
+ list(APPEND __boost_packages wave)
+ endif()
+ endif()
+ find_package(Boost 1.48 COMPONENTS ${__boost_packages} REQUIRED)
+ if(NOT Boost_FOUND)
+ # Try to find non-multithreaded if -mt not found, this flag
+ # doesn't matter for us, it has nothing to do with thread
+ # safety, but keep it to not disturb build setups.
+ set(Boost_USE_MULTITHREADED OFF)
+ find_package(Boost 1.48 COMPONENTS ${__boost_packages})
+ endif()
+ unset(__boost_packages)
+ set(BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIRS})
+ set(BOOST_LIBRARIES ${Boost_LIBRARIES})
+ set(BOOST_LIBPATH ${Boost_LIBRARY_DIRS})
+ set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
+
+ ####
+ # OpenShadingLanguage
+ if(WITH_CYCLES_OSL)
+ find_package(OpenShadingLanguage REQUIRED)
+ find_package(LLVM REQUIRED)
+ endif()
+
+ ####
+ # Logging
+ if(WITH_CYCLES_LOGGING)
+ find_package(Glog REQUIRED)
+ find_package(Gflags REQUIRED)
+ endif()
+
+ unset(_lib_DIR)
+else()
+ if(WIN32)
+ set(GLOG_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extern/libmv/third_party/glog/src/windows)
+ set(GFLAGS_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extern/libmv/third_party/gflags)
+ else()
+ set(GLOG_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extern/libmv/third_party/glog/src)
+ set(GFLAGS_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extern/libmv/third_party/gflags)
+ endif()
+ set(GFLAGS_NAMESPACE "gflags")
+ set(LLVM_LIBRARIES ${LLVM_LIBRARY})
+endif()
diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt
index 998b35351e3..b0fa283c1d8 100644
--- a/intern/cycles/device/CMakeLists.txt
+++ b/intern/cycles/device/CMakeLists.txt
@@ -10,7 +10,7 @@ set(INC
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_DIR}
../../../extern/cuew/include
../../../extern/clew/include
)
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index efdfa98cfb5..3a33b8fb68b 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdlib.h>
@@ -20,9 +20,6 @@
#include "device.h"
#include "device_intern.h"
-#include "cuew.h"
-#include "clew.h"
-
#include "util_debug.h"
#include "util_foreach.h"
#include "util_half.h"
@@ -268,5 +265,28 @@ vector<DeviceInfo>& Device::available_devices()
return devices;
}
-CCL_NAMESPACE_END
+string Device::device_capabilities()
+{
+ string capabilities = "CPU device capabilities: ";
+ capabilities += device_cpu_capabilities() + "\n";
+#ifdef WITH_CUDA
+ if(device_cuda_init()) {
+ capabilities += "\nCUDA device capabilities:\n";
+ capabilities += device_cuda_capabilities();
+ }
+#endif
+#ifdef WITH_OPENCL
+ /* TODO(sergey): Needs proper usable implementation. */
+ /*
+ if(device_opencl_init()) {
+ capabilities += "\nOpenCL device capabilities:\n";
+ capabilities += device_opencl_capabilities();
+ }
+ */
+#endif
+
+ return capabilities;
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 20ebfd391d6..7c17f7f4112 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __DEVICE_H__
@@ -148,6 +148,7 @@ public:
static string string_from_type(DeviceType type);
static vector<DeviceType>& available_types();
static vector<DeviceInfo>& available_devices();
+ static string device_capabilities();
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index c9b8a5b726b..9abcf9167d5 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdlib.h>
@@ -170,141 +170,58 @@ public:
#endif
RenderTile tile;
-
- while(task.acquire_tile(this, tile)) {
- float *render_buffer = (float*)tile.buffer;
- uint *rng_state = (uint*)tile.rng_state;
- int start_sample = tile.start_sample;
- int end_sample = tile.start_sample + tile.num_samples;
-
-#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
- if(system_cpu_support_avx2()) {
- for(int sample = start_sample; sample < end_sample; sample++) {
- if (task.get_cancel() || task_pool.canceled()) {
- if(task.need_finish_queue == false)
- break;
- }
-
- for(int y = tile.y; y < tile.y + tile.h; y++) {
- for(int x = tile.x; x < tile.x + tile.w; x++) {
- kernel_cpu_avx2_path_trace(&kg, render_buffer, rng_state,
- sample, x, y, tile.offset, tile.stride);
- }
- }
- tile.sample = sample + 1;
+ void(*path_trace_kernel)(KernelGlobals*, float*, unsigned int*, int, int, int, int, int);
- task.update_progress(&tile);
- }
- }
- else
+#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
+ if(system_cpu_support_avx2())
+ path_trace_kernel = kernel_cpu_avx2_path_trace;
+ else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX
- if(system_cpu_support_avx()) {
- for(int sample = start_sample; sample < end_sample; sample++) {
- if (task.get_cancel() || task_pool.canceled()) {
- if(task.need_finish_queue == false)
- break;
- }
-
- for(int y = tile.y; y < tile.y + tile.h; y++) {
- for(int x = tile.x; x < tile.x + tile.w; x++) {
- kernel_cpu_avx_path_trace(&kg, render_buffer, rng_state,
- sample, x, y, tile.offset, tile.stride);
- }
- }
-
- tile.sample = sample + 1;
-
- task.update_progress(&tile);
- }
- }
- else
+ if(system_cpu_support_avx())
+ path_trace_kernel = kernel_cpu_avx_path_trace;
+ else
#endif
-#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
- if(system_cpu_support_sse41()) {
- for(int sample = start_sample; sample < end_sample; sample++) {
- if (task.get_cancel() || task_pool.canceled()) {
- if(task.need_finish_queue == false)
- break;
- }
-
- for(int y = tile.y; y < tile.y + tile.h; y++) {
- for(int x = tile.x; x < tile.x + tile.w; x++) {
- kernel_cpu_sse41_path_trace(&kg, render_buffer, rng_state,
- sample, x, y, tile.offset, tile.stride);
- }
- }
-
- tile.sample = sample + 1;
-
- task.update_progress(&tile);
- }
- }
- else
+#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
+ if(system_cpu_support_sse41())
+ path_trace_kernel = kernel_cpu_sse41_path_trace;
+ else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
- if(system_cpu_support_sse3()) {
- for(int sample = start_sample; sample < end_sample; sample++) {
- if (task.get_cancel() || task_pool.canceled()) {
- if(task.need_finish_queue == false)
- break;
- }
-
- for(int y = tile.y; y < tile.y + tile.h; y++) {
- for(int x = tile.x; x < tile.x + tile.w; x++) {
- kernel_cpu_sse3_path_trace(&kg, render_buffer, rng_state,
- sample, x, y, tile.offset, tile.stride);
- }
- }
-
- tile.sample = sample + 1;
-
- task.update_progress(&tile);
- }
- }
- else
+ if(system_cpu_support_sse3())
+ path_trace_kernel = kernel_cpu_sse3_path_trace;
+ else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
- if(system_cpu_support_sse2()) {
- for(int sample = start_sample; sample < end_sample; sample++) {
- if (task.get_cancel() || task_pool.canceled()) {
- if(task.need_finish_queue == false)
- break;
- }
-
- for(int y = tile.y; y < tile.y + tile.h; y++) {
- for(int x = tile.x; x < tile.x + tile.w; x++) {
- kernel_cpu_sse2_path_trace(&kg, render_buffer, rng_state,
- sample, x, y, tile.offset, tile.stride);
- }
- }
-
- tile.sample = sample + 1;
+ if(system_cpu_support_sse2())
+ path_trace_kernel = kernel_cpu_sse2_path_trace;
+ else
+#endif
+ path_trace_kernel = kernel_cpu_path_trace;
+
+ while(task.acquire_tile(this, tile)) {
+ float *render_buffer = (float*)tile.buffer;
+ uint *rng_state = (uint*)tile.rng_state;
+ int start_sample = tile.start_sample;
+ int end_sample = tile.start_sample + tile.num_samples;
- task.update_progress(&tile);
+ for(int sample = start_sample; sample < end_sample; sample++) {
+ if (task.get_cancel() || task_pool.canceled()) {
+ if(task.need_finish_queue == false)
+ break;
}
- }
- else
-#endif
- {
- for(int sample = start_sample; sample < end_sample; sample++) {
- if (task.get_cancel() || task_pool.canceled()) {
- if(task.need_finish_queue == false)
- break;
- }
- for(int y = tile.y; y < tile.y + tile.h; y++) {
- for(int x = tile.x; x < tile.x + tile.w; x++) {
- kernel_cpu_path_trace(&kg, render_buffer, rng_state,
- sample, x, y, tile.offset, tile.stride);
- }
+ for(int y = tile.y; y < tile.y + tile.h; y++) {
+ for(int x = tile.x; x < tile.x + tile.w; x++) {
+ path_trace_kernel(&kg, render_buffer, rng_state,
+ sample, x, y, tile.offset, tile.stride);
}
+ }
- tile.sample = sample + 1;
+ tile.sample = sample + 1;
- task.update_progress(&tile);
- }
+ task.update_progress(&tile);
}
task.release_tile(tile);
@@ -325,110 +242,74 @@ public:
float sample_scale = 1.0f/(task.sample + 1);
if(task.rgba_half) {
+ void(*convert_to_half_float_kernel)(KernelGlobals *, uchar4 *, float *, float, int, int, int, int);
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
- if(system_cpu_support_avx2()) {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_avx2_convert_to_half_float(&kernel_globals, (uchar4*)task.rgba_half, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ if(system_cpu_support_avx2())
+ convert_to_half_float_kernel = kernel_cpu_avx2_convert_to_half_float;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX
- if(system_cpu_support_avx()) {
+ if(system_cpu_support_avx())
for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_avx_convert_to_half_float(&kernel_globals, (uchar4*)task.rgba_half, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ convert_to_half_float_kernel = kernel_cpu_avx_convert_to_half_float;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
- if(system_cpu_support_sse41()) {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_sse41_convert_to_half_float(&kernel_globals, (uchar4*)task.rgba_half, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ if(system_cpu_support_sse41())
+ convert_to_half_float_kernel = kernel_cpu_sse41_convert_to_half_float;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
- if(system_cpu_support_sse3()) {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_sse3_convert_to_half_float(&kernel_globals, (uchar4*)task.rgba_half, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ if(system_cpu_support_sse3())
+ convert_to_half_float_kernel = kernel_cpu_sse3_convert_to_half_float;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
- if(system_cpu_support_sse2()) {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_sse2_convert_to_half_float(&kernel_globals, (uchar4*)task.rgba_half, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ if(system_cpu_support_sse2())
+ convert_to_half_float_kernel = kernel_cpu_sse2_convert_to_half_float;
else
#endif
- {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_convert_to_half_float(&kernel_globals, (uchar4*)task.rgba_half, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ convert_to_half_float_kernel = kernel_cpu_convert_to_half_float;
+
+ for(int y = task.y; y < task.y + task.h; y++)
+ for(int x = task.x; x < task.x + task.w; x++)
+ convert_to_half_float_kernel(&kernel_globals, (uchar4*)task.rgba_half, (float*)task.buffer,
+ sample_scale, x, y, task.offset, task.stride);
}
else {
+ void(*convert_to_byte_kernel)(KernelGlobals *, uchar4 *, float *, float, int, int, int, int);
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
- if(system_cpu_support_avx2()) {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_avx2_convert_to_byte(&kernel_globals, (uchar4*)task.rgba_byte, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ if(system_cpu_support_avx2())
+ convert_to_byte_kernel = kernel_cpu_avx2_convert_to_byte;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX
- if(system_cpu_support_avx()) {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_avx_convert_to_byte(&kernel_globals, (uchar4*)task.rgba_byte, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ if(system_cpu_support_avx())
+ convert_to_byte_kernel = kernel_cpu_avx_convert_to_byte;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
- if(system_cpu_support_sse41()) {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_sse41_convert_to_byte(&kernel_globals, (uchar4*)task.rgba_byte, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ if(system_cpu_support_sse41())
+ convert_to_byte_kernel = kernel_cpu_sse41_convert_to_byte;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
- if(system_cpu_support_sse3()) {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_sse3_convert_to_byte(&kernel_globals, (uchar4*)task.rgba_byte, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ if(system_cpu_support_sse3())
+ convert_to_byte_kernel = kernel_cpu_sse3_convert_to_byte;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
- if(system_cpu_support_sse2()) {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_sse2_convert_to_byte(&kernel_globals, (uchar4*)task.rgba_byte, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ if(system_cpu_support_sse2())
+ convert_to_byte_kernel = kernel_cpu_sse2_convert_to_byte;
else
#endif
- {
- for(int y = task.y; y < task.y + task.h; y++)
- for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_convert_to_byte(&kernel_globals, (uchar4*)task.rgba_byte, (float*)task.buffer,
- sample_scale, x, y, task.offset, task.stride);
- }
+ convert_to_byte_kernel = kernel_cpu_convert_to_byte;
+
+ for(int y = task.y; y < task.y + task.h; y++)
+ for(int x = task.x; x < task.x + task.w; x++)
+ convert_to_byte_kernel(&kernel_globals, (uchar4*)task.rgba_byte, (float*)task.buffer,
+ sample_scale, x, y, task.offset, task.stride);
+
}
}
@@ -439,93 +320,45 @@ public:
#ifdef WITH_OSL
OSLShader::thread_init(&kg, &kernel_globals, &osl_globals);
#endif
+ void(*shader_kernel)(KernelGlobals*, uint4*, float4*, int, int, int, int);
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
- if(system_cpu_support_avx2()) {
- for(int sample = 0; sample < task.num_samples; sample++) {
- for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
- kernel_cpu_avx2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output,
- task.shader_eval_type, x, task.offset, sample);
-
- if(task.get_cancel() || task_pool.canceled())
- break;
-
- task.update_progress(NULL);
- }
- }
+ if(system_cpu_support_avx2())
+ shader_kernel = kernel_cpu_avx2_shader;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX
- if(system_cpu_support_avx()) {
- for(int sample = 0; sample < task.num_samples; sample++) {
- for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
- kernel_cpu_avx_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output,
- task.shader_eval_type, x, task.offset, sample);
-
- if(task.get_cancel() || task_pool.canceled())
- break;
-
- task.update_progress(NULL);
- }
- }
+ if(system_cpu_support_avx())
+ shader_kernel = kernel_cpu_avx_shader;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
- if(system_cpu_support_sse41()) {
- for(int sample = 0; sample < task.num_samples; sample++) {
- for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
- kernel_cpu_sse41_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output,
- task.shader_eval_type, x, task.offset, sample);
-
- if(task.get_cancel() || task_pool.canceled())
- break;
-
- task.update_progress(NULL);
- }
- }
+ if(system_cpu_support_sse41())
+ shader_kernel = kernel_cpu_sse41_shader;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
- if(system_cpu_support_sse3()) {
- for(int sample = 0; sample < task.num_samples; sample++) {
- for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
- kernel_cpu_sse3_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output,
- task.shader_eval_type, x, task.offset, sample);
-
- if(task.get_cancel() || task_pool.canceled())
- break;
-
- task.update_progress(NULL);
- }
- }
+ if(system_cpu_support_sse3())
+ shader_kernel = kernel_cpu_sse3_shader;
else
#endif
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
- if(system_cpu_support_sse2()) {
- for(int sample = 0; sample < task.num_samples; sample++) {
- for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
- kernel_cpu_sse2_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output,
- task.shader_eval_type, x, task.offset, sample);
-
- if(task.get_cancel() || task_pool.canceled())
- break;
-
- task.update_progress(NULL);
- }
- }
+ if(system_cpu_support_sse2())
+ shader_kernel = kernel_cpu_sse2_shader;
else
#endif
- {
- for(int sample = 0; sample < task.num_samples; sample++) {
- for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
- kernel_cpu_shader(&kg, (uint4*)task.shader_input, (float4*)task.shader_output,
- task.shader_eval_type, x, task.offset, sample);
+ shader_kernel = kernel_cpu_shader;
- if(task.get_cancel() || task_pool.canceled())
- break;
+ for(int sample = 0; sample < task.num_samples; sample++) {
+ for(int x = task.shader_x; x < task.shader_x + task.shader_w; x++)
+ shader_kernel(&kg, (uint4*)task.shader_input, (float4*)task.shader_output,
+ task.shader_eval_type, x, task.offset, sample);
+
+ if(task.get_cancel() || task_pool.canceled())
+ break;
+
+ task.update_progress(NULL);
- task.update_progress(NULL);
- }
}
#ifdef WITH_OSL
@@ -585,5 +418,17 @@ void device_cpu_info(vector<DeviceInfo>& devices)
devices.insert(devices.begin(), info);
}
-CCL_NAMESPACE_END
+string device_cpu_capabilities(void)
+{
+ string capabilities = "";
+ capabilities += system_cpu_support_sse2() ? "SSE2 " : "";
+ capabilities += system_cpu_support_sse3() ? "SSE3 " : "";
+ capabilities += system_cpu_support_sse41() ? "SSE41 " : "";
+ capabilities += system_cpu_support_avx() ? "AVX " : "";
+ capabilities += system_cpu_support_avx2() ? "AVX2" : "";
+ if(capabilities[capabilities.size() - 1] == ' ')
+ capabilities.resize(capabilities.size() - 1);
+ return capabilities;
+}
+CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 844fb3b8d50..79a1a2b7fe1 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdio.h>
@@ -25,9 +25,11 @@
#include "cuew.h"
#include "util_debug.h"
+#include "util_logging.h"
#include "util_map.h"
#include "util_opengl.h"
#include "util_path.h"
+#include "util_string.h"
#include "util_system.h"
#include "util_types.h"
#include "util_time.h"
@@ -76,7 +78,7 @@ public:
{
if(first_error) {
fprintf(stderr, "\nRefer to the Cycles GPU rendering documentation for possible solutions:\n");
- fprintf(stderr, "http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/GPU_Rendering\n\n");
+ fprintf(stderr, "http://www.blender.org/manual/render/cycles/gpu_rendering.html\n\n");
first_error = false;
}
}
@@ -202,19 +204,18 @@ public:
/* compute cubin name */
int major, minor;
cuDeviceComputeCapability(&major, &minor, cuDevId);
-
- /* workaround to make sm_52 cards work, until we bundle kernel */
- if(major == 5 && minor == 2)
- minor = 0;
+ string cubin;
/* attempt to use kernel provided with blender */
- string cubin;
if(experimental)
cubin = path_get(string_printf("lib/kernel_experimental_sm_%d%d.cubin", major, minor));
else
cubin = path_get(string_printf("lib/kernel_sm_%d%d.cubin", major, minor));
- if(path_exists(cubin))
+ VLOG(1) << "Testing for pre-compiled kernel " << cubin;
+ if(path_exists(cubin)) {
+ VLOG(1) << "Using precompiled kernel";
return cubin;
+ }
/* not found, try to use locally compiled kernel */
string kernel_path = path_get("kernel");
@@ -225,10 +226,12 @@ public:
else
cubin = string_printf("cycles_kernel_sm%d%d_%s.cubin", major, minor, md5.c_str());
cubin = path_user_get(path_join("cache", cubin));
-
+ VLOG(1) << "Testing for locally compiled kernel " << cubin;
/* if exists already, use it */
- if(path_exists(cubin))
+ if(path_exists(cubin)) {
+ VLOG(1) << "Using locally compiled kernel";
return cubin;
+ }
#ifdef _WIN32
if(have_precompiled_kernels()) {
@@ -249,6 +252,7 @@ public:
}
int cuda_version = cuewCompilerVersion();
+ VLOG(1) << "Found nvcc " << nvcc << ", CUDA version " << cuda_version;
if(cuda_version == 0) {
cuda_error_message("CUDA nvcc compiler version could not be parsed.");
@@ -272,12 +276,17 @@ public:
path_create_directories(cubin);
string command = string_printf("\"%s\" -arch=sm_%d%d -m%d --cubin \"%s\" "
- "-o \"%s\" --ptxas-options=\"-v\" -I\"%s\" -DNVCC -D__KERNEL_CUDA_VERSION__=%d",
+ "-o \"%s\" --ptxas-options=\"-v\" --use_fast_math -I\"%s\" "
+ "-DNVCC -D__KERNEL_CUDA_VERSION__=%d",
nvcc, major, minor, machine, kernel.c_str(), cubin.c_str(), include.c_str(), cuda_version);
if(experimental)
command += " -D__KERNEL_CUDA_EXPERIMENTAL__";
+ if(getenv("CYCLES_CUDA_EXTRA_CFLAGS")) {
+ command += string(" ") + getenv("CYCLES_CUDA_EXTRA_CFLAGS");
+ }
+
#ifdef WITH_CYCLES_DEBUG
command += " -D__KERNEL_DEBUG__";
#endif
@@ -1030,15 +1039,30 @@ bool device_cuda_init(void)
return result;
initialized = true;
-
- if (cuewInit() == CUEW_SUCCESS) {
- if(CUDADevice::have_precompiled_kernels())
+ int cuew_result = cuewInit();
+ if (cuew_result == CUEW_SUCCESS) {
+ VLOG(1) << "CUEW initialization succeeded";
+ if(CUDADevice::have_precompiled_kernels()) {
+ VLOG(1) << "Found precompiled kernels";
result = true;
+ }
#ifndef _WIN32
- else if(cuewCompilerPath() != NULL)
+ else if(cuewCompilerPath() != NULL) {
+ VLOG(1) << "Found CUDA compiled " << cuewCompilerPath();
result = true;
+ }
+ else {
+ VLOG(1) << "Neither precompiled kernels nor CUDA compiler wad found,"
+ << " unable to use CUDA";
+ }
#endif
}
+ else {
+ VLOG(1) << "CUEW initialization failed: "
+ << ((cuew_result == CUEW_ERROR_ATEXIT_FAILED)
+ ? "Error setting up atexit() handler"
+ : "Error opening the library");
+ }
return result;
}
@@ -1101,5 +1125,135 @@ void device_cuda_info(vector<DeviceInfo>& devices)
devices.insert(devices.end(), display_devices.begin(), display_devices.end());
}
-CCL_NAMESPACE_END
+string device_cuda_capabilities(void)
+{
+ CUresult result = cuInit(0);
+ if(result != CUDA_SUCCESS) {
+ if(result != CUDA_ERROR_NO_DEVICE) {
+ return string("Error initializing CUDA: ") + cuewErrorString(result);
+ }
+ return "No CUDA device found";
+ }
+
+ int count;
+ result = cuDeviceGetCount(&count);
+ if(result != CUDA_SUCCESS) {
+ return string("Error getting devices: ") + cuewErrorString(result);
+ }
+
+ string capabilities = "";
+ for(int num = 0; num < count; num++) {
+ char name[256];
+ if(cuDeviceGetName(name, 256, num) != CUDA_SUCCESS) {
+ continue;
+ }
+ capabilities += string("\t") + name + "\n";
+ int value;
+#define GET_ATTR(attr) \
+ { \
+ if(cuDeviceGetAttribute(&value, \
+ CU_DEVICE_ATTRIBUTE_##attr, \
+ num) == CUDA_SUCCESS) \
+ { \
+ capabilities += string_printf("\t\tCU_DEVICE_ATTRIBUTE_" #attr "\t\t\t%d\n", \
+ value); \
+ } \
+ } (void)0
+ /* TODO(sergey): Strip all attributes which are not useful for us
+ * or does not depend on the driver.
+ */
+ GET_ATTR(MAX_THREADS_PER_BLOCK);
+ GET_ATTR(MAX_BLOCK_DIM_X);
+ GET_ATTR(MAX_BLOCK_DIM_Y);
+ GET_ATTR(MAX_BLOCK_DIM_Z);
+ GET_ATTR(MAX_GRID_DIM_X);
+ GET_ATTR(MAX_GRID_DIM_Y);
+ GET_ATTR(MAX_GRID_DIM_Z);
+ GET_ATTR(MAX_SHARED_MEMORY_PER_BLOCK);
+ GET_ATTR(SHARED_MEMORY_PER_BLOCK);
+ GET_ATTR(TOTAL_CONSTANT_MEMORY);
+ GET_ATTR(WARP_SIZE);
+ GET_ATTR(MAX_PITCH);
+ GET_ATTR(MAX_REGISTERS_PER_BLOCK);
+ GET_ATTR(REGISTERS_PER_BLOCK);
+ GET_ATTR(CLOCK_RATE);
+ GET_ATTR(TEXTURE_ALIGNMENT);
+ GET_ATTR(GPU_OVERLAP);
+ GET_ATTR(MULTIPROCESSOR_COUNT);
+ GET_ATTR(KERNEL_EXEC_TIMEOUT);
+ GET_ATTR(INTEGRATED);
+ GET_ATTR(CAN_MAP_HOST_MEMORY);
+ GET_ATTR(COMPUTE_MODE);
+ GET_ATTR(MAXIMUM_TEXTURE1D_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE3D_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE3D_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE3D_DEPTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LAYERED_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LAYERED_LAYERS);
+ GET_ATTR(MAXIMUM_TEXTURE2D_ARRAY_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_ARRAY_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES);
+ GET_ATTR(SURFACE_ALIGNMENT);
+ GET_ATTR(CONCURRENT_KERNELS);
+ GET_ATTR(ECC_ENABLED);
+ GET_ATTR(TCC_DRIVER);
+ GET_ATTR(MEMORY_CLOCK_RATE);
+ GET_ATTR(GLOBAL_MEMORY_BUS_WIDTH);
+ GET_ATTR(L2_CACHE_SIZE);
+ GET_ATTR(MAX_THREADS_PER_MULTIPROCESSOR);
+ GET_ATTR(ASYNC_ENGINE_COUNT);
+ GET_ATTR(UNIFIED_ADDRESSING);
+ GET_ATTR(MAXIMUM_TEXTURE1D_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE1D_LAYERED_LAYERS);
+ GET_ATTR(CAN_TEX2D_GATHER);
+ GET_ATTR(MAXIMUM_TEXTURE2D_GATHER_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_GATHER_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE3D_WIDTH_ALTERNATE);
+ GET_ATTR(MAXIMUM_TEXTURE3D_HEIGHT_ALTERNATE);
+ GET_ATTR(MAXIMUM_TEXTURE3D_DEPTH_ALTERNATE);
+ GET_ATTR(TEXTURE_PITCH_ALIGNMENT);
+ GET_ATTR(MAXIMUM_TEXTURECUBEMAP_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURECUBEMAP_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURECUBEMAP_LAYERED_LAYERS);
+ GET_ATTR(MAXIMUM_SURFACE1D_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACE2D_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACE2D_HEIGHT);
+ GET_ATTR(MAXIMUM_SURFACE3D_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACE3D_HEIGHT);
+ GET_ATTR(MAXIMUM_SURFACE3D_DEPTH);
+ GET_ATTR(MAXIMUM_SURFACE1D_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACE1D_LAYERED_LAYERS);
+ GET_ATTR(MAXIMUM_SURFACE2D_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACE2D_LAYERED_HEIGHT);
+ GET_ATTR(MAXIMUM_SURFACE2D_LAYERED_LAYERS);
+ GET_ATTR(MAXIMUM_SURFACECUBEMAP_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACECUBEMAP_LAYERED_WIDTH);
+ GET_ATTR(MAXIMUM_SURFACECUBEMAP_LAYERED_LAYERS);
+ GET_ATTR(MAXIMUM_TEXTURE1D_LINEAR_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LINEAR_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LINEAR_HEIGHT);
+ GET_ATTR(MAXIMUM_TEXTURE2D_LINEAR_PITCH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_MIPMAPPED_WIDTH);
+ GET_ATTR(MAXIMUM_TEXTURE2D_MIPMAPPED_HEIGHT);
+ GET_ATTR(COMPUTE_CAPABILITY_MAJOR);
+ GET_ATTR(COMPUTE_CAPABILITY_MINOR);
+ GET_ATTR(MAXIMUM_TEXTURE1D_MIPMAPPED_WIDTH);
+ GET_ATTR(STREAM_PRIORITIES_SUPPORTED);
+ GET_ATTR(GLOBAL_L1_CACHE_SUPPORTED);
+ GET_ATTR(LOCAL_L1_CACHE_SUPPORTED);
+ GET_ATTR(MAX_SHARED_MEMORY_PER_MULTIPROCESSOR);
+ GET_ATTR(MAX_REGISTERS_PER_MULTIPROCESSOR);
+ GET_ATTR(MANAGED_MEMORY);
+ GET_ATTR(MULTI_GPU_BOARD);
+ GET_ATTR(MULTI_GPU_BOARD_GROUP_ID);
+#undef GET_ATTR
+ capabilities += "\n";
+ }
+
+ return capabilities;
+}
+CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_intern.h b/intern/cycles/device/device_intern.h
index 80f1e2441a5..47584ae6d22 100644
--- a/intern/cycles/device/device_intern.h
+++ b/intern/cycles/device/device_intern.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __DEVICE_INTERN_H__
@@ -35,6 +35,10 @@ void device_cuda_info(vector<DeviceInfo>& devices);
void device_network_info(vector<DeviceInfo>& devices);
void device_multi_info(vector<DeviceInfo>& devices);
+string device_cpu_capabilities(void);
+string device_opencl_capabilities(void);
+string device_cuda_capabilities(void);
+
CCL_NAMESPACE_END
#endif /* __DEVICE_INTERN_H__ */
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index 07a6eb36a3c..7df2bc1a0c2 100644
--- a/intern/cycles/device/device_memory.h
+++ b/intern/cycles/device/device_memory.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __DEVICE_MEMORY_H__
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 7f055c79491..9aac86daa1d 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdlib.h>
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index dca9bf29e70..4733482bf4e 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "device.h"
diff --git a/intern/cycles/device/device_network.h b/intern/cycles/device/device_network.h
index 893841d1da7..2e751f6697f 100644
--- a/intern/cycles/device/device_network.h
+++ b/intern/cycles/device/device_network.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __DEVICE_NETWORK_H__
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 58b2bcafb82..a5bf35a63c8 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifdef WITH_OPENCL
@@ -20,13 +20,13 @@
#include <stdlib.h>
#include <string.h>
+#include "clew.h"
+
#include "device.h"
#include "device_intern.h"
#include "buffers.h"
-#include "clew.h"
-
#include "util_foreach.h"
#include "util_map.h"
#include "util_math.h"
@@ -1195,7 +1195,12 @@ void device_opencl_info(vector<DeviceInfo>& devices)
}
}
+string device_opencl_capabilities(void)
+{
+ /* TODO(sergey): Not implemented yet. */
+ return "";
+}
+
CCL_NAMESPACE_END
#endif /* WITH_OPENCL */
-
diff --git a/intern/cycles/device/device_task.cpp b/intern/cycles/device/device_task.cpp
index dc124f8cf37..2fe2f334176 100644
--- a/intern/cycles/device/device_task.cpp
+++ b/intern/cycles/device/device_task.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdlib.h>
diff --git a/intern/cycles/device/device_task.h b/intern/cycles/device/device_task.h
index 50216adefe2..84945bcf9a5 100644
--- a/intern/cycles/device/device_task.h
+++ b/intern/cycles/device/device_task.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __DEVICE_TASK_H__
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index c521e1383a4..a25eb3f5b50 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -91,6 +91,7 @@ set(SRC_SVM_HEADERS
svm/svm_magic.h
svm/svm_mapping.h
svm/svm_math.h
+ svm/svm_math_util.h
svm/svm_mix.h
svm/svm_musgrave.h
svm/svm_noise.h
@@ -122,7 +123,13 @@ set(SRC_GEOM_HEADERS
geom/geom_motion_triangle.h
geom/geom_object.h
geom/geom_primitive.h
+ geom/geom_qbvh.h
+ geom/geom_qbvh_shadow.h
+ geom/geom_qbvh_subsurface.h
+ geom/geom_qbvh_traversal.h
+ geom/geom_qbvh_volume.h
geom/geom_triangle.h
+ geom/geom_triangle_intersect.h
geom/geom_volume.h
)
@@ -130,6 +137,7 @@ set(SRC_UTIL_HEADERS
../util/util_color.h
../util/util_half.h
../util/util_math.h
+ ../util/util_math_fast.h
../util/util_transform.h
../util/util_types.h
)
@@ -235,17 +243,26 @@ if(CXX_HAS_SSE)
kernel_sse2.cpp
kernel_sse3.cpp
kernel_sse41.cpp
- kernel_avx.cpp
- kernel_avx2.cpp
)
set_source_files_properties(kernel_sse2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}")
set_source_files_properties(kernel_sse3.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS}")
set_source_files_properties(kernel_sse41.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS}")
+endif()
+
+if(CXX_HAS_AVX)
+ list(APPEND SRC
+ kernel_avx.cpp
+ )
set_source_files_properties(kernel_avx.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
- set_source_files_properties(kernel_avx2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
endif()
+if(CXX_HAS_AVX2)
+ list(APPEND SRC
+ kernel_avx2.cpp
+ )
+ set_source_files_properties(kernel_avx2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
+endif()
add_library(cycles_kernel ${SRC} ${SRC_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_SVM_HEADERS} ${SRC_GEOM_HEADERS})
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index 7d4783b0f3c..2b9e2a4e44d 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "../closure/bsdf_ashikhmin_velvet.h"
@@ -275,6 +275,8 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const Shade
ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
{
+/* ToDo: do we want to blur volume closures? */
+
#ifdef __OSL__
if(kg->osl && sc->prim) {
OSLShader::bsdf_blur(sc, roughness);
@@ -282,33 +284,8 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
}
#endif
- switch(sc->type) {
- case CLOSURE_BSDF_DIFFUSE_ID:
- case CLOSURE_BSDF_BSSRDF_ID:
- bsdf_diffuse_blur(sc, roughness);
- break;
#ifdef __SVM__
- case CLOSURE_BSDF_OREN_NAYAR_ID:
- bsdf_oren_nayar_blur(sc, roughness);
- break;
- /*case CLOSURE_BSDF_PHONG_RAMP_ID:
- bsdf_phong_ramp_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
- bsdf_diffuse_ramp_blur(sc, roughness);
- break;*/
- case CLOSURE_BSDF_TRANSLUCENT_ID:
- bsdf_translucent_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_REFLECTION_ID:
- bsdf_reflection_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_REFRACTION_ID:
- bsdf_refraction_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_TRANSPARENT_ID:
- bsdf_transparent_blur(sc, roughness);
- break;
+ switch(sc->type) {
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
@@ -323,24 +300,10 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
bsdf_ashikhmin_shirley_blur(sc, roughness);
break;
- case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- bsdf_ashikhmin_velvet_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_DIFFUSE_TOON_ID:
- bsdf_diffuse_toon_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_GLOSSY_TOON_ID:
- bsdf_glossy_toon_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_HAIR_REFLECTION_ID:
- case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
- bsdf_hair_reflection_blur(sc, roughness);
- break;
-#endif
- /* todo: do we want to blur volume closures? */
default:
break;
}
+#endif
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
index ad7864cb8ea..acc477246d2 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2013 Blender Foundation
+ * Copyright 2011-2014 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __BSDF_ASHIKHMIN_SHIRLEY_H__
@@ -33,24 +33,20 @@ CCL_NAMESPACE_BEGIN
ccl_device int bsdf_ashikhmin_shirley_setup(ShaderClosure *sc)
{
- /* store roughness. could already convert to exponent to save some cycles
- * in eval, but this is more consistent with other bsdfs and shader_blur. */
sc->data0 = clamp(sc->data0, 1e-4f, 1.0f);
sc->data1 = sc->data0;
sc->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_ashikhmin_shirley_aniso_setup(ShaderClosure *sc)
{
- /* store roughness. could already convert to exponent to save some cycles
- * in eval, but this is more consistent with other bsdfs and shader_blur. */
sc->data0 = clamp(sc->data0, 1e-4f, 1.0f);
sc->data1 = clamp(sc->data1, 1e-4f, 1.0f);
sc->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_ashikhmin_shirley_blur(ShaderClosure *sc, float roughness)
@@ -73,7 +69,7 @@ ccl_device float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc, c
float out = 0.0f;
- if (NdotI > 0.0f && NdotO > 0.0f) {
+ if(NdotI > 0.0f && NdotO > 0.0f) {
NdotI = fmaxf(NdotI, 1e-6f);
NdotO = fmaxf(NdotO, 1e-6f);
float3 H = normalize(omega_in + I);
@@ -86,7 +82,8 @@ ccl_device float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc, c
float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data0);
float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data1);
- if (n_x == n_y) { /* => isotropic case */
+ if(n_x == n_y) {
+ /* isotropic */
float e = n_x;
float lobe = powf(HdotN, e);
float norm = (n_x + 1.0f) / (8.0f * M_PI_F);
@@ -94,7 +91,8 @@ ccl_device float3 bsdf_ashikhmin_shirley_eval_reflect(const ShaderClosure *sc, c
out = NdotO * norm * lobe * pump;
*pdf = norm * lobe / HdotI; /* this is p_h / 4(H.I) (conversion from 'wh measure' to 'wi measure', eq. 8 in paper) */
}
- else { /* => ANisotropic case */
+ else {
+ /* anisotropic */
float3 X, Y;
make_orthonormals_tangent(N, sc->T, &X, &Y);
@@ -130,7 +128,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng,
float3 N = sc->N;
float NdotI = dot(N, I);
- if (NdotI > 0.0f) {
+ if(NdotI > 0.0f) {
float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data0);
float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(sc->data1);
@@ -146,21 +144,23 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng,
/* sample spherical coords for h in tangent space */
float phi;
float cos_theta;
- if (n_x == n_y) { /* => simple isotropic sampling */
+ if(n_x == n_y) {
+ /* isotropic sampling */
phi = M_2PI_F * randu;
cos_theta = powf(randv, 1.0f / (n_x + 1.0f));
}
- else { /* => more complex anisotropic sampling */
- if (randu < 0.25f) { /* first quadrant */
+ else {
+ /* anisotropic sampling */
+ if(randu < 0.25f) { /* first quadrant */
float remapped_randu = 4.0f * randu;
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
}
- else if (randu < 0.5f) { /* second quadrant */
+ else if(randu < 0.5f) { /* second quadrant */
float remapped_randu = 4.0f * (.5f - randu);
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
phi = M_PI_F - phi;
}
- else if (randu < 0.75f) { /* third quadrant */
+ else if(randu < 0.75f) { /* third quadrant */
float remapped_randu = 4.0f * (randu - 0.5f);
bsdf_ashikhmin_shirley_sample_first_quadrant(n_x, n_y, remapped_randu, randv, &phi, &cos_theta);
phi = M_PI_F + phi;
@@ -185,13 +185,12 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng,
/* half vector to world space */
float3 H = h.x*X + h.y*Y + h.z*N;
float HdotI = dot(H, I);
- if (HdotI < 0.0f) H = -H;
+ if(HdotI < 0.0f) H = -H;
/* reflect I on H to get omega_in */
*omega_in = -I + (2.0f * HdotI) * H;
/* leave the rest to eval_reflect */
- /* (could maybe optimize a few things by manual inlining, but I doubt it would make much difference) */
*eval = bsdf_ashikhmin_shirley_eval_reflect(sc, I, *omega_in, pdf);
#ifdef __RAY_DIFFERENTIALS__
@@ -201,7 +200,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(const ShaderClosure *sc, float3 Ng,
#endif
}
- return LABEL_REFLECT | LABEL_GLOSSY;
+ return LABEL_REFLECT|LABEL_GLOSSY;
}
diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
index 3631f90bf8c..580f50d5dd6 100644
--- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
@@ -45,10 +45,6 @@ ccl_device int bsdf_ashikhmin_velvet_setup(ShaderClosure *sc)
return SD_BSDF|SD_BSDF_HAS_EVAL;
}
-ccl_device void bsdf_ashikhmin_velvet_blur(ShaderClosure *sc, float roughness)
-{
-}
-
ccl_device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_invsigma2 = sc->data0;
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index 949fe869549..4b29bb096d1 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -43,10 +43,6 @@ ccl_device int bsdf_diffuse_setup(ShaderClosure *sc)
return SD_BSDF|SD_BSDF_HAS_EVAL;
}
-ccl_device void bsdf_diffuse_blur(ShaderClosure *sc, float roughness)
-{
-}
-
ccl_device float3 bsdf_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float3 N = sc->N;
@@ -90,10 +86,6 @@ ccl_device int bsdf_translucent_setup(ShaderClosure *sc)
return SD_BSDF|SD_BSDF_HAS_EVAL;
}
-ccl_device void bsdf_translucent_blur(ShaderClosure *sc, float roughness)
-{
-}
-
ccl_device float3 bsdf_translucent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
@@ -108,11 +100,6 @@ ccl_device float3 bsdf_translucent_eval_transmit(const ShaderClosure *sc, const
return make_float3 (cos_pi, cos_pi, cos_pi);
}
-ccl_device float bsdf_translucent_albedo(const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
ccl_device int bsdf_translucent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
float3 N = sc->N;
diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
index b856774375f..cdaf84f1750 100644
--- a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h
@@ -41,9 +41,9 @@ ccl_device float3 bsdf_diffuse_ramp_get_color(const ShaderClosure *sc, const flo
float npos = pos * (float)(MAXCOLORS - 1);
int ipos = float_to_int(npos);
- if (ipos < 0)
+ if(ipos < 0)
return colors[0];
- if (ipos >= (MAXCOLORS - 1))
+ if(ipos >= (MAXCOLORS - 1))
return colors[MAXCOLORS - 1];
float offset = npos - (float)ipos;
return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset;
@@ -52,7 +52,7 @@ ccl_device float3 bsdf_diffuse_ramp_get_color(const ShaderClosure *sc, const flo
ccl_device int bsdf_diffuse_ramp_setup(ShaderClosure *sc)
{
sc->type = CLOSURE_BSDF_DIFFUSE_RAMP_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_diffuse_ramp_blur(ShaderClosure *sc, float roughness)
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index e0b5454592b..1e81617a7d3 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -36,20 +36,12 @@
CCL_NAMESPACE_BEGIN
-ccl_device void bsdf_hair_reflection_blur(ShaderClosure *sc, float roughness)
-{
-}
-
-ccl_device void bsdf_hair_transmission_blur(ShaderClosure *sc, float roughness)
-{
-}
-
ccl_device int bsdf_hair_reflection_setup(ShaderClosure *sc)
{
sc->type = CLOSURE_BSDF_HAIR_REFLECTION_ID;
sc->data0 = clamp(sc->data0, 0.001f, 1.0f);
sc->data1 = clamp(sc->data1, 0.001f, 1.0f);
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_hair_transmission_setup(ShaderClosure *sc)
@@ -57,31 +49,25 @@ ccl_device int bsdf_hair_transmission_setup(ShaderClosure *sc)
sc->type = CLOSURE_BSDF_HAIR_TRANSMISSION_ID;
sc->data0 = clamp(sc->data0, 0.001f, 1.0f);
sc->data1 = clamp(sc->data1, 0.001f, 1.0f);
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device float3 bsdf_hair_reflection_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
-#ifdef __HAIR__
float offset = sc->data2;
float3 Tg = sc->T;
-#else
- float offset = 0.0f;
- float3 Tg = make_float3(1.0f, 0.0f, 0.0f);
-#endif
float roughness1 = sc->data0;
float roughness2 = sc->data1;
float Iz = dot(Tg, I);
float3 locy = normalize(I - Tg * Iz);
- //float3 locx = cross(locy, Tg);
- float theta_r = M_PI_2_F - safe_acosf(Iz);
+ float theta_r = M_PI_2_F - fast_acosf(Iz);
float omega_in_z = dot(Tg, omega_in);
float3 omega_in_y = normalize(omega_in - Tg * omega_in_z);
- float theta_i = M_PI_2_F - safe_acosf(omega_in_z);
+ float theta_i = M_PI_2_F - fast_acosf(omega_in_z);
float cosphi_i = dot(omega_in_y, locy);
if(M_PI_2_F - fabsf(theta_i) < 0.001f || cosphi_i < 0.0f) {
@@ -89,17 +75,19 @@ ccl_device float3 bsdf_hair_reflection_eval_reflect(const ShaderClosure *sc, con
return make_float3(*pdf, *pdf, *pdf);
}
- float phi_i = safe_acosf(cosphi_i) / roughness2;
+ float roughness1_inv = 1.0f / roughness1;
+ float roughness2_inv = 1.0f / roughness2;
+ float phi_i = fast_acosf(cosphi_i) * roughness2_inv;
phi_i = fabsf(phi_i) < M_PI_F ? phi_i : M_PI_F;
- float costheta_i = cosf(theta_i);
+ float costheta_i = fast_cosf(theta_i);
- float a_R = atan2f(((M_PI_2_F + theta_r) * 0.5f - offset) / roughness1, 1.0f);
- float b_R = atan2f(((-M_PI_2_F + theta_r) * 0.5f - offset) / roughness1, 1.0f);
+ float a_R = fast_atan2f(((M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
+ float b_R = fast_atan2f(((-M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
float theta_h = (theta_i + theta_r) * 0.5f;
float t = theta_h - offset;
- float phi_pdf = cosf(phi_i * 0.5f) * 0.25f / roughness2;
+ float phi_pdf = fast_cosf(phi_i * 0.5f) * 0.25f * roughness2_inv;
float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_R - b_R)* costheta_i);
*pdf = phi_pdf * theta_pdf;
@@ -119,37 +107,32 @@ ccl_device float3 bsdf_hair_reflection_eval_transmit(const ShaderClosure *sc, co
ccl_device float3 bsdf_hair_transmission_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
-#ifdef __HAIR__
float offset = sc->data2;
float3 Tg = sc->T;
-#else
- float offset = 0.0f;
- float3 Tg = make_float3(1.0f, 0.0f, 0.0f);
-#endif
float roughness1 = sc->data0;
float roughness2 = sc->data1;
float Iz = dot(Tg, I);
float3 locy = normalize(I - Tg * Iz);
- //float3 locx = cross(locy, Tg);
- float theta_r = M_PI_2_F - safe_acosf(Iz);
+ float theta_r = M_PI_2_F - fast_acosf(Iz);
float omega_in_z = dot(Tg, omega_in);
float3 omega_in_y = normalize(omega_in - Tg * omega_in_z);
- float theta_i = M_PI_2_F - safe_acosf(omega_in_z);
- float phi_i = safe_acosf(dot(omega_in_y, locy));
+ float theta_i = M_PI_2_F - fast_acosf(omega_in_z);
+ float phi_i = fast_acosf(dot(omega_in_y, locy));
if(M_PI_2_F - fabsf(theta_i) < 0.001f) {
*pdf = 0.0f;
return make_float3(*pdf, *pdf, *pdf);
}
- float costheta_i = cosf(theta_i);
+ float costheta_i = fast_cosf(theta_i);
- float a_TT = atan2f(((M_PI_2_F + theta_r)/2 - offset) / roughness1, 1.0f);
- float b_TT = atan2f(((-M_PI_2_F + theta_r)/2 - offset) / roughness1, 1.0f);
- float c_TT = 2 * atan2f(M_PI_2_F / roughness2, 1.0f);
+ float roughness1_inv = 1.0f / roughness1;
+ float a_TT = fast_atan2f(((M_PI_2_F + theta_r)/2 - offset) * roughness1_inv, 1.0f);
+ float b_TT = fast_atan2f(((-M_PI_2_F + theta_r)/2 - offset) * roughness1_inv, 1.0f);
+ float c_TT = 2 * fast_atan2f(M_PI_2_F / roughness2, 1.0f);
float theta_h = (theta_i + theta_r) / 2;
float t = theta_h - offset;
@@ -165,39 +148,38 @@ ccl_device float3 bsdf_hair_transmission_eval_transmit(const ShaderClosure *sc,
ccl_device int bsdf_hair_reflection_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
-#ifdef __HAIR__
float offset = sc->data2;
float3 Tg = sc->T;
-#else
- float offset = 0.0f;
- float3 Tg = make_float3(1.0f, 0.0f, 0.0f);
-#endif
float roughness1 = sc->data0;
float roughness2 = sc->data1;
float Iz = dot(Tg, I);
float3 locy = normalize(I - Tg * Iz);
float3 locx = cross(locy, Tg);
- float theta_r = M_PI_2_F - safe_acosf(Iz);
+ float theta_r = M_PI_2_F - fast_acosf(Iz);
- float a_R = atan2f(((M_PI_2_F + theta_r) * 0.5f - offset) / roughness1, 1.0f);
- float b_R = atan2f(((-M_PI_2_F + theta_r) * 0.5f - offset) / roughness1, 1.0f);
+ float roughness1_inv = 1.0f / roughness1;
+ float a_R = fast_atan2f(((M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
+ float b_R = fast_atan2f(((-M_PI_2_F + theta_r) * 0.5f - offset) * roughness1_inv, 1.0f);
float t = roughness1 * tanf(randu * (a_R - b_R) + b_R);
float theta_h = t + offset;
float theta_i = 2 * theta_h - theta_r;
- float costheta_i = cosf(theta_i);
- float sintheta_i = sinf(theta_i);
+
+ float costheta_i, sintheta_i;
+ fast_sincosf(theta_i, &sintheta_i, &costheta_i);
float phi = 2 * safe_asinf(1 - 2 * randv) * roughness2;
- float phi_pdf = cosf(phi * 0.5f) * 0.25f / roughness2;
+ float phi_pdf = fast_cosf(phi * 0.5f) * 0.25f / roughness2;
float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_R - b_R)*costheta_i);
- *omega_in =(cosf(phi) * costheta_i) * locy -
- (sinf(phi) * costheta_i) * locx +
- ( sintheta_i) * Tg;
+ float sinphi, cosphi;
+ fast_sincosf(phi, &sinphi, &cosphi);
+ *omega_in =(cosphi * costheta_i) * locy -
+ (sinphi * costheta_i) * locx +
+ ( sintheta_i) * Tg;
//differentials - TODO: find a better approximation for the reflective bounce
#ifdef __RAY_DIFFERENTIALS__
@@ -211,48 +193,43 @@ ccl_device int bsdf_hair_reflection_sample(const ShaderClosure *sc, float3 Ng, f
*eval = make_float3(*pdf, *pdf, *pdf);
- if(dot(locy, *omega_in) < 0.0f) {
- return LABEL_REFLECT|LABEL_TRANSMIT|LABEL_GLOSSY;
- }
-
return LABEL_REFLECT|LABEL_GLOSSY;
}
ccl_device int bsdf_hair_transmission_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
{
-#ifdef __HAIR__
float offset = sc->data2;
float3 Tg = sc->T;
-#else
- float offset = 0.0f;
- float3 Tg = make_float3(1.0f, 0.0f, 0.0f);
-#endif
float roughness1 = sc->data0;
float roughness2 = sc->data1;
float Iz = dot(Tg, I);
float3 locy = normalize(I - Tg * Iz);
float3 locx = cross(locy, Tg);
- float theta_r = M_PI_2_F - safe_acosf(Iz);
+ float theta_r = M_PI_2_F - fast_acosf(Iz);
- float a_TT = atan2f(((M_PI_2_F + theta_r)/2 - offset) / roughness1, 1.0f);
- float b_TT = atan2f(((-M_PI_2_F + theta_r)/2 - offset) / roughness1, 1.0f);
- float c_TT = 2 * atan2f(M_PI_2_F / roughness2, 1.0f);
+ float roughness1_inv = 1.0f / roughness1;
+ float a_TT = fast_atan2f(((M_PI_2_F + theta_r)/2 - offset) * roughness1_inv, 1.0f);
+ float b_TT = fast_atan2f(((-M_PI_2_F + theta_r)/2 - offset) * roughness1_inv, 1.0f);
+ float c_TT = 2 * fast_atan2f(M_PI_2_F / roughness2, 1.0f);
float t = roughness1 * tanf(randu * (a_TT - b_TT) + b_TT);
float theta_h = t + offset;
float theta_i = 2 * theta_h - theta_r;
- float costheta_i = cosf(theta_i);
- float sintheta_i = sinf(theta_i);
+
+ float costheta_i, sintheta_i;
+ fast_sincosf(theta_i, &sintheta_i, &costheta_i);
float p = roughness2 * tanf(c_TT * (randv - 0.5f));
float phi = p + M_PI_F;
float theta_pdf = roughness1 / (2 * (t*t + roughness1*roughness1) * (a_TT - b_TT) * costheta_i);
float phi_pdf = roughness2 / (c_TT * (p * p + roughness2 * roughness2));
- *omega_in =(cosf(phi) * costheta_i) * locy -
- (sinf(phi) * costheta_i) * locx +
- ( sintheta_i) * Tg;
+ float sinphi, cosphi;
+ fast_sincosf(phi, &sinphi, &cosphi);
+ *omega_in =(cosphi * costheta_i) * locy -
+ (sinphi * costheta_i) * locx +
+ ( sintheta_i) * Tg;
//differentials - TODO: find a better approximation for the transmission bounce
#ifdef __RAY_DIFFERENTIALS__
@@ -267,10 +244,9 @@ ccl_device int bsdf_hair_transmission_sample(const ShaderClosure *sc, float3 Ng,
*eval = make_float3(*pdf, *pdf, *pdf);
- if(dot(locy, *omega_in) < 0.0f)
- return LABEL_TRANSMIT|LABEL_GLOSSY;
-
- return LABEL_GLOSSY;
+ kernel_assert(dot(locy, *omega_in) < 0.0f);
+
+ return LABEL_TRANSMIT|LABEL_GLOSSY;
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 8737b0e2d94..71086f2e764 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -305,7 +305,7 @@ ccl_device int bsdf_microfacet_ggx_setup(ShaderClosure *sc)
sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_aniso_setup(ShaderClosure *sc)
@@ -315,7 +315,7 @@ ccl_device int bsdf_microfacet_ggx_aniso_setup(ShaderClosure *sc)
sc->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_refraction_setup(ShaderClosure *sc)
@@ -325,7 +325,7 @@ ccl_device int bsdf_microfacet_ggx_refraction_setup(ShaderClosure *sc)
sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness)
@@ -338,7 +338,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, cons
{
float alpha_x = sc->data0;
float alpha_y = sc->data1;
- int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
float3 N = sc->N;
if(m_refractive || fmaxf(alpha_x, alpha_y) <= 1e-4f)
@@ -429,7 +429,7 @@ ccl_device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, con
float alpha_x = sc->data0;
float alpha_y = sc->data1;
float m_eta = sc->data2;
- int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
float3 N = sc->N;
if(!m_refractive || fmaxf(alpha_x, alpha_y) <= 1e-4f)
@@ -486,7 +486,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
{
float alpha_x = sc->data0;
float alpha_y = sc->data1;
- int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
+ bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
float3 N = sc->N;
float cosNO = dot(N, I);
@@ -591,16 +591,16 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure
#ifdef __RAY_DIFFERENTIALS__
float3 dRdx, dRdy, dTdx, dTdy;
#endif
- float m_eta = sc->data2;
+ float m_eta = sc->data2, fresnel;
bool inside;
- fresnel_dielectric(m_eta, m, I, &R, &T,
+ fresnel = fresnel_dielectric(m_eta, m, I, &R, &T,
#ifdef __RAY_DIFFERENTIALS__
dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
#endif
&inside);
- if(!inside) {
+ if(!inside && fresnel != 1.0f) {
*omega_in = T;
#ifdef __RAY_DIFFERENTIALS__
@@ -657,7 +657,7 @@ ccl_device int bsdf_microfacet_beckmann_setup(ShaderClosure *sc)
sc->data1 = sc->data0; /* alpha_y */
sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_beckmann_aniso_setup(ShaderClosure *sc)
@@ -666,7 +666,7 @@ ccl_device int bsdf_microfacet_beckmann_aniso_setup(ShaderClosure *sc)
sc->data1 = clamp(sc->data1, 0.0f, 1.0f); /* alpha_y */
sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_beckmann_refraction_setup(ShaderClosure *sc)
@@ -675,7 +675,7 @@ ccl_device int bsdf_microfacet_beckmann_refraction_setup(ShaderClosure *sc)
sc->data1 = sc->data0; /* alpha_y */
sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness)
@@ -688,7 +688,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc,
{
float alpha_x = sc->data0;
float alpha_y = sc->data1;
- int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
float3 N = sc->N;
if(m_refractive || fmaxf(alpha_x, alpha_y) <= 1e-4f)
@@ -782,7 +782,7 @@ ccl_device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc
float alpha_x = sc->data0;
float alpha_y = sc->data1;
float m_eta = sc->data2;
- int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
float3 N = sc->N;
if(!m_refractive || fmaxf(alpha_x, alpha_y) <= 1e-4f)
@@ -838,7 +838,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg, const ShaderCl
{
float alpha_x = sc->data0;
float alpha_y = sc->data1;
- int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ bool m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
float3 N = sc->N;
float cosNO = dot(N, I);
@@ -945,16 +945,16 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg, const ShaderCl
#ifdef __RAY_DIFFERENTIALS__
float3 dRdx, dRdy, dTdx, dTdy;
#endif
- float m_eta = sc->data2;
+ float m_eta = sc->data2, fresnel;
bool inside;
- fresnel_dielectric(m_eta, m, I, &R, &T,
+ fresnel = fresnel_dielectric(m_eta, m, I, &R, &T,
#ifdef __RAY_DIFFERENTIALS__
dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
#endif
&inside);
- if(!inside) {
+ if(!inside && fresnel != 1.0f) {
*omega_in = T;
#ifdef __RAY_DIFFERENTIALS__
diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
index 6f685d5eeea..c476d4ca4e2 100644
--- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h
+++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __BSDF_OREN_NAYAR_H__
@@ -25,7 +25,7 @@ ccl_device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3
float nv = max(dot(n, v), 0.0f);
float t = dot(l, v) - nl * nv;
- if (t > 0.0f)
+ if(t > 0.0f)
t /= max(nl, nv) + FLT_MIN;
float is = nl * (sc->data0 + sc->data1 * t);
return make_float3(is, is, is);
@@ -44,16 +44,12 @@ ccl_device int bsdf_oren_nayar_setup(ShaderClosure *sc)
sc->data0 = 1.0f * div;
sc->data1 = sigma * div;
- return SD_BSDF | SD_BSDF_HAS_EVAL;
-}
-
-ccl_device void bsdf_oren_nayar_blur(ShaderClosure *sc, float roughness)
-{
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- if (dot(sc->N, omega_in) > 0.0f) {
+ if(dot(sc->N, omega_in) > 0.0f) {
*pdf = 0.5f * M_1_PI_F;
return bsdf_oren_nayar_get_intensity(sc, sc->N, I, omega_in);
}
@@ -72,7 +68,7 @@ ccl_device int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3
{
sample_uniform_hemisphere(sc->N, randu, randv, omega_in, pdf);
- if (dot(Ng, *omega_in) > 0.0f) {
+ if(dot(Ng, *omega_in) > 0.0f) {
*eval = bsdf_oren_nayar_get_intensity(sc, sc->N, I, *omega_in);
#ifdef __RAY_DIFFERENTIALS__
@@ -86,7 +82,7 @@ ccl_device int bsdf_oren_nayar_sample(const ShaderClosure *sc, float3 Ng, float3
*eval = make_float3(0.0f, 0.0f, 0.0f);
}
- return LABEL_REFLECT | LABEL_DIFFUSE;
+ return LABEL_REFLECT|LABEL_DIFFUSE;
}
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
index 2b4e1c68640..f9f263719e9 100644
--- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -41,9 +41,9 @@ ccl_device float3 bsdf_phong_ramp_get_color(const ShaderClosure *sc, const float
float npos = pos * (float)(MAXCOLORS - 1);
int ipos = float_to_int(npos);
- if (ipos < 0)
+ if(ipos < 0)
return colors[0];
- if (ipos >= (MAXCOLORS - 1))
+ if(ipos >= (MAXCOLORS - 1))
return colors[MAXCOLORS - 1];
float offset = npos - (float)ipos;
return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset;
@@ -54,7 +54,7 @@ ccl_device int bsdf_phong_ramp_setup(ShaderClosure *sc)
sc->data0 = max(sc->data0, 0.0f);
sc->type = CLOSURE_BSDF_PHONG_RAMP_ID;
- return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
ccl_device void bsdf_phong_ramp_blur(ShaderClosure *sc, float roughness)
@@ -67,11 +67,11 @@ ccl_device float3 bsdf_phong_ramp_eval_reflect(const ShaderClosure *sc, const fl
float cosNI = dot(sc->N, omega_in);
float cosNO = dot(sc->N, I);
- if (cosNI > 0 && cosNO > 0) {
+ if(cosNI > 0 && cosNO > 0) {
// reflect the view vector
float3 R = (2 * cosNO) * sc->N - I;
float cosRI = dot(R, omega_in);
- if (cosRI > 0) {
+ if(cosRI > 0) {
float cosp = powf(cosRI, m_exponent);
float common = 0.5f * M_1_PI_F * cosp;
float out = cosNI * (m_exponent + 2) * common;
@@ -93,7 +93,7 @@ ccl_device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colo
float cosNO = dot(sc->N, I);
float m_exponent = sc->data0;
- if (cosNO > 0) {
+ if(cosNO > 0) {
// reflect the view vector
float3 R = (2 * cosNO) * sc->N - I;
@@ -111,12 +111,12 @@ ccl_device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colo
*omega_in = (cosf(phi) * sinTheta) * T +
(sinf(phi) * sinTheta) * B +
( cosTheta) * R;
- if (dot(Ng, *omega_in) > 0.0f)
+ if(dot(Ng, *omega_in) > 0.0f)
{
// common terms for pdf and eval
float cosNI = dot(sc->N, *omega_in);
// make sure the direction we chose is still in the right hemisphere
- if (cosNI > 0)
+ if(cosNI > 0)
{
float cosp = powf(cosTheta, m_exponent);
float common = 0.5f * M_1_PI_F * cosp;
diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h
index 0baccdf155c..303f4c9ce34 100644
--- a/intern/cycles/kernel/closure/bsdf_reflection.h
+++ b/intern/cycles/kernel/closure/bsdf_reflection.h
@@ -43,10 +43,6 @@ ccl_device int bsdf_reflection_setup(ShaderClosure *sc)
return SD_BSDF;
}
-ccl_device void bsdf_reflection_blur(ShaderClosure *sc, float roughness)
-{
-}
-
ccl_device float3 bsdf_reflection_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
@@ -70,8 +66,9 @@ ccl_device int bsdf_reflection_sample(const ShaderClosure *sc, float3 Ng, float3
*domega_in_dx = 2 * dot(N, dIdx) * N - dIdx;
*domega_in_dy = 2 * dot(N, dIdy) * N - dIdy;
#endif
- *pdf = 1;
- *eval = make_float3(1, 1, 1);
+ /* Some high number for MIS. */
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
}
}
return LABEL_REFLECT|LABEL_SINGULAR;
diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h
index c4698b42060..c78a4b67134 100644
--- a/intern/cycles/kernel/closure/bsdf_refraction.h
+++ b/intern/cycles/kernel/closure/bsdf_refraction.h
@@ -43,10 +43,6 @@ ccl_device int bsdf_refraction_setup(ShaderClosure *sc)
return SD_BSDF;
}
-ccl_device void bsdf_refraction_blur(ShaderClosure *sc, float roughness)
-{
-}
-
ccl_device float3 bsdf_refraction_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
@@ -67,15 +63,17 @@ ccl_device int bsdf_refraction_sample(const ShaderClosure *sc, float3 Ng, float3
float3 dRdx, dRdy, dTdx, dTdy;
#endif
bool inside;
- fresnel_dielectric(m_eta, N, I, &R, &T,
+ float fresnel;
+ fresnel = fresnel_dielectric(m_eta, N, I, &R, &T,
#ifdef __RAY_DIFFERENTIALS__
dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
#endif
&inside);
-
- if(!inside) {
- *pdf = 1.0f;
- *eval = make_float3(1.0f, 1.0f, 1.0f);
+
+ if(!inside && fresnel != 1.0f) {
+ /* Some high number for MIS. */
+ *pdf = 1e6f;
+ *eval = make_float3(1e6f, 1e6f, 1e6f);
*omega_in = T;
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = dTdx;
diff --git a/intern/cycles/kernel/closure/bsdf_toon.h b/intern/cycles/kernel/closure/bsdf_toon.h
index 797fa4227ae..df03942638f 100644
--- a/intern/cycles/kernel/closure/bsdf_toon.h
+++ b/intern/cycles/kernel/closure/bsdf_toon.h
@@ -46,10 +46,6 @@ ccl_device int bsdf_diffuse_toon_setup(ShaderClosure *sc)
return SD_BSDF|SD_BSDF_HAS_EVAL;
}
-ccl_device void bsdf_diffuse_toon_blur(ShaderClosure *sc, float roughness)
-{
-}
-
ccl_device float3 bsdf_toon_get_intensity(float max_angle, float smooth, float angle)
{
float is;
@@ -130,10 +126,6 @@ ccl_device int bsdf_glossy_toon_setup(ShaderClosure *sc)
return SD_BSDF|SD_BSDF_HAS_EVAL;
}
-ccl_device void bsdf_glossy_toon_blur(ShaderClosure *sc, float roughness)
-{
-}
-
ccl_device float3 bsdf_glossy_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float max_angle = sc->data0*M_PI_2_F;
diff --git a/intern/cycles/kernel/closure/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h
index 73601d20c3a..3c2fd8004df 100644
--- a/intern/cycles/kernel/closure/bsdf_transparent.h
+++ b/intern/cycles/kernel/closure/bsdf_transparent.h
@@ -41,10 +41,6 @@ ccl_device int bsdf_transparent_setup(ShaderClosure *sc)
return SD_BSDF|SD_TRANSPARENT;
}
-ccl_device void bsdf_transparent_blur(ShaderClosure *sc, float roughness)
-{
-}
-
ccl_device float3 bsdf_transparent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h
index 3849dedc3b6..b6de2da8c71 100644
--- a/intern/cycles/kernel/closure/bssrdf.h
+++ b/intern/cycles/kernel/closure/bssrdf.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __KERNEL_BSSRDF_H__
diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h
index 058c4b8408f..439610546e5 100644
--- a/intern/cycles/kernel/closure/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __VOLUME_H__
@@ -26,9 +26,6 @@ CCL_NAMESPACE_BEGIN
* uniform sphere. g=0 uniform diffuse-like, g=1 close to sharp single ray. */
ccl_device float single_peaked_henyey_greenstein(float cos_theta, float g)
{
- if(fabsf(g) < 1e-3f)
- return M_1_PI_F * 0.25f;
-
return ((1.0f - g * g) / safe_powf(1.0f + g * g - 2.0f * g * cos_theta, 1.5f)) * (M_1_PI_F * 0.25f);
};
@@ -39,7 +36,7 @@ ccl_device int volume_henyey_greenstein_setup(ShaderClosure *sc)
/* clamp anisotropy to avoid delta function */
sc->data0 = signf(sc->data0) * min(fabsf(sc->data0), 1.0f - 1e-3f);
- return SD_SCATTER|SD_PHASE_HAS_EVAL;
+ return SD_SCATTER;
}
ccl_device float3 volume_henyey_greenstein_eval_phase(const ShaderClosure *sc, const float3 I, float3 omega_in, float *pdf)
@@ -47,9 +44,13 @@ ccl_device float3 volume_henyey_greenstein_eval_phase(const ShaderClosure *sc, c
float g = sc->data0;
/* note that I points towards the viewer */
- float cos_theta = dot(-I, omega_in);
-
- *pdf = single_peaked_henyey_greenstein(cos_theta, g);
+ if(fabsf(g) < 1e-3f) {
+ *pdf = M_1_PI_F * 0.25f;
+ }
+ else {
+ float cos_theta = dot(-I, omega_in);
+ *pdf = single_peaked_henyey_greenstein(cos_theta, g);
+ }
return make_float3(*pdf, *pdf, *pdf);
}
@@ -63,10 +64,12 @@ ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc, float3 I
/* match pdf for small g */
if(fabsf(g) < 1e-3f) {
cos_theta = (1.0f - 2.0f * randu);
+ *pdf = M_1_PI_F * 0.25f;
}
else {
float k = (1.0f - g * g) / (1.0f - g + 2.0f * g * randu);
cos_theta = (1.0f + g * g - k * k) / (2.0f * g);
+ *pdf = single_peaked_henyey_greenstein(cos_theta, g);
}
float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta);
@@ -80,7 +83,6 @@ ccl_device int volume_henyey_greenstein_sample(const ShaderClosure *sc, float3 I
make_orthonormals(-I, &T, &B);
*omega_in = sin_theta * cos_phi * T + sin_theta * sin_phi * B + cos_theta * (-I);
- *pdf = single_peaked_henyey_greenstein(cos_theta, g);
*eval = make_float3(*pdf, *pdf, *pdf); /* perfect importance sampling */
#ifdef __RAY_DIFFERENTIALS__
diff --git a/intern/cycles/kernel/geom/geom.h b/intern/cycles/kernel/geom/geom.h
index 9495a2541f9..bf0d86e6206 100644
--- a/intern/cycles/kernel/geom/geom.h
+++ b/intern/cycles/kernel/geom/geom.h
@@ -20,7 +20,9 @@
/* 64 object BVH + 64 mesh BVH + 64 object node splitting */
#define BVH_STACK_SIZE 192
+#define BVH_QSTACK_SIZE 384
#define BVH_NODE_SIZE 4
+#define BVH_QNODE_SIZE 7
#define TRI_NODE_SIZE 3
/* silly workaround for float extended precision that happens when compiling
@@ -35,6 +37,7 @@
#include "geom_attribute.h"
#include "geom_object.h"
#include "geom_triangle.h"
+#include "geom_triangle_intersect.h"
#include "geom_motion_triangle.h"
#include "geom_motion_curve.h"
#include "geom_curve.h"
diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h
index 63ce31c492f..9ac16e86085 100644
--- a/intern/cycles/kernel/geom/geom_attribute.h
+++ b/intern/cycles/kernel/geom/geom_attribute.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
@@ -40,6 +40,9 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, const ShaderData *sd, ui
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
while(attr_map.x != id) {
+ if(UNLIKELY(attr_map.x == ATTR_STD_NONE)) {
+ return ATTR_STD_NOT_FOUND;
+ }
attr_offset += ATTR_PRIM_TYPES;
attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
}
diff --git a/intern/cycles/kernel/geom/geom_bvh.h b/intern/cycles/kernel/geom/geom_bvh.h
index c5336e086b7..c0eefcd9c7f 100644
--- a/intern/cycles/kernel/geom/geom_bvh.h
+++ b/intern/cycles/kernel/geom/geom_bvh.h
@@ -42,6 +42,17 @@ CCL_NAMESPACE_BEGIN
#define BVH_HAIR 4
#define BVH_HAIR_MINIMUM_WIDTH 8
+#define BVH_NAME_JOIN(x,y) x ## _ ## y
+#define BVH_NAME_EVAL(x,y) BVH_NAME_JOIN(x,y)
+#define BVH_FUNCTION_FULL_NAME(prefix) BVH_NAME_EVAL(prefix, BVH_FUNCTION_NAME)
+
+#define BVH_FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0)
+
+/* Common QBVH functions. */
+#ifdef __QBVH__
+#include "geom_qbvh.h"
+#endif
+
/* Regular BVH traversal */
#define BVH_FUNCTION_NAME bvh_intersect
@@ -168,6 +179,11 @@ CCL_NAMESPACE_BEGIN
#include "geom_bvh_volume.h"
#endif
+#undef BVH_FEATURE
+#undef BVH_NAME_JOIN
+#undef BVH_NAME_EVAL
+#undef BVH_FUNCTION_FULL_NAME
+
ccl_device_intersect bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect,
uint *lcg_state, float difl, float extmax)
{
diff --git a/intern/cycles/kernel/geom/geom_bvh_shadow.h b/intern/cycles/kernel/geom/geom_bvh_shadow.h
index aee4097d77e..193f49074a3 100644
--- a/intern/cycles/kernel/geom/geom_bvh_shadow.h
+++ b/intern/cycles/kernel/geom/geom_bvh_shadow.h
@@ -17,6 +17,10 @@
* limitations under the License.
*/
+#ifdef __QBVH__
+#include "geom_qbvh_shadow.h"
+#endif
+
/* This is a template BVH traversal function, where various features can be
* enabled/disabled. This way we can compile optimized versions for each case
* without new features slowing things down.
@@ -27,10 +31,11 @@
*
*/
-#define FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0)
-
-ccl_device bool BVH_FUNCTION_NAME
-(KernelGlobals *kg, const Ray *ray, Intersection *isect_array, const uint max_hits, uint *num_hits)
+ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect_array,
+ const uint max_hits,
+ uint *num_hits)
{
/* todo:
* - likely and unlikely for if() statements
@@ -53,11 +58,11 @@ ccl_device bool BVH_FUNCTION_NAME
int object = OBJECT_NONE;
float isect_t = tmax;
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
Transform ob_tfm;
#endif
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
int num_hits_in_instance = 0;
#endif
@@ -81,6 +86,9 @@ ccl_device bool BVH_FUNCTION_NAME
gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
+ IsectPrecalc isect_precalc;
+ triangle_intersect_precalc(dir, &isect_precalc);
+
/* traversal loop */
do {
do {
@@ -174,6 +182,7 @@ ccl_device bool BVH_FUNCTION_NAME
}
++stackPtr;
+ kernel_assert(stackPtr < BVH_STACK_SIZE);
traversalStack[stackPtr] = nodeAddrChild1;
}
else {
@@ -191,13 +200,15 @@ ccl_device bool BVH_FUNCTION_NAME
/* if node is leaf, fetch triangle list */
if(nodeAddr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+(BVH_NODE_SIZE-1));
+ float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+3);
int primAddr = __float_as_int(leaf.x);
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
if(primAddr >= 0) {
#endif
- int primAddr2 = __float_as_int(leaf.y);
+ const int primAddr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ const uint p_type = type & PRIMITIVE_ALL;
/* pop */
nodeAddr = traversalStack[stackPtr];
@@ -205,25 +216,26 @@ ccl_device bool BVH_FUNCTION_NAME
/* primitive intersection */
while(primAddr < primAddr2) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+
bool hit;
- uint type = kernel_tex_fetch(__prim_type, primAddr);
/* todo: specialized intersect functions which don't fill in
* isect unless needed and check SD_HAS_TRANSPARENT_SHADOW?
* might give a few % performance improvement */
- switch(type & PRIMITIVE_ALL) {
+ switch(p_type) {
case PRIMITIVE_TRIANGLE: {
- hit = triangle_intersect(kg, isect_array, P, dir, PATH_RAY_SHADOW, object, primAddr);
+ hit = triangle_intersect(kg, &isect_precalc, isect_array, P, dir, PATH_RAY_SHADOW, object, primAddr);
break;
}
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
case PRIMITIVE_MOTION_TRIANGLE: {
hit = motion_triangle_intersect(kg, isect_array, P, dir, ray->time, PATH_RAY_SHADOW, object, primAddr);
break;
}
#endif
-#if FEATURE(BVH_HAIR)
+#if BVH_FEATURE(BVH_HAIR)
case PRIMITIVE_CURVE:
case PRIMITIVE_MOTION_CURVE: {
if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
@@ -274,7 +286,7 @@ ccl_device bool BVH_FUNCTION_NAME
/* move on to next entry in intersections array */
isect_array++;
(*num_hits)++;
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++;
#endif
@@ -284,52 +296,55 @@ ccl_device bool BVH_FUNCTION_NAME
primAddr++;
}
}
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
else {
/* instance push */
object = kernel_tex_fetch(__prim_object, -primAddr-1);
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
num_hits_in_instance = 0;
+ isect_array->t = isect_t;
#if defined(__KERNEL_SSE2__)
Psplat[0] = ssef(P.x);
Psplat[1] = ssef(P.y);
Psplat[2] = ssef(P.z);
- isect_array->t = isect_t;
tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t);
-
gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
++stackPtr;
+ kernel_assert(stackPtr < BVH_STACK_SIZE);
traversalStack[stackPtr] = ENTRYPOINT_SENTINEL;
nodeAddr = kernel_tex_fetch(__object_node, object);
}
}
-#endif
+#endif /* FEATURE(BVH_INSTANCING) */
} while(nodeAddr != ENTRYPOINT_SENTINEL);
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
if(stackPtr >= 0) {
kernel_assert(object != OBJECT_NONE);
if(num_hits_in_instance) {
float t_fac;
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm);
#else
bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
/* scale isect->t to adjust for instancing */
for(int i = 0; i < num_hits_in_instance; i++)
(isect_array-i-1)->t *= t_fac;
@@ -337,22 +352,23 @@ ccl_device bool BVH_FUNCTION_NAME
else {
float ignore_t = FLT_MAX;
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t);
#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
}
+ isect_t = tmax;
+ isect_array->t = isect_t;
+
#if defined(__KERNEL_SSE2__)
Psplat[0] = ssef(P.x);
Psplat[1] = ssef(P.y);
Psplat[2] = ssef(P.z);
- isect_t = tmax;
- isect_array->t = isect_t;
tsplat = ssef(0.0f, 0.0f, -isect_t, -isect_t);
-
gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
@@ -360,13 +376,37 @@ ccl_device bool BVH_FUNCTION_NAME
nodeAddr = traversalStack[stackPtr];
--stackPtr;
}
-#endif
+#endif /* FEATURE(BVH_INSTANCING) */
} while(nodeAddr != ENTRYPOINT_SENTINEL);
return false;
}
-#undef FEATURE
+ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect_array,
+ const uint max_hits,
+ uint *num_hits)
+{
+#ifdef __QBVH__
+ if(kernel_data.bvh.use_qbvh) {
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
+ ray,
+ isect_array,
+ max_hits,
+ num_hits);
+ }
+ else
+#endif
+ {
+ kernel_assert(kernel_data.bvh.use_qbvh == false);
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg,
+ ray,
+ isect_array,
+ max_hits,
+ num_hits);
+ }
+}
+
#undef BVH_FUNCTION_NAME
#undef BVH_FUNCTION_FEATURES
-
diff --git a/intern/cycles/kernel/geom/geom_bvh_subsurface.h b/intern/cycles/kernel/geom/geom_bvh_subsurface.h
index a8f57cffa78..290297ef5c5 100644
--- a/intern/cycles/kernel/geom/geom_bvh_subsurface.h
+++ b/intern/cycles/kernel/geom/geom_bvh_subsurface.h
@@ -17,6 +17,10 @@
* limitations under the License.
*/
+#ifdef __QBVH__
+#include "geom_qbvh_subsurface.h"
+#endif
+
/* This is a template BVH traversal function for subsurface scattering, where
* various features can be enabled/disabled. This way we can compile optimized
* versions for each case without new features slowing things down.
@@ -26,10 +30,12 @@
*
*/
-#define FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0)
-
-ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersection *isect_array,
- int subsurface_object, uint *lcg_state, int max_hits)
+ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect_array,
+ int subsurface_object,
+ uint *lcg_state,
+ int max_hits)
{
/* todo:
* - test if pushing distance on the stack helps (for non shadow rays)
@@ -54,10 +60,9 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
int object = OBJECT_NONE;
float isect_t = ray->t;
- const uint visibility = PATH_RAY_ALL_VISIBILITY;
uint num_hits = 0;
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
Transform ob_tfm;
#endif
@@ -78,6 +83,9 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
+ IsectPrecalc isect_precalc;
+ triangle_intersect_precalc(dir, &isect_precalc);
+
/* traversal loop */
do {
do
@@ -118,14 +126,8 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
NO_EXTENDED_PRECISION float c1max = min4(max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz), t);
/* decide which nodes to traverse next */
-#ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- traverseChild0 = (c0max >= c0min) && (__float_as_uint(cnodes.z) & visibility);
- traverseChild1 = (c1max >= c1min) && (__float_as_uint(cnodes.w) & visibility);
-#else
traverseChild0 = (c0max >= c0min);
traverseChild1 = (c1max >= c1min);
-#endif
#else // __KERNEL_SSE2__
/* Intersect two child bounding boxes, SSE3 version adapted from Embree */
@@ -145,14 +147,8 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
const sseb lrhit = tminmax <= shuffle<2, 3, 0, 1>(tminmax);
/* decide which nodes to traverse next */
-#ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- traverseChild0 = (movemask(lrhit) & 1) && (__float_as_uint(cnodes.z) & visibility);
- traverseChild1 = (movemask(lrhit) & 2) && (__float_as_uint(cnodes.w) & visibility);
-#else
traverseChild0 = (movemask(lrhit) & 1);
traverseChild1 = (movemask(lrhit) & 2);
-#endif
#endif // __KERNEL_SSE2__
nodeAddr = __float_as_int(cnodes.x);
@@ -173,6 +169,7 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
}
++stackPtr;
+ kernel_assert(stackPtr < BVH_STACK_SIZE);
traversalStack[stackPtr] = nodeAddrChild1;
}
else {
@@ -190,57 +187,64 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
/* if node is leaf, fetch triangle list */
if(nodeAddr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+(BVH_NODE_SIZE-1));
+ float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+3);
int primAddr = __float_as_int(leaf.x);
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
if(primAddr >= 0) {
#endif
- int primAddr2 = __float_as_int(leaf.y);
+ const int primAddr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
/* pop */
nodeAddr = traversalStack[stackPtr];
--stackPtr;
/* primitive intersection */
- for(; primAddr < primAddr2; primAddr++) {
- /* only primitives from the same object */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
-
- if(tri_object != subsurface_object)
- continue;
-
- /* intersect ray against primitive */
- uint type = kernel_tex_fetch(__prim_type, primAddr);
-
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- triangle_intersect_subsurface(kg, isect_array, P, dir, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
- break;
+ switch(type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ /* intersect ray against primitive */
+ for(; primAddr < primAddr2; primAddr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ /* only primitives from the same object */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ if(tri_object != subsurface_object)
+ continue;
+ triangle_intersect_subsurface(kg, &isect_precalc, isect_array, P, dir, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
}
-#if FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
+ break;
+ }
+#if BVH_FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ /* intersect ray against primitive */
+ for(; primAddr < primAddr2; primAddr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ /* only primitives from the same object */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ if(tri_object != subsurface_object)
+ continue;
motion_triangle_intersect_subsurface(kg, isect_array, P, dir, ray->time, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
- break;
}
+ break;
+ }
#endif
- default: {
- break;
- }
+ default: {
+ break;
}
}
}
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
else {
/* instance push */
if(subsurface_object == kernel_tex_fetch(__prim_object, -primAddr-1)) {
object = subsurface_object;
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
#if defined(__KERNEL_SSE2__)
Psplat[0] = ssef(P.x);
@@ -253,6 +257,7 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
#endif
++stackPtr;
+ kernel_assert(stackPtr < BVH_STACK_SIZE);
traversalStack[stackPtr] = ENTRYPOINT_SENTINEL;
nodeAddr = kernel_tex_fetch(__object_node, object);
@@ -264,20 +269,22 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
}
}
}
-#endif
+#endif /* FEATURE(BVH_INSTANCING) */
} while(nodeAddr != ENTRYPOINT_SENTINEL);
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
if(stackPtr >= 0) {
kernel_assert(object != OBJECT_NONE);
/* instance pop */
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t);
#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
#if defined(__KERNEL_SSE2__)
Psplat[0] = ssef(P.x);
Psplat[1] = ssef(P.y);
@@ -292,13 +299,40 @@ ccl_device uint BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersectio
nodeAddr = traversalStack[stackPtr];
--stackPtr;
}
-#endif
+#endif /* FEATURE(BVH_INSTANCING) */
} while(nodeAddr != ENTRYPOINT_SENTINEL);
return num_hits;
}
-#undef FEATURE
+ccl_device_inline uint BVH_FUNCTION_NAME(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect_array,
+ int subsurface_object,
+ uint *lcg_state,
+ int max_hits)
+{
+#ifdef __QBVH__
+ if(kernel_data.bvh.use_qbvh) {
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
+ ray,
+ isect_array,
+ subsurface_object,
+ lcg_state,
+ max_hits);
+ }
+ else
+#endif
+ {
+ kernel_assert(kernel_data.bvh.use_qbvh == false);
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg,
+ ray,
+ isect_array,
+ subsurface_object,
+ lcg_state,
+ max_hits);
+ }
+}
+
#undef BVH_FUNCTION_NAME
#undef BVH_FUNCTION_FEATURES
-
diff --git a/intern/cycles/kernel/geom/geom_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h
index 114d30a479d..0298e687de2 100644
--- a/intern/cycles/kernel/geom/geom_bvh_traversal.h
+++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h
@@ -17,6 +17,10 @@
* limitations under the License.
*/
+#ifdef __QBVH__
+#include "geom_qbvh_traversal.h"
+#endif
+
/* This is a template BVH traversal function, where various features can be
* enabled/disabled. This way we can compile optimized versions for each case
* without new features slowing things down.
@@ -28,14 +32,16 @@
*
*/
-#define FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0)
-
-ccl_device bool BVH_FUNCTION_NAME
-(KernelGlobals *kg, const Ray *ray, Intersection *isect, const uint visibility
-#if FEATURE(BVH_HAIR_MINIMUM_WIDTH)
-, uint *lcg_state, float difl, float extmax
+ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect,
+ const uint visibility
+#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ , uint *lcg_state,
+ float difl,
+ float extmax
#endif
-)
+ )
{
/* todo:
* - test if pushing distance on the stack helps (for non shadow rays)
@@ -58,7 +64,7 @@ ccl_device bool BVH_FUNCTION_NAME
float3 idir = bvh_inverse_direction(dir);
int object = OBJECT_NONE;
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
Transform ob_tfm;
#endif
@@ -89,6 +95,9 @@ ccl_device bool BVH_FUNCTION_NAME
gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
+ IsectPrecalc isect_precalc;
+ triangle_intersect_precalc(dir, &isect_precalc);
+
/* traversal loop */
do {
do {
@@ -126,7 +135,7 @@ ccl_device bool BVH_FUNCTION_NAME
NO_EXTENDED_PRECISION float c1min = max4(min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz), 0.0f);
NO_EXTENDED_PRECISION float c1max = min4(max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz), t);
-#if FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
if(difl != 0.0f) {
float hdiff = 1.0f + difl;
float ldiff = 1.0f - difl;
@@ -167,7 +176,7 @@ ccl_device bool BVH_FUNCTION_NAME
ssef minmax = max(max(tminmaxx, tminmaxy), max(tminmaxz, tsplat));
const ssef tminmax = minmax ^ pn;
-#if FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
if(difl != 0.0f) {
float4 *tminmaxview = (float4*)&tminmax;
float &c0min = tminmaxview->x, &c1min = tminmaxview->y;
@@ -217,6 +226,7 @@ ccl_device bool BVH_FUNCTION_NAME
}
++stackPtr;
+ kernel_assert(stackPtr < BVH_STACK_SIZE);
traversalStack[stackPtr] = nodeAddrChild1;
}
else {
@@ -238,80 +248,104 @@ ccl_device bool BVH_FUNCTION_NAME
/* if node is leaf, fetch triangle list */
if(nodeAddr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+(BVH_NODE_SIZE-1));
+ float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+3);
int primAddr = __float_as_int(leaf.x);
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
if(primAddr >= 0) {
#endif
- int primAddr2 = __float_as_int(leaf.y);
+ const int primAddr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
/* pop */
nodeAddr = traversalStack[stackPtr];
--stackPtr;
/* primitive intersection */
- while(primAddr < primAddr2) {
- bool hit;
- uint type = kernel_tex_fetch(__prim_type, primAddr);
-
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- hit = triangle_intersect(kg, isect, P, dir, visibility, object, primAddr);
- break;
- }
-#if FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
- hit = motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, primAddr);
- break;
- }
+ switch(type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ for(; primAddr < primAddr2; primAddr++) {
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps++;
#endif
-#if FEATURE(BVH_HAIR)
- case PRIMITIVE_CURVE:
- case PRIMITIVE_MOTION_CURVE: {
- if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
- hit = bvh_cardinal_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
- else
- hit = bvh_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
- break;
- }
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ if(triangle_intersect(kg, &isect_precalc, isect, P, dir, visibility, object, primAddr)) {
+ /* shadow ray early termination */
+#if defined(__KERNEL_SSE2__)
+ if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ return true;
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+#else
+ if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ return true;
#endif
- default: {
- hit = false;
- break;
+ }
}
+ break;
}
-
+#if BVH_FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ for(; primAddr < primAddr2; primAddr++) {
#if defined(__KERNEL_DEBUG__)
- isect->num_traversal_steps++;
+ isect->num_traversal_steps++;
#endif
-
- /* shadow ray early termination */
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ if(motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, primAddr)) {
+ /* shadow ray early termination */
#if defined(__KERNEL_SSE2__)
- if(hit) {
- if(visibility == PATH_RAY_SHADOW_OPAQUE)
- return true;
-
- tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+ if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ return true;
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+#else
+ if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ return true;
+#endif
+ }
+ }
+ break;
}
+#endif /* BVH_FEATURE(BVH_MOTION) */
+#if BVH_FEATURE(BVH_HAIR)
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ for(; primAddr < primAddr2; primAddr++) {
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps++;
+#endif
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ bool hit;
+ if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
+ hit = bvh_cardinal_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
+ else
+ hit = bvh_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
+ if(hit) {
+ /* shadow ray early termination */
+#if defined(__KERNEL_SSE2__)
+ if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ return true;
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
#else
- if(hit && visibility == PATH_RAY_SHADOW_OPAQUE)
- return true;
+ if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ return true;
#endif
-
- primAddr++;
+ }
+ }
+ break;
+ }
+#endif /* BVH_FEATURE(BVH_HAIR) */
}
}
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
else {
/* instance push */
object = kernel_tex_fetch(__prim_object, -primAddr-1);
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
#if defined(__KERNEL_SSE2__)
Psplat[0] = ssef(P.x);
@@ -324,24 +358,26 @@ ccl_device bool BVH_FUNCTION_NAME
#endif
++stackPtr;
+ kernel_assert(stackPtr < BVH_STACK_SIZE);
traversalStack[stackPtr] = ENTRYPOINT_SENTINEL;
nodeAddr = kernel_tex_fetch(__object_node, object);
}
}
-#endif
+#endif /* FEATURE(BVH_INSTANCING) */
} while(nodeAddr != ENTRYPOINT_SENTINEL);
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
if(stackPtr >= 0) {
kernel_assert(object != OBJECT_NONE);
/* instance pop */
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
#if defined(__KERNEL_SSE2__)
Psplat[0] = ssef(P.x);
@@ -357,13 +393,52 @@ ccl_device bool BVH_FUNCTION_NAME
nodeAddr = traversalStack[stackPtr];
--stackPtr;
}
-#endif
+#endif /* FEATURE(BVH_INSTANCING) */
} while(nodeAddr != ENTRYPOINT_SENTINEL);
return (isect->prim != PRIM_NONE);
}
-#undef FEATURE
+ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect,
+ const uint visibility
+#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ , uint *lcg_state,
+ float difl,
+ float extmax
+#endif
+ )
+{
+#ifdef __QBVH__
+ if(kernel_data.bvh.use_qbvh) {
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
+ ray,
+ isect,
+ visibility
+#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ , lcg_state,
+ difl,
+ extmax
+#endif
+ );
+ }
+ else
+#endif
+ {
+ kernel_assert(kernel_data.bvh.use_qbvh == false);
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg,
+ ray,
+ isect,
+ visibility
+#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ , lcg_state,
+ difl,
+ extmax
+#endif
+ );
+ }
+}
+
#undef BVH_FUNCTION_NAME
#undef BVH_FUNCTION_FEATURES
-
diff --git a/intern/cycles/kernel/geom/geom_bvh_volume.h b/intern/cycles/kernel/geom/geom_bvh_volume.h
index 9dd8d226f5b..0862812a170 100644
--- a/intern/cycles/kernel/geom/geom_bvh_volume.h
+++ b/intern/cycles/kernel/geom/geom_bvh_volume.h
@@ -17,6 +17,10 @@
* limitations under the License.
*/
+#ifdef __QBVH__
+#include "geom_qbvh_volume.h"
+#endif
+
/* This is a template BVH traversal function for volumes, where
* various features can be enabled/disabled. This way we can compile optimized
* versions for each case without new features slowing things down.
@@ -27,11 +31,9 @@
*
*/
-#define FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0)
-
-ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
- const Ray *ray,
- Intersection *isect)
+ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect)
{
/* todo:
* - test if pushing distance on the stack helps (for non shadow rays)
@@ -56,7 +58,7 @@ ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
const uint visibility = PATH_RAY_ALL_VISIBILITY;
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
Transform ob_tfm;
#endif
@@ -83,6 +85,9 @@ ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
#endif
+ IsectPrecalc isect_precalc;
+ triangle_intersect_precalc(dir, &isect_precalc);
+
/* traversal loop */
do {
do {
@@ -121,14 +126,8 @@ ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
NO_EXTENDED_PRECISION float c1max = min4(max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz), t);
/* decide which nodes to traverse next */
-#ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- traverseChild0 = (c0max >= c0min) && (__float_as_uint(cnodes.z) & visibility);
- traverseChild1 = (c1max >= c1min) && (__float_as_uint(cnodes.w) & visibility);
-#else
traverseChild0 = (c0max >= c0min);
traverseChild1 = (c1max >= c1min);
-#endif
#else // __KERNEL_SSE2__
/* Intersect two child bounding boxes, SSE3 version adapted from Embree */
@@ -149,14 +148,8 @@ ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
const sseb lrhit = tminmax <= shuffle<2, 3, 0, 1>(tminmax);
/* decide which nodes to traverse next */
-#ifdef __VISIBILITY_FLAG__
- /* this visibility test gives a 5% performance hit, how to solve? */
- traverseChild0 = (movemask(lrhit) & 1) && (__float_as_uint(cnodes.z) & visibility);
- traverseChild1 = (movemask(lrhit) & 2) && (__float_as_uint(cnodes.w) & visibility);
-#else
traverseChild0 = (movemask(lrhit) & 1);
traverseChild1 = (movemask(lrhit) & 2);
-#endif
#endif // __KERNEL_SSE2__
nodeAddr = __float_as_int(cnodes.x);
@@ -177,6 +170,7 @@ ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
}
++stackPtr;
+ kernel_assert(stackPtr < BVH_STACK_SIZE);
traversalStack[stackPtr] = nodeAddrChild1;
}
else {
@@ -194,59 +188,77 @@ ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
/* if node is leaf, fetch triangle list */
if(nodeAddr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+(BVH_NODE_SIZE-1));
+ float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+3);
int primAddr = __float_as_int(leaf.x);
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
if(primAddr >= 0) {
#endif
- int primAddr2 = __float_as_int(leaf.y);
+ const int primAddr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
/* pop */
nodeAddr = traversalStack[stackPtr];
--stackPtr;
/* primitive intersection */
- for(; primAddr < primAddr2; primAddr++) {
- /* only primitives from volume object */
- uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
- int object_flag = kernel_tex_fetch(__object_flag, tri_object);
-
- if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
- continue;
- }
-
- /* intersect ray against primitive */
- uint type = kernel_tex_fetch(__prim_type, primAddr);
-
- switch(type & PRIMITIVE_ALL) {
- case PRIMITIVE_TRIANGLE: {
- triangle_intersect(kg, isect, P, dir, visibility, object, primAddr);
- break;
+ switch(type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ /* intersect ray against primitive */
+ for(; primAddr < primAddr2; primAddr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ /* only primitives from volume object */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ triangle_intersect(kg, &isect_precalc, isect, P, dir, visibility, object, primAddr);
}
-#if FEATURE(BVH_MOTION)
- case PRIMITIVE_MOTION_TRIANGLE: {
+ break;
+ }
+#if BVH_FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ /* intersect ray against primitive */
+ for(; primAddr < primAddr2; primAddr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ /* only primitives from volume object */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, primAddr);
- break;
}
+ break;
+ }
#endif
-#if FEATURE(BVH_HAIR)
- case PRIMITIVE_CURVE:
- case PRIMITIVE_MOTION_CURVE: {
- if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
+#if BVH_FEATURE(BVH_HAIR)
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ /* intersect ray against primitive */
+ for(; primAddr < primAddr2; primAddr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ /* only primitives from volume object */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
bvh_cardinal_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, NULL, 0, 0);
else
bvh_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, NULL, 0, 0);
- break;
}
+ break;
+ }
#endif
- default: {
- break;
- }
+ default: {
+ break;
}
}
}
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
else {
/* instance push */
object = kernel_tex_fetch(__prim_object, -primAddr-1);
@@ -254,12 +266,14 @@ ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
if(object_flag & SD_OBJECT_HAS_VOLUME) {
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
#else
bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
#if defined(__KERNEL_SSE2__)
Psplat[0] = ssef(P.x);
Psplat[1] = ssef(P.y);
@@ -271,31 +285,35 @@ ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
#endif
++stackPtr;
+ kernel_assert(stackPtr < BVH_STACK_SIZE);
traversalStack[stackPtr] = ENTRYPOINT_SENTINEL;
nodeAddr = kernel_tex_fetch(__object_node, object);
}
else {
/* pop */
+ object = OBJECT_NONE;
nodeAddr = traversalStack[stackPtr];
--stackPtr;
}
}
}
-#endif
+#endif /* FEATURE(BVH_INSTANCING) */
} while(nodeAddr != ENTRYPOINT_SENTINEL);
-#if FEATURE(BVH_INSTANCING)
+#if BVH_FEATURE(BVH_INSTANCING)
if(stackPtr >= 0) {
kernel_assert(object != OBJECT_NONE);
/* instance pop */
-#if FEATURE(BVH_MOTION)
+#if BVH_FEATURE(BVH_MOTION)
bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
#else
bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t);
#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
#if defined(__KERNEL_SSE2__)
Psplat[0] = ssef(P.x);
Psplat[1] = ssef(P.y);
@@ -310,13 +328,31 @@ ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
nodeAddr = traversalStack[stackPtr];
--stackPtr;
}
-#endif
+#endif /* FEATURE(BVH_MOTION) */
} while(nodeAddr != ENTRYPOINT_SENTINEL);
return (isect->prim != PRIM_NONE);
}
-#undef FEATURE
+ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect)
+{
+#ifdef __QBVH__
+ if(kernel_data.bvh.use_qbvh) {
+ return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
+ ray,
+ isect);
+ }
+ else
+#endif
+ {
+ kernel_assert(kernel_data.bvh.use_qbvh == false);
+ return BVH_FUNCTION_FULL_NAME(BVH)(kg,
+ ray,
+ isect);
+ }
+}
+
#undef BVH_FUNCTION_NAME
#undef BVH_FUNCTION_FEATURES
-
diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h
index b6d21c91916..ac6c6ec4929 100644
--- a/intern/cycles/kernel/geom/geom_curve.h
+++ b/intern/cycles/kernel/geom/geom_curve.h
@@ -646,8 +646,8 @@ ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isec
float4 P_curve[2];
if(type & PRIMITIVE_CURVE) {
- P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
- P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
}
else {
int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
@@ -709,7 +709,7 @@ ccl_device_inline bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isec
const ssef sphere_dif1 = (dif + dif_second) * 0.5f;
const ssef dir = load4f(direction);
const ssef sphere_b_tmp = dot3_splat(dir, sphere_dif1);
- const ssef sphere_dif2 = nmsub(sphere_b_tmp, dir, sphere_dif1);
+ const ssef sphere_dif2 = nmadd(sphere_b_tmp, dir, sphere_dif1);
#endif
float mr = max(r1, r2);
diff --git a/intern/cycles/kernel/geom/geom_motion_curve.h b/intern/cycles/kernel/geom/geom_motion_curve.h
index 1022a957b05..6de5aa7ea99 100644
--- a/intern/cycles/kernel/geom/geom_motion_curve.h
+++ b/intern/cycles/kernel/geom/geom_motion_curve.h
@@ -27,17 +27,22 @@ CCL_NAMESPACE_BEGIN
ccl_device_inline int find_attribute_curve_motion(KernelGlobals *kg, int object, uint id, AttributeElement *elem)
{
- /* todo: find a better (faster) solution for this, maybe store offset per object */
+ /* todo: find a better (faster) solution for this, maybe store offset per object.
+ *
+ * NOTE: currently it's not a bottleneck because in test scenes the loop below runs
+ * zero iterations and rendering is really slow with motion curves. For until other
+ * areas are speed up it's probably not so crucial to optimize this out.
+ */
uint attr_offset = object*kernel_data.bvh.attributes_map_stride + ATTR_PRIM_CURVE;
uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-
+
while(attr_map.x != id) {
attr_offset += ATTR_PRIM_TYPES;
attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
}
*elem = (AttributeElement)attr_map.y;
-
+
/* return result */
return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
}
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h b/intern/cycles/kernel/geom/geom_motion_triangle.h
index 3a4b20e61aa..d3297e05c67 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle.h
@@ -130,6 +130,9 @@ ccl_device_inline float3 motion_triangle_refine(KernelGlobals *kg, ShaderData *s
#ifdef __INTERSECTION_REFINE__
if(isect->object != OBJECT_NONE) {
+ if(UNLIKELY(t == 0.0f)) {
+ return P;
+ }
#ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_itfm;
#else
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
index 91edd5863ac..79a56683454 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -391,6 +391,38 @@ ccl_device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ra
*t *= len;
}
+#ifdef __QBVH__
+/* Same as above, but optimized for QBVH scene intersection,
+ * which needs to modify two max distances.
+ *
+ * TODO(sergey): Investigate if passing NULL instead of t1 gets optimized
+ * so we can avoid having this duplication.
+ */
+ccl_device_inline void qbvh_instance_push(KernelGlobals *kg,
+ int object,
+ const Ray *ray,
+ float3 *P,
+ float3 *dir,
+ float3 *idir,
+ float *t,
+ float *t1)
+{
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+
+ *P = transform_point(&tfm, ray->P);
+
+ float len;
+ *dir = bvh_clamp_direction(normalize_len(transform_direction(&tfm, ray->D), &len));
+ *idir = bvh_inverse_direction(*dir);
+
+ if(*t != FLT_MAX)
+ *t *= len;
+
+ if(*t1 != -FLT_MAX)
+ *t1 *= len;
+}
+#endif
+
/* Transorm ray to exit static object in BVH */
ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t)
@@ -436,6 +468,33 @@ ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, c
*t *= len;
}
+#ifdef __QBVH__
+/* Same as above, but optimized for QBVH scene intersection,
+ * which needs to modify two max distances.
+ *
+ * TODO(sergey): Investigate if passing NULL instead of t1 gets optimized
+ * so we can avoid having this duplication.
+ */
+ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t, float *t1, Transform *tfm)
+{
+ Transform itfm;
+ *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm);
+
+ *P = transform_point(&itfm, ray->P);
+
+ float len;
+ *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len));
+ *idir = bvh_inverse_direction(*dir);
+
+
+ if(*t != FLT_MAX)
+ *t *= len;
+
+ if(*t1 != -FLT_MAX)
+ *t1 *= len;
+}
+#endif
+
/* Transorm ray to exit motion blurred object in BVH */
ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t, Transform *tfm)
diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h
index 5df6c75df86..b52ec7ef1b2 100644
--- a/intern/cycles/kernel/geom/geom_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* Primitive Utilities
@@ -144,7 +144,8 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
float3 center;
#ifdef __HAIR__
- if(sd->type & PRIMITIVE_ALL_CURVE) {
+ bool is_curve_primitive = sd->type & PRIMITIVE_ALL_CURVE;
+ if(is_curve_primitive) {
center = curve_motion_center_location(kg, sd);
if(!(sd->flag & SD_TRANSFORM_APPLIED))
@@ -170,6 +171,13 @@ ccl_device float4 primitive_motion_vector(KernelGlobals *kg, ShaderData *sd)
motion_pre = primitive_attribute_float3(kg, sd, elem, offset, NULL, NULL);
motion_post = primitive_attribute_float3(kg, sd, elem, offset_next, NULL, NULL);
+
+#ifdef __HAIR__
+ if(is_curve_primitive && (sd->flag & SD_OBJECT_HAS_VERTEX_MOTION) == 0) {
+ object_position_transform(kg, sd, &motion_pre);
+ object_position_transform(kg, sd, &motion_post);
+ }
+#endif
}
/* object motion. note that depending on the mesh having motion vectors, this
diff --git a/intern/cycles/kernel/geom/geom_qbvh.h b/intern/cycles/kernel/geom/geom_qbvh.h
new file mode 100644
index 00000000000..37deaac0800
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_qbvh.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2011-2014, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+struct QBVHStackItem {
+ int addr;
+ float dist;
+};
+
+/* TOOD(sergey): Investigate if using instrinsics helps for both
+ * stack item swap and float comparison.
+ */
+ccl_device_inline void qbvh_item_swap(QBVHStackItem *__restrict a,
+ QBVHStackItem *__restrict b)
+{
+ QBVHStackItem tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+ccl_device_inline void qbvh_stack_sort(QBVHStackItem *__restrict s1,
+ QBVHStackItem *__restrict s2,
+ QBVHStackItem *__restrict s3)
+{
+ if(s2->dist < s1->dist) { qbvh_item_swap(s2, s1); }
+ if(s3->dist < s2->dist) { qbvh_item_swap(s3, s2); }
+ if(s2->dist < s1->dist) { qbvh_item_swap(s2, s1); }
+}
+
+ccl_device_inline void qbvh_stack_sort(QBVHStackItem *__restrict s1,
+ QBVHStackItem *__restrict s2,
+ QBVHStackItem *__restrict s3,
+ QBVHStackItem *__restrict s4)
+{
+ if(s2->dist < s1->dist) { qbvh_item_swap(s2, s1); }
+ if(s4->dist < s3->dist) { qbvh_item_swap(s4, s3); }
+ if(s3->dist < s1->dist) { qbvh_item_swap(s3, s1); }
+ if(s4->dist < s2->dist) { qbvh_item_swap(s4, s2); }
+ if(s3->dist < s2->dist) { qbvh_item_swap(s3, s2); }
+}
+
+ccl_device_inline int qbvh_node_intersect(KernelGlobals *__restrict kg,
+ const ssef& tnear,
+ const ssef& tfar,
+#ifdef __KERNEL_AVX2__
+ const sse3f& org_idir,
+#else
+ const sse3f& org,
+#endif
+ const sse3f& idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int nodeAddr,
+ ssef *__restrict dist)
+{
+ const int offset = nodeAddr*BVH_QNODE_SIZE;
+#ifdef __KERNEL_AVX2__
+ const ssef tnear_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_x), idir.x, org_idir.x);
+ const ssef tnear_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_y), idir.y, org_idir.y);
+ const ssef tnear_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_z), idir.z, org_idir.z);
+ const ssef tfar_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_x), idir.x, org_idir.x);
+ const ssef tfar_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_y), idir.y, org_idir.y);
+ const ssef tfar_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_z), idir.z, org_idir.z);
+#else
+ const ssef tnear_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_x) - org.x) * idir.x;
+ const ssef tnear_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_y) - org.y) * idir.y;
+ const ssef tnear_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_z) - org.z) * idir.z;
+ const ssef tfar_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_x) - org.x) * idir.x;
+ const ssef tfar_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_y) - org.y) * idir.y;
+ const ssef tfar_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_z) - org.z) * idir.z;
+#endif
+
+#ifdef __KERNEL_SSE41__
+ const ssef tNear = maxi(maxi(tnear_x, tnear_y), maxi(tnear_z, tnear));
+ const ssef tFar = mini(mini(tfar_x, tfar_y), mini(tfar_z, tfar));
+ const sseb vmask = cast(tNear) > cast(tFar);
+ int mask = (int)movemask(vmask)^0xf;
+#else
+ const ssef tNear = max4(tnear_x, tnear_y, tnear_z, tnear);
+ const ssef tFar = min4(tfar_x, tfar_y, tfar_z, tfar);
+ const sseb vmask = tNear <= tFar;
+ int mask = (int)movemask(vmask);
+#endif
+ *dist = tNear;
+ return mask;
+}
+
+ccl_device_inline int qbvh_node_intersect_robust(KernelGlobals *__restrict kg,
+ const ssef& tnear,
+ const ssef& tfar,
+#ifdef __KERNEL_AVX2__
+ const sse3f& P_idir,
+#else
+ const sse3f& P,
+#endif
+ const sse3f& idir,
+ const int near_x,
+ const int near_y,
+ const int near_z,
+ const int far_x,
+ const int far_y,
+ const int far_z,
+ const int nodeAddr,
+ const float difl,
+ ssef *__restrict dist)
+{
+ const int offset = nodeAddr*BVH_QNODE_SIZE;
+#ifdef __KERNEL_AVX2__
+ const ssef tnear_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_x), idir.x, P_idir.x);
+ const ssef tnear_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_y), idir.y, P_idir.y);
+ const ssef tnear_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+near_z), idir.z, P_idir.z);
+ const ssef tfar_x = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_x), idir.x, P_idir.x);
+ const ssef tfar_y = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_y), idir.y, P_idir.y);
+ const ssef tfar_z = msub(kernel_tex_fetch_ssef(__bvh_nodes, offset+far_z), idir.z, P_idir.z);
+#else
+ const ssef tnear_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_x) - P.x) * idir.x;
+ const ssef tnear_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_y) - P.y) * idir.y;
+ const ssef tnear_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset+near_z) - P.z) * idir.z;
+ const ssef tfar_x = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_x) - P.x) * idir.x;
+ const ssef tfar_y = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_y) - P.y) * idir.y;
+ const ssef tfar_z = (kernel_tex_fetch_ssef(__bvh_nodes, offset+far_z) - P.z) * idir.z;
+#endif
+
+ const float round_down = 1.0f - difl;
+ const float round_up = 1.0f + difl;
+ const ssef tNear = max4(tnear_x, tnear_y, tnear_z, tnear);
+ const ssef tFar = min4(tfar_x, tfar_y, tfar_z, tfar);
+ const sseb vmask = round_down*tNear <= round_up*tFar;
+ *dist = tNear;
+ return (int)movemask(vmask);
+}
diff --git a/intern/cycles/kernel/geom/geom_qbvh_shadow.h b/intern/cycles/kernel/geom/geom_qbvh_shadow.h
new file mode 100644
index 00000000000..4233ff15c86
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_qbvh_shadow.h
@@ -0,0 +1,403 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation,
+ * and code copyright 2009-2012 Intel Corporation
+ *
+ * Modifications Copyright 2011-2014, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This is a template BVH traversal function, where various features can be
+ * enabled/disabled. This way we can compile optimized versions for each case
+ * without new features slowing things down.
+ *
+ * BVH_INSTANCING: object instancing
+ * BVH_HAIR: hair curve rendering
+ * BVH_MOTION: motion blur rendering
+ *
+ */
+
+ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect_array,
+ const uint max_hits,
+ uint *num_hits)
+{
+ /* TODO(sergey):
+ * - Likely and unlikely for if() statements.
+ * - Test restrict attribute for pointers.
+ */
+
+ /* Traversal stack in CUDA thread-local memory. */
+ QBVHStackItem traversalStack[BVH_QSTACK_SIZE];
+ traversalStack[0].addr = ENTRYPOINT_SENTINEL;
+
+ /* Traversal variables in registers. */
+ int stackPtr = 0;
+ int nodeAddr = kernel_data.bvh.root;
+
+ /* Ray parameters in registers. */
+ const float tmax = ray->t;
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = tmax;
+
+#if BVH_FEATURE(BVH_MOTION)
+ Transform ob_tfm;
+#endif
+
+#ifndef __KERNEL_SSE41__
+ if(!isfinite(P.x)) {
+ return false;
+ }
+#endif
+
+#if BVH_FEATURE(BVH_INSTANCING)
+ int num_hits_in_instance = 0;
+#endif
+
+ *num_hits = 0;
+ isect_array->t = tmax;
+
+ ssef tnear(0.0f), tfar(tmax);
+ sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+
+#ifdef __KERNEL_AVX2__
+ float3 P_idir = P*idir;
+ sse3f P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ sse3f org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+
+ IsectPrecalc isect_precalc;
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL) {
+ ssef dist;
+ int traverseChild = qbvh_node_intersect(kg,
+ tnear,
+ tfar,
+#ifdef __KERNEL_AVX2__
+ P_idir4,
+#else
+ org,
+#endif
+ idir4,
+ near_x, near_y, near_z,
+ far_x, far_y, far_z,
+ nodeAddr,
+ &dist);
+
+ if(traverseChild != 0) {
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_QNODE_SIZE+6);
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(traverseChild);
+ if(traverseChild == 0) {
+ nodeAddr = __float_as_int(cnodes[r]);
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float*)&dist)[r];
+ r = __bscf(traverseChild);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float*)&dist)[r];
+ if(traverseChild == 0) {
+ if(d1 < d0) {
+ nodeAddr = c1;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c0;
+ traversalStack[stackPtr].dist = d0;
+ continue;
+ }
+ else {
+ nodeAddr = c0;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c1;
+ traversalStack[stackPtr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c1;
+ traversalStack[stackPtr].dist = c1;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c0;
+ traversalStack[stackPtr].dist = c0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(traverseChild);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float*)&dist)[r];
+ if(traverseChild == 0) {
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c2;
+ traversalStack[stackPtr].dist = d2;
+ qbvh_stack_sort(&traversalStack[stackPtr],
+ &traversalStack[stackPtr - 1],
+ &traversalStack[stackPtr - 2]);
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(traverseChild);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float*)&dist)[r];
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c3;
+ traversalStack[stackPtr].dist = d3;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c2;
+ traversalStack[stackPtr].dist = d2;
+ qbvh_stack_sort(&traversalStack[stackPtr],
+ &traversalStack[stackPtr - 1],
+ &traversalStack[stackPtr - 2],
+ &traversalStack[stackPtr - 3]);
+ }
+
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if(nodeAddr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_QNODE_SIZE+6);
+#ifdef __VISIBILITY_FLAG__
+ if((__float_as_uint(leaf.z) & PATH_RAY_SHADOW) == 0) {
+ /* Pop. */
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ continue;
+ }
+#endif
+
+ int primAddr = __float_as_int(leaf.x);
+
+#if BVH_FEATURE(BVH_INSTANCING)
+ if(primAddr >= 0) {
+#endif
+ int primAddr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ const uint p_type = type & PRIMITIVE_ALL;
+
+ /* Pop. */
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+
+ /* Primitive intersection. */
+ while(primAddr < primAddr2) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+
+ bool hit;
+
+ /* todo: specialized intersect functions which don't fill in
+ * isect unless needed and check SD_HAS_TRANSPARENT_SHADOW?
+ * might give a few % performance improvement */
+
+ switch(p_type) {
+ case PRIMITIVE_TRIANGLE: {
+ hit = triangle_intersect(kg, &isect_precalc, isect_array, P, dir, PATH_RAY_SHADOW, object, primAddr);
+ break;
+ }
+#if BVH_FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ hit = motion_triangle_intersect(kg, isect_array, P, dir, ray->time, PATH_RAY_SHADOW, object, primAddr);
+ break;
+ }
+#endif
+#if BVH_FEATURE(BVH_HAIR)
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
+ hit = bvh_cardinal_curve_intersect(kg, isect_array, P, dir, PATH_RAY_SHADOW, object, primAddr, ray->time, type, NULL, 0, 0);
+ else
+ hit = bvh_curve_intersect(kg, isect_array, P, dir, PATH_RAY_SHADOW, object, primAddr, ray->time, type, NULL, 0, 0);
+ break;
+ }
+#endif
+ default: {
+ hit = false;
+ break;
+ }
+ }
+
+ /* Shadow ray early termination. */
+ if(hit) {
+ /* detect if this surface has a shader with transparent shadows */
+
+ /* todo: optimize so primitive visibility flag indicates if
+ * the primitive has a transparent shadow shader? */
+ int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
+ int shader = 0;
+
+#ifdef __HAIR__
+ if(kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
+#endif
+ {
+ shader = kernel_tex_fetch(__tri_shader, prim);
+ }
+#ifdef __HAIR__
+ else {
+ float4 str = kernel_tex_fetch(__curves, prim);
+ shader = __float_as_int(str.z);
+ }
+#endif
+ int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
+
+ /* if no transparent shadows, all light is blocked */
+ if(!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
+ return true;
+ }
+ /* if maximum number of hits reached, block all light */
+ else if(*num_hits == max_hits) {
+ return true;
+ }
+
+ /* move on to next entry in intersections array */
+ isect_array++;
+ (*num_hits)++;
+#if BVH_FEATURE(BVH_INSTANCING)
+ num_hits_in_instance++;
+#endif
+
+ isect_array->t = isect_t;
+ }
+
+ primAddr++;
+ }
+ }
+#if BVH_FEATURE(BVH_INSTANCING)
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -primAddr-1);
+
+#if BVH_FEATURE(BVH_MOTION)
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+#else
+ bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
+#endif
+
+ num_hits_in_instance = 0;
+ isect_array->t = isect_t;
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+ tfar = ssef(isect_t);
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+#ifdef __KERNEL_AVX2__
+ P_idir = P*idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = ENTRYPOINT_SENTINEL;
+
+ nodeAddr = kernel_tex_fetch(__object_node, object);
+
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+#if BVH_FEATURE(BVH_INSTANCING)
+ if(stackPtr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
+
+ if(num_hits_in_instance) {
+ float t_fac;
+
+#if BVH_FEATURE(BVH_MOTION)
+ bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm);
+#else
+ bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac);
+#endif
+
+ /* scale isect->t to adjust for instancing */
+ for(int i = 0; i < num_hits_in_instance; i++)
+ (isect_array-i-1)->t *= t_fac;
+ }
+ else {
+ float ignore_t = FLT_MAX;
+
+#if BVH_FEATURE(BVH_MOTION)
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm);
+#else
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t);
+#endif
+ }
+
+ isect_t = tmax;
+ isect_array->t = isect_t;
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+ tfar = ssef(tmax);
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+#ifdef __KERNEL_AVX2__
+ P_idir = P*idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ object = OBJECT_NONE;
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+ return false;
+}
diff --git a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h
new file mode 100644
index 00000000000..62598115fa3
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h
@@ -0,0 +1,326 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation,
+ * and code copyright 2009-2012 Intel Corporation
+ *
+ * Modifications Copyright 2011-2014, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This is a template BVH traversal function for subsurface scattering, where
+ * various features can be enabled/disabled. This way we can compile optimized
+ * versions for each case without new features slowing things down.
+ *
+ * BVH_INSTANCING: object instancing
+ * BVH_MOTION: motion blur rendering
+ *
+ */
+
+ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect_array,
+ int subsurface_object,
+ uint *lcg_state,
+ int max_hits)
+{
+ /* TODO(sergey):
+ * - Test if pushing distance on the stack helps (for non shadow rays).
+ * - Separate version for shadow rays.
+ * - Likely and unlikely for if() statements.
+ * - SSE for hair.
+ * - Test restrict attribute for pointers.
+ */
+
+ /* Traversal stack in CUDA thread-local memory. */
+ QBVHStackItem traversalStack[BVH_QSTACK_SIZE];
+ traversalStack[0].addr = ENTRYPOINT_SENTINEL;
+
+ /* Traversal variables in registers. */
+ int stackPtr = 0;
+ int nodeAddr = kernel_data.bvh.root;
+
+ /* Ray parameters in registers. */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+ float isect_t = ray->t;
+ uint num_hits = 0;
+
+#if BVH_FEATURE(BVH_MOTION)
+ Transform ob_tfm;
+#endif
+
+#ifndef __KERNEL_SSE41__
+ if(!isfinite(P.x)) {
+ return 0;
+ }
+#endif
+
+ ssef tnear(0.0f), tfar(isect_t);
+ sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+
+#ifdef __KERNEL_AVX2__
+ float3 P_idir = P*idir;
+ sse3f P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ sse3f org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+
+ IsectPrecalc isect_precalc;
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL) {
+ ssef dist;
+ int traverseChild = qbvh_node_intersect(kg,
+ tnear,
+ tfar,
+#ifdef __KERNEL_AVX2__
+ P_idir4,
+#else
+ org,
+#endif
+ idir4,
+ near_x, near_y, near_z,
+ far_x, far_y, far_z,
+ nodeAddr,
+ &dist);
+
+ if(traverseChild != 0) {
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_QNODE_SIZE+6);
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(traverseChild);
+ if(traverseChild == 0) {
+ nodeAddr = __float_as_int(cnodes[r]);
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float*)&dist)[r];
+ r = __bscf(traverseChild);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float*)&dist)[r];
+ if(traverseChild == 0) {
+ if(d1 < d0) {
+ nodeAddr = c1;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c0;
+ traversalStack[stackPtr].dist = d0;
+ continue;
+ }
+ else {
+ nodeAddr = c0;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c1;
+ traversalStack[stackPtr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c1;
+ traversalStack[stackPtr].dist = d1;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c0;
+ traversalStack[stackPtr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(traverseChild);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float*)&dist)[r];
+ if(traverseChild == 0) {
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c2;
+ traversalStack[stackPtr].dist = d2;
+ qbvh_stack_sort(&traversalStack[stackPtr],
+ &traversalStack[stackPtr - 1],
+ &traversalStack[stackPtr - 2]);
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(traverseChild);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float*)&dist)[r];
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c3;
+ traversalStack[stackPtr].dist = d3;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c2;
+ traversalStack[stackPtr].dist = d2;
+ qbvh_stack_sort(&traversalStack[stackPtr],
+ &traversalStack[stackPtr - 1],
+ &traversalStack[stackPtr - 2],
+ &traversalStack[stackPtr - 3]);
+ }
+
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if(nodeAddr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_QNODE_SIZE+6);
+ int primAddr = __float_as_int(leaf.x);
+
+#if BVH_FEATURE(BVH_INSTANCING)
+ if(primAddr >= 0) {
+#endif
+ int primAddr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+
+ /* Pop. */
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+
+ /* Primitive intersection. */
+ switch(type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ /* Intersect ray against primitive, */
+ for(; primAddr < primAddr2; primAddr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ /* Only primitives from the same object. */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ if(tri_object != subsurface_object) {
+ continue;
+ }
+ triangle_intersect_subsurface(kg, &isect_precalc, isect_array, P, dir, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
+ }
+ break;
+ }
+#if BVH_FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ /* Intersect ray against primitive. */
+ for(; primAddr < primAddr2; primAddr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ /* Only primitives from the same object. */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ if(tri_object != subsurface_object) {
+ continue;
+ }
+ motion_triangle_intersect_subsurface(kg, isect_array, P, dir, ray->time, object, primAddr, isect_t, &num_hits, lcg_state, max_hits);
+ }
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+ }
+#if BVH_FEATURE(BVH_INSTANCING)
+ else {
+ /* Instance push. */
+ if(subsurface_object == kernel_tex_fetch(__prim_object, -primAddr-1)) {
+ object = subsurface_object;
+
+#if BVH_FEATURE(BVH_MOTION)
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+#else
+ bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t);
+#endif
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+ tfar = ssef(isect_t);
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+#ifdef __KERNEL_AVX2__
+ P_idir = P*idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = ENTRYPOINT_SENTINEL;
+
+ nodeAddr = kernel_tex_fetch(__object_node, object);
+ }
+ else {
+ /* Pop. */
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ }
+
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+#if BVH_FEATURE(BVH_INSTANCING)
+ if(stackPtr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
+
+ /* Instance pop. */
+#if BVH_FEATURE(BVH_MOTION)
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm);
+#else
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t);
+#endif
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+ tfar = ssef(isect_t);
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+#ifdef __KERNEL_AVX2__
+ P_idir = P*idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ object = OBJECT_NONE;
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+ return num_hits;
+}
diff --git a/intern/cycles/kernel/geom/geom_qbvh_traversal.h b/intern/cycles/kernel/geom/geom_qbvh_traversal.h
new file mode 100644
index 00000000000..99d2fb20837
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_qbvh_traversal.h
@@ -0,0 +1,418 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation,
+ * and code copyright 2009-2012 Intel Corporation
+ *
+ * Modifications Copyright 2011-2014, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This is a template BVH traversal function, where various features can be
+ * enabled/disabled. This way we can compile optimized versions for each case
+ * without new features slowing things down.
+ *
+ * BVH_INSTANCING: object instancing
+ * BVH_HAIR: hair curve rendering
+ * BVH_HAIR_MINIMUM_WIDTH: hair curve rendering with minimum width
+ * BVH_MOTION: motion blur rendering
+ *
+ */
+
+ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect,
+ const uint visibility
+#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ ,uint *lcg_state,
+ float difl,
+ float extmax
+#endif
+ )
+{
+ /* TODO(sergey):
+ * - Test if pushing distance on the stack helps (for non shadow rays).
+ * - Separate version for shadow rays.
+ * - Likely and unlikely for if() statements.
+ * - Test restrict attribute for pointers.
+ */
+
+ /* Traversal stack in CUDA thread-local memory. */
+ QBVHStackItem traversalStack[BVH_QSTACK_SIZE];
+ traversalStack[0].addr = ENTRYPOINT_SENTINEL;
+ traversalStack[0].dist = -FLT_MAX;
+
+ /* Traversal variables in registers. */
+ int stackPtr = 0;
+ int nodeAddr = kernel_data.bvh.root;
+ float nodeDist = -FLT_MAX;
+
+ /* Ray parameters in registers. */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+
+#if BVH_FEATURE(BVH_MOTION)
+ Transform ob_tfm;
+#endif
+
+#ifndef __KERNEL_SSE41__
+ if(!isfinite(P.x)) {
+ return false;
+ }
+#endif
+
+ isect->t = ray->t;
+ isect->u = 0.0f;
+ isect->v = 0.0f;
+ isect->prim = PRIM_NONE;
+ isect->object = OBJECT_NONE;
+
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps = 0;
+#endif
+
+ ssef tnear(0.0f), tfar(ray->t);
+ sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+
+#ifdef __KERNEL_AVX2__
+ float3 P_idir = P*idir;
+ sse3f P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ sse3f org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+
+ IsectPrecalc isect_precalc;
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL) {
+ if(UNLIKELY(nodeDist > isect->t)) {
+ /* Pop. */
+ nodeAddr = traversalStack[stackPtr].addr;
+ nodeDist = traversalStack[stackPtr].dist;
+ --stackPtr;
+ continue;
+ }
+
+ int traverseChild;
+ ssef dist;
+
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps++;
+#endif
+
+#if BVH_FEATURE(BVH_HAIR_MINIMUM_WIDTH)
+ if(difl != 0.0f) {
+ /* NOTE: We extend all the child BB instead of fetching
+ * and checking visibility flags for each of the,
+ *
+ * Need to test if doing opposite would be any faster.
+ */
+ traverseChild = qbvh_node_intersect_robust(kg,
+ tnear,
+ tfar,
+#ifdef __KERNEL_AVX2__
+ P_idir4,
+#else
+ org,
+#endif
+ idir4,
+ near_x, near_y, near_z,
+ far_x, far_y, far_z,
+ nodeAddr,
+ difl,
+ &dist);
+ }
+ else
+#endif
+ {
+ traverseChild = qbvh_node_intersect(kg,
+ tnear,
+ tfar,
+#ifdef __KERNEL_AVX2__
+ P_idir4,
+#else
+ org,
+#endif
+ idir4,
+ near_x, near_y, near_z,
+ far_x, far_y, far_z,
+ nodeAddr,
+ &dist);
+ }
+
+ if(traverseChild != 0) {
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_QNODE_SIZE+6);
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(traverseChild);
+ float d0 = ((float*)&dist)[r];
+ if(traverseChild == 0) {
+ nodeAddr = __float_as_int(cnodes[r]);
+ nodeDist = d0;
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ r = __bscf(traverseChild);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float*)&dist)[r];
+ if(traverseChild == 0) {
+ if(d1 < d0) {
+ nodeAddr = c1;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c0;
+ traversalStack[stackPtr].dist = d0;
+ continue;
+ }
+ else {
+ nodeAddr = c0;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c1;
+ traversalStack[stackPtr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c1;
+ traversalStack[stackPtr].dist = d1;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c0;
+ traversalStack[stackPtr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(traverseChild);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float*)&dist)[r];
+ if(traverseChild == 0) {
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c2;
+ traversalStack[stackPtr].dist = d2;
+ qbvh_stack_sort(&traversalStack[stackPtr],
+ &traversalStack[stackPtr - 1],
+ &traversalStack[stackPtr - 2]);
+ nodeAddr = traversalStack[stackPtr].addr;
+ nodeDist = traversalStack[stackPtr].dist;
+ --stackPtr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(traverseChild);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float*)&dist)[r];
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c3;
+ traversalStack[stackPtr].dist = d3;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c2;
+ traversalStack[stackPtr].dist = d2;
+ qbvh_stack_sort(&traversalStack[stackPtr],
+ &traversalStack[stackPtr - 1],
+ &traversalStack[stackPtr - 2],
+ &traversalStack[stackPtr - 3]);
+ }
+
+ nodeAddr = traversalStack[stackPtr].addr;
+ nodeDist = traversalStack[stackPtr].dist;
+ --stackPtr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if(nodeAddr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_QNODE_SIZE+6);
+
+#ifdef __VISIBILITY_FLAG__
+ if(UNLIKELY((nodeDist > isect->t) || ((__float_as_uint(leaf.z) & visibility) == 0)))
+#else
+ if(UNLIKELY((nodeDist > isect->t)))
+#endif
+ {
+ /* Pop. */
+ nodeAddr = traversalStack[stackPtr].addr;
+ nodeDist = traversalStack[stackPtr].dist;
+ --stackPtr;
+ continue;
+ }
+
+ int primAddr = __float_as_int(leaf.x);
+
+#if BVH_FEATURE(BVH_INSTANCING)
+ if(primAddr >= 0) {
+#endif
+ int primAddr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+
+ /* Pop. */
+ nodeAddr = traversalStack[stackPtr].addr;
+ nodeDist = traversalStack[stackPtr].dist;
+ --stackPtr;
+
+ /* Primitive intersection. */
+ switch(type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ for(; primAddr < primAddr2; primAddr++) {
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps++;
+#endif
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ if(triangle_intersect(kg, &isect_precalc, isect, P, dir, visibility, object, primAddr)) {
+ tfar = ssef(isect->t);
+ /* Shadow ray early termination. */
+ if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ return true;
+ }
+ }
+ break;
+ }
+#if BVH_FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ for(; primAddr < primAddr2; primAddr++) {
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps++;
+#endif
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ if(motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, primAddr)) {
+ tfar = ssef(isect->t);
+ /* Shadow ray early termination. */
+ if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ return true;
+ }
+ }
+ break;
+ }
+#endif /* BVH_FEATURE(BVH_MOTION) */
+#if BVH_FEATURE(BVH_HAIR)
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ for(; primAddr < primAddr2; primAddr++) {
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps++;
+#endif
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ bool hit;
+ if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
+ hit = bvh_cardinal_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
+ else
+ hit = bvh_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, lcg_state, difl, extmax);
+ if(hit) {
+ tfar = ssef(isect->t);
+ /* Shadow ray early termination. */
+ if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ return true;
+ }
+ }
+ break;
+ }
+#endif /* BVH_FEATURE(BVH_HAIR) */
+ }
+ }
+#if BVH_FEATURE(BVH_INSTANCING)
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -primAddr-1);
+
+#if BVH_FEATURE(BVH_MOTION)
+ qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist, &ob_tfm);
+#else
+ qbvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist);
+#endif
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+ tfar = ssef(isect->t);
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+#ifdef __KERNEL_AVX2__
+ P_idir = P*idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = ENTRYPOINT_SENTINEL;
+ traversalStack[stackPtr].dist = -FLT_MAX;
+
+ nodeAddr = kernel_tex_fetch(__object_node, object);
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+#if BVH_FEATURE(BVH_INSTANCING)
+ if(stackPtr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
+
+ /* Instance pop. */
+#if BVH_FEATURE(BVH_MOTION)
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+#else
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t);
+#endif
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+ tfar = ssef(isect->t);
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+#ifdef __KERNEL_AVX2__
+ P_idir = P*idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ object = OBJECT_NONE;
+ nodeAddr = traversalStack[stackPtr].addr;
+ nodeDist = traversalStack[stackPtr].dist;
+ --stackPtr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+ return (isect->prim != PRIM_NONE);
+}
diff --git a/intern/cycles/kernel/geom/geom_qbvh_volume.h b/intern/cycles/kernel/geom/geom_qbvh_volume.h
new file mode 100644
index 00000000000..2c396e99fc4
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_qbvh_volume.h
@@ -0,0 +1,355 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation,
+ * and code copyright 2009-2012 Intel Corporation
+ *
+ * Modifications Copyright 2011-2014, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This is a template BVH traversal function for volumes, where
+ * various features can be enabled/disabled. This way we can compile optimized
+ * versions for each case without new features slowing things down.
+ *
+ * BVH_INSTANCING: object instancing
+ * BVH_HAIR: hair curve rendering
+ * BVH_MOTION: motion blur rendering
+ *
+ */
+
+ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect)
+{
+ /* TODO(sergey):
+ * - Test if pushing distance on the stack helps.
+ * - Likely and unlikely for if() statements.
+ * - Test restrict attribute for pointers.
+ */
+
+ /* Traversal stack in CUDA thread-local memory. */
+ QBVHStackItem traversalStack[BVH_QSTACK_SIZE];
+ traversalStack[0].addr = ENTRYPOINT_SENTINEL;
+
+ /* Traversal variables in registers. */
+ int stackPtr = 0;
+ int nodeAddr = kernel_data.bvh.root;
+
+ /* Ray parameters in registers. */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+
+ const uint visibility = PATH_RAY_ALL_VISIBILITY;
+
+#if BVH_FEATURE(BVH_MOTION)
+ Transform ob_tfm;
+#endif
+
+#ifndef __KERNEL_SSE41__
+ if(!isfinite(P.x)) {
+ return false;
+ }
+#endif
+
+ isect->t = ray->t;
+ isect->u = 0.0f;
+ isect->v = 0.0f;
+ isect->prim = PRIM_NONE;
+ isect->object = OBJECT_NONE;
+
+ ssef tnear(0.0f), tfar(ray->t);
+ sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+
+#ifdef __KERNEL_AVX2__
+ float3 P_idir = P*idir;
+ sse3f P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ sse3f org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+
+ /* Offsets to select the side that becomes the lower or upper bound. */
+ int near_x, near_y, near_z;
+ int far_x, far_y, far_z;
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+
+ IsectPrecalc isect_precalc;
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ /* Traversal loop. */
+ do {
+ do {
+ /* Traverse internal nodes. */
+ while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL) {
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps++;
+#endif
+
+ ssef dist;
+ int traverseChild = qbvh_node_intersect(kg,
+ tnear,
+ tfar,
+#ifdef __KERNEL_AVX2__
+ P_idir4,
+#else
+ org,
+#endif
+ idir4,
+ near_x, near_y, near_z,
+ far_x, far_y, far_z,
+ nodeAddr,
+ &dist);
+
+ if(traverseChild != 0) {
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_QNODE_SIZE+6);
+
+ /* One child is hit, continue with that child. */
+ int r = __bscf(traverseChild);
+ if(traverseChild == 0) {
+ nodeAddr = __float_as_int(cnodes[r]);
+ continue;
+ }
+
+ /* Two children are hit, push far child, and continue with
+ * closer child.
+ */
+ int c0 = __float_as_int(cnodes[r]);
+ float d0 = ((float*)&dist)[r];
+ r = __bscf(traverseChild);
+ int c1 = __float_as_int(cnodes[r]);
+ float d1 = ((float*)&dist)[r];
+ if(traverseChild == 0) {
+ if(d1 < d0) {
+ nodeAddr = c1;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c0;
+ traversalStack[stackPtr].dist = d0;
+ continue;
+ }
+ else {
+ nodeAddr = c0;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c1;
+ traversalStack[stackPtr].dist = d1;
+ continue;
+ }
+ }
+
+ /* Here starts the slow path for 3 or 4 hit children. We push
+ * all nodes onto the stack to sort them there.
+ */
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c1;
+ traversalStack[stackPtr].dist = d1;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c0;
+ traversalStack[stackPtr].dist = d0;
+
+ /* Three children are hit, push all onto stack and sort 3
+ * stack items, continue with closest child.
+ */
+ r = __bscf(traverseChild);
+ int c2 = __float_as_int(cnodes[r]);
+ float d2 = ((float*)&dist)[r];
+ if(traverseChild == 0) {
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c2;
+ traversalStack[stackPtr].dist = d2;
+ qbvh_stack_sort(&traversalStack[stackPtr],
+ &traversalStack[stackPtr - 1],
+ &traversalStack[stackPtr - 2]);
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ continue;
+ }
+
+ /* Four children are hit, push all onto stack and sort 4
+ * stack items, continue with closest child.
+ */
+ r = __bscf(traverseChild);
+ int c3 = __float_as_int(cnodes[r]);
+ float d3 = ((float*)&dist)[r];
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c3;
+ traversalStack[stackPtr].dist = d3;
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = c2;
+ traversalStack[stackPtr].dist = d2;
+ qbvh_stack_sort(&traversalStack[stackPtr],
+ &traversalStack[stackPtr - 1],
+ &traversalStack[stackPtr - 2],
+ &traversalStack[stackPtr - 3]);
+ }
+
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ }
+
+ /* If node is leaf, fetch triangle list. */
+ if(nodeAddr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_QNODE_SIZE+6);
+ int primAddr = __float_as_int(leaf.x);
+
+#if BVH_FEATURE(BVH_INSTANCING)
+ if(primAddr >= 0) {
+#endif
+ int primAddr2 = __float_as_int(leaf.y);
+ const uint type = __float_as_int(leaf.w);
+ const uint p_type = type & PRIMITIVE_ALL;
+
+ /* Pop. */
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+
+ /* Primitive intersection. */
+ switch(p_type) {
+ case PRIMITIVE_TRIANGLE: {
+ for(; primAddr < primAddr2; primAddr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ triangle_intersect(kg, &isect_precalc, isect, P, dir, visibility, object, primAddr);
+ }
+ break;
+ }
+#if BVH_FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ for(; primAddr < primAddr2; primAddr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, primAddr);
+ }
+ break;
+ }
+#endif
+#if BVH_FEATURE(BVH_HAIR)
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ for(; primAddr < primAddr2; primAddr++) {
+ kernel_assert(kernel_tex_fetch(__prim_type, primAddr) == type);
+ /* Only primitives from volume object. */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+ if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+ /* Intersect ray against primitive. */
+ if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
+ bvh_cardinal_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, NULL, 0, 0);
+ else
+ bvh_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, NULL, 0, 0);
+ }
+ break;
+ }
+#endif
+ }
+ }
+#if BVH_FEATURE(BVH_INSTANCING)
+ else {
+ /* Instance push. */
+ object = kernel_tex_fetch(__prim_object, -primAddr-1);
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+
+ if(object_flag & SD_OBJECT_HAS_VOLUME) {
+
+#if BVH_FEATURE(BVH_MOTION)
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+#else
+ bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t);
+#endif
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+ tfar = ssef(isect->t);
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+#ifdef __KERNEL_AVX2__
+ P_idir = P*idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ ++stackPtr;
+ kernel_assert(stackPtr < BVH_QSTACK_SIZE);
+ traversalStack[stackPtr].addr = ENTRYPOINT_SENTINEL;
+
+ nodeAddr = kernel_tex_fetch(__object_node, object);
+ }
+ else {
+ /* Pop. */
+ object = OBJECT_NONE;
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ }
+ }
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+#if BVH_FEATURE(BVH_INSTANCING)
+ if(stackPtr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
+
+ /* Instance pop. */
+#if BVH_FEATURE(BVH_MOTION)
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+#else
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t);
+#endif
+
+ if(idir.x >= 0.0f) { near_x = 0; far_x = 1; } else { near_x = 1; far_x = 0; }
+ if(idir.y >= 0.0f) { near_y = 2; far_y = 3; } else { near_y = 3; far_y = 2; }
+ if(idir.z >= 0.0f) { near_z = 4; far_z = 5; } else { near_z = 5; far_z = 4; }
+ tfar = ssef(isect->t);
+ idir4 = sse3f(ssef(idir.x), ssef(idir.y), ssef(idir.z));
+#ifdef __KERNEL_AVX2__
+ P_idir = P*idir;
+ P_idir4 = sse3f(P_idir.x, P_idir.y, P_idir.z);
+#else
+ org = sse3f(ssef(P.x), ssef(P.y), ssef(P.z));
+#endif
+ triangle_intersect_precalc(dir, &isect_precalc);
+
+ object = OBJECT_NONE;
+ nodeAddr = traversalStack[stackPtr].addr;
+ --stackPtr;
+ }
+#endif /* FEATURE(BVH_INSTANCING) */
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+ return (isect->prim != PRIM_NONE);
+}
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h
index c08a82ee038..dd3928682e3 100644
--- a/intern/cycles/kernel/geom/geom_triangle.h
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -23,99 +23,6 @@
CCL_NAMESPACE_BEGIN
-/* Refine triangle intersection to more precise hit point. For rays that travel
- * far the precision is often not so good, this reintersects the primitive from
- * a closer distance. */
-
-ccl_device_inline float3 triangle_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
-{
- float3 P = ray->P;
- float3 D = ray->D;
- float t = isect->t;
-
-#ifdef __INTERSECTION_REFINE__
- if(isect->object != OBJECT_NONE) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D*t);
- D = normalize_len(D, &t);
- }
-
- P = P + D*t;
-
- float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0);
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z);
- float rt = Oz * invDz;
-
- P = P + D*rt;
-
- if(isect->object != OBJECT_NONE) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- }
-
- return P;
-#else
- return P + D*t;
-#endif
-}
-
-/* same as above, except that isect->t is assumed to be in object space for instancing */
-ccl_device_inline float3 triangle_refine_subsurface(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
-{
- float3 P = ray->P;
- float3 D = ray->D;
- float t = isect->t;
-
-#ifdef __INTERSECTION_REFINE__
- if(isect->object != OBJECT_NONE) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D);
- D = normalize(D);
- }
-
- P = P + D*t;
-
- float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0);
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z);
- float rt = Oz * invDz;
-
- P = P + D*rt;
-
- if(isect->object != OBJECT_NONE) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- }
-
- return P;
-#else
- return P + D*t;
-#endif
-}
-
/* normal on triangle */
ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd)
{
@@ -298,116 +205,4 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData
}
}
-/* Ray-Triangle intersection for BVH traversal
- *
- * Based on Sven Woop's algorithm with precomputed triangle storage */
-
-ccl_device_inline bool triangle_intersect(KernelGlobals *kg, Intersection *isect,
- float3 P, float3 dir, uint visibility, int object, int triAddr)
-{
- /* compute and check intersection t-value */
- float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0);
- float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1);
-
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z);
- float t = Oz * invDz;
-
- if(t > 0.0f && t < isect->t) {
- /* compute and check barycentric u */
- float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z;
- float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z;
- float u = Ox + t*Dx;
-
- if(u >= 0.0f) {
- /* compute and check barycentric v */
- float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2);
- float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z;
- float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z;
- float v = Oy + t*Dy;
-
- if(v >= 0.0f && u + v <= 1.0f) {
-#ifdef __VISIBILITY_FLAG__
- /* visibility flag test. we do it here under the assumption
- * that most triangles are culled by node flags */
- if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility)
-#endif
- {
- /* record intersection */
- isect->t = t;
- isect->u = u;
- isect->v = v;
- isect->prim = triAddr;
- isect->object = object;
- isect->type = PRIMITIVE_TRIANGLE;
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-/* Special ray intersection routines for subsurface scattering. In that case we
- * only want to intersect with primitives in the same object, and if case of
- * multiple hits we pick a single random primitive as the intersection point. */
-
-#ifdef __SUBSURFACE__
-ccl_device_inline void triangle_intersect_subsurface(KernelGlobals *kg, Intersection *isect_array,
- float3 P, float3 dir, int object, int triAddr, float tmax, uint *num_hits, uint *lcg_state, int max_hits)
-{
- /* compute and check intersection t-value */
- float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0);
- float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1);
-
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z);
- float t = Oz * invDz;
-
- if(t > 0.0f && t < tmax) {
- /* compute and check barycentric u */
- float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z;
- float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z;
- float u = Ox + t*Dx;
-
- if(u >= 0.0f) {
- /* compute and check barycentric v */
- float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2);
- float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z;
- float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z;
- float v = Oy + t*Dy;
-
- if(v >= 0.0f && u + v <= 1.0f) {
- (*num_hits)++;
-
- int hit;
-
- if(*num_hits <= max_hits) {
- hit = *num_hits - 1;
- }
- else {
- /* reservoir sampling: if we are at the maximum number of
- * hits, randomly replace element or skip it */
- hit = lcg_step_uint(lcg_state) % *num_hits;
-
- if(hit >= max_hits)
- return;
- }
-
- /* record intersection */
- Intersection *isect = &isect_array[hit];
- isect->t = t;
- isect->u = u;
- isect->v = v;
- isect->prim = triAddr;
- isect->object = object;
- isect->type = PRIMITIVE_TRIANGLE;
- }
- }
- }
-}
-#endif
-
CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
new file mode 100644
index 00000000000..c9e30a451da
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -0,0 +1,423 @@
+/*
+ * Copyright 2014, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Triangle/Ray intersections .
+ *
+ * For BVH ray intersection we use a precomputed triangle storage to accelerate
+ * intersection at the cost of more memory usage.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+/* Workaround stupidness of CUDA/OpenCL which doesn't allow to access indexed
+ * component of float3 value.
+ */
+#ifndef __KERNEL_CPU__
+# define IDX(vec, idx) \
+ ((idx == 0) ? ((vec).x) : ( (idx == 1) ? ((vec).y) : ((vec).z) ))
+#else
+# define IDX(vec, idx) ((vec)[idx])
+#endif
+
+/* Ray-Triangle intersection for BVH traversal
+ *
+ * Sven Woop
+ * Watertight Ray/Triangle Intersection
+ *
+ * http://jcgt.org/published/0002/01/05/paper.pdf
+ */
+
+/* Precalculated data for the ray->tri intersection. */
+typedef struct IsectPrecalc {
+ /* Maximal dimension kz, and orthogonal dimensions. */
+ int kx, ky, kz;
+
+ /* Shear constants. */
+ float Sx, Sy, Sz;
+} IsectPrecalc;
+
+/* Workaround for CUDA toolkit 6.5.16. */
+#if defined(__KERNEL_CPU__) || !defined(__KERNEL_CUDA_EXPERIMENTAL__) || __CUDA_ARCH__ < 500
+# if (defined(i386) || defined(_M_IX86))
+ccl_device_noinline
+# else
+ccl_device_inline
+# endif
+#else
+ccl_device_noinline
+#endif
+void triangle_intersect_precalc(float3 dir,
+ IsectPrecalc *isect_precalc)
+{
+ /* Calculate dimension where the ray direction is maximal. */
+ int kz = util_max_axis(make_float3(fabsf(dir.x),
+ fabsf(dir.y),
+ fabsf(dir.z)));
+ int kx = kz + 1; if(kx == 3) kx = 0;
+ int ky = kx + 1; if(ky == 3) ky = 0;
+
+ /* Swap kx and ky dimensions to preserve winding direction of triangles. */
+ if(IDX(dir, kz) < 0.0f) {
+ int tmp = kx;
+ kx = ky;
+ ky = tmp;
+ }
+
+ /* Calculate the shear constants. */
+ float inf_dir_z = 1.0f / IDX(dir, kz);
+ isect_precalc->Sx = IDX(dir, kx) * inf_dir_z;
+ isect_precalc->Sy = IDX(dir, ky) * inf_dir_z;
+ isect_precalc->Sz = inf_dir_z;
+
+ /* Store the dimensions. */
+ isect_precalc->kx = kx;
+ isect_precalc->ky = ky;
+ isect_precalc->kz = kz;
+}
+
+/* TODO(sergey): Make it general utility function. */
+ccl_device_inline float xor_signmast(float x, int y)
+{
+ return __int_as_float(__float_as_int(x) ^ y);
+}
+
+ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
+ const IsectPrecalc *isect_precalc,
+ Intersection *isect,
+ float3 P,
+ float3 dir,
+ uint visibility,
+ int object,
+ int triAddr)
+{
+ const int kx = isect_precalc->kx;
+ const int ky = isect_precalc->ky;
+ const int kz = isect_precalc->kz;
+ const float Sx = isect_precalc->Sx;
+ const float Sy = isect_precalc->Sy;
+ const float Sz = isect_precalc->Sz;
+
+ /* Calculate vertices relative to ray origin. */
+ float3 tri[3];
+ tri[0] = float4_to_float3(kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0));
+ tri[1] = float4_to_float3(kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1));
+ tri[2] = float4_to_float3(kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2));
+
+ const float3 A = tri[0] - P;
+ const float3 B = tri[1] - P;
+ const float3 C = tri[2] - P;
+
+ const float A_kx = IDX(A, kx), A_ky = IDX(A, ky), A_kz = IDX(A, kz);
+ const float B_kx = IDX(B, kx), B_ky = IDX(B, ky), B_kz = IDX(B, kz);
+ const float C_kx = IDX(C, kx), C_ky = IDX(C, ky), C_kz = IDX(C, kz);
+
+ /* Perform shear and scale of vertices. */
+ const float Ax = A_kx - Sx * A_kz;
+ const float Ay = A_ky - Sy * A_kz;
+ const float Bx = B_kx - Sx * B_kz;
+ const float By = B_ky - Sy * B_kz;
+ const float Cx = C_kx - Sx * C_kz;
+ const float Cy = C_ky - Sy * C_kz;
+
+ /* Calculate scaled barycentric coordinates. */
+ float U = Cx * By - Cy * Bx;
+ int sign_mask = (__float_as_int(U) & 0x80000000);
+ float V = Ax * Cy - Ay * Cx;
+ if(sign_mask != (__float_as_int(V) & 0x80000000)) {
+ return false;
+ }
+ float W = Bx * Ay - By * Ax;
+ if(sign_mask != (__float_as_int(W) & 0x80000000)) {
+ return false;
+ }
+
+ /* Calculate determinant. */
+ float det = U + V + W;
+ if(UNLIKELY(det == 0.0f)) {
+ return false;
+ }
+
+ /* Calculate scaled z−coordinates of vertices and use them to calculate
+ * the hit distance.
+ */
+ const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz;
+ const float sign_T = xor_signmast(T, sign_mask);
+ if ((sign_T < 0.0f) ||
+ (sign_T > isect->t * xor_signmast(det, sign_mask)))
+ {
+ return false;
+ }
+
+#ifdef __VISIBILITY_FLAG__
+ /* visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags */
+ if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility)
+#endif
+ {
+ /* Normalize U, V, W, and T. */
+ const float inv_det = 1.0f / det;
+ isect->prim = triAddr;
+ isect->object = object;
+ isect->type = PRIMITIVE_TRIANGLE;
+ isect->u = U * inv_det;
+ isect->v = V * inv_det;
+ isect->t = T * inv_det;
+ return true;
+ }
+ return false;
+}
+
+/* Special ray intersection routines for subsurface scattering. In that case we
+ * only want to intersect with primitives in the same object, and if case of
+ * multiple hits we pick a single random primitive as the intersection point.
+ */
+
+#ifdef __SUBSURFACE__
+ccl_device_inline void triangle_intersect_subsurface(
+ KernelGlobals *kg,
+ const IsectPrecalc *isect_precalc,
+ Intersection *isect_array,
+ float3 P,
+ float3 dir,
+ int object,
+ int triAddr,
+ float tmax,
+ uint *num_hits,
+ uint *lcg_state,
+ int max_hits)
+{
+ const int kx = isect_precalc->kx;
+ const int ky = isect_precalc->ky;
+ const int kz = isect_precalc->kz;
+ const float Sx = isect_precalc->Sx;
+ const float Sy = isect_precalc->Sy;
+ const float Sz = isect_precalc->Sz;
+
+ /* Calculate vertices relative to ray origin. */
+ float3 tri[3];
+ tri[0] = float4_to_float3(kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0));
+ tri[1] = float4_to_float3(kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1));
+ tri[2] = float4_to_float3(kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2));
+
+ const float3 A = tri[0] - P;
+ const float3 B = tri[1] - P;
+ const float3 C = tri[2] - P;
+
+ const float A_kx = IDX(A, kx), A_ky = IDX(A, ky), A_kz = IDX(A, kz);
+ const float B_kx = IDX(B, kx), B_ky = IDX(B, ky), B_kz = IDX(B, kz);
+ const float C_kx = IDX(C, kx), C_ky = IDX(C, ky), C_kz = IDX(C, kz);
+
+ /* Perform shear and scale of vertices. */
+ const float Ax = A_kx - Sx * A_kz;
+ const float Ay = A_ky - Sy * A_kz;
+ const float Bx = B_kx - Sx * B_kz;
+ const float By = B_ky - Sy * B_kz;
+ const float Cx = C_kx - Sx * C_kz;
+ const float Cy = C_ky - Sy * C_kz;
+
+ /* Calculate scaled barycentric coordinates. */
+ float U = Cx * By - Cy * Bx;
+ int sign_mask = (__float_as_int(U) & 0x80000000);
+ float V = Ax * Cy - Ay * Cx;
+ if(sign_mask != (__float_as_int(V) & 0x80000000)) {
+ return;
+ }
+ float W = Bx * Ay - By * Ax;
+ if(sign_mask != (__float_as_int(W) & 0x80000000)) {
+ return;
+ }
+
+ /* Calculate determinant. */
+ float det = U + V + W;
+ if(UNLIKELY(det == 0.0f)) {
+ return;
+ }
+
+ /* Calculate scaled z−coordinates of vertices and use them to calculate
+ * the hit distance.
+ */
+ const float Az = Sz * A_kz;
+ const float Bz = Sz * B_kz;
+ const float Cz = Sz * C_kz;
+ const float T = U * Az + V * Bz + W * Cz;
+
+ if ((xor_signmast(T, sign_mask) < 0.0f) ||
+ (xor_signmast(T, sign_mask) > tmax * xor_signmast(det, sign_mask)))
+ {
+ return;
+ }
+
+ /* Normalize U, V, W, and T. */
+ const float inv_det = 1.0f / det;
+
+ (*num_hits)++;
+ int hit;
+
+ if(*num_hits <= max_hits) {
+ hit = *num_hits - 1;
+ }
+ else {
+ /* reservoir sampling: if we are at the maximum number of
+ * hits, randomly replace element or skip it */
+ hit = lcg_step_uint(lcg_state) % *num_hits;
+
+ if(hit >= max_hits)
+ return;
+ }
+
+ /* record intersection */
+ Intersection *isect = &isect_array[hit];
+ isect->prim = triAddr;
+ isect->object = object;
+ isect->type = PRIMITIVE_TRIANGLE;
+ isect->u = U * inv_det;
+ isect->v = V * inv_det;
+ isect->t = T * inv_det;
+}
+#endif
+
+/* Refine triangle intersection to more precise hit point. For rays that travel
+ * far the precision is often not so good, this reintersects the primitive from
+ * a closer distance. */
+
+/* Reintersections uses the paper:
+ *
+ * Tomas Moeller
+ * Fast, minimum storage ray/triangle intersection
+ * http://www.cs.virginia.edu/~gfx/Courses/2003/ImageSynthesis/papers/Acceleration/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf
+ */
+
+ccl_device_inline float3 triangle_refine(KernelGlobals *kg,
+ ShaderData *sd,
+ const Intersection *isect,
+ const Ray *ray)
+{
+ float3 P = ray->P;
+ float3 D = ray->D;
+ float t = isect->t;
+
+#ifdef __INTERSECTION_REFINE__
+ if(isect->object != OBJECT_NONE) {
+ if(UNLIKELY(t == 0.0f)) {
+ return P;
+ }
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D*t);
+ D = normalize_len(D, &t);
+ }
+
+ P = P + D*t;
+
+ float3 tri[3];
+ tri[0] = float4_to_float3(kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0));
+ tri[1] = float4_to_float3(kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+1));
+ tri[2] = float4_to_float3(kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+2));
+
+ float3 edge1 = tri[0] - tri[2];
+ float3 edge2 = tri[1] - tri[2];
+ float3 tvec = P - tri[2];
+ float3 qvec = cross(tvec, edge1);
+ float3 pvec = cross(D, edge2);
+ float rt = dot(edge2, qvec) / dot(edge1, pvec);
+
+ P = P + D*rt;
+
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+#else
+ return P + D*t;
+#endif
+}
+
+/* Same as above, except that isect->t is assumed to be in object space for
+ * instancing.
+ */
+ccl_device_inline float3 triangle_refine_subsurface(KernelGlobals *kg,
+ ShaderData *sd,
+ const Intersection *isect,
+ const Ray *ray)
+{
+ float3 P = ray->P;
+ float3 D = ray->D;
+ float t = isect->t;
+
+#ifdef __INTERSECTION_REFINE__
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ Transform tfm = object_fetch_transform(kg,
+ isect->object,
+ OBJECT_INVERSE_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D);
+ D = normalize(D);
+ }
+
+ P = P + D*t;
+
+ float3 tri[3];
+ tri[0] = float4_to_float3(kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0));
+ tri[1] = float4_to_float3(kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+1));
+ tri[2] = float4_to_float3(kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+2));
+
+ float3 edge1 = tri[0] - tri[2];
+ float3 edge2 = tri[1] - tri[2];
+ float3 tvec = P - tri[2];
+ float3 qvec = cross(tvec, edge1);
+ float3 pvec = cross(D, edge2);
+ float rt = dot(edge2, qvec) / dot(edge1, pvec);
+
+ P = P + D*rt;
+
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ Transform tfm = object_fetch_transform(kg,
+ isect->object,
+ OBJECT_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+#else
+ return P + D*t;
+#endif
+}
+
+#undef IDX
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_volume.h b/intern/cycles/kernel/geom/geom_volume.h
index 3cb6d168f80..c33509fbf4f 100644
--- a/intern/cycles/kernel/geom/geom_volume.h
+++ b/intern/cycles/kernel/geom/geom_volume.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* Volume Primitive
diff --git a/intern/cycles/kernel/kernel.cl b/intern/cycles/kernel/kernel.cl
index 4f20ef9ca15..5a47260a4ee 100644
--- a/intern/cycles/kernel/kernel.cl
+++ b/intern/cycles/kernel/kernel.cl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* OpenCL kernel entry points - unfinished */
diff --git a/intern/cycles/kernel/kernel.cpp b/intern/cycles/kernel/kernel.cpp
index fa2113fbb46..013eeff57fa 100644
--- a/intern/cycles/kernel/kernel.cpp
+++ b/intern/cycles/kernel/kernel.cpp
@@ -11,13 +11,13 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* CPU kernel entry points */
-#include "kernel.h"
#include "kernel_compat_cpu.h"
+#include "kernel.h"
#include "kernel_math.h"
#include "kernel_types.h"
#include "kernel_globals.h"
diff --git a/intern/cycles/kernel/kernel.cu b/intern/cycles/kernel/kernel.cu
index 489daacddde..64069fc049f 100644
--- a/intern/cycles/kernel/kernel.cu
+++ b/intern/cycles/kernel/kernel.cu
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* CUDA kernel entry points */
diff --git a/intern/cycles/kernel/kernel.h b/intern/cycles/kernel/kernel.h
index 19e06b88797..0996e51b7a0 100644
--- a/intern/cycles/kernel/kernel.h
+++ b/intern/cycles/kernel/kernel.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __KERNEL_H__
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index b0efcdc66a7..369c615eade 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/kernel_avx.cpp b/intern/cycles/kernel/kernel_avx.cpp
index e7ff21a6f09..f1027ad413d 100644
--- a/intern/cycles/kernel/kernel_avx.cpp
+++ b/intern/cycles/kernel/kernel_avx.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* Optimized CPU kernel entry points. This file is compiled with AVX
@@ -31,8 +31,8 @@
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX
-#include "kernel.h"
#include "kernel_compat_cpu.h"
+#include "kernel.h"
#include "kernel_math.h"
#include "kernel_types.h"
#include "kernel_globals.h"
diff --git a/intern/cycles/kernel/kernel_avx2.cpp b/intern/cycles/kernel/kernel_avx2.cpp
index cb1662bbfbe..b2f16ff54d8 100644
--- a/intern/cycles/kernel/kernel_avx2.cpp
+++ b/intern/cycles/kernel/kernel_avx2.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* Optimized CPU kernel entry points. This file is compiled with AVX2
@@ -32,8 +32,8 @@
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
-#include "kernel.h"
#include "kernel_compat_cpu.h"
+#include "kernel.h"
#include "kernel_math.h"
#include "kernel_types.h"
#include "kernel_globals.h"
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index a1ec080e3d3..20d7a143c67 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -11,11 +11,13 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
+#undef USE_BAKE_JITTER
+
ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, RNG rng,
const bool is_combined, const bool is_ao, const bool is_sss, int sample)
{
@@ -159,7 +161,8 @@ ccl_device bool is_light_pass(ShaderEvalType type)
}
}
-#if 0
+/* this helps with AA but it's not the real solution as it does not AA the geometry
+ * but it's better than nothing, thus committed */
ccl_device_inline float bake_clamp_mirror_repeat(float u)
{
/* use mirror repeat (like opengl texture) so that if the barycentric
@@ -170,7 +173,6 @@ ccl_device_inline float bake_clamp_mirror_repeat(float u)
return (((int)fu) & 1)? 1.0f - u: u;
}
-#endif
ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, ccl_global float4 *output,
ShaderEvalType type, int i, int offset, int sample)
@@ -198,12 +200,16 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
int num_samples = kernel_data.integrator.aa_samples;
/* random number generator */
- RNG rng = cmj_hash(offset + i, 0);
+ RNG rng = cmj_hash(offset + i, kernel_data.integrator.seed);
-#if 0
- uint rng_state = cmj_hash(i, 0);
+#ifdef USE_BAKE_JITTER
float filter_x, filter_y;
- path_rng_init(kg, &rng_state, sample, num_samples, &rng, 0, 0, &filter_x, &filter_y);
+ if(sample == 0) {
+ filter_x = filter_y = 0.5f;
+ }
+ else {
+ path_rng_2D(kg, &rng, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_x);
+ }
/* subpixel u/v offset */
if(sample > 0) {
@@ -253,6 +259,10 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
/* data passes */
case SHADER_EVAL_NORMAL:
{
+ if ((sd.flag & SD_HAS_BUMP)) {
+ shader_eval_surface(kg, &sd, 0.f, 0, SHADER_CONTEXT_MAIN);
+ }
+
/* compression: normal = (2 * color) - 1 */
out = sd.N * 0.5f + make_float3(0.5f, 0.5f, 0.5f);
break;
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 5c83358a56d..ded222e20ff 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -11,11 +11,22 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
+/* Workaround for explicit conversion from constant to private memory
+ * pointer when using OpenCL.
+ *
+ * TODO(sergey): Find a real solution for this.
+ */
+#ifdef __KERNEL_OPENCL__
+# define __motion_as_decoupled_const_ptr(motion) ((motion))
+#else
+# define __motion_as_decoupled_const_ptr(motion) ((const DecompMotionTransform*)(motion))
+#endif
+
/* Perspective Camera */
ccl_device float2 camera_sample_aperture(KernelGlobals *kg, float u, float v)
@@ -68,8 +79,11 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
Transform cameratoworld = kernel_data.cam.cameratoworld;
#ifdef __CAMERA_MOTION__
- if(kernel_data.cam.have_motion)
- transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
+ if(kernel_data.cam.have_motion) {
+ transform_motion_interpolate(&cameratoworld,
+ __motion_as_decoupled_const_ptr(&kernel_data.cam.motion),
+ ray->time);
+ }
#endif
ray->P = transform_point(&cameratoworld, ray->P);
@@ -88,8 +102,10 @@ ccl_device void camera_sample_perspective(KernelGlobals *kg, float raster_x, flo
#ifdef __CAMERA_CLIPPING__
/* clipping */
- ray->P += kernel_data.cam.nearclip*ray->D;
- ray->t = kernel_data.cam.cliplength;
+ float3 Pclip = normalize(Pcamera);
+ float z_inv = 1.0f / Pclip.z;
+ ray->P += kernel_data.cam.nearclip*ray->D * z_inv;
+ ray->t = kernel_data.cam.cliplength * z_inv;
#else
ray->t = FLT_MAX;
#endif
@@ -127,8 +143,11 @@ ccl_device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, fl
Transform cameratoworld = kernel_data.cam.cameratoworld;
#ifdef __CAMERA_MOTION__
- if(kernel_data.cam.have_motion)
- transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
+ if(kernel_data.cam.have_motion) {
+ transform_motion_interpolate(&cameratoworld,
+ __motion_as_decoupled_const_ptr(&kernel_data.cam.motion),
+ ray->time);
+ }
#endif
ray->P = transform_point(&cameratoworld, ray->P);
@@ -202,7 +221,9 @@ ccl_device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float
#ifdef __CAMERA_MOTION__
if(kernel_data.cam.have_motion)
- transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time);
+ transform_motion_interpolate(&cameratoworld,
+ __motion_as_decoupled_const_ptr(&kernel_data.cam.motion),
+ ray->time);
#endif
ray->P = transform_point(&cameratoworld, ray->P);
@@ -308,5 +329,7 @@ ccl_device_inline float3 camera_world_to_ndc(KernelGlobals *kg, ShaderData *sd,
}
}
+#undef __motion_as_decoupled_const_ptr
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index 37cba03ff97..200667a0911 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __KERNEL_COMPAT_CPU_H__
@@ -19,16 +19,25 @@
#define __KERNEL_CPU__
+/* Release kernel has too much false-positive maybe-uninitialized warnings,
+ * which makes it possible to miss actual warnings.
+ */
+#if defined(__GNUC__) && defined(NDEBUG)
+# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+
#include "util_debug.h"
#include "util_math.h"
#include "util_simd.h"
#include "util_half.h"
#include "util_types.h"
-/* On 64bit linux single precision exponent is really slow comparing to the
- * double precision version, even with float<->double conversion involved.
+/* On x86_64, versions of glibc < 2.16 have an issue where expf is
+ * much slower than the double version. This was fixed in glibc 2.16.
*/
-#if !defined(__KERNEL_GPU__) && defined(__linux__) && defined(__x86_64__)
+#if !defined(__KERNEL_GPU__) && defined(__x86_64__) && defined(__x86_64__) && \
+ defined(__GNU_LIBRARY__) && defined(__GLIBC__ ) && defined(__GLIBC_MINOR__) && \
+ (__GLIBC__ <= 2 && __GLIBC_MINOR__ < 16)
# define expf(x) ((float)exp((double)(x)))
#endif
@@ -50,7 +59,7 @@ template<typename T> struct texture {
return data[index];
}
-#if 0
+#ifdef __KERNEL_SSE2__
ccl_always_inline ssef fetch_ssef(int index)
{
kernel_assert(index >= 0 && index < width);
@@ -69,6 +78,14 @@ template<typename T> struct texture {
};
template<typename T> struct texture_image {
+#define SET_CUBIC_SPLINE_WEIGHTS(u, t) \
+ { \
+ u[0] = (((-1.0f/6.0f)* t + 0.5f) * t - 0.5f) * t + (1.0f/6.0f); \
+ u[1] = (( 0.5f * t - 1.0f) * t ) * t + (2.0f/3.0f); \
+ u[2] = (( -0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f/6.0f); \
+ u[3] = (1.0f / 6.0f) * t * t * t; \
+ } (void)0
+
ccl_always_inline float4 read(float4 r)
{
return r;
@@ -121,7 +138,7 @@ template<typename T> struct texture_image {
}
return read(data[ix + iy*width]);
}
- else {
+ else if(interpolation == INTERPOLATION_LINEAR) {
float tx = frac(x*(float)width - 0.5f, &ix);
float ty = frac(y*(float)height - 0.5f, &iy);
@@ -147,6 +164,62 @@ template<typename T> struct texture_image {
return r;
}
+ else {
+ /* Tricubic b-spline interpolation. */
+ const float tx = frac(x*(float)width - 0.5f, &ix);
+ const float ty = frac(y*(float)height - 0.5f, &iy);
+ int pix, piy, nnix, nniy;
+ if(periodic) {
+ ix = wrap_periodic(ix, width);
+ iy = wrap_periodic(iy, height);
+
+ pix = wrap_periodic(ix-1, width);
+ piy = wrap_periodic(iy-1, height);
+
+ nix = wrap_periodic(ix+1, width);
+ niy = wrap_periodic(iy+1, height);
+
+ nnix = wrap_periodic(ix+2, width);
+ nniy = wrap_periodic(iy+2, height);
+ }
+ else {
+ ix = wrap_clamp(ix, width);
+ iy = wrap_clamp(iy, height);
+
+ pix = wrap_clamp(ix-1, width);
+ piy = wrap_clamp(iy-1, height);
+
+ nix = wrap_clamp(ix+1, width);
+ niy = wrap_clamp(iy+1, height);
+
+ nnix = wrap_clamp(ix+2, width);
+ nniy = wrap_clamp(iy+2, height);
+ }
+ const int xc[4] = {pix, ix, nix, nnix};
+ const int yc[4] = {width * piy,
+ width * iy,
+ width * niy,
+ width * nniy};
+ float u[4], v[4];
+ /* Some helper macro to keep code reasonable size,
+ * let compiler to inline all the matrix multiplications.
+ */
+#define DATA(x, y) (read(data[xc[x] + yc[y]]))
+#define TERM(col) \
+ (v[col] * (u[0] * DATA(0, col) + \
+ u[1] * DATA(1, col) + \
+ u[2] * DATA(2, col) + \
+ u[3] * DATA(3, col)))
+
+ SET_CUBIC_SPLINE_WEIGHTS(u, tx);
+ SET_CUBIC_SPLINE_WEIGHTS(v, ty);
+
+ /* Actual interpolation. */
+ return TERM(0) + TERM(1) + TERM(2) + TERM(3);
+
+#undef TERM
+#undef DATA
+ }
}
ccl_always_inline float4 interp_3d(float x, float y, float z, bool periodic = false)
@@ -275,13 +348,6 @@ template<typename T> struct texture_image {
/* Some helper macro to keep code reasonable size,
* let compiler to inline all the matrix multiplications.
*/
-#define SET_SPLINE_WEIGHTS(u, t) \
- { \
- u[0] = (((-1.0f/6.0f)* t + 0.5f) * t - 0.5f) * t + (1.0f/6.0f); \
- u[1] = (( 0.5f * t - 1.0f) * t ) * t + (2.0f/3.0f); \
- u[2] = (( -0.5f * t + 0.5f) * t + 0.5f) * t + (1.0f/6.0f); \
- u[3] = (1.0f / 6.0f) * t * t * t; \
- } (void)0
#define DATA(x, y, z) (read(data[xc[x] + yc[y] + zc[z]]))
#define COL_TERM(col, row) \
(v[col] * (u[0] * DATA(0, col, row) + \
@@ -294,9 +360,9 @@ template<typename T> struct texture_image {
COL_TERM(2, row) + \
COL_TERM(3, row)))
- SET_SPLINE_WEIGHTS(u, tx);
- SET_SPLINE_WEIGHTS(v, ty);
- SET_SPLINE_WEIGHTS(w, tz);
+ SET_CUBIC_SPLINE_WEIGHTS(u, tx);
+ SET_CUBIC_SPLINE_WEIGHTS(v, ty);
+ SET_CUBIC_SPLINE_WEIGHTS(w, tz);
/* Actual interpolation. */
return ROW_TERM(0) + ROW_TERM(1) + ROW_TERM(2) + ROW_TERM(3);
@@ -304,7 +370,6 @@ template<typename T> struct texture_image {
#undef COL_TERM
#undef ROW_TERM
#undef DATA
-#undef SET_SPLINE_WEIGHTS
}
}
@@ -318,6 +383,7 @@ template<typename T> struct texture_image {
T *data;
int interpolation;
int width, height, depth;
+#undef SET_CUBIC_SPLINE_WEIGHTS
};
typedef texture<float4> texture_float4;
@@ -342,6 +408,34 @@ typedef texture_image<uchar4> texture_image_uchar4;
#define kernel_data (kg->__data)
+#ifdef __KERNEL_SSE2__
+typedef vector3<sseb> sse3b;
+typedef vector3<ssef> sse3f;
+typedef vector3<ssei> sse3i;
+
+ccl_device_inline void print_sse3b(const char *label, sse3b& a)
+{
+ print_sseb(label, a.x);
+ print_sseb(label, a.y);
+ print_sseb(label, a.z);
+}
+
+ccl_device_inline void print_sse3f(const char *label, sse3f& a)
+{
+ print_ssef(label, a.x);
+ print_ssef(label, a.y);
+ print_ssef(label, a.z);
+}
+
+ccl_device_inline void print_sse3i(const char *label, sse3i& a)
+{
+ print_ssei(label, a.x);
+ print_ssei(label, a.y);
+ print_ssei(label, a.z);
+}
+
+#endif
+
CCL_NAMESPACE_END
#endif /* __KERNEL_COMPAT_CPU_H__ */
diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h
index f14f3262274..904736c190c 100644
--- a/intern/cycles/kernel/kernel_compat_cuda.h
+++ b/intern/cycles/kernel/kernel_compat_cuda.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __KERNEL_COMPAT_CUDA_H__
diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h
index 58031a41b78..d480ec0f270 100644
--- a/intern/cycles/kernel/kernel_compat_opencl.h
+++ b/intern/cycles/kernel/kernel_compat_opencl.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __KERNEL_COMPAT_OPENCL_H__
diff --git a/intern/cycles/kernel/kernel_debug.h b/intern/cycles/kernel/kernel_debug.h
index bf1bc0e9db8..f532442ba41 100644
--- a/intern/cycles/kernel/kernel_debug.h
+++ b/intern/cycles/kernel/kernel_debug.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/kernel_differential.h b/intern/cycles/kernel/kernel_differential.h
index daba2d927b7..e5fbd5b450e 100644
--- a/intern/cycles/kernel/kernel_differential.h
+++ b/intern/cycles/kernel/kernel_differential.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 4b2bb723ab6..7523105607f 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
@@ -188,7 +188,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, PathState *st
/* use visibility flag to skip lights */
if(ls.shader & SHADER_EXCLUDE_ANY) {
if(((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
- ((ls.shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_GLOSSY)) ||
+ ((ls.shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_REFLECT)) ||
((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
((ls.shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER)))
continue;
@@ -232,7 +232,7 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, PathState *sta
/* use visibility flag to skip lights */
if(shader & SHADER_EXCLUDE_ANY) {
if(((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
- ((shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_GLOSSY)) ||
+ ((shader & SHADER_EXCLUDE_GLOSSY) && (state->flag & PATH_RAY_REFLECT)) ||
((shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA)) ||
((shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER)))
diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h
index dc5f6e7ce38..4668b40b86d 100644
--- a/intern/cycles/kernel/kernel_film.h
+++ b/intern/cycles/kernel/kernel_film.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/kernel_globals.h b/intern/cycles/kernel/kernel_globals.h
index 6bd2ec0662c..0a9753baca2 100644
--- a/intern/cycles/kernel/kernel_globals.h
+++ b/intern/cycles/kernel/kernel_globals.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* Constant Globals */
diff --git a/intern/cycles/kernel/kernel_jitter.h b/intern/cycles/kernel/kernel_jitter.h
index 2a5b7689e57..6953f005ea9 100644
--- a/intern/cycles/kernel/kernel_jitter.h
+++ b/intern/cycles/kernel/kernel_jitter.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* TODO(sergey): Consider moving portable ctz/clz stuff to util. */
@@ -47,6 +47,8 @@ ccl_device_inline int cmj_fast_div_pow2(int a, int b)
# else
return a >> __builtin_ctz(b);
# endif
+#elif defined(__KERNEL_CUDA__)
+ return a >> (__ffs(b) - 1);
#else
return a/b;
#endif
@@ -63,6 +65,8 @@ ccl_device_inline uint cmj_w_mask(uint w)
# else
return ((1 << (32 - __builtin_clz(w))) - 1);
# endif
+#elif defined(__KERNEL_CUDA__)
+ return ((1 << (32 - __clz(w))) - 1);
#else
w |= w >> 1;
w |= w >> 2;
@@ -167,7 +171,11 @@ ccl_device void cmj_sample_2D(int s, int N, int p, float *fx, float *fy)
{
kernel_assert(s < N);
+#if defined(__KERNEL_CUDA__)
+ int m = float_to_int(__fsqrt_ru(N));
+#else
int m = float_to_int(sqrtf(N));
+#endif
int n = (N + m - 1)/m;
float invN = 1.0f/N;
float invm = 1.0f/m;
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index b18f67ad524..76fa754b5fa 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
@@ -37,7 +37,16 @@ typedef struct LightSample {
#ifdef __BACKGROUND_MIS__
-ccl_device float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf)
+/* TODO(sergey): In theory it should be all fine to use noinline for all
+ * devices, but we're so close to the release so better not screw things
+ * up for CPU at least.
+ */
+#ifdef __KERNEL_GPU__
+ccl_device_noinline
+#else
+ccl_device
+#endif
+float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf)
{
/* for the following, the CDF values are actually a pair of floats, with the
* function value as X and the actual CDF as Y. The last entry's function
@@ -113,7 +122,15 @@ ccl_device float3 background_light_sample(KernelGlobals *kg, float randu, float
return -equirectangular_to_direction(u, v);
}
-ccl_device float background_light_pdf(KernelGlobals *kg, float3 direction)
+/* TODO(sergey): Same as above, after the release we should consider using
+ * 'noinline' for all devices.
+ */
+#ifdef __KERNEL_GPU__
+ccl_device_noinline
+#else
+ccl_device
+#endif
+float background_light_pdf(KernelGlobals *kg, float3 direction)
{
float2 uv = direction_to_equirectangular(direction);
int res = kernel_data.integrator.pdf_background_res;
@@ -173,18 +190,20 @@ ccl_device float3 sphere_light_sample(float3 P, float3 center, float radius, flo
* An Area-Preserving Parametrization for Spherical Rectangles.
*
* https://www.solidangle.com/research/egsr2013_spherical_rectangle.pdf
+ *
+ * Note: light_p is modified when sample_coord is true.
*/
-ccl_device float3 area_light_sample(float3 P,
- float3 light_p,
- float3 axisu, float3 axisv,
- float randu, float randv,
- float *pdf)
+ccl_device float area_light_sample(float3 P,
+ float3 *light_p,
+ float3 axisu, float3 axisv,
+ float randu, float randv,
+ bool sample_coord)
{
/* In our name system we're using P for the center,
* which is o in the paper.
*/
- float3 corner = light_p - axisu * 0.5f - axisv * 0.5f;
+ float3 corner = *light_p - axisu * 0.5f - axisv * 0.5f;
float axisu_len, axisv_len;
/* Compute local reference system R. */
float3 x = normalize_len(axisu, &axisu_len);
@@ -198,13 +217,10 @@ ccl_device float3 area_light_sample(float3 P,
z *= -1.0f;
z0 *= -1.0f;
}
- float z0sq = z0 * z0;
float x0 = dot(dir, x);
float y0 = dot(dir, y);
float x1 = x0 + axisu_len;
float y1 = y0 + axisv_len;
- float y0sq = y0 * y0;
- float y1sq = y1 * y1;
/* Create vectors to four vertices. */
float3 v00 = make_float3(x0, y0, z0);
float3 v01 = make_float3(x0, y1, z0);
@@ -216,10 +232,10 @@ ccl_device float3 area_light_sample(float3 P,
float3 n2 = normalize(cross(v11, v01));
float3 n3 = normalize(cross(v01, v00));
/* Compute internal angles (gamma_i). */
- float g0 = acosf(-dot(n0, n1));
- float g1 = acosf(-dot(n1, n2));
- float g2 = acosf(-dot(n2, n3));
- float g3 = acosf(-dot(n3, n0));
+ float g0 = safe_acosf(-dot(n0, n1));
+ float g1 = safe_acosf(-dot(n1, n2));
+ float g2 = safe_acosf(-dot(n2, n3));
+ float g3 = safe_acosf(-dot(n3, n0));
/* Compute predefined constants. */
float b0 = n0.z;
float b1 = n2.z;
@@ -228,76 +244,34 @@ ccl_device float3 area_light_sample(float3 P,
/* Compute solid angle from internal angles. */
float S = g0 + g1 - k;
- /* Compute cu. */
- float au = randu * S + k;
- float fu = (cosf(au) * b0 - b1) / sinf(au);
- float cu = 1.0f / sqrtf(fu * fu + b0sq) * (fu > 0.0f ? 1.0f : -1.0f);
- cu = clamp(cu, -1.0f, 1.0f);
- /* Compute xu. */
- float xu = -(cu * z0) / sqrtf(1.0f - cu * cu);
- xu = clamp(xu, x0, x1);
- /* Compute yv. */
- float d = sqrtf(xu * xu + z0sq);
- float h0 = y0 / sqrtf(d * d + y0sq);
- float h1 = y1 / sqrtf(d * d + y1sq);
- float hv = h0 + randv * (h1 - h0), hv2 = hv * hv;
- float yv = (hv2 < 1.0f - 1e-6f) ? (hv * d) / sqrtf(1.0f - hv2) : y1;
-
- *pdf = 1.0f / S;
-
- /* Transform (xu, yv, z0) to world coords. */
- return P + xu * x + yv * y + z0 * z;
-}
-
-/* TODO(sergey): This is actually a duplicated code from above, but how to avoid
- * this without having some nasty function with loads of parameters?
- */
-ccl_device float area_light_pdf(float3 P,
- float3 light_p,
- float3 axisu, float3 axisv)
-{
- /* In our name system we're using P for the center,
- * which is o in the paper.
- */
-
- float3 corner = light_p - axisu * 0.5f - axisv * 0.5f;
- float axisu_len, axisv_len;
- /* Compute local reference system R. */
- float3 x = normalize_len(axisu, &axisu_len);
- float3 y = normalize_len(axisv, &axisv_len);
- float3 z = cross(x, y);
- /* Compute rectangle coords in local reference system. */
- float3 dir = corner - P;
- float z0 = dot(dir, z);
- /* Flip 'z' to make it point against Q. */
- if(z0 > 0.0f) {
- z *= -1.0f;
- z0 *= -1.0f;
+ if(sample_coord) {
+ /* Compute cu. */
+ float au = randu * S + k;
+ float fu = (cosf(au) * b0 - b1) / sinf(au);
+ float cu = 1.0f / sqrtf(fu * fu + b0sq) * (fu > 0.0f ? 1.0f : -1.0f);
+ cu = clamp(cu, -1.0f, 1.0f);
+ /* Compute xu. */
+ float xu = -(cu * z0) / sqrtf(1.0f - cu * cu);
+ xu = clamp(xu, x0, x1);
+ /* Compute yv. */
+ float z0sq = z0 * z0;
+ float y0sq = y0 * y0;
+ float y1sq = y1 * y1;
+ float d = sqrtf(xu * xu + z0sq);
+ float h0 = y0 / sqrtf(d * d + y0sq);
+ float h1 = y1 / sqrtf(d * d + y1sq);
+ float hv = h0 + randv * (h1 - h0), hv2 = hv * hv;
+ float yv = (hv2 < 1.0f - 1e-6f) ? (hv * d) / sqrtf(1.0f - hv2) : y1;
+
+ /* Transform (xu, yv, z0) to world coords. */
+ *light_p = P + xu * x + yv * y + z0 * z;
}
- float x0 = dot(dir, x);
- float y0 = dot(dir, y);
- float x1 = x0 + axisu_len;
- float y1 = y0 + axisv_len;
- /* Create vectors to four vertices. */
- float3 v00 = make_float3(x0, y0, z0);
- float3 v01 = make_float3(x0, y1, z0);
- float3 v10 = make_float3(x1, y0, z0);
- float3 v11 = make_float3(x1, y1, z0);
- /* Compute normals to edges. */
- float3 n0 = normalize(cross(v00, v10));
- float3 n1 = normalize(cross(v10, v11));
- float3 n2 = normalize(cross(v11, v01));
- float3 n3 = normalize(cross(v01, v00));
- /* Compute internal angles (gamma_i). */
- float g0 = acosf(-dot(n0, n1));
- float g1 = acosf(-dot(n1, n2));
- float g2 = acosf(-dot(n2, n3));
- float g3 = acosf(-dot(n3, n0));
- /* Compute predefined constants. */
- float k = M_2PI_F - g2 - g3;
- /* Compute solid angle from internal angles. */
- float S = g0 + g1 - k;
- return 1.0f / S;
+
+ /* return pdf */
+ if(S != 0.0f)
+ return 1.0f / S;
+ else
+ return 0.0f;
}
ccl_device float spot_light_attenuation(float4 data1, float4 data2, LightSample *ls)
@@ -412,10 +386,10 @@ ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp,
float3 axisv = make_float3(data2.y, data2.z, data2.w);
float3 D = make_float3(data3.y, data3.z, data3.w);
- ls->P = area_light_sample(P, ls->P,
+ ls->pdf = area_light_sample(P, &ls->P,
axisu, axisv,
randu, randv,
- &ls->pdf);
+ true);
ls->Ng = D;
ls->D = normalize_len(ls->P - P, &ls->t);
@@ -488,9 +462,6 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
/* compute pdf */
float invarea = data1.w;
ls->pdf = invarea/(costheta*costheta*costheta);
- if(ls->t != FLT_MAX)
- ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
-
ls->eval_fac = ls->pdf;
}
else if(type == LIGHT_POINT || type == LIGHT_SPOT) {
@@ -550,7 +521,7 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
ls->D = D;
ls->Ng = Ng;
- ls->pdf = area_light_pdf(P, ls->P, axisu, axisv);
+ ls->pdf = area_light_sample(P, &ls->P, axisu, axisv, 0, 0, false);
ls->eval_fac = 0.25f*invarea;
}
else
@@ -648,7 +619,13 @@ ccl_device int light_distribution_sample(KernelGlobals *kg, float randt)
/* Generic Light */
-ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls)
+ccl_device bool light_select_reached_max_bounces(KernelGlobals *kg, int index, int bounce)
+{
+ float4 data4 = kernel_tex_fetch(__light_data, index*LIGHT_SIZE + 4);
+ return (bounce > __float_as_int(data4.x));
+}
+
+ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, int bounce, LightSample *ls)
{
/* sample index */
int index = light_distribution_sample(kg, randt);
@@ -670,6 +647,12 @@ ccl_device void light_sample(KernelGlobals *kg, float randt, float randu, float
}
else {
int lamp = -prim-1;
+
+ if(UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) {
+ ls->pdf = 0.0f;
+ return;
+ }
+
lamp_light_sample(kg, lamp, randu, randv, P, ls);
}
}
@@ -680,22 +663,5 @@ ccl_device int light_select_num_samples(KernelGlobals *kg, int index)
return __float_as_int(data3.x);
}
-ccl_device int lamp_light_eval_sample(KernelGlobals *kg, float randt)
-{
- /* sample index */
- int index = light_distribution_sample(kg, randt);
-
- /* fetch light data */
- float4 l = kernel_tex_fetch(__light_distribution, index);
- int prim = __float_as_int(l.y);
-
- if(prim < 0) {
- int lamp = -prim-1;
- return lamp;
- }
- else
- return LAMP_NONE;
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_math.h b/intern/cycles/kernel/kernel_math.h
index 97621db1cf3..453f4c8b421 100644
--- a/intern/cycles/kernel/kernel_math.h
+++ b/intern/cycles/kernel/kernel_math.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __KERNEL_MATH_H__
@@ -19,6 +19,7 @@
#include "util_color.h"
#include "util_math.h"
+#include "util_math_fast.h"
#include "util_transform.h"
#endif /* __KERNEL_MATH_H__ */
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index b3b6fc02894..6bb39ee485d 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index c03229f0a3a..9b9495644dd 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifdef __OSL__
@@ -117,7 +117,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray,
/* direct light sampling */
kernel_branched_path_volume_connect_light(kg, rng, &volume_sd,
- throughput, &state, L, 1.0f, all, &volume_ray, &volume_segment);
+ throughput, &state, L, all, &volume_ray, &volume_segment);
/* indirect sample. if we use distance sampling and take just
* one sample for direct and indirect light, we could share
@@ -130,9 +130,6 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray,
rphase, rscatter, &volume_segment, NULL, true);
}
- if(result != VOLUME_PATH_SCATTERED)
- throughput *= volume_segment.accum_transmittance;
-
/* free cached steps */
kernel_volume_decoupled_free(kg, &volume_segment);
@@ -142,6 +139,9 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray,
else
break;
}
+ else {
+ throughput *= volume_segment.accum_transmittance;
+ }
}
else
#endif
@@ -373,8 +373,9 @@ ccl_device void kernel_path_subsurface_update_volume_stack(KernelGlobals *kg,
Ray volume_ray = *ray;
Intersection isect;
-
- while(scene_intersect_volume(kg, &volume_ray, &isect))
+ int step = 0;
+ while(step < VOLUME_STACK_SIZE &&
+ scene_intersect_volume(kg, &volume_ray, &isect))
{
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &volume_ray, 0, 0);
@@ -383,6 +384,7 @@ ccl_device void kernel_path_subsurface_update_volume_stack(KernelGlobals *kg,
/* Move ray forward. */
volume_ray.P = ray_offset(sd.P, -sd.Ng);
volume_ray.t -= sd.ray_length;
+ ++step;
}
}
#endif
@@ -560,7 +562,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
/* direct light sampling */
kernel_branched_path_volume_connect_light(kg, rng, &volume_sd,
- throughput, &state, &L, 1.0f, all, &volume_ray, &volume_segment);
+ throughput, &state, &L, all, &volume_ray, &volume_segment);
/* indirect sample. if we use distance sampling and take just
* one sample for direct and indirect light, we could share
@@ -573,9 +575,6 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
rphase, rscatter, &volume_segment, NULL, true);
}
- if(result != VOLUME_PATH_SCATTERED)
- throughput *= volume_segment.accum_transmittance;
-
/* free cached steps */
kernel_volume_decoupled_free(kg, &volume_segment);
@@ -585,6 +584,9 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
else
break;
}
+ else {
+ throughput *= volume_segment.accum_transmittance;
+ }
}
else
#endif
@@ -935,7 +937,7 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
bool all = kernel_data.integrator.sample_all_lights_direct;
kernel_branched_path_volume_connect_light(kg, rng, &volume_sd,
- throughput, &state, &L, 1.0f, all, &volume_ray, &volume_segment);
+ throughput, &state, &L, all, &volume_ray, &volume_segment);
/* indirect light sampling */
int num_samples = kernel_data.integrator.volume_samples;
diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h
index f29168642a4..ab146c72cd0 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h
index 9553c2da0df..f0d4e98c5e0 100644
--- a/intern/cycles/kernel/kernel_path_surface.h
+++ b/intern/cycles/kernel/kernel_path_surface.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
@@ -38,6 +38,9 @@ ccl_device void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RN
if(sample_all_lights) {
/* lamp sampling */
for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
+ if(UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
+ continue;
+
int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
RNG lamp_rng = cmj_hash(*rng, i);
@@ -82,7 +85,7 @@ ccl_device void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RN
light_t = 0.5f*light_t;
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
@@ -103,7 +106,7 @@ ccl_device void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RN
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
/* sample random light */
if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
@@ -200,7 +203,7 @@ ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, RNG
#endif
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
if(direct_emission(kg, sd, &ls, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
@@ -278,6 +281,11 @@ ccl_device_inline bool kernel_path_surface_bounce(KernelGlobals *kg, RNG *rng,
/* update path state, count as transparent */
path_state_next(kg, state, LABEL_TRANSPARENT);
+ if(state->bounce == 0)
+ ray->t -= sd->ray_length; /* clipping works through transparent */
+ else
+ ray->t = FLT_MAX;
+
/* setup ray position, direction stays unchanged */
ray->P = ray_offset(sd->P, -sd->Ng);
#ifdef __RAY_DIFFERENTIALS__
diff --git a/intern/cycles/kernel/kernel_path_volume.h b/intern/cycles/kernel/kernel_path_volume.h
index d8143832294..82dc0f97622 100644
--- a/intern/cycles/kernel/kernel_path_volume.h
+++ b/intern/cycles/kernel/kernel_path_volume.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
@@ -40,7 +40,7 @@ ccl_device void kernel_path_volume_connect_light(KernelGlobals *kg, RNG *rng,
light_ray.time = sd->time;
#endif
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
if(ls.pdf == 0.0f)
return;
@@ -107,7 +107,7 @@ bool kernel_path_volume_bounce(KernelGlobals *kg, RNG *rng,
ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG *rng,
ShaderData *sd, float3 throughput, PathState *state, PathRadiance *L,
- float num_samples_adjust, bool sample_all_lights, Ray *ray, const VolumeSegment *segment)
+ bool sample_all_lights, Ray *ray, const VolumeSegment *segment)
{
#ifdef __EMISSION__
if(!kernel_data.integrator.use_direct_light)
@@ -124,8 +124,11 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
if(sample_all_lights) {
/* lamp sampling */
for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) {
- int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i));
- float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights);
+ if(UNLIKELY(light_select_reached_max_bounces(kg, i, state->bounce)))
+ continue;
+
+ int num_samples = light_select_num_samples(kg, i);
+ float num_samples_inv = 1.0f/(num_samples*kernel_data.integrator.num_all_lights);
RNG lamp_rng = cmj_hash(*rng, i);
if(kernel_data.integrator.pdf_triangles != 0.0f)
@@ -171,8 +174,8 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
/* mesh light sampling */
if(kernel_data.integrator.pdf_triangles != 0.0f) {
- int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples);
- float num_samples_inv = num_samples_adjust/num_samples;
+ int num_samples = kernel_data.integrator.mesh_light_samples;
+ float num_samples_inv = 1.0f/num_samples;
if(kernel_data.integrator.num_all_lights)
num_samples_inv *= 0.5f;
@@ -188,7 +191,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
light_t = 0.5f*light_t;
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
float3 tp = throughput;
@@ -203,7 +206,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
kernel_assert(result == VOLUME_PATH_SCATTERED);
/* todo: split up light_sample so we don't have to call it again with new position */
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
if(ls.pdf == 0.0f)
continue;
@@ -227,7 +230,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
LightSample ls;
- light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, ray->P, state->bounce, &ls);
float3 tp = throughput;
@@ -242,7 +245,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
kernel_assert(result == VOLUME_PATH_SCATTERED);
/* todo: split up light_sample so we don't have to call it again with new position */
- light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, &ls);
+ light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls);
if(ls.pdf == 0.0f)
return;
diff --git a/intern/cycles/kernel/kernel_projection.h b/intern/cycles/kernel/kernel_projection.h
index 6744471d659..bd18fd21354 100644
--- a/intern/cycles/kernel/kernel_projection.h
+++ b/intern/cycles/kernel/kernel_projection.h
@@ -55,18 +55,18 @@ ccl_device float3 spherical_to_direction(float theta, float phi)
/* Equirectangular coordinates <-> Cartesian direction */
-ccl_device float2 direction_to_equirectangular(float3 dir)
+ccl_device float2 direction_to_equirectangular_range(float3 dir, float4 range)
{
- float u = -atan2f(dir.y, dir.x)/(M_2PI_F) + 0.5f;
- float v = atan2f(dir.z, hypotf(dir.x, dir.y))/M_PI_F + 0.5f;
+ float u = (atan2f(dir.y, dir.x) - range.y) / range.x;
+ float v = (acosf(dir.z / len(dir)) - range.w) / range.z;
return make_float2(u, v);
}
-ccl_device float3 equirectangular_to_direction(float u, float v)
+ccl_device float3 equirectangular_range_to_direction(float u, float v, float4 range)
{
- float phi = M_PI_F*(1.0f - 2.0f*u);
- float theta = M_PI_F*(1.0f - v);
+ float phi = range.x*u + range.y;
+ float theta = range.z*v + range.w;
return make_float3(
sinf(theta)*cosf(phi),
@@ -74,6 +74,16 @@ ccl_device float3 equirectangular_to_direction(float u, float v)
cosf(theta));
}
+ccl_device float2 direction_to_equirectangular(float3 dir)
+{
+ return direction_to_equirectangular_range(dir, make_float4(-M_2PI_F, M_PI_F, -M_PI_F, M_PI_F));
+}
+
+ccl_device float3 equirectangular_to_direction(float u, float v)
+{
+ return equirectangular_range_to_direction(u, v, make_float4(-M_2PI_F, M_PI_F, -M_PI_F, M_PI_F));
+}
+
/* Fisheye <-> Cartesian direction */
ccl_device float2 direction_to_fisheye(float3 dir, float fov)
@@ -180,7 +190,7 @@ ccl_device float3 panorama_to_direction(KernelGlobals *kg, float u, float v)
{
switch(kernel_data.cam.panorama_type) {
case PANORAMA_EQUIRECTANGULAR:
- return equirectangular_to_direction(u, v);
+ return equirectangular_range_to_direction(u, v, kernel_data.cam.equirectangular_range);
case PANORAMA_FISHEYE_EQUIDISTANT:
return fisheye_to_direction(u, v, kernel_data.cam.fisheye_fov);
case PANORAMA_FISHEYE_EQUISOLID:
@@ -194,7 +204,7 @@ ccl_device float2 direction_to_panorama(KernelGlobals *kg, float3 dir)
{
switch(kernel_data.cam.panorama_type) {
case PANORAMA_EQUIRECTANGULAR:
- return direction_to_equirectangular(dir);
+ return direction_to_equirectangular_range(dir, kernel_data.cam.equirectangular_range);
case PANORAMA_FISHEYE_EQUIDISTANT:
return direction_to_fisheye(dir, kernel_data.cam.fisheye_fov);
case PANORAMA_FISHEYE_EQUISOLID:
diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h
index 236f74c0a82..40767bac013 100644
--- a/intern/cycles/kernel/kernel_random.h
+++ b/intern/cycles/kernel/kernel_random.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "kernel_jitter.h"
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index db08c328d7e..0f3b09a9555 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/*
@@ -387,10 +387,8 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
/* differentials */
sd->dP = ray->dD;
differential_incoming(&sd->dI, sd->dP);
- sd->du.dx = 0.0f;
- sd->du.dy = 0.0f;
- sd->dv.dx = 0.0f;
- sd->dv.dy = 0.0f;
+ sd->du = differential_zero();
+ sd->dv = differential_zero();
#endif
}
@@ -681,7 +679,7 @@ ccl_device float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd)
for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSSRDF(sc->type))
+ if(CLOSURE_IS_BSSRDF(sc->type) || CLOSURE_IS_BSDF_BSSRDF(sc->type))
eval += sc->weight;
}
diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h
index 61954282c28..8923fcebee5 100644
--- a/intern/cycles/kernel/kernel_shadow.h
+++ b/intern/cycles/kernel/kernel_shadow.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/kernel_sse2.cpp b/intern/cycles/kernel/kernel_sse2.cpp
index 740998e8c92..cc8c603e8f8 100644
--- a/intern/cycles/kernel/kernel_sse2.cpp
+++ b/intern/cycles/kernel/kernel_sse2.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* Optimized CPU kernel entry points. This file is compiled with SSE2
@@ -27,8 +27,8 @@
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
-#include "kernel.h"
#include "kernel_compat_cpu.h"
+#include "kernel.h"
#include "kernel_math.h"
#include "kernel_types.h"
#include "kernel_globals.h"
diff --git a/intern/cycles/kernel/kernel_sse3.cpp b/intern/cycles/kernel/kernel_sse3.cpp
index da73a3a1c97..20919a4f26e 100644
--- a/intern/cycles/kernel/kernel_sse3.cpp
+++ b/intern/cycles/kernel/kernel_sse3.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* Optimized CPU kernel entry points. This file is compiled with SSE3/SSSE3
@@ -29,8 +29,8 @@
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3
-#include "kernel.h"
#include "kernel_compat_cpu.h"
+#include "kernel.h"
#include "kernel_math.h"
#include "kernel_types.h"
#include "kernel_globals.h"
diff --git a/intern/cycles/kernel/kernel_sse41.cpp b/intern/cycles/kernel/kernel_sse41.cpp
index 5704f60e138..48579d3b7e5 100644
--- a/intern/cycles/kernel/kernel_sse41.cpp
+++ b/intern/cycles/kernel/kernel_sse41.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* Optimized CPU kernel entry points. This file is compiled with SSE3/SSSE3
@@ -30,8 +30,8 @@
#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
-#include "kernel.h"
#include "kernel_compat_cpu.h"
+#include "kernel.h"
#include "kernel_math.h"
#include "kernel_types.h"
#include "kernel_globals.h"
diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h
index fb927e81f22..2da060c32a2 100644
--- a/intern/cycles/kernel/kernel_subsurface.h
+++ b/intern/cycles/kernel/kernel_subsurface.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index ef46b2f707f..374dc6d1dd9 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef KERNEL_TEX
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index cfac8d1e905..238b4b0bfdc 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __KERNEL_TYPES_H__
@@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN
/* constants */
#define OBJECT_SIZE 11
#define OBJECT_VECTOR_SIZE 6
-#define LIGHT_SIZE 4
+#define LIGHT_SIZE 5
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
#define PARTICLE_SIZE 5
@@ -57,6 +57,9 @@ CCL_NAMESPACE_BEGIN
/* device capabilities */
#ifdef __KERNEL_CPU__
+#ifdef __KERNEL_SSE2__
+# define __QBVH__
+#endif
#define __KERNEL_SHADING__
#define __KERNEL_ADV_SHADING__
#define __BRANCHED_PATH__
@@ -478,7 +481,12 @@ typedef enum PrimitiveType {
PRIMITIVE_ALL_TRIANGLE = (PRIMITIVE_TRIANGLE|PRIMITIVE_MOTION_TRIANGLE),
PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE|PRIMITIVE_MOTION_CURVE),
PRIMITIVE_ALL_MOTION = (PRIMITIVE_MOTION_TRIANGLE|PRIMITIVE_MOTION_CURVE),
- PRIMITIVE_ALL = (PRIMITIVE_ALL_TRIANGLE|PRIMITIVE_ALL_CURVE)
+ PRIMITIVE_ALL = (PRIMITIVE_ALL_TRIANGLE|PRIMITIVE_ALL_CURVE),
+
+ /* Total number of different primitives.
+ * NOTE: This is an actual value, not a bitflag.
+ */
+ PRIMITIVE_NUM_TOTAL = 4,
} PrimitiveType;
#define PRIMITIVE_PACK_SEGMENT(type, segment) ((segment << 16) | type)
@@ -526,6 +534,7 @@ typedef enum AttributeStandard {
ATTR_STD_VOLUME_FLAME,
ATTR_STD_VOLUME_HEAT,
ATTR_STD_VOLUME_VELOCITY,
+ ATTR_STD_POINTINESS,
ATTR_STD_NUM,
ATTR_STD_NOT_FOUND = ~0
@@ -539,34 +548,25 @@ typedef enum AttributeStandard {
#define MAX_CLOSURE 1
#endif
-/* TODO(sergey): This is rather nasty bug happening in here, which
- * could be simply a compilers bug for which we can't find a generic
- * platform independent workaround. Also even if it's a compiler
- * issue, it's not so simple to upgrade the compiler in the release
- * environment for linux and doing it so closer to the release is
- * rather a risky business.
- *
- * For this release it's probably safer to stick with such a rather
- * dirty solution, and look for a cleaner fix during the next release
- * cycle.
+/* This struct is to be 16 bytes aligned, we also keep some extra precautions:
+ * - All the float3 members are in the beginning of the struct, so compiler
+ * does not put own padding trying to align this members.
+ * - We make sure OSL pointer is also 16 bytes aligned.
*/
typedef struct ShaderClosure {
- ClosureType type;
float3 weight;
-#ifndef __APPLE__
+ float3 N;
+ float3 T;
+
+ ClosureType type;
float sample_weight;
-#endif
float data0;
float data1;
float data2;
+ int pad1, pad2, pad3;
- float3 N;
- float3 T;
-#ifdef __APPLE__
- float sample_weight;
-#endif
#ifdef __OSL__
- void *prim;
+ void *prim, *pad4;
#endif
} ShaderClosure;
@@ -595,33 +595,32 @@ enum ShaderDataFlag {
SD_EMISSION = (1 << 1), /* have emissive closure? */
SD_BSDF = (1 << 2), /* have bsdf closure? */
SD_BSDF_HAS_EVAL = (1 << 3), /* have non-singular bsdf closure? */
- SD_PHASE_HAS_EVAL = (1 << 3), /* have non-singular phase closure? */
- SD_BSDF_GLOSSY = (1 << 4), /* have glossy bsdf */
- SD_BSSRDF = (1 << 5), /* have bssrdf */
- SD_HOLDOUT = (1 << 6), /* have holdout closure? */
- SD_ABSORPTION = (1 << 7), /* have volume absorption closure? */
- SD_SCATTER = (1 << 8), /* have volume phase closure? */
- SD_AO = (1 << 9), /* have ao closure? */
- SD_TRANSPARENT = (1 << 10), /* have transparent closure? */
-
- SD_CLOSURE_FLAGS = (SD_EMISSION|SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY|
- SD_BSSRDF|SD_HOLDOUT|SD_ABSORPTION|SD_SCATTER|SD_AO),
+ SD_BSSRDF = (1 << 4), /* have bssrdf */
+ SD_HOLDOUT = (1 << 5), /* have holdout closure? */
+ SD_ABSORPTION = (1 << 6), /* have volume absorption closure? */
+ SD_SCATTER = (1 << 7), /* have volume phase closure? */
+ SD_AO = (1 << 8), /* have ao closure? */
+ SD_TRANSPARENT = (1 << 9), /* have transparent closure? */
+
+ SD_CLOSURE_FLAGS = (SD_EMISSION|SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSSRDF|
+ SD_HOLDOUT|SD_ABSORPTION|SD_SCATTER|SD_AO),
/* shader flags */
- SD_USE_MIS = (1 << 11), /* direct light sample */
- SD_HAS_TRANSPARENT_SHADOW = (1 << 12), /* has transparent shadow */
- SD_HAS_VOLUME = (1 << 13), /* has volume shader */
- SD_HAS_ONLY_VOLUME = (1 << 14), /* has only volume shader, no surface */
- SD_HETEROGENEOUS_VOLUME = (1 << 15), /* has heterogeneous volume */
- SD_HAS_BSSRDF_BUMP = (1 << 16), /* bssrdf normal uses bump */
- SD_VOLUME_EQUIANGULAR = (1 << 17), /* use equiangular sampling */
- SD_VOLUME_MIS = (1 << 18), /* use multiple importance sampling */
- SD_VOLUME_CUBIC = (1 << 19), /* use cubic interpolation for voxels */
+ SD_USE_MIS = (1 << 10), /* direct light sample */
+ SD_HAS_TRANSPARENT_SHADOW = (1 << 11), /* has transparent shadow */
+ SD_HAS_VOLUME = (1 << 12), /* has volume shader */
+ SD_HAS_ONLY_VOLUME = (1 << 13), /* has only volume shader, no surface */
+ SD_HETEROGENEOUS_VOLUME = (1 << 14), /* has heterogeneous volume */
+ SD_HAS_BSSRDF_BUMP = (1 << 15), /* bssrdf normal uses bump */
+ SD_VOLUME_EQUIANGULAR = (1 << 16), /* use equiangular sampling */
+ SD_VOLUME_MIS = (1 << 17), /* use multiple importance sampling */
+ SD_VOLUME_CUBIC = (1 << 18), /* use cubic interpolation for voxels */
+ SD_HAS_BUMP = (1 << 19), /* has data connected to the displacement input */
SD_SHADER_FLAGS = (SD_USE_MIS|SD_HAS_TRANSPARENT_SHADOW|SD_HAS_VOLUME|
SD_HAS_ONLY_VOLUME|SD_HETEROGENEOUS_VOLUME|
SD_HAS_BSSRDF_BUMP|SD_VOLUME_EQUIANGULAR|SD_VOLUME_MIS|
- SD_VOLUME_CUBIC),
+ SD_VOLUME_CUBIC|SD_HAS_BUMP),
/* object flags */
SD_HOLDOUT_MASK = (1 << 20), /* holdout for camera rays */
@@ -630,6 +629,7 @@ enum ShaderDataFlag {
SD_NEGATIVE_SCALE_APPLIED = (1 << 23), /* vertices have negative scale applied */
SD_OBJECT_HAS_VOLUME = (1 << 24), /* object has a volume shader */
SD_OBJECT_INTERSECTS_VOLUME = (1 << 25), /* object intersects AABB of an object with volume shader */
+ SD_OBJECT_HAS_VERTEX_MOTION = (1 << 26), /* has position for motion vertices */
SD_OBJECT_FLAGS = (SD_HOLDOUT_MASK|SD_OBJECT_MOTION|SD_TRANSFORM_APPLIED|
SD_NEGATIVE_SCALE_APPLIED|SD_OBJECT_HAS_VOLUME|
@@ -767,6 +767,7 @@ typedef struct KernelCamera {
int panorama_type;
float fisheye_fov;
float fisheye_lens;
+ float4 equirectangular_range;
/* matrices */
Transform cameratoworld;
@@ -955,8 +956,8 @@ typedef struct KernelBVH {
int have_motion;
int have_curves;
int have_instancing;
-
- int pad1, pad2, pad3;
+ int use_qbvh;
+ int pad1, pad2;
} KernelBVH;
typedef enum CurveFlag {
@@ -996,7 +997,7 @@ typedef struct KernelData {
#ifdef __KERNEL_DEBUG__
typedef struct DebugData {
- // Total number of BVH node travesal steps and primitives intersections
+ // Total number of BVH node traversal steps and primitives intersections
// for the camera rays.
int num_bvh_traversal_steps;
} DebugData;
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index ce20f20e75a..0300e1d4c7f 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
@@ -581,7 +581,8 @@ ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals
* through a volume. This can then latter be used for decoupled sampling as in:
* "Importance Sampling Techniques for Path Tracing in Participating Media"
*
- * On the GPU this is only supported for homogeneous volumes (1 step), due to
+ * On the GPU this is only supported (but currently not enabled)
+ * for homogeneous volumes (1 step), due to
* no support for malloc/free and too much stack usage with a fix size array. */
typedef struct VolumeStep {
@@ -595,6 +596,7 @@ typedef struct VolumeStep {
} VolumeStep;
typedef struct VolumeSegment {
+ VolumeStep stack_step; /* stack storage for homogeneous step, to avoid malloc */
VolumeStep *steps; /* recorded steps */
int numsteps; /* number of steps */
int closure_flag; /* accumulated closure flags from all steps */
@@ -621,17 +623,22 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
float step_size, random_jitter_offset;
if(heterogeneous) {
- max_steps = kernel_data.integrator.volume_max_steps;
+ const int global_max_steps = kernel_data.integrator.volume_max_steps;
step_size = kernel_data.integrator.volume_step_size;
- random_jitter_offset = lcg_step_float(&state->rng_congruential) * step_size;
-
/* compute exact steps in advance for malloc */
max_steps = max((int)ceilf(ray->t/step_size), 1);
+ if (max_steps > global_max_steps) {
+ max_steps = global_max_steps;
+ step_size = ray->t / (float)max_steps;
+ }
+ segment->steps = (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
+ random_jitter_offset = lcg_step_float(&state->rng_congruential) * step_size;
}
else {
max_steps = 1;
step_size = ray->t;
random_jitter_offset = 0.0f;
+ segment->steps = &segment->stack_step;
}
/* init accumulation variables */
@@ -640,10 +647,9 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
float3 cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
float t = 0.0f;
- segment->closure_flag = 0;
segment->numsteps = 0;
-
- segment->steps = (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
+ segment->closure_flag = 0;
+ bool is_last_step_empty = false;
VolumeStep *step = segment->steps;
@@ -685,12 +691,24 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
step->closure_flag = closure_flag;
segment->closure_flag |= closure_flag;
+
+ is_last_step_empty = false;
+ segment->numsteps++;
}
else {
- /* store empty step (todo: skip consecutive empty steps) */
- step->sigma_t = make_float3(0.0f, 0.0f, 0.0f);
- step->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
- step->closure_flag = 0;
+ if(is_last_step_empty) {
+ /* consecutive empty step, merge */
+ step--;
+ }
+ else {
+ /* store empty step */
+ step->sigma_t = make_float3(0.0f, 0.0f, 0.0f);
+ step->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
+ step->closure_flag = 0;
+
+ segment->numsteps++;
+ is_last_step_empty = true;
+ }
}
step->accum_transmittance = accum_transmittance;
@@ -698,8 +716,6 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
step->t = new_t;
step->shade_t = t + random_jitter_offset;
- segment->numsteps++;
-
/* stop if at the end of the volume */
t = new_t;
if(t == ray->t)
@@ -729,16 +745,13 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
ccl_device void kernel_volume_decoupled_free(KernelGlobals *kg, VolumeSegment *segment)
{
- free(segment->steps);
+ if(segment->steps != &segment->stack_step)
+ free(segment->steps);
}
/* scattering for homogeneous and heterogeneous volumes, using decoupled ray
- * marching. unlike the non-decoupled functions, these do not do probalistic
- * scattering, they always scatter if there is any non-zero scattering
- * coefficient.
+ * marching. this function does not do emission or modify throughput.
*
- * these also do not do emission or modify throughput.
- *
* function is expected to return VOLUME_PATH_SCATTERED when probalistic_scatter is false */
ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
KernelGlobals *kg, PathState *state, Ray *ray, ShaderData *sd,
@@ -981,9 +994,11 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg,
int stack_index = 0, enclosed_index = 0;
int enclosed_volumes[VOLUME_STACK_SIZE];
+ int step = 0;
while(stack_index < VOLUME_STACK_SIZE - 1 &&
- enclosed_index < VOLUME_STACK_SIZE - 1)
+ enclosed_index < VOLUME_STACK_SIZE - 1 &&
+ step < 2 * VOLUME_STACK_SIZE)
{
Intersection isect;
if(!scene_intersect_volume(kg, &volume_ray, &isect)) {
@@ -992,34 +1007,33 @@ ccl_device void kernel_volume_stack_init(KernelGlobals *kg,
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, &volume_ray, 0, 0);
- if(sd.flag & SD_HAS_VOLUME) {
- if(sd.flag & SD_BACKFACING) {
- /* If ray exited the volume and never entered to that volume
- * it means that camera is inside such a volume.
- */
- bool is_enclosed = false;
- for(int i = 0; i < enclosed_index; ++i) {
- if(enclosed_volumes[i] == sd.object) {
- is_enclosed = true;
- break;
- }
- }
- if(is_enclosed == false) {
- stack[stack_index].object = sd.object;
- stack[stack_index].shader = sd.shader;
- ++stack_index;
+ if(sd.flag & SD_BACKFACING) {
+ /* If ray exited the volume and never entered to that volume
+ * it means that camera is inside such a volume.
+ */
+ bool is_enclosed = false;
+ for(int i = 0; i < enclosed_index; ++i) {
+ if(enclosed_volumes[i] == sd.object) {
+ is_enclosed = true;
+ break;
}
}
- else {
- /* If ray from camera enters the volume, this volume shouldn't
- * be added to the stak on exit.
- */
- enclosed_volumes[enclosed_index++] = sd.object;
+ if(is_enclosed == false) {
+ stack[stack_index].object = sd.object;
+ stack[stack_index].shader = sd.shader;
+ ++stack_index;
}
}
+ else {
+ /* If ray from camera enters the volume, this volume shouldn't
+ * be added to the stack on exit.
+ */
+ enclosed_volumes[enclosed_index++] = sd.object;
+ }
/* Move ray forward. */
volume_ray.P = ray_offset(sd.P, -sd.Ng);
+ ++step;
}
/* stack_index of 0 means quick checks outside of the kernel gave false
* positive, nothing to worry about, just we've wasted quite a few of
diff --git a/intern/cycles/kernel/osl/SConscript b/intern/cycles/kernel/osl/SConscript
index d721edbaf6e..58b0204a1b9 100644
--- a/intern/cycles/kernel/osl/SConscript
+++ b/intern/cycles/kernel/osl/SConscript
@@ -38,6 +38,7 @@ incs.append(env['BF_OIIO_INC'])
incs.append(env['BF_BOOST_INC'])
incs.append(env['BF_OSL_INC'])
incs.append(env['BF_OPENEXR_INC'].split())
+incs.append('#/intern/atomic')
defs.append('CCL_NAMESPACE_BEGIN=namespace ccl {')
defs.append('CCL_NAMESPACE_END=}')
@@ -46,6 +47,17 @@ defs.append('WITH_OSL')
if env['WITH_BF_CYCLES_DEBUG']:
defs.append('WITH_CYCLES_DEBUG')
+if env['WITH_BF_CYCLES_LOGGING']:
+ defs.append('WITH_CYCLES_LOGGING')
+ defs.append('GOOGLE_GLOG_DLL_DECL=')
+ defs.append('CYCLES_GFLAGS_NAMESPACE=gflags')
+ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+ incs.append('#extern/libmv/third_party/glog/src/windows')
+ incs.append('#extern/libmv/third_party/gflags')
+ else:
+ incs.append('#extern/libmv/third_party/glog/src')
+ incs.append('#extern/libmv/third_party/gflags')
+
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
cxxflags.append('-DBOOST_NO_RTTI -DBOOST_NO_TYPEID /fp:fast'.split())
incs.append(env['BF_PTHREADS_INC'])
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index cc9942b024e..461ce8f7598 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -153,26 +153,16 @@ BSDF_CLOSURE_CLASS_BEGIN(HairReflection, hair_reflection, hair_reflection, LABEL
CLOSURE_FLOAT3_PARAM(HairReflectionClosure, sc.N),
CLOSURE_FLOAT_PARAM(HairReflectionClosure, sc.data0),
CLOSURE_FLOAT_PARAM(HairReflectionClosure, sc.data1),
-#ifdef __HAIR__
CLOSURE_FLOAT3_PARAM(HairReflectionClosure, sc.T),
CLOSURE_FLOAT_PARAM(HairReflectionClosure, sc.data2),
-#else
- CLOSURE_FLOAT3_PARAM(HairReflectionClosure, sc.N),
- CLOSURE_FLOAT_PARAM(HairReflectionClosure, sc.data1),
-#endif
BSDF_CLOSURE_CLASS_END(HairReflection, hair_reflection)
BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, hair_transmission, LABEL_GLOSSY)
CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, sc.N),
CLOSURE_FLOAT_PARAM(HairTransmissionClosure, sc.data0),
CLOSURE_FLOAT_PARAM(HairTransmissionClosure, sc.data1),
-#ifdef __HAIR__
CLOSURE_FLOAT3_PARAM(HairReflectionClosure, sc.T),
CLOSURE_FLOAT_PARAM(HairReflectionClosure, sc.data2),
-#else
- CLOSURE_FLOAT3_PARAM(HairReflectionClosure, sc.N),
- CLOSURE_FLOAT_PARAM(HairReflectionClosure, sc.data1),
-#endif
BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
VOLUME_CLOSURE_CLASS_BEGIN(VolumeHenyeyGreenstein, henyey_greenstein, LABEL_VOLUME_SCATTER)
@@ -189,11 +179,7 @@ static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, O
/* optimization: it's possible to not use a prepare function at all and
* only initialize the actual class when accessing the closure component
* data, but then we need to map the id to the class somehow */
-#ifdef CLOSURE_PREPARE
- ss->register_closure(name, id, params, prepare, NULL, NULL);
-#else
- ss->register_closure(name, id, params, prepare, NULL);
-#endif
+ ss->register_closure(name, id, params, prepare, NULL, 16);
}
void OSLShader::register_closures(OSLShadingSystem *ss_)
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 9c3134e41c9..e349ac676b0 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __OSL_GLOBALS_H__
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index a9694651e14..1f6015d0d6b 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -11,9 +11,17 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
+/* TODO(sergey): There is a bit of headers dependency hell going on
+ * here, so for now we just put here. In the future it might be better
+ * to have dedicated file for such tweaks.
+ */
+#if defined(__GNUC__) && defined(NDEBUG)
+# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+
#include <string.h>
#include "mesh.h"
@@ -834,7 +842,7 @@ bool OSLRenderServices::has_userdata(ustring name, TypeDesc type, OSL::ShaderGlo
bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg,
float s, float t, float dsdx, float dtdx,
- float dsdy, float dtdy, float *result)
+ float dsdy, float dtdy, int nchannels, float *result)
{
OSL::TextureSystem *ts = osl_ts;
ShaderData *sd = (ShaderData *)(sg->renderstate);
@@ -869,9 +877,9 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
PtexFilter::Options opts(PtexFilter::f_bicubic, mipmaplerp, sharpness);
PtexPtr<PtexFilter> f(PtexFilter::getFilter(r, opts));
- f->eval(result, options.firstchannel, options.nchannels, faceid, u, v, dudx, dvdx, dudy, dvdy);
+ f->eval(result, options.firstchannel, nchannels, faceid, u, v, dudx, dvdx, dudy, dvdy);
- for(int c = r->numChannels(); c < options.nchannels; c++)
+ for(int c = r->numChannels(); c < nchannels; c++)
result[c] = result[0];
return true;
@@ -880,15 +888,15 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
bool status;
if(filename[0] == '@' && filename.find('.') == -1) {
- int slot = atoi(filename.c_str() + 1);
+ int slot = atoi(filename.c_str() + 1);
float4 rgba = kernel_tex_image_interp(slot, s, 1.0f - t);
result[0] = rgba[0];
- if(options.nchannels > 1)
+ if(nchannels > 1)
result[1] = rgba[1];
- if(options.nchannels > 2)
+ if(nchannels > 2)
result[2] = rgba[2];
- if(options.nchannels > 3)
+ if(nchannels > 3)
result[3] = rgba[3];
status = true;
}
@@ -898,17 +906,24 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info);
+#if OIIO_VERSION < 10500
status = ts->texture(th, thread_info,
- options, s, t, dsdx, dtdx, dsdy, dtdy, result);
+ options, s, t, dsdx, dtdx, dsdy, dtdy,
+ result);
+#else
+ status = ts->texture(th, thread_info,
+ options, s, t, dsdx, dtdx, dsdy, dtdy,
+ nchannels, result);
+#endif
}
if(!status) {
- if(options.nchannels == 3 || options.nchannels == 4) {
+ if(nchannels == 3 || nchannels == 4) {
result[0] = 1.0f;
result[1] = 0.0f;
result[2] = 1.0f;
- if(options.nchannels == 4)
+ if(nchannels == 4)
result[3] = 1.0f;
}
}
@@ -919,7 +934,7 @@ bool OSLRenderServices::texture(ustring filename, TextureOpt &options,
bool OSLRenderServices::texture3d(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
- const OSL::Vec3 &dPdz, float *result)
+ const OSL::Vec3 &dPdz, int nchannels, float *result)
{
OSL::TextureSystem *ts = osl_ts;
ShaderData *sd = (ShaderData *)(sg->renderstate);
@@ -929,16 +944,22 @@ bool OSLRenderServices::texture3d(ustring filename, TextureOpt &options,
OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info);
+#if OIIO_VERSION < 10500
bool status = ts->texture3d(th, thread_info,
options, P, dPdx, dPdy, dPdz, result);
+#else
+ bool status = ts->texture3d(th, thread_info,
+ options, P, dPdx, dPdy, dPdz,
+ nchannels, result);
+#endif
if(!status) {
- if(options.nchannels == 3 || options.nchannels == 4) {
+ if(nchannels == 3 || nchannels == 4) {
result[0] = 1.0f;
result[1] = 0.0f;
result[2] = 1.0f;
- if(options.nchannels == 4)
+ if(nchannels == 4)
result[3] = 1.0f;
}
@@ -949,7 +970,8 @@ bool OSLRenderServices::texture3d(ustring filename, TextureOpt &options,
bool OSLRenderServices::environment(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
- const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result)
+ const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy,
+ int nchannels, float *result)
{
OSL::TextureSystem *ts = osl_ts;
ShaderData *sd = (ShaderData *)(sg->renderstate);
@@ -958,16 +980,23 @@ bool OSLRenderServices::environment(ustring filename, TextureOpt &options,
OIIO::TextureSystem::Perthread *thread_info = tdata->oiio_thread_info;
OIIO::TextureSystem::TextureHandle *th = ts->get_texture_handle(filename, thread_info);
+
+#if OIIO_VERSION < 10500
bool status = ts->environment(th, thread_info,
options, R, dRdx, dRdy, result);
+#else
+ bool status = ts->environment(th, thread_info,
+ options, R, dRdx, dRdy,
+ nchannels, result);
+#endif
if(!status) {
- if(options.nchannels == 3 || options.nchannels == 4) {
+ if(nchannels == 3 || nchannels == 4) {
result[0] = 1.0f;
result[1] = 0.0f;
result[2] = 1.0f;
- if(options.nchannels == 4)
+ if(nchannels == 4)
result[3] = 1.0f;
}
}
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index 6f928a0d103..190234a7706 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __OSL_SERVICES_H__
@@ -97,16 +97,17 @@ public:
bool texture(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg,
float s, float t, float dsdx, float dtdx,
- float dsdy, float dtdy, float *result);
+ float dsdy, float dtdy, int nchannels, float *result);
bool texture3d(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
- const OSL::Vec3 &dPdz, float *result);
+ const OSL::Vec3 &dPdz, int nchannels, float *result);
bool environment(ustring filename, TextureOpt &options,
OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
- const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy, float *result);
+ const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy,
+ int nchannels, float *result);
bool get_texture_info(OSL::ShaderGlobals *sg, ustring filename, int subimage,
ustring dataname, TypeDesc datatype, void *data);
@@ -159,70 +160,37 @@ public:
static ustring u_v;
static ustring u_empty;
-#if OSL_LIBRARY_VERSION_CODE < 10500
- bool get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform, float time) {
- return get_matrix(NULL, result, xform, time);
- }
-
- bool get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform, float time) {
- return get_inverse_matrix(NULL, result, xform, time);
- }
-
- bool get_matrix(OSL::Matrix44 &result, ustring from, float time) {
- return get_matrix(NULL, result, from, time);
- }
-
- bool get_inverse_matrix(OSL::Matrix44 &result, ustring to, float time) {
- return get_inverse_matrix(NULL, result, to, time);
- }
-
- bool get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform) {
- return get_matrix(NULL, result, xform);
- }
-
- bool get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform) {
- return get_inverse_matrix(NULL, result, xform);
- }
+ /* Code to make OSL versions transition smooth. */
- bool get_matrix(OSL::Matrix44 &result, ustring from) {
- return get_matrix(NULL, result, from);
+#if OSL_LIBRARY_VERSION_CODE < 10600
+ inline bool texture(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg,
+ float s, float t, float dsdx, float dtdx,
+ float dsdy, float dtdy, float *result)
+ {
+ return texture(filename, options, sg, s, t, dsdx, dtdx, dsdy, dtdy,
+ options.nchannels, result);
}
- bool get_inverse_matrix(OSL::Matrix44 &result, ustring to) {
- return get_inverse_matrix(NULL, result, to);
+ inline bool texture3d(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg, const OSL::Vec3 &P,
+ const OSL::Vec3 &dPdx, const OSL::Vec3 &dPdy,
+ const OSL::Vec3 &dPdz, float *result)
+ {
+ return texture3d(filename, options, sg, P, dPdx, dPdy, dPdz,
+ options.nchannels, result);
}
- bool get_array_attribute(void *renderstate, bool derivatives,
- ustring object, TypeDesc type, ustring name,
- int index, void *val) {
- OSL::ShaderGlobals sg;
- sg.renderstate = renderstate;
- return get_array_attribute(&sg, derivatives,
- object, type, name,
- index, val);
- }
-
- bool get_attribute(void *renderstate, bool derivatives, ustring object_name,
- TypeDesc type, ustring name, void *val) {
- OSL::ShaderGlobals sg;
- sg.renderstate = renderstate;
- return get_attribute(&sg, derivatives, object_name, type, name, val);
- }
-
- bool has_userdata(ustring name, TypeDesc type, void *renderstate) {
- return has_userdata(name, type, (OSL::ShaderGlobals *) renderstate);
- }
-
- bool get_userdata(bool derivatives, ustring name, TypeDesc type,
- void *renderstate, void *val) {
- return get_userdata(derivatives, name, type, (OSL::ShaderGlobals *) renderstate, val);
- }
-
- bool get_texture_info(ustring filename, int subimage,
- ustring dataname, TypeDesc datatype, void *data) {
- return get_texture_info(NULL, filename, subimage, dataname, datatype, data);
+ inline bool environment(ustring filename, TextureOpt &options,
+ OSL::ShaderGlobals *sg, const OSL::Vec3 &R,
+ const OSL::Vec3 &dRdx, const OSL::Vec3 &dRdy,
+ float *result)
+ {
+ return environment(filename, options, sg, R, dRdx, dRdy,
+ options.nchannels, result);
}
#endif
+
private:
KernelGlobals *kernel_globals;
OSL::TextureSystem *osl_ts;
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index ca0c2cc4415..ebf72ae11f4 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <OSL/oslexec.h>
diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h
index 40f50d8b0e9..15dd74f9d38 100644
--- a/intern/cycles/kernel/osl/osl_shader.h
+++ b/intern/cycles/kernel/osl/osl_shader.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __OSL_SHADER_H__
diff --git a/intern/cycles/kernel/shaders/node_absorption_volume.osl b/intern/cycles/kernel/shaders/node_absorption_volume.osl
index 6bac83ba4f5..18f662ebbbd 100644
--- a/intern/cycles/kernel/shaders/node_absorption_volume.osl
+++ b/intern/cycles/kernel/shaders/node_absorption_volume.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_add_closure.osl b/intern/cycles/kernel/shaders/node_add_closure.osl
index b826fb22784..b6596e0b6bd 100644
--- a/intern/cycles/kernel/shaders/node_add_closure.osl
+++ b/intern/cycles/kernel/shaders/node_add_closure.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
index 961aed1016b..5f056122bbe 100644
--- a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
+++ b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl b/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl
index da1e4f77107..281ed4e8726 100644
--- a/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_anisotropic_bsdf.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_attribute.osl b/intern/cycles/kernel/shaders/node_attribute.osl
index 43f69fab053..67183e9ffe0 100644
--- a/intern/cycles/kernel/shaders/node_attribute.osl
+++ b/intern/cycles/kernel/shaders/node_attribute.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_background.osl b/intern/cycles/kernel/shaders/node_background.osl
index c4379a8f71b..613d4e360fa 100644
--- a/intern/cycles/kernel/shaders/node_background.osl
+++ b/intern/cycles/kernel/shaders/node_background.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_blackbody.osl b/intern/cycles/kernel/shaders/node_blackbody.osl
index d26e56ab06d..1da6894d0f0 100644
--- a/intern/cycles/kernel/shaders/node_blackbody.osl
+++ b/intern/cycles/kernel/shaders/node_blackbody.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl
index c9fb3542aef..e26e8dbff2c 100644
--- a/intern/cycles/kernel/shaders/node_brick_texture.osl
+++ b/intern/cycles/kernel/shaders/node_brick_texture.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
@@ -87,10 +87,7 @@ shader node_brick_texture(
if (Fac != 1.0) {
float facm = 1.0 - tint;
-
- Col[0] = facm * (Color1[0]) + tint * Color2[0];
- Col[1] = facm * (Color1[1]) + tint * Color2[1];
- Col[2] = facm * (Color1[2]) + tint * Color2[2];
+ Col = facm * Color1 + tint * Color2;
}
Color = (Fac == 1.0) ? Mortar : Col;
diff --git a/intern/cycles/kernel/shaders/node_brightness.osl b/intern/cycles/kernel/shaders/node_brightness.osl
index 468b0f052c3..00cfb167885 100644
--- a/intern/cycles/kernel/shaders/node_brightness.osl
+++ b/intern/cycles/kernel/shaders/node_brightness.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_bump.osl b/intern/cycles/kernel/shaders/node_bump.osl
index bbc08760cd5..9882857f2ec 100644
--- a/intern/cycles/kernel/shaders/node_bump.osl
+++ b/intern/cycles/kernel/shaders/node_bump.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_camera.osl b/intern/cycles/kernel/shaders/node_camera.osl
index 20ebb7dc095..5e90cb8b8ee 100644
--- a/intern/cycles/kernel/shaders/node_camera.osl
+++ b/intern/cycles/kernel/shaders/node_camera.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_checker_texture.osl b/intern/cycles/kernel/shaders/node_checker_texture.osl
index a6d21fd36f3..ae84c71dd42 100644
--- a/intern/cycles/kernel/shaders/node_checker_texture.osl
+++ b/intern/cycles/kernel/shaders/node_checker_texture.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_color.h b/intern/cycles/kernel/shaders/node_color.h
index 095e628f20c..4a17286a07f 100644
--- a/intern/cycles/kernel/shaders/node_color.h
+++ b/intern/cycles/kernel/shaders/node_color.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
float color_srgb_to_scene_linear(float c)
diff --git a/intern/cycles/kernel/shaders/node_combine_hsv.osl b/intern/cycles/kernel/shaders/node_combine_hsv.osl
index 010773acc5c..6b922bf4e6b 100644
--- a/intern/cycles/kernel/shaders/node_combine_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_combine_hsv.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_combine_rgb.osl b/intern/cycles/kernel/shaders/node_combine_rgb.osl
index 8466a89b536..f343fdefd84 100644
--- a/intern/cycles/kernel/shaders/node_combine_rgb.osl
+++ b/intern/cycles/kernel/shaders/node_combine_rgb.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_combine_xyz.osl b/intern/cycles/kernel/shaders/node_combine_xyz.osl
index 933dee5bd78..86182056b09 100644
--- a/intern/cycles/kernel/shaders/node_combine_xyz.osl
+++ b/intern/cycles/kernel/shaders/node_combine_xyz.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_convert_from_color.osl b/intern/cycles/kernel/shaders/node_convert_from_color.osl
index 2f4503e66e3..44074317f42 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_color.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_color.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_convert_from_float.osl b/intern/cycles/kernel/shaders/node_convert_from_float.osl
index f5b91903078..fc5c79c4c64 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_float.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_float.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_convert_from_int.osl b/intern/cycles/kernel/shaders/node_convert_from_int.osl
index 110922a5df1..3c3785ebc0d 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_int.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_int.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_convert_from_normal.osl b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
index 995c86d8828..8ecc56ac8ce 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_normal.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_convert_from_point.osl b/intern/cycles/kernel/shaders/node_convert_from_point.osl
index 2ed151273a8..e5913b7a1e4 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_point.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_point.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_convert_from_string.osl b/intern/cycles/kernel/shaders/node_convert_from_string.osl
index 50cce252be4..0466734277b 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_string.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_string.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_convert_from_vector.osl b/intern/cycles/kernel/shaders/node_convert_from_vector.osl
index 035c46625a0..79c5cb04550 100644
--- a/intern/cycles/kernel/shaders/node_convert_from_vector.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_vector.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
index e8c94660e4f..2bef2d65baa 100644
--- a/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_emission.osl b/intern/cycles/kernel/shaders/node_emission.osl
index b28d731c19f..c36e2a4c0f3 100644
--- a/intern/cycles/kernel/shaders/node_emission.osl
+++ b/intern/cycles/kernel/shaders/node_emission.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl
index 136ccdf8b18..14f0226a0e5 100644
--- a/intern/cycles/kernel/shaders/node_environment_texture.osl
+++ b/intern/cycles/kernel/shaders/node_environment_texture.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_fresnel.h b/intern/cycles/kernel/shaders/node_fresnel.h
index d192c5d02de..de2d40a849c 100644
--- a/intern/cycles/kernel/shaders/node_fresnel.h
+++ b/intern/cycles/kernel/shaders/node_fresnel.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
float fresnel_dielectric_cos(float cosi, float eta)
diff --git a/intern/cycles/kernel/shaders/node_fresnel.osl b/intern/cycles/kernel/shaders/node_fresnel.osl
index 7ef553c0f39..8bec7b432f5 100644
--- a/intern/cycles/kernel/shaders/node_fresnel.osl
+++ b/intern/cycles/kernel/shaders/node_fresnel.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_gamma.osl b/intern/cycles/kernel/shaders/node_gamma.osl
index a2ad3f766fe..bc4c1b34266 100644
--- a/intern/cycles/kernel/shaders/node_gamma.osl
+++ b/intern/cycles/kernel/shaders/node_gamma.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl
index cd68f07b21e..b0bd7692489 100644
--- a/intern/cycles/kernel/shaders/node_geometry.osl
+++ b/intern/cycles/kernel/shaders/node_geometry.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
@@ -26,7 +26,8 @@ shader node_geometry(
output normal TrueNormal = normal(0.0, 0.0, 0.0),
output vector Incoming = vector(0.0, 0.0, 0.0),
output point Parametric = point(0.0, 0.0, 0.0),
- output float Backfacing = 0.0)
+ output float Backfacing = 0.0,
+ output float Pointiness = 0.0)
{
Position = P;
Normal = NormalIn;
@@ -57,5 +58,13 @@ shader node_geometry(
/* otherwise use surface derivatives */
Tangent = normalize(dPdu);
}
+
+ getattribute("geom:pointiness", Pointiness);
+ if (bump_offset == "dx") {
+ Pointiness += Dx(Pointiness);
+ }
+ else if (bump_offset == "dy") {
+ Pointiness += Dy(Pointiness);
+ }
}
diff --git a/intern/cycles/kernel/shaders/node_glass_bsdf.osl b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
index b3d6133553b..68bc107cc5e 100644
--- a/intern/cycles/kernel/shaders/node_glass_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
index 5c727ca6917..d3250b32d0b 100644
--- a/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_gradient_texture.osl b/intern/cycles/kernel/shaders/node_gradient_texture.osl
index 5aa05917dc2..52b49688ab3 100644
--- a/intern/cycles/kernel/shaders/node_gradient_texture.osl
+++ b/intern/cycles/kernel/shaders/node_gradient_texture.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_hair_info.osl b/intern/cycles/kernel/shaders/node_hair_info.osl
index 1d1ba1983e1..965d2a3c7f7 100644
--- a/intern/cycles/kernel/shaders/node_hair_info.osl
+++ b/intern/cycles/kernel/shaders/node_hair_info.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_holdout.osl b/intern/cycles/kernel/shaders/node_holdout.osl
index cafad1b5757..78a9f46fd15 100644
--- a/intern/cycles/kernel/shaders/node_holdout.osl
+++ b/intern/cycles/kernel/shaders/node_holdout.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_hsv.osl b/intern/cycles/kernel/shaders/node_hsv.osl
index 4722bde4cd7..8d9e50fed6b 100644
--- a/intern/cycles/kernel/shaders/node_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_hsv.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
@@ -35,6 +35,11 @@ shader node_hsv(
Color = hsv_to_rgb(Color);
+ // Clamp color to prevent negative values cauzed by oversaturation.
+ Color[0] = max(Color[0], 0.0);
+ Color[1] = max(Color[1], 0.0);
+ Color[2] = max(Color[2], 0.0);
+
ColorOut = mix(ColorIn, Color, Fac);
}
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl
index 18b5fb4b31f..526a87525cd 100644
--- a/intern/cycles/kernel/shaders/node_image_texture.osl
+++ b/intern/cycles/kernel/shaders/node_image_texture.osl
@@ -11,12 +11,50 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
#include "node_color.h"
+point texco_remap_square(point co)
+{
+ return (co - point(0.5, 0.5, 0.5)) * 2.0;
+}
+
+point map_to_tube(vector dir)
+{
+ float u, v;
+ v = (dir[2] + 1.0) * 0.5;
+ float len = sqrt(dir[0]*dir[0] + dir[1]*dir[1]);
+ if (len > 0.0) {
+ u = (1.0 - (atan2(dir[0] / len, dir[1] / len) / M_PI)) * 0.5;
+ }
+ else {
+ v = u = 0.0; /* To avoid un-initialized variables. */
+ }
+ return point(u, v, 0.0);
+}
+
+point map_to_sphere(vector dir)
+{
+ float len = length(dir);
+ float v, u;
+ if(len > 0.0) {
+ if(dir[0] == 0.0 && dir[1] == 0.0) {
+ u = 0.0; /* Othwise domain error. */
+ }
+ else {
+ u = (1.0 - atan2(dir[0], dir[1]) / M_PI) / 2.0;
+ }
+ v = 1.0 - acos(dir[2] / len) / M_PI;
+ }
+ else {
+ v = u = 0.0; /* To avoid un-initialized variables. */
+ }
+ return point(u, v, 0.0);
+}
+
color image_texture_lookup(string filename, string color_space, float u, float v, output float Alpha, int use_alpha, int is_float, string interpolation)
{
color rgb = (color)texture(filename, u, 1.0 - v, "wrap", "periodic", "interp", interpolation, "alpha", Alpha);
@@ -136,5 +174,16 @@ shader node_image_texture(
Alpha += weight[2] * tmp_alpha;
}
}
+ else if (projection == "Sphere") {
+ point projected = map_to_sphere(texco_remap_square(p));
+ Color = image_texture_lookup(filename, color_space,
+ projected[0], projected[1],
+ Alpha, use_alpha, is_float, interpolation);
+ }
+ else if (projection == "Tube") {
+ point projected = map_to_tube(texco_remap_square(p));
+ Color = image_texture_lookup(filename, color_space,
+ projected[0], projected[1],
+ Alpha, use_alpha, is_float, interpolation);
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/node_invert.osl b/intern/cycles/kernel/shaders/node_invert.osl
index 81ef2d0dc3d..b33b0a43d63 100644
--- a/intern/cycles/kernel/shaders/node_invert.osl
+++ b/intern/cycles/kernel/shaders/node_invert.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_layer_weight.osl b/intern/cycles/kernel/shaders/node_layer_weight.osl
index d03ebe2239a..f583df25773 100644
--- a/intern/cycles/kernel/shaders/node_layer_weight.osl
+++ b/intern/cycles/kernel/shaders/node_layer_weight.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_light_falloff.osl b/intern/cycles/kernel/shaders/node_light_falloff.osl
index 311b87f3764..a594e33d643 100644
--- a/intern/cycles/kernel/shaders/node_light_falloff.osl
+++ b/intern/cycles/kernel/shaders/node_light_falloff.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_light_path.osl b/intern/cycles/kernel/shaders/node_light_path.osl
index 95fbcabf917..99a92c4f403 100644
--- a/intern/cycles/kernel/shaders/node_light_path.osl
+++ b/intern/cycles/kernel/shaders/node_light_path.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_magic_texture.osl b/intern/cycles/kernel/shaders/node_magic_texture.osl
index b8afc6e29ac..c09523f205b 100644
--- a/intern/cycles/kernel/shaders/node_magic_texture.osl
+++ b/intern/cycles/kernel/shaders/node_magic_texture.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_mapping.osl b/intern/cycles/kernel/shaders/node_mapping.osl
index 46ff9f05e07..69106957ee4 100644
--- a/intern/cycles/kernel/shaders/node_mapping.osl
+++ b/intern/cycles/kernel/shaders/node_mapping.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_math.osl b/intern/cycles/kernel/shaders/node_math.osl
index abb6a359e75..bbc008b4299 100644
--- a/intern/cycles/kernel/shaders/node_math.osl
+++ b/intern/cycles/kernel/shaders/node_math.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_mix.osl b/intern/cycles/kernel/shaders/node_mix.osl
index dd54fd814de..9ef58e4cbba 100644
--- a/intern/cycles/kernel/shaders/node_mix.osl
+++ b/intern/cycles/kernel/shaders/node_mix.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_mix_closure.osl b/intern/cycles/kernel/shaders/node_mix_closure.osl
index 79d71c97371..5946dfdaaba 100644
--- a/intern/cycles/kernel/shaders/node_mix_closure.osl
+++ b/intern/cycles/kernel/shaders/node_mix_closure.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
index a32c3d4b1b8..a349dc8cb9a 100644
--- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_noise_texture.osl b/intern/cycles/kernel/shaders/node_noise_texture.osl
index 912795966e0..dabc0b6843f 100644
--- a/intern/cycles/kernel/shaders/node_noise_texture.osl
+++ b/intern/cycles/kernel/shaders/node_noise_texture.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_normal.osl b/intern/cycles/kernel/shaders/node_normal.osl
index 14af044e0c0..2d04978fc72 100644
--- a/intern/cycles/kernel/shaders/node_normal.osl
+++ b/intern/cycles/kernel/shaders/node_normal.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
@@ -23,6 +23,6 @@ shader node_normal(
output float Dot = 1.0)
{
NormalOut = normalize(Direction);
- Dot = dot(NormalOut, NormalIn);
+ Dot = dot(NormalOut, normalize(NormalIn));
}
diff --git a/intern/cycles/kernel/shaders/node_normal_map.osl b/intern/cycles/kernel/shaders/node_normal_map.osl
index c2080ecb194..01be566fb20 100644
--- a/intern/cycles/kernel/shaders/node_normal_map.osl
+++ b/intern/cycles/kernel/shaders/node_normal_map.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_object_info.osl b/intern/cycles/kernel/shaders/node_object_info.osl
index 1ebe767e82d..dd7c663b8d8 100644
--- a/intern/cycles/kernel/shaders/node_object_info.osl
+++ b/intern/cycles/kernel/shaders/node_object_info.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_output_displacement.osl b/intern/cycles/kernel/shaders/node_output_displacement.osl
index 613d6be5f3b..d0688cfda8d 100644
--- a/intern/cycles/kernel/shaders/node_output_displacement.osl
+++ b/intern/cycles/kernel/shaders/node_output_displacement.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_output_surface.osl b/intern/cycles/kernel/shaders/node_output_surface.osl
index fb16e85ce0d..2cc4575a8c8 100644
--- a/intern/cycles/kernel/shaders/node_output_surface.osl
+++ b/intern/cycles/kernel/shaders/node_output_surface.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_output_volume.osl b/intern/cycles/kernel/shaders/node_output_volume.osl
index 11a884b7d75..f220ba866e3 100644
--- a/intern/cycles/kernel/shaders/node_output_volume.osl
+++ b/intern/cycles/kernel/shaders/node_output_volume.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_particle_info.osl b/intern/cycles/kernel/shaders/node_particle_info.osl
index 077b0c114da..768b7753d02 100644
--- a/intern/cycles/kernel/shaders/node_particle_info.osl
+++ b/intern/cycles/kernel/shaders/node_particle_info.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
index 4a32415b482..d458ca730a4 100644
--- a/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_rgb_curves.osl b/intern/cycles/kernel/shaders/node_rgb_curves.osl
index 4e0f8721144..60cb273ba98 100644
--- a/intern/cycles/kernel/shaders/node_rgb_curves.osl
+++ b/intern/cycles/kernel/shaders/node_rgb_curves.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_rgb_ramp.osl b/intern/cycles/kernel/shaders/node_rgb_ramp.osl
index d3c2e9573d2..0202ba0bf79 100644
--- a/intern/cycles/kernel/shaders/node_rgb_ramp.osl
+++ b/intern/cycles/kernel/shaders/node_rgb_ramp.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_scatter_volume.osl b/intern/cycles/kernel/shaders/node_scatter_volume.osl
index 77c157bd92b..002e2750fca 100644
--- a/intern/cycles/kernel/shaders/node_scatter_volume.osl
+++ b/intern/cycles/kernel/shaders/node_scatter_volume.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_separate_hsv.osl b/intern/cycles/kernel/shaders/node_separate_hsv.osl
index 94fc5de9122..2a804040294 100644
--- a/intern/cycles/kernel/shaders/node_separate_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_separate_hsv.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_separate_rgb.osl b/intern/cycles/kernel/shaders/node_separate_rgb.osl
index aebb63a0ee4..43d9e3aa4b1 100644
--- a/intern/cycles/kernel/shaders/node_separate_rgb.osl
+++ b/intern/cycles/kernel/shaders/node_separate_rgb.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_separate_xyz.osl b/intern/cycles/kernel/shaders/node_separate_xyz.osl
index 63725cb9995..e1963a1902f 100644
--- a/intern/cycles/kernel/shaders/node_separate_xyz.osl
+++ b/intern/cycles/kernel/shaders/node_separate_xyz.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_set_normal.osl b/intern/cycles/kernel/shaders/node_set_normal.osl
index 8eef152308a..7ca7ac9350c 100644
--- a/intern/cycles/kernel/shaders/node_set_normal.osl
+++ b/intern/cycles/kernel/shaders/node_set_normal.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl
index 85c2dbdb2c2..05eed23bea8 100644
--- a/intern/cycles/kernel/shaders/node_sky_texture.osl
+++ b/intern/cycles/kernel/shaders/node_sky_texture.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
index 1c0cd74c0be..dbbf657776c 100644
--- a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
+++ b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_tangent.osl b/intern/cycles/kernel/shaders/node_tangent.osl
index 41a2b2b0216..53a47396f9f 100644
--- a/intern/cycles/kernel/shaders/node_tangent.osl
+++ b/intern/cycles/kernel/shaders/node_tangent.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h
index 2710eed414a..5f9cd5afa47 100644
--- a/intern/cycles/kernel/shaders/node_texture.h
+++ b/intern/cycles/kernel/shaders/node_texture.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* Voronoi Distances */
diff --git a/intern/cycles/kernel/shaders/node_texture_coordinate.osl b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
index 8fdf469df21..9e2109fa082 100644
--- a/intern/cycles/kernel/shaders/node_texture_coordinate.osl
+++ b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
@@ -21,7 +21,9 @@ shader node_texture_coordinate(
int is_background = 0,
int is_volume = 0,
int from_dupli = 0,
+ int use_transform = 0,
string bump_offset = "center",
+ matrix object_itfm = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
output point Generated = point(0.0, 0.0, 0.0),
output point UV = point(0.0, 0.0, 0.0),
@@ -60,7 +62,12 @@ shader node_texture_coordinate(
getattribute("geom:uv", UV);
}
- Object = transform("object", P);
+ if (use_transform) {
+ Object = transform(object_itfm, P);
+ }
+ else {
+ Object = transform("object", P);
+ }
Camera = transform("camera", P);
Window = transform("NDC", P);
Normal = transform("world", "object", NormalIn);
diff --git a/intern/cycles/kernel/shaders/node_toon_bsdf.osl b/intern/cycles/kernel/shaders/node_toon_bsdf.osl
index 1f7e1b8e6e1..75c5d06f847 100644
--- a/intern/cycles/kernel/shaders/node_toon_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_toon_bsdf.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_translucent_bsdf.osl b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
index 8059f5788ec..94d23d35326 100644
--- a/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_transparent_bsdf.osl b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
index 552e4106b0c..5d6798f19a6 100644
--- a/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_uv_map.osl b/intern/cycles/kernel/shaders/node_uv_map.osl
index 01c984aff4c..77e2e8d12d7 100644
--- a/intern/cycles/kernel/shaders/node_uv_map.osl
+++ b/intern/cycles/kernel/shaders/node_uv_map.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_value.osl b/intern/cycles/kernel/shaders/node_value.osl
index aebfab35d2a..f75388d1f76 100644
--- a/intern/cycles/kernel/shaders/node_value.osl
+++ b/intern/cycles/kernel/shaders/node_value.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_vector_curves.osl b/intern/cycles/kernel/shaders/node_vector_curves.osl
index 137ebe112eb..7bbf97d95ea 100644
--- a/intern/cycles/kernel/shaders/node_vector_curves.osl
+++ b/intern/cycles/kernel/shaders/node_vector_curves.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_vector_math.osl b/intern/cycles/kernel/shaders/node_vector_math.osl
index 0c8857deae2..f83412dc0f7 100644
--- a/intern/cycles/kernel/shaders/node_vector_math.osl
+++ b/intern/cycles/kernel/shaders/node_vector_math.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_vector_transform.osl b/intern/cycles/kernel/shaders/node_vector_transform.osl
index 6fb0ab1d8cc..8ebaa31ab25 100644
--- a/intern/cycles/kernel/shaders/node_vector_transform.osl
+++ b/intern/cycles/kernel/shaders/node_vector_transform.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_velvet_bsdf.osl b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
index 37b26babc64..456c26998c8 100644
--- a/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_voronoi_texture.osl b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
index 7a1e0016690..df169599d08 100644
--- a/intern/cycles/kernel/shaders/node_voronoi_texture.osl
+++ b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl
index ba40207b446..a95752fc592 100644
--- a/intern/cycles/kernel/shaders/node_wave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_wave_texture.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_wavelength.osl b/intern/cycles/kernel/shaders/node_wavelength.osl
index 4333c1fd944..79e7043d4bf 100644
--- a/intern/cycles/kernel/shaders/node_wavelength.osl
+++ b/intern/cycles/kernel/shaders/node_wavelength.osl
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
diff --git a/intern/cycles/kernel/shaders/node_wireframe.osl b/intern/cycles/kernel/shaders/node_wireframe.osl
index db8925c9efc..5cc214495dd 100644
--- a/intern/cycles/kernel/shaders/node_wireframe.osl
+++ b/intern/cycles/kernel/shaders/node_wireframe.osl
@@ -11,17 +11,31 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "stdosl.h"
#include "oslutil.h"
shader node_wireframe(
+ string bump_offset = "center",
int use_pixel_size = 0,
float Size = 0.01,
output float Fac = 0.0)
{
Fac = wireframe("triangles", Size, use_pixel_size);
+ /* TODO(sergey): Since we can't use autodiff here we do algebraic
+ * calculation of derivatives by definition. We could probably
+ * optimize this a bit by doing some extra calculation in wireframe().
+ */
+ if (bump_offset == "dx") {
+ point dx = Dx(P);
+ P -= dx;
+ Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dx);
+ }
+ else if (bump_offset == "dy") {
+ point dy = Dy(P);
+ P -= dy;
+ Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dy);
+ }
}
-
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index 1ff8f363b49..6babe98717c 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -505,6 +505,47 @@ closure color hair_transmission(normal N, float roughnessu, float roughnessv, ve
closure color henyey_greenstein(float g) BUILTIN;
closure color absorption() BUILTIN;
+// OSL 1.5 Microfacet functions
+closure color microfacet(string distribution, normal N, vector U, float xalpha, float yalpha, float eta, int refract) {
+ /* GGX */
+ if (distribution == "ggx" || distribution == "default") {
+ if (!refract) {
+ if (xalpha == yalpha) {
+ /* Isotropic */
+ return microfacet_ggx(N, xalpha);
+ }
+ else {
+ /* Anisotropic */
+ return microfacet_ggx_aniso(N, U, xalpha, yalpha);
+ }
+ }
+ else {
+ return microfacet_ggx_refraction(N, xalpha, eta);
+ }
+ }
+ /* Beckmann */
+ else {
+ if (!refract) {
+ if (xalpha == yalpha) {
+ /* Isotropic */
+ return microfacet_beckmann(N, xalpha);
+ }
+ else {
+ /* Anisotropic */
+ return microfacet_beckmann_aniso(N, U, xalpha, yalpha);
+ }
+ }
+ else {
+ return microfacet_beckmann_refraction(N, xalpha, eta);
+ }
+ }
+}
+
+closure color microfacet (string distribution, normal N, float alpha, float eta, int refract) {
+ return microfacet(distribution, N, vector(0), alpha, alpha, eta, refract);
+}
+
+
// Renderer state
int backfacing () BUILTIN;
int raytype (string typename) BUILTIN;
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index c13eae813d6..d59c9b9e61c 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SVM_H__
@@ -164,6 +164,7 @@ CCL_NAMESPACE_END
#include "svm_mapping.h"
#include "svm_normal.h"
#include "svm_wave.h"
+#include "svm_math_util.h"
#include "svm_math.h"
#include "svm_mix.h"
#include "svm_ramp.h"
@@ -360,7 +361,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
break;
#ifdef __EXTRA_NODES__
case NODE_WIREFRAME:
- svm_node_wireframe(kg, sd, stack, node.y, node.z, node.w);
+ svm_node_wireframe(kg, sd, stack, node);
break;
case NODE_WAVELENGTH:
svm_node_wavelength(sd, stack, node.y, node.z);
@@ -394,14 +395,14 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
svm_node_min_max(kg, sd, stack, node.y, node.z, &offset);
break;
case NODE_TEX_COORD:
- svm_node_tex_coord(kg, sd, path_flag, stack, node.y, node.z);
+ svm_node_tex_coord(kg, sd, path_flag, stack, node, &offset);
break;
#ifdef __EXTRA_NODES__
case NODE_TEX_COORD_BUMP_DX:
- svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node.y, node.z);
+ svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node, &offset);
break;
case NODE_TEX_COORD_BUMP_DY:
- svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node.y, node.z);
+ svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node, &offset);
break;
case NODE_CLOSURE_SET_NORMAL:
svm_node_set_normal(kg, sd, stack, node.y, node.z );
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index fd0ea7fef31..b63978b6e1f 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_brick.h b/intern/cycles/kernel/svm/svm_brick.h
index 97c2b545c5f..33a2a5c7598 100644
--- a/intern/cycles/kernel/svm/svm_brick.h
+++ b/intern/cycles/kernel/svm/svm_brick.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
@@ -95,10 +95,7 @@ ccl_device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *sta
if(f != 1.0f) {
float facm = 1.0f - tint;
-
- color1.x = facm * (color1.x) + tint * color2.x;
- color1.y = facm * (color1.y) + tint * color2.y;
- color1.z = facm * (color1.z) + tint * color2.z;
+ color1 = facm * color1 + tint * color2;
}
if(stack_valid(color_offset))
diff --git a/intern/cycles/kernel/svm/svm_brightness.h b/intern/cycles/kernel/svm/svm_brightness.h
index 9b330b3213f..631bd1825ee 100644
--- a/intern/cycles/kernel/svm/svm_brightness.h
+++ b/intern/cycles/kernel/svm/svm_brightness.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_camera.h b/intern/cycles/kernel/svm/svm_camera.h
index bfe9289fa02..e03745cb331 100644
--- a/intern/cycles/kernel/svm/svm_camera.h
+++ b/intern/cycles/kernel/svm/svm_camera.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_checker.h b/intern/cycles/kernel/svm/svm_checker.h
index e0408ad334a..186bf7df55f 100644
--- a/intern/cycles/kernel/svm/svm_checker.h
+++ b/intern/cycles/kernel/svm/svm_checker.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 30110db3ef9..07ac7104e68 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
@@ -402,7 +402,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
sc->data2 = 0.0f;
}
else
- sc->T = sd->dPdu;
+ sc->T = normalize(sd->dPdu);
if(type == CLOSURE_BSDF_HAIR_REFLECTION_ID) {
sd->flag |= bsdf_hair_reflection_setup(sc);
@@ -528,8 +528,7 @@ ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight * density);
if(sc) {
- float g = param2;
- sc->data0 = g;
+ sc->data0 = param2; /* g */
sd->flag |= volume_henyey_greenstein_setup(sc);
}
break;
diff --git a/intern/cycles/kernel/svm/svm_convert.h b/intern/cycles/kernel/svm/svm_convert.h
index b221e0728ec..34080377083 100644
--- a/intern/cycles/kernel/svm/svm_convert.h
+++ b/intern/cycles/kernel/svm/svm_convert.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h
index 6cd5ee4b375..4a058905a93 100644
--- a/intern/cycles/kernel/svm/svm_displace.h
+++ b/intern/cycles/kernel/svm/svm_displace.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_fresnel.h b/intern/cycles/kernel/svm/svm_fresnel.h
index 5def52205eb..3703ec55015 100644
--- a/intern/cycles/kernel/svm/svm_fresnel.h
+++ b/intern/cycles/kernel/svm/svm_fresnel.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_gamma.h b/intern/cycles/kernel/svm/svm_gamma.h
index c4749e7b936..8bc59b9c673 100644
--- a/intern/cycles/kernel/svm/svm_gamma.h
+++ b/intern/cycles/kernel/svm/svm_gamma.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index fe681ec92af..efbefa77d28 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_gradient.h b/intern/cycles/kernel/svm/svm_gradient.h
index a4b3c0583f7..a5e385faddc 100644
--- a/intern/cycles/kernel/svm/svm_gradient.h
+++ b/intern/cycles/kernel/svm/svm_gradient.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_hsv.h b/intern/cycles/kernel/svm/svm_hsv.h
index 11dfc4f096b..eeb4ba25e91 100644
--- a/intern/cycles/kernel/svm/svm_hsv.h
+++ b/intern/cycles/kernel/svm/svm_hsv.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SVM_HSV_H__
@@ -46,6 +46,11 @@ ccl_device void svm_node_hsv(KernelGlobals *kg, ShaderData *sd, float *stack, ui
color.y = fac*color.y + (1.0f - fac)*in_color.y;
color.z = fac*color.z + (1.0f - fac)*in_color.z;
+ /* Clamp color to prevent negative values cauzed by oversaturation. */
+ color.x = max(color.x, 0.0f);
+ color.y = max(color.y, 0.0f);
+ color.z = max(color.z, 0.0f);
+
if (stack_valid(out_color_offset))
stack_store_float3(stack, out_color_offset, color);
}
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 8a256c9bda5..4de69479bd9 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
@@ -354,6 +354,12 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
#endif
+/* Remap coordnate from 0..1 box to -1..-1 */
+ccl_device_inline float3 texco_remap_square(float3 co)
+{
+ return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f;
+}
+
ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
uint id = node.y;
@@ -362,8 +368,20 @@ ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *sta
decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
float3 co = stack_load_float3(stack, co_offset);
+ float2 tex_co;
uint use_alpha = stack_valid(alpha_offset);
- float4 f = svm_image_texture(kg, id, co.x, co.y, srgb, use_alpha);
+ if(node.w == NODE_IMAGE_PROJ_SPHERE) {
+ co = texco_remap_square(co);
+ tex_co = map_to_sphere(co);
+ }
+ else if(node.w == NODE_IMAGE_PROJ_TUBE) {
+ co = texco_remap_square(co);
+ tex_co = map_to_tube(co);
+ }
+ else {
+ tex_co = make_float2(co.x, co.y);
+ }
+ float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, srgb, use_alpha);
if(stack_valid(out_offset))
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
@@ -463,7 +481,6 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float
stack_store_float(stack, alpha_offset, f.w);
}
-
ccl_device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
uint id = node.y;
diff --git a/intern/cycles/kernel/svm/svm_invert.h b/intern/cycles/kernel/svm/svm_invert.h
index eb47e9ad4ab..152b49174e0 100644
--- a/intern/cycles/kernel/svm/svm_invert.h
+++ b/intern/cycles/kernel/svm/svm_invert.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_light_path.h b/intern/cycles/kernel/svm/svm_light_path.h
index da544c63ae0..677d139c5d4 100644
--- a/intern/cycles/kernel/svm/svm_light_path.h
+++ b/intern/cycles/kernel/svm/svm_light_path.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_magic.h b/intern/cycles/kernel/svm/svm_magic.h
index b661f5cacf8..ac87c77d719 100644
--- a/intern/cycles/kernel/svm/svm_magic.h
+++ b/intern/cycles/kernel/svm/svm_magic.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_mapping.h b/intern/cycles/kernel/svm/svm_mapping.h
index c9fa8502dd1..0a890545af4 100644
--- a/intern/cycles/kernel/svm/svm_mapping.h
+++ b/intern/cycles/kernel/svm/svm_mapping.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h
index 1ce9386e40e..d633e54ed8d 100644
--- a/intern/cycles/kernel/svm/svm_math.h
+++ b/intern/cycles/kernel/svm/svm_math.h
@@ -11,99 +11,11 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
-ccl_device float svm_math(NodeMath type, float Fac1, float Fac2)
-{
- float Fac;
-
- if(type == NODE_MATH_ADD)
- Fac = Fac1 + Fac2;
- else if(type == NODE_MATH_SUBTRACT)
- Fac = Fac1 - Fac2;
- else if(type == NODE_MATH_MULTIPLY)
- Fac = Fac1*Fac2;
- else if(type == NODE_MATH_DIVIDE)
- Fac = safe_divide(Fac1, Fac2);
- else if(type == NODE_MATH_SINE)
- Fac = sinf(Fac1);
- else if(type == NODE_MATH_COSINE)
- Fac = cosf(Fac1);
- else if(type == NODE_MATH_TANGENT)
- Fac = tanf(Fac1);
- else if(type == NODE_MATH_ARCSINE)
- Fac = safe_asinf(Fac1);
- else if(type == NODE_MATH_ARCCOSINE)
- Fac = safe_acosf(Fac1);
- else if(type == NODE_MATH_ARCTANGENT)
- Fac = atanf(Fac1);
- else if(type == NODE_MATH_POWER)
- Fac = safe_powf(Fac1, Fac2);
- else if(type == NODE_MATH_LOGARITHM)
- Fac = safe_logf(Fac1, Fac2);
- else if(type == NODE_MATH_MINIMUM)
- Fac = fminf(Fac1, Fac2);
- else if(type == NODE_MATH_MAXIMUM)
- Fac = fmaxf(Fac1, Fac2);
- else if(type == NODE_MATH_ROUND)
- Fac = floorf(Fac1 + 0.5f);
- else if(type == NODE_MATH_LESS_THAN)
- Fac = Fac1 < Fac2;
- else if(type == NODE_MATH_GREATER_THAN)
- Fac = Fac1 > Fac2;
- else if(type == NODE_MATH_MODULO)
- Fac = safe_modulo(Fac1, Fac2);
- else if(type == NODE_MATH_ABSOLUTE)
- Fac = fabsf(Fac1);
- else if(type == NODE_MATH_CLAMP)
- Fac = clamp(Fac1, 0.0f, 1.0f);
- else
- Fac = 0.0f;
-
- return Fac;
-}
-
-ccl_device float average_fac(float3 v)
-{
- return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z))/3.0f;
-}
-
-ccl_device void svm_vector_math(float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2)
-{
- if(type == NODE_VECTOR_MATH_ADD) {
- *Vector = Vector1 + Vector2;
- *Fac = average_fac(*Vector);
- }
- else if(type == NODE_VECTOR_MATH_SUBTRACT) {
- *Vector = Vector1 - Vector2;
- *Fac = average_fac(*Vector);
- }
- else if(type == NODE_VECTOR_MATH_AVERAGE) {
- *Fac = len(Vector1 + Vector2);
- *Vector = normalize(Vector1 + Vector2);
- }
- else if(type == NODE_VECTOR_MATH_DOT_PRODUCT) {
- *Fac = dot(Vector1, Vector2);
- *Vector = make_float3(0.0f, 0.0f, 0.0f);
- }
- else if(type == NODE_VECTOR_MATH_CROSS_PRODUCT) {
- float3 c = cross(Vector1, Vector2);
- *Fac = len(c);
- *Vector = normalize(c);
- }
- else if(type == NODE_VECTOR_MATH_NORMALIZE) {
- *Fac = len(Vector1);
- *Vector = normalize(Vector1);
- }
- else {
- *Fac = 0.0f;
- *Vector = make_float3(0.0f, 0.0f, 0.0f);
- }
-}
-
/* Nodes */
ccl_device void svm_node_math(KernelGlobals *kg, ShaderData *sd, float *stack, uint itype, uint f1_offset, uint f2_offset, int *offset)
diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h
new file mode 100644
index 00000000000..39cc14d5e8e
--- /dev/null
+++ b/intern/cycles/kernel/svm/svm_math_util.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2011-2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device float average_fac(float3 v)
+{
+ return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z))/3.0f;
+}
+
+ccl_device void svm_vector_math(float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2)
+{
+ if(type == NODE_VECTOR_MATH_ADD) {
+ *Vector = Vector1 + Vector2;
+ *Fac = average_fac(*Vector);
+ }
+ else if(type == NODE_VECTOR_MATH_SUBTRACT) {
+ *Vector = Vector1 - Vector2;
+ *Fac = average_fac(*Vector);
+ }
+ else if(type == NODE_VECTOR_MATH_AVERAGE) {
+ *Fac = len(Vector1 + Vector2);
+ *Vector = normalize(Vector1 + Vector2);
+ }
+ else if(type == NODE_VECTOR_MATH_DOT_PRODUCT) {
+ *Fac = dot(Vector1, Vector2);
+ *Vector = make_float3(0.0f, 0.0f, 0.0f);
+ }
+ else if(type == NODE_VECTOR_MATH_CROSS_PRODUCT) {
+ float3 c = cross(Vector1, Vector2);
+ *Fac = len(c);
+ *Vector = normalize(c);
+ }
+ else if(type == NODE_VECTOR_MATH_NORMALIZE) {
+ *Fac = len(Vector1);
+ *Vector = normalize(Vector1);
+ }
+ else {
+ *Fac = 0.0f;
+ *Vector = make_float3(0.0f, 0.0f, 0.0f);
+ }
+}
+
+ccl_device float svm_math(NodeMath type, float Fac1, float Fac2)
+{
+ float Fac;
+
+ if(type == NODE_MATH_ADD)
+ Fac = Fac1 + Fac2;
+ else if(type == NODE_MATH_SUBTRACT)
+ Fac = Fac1 - Fac2;
+ else if(type == NODE_MATH_MULTIPLY)
+ Fac = Fac1*Fac2;
+ else if(type == NODE_MATH_DIVIDE)
+ Fac = safe_divide(Fac1, Fac2);
+ else if(type == NODE_MATH_SINE)
+ Fac = sinf(Fac1);
+ else if(type == NODE_MATH_COSINE)
+ Fac = cosf(Fac1);
+ else if(type == NODE_MATH_TANGENT)
+ Fac = tanf(Fac1);
+ else if(type == NODE_MATH_ARCSINE)
+ Fac = safe_asinf(Fac1);
+ else if(type == NODE_MATH_ARCCOSINE)
+ Fac = safe_acosf(Fac1);
+ else if(type == NODE_MATH_ARCTANGENT)
+ Fac = atanf(Fac1);
+ else if(type == NODE_MATH_POWER)
+ Fac = safe_powf(Fac1, Fac2);
+ else if(type == NODE_MATH_LOGARITHM)
+ Fac = safe_logf(Fac1, Fac2);
+ else if(type == NODE_MATH_MINIMUM)
+ Fac = fminf(Fac1, Fac2);
+ else if(type == NODE_MATH_MAXIMUM)
+ Fac = fmaxf(Fac1, Fac2);
+ else if(type == NODE_MATH_ROUND)
+ Fac = floorf(Fac1 + 0.5f);
+ else if(type == NODE_MATH_LESS_THAN)
+ Fac = Fac1 < Fac2;
+ else if(type == NODE_MATH_GREATER_THAN)
+ Fac = Fac1 > Fac2;
+ else if(type == NODE_MATH_MODULO)
+ Fac = safe_modulo(Fac1, Fac2);
+ else if(type == NODE_MATH_ABSOLUTE)
+ Fac = fabsf(Fac1);
+ else if(type == NODE_MATH_CLAMP)
+ Fac = clamp(Fac1, 0.0f, 1.0f);
+ else
+ Fac = 0.0f;
+
+ return Fac;
+}
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/svm/svm_mix.h b/intern/cycles/kernel/svm/svm_mix.h
index edc3903865e..b6b1966cb3b 100644
--- a/intern/cycles/kernel/svm/svm_mix.h
+++ b/intern/cycles/kernel/svm/svm_mix.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_musgrave.h b/intern/cycles/kernel/svm/svm_musgrave.h
index 61171d6849c..2f81ddaa74c 100644
--- a/intern/cycles/kernel/svm/svm_musgrave.h
+++ b/intern/cycles/kernel/svm/svm_musgrave.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_noisetex.h b/intern/cycles/kernel/svm/svm_noisetex.h
index 5d5cfe6ffcc..eccd119b74f 100644
--- a/intern/cycles/kernel/svm/svm_noisetex.h
+++ b/intern/cycles/kernel/svm/svm_noisetex.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_normal.h b/intern/cycles/kernel/svm/svm_normal.h
index 8695031b8b9..67b5321e0de 100644
--- a/intern/cycles/kernel/svm/svm_normal.h
+++ b/intern/cycles/kernel/svm/svm_normal.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_ramp.h b/intern/cycles/kernel/svm/svm_ramp.h
index 55eee3d24c3..998f649a571 100644
--- a/intern/cycles/kernel/svm/svm_ramp.h
+++ b/intern/cycles/kernel/svm/svm_ramp.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SVM_RAMP_H__
diff --git a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
index 111d5d47988..68f9fea02f0 100644
--- a/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
+++ b/intern/cycles/kernel/svm/svm_sepcomb_hsv.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_sepcomb_vector.h b/intern/cycles/kernel/svm/svm_sepcomb_vector.h
index c8e7e34f87d..7a5a69f6dff 100644
--- a/intern/cycles/kernel/svm/svm_sepcomb_vector.h
+++ b/intern/cycles/kernel/svm/svm_sepcomb_vector.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h
index 500b5146931..4c8e3a32271 100644
--- a/intern/cycles/kernel/svm/svm_sky.h
+++ b/intern/cycles/kernel/svm/svm_sky.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index a17e4a25efe..a399acf3c0f 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -11,22 +11,40 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
/* Texture Coordinate Node */
-ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint type, uint out_offset)
+ccl_device void svm_node_tex_coord(KernelGlobals *kg,
+ ShaderData *sd,
+ int path_flag,
+ float *stack,
+ uint4 node,
+ int *offset)
{
float3 data;
+ uint type = node.y;
+ uint out_offset = node.z;
switch(type) {
case NODE_TEXCO_OBJECT: {
data = sd->P;
- if(sd->object != OBJECT_NONE)
- object_inverse_position_transform(kg, sd, &data);
+ if(node.w == 0) {
+ if(sd->object != OBJECT_NONE) {
+ object_inverse_position_transform(kg, sd, &data);
+ }
+ }
+ else {
+ Transform tfm;
+ tfm.x = read_node_float(kg, offset);
+ tfm.y = read_node_float(kg, offset);
+ tfm.z = read_node_float(kg, offset);
+ tfm.w = read_node_float(kg, offset);
+ data = transform_point(&tfm, data);
+ }
break;
}
case NODE_TEXCO_NORMAL: {
@@ -81,16 +99,34 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_f
stack_store_float3(stack, out_offset, data);
}
-ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint type, uint out_offset)
+ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg,
+ ShaderData *sd,
+ int path_flag,
+ float *stack,
+ uint4 node,
+ int *offset)
{
#ifdef __RAY_DIFFERENTIALS__
float3 data;
+ uint type = node.y;
+ uint out_offset = node.z;
switch(type) {
case NODE_TEXCO_OBJECT: {
data = sd->P + sd->dP.dx;
- if(sd->object != OBJECT_NONE)
- object_inverse_position_transform(kg, sd, &data);
+ if(node.w == 0) {
+ if(sd->object != OBJECT_NONE) {
+ object_inverse_position_transform(kg, sd, &data);
+ }
+ }
+ else {
+ Transform tfm;
+ tfm.x = read_node_float(kg, offset);
+ tfm.y = read_node_float(kg, offset);
+ tfm.z = read_node_float(kg, offset);
+ tfm.w = read_node_float(kg, offset);
+ data = transform_point(&tfm, data);
+ }
break;
}
case NODE_TEXCO_NORMAL: {
@@ -144,20 +180,38 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, in
stack_store_float3(stack, out_offset, data);
#else
- svm_node_tex_coord(kg, sd, stack, type, out_offset);
+ svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
#endif
}
-ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint type, uint out_offset)
+ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg,
+ ShaderData *sd,
+ int path_flag,
+ float *stack,
+ uint4 node,
+ int *offset)
{
#ifdef __RAY_DIFFERENTIALS__
float3 data;
+ uint type = node.y;
+ uint out_offset = node.z;
switch(type) {
case NODE_TEXCO_OBJECT: {
data = sd->P + sd->dP.dy;
- if(sd->object != OBJECT_NONE)
- object_inverse_position_transform(kg, sd, &data);
+ if(node.w == 0) {
+ if(sd->object != OBJECT_NONE) {
+ object_inverse_position_transform(kg, sd, &data);
+ }
+ }
+ else {
+ Transform tfm;
+ tfm.x = read_node_float(kg, offset);
+ tfm.y = read_node_float(kg, offset);
+ tfm.z = read_node_float(kg, offset);
+ tfm.w = read_node_float(kg, offset);
+ data = transform_point(&tfm, data);
+ }
break;
}
case NODE_TEXCO_NORMAL: {
@@ -211,7 +265,7 @@ ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, in
stack_store_float3(stack, out_offset, data);
#else
- svm_node_tex_coord(kg, sd, stack, type, out_offset);
+ svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
#endif
}
diff --git a/intern/cycles/kernel/svm/svm_texture.h b/intern/cycles/kernel/svm/svm_texture.h
index d97c85db36a..c5dc213c82d 100644
--- a/intern/cycles/kernel/svm/svm_texture.h
+++ b/intern/cycles/kernel/svm/svm_texture.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index fbe669c1fab..7130b14a426 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SVM_TYPES_H__
@@ -334,6 +334,19 @@ typedef enum NodeNormalMapSpace {
NODE_NORMAL_MAP_BLENDER_WORLD,
} NodeNormalMapSpace;
+typedef enum NodeImageProjection {
+ NODE_IMAGE_PROJ_FLAT = 0,
+ NODE_IMAGE_PROJ_BOX = 1,
+ NODE_IMAGE_PROJ_SPHERE = 2,
+ NODE_IMAGE_PROJ_TUBE = 3,
+} NodeImageProjection;
+
+typedef enum NodeBumpOffset {
+ NODE_BUMP_OFFSET_CENTER,
+ NODE_BUMP_OFFSET_DX,
+ NODE_BUMP_OFFSET_DY,
+} NodeBumpOffset;
+
typedef enum ShaderType {
SHADER_TYPE_SURFACE,
SHADER_TYPE_VOLUME,
diff --git a/intern/cycles/kernel/svm/svm_value.h b/intern/cycles/kernel/svm/svm_value.h
index 7beed065288..c1c2b539df3 100644
--- a/intern/cycles/kernel/svm/svm_value.h
+++ b/intern/cycles/kernel/svm/svm_value.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_vector_transform.h b/intern/cycles/kernel/svm/svm_vector_transform.h
index 61d33aeb8cf..a16786f3ed3 100644
--- a/intern/cycles/kernel/svm/svm_vector_transform.h
+++ b/intern/cycles/kernel/svm/svm_vector_transform.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_voronoi.h b/intern/cycles/kernel/svm/svm_voronoi.h
index 083a2f30e06..5a2e6e97dd3 100644
--- a/intern/cycles/kernel/svm/svm_voronoi.h
+++ b/intern/cycles/kernel/svm/svm_voronoi.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_wave.h b/intern/cycles/kernel/svm/svm_wave.h
index 7f9081539a4..36b59c3684c 100644
--- a/intern/cycles/kernel/svm/svm_wave.h
+++ b/intern/cycles/kernel/svm/svm_wave.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/svm/svm_wireframe.h b/intern/cycles/kernel/svm/svm_wireframe.h
index 660e6e2ca47..42fe3e8e429 100644
--- a/intern/cycles/kernel/svm/svm_wireframe.h
+++ b/intern/cycles/kernel/svm/svm_wireframe.h
@@ -34,16 +34,12 @@ CCL_NAMESPACE_BEGIN
/* Wireframe Node */
-ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_size, uint out_fac, uint use_pixel_size)
+ccl_device float wireframe(KernelGlobals *kg,
+ ShaderData *sd,
+ float size,
+ int pixel_size,
+ float3 *P)
{
- /* Input Data */
- float size = stack_load_float(stack, in_size);
- int pixel_size = (int)use_pixel_size;
-
- /* Output */
- float f = 0.0f;
-
- /* Calculate wireframe */
#ifdef __HAIR__
if (sd->prim != PRIM_NONE && sd->type & PRIMITIVE_ALL_TRIANGLE)
#else
@@ -55,7 +51,7 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta
/* Triangles */
int np = 3;
-
+
if(sd->type & PRIMITIVE_TRIANGLE)
triangle_vertices(kg, sd->prim, Co);
else
@@ -66,7 +62,7 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta
object_position_transform(kg, sd, &Co[1]);
object_position_transform(kg, sd, &Co[2]);
}
-
+
if(pixel_size) {
// Project the derivatives of P to the viewing plane defined
// by I so we have a measure of how big is a pixel at this point
@@ -75,24 +71,53 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta
// Take the average of both axis' length
pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f;
}
-
+
// Use half the width as the neighbor face will render the
// other half. And take the square for fast comparison
pixelwidth *= 0.5f * size;
pixelwidth *= pixelwidth;
for (int i = 0; i < np; i++) {
int i2 = i ? i - 1 : np - 1;
- float3 dir = sd->P - Co[i];
+ float3 dir = *P - Co[i];
float3 edge = Co[i] - Co[i2];
float3 crs = cross(edge, dir);
// At this point dot(crs, crs) / dot(edge, edge) is
// the square of area / length(edge) == square of the
// distance to the edge.
if (dot(crs, crs) < (dot(edge, edge) * pixelwidth))
- f = 1.0f;
+ return 1.0f;
}
}
-
+ return 0.0f;
+}
+
+ccl_device void svm_node_wireframe(KernelGlobals *kg,
+ ShaderData *sd,
+ float *stack,
+ uint4 node)
+{
+ uint in_size = node.y;
+ uint out_fac = node.z;
+ uint use_pixel_size, bump_offset;
+ decode_node_uchar4(node.w, &use_pixel_size, &bump_offset, NULL, NULL);
+
+ /* Input Data */
+ float size = stack_load_float(stack, in_size);
+ int pixel_size = (int)use_pixel_size;
+
+ /* Calculate wireframe */
+ float f = wireframe(kg, sd, size, pixel_size, &sd->P);
+
+ /* TODO(sergey): Think of faster way to calculate derivatives. */
+ if(bump_offset == NODE_BUMP_OFFSET_DX) {
+ float3 Px = sd->P - sd->dP.dx;
+ f += (f - wireframe(kg, sd, size, pixel_size, &Px)) / len(sd->dP.dx);
+ }
+ else if (bump_offset == NODE_BUMP_OFFSET_DY) {
+ float3 Py = sd->P - sd->dP.dy;
+ f += (f - wireframe(kg, sd, size, pixel_size, &Py)) / len(sd->dP.dy);
+ }
+
if (stack_valid(out_fac))
stack_store_float(stack, out_fac, f);
}
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index c3907da39d0..2dc6962633d 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -11,7 +11,7 @@ set(INC
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_DIR}
)
set(SRC
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index 8abf869a775..656420f5dbc 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "image.h"
@@ -230,6 +230,8 @@ const char *Attribute::standard_name(AttributeStandard std)
return "heat";
case ATTR_STD_VOLUME_VELOCITY:
return "velocity";
+ case ATTR_STD_POINTINESS:
+ return "pointiness";
case ATTR_STD_NOT_FOUND:
case ATTR_STD_NONE:
case ATTR_STD_NUM:
@@ -375,6 +377,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
case ATTR_STD_VOLUME_VELOCITY:
attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_VOXEL);
break;
+ case ATTR_STD_POINTINESS:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
+ break;
default:
assert(0);
break;
@@ -395,6 +400,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
case ATTR_STD_GENERATED_TRANSFORM:
attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH);
break;
+ case ATTR_STD_POINTINESS:
+ attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
+ break;
default:
assert(0);
break;
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h
index f5227ebde52..bbc6cf7f65f 100644
--- a/intern/cycles/render/attribute.h
+++ b/intern/cycles/render/attribute.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __ATTRIBUTE_H__
diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp
index 3926ecb99d6..f5e51f2e159 100644
--- a/intern/cycles/render/background.cpp
+++ b/intern/cycles/render/background.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "background.h"
@@ -72,16 +72,23 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
else
kbackground->volume_shader = SHADER_NONE;
- if(!(visibility & PATH_RAY_DIFFUSE))
- kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
- if(!(visibility & PATH_RAY_GLOSSY))
- kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY;
- if(!(visibility & PATH_RAY_TRANSMIT))
- kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT;
- if(!(visibility & PATH_RAY_VOLUME_SCATTER))
- kbackground->surface_shader |= SHADER_EXCLUDE_SCATTER;
- if(!(visibility & PATH_RAY_CAMERA))
- kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
+ /* No background node, make world shader invisible to all rays, to skip evaluation in kernel. */
+ if(scene->shaders[shader]->graph->nodes.size() <= 1) {
+ kbackground->surface_shader |= SHADER_EXCLUDE_ANY;
+ }
+ /* Background present, check visibilities */
+ else {
+ if(!(visibility & PATH_RAY_DIFFUSE))
+ kbackground->surface_shader |= SHADER_EXCLUDE_DIFFUSE;
+ if(!(visibility & PATH_RAY_GLOSSY))
+ kbackground->surface_shader |= SHADER_EXCLUDE_GLOSSY;
+ if(!(visibility & PATH_RAY_TRANSMIT))
+ kbackground->surface_shader |= SHADER_EXCLUDE_TRANSMIT;
+ if(!(visibility & PATH_RAY_VOLUME_SCATTER))
+ kbackground->surface_shader |= SHADER_EXCLUDE_SCATTER;
+ if(!(visibility & PATH_RAY_CAMERA))
+ kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
+ }
need_update = false;
}
diff --git a/intern/cycles/render/background.h b/intern/cycles/render/background.h
index cf627862513..26a727291ee 100644
--- a/intern/cycles/render/background.h
+++ b/intern/cycles/render/background.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __BACKGROUND_H__
diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp
index 5723a22dd84..1e8c1ac8bc9 100644
--- a/intern/cycles/render/bake.cpp
+++ b/intern/cycles/render/bake.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "bake.h"
diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h
index 186fbbeea4d..9ff10dafa0e 100644
--- a/intern/cycles/render/bake.h
+++ b/intern/cycles/render/bake.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __BAKE_H__
diff --git a/intern/cycles/render/blackbody.cpp b/intern/cycles/render/blackbody.cpp
index 6e2cb7c62b6..04e6eaf5373 100644
--- a/intern/cycles/render/blackbody.cpp
+++ b/intern/cycles/render/blackbody.cpp
@@ -38,7 +38,7 @@
CCL_NAMESPACE_BEGIN
-vector<float> blackbody_table()
+vector<float> blackbody_table_build()
{
/* quoted from OSLs opcolor.cpp
In order to speed up the blackbody computation, we have a table
diff --git a/intern/cycles/render/blackbody.h b/intern/cycles/render/blackbody.h
index c3be0ebdf30..6b752a227fa 100644
--- a/intern/cycles/render/blackbody.h
+++ b/intern/cycles/render/blackbody.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __BLACKBODY_H__
@@ -21,7 +21,7 @@
CCL_NAMESPACE_BEGIN
-vector<float> blackbody_table();
+vector<float> blackbody_table_build();
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index 756e16b38b5..5202bf5862c 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdlib.h>
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index 27ab20bbafd..4fa1c51d821 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __BUFFERS_H__
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 110adb4d036..ea9b853d454 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "camera.h"
@@ -47,6 +47,10 @@ Camera::Camera()
panorama_type = PANORAMA_EQUIRECTANGULAR;
fisheye_fov = M_PI_F;
fisheye_lens = 10.5f;
+ latitude_min = -M_PI_2_F;
+ latitude_max = M_PI_2_F;
+ longitude_min = -M_PI_F;
+ longitude_max = M_PI_F;
fov = M_PI_4_F;
sensorwidth = 0.036f;
@@ -105,16 +109,17 @@ void Camera::update()
{
if(!need_update)
return;
-
+
+ /* Full viewport to camera border in the viewport. */
+ Transform fulltoborder = transform_from_viewplane(viewport_camera_border);
+ Transform bordertofull = transform_inverse(fulltoborder);
+
/* ndc to raster */
Transform screentocamera;
- Transform ndctoraster = transform_scale(width, height, 1.0f);
+ Transform ndctoraster = transform_scale(width, height, 1.0f) * bordertofull;
/* raster to screen */
- Transform screentondc =
- transform_scale(1.0f/(viewplane.right - viewplane.left),
- 1.0f/(viewplane.top - viewplane.bottom), 1.0f) *
- transform_translate(-viewplane.left, -viewplane.bottom, 0.0f);
+ Transform screentondc = fulltoborder * transform_from_viewplane(viewplane);
Transform screentoraster = ndctoraster * screentondc;
Transform rastertoscreen = transform_inverse(screentoraster);
@@ -253,6 +258,8 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kcam->panorama_type = panorama_type;
kcam->fisheye_fov = fisheye_fov;
kcam->fisheye_lens = fisheye_lens;
+ kcam->equirectangular_range = make_float4(longitude_min - longitude_max, -longitude_min,
+ latitude_min - latitude_max, -latitude_min + M_PI_2_F);
/* sensor size */
kcam->sensorwidth = sensorwidth;
@@ -271,11 +278,20 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kcam->nearclip = nearclip;
kcam->cliplength = (farclip == FLT_MAX)? FLT_MAX: farclip - nearclip;
- need_device_update = false;
- previous_need_motion = need_motion;
-
/* Camera in volume. */
kcam->is_inside_volume = 0;
+
+ previous_need_motion = need_motion;
+}
+
+void Camera::device_update_volume(Device *device,
+ DeviceScene *dscene,
+ Scene *scene)
+{
+ if(!need_device_update) {
+ return;
+ }
+ KernelCamera *kcam = &dscene->data.cam;
BoundBox viewplane_boundbox = viewplane_bounds_get();
for(size_t i = 0; i < scene->objects.size(); ++i) {
Object *object = scene->objects[i];
@@ -287,6 +303,7 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
break;
}
}
+ need_device_update = false;
}
void Camera::device_free(Device *device, DeviceScene *dscene)
@@ -316,7 +333,11 @@ bool Camera::modified(const Camera& cam)
(aperture_ratio == cam.aperture_ratio) &&
(panorama_type == cam.panorama_type) &&
(fisheye_fov == cam.fisheye_fov) &&
- (fisheye_lens == cam.fisheye_lens));
+ (fisheye_lens == cam.fisheye_lens) &&
+ (latitude_min == cam.latitude_min) &&
+ (latitude_max == cam.latitude_max) &&
+ (longitude_min == cam.longitude_min) &&
+ (longitude_max == cam.longitude_max));
}
bool Camera::motion_modified(const Camera& cam)
@@ -336,6 +357,7 @@ float3 Camera::transform_raster_to_world(float raster_x, float raster_y)
if(type == CAMERA_PERSPECTIVE) {
D = transform_perspective(&rastertocamera,
make_float3(raster_x, raster_y, 0.0f));
+ float3 Pclip = normalize(D);
P = make_float3(0.0f, 0.0f, 0.0f);
/* TODO(sergey): Aperture support? */
P = transform_point(&cameratoworld, P);
@@ -344,7 +366,7 @@ float3 Camera::transform_raster_to_world(float raster_x, float raster_y)
* be mistakes in here, currently leading to wrong camera-in-volume
* detection.
*/
- P += nearclip * D;
+ P += nearclip * D / Pclip.z;
}
else if (type == CAMERA_ORTHOGRAPHIC) {
D = make_float3(0.0f, 0.0f, 1.0f);
@@ -387,5 +409,15 @@ BoundBox Camera::viewplane_bounds_get()
return bounds;
}
-CCL_NAMESPACE_END
+Transform Camera::transform_from_viewplane(BoundBox2D &viewplane)
+{
+ return
+ transform_scale(1.0f / (viewplane.right - viewplane.left),
+ 1.0f / (viewplane.top - viewplane.bottom),
+ 1.0f) *
+ transform_translate(-viewplane.left,
+ -viewplane.bottom,
+ 0.0f);
+}
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 788ae7b9bb6..e1faee3543d 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __CAMERA_H__
@@ -53,6 +53,10 @@ public:
PanoramaType panorama_type;
float fisheye_fov;
float fisheye_lens;
+ float latitude_min;
+ float latitude_max;
+ float longitude_min;
+ float longitude_max;
/* anamorphic lens bokeh */
float aperture_ratio;
@@ -72,6 +76,7 @@ public:
/* border */
BoundBox2D border;
+ BoundBox2D viewport_camera_border;
/* transformation */
Transform matrix;
@@ -111,6 +116,7 @@ public:
void update();
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
+ void device_update_volume(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene);
bool modified(const Camera& cam);
@@ -119,6 +125,7 @@ public:
BoundBox viewplane_bounds_get();
float3 transform_raster_to_world(float raster_x, float raster_y);
+ Transform transform_from_viewplane(BoundBox2D &viewplane);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/curves.cpp b/intern/cycles/render/curves.cpp
index dc7665fe144..80dc6434cde 100644
--- a/intern/cycles/render/curves.cpp
+++ b/intern/cycles/render/curves.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "device.h"
diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h
index 6fd0fff57fb..22ab5d05f8a 100644
--- a/intern/cycles/render/curves.h
+++ b/intern/cycles/render/curves.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __CURVES_H__
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 19f959d4ea1..c6d12928dd4 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "camera.h"
diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h
index cc7183bfd95..e2cd63cc2ed 100644
--- a/intern/cycles/render/film.h
+++ b/intern/cycles/render/film.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __FILM_H__
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 45b08832fea..9896eaba89b 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "attribute.h"
@@ -227,6 +227,21 @@ void ShaderGraph::disconnect(ShaderInput *to)
from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
}
+void ShaderGraph::relink(vector<ShaderInput*> inputs, vector<ShaderInput*> outputs, ShaderOutput *output)
+{
+ /* Remove nodes and re-link if output isn't NULL. */
+ foreach(ShaderInput *sock, inputs) {
+ if(sock->link)
+ disconnect(sock);
+ }
+
+ foreach(ShaderInput *sock, outputs) {
+ disconnect(sock);
+ if(output)
+ connect(output, sock);
+ }
+}
+
void ShaderGraph::finalize(bool do_bump, bool do_osl)
{
/* before compiling, the shader graph may undergo a number of modifications.
@@ -374,6 +389,21 @@ void ShaderGraph::remove_unneeded_nodes()
removed[proxy->id] = true;
any_node_removed = true;
}
+ else if(node->special_type == SHADER_SPECIAL_TYPE_BACKGROUND) {
+ BackgroundNode *bg = static_cast<BackgroundNode*>(node);
+
+ if(bg->outputs[0]->links.size()) {
+ /* Black color or zero strength, remove node */
+ if((!bg->inputs[0]->link && bg->inputs[0]->value == make_float3(0.0f, 0.0f, 0.0f)) ||
+ (!bg->inputs[1]->link && bg->inputs[1]->value.x == 0.0f)) {
+ vector<ShaderInput*> inputs = bg->outputs[0]->links;
+
+ relink(bg->inputs, inputs, NULL);
+ removed[bg->id] = true;
+ any_node_removed = true;
+ }
+ }
+ }
else if(node->special_type == SHADER_SPECIAL_TYPE_MIX_CLOSURE) {
MixClosureNode *mix = static_cast<MixClosureNode*>(node);
@@ -382,15 +412,7 @@ void ShaderGraph::remove_unneeded_nodes()
ShaderOutput *output = mix->inputs[1]->link;
vector<ShaderInput*> inputs = mix->outputs[0]->links;
- foreach(ShaderInput *sock, mix->inputs)
- if(sock->link)
- disconnect(sock);
-
- foreach(ShaderInput *input, inputs) {
- disconnect(input);
- if(output)
- connect(output, input);
- }
+ relink(mix->inputs, inputs, output);
removed[mix->id] = true;
any_node_removed = true;
}
@@ -403,15 +425,7 @@ void ShaderGraph::remove_unneeded_nodes()
ShaderOutput *output = mix->inputs[1]->link;
vector<ShaderInput*> inputs = mix->outputs[0]->links;
- foreach(ShaderInput *sock, mix->inputs)
- if(sock->link)
- disconnect(sock);
-
- foreach(ShaderInput *input, inputs) {
- disconnect(input);
- if(output)
- connect(output, input);
- }
+ relink(mix->inputs, inputs, output);
removed[mix->id] = true;
any_node_removed = true;
}
@@ -419,16 +433,8 @@ void ShaderGraph::remove_unneeded_nodes()
else if(mix->inputs[0]->value.x == 1.0f) {
ShaderOutput *output = mix->inputs[2]->link;
vector<ShaderInput*> inputs = mix->outputs[0]->links;
-
- foreach(ShaderInput *sock, mix->inputs)
- if(sock->link)
- disconnect(sock);
-
- foreach(ShaderInput *input, inputs) {
- disconnect(input);
- if(output)
- connect(output, input);
- }
+
+ relink(mix->inputs, inputs, output);
removed[mix->id] = true;
any_node_removed = true;
}
@@ -445,15 +451,7 @@ void ShaderGraph::remove_unneeded_nodes()
ShaderOutput *output = mix->inputs[1]->link;
vector<ShaderInput*> inputs = mix->outputs[0]->links;
- foreach(ShaderInput *sock, mix->inputs)
- if(sock->link)
- disconnect(sock);
-
- foreach(ShaderInput *input, inputs) {
- disconnect(input);
- if(output)
- connect(output, input);
- }
+ relink(mix->inputs, inputs, output);
removed[mix->id] = true;
any_node_removed = true;
}
@@ -462,15 +460,7 @@ void ShaderGraph::remove_unneeded_nodes()
ShaderOutput *output = mix->inputs[2]->link;
vector<ShaderInput*> inputs = mix->outputs[0]->links;
- foreach(ShaderInput *sock, mix->inputs)
- if(sock->link)
- disconnect(sock);
-
- foreach(ShaderInput *input, inputs) {
- disconnect(input);
- if(output)
- connect(output, input);
- }
+ relink(mix->inputs, inputs, output);
removed[mix->id] = true;
any_node_removed = true;
}
@@ -519,7 +509,7 @@ void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<b
void ShaderGraph::clean()
{
- /* remove proxy and unnecessary mix nodes */
+ /* remove proxy and unnecessary nodes */
remove_unneeded_nodes();
/* we do two things here: find cycles and break them, and remove unused
@@ -684,7 +674,7 @@ void ShaderGraph::bump_from_displacement()
* different shifted coordinates.
*
* these 3 displacement values are then fed into the bump node, which will
- * output the the perturbed normal. */
+ * output the perturbed normal. */
ShaderInput *displacement_in = output()->input("Displacement");
@@ -844,7 +834,7 @@ void ShaderGraph::dump_graph(const char *filename)
return;
}
- fprintf(fd, "digraph dependencygraph {\n");
+ fprintf(fd, "digraph shader_graph {\n");
fprintf(fd, "ranksep=1.5\n");
fprintf(fd, "splines=false\n");
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 7b95703d3aa..b39b3dae324 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __GRAPH_H__
@@ -79,7 +79,8 @@ enum ShaderNodeSpecialType {
SHADER_SPECIAL_TYPE_MIX_RGB, /* Only Mix subtype */
SHADER_SPECIAL_TYPE_AUTOCONVERT,
SHADER_SPECIAL_TYPE_GEOMETRY,
- SHADER_SPECIAL_TYPE_SCRIPT
+ SHADER_SPECIAL_TYPE_SCRIPT,
+ SHADER_SPECIAL_TYPE_BACKGROUND,
};
/* Enum
@@ -195,6 +196,7 @@ public:
virtual bool has_converter_blackbody() { return false; }
virtual bool has_bssrdf_bump() { return false; }
virtual bool has_spatial_varying() { return false; }
+ virtual bool has_object_dependency() { return false; }
vector<ShaderInput*> inputs;
vector<ShaderOutput*> outputs;
@@ -246,6 +248,7 @@ public:
void connect(ShaderOutput *from, ShaderInput *to);
void disconnect(ShaderInput *to);
+ void relink(vector<ShaderInput*> inputs, vector<ShaderInput*> outputs, ShaderOutput *output);
void remove_unneeded_nodes();
void finalize(bool do_bump = false, bool do_osl = false);
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index eb2c3333c44..61a0a81d51d 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "device.h"
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 535f0ff156d..2f5dcb6efd5 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __IMAGE_H__
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index 03a8cd5d2d3..17c50ca826f 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "device.h"
@@ -39,7 +39,6 @@ Integrator::Integrator()
transparent_max_bounce = max_bounce;
transparent_shadows = false;
- volume_homogeneous_sampling = 0;
volume_max_steps = 1024;
volume_step_size = 0.1f;
@@ -60,6 +59,10 @@ Integrator::Integrator()
mesh_light_samples = 1;
subsurface_samples = 1;
volume_samples = 1;
+
+ sample_all_lights_direct = true;
+ sample_all_lights_indirect = true;
+
method = PATH;
sampling_pattern = SAMPLING_PATTERN_SOBOL;
@@ -189,7 +192,6 @@ bool Integrator::modified(const Integrator& integrator)
transparent_min_bounce == integrator.transparent_min_bounce &&
transparent_max_bounce == integrator.transparent_max_bounce &&
transparent_shadows == integrator.transparent_shadows &&
- volume_homogeneous_sampling == integrator.volume_homogeneous_sampling &&
volume_max_steps == integrator.volume_max_steps &&
volume_step_size == integrator.volume_step_size &&
caustics_reflective == integrator.caustics_reflective &&
diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h
index 13c10e8ca94..fd2ad14488d 100644
--- a/intern/cycles/render/integrator.h
+++ b/intern/cycles/render/integrator.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __INTEGRATOR_H__
@@ -39,7 +39,6 @@ public:
int transparent_max_bounce;
bool transparent_shadows;
- int volume_homogeneous_sampling;
int volume_max_steps;
float volume_step_size;
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 1f006637e67..56bec4053d5 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "background.h"
@@ -26,6 +26,7 @@
#include "util_foreach.h"
#include "util_progress.h"
+#include "util_logging.h"
CCL_NAMESPACE_BEGIN
@@ -82,6 +83,8 @@ static void shade_background_pixels(Device *device, DeviceScene *dscene, int res
device->mem_free(d_input);
device->mem_free(d_output);
+ d_input.clear();
+
float4 *d_output_data = reinterpret_cast<float4*>(d_output.data_pointer);
pixels.resize(width*height);
@@ -125,6 +128,7 @@ Light::Light()
shader = 0;
samples = 1;
+ max_bounces = 1024;
}
void Light::tag_update(Scene *scene)
@@ -374,6 +378,45 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
}
}
+static void background_cdf(int start,
+ int end,
+ int res,
+ int cdf_count,
+ const vector<float3> *pixels,
+ float2 *cond_cdf)
+{
+ /* Conditional CDFs (rows, U direction). */
+ for(int i = start; i < end; i++) {
+ float sin_theta = sinf(M_PI_F * (i + 0.5f) / res);
+ float3 env_color = (*pixels)[i * res];
+ float ave_luminamce = average(env_color);
+
+ cond_cdf[i * cdf_count].x = ave_luminamce * sin_theta;
+ cond_cdf[i * cdf_count].y = 0.0f;
+
+ for(int j = 1; j < res; j++) {
+ env_color = (*pixels)[i * res + j];
+ ave_luminamce = average(env_color);
+
+ cond_cdf[i * cdf_count + j].x = ave_luminamce * sin_theta;
+ cond_cdf[i * cdf_count + j].y = cond_cdf[i * cdf_count + j - 1].y + cond_cdf[i * cdf_count + j - 1].x / res;
+ }
+
+ float cdf_total = cond_cdf[i * cdf_count + res - 1].y + cond_cdf[i * cdf_count + res - 1].x / res;
+ float cdf_total_inv = 1.0f / cdf_total;
+
+ /* stuff the total into the brightness value for the last entry, because
+ * we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
+ cond_cdf[i * cdf_count + res].x = cdf_total;
+
+ if(cdf_total > 0.0f)
+ for(int j = 1; j < res; j++)
+ cond_cdf[i * cdf_count + j].y *= cdf_total_inv;
+
+ cond_cdf[i * cdf_count + res].y = 1.0f;
+ }
+}
+
void LightManager::device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
KernelIntegrator *kintegrator = &dscene->data.integrator;
@@ -414,34 +457,28 @@ void LightManager::device_update_background(Device *device, DeviceScene *dscene,
float2 *marg_cdf = dscene->light_background_marginal_cdf.resize(cdf_count);
float2 *cond_cdf = dscene->light_background_conditional_cdf.resize(cdf_count * cdf_count);
- /* conditional CDFs (rows, U direction) */
- for(int i = 0; i < res; i++) {
- float sin_theta = sinf(M_PI_F * (i + 0.5f) / res);
- float3 env_color = pixels[i * res];
- float ave_luminamce = average(env_color);
-
- cond_cdf[i * cdf_count].x = ave_luminamce * sin_theta;
- cond_cdf[i * cdf_count].y = 0.0f;
-
- for(int j = 1; j < res; j++) {
- env_color = pixels[i * res + j];
- ave_luminamce = average(env_color);
-
- cond_cdf[i * cdf_count + j].x = ave_luminamce * sin_theta;
- cond_cdf[i * cdf_count + j].y = cond_cdf[i * cdf_count + j - 1].y + cond_cdf[i * cdf_count + j - 1].x / res;
+ double time_start = time_dt();
+ if(res < 512) {
+ /* Small enough resolution, faster to do single-threaded. */
+ background_cdf(0, res, res, cdf_count, &pixels, cond_cdf);
+ }
+ else {
+ /* Threaded evaluation for large resolution. */
+ const int num_blocks = TaskScheduler::num_threads();
+ const int chunk_size = res / num_blocks;
+ TaskPool pool;
+ for(int i = 0; i < num_blocks; ++i) {
+ const int current_chunk_size =
+ (i != num_blocks - 1) ? chunk_size
+ : (res - i * chunk_size);
+ pool.push(function_bind(&background_cdf,
+ i, i + current_chunk_size,
+ res,
+ cdf_count,
+ &pixels,
+ cond_cdf));
}
-
- float cdf_total = cond_cdf[i * cdf_count + res - 1].y + cond_cdf[i * cdf_count + res - 1].x / res;
-
- /* stuff the total into the brightness value for the last entry, because
- * we are going to normalize the CDFs to 0.0 to 1.0 afterwards */
- cond_cdf[i * cdf_count + res].x = cdf_total;
-
- if(cdf_total > 0.0f)
- for(int j = 1; j < res; j++)
- cond_cdf[i * cdf_count + j].y /= cdf_total;
-
- cond_cdf[i * cdf_count + res].y = 1.0f;
+ pool.wait_work();
}
/* marginal CDFs (column, V direction, sum of rows) */
@@ -462,6 +499,8 @@ void LightManager::device_update_background(Device *device, DeviceScene *dscene,
marg_cdf[res].y = 1.0f;
+ VLOG(2) << "Background MIS build time " << time_dt() - time_start << "\n";
+
/* update device */
device->tex_alloc("__light_background_marginal_cdf", dscene->light_background_marginal_cdf);
device->tex_alloc("__light_background_conditional_cdf", dscene->light_background_conditional_cdf);
@@ -489,6 +528,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
float3 co = light->co;
int shader_id = scene->shader_manager->get_shader_id(scene->lights[i]->shader);
float samples = __int_as_float(light->samples);
+ float max_bounces = __int_as_float(light->max_bounces);
if(!light->cast_shadow)
shader_id &= ~SHADER_CAST_SHADOW;
@@ -523,6 +563,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_DISTANT) {
shader_id &= ~SHADER_AREA_LIGHT;
@@ -533,9 +574,8 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
float area = M_PI_F*radius*radius;
float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
float3 dir = light->dir;
-
- if(len(dir) > 0.0f)
- dir = normalize(dir);
+
+ dir = safe_normalize(dir);
if(light->use_mis && area > 0.0f)
shader_id |= SHADER_USE_MIS;
@@ -544,6 +584,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, cosangle, invarea);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_BACKGROUND) {
uint visibility = scene->background->visibility;
@@ -572,6 +613,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_AREA) {
float3 axisu = light->axisu*(light->sizeu*light->size);
@@ -580,8 +622,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
float3 dir = light->dir;
- if(len(dir) > 0.0f)
- dir = normalize(dir);
+ dir = safe_normalize(dir);
if(light->use_mis && area > 0.0f)
shader_id |= SHADER_USE_MIS;
@@ -590,6 +631,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z);
light_data[i*LIGHT_SIZE + 2] = make_float4(invarea, axisv.x, axisv.y, axisv.z);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z);
+ light_data[i*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_SPOT) {
shader_id &= ~SHADER_AREA_LIGHT;
@@ -600,8 +642,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
float spot_smooth = (1.0f - spot_angle)*light->spot_smooth;
float3 dir = light->dir;
- if(len(dir) > 0.0f)
- dir = normalize(dir);
+ dir = safe_normalize(dir);
if(light->use_mis && radius > 0.0f)
shader_id |= SHADER_USE_MIS;
@@ -610,6 +651,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, spot_angle);
light_data[i*LIGHT_SIZE + 2] = make_float4(spot_smooth, dir.x, dir.y, dir.z);
light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f);
}
}
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index 89091bb5f9e..1f8eac6a97f 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __LIGHT_H__
@@ -58,6 +58,7 @@ public:
int shader;
int samples;
+ int max_bounces;
void tag_update(Scene *scene);
};
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 6137f7d4fdc..9c7310d4a05 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "bvh.h"
@@ -30,6 +30,7 @@
#include "util_cache.h"
#include "util_foreach.h"
+#include "util_logging.h"
#include "util_progress.h"
#include "util_set.h"
@@ -555,6 +556,7 @@ MeshManager::MeshManager()
{
bvh = NULL;
need_update = true;
+ need_flags_update = true;
}
MeshManager::~MeshManager()
@@ -748,8 +750,49 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
device->tex_alloc("__attributes_map", dscene->attributes_map);
}
-static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_float, vector<float4>& attr_float3, vector<uchar4>& attr_uchar4,
- Attribute *mattr, TypeDesc& type, int& offset, AttributeElement& element)
+static void update_attribute_element_size(Mesh *mesh,
+ Attribute *mattr,
+ size_t *attr_float_size,
+ size_t *attr_float3_size,
+ size_t *attr_uchar4_size)
+{
+ if(mattr) {
+ size_t size = mattr->element_size(
+ mesh->verts.size(),
+ mesh->triangles.size(),
+ mesh->motion_steps,
+ mesh->curves.size(),
+ mesh->curve_keys.size());
+
+ if(mattr->element == ATTR_ELEMENT_VOXEL) {
+ /* pass */
+ }
+ else if(mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
+ *attr_uchar4_size += size;
+ }
+ else if(mattr->type == TypeDesc::TypeFloat) {
+ *attr_float_size += size;
+ }
+ else if(mattr->type == TypeDesc::TypeMatrix) {
+ *attr_float3_size += size * 4;
+ }
+ else {
+ *attr_float3_size += size;
+ }
+ }
+}
+
+static void update_attribute_element_offset(Mesh *mesh,
+ vector<float>& attr_float,
+ size_t& attr_float_offset,
+ vector<float4>& attr_float3,
+ size_t& attr_float3_offset,
+ vector<uchar4>& attr_uchar4,
+ size_t& attr_uchar4_offset,
+ Attribute *mattr,
+ TypeDesc& type,
+ int& offset,
+ AttributeElement& element)
{
if(mattr) {
/* store element and type */
@@ -771,39 +814,43 @@ static void update_attribute_element_offset(Mesh *mesh, vector<float>& attr_floa
}
else if(mattr->element == ATTR_ELEMENT_CORNER_BYTE) {
uchar4 *data = mattr->data_uchar4();
- offset = attr_uchar4.size();
+ offset = attr_uchar4_offset;
- attr_uchar4.resize(attr_uchar4.size() + size);
-
- for(size_t k = 0; k < size; k++)
+ assert(attr_uchar4.capacity() >= offset + size);
+ for(size_t k = 0; k < size; k++) {
attr_uchar4[offset+k] = data[k];
+ }
+ attr_uchar4_offset += size;
}
else if(mattr->type == TypeDesc::TypeFloat) {
float *data = mattr->data_float();
- offset = attr_float.size();
+ offset = attr_float_offset;
- attr_float.resize(attr_float.size() + size);
-
- for(size_t k = 0; k < size; k++)
+ assert(attr_float.capacity() >= offset + size);
+ for(size_t k = 0; k < size; k++) {
attr_float[offset+k] = data[k];
+ }
+ attr_float_offset += size;
}
else if(mattr->type == TypeDesc::TypeMatrix) {
Transform *tfm = mattr->data_transform();
- offset = attr_float3.size();
+ offset = attr_float3_offset;
- attr_float3.resize(attr_float3.size() + size*4);
-
- for(size_t k = 0; k < size*4; k++)
+ assert(attr_float3.capacity() >= offset + size * 4);
+ for(size_t k = 0; k < size*4; k++) {
attr_float3[offset+k] = (&tfm->x)[k];
+ }
+ attr_float3_offset += size * 4;
}
else {
float4 *data = mattr->data_float4();
- offset = attr_float3.size();
+ offset = attr_float3_offset;
- attr_float3.resize(attr_float3.size() + size);
-
- for(size_t k = 0; k < size; k++)
+ assert(attr_float3.capacity() >= offset + size);
+ for(size_t k = 0; k < size; k++) {
attr_float3[offset+k] = data[k];
+ }
+ attr_float3_offset += size;
}
/* mesh vertex/curve index is global, not per object, so we sneak
@@ -853,16 +900,16 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
/* mesh attribute are stored in a single array per data type. here we fill
* those arrays, and set the offset and element type to create attribute
* maps next */
- vector<float> attr_float;
- vector<float4> attr_float3;
- vector<uchar4> attr_uchar4;
+ /* Pre-allocate attributes to avoid arrays re-allocation which would
+ * take 2x of overall attribute memory usage.
+ */
+ size_t attr_float_size = 0;
+ size_t attr_float3_size = 0;
+ size_t attr_uchar4_size = 0;
for(size_t i = 0; i < scene->meshes.size(); i++) {
Mesh *mesh = scene->meshes[i];
AttributeRequestSet& attributes = mesh_attributes[i];
-
- /* todo: we now store std and name attributes from requests even if
- * they actually refer to the same mesh attributes, optimize */
foreach(AttributeRequest& req, attributes.requests) {
Attribute *triangle_mattr = mesh->attributes.find(req);
Attribute *curve_mattr = mesh->curve_attributes.find(req);
@@ -876,12 +923,56 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
memcpy(triangle_mattr->data_float3(), &mesh->verts[0], sizeof(float3)*mesh->verts.size());
}
- update_attribute_element_offset(mesh, attr_float, attr_float3, attr_uchar4, triangle_mattr,
- req.triangle_type, req.triangle_offset, req.triangle_element);
+ update_attribute_element_size(mesh,
+ triangle_mattr,
+ &attr_float_size,
+ &attr_float3_size,
+ &attr_uchar4_size);
+ update_attribute_element_size(mesh,
+ curve_mattr,
+ &attr_float_size,
+ &attr_float3_size,
+ &attr_uchar4_size);
+ }
+ }
+
+ vector<float> attr_float(attr_float_size);
+ vector<float4> attr_float3(attr_float3_size);
+ vector<uchar4> attr_uchar4(attr_uchar4_size);
+
+ size_t attr_float_offset = 0;
+ size_t attr_float3_offset = 0;
+ size_t attr_uchar4_offset = 0;
+
+ /* Fill in attributes. */
+ for(size_t i = 0; i < scene->meshes.size(); i++) {
+ Mesh *mesh = scene->meshes[i];
+ AttributeRequestSet& attributes = mesh_attributes[i];
+
+ /* todo: we now store std and name attributes from requests even if
+ * they actually refer to the same mesh attributes, optimize */
+ foreach(AttributeRequest& req, attributes.requests) {
+ Attribute *triangle_mattr = mesh->attributes.find(req);
+ Attribute *curve_mattr = mesh->curve_attributes.find(req);
+
+ update_attribute_element_offset(mesh,
+ attr_float, attr_float_offset,
+ attr_float3, attr_float3_offset,
+ attr_uchar4, attr_uchar4_offset,
+ triangle_mattr,
+ req.triangle_type,
+ req.triangle_offset,
+ req.triangle_element);
+
+ update_attribute_element_offset(mesh,
+ attr_float, attr_float_offset,
+ attr_float3, attr_float3_offset,
+ attr_uchar4, attr_uchar4_offset,
+ curve_mattr,
+ req.curve_type,
+ req.curve_offset,
+ req.curve_element);
- update_attribute_element_offset(mesh, attr_float, attr_float3, attr_uchar4, curve_mattr,
- req.curve_type, req.curve_offset, req.curve_element);
-
if(progress.get_cancel()) return;
}
}
@@ -980,6 +1071,9 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
/* bvh build */
progress.set_status("Updating Scene BVH", "Building");
+ VLOG(1) << (scene->params.use_qbvh ? "Using QBVH optimization structure"
+ : "Using regular BVH optimization structure");
+
BVHParams bparams;
bparams.top_level = true;
bparams.use_qbvh = scene->params.use_qbvh;
@@ -1027,6 +1121,24 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
}
dscene->data.bvh.root = pack.root_index;
+ dscene->data.bvh.use_qbvh = scene->params.use_qbvh;
+}
+
+void MeshManager::device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+{
+ if(!need_update && !need_flags_update) {
+ return;
+ }
+ /* update flags */
+ foreach(Mesh *mesh, scene->meshes) {
+ mesh->has_volume = false;
+ foreach(uint shader, mesh->used_shaders) {
+ if(scene->shaders[shader]->has_volume) {
+ mesh->has_volume = true;
+ }
+ }
+ }
+ need_flags_update = false;
}
void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
@@ -1034,15 +1146,11 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
if(!need_update)
return;
- /* update normals and flags */
+ /* update normals */
foreach(Mesh *mesh, scene->meshes) {
- mesh->has_volume = false;
foreach(uint shader, mesh->used_shaders) {
if(scene->shaders[shader]->need_update_attributes)
mesh->need_update = true;
- if(scene->shaders[shader]->has_volume) {
- mesh->has_volume = true;
- }
}
if(mesh->need_update) {
@@ -1094,13 +1202,17 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
foreach(Mesh *mesh, scene->meshes) {
if(mesh->need_update) {
- pool.push(function_bind(&Mesh::compute_bvh, mesh, &scene->params, &progress, i, num_bvh));
+ pool.push(function_bind(&Mesh::compute_bvh,
+ mesh,
+ &scene->params,
+ &progress,
+ i,
+ num_bvh));
i++;
}
}
pool.wait_work();
-
foreach(Shader *shader, scene->shaders)
shader->need_update_attributes = false;
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 7e34b761faf..62e775e5bc9 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __MESH_H__
@@ -79,7 +79,7 @@ public:
vector<uint> shader;
vector<bool> smooth;
- bool has_volume; /* Set in the device_update(). */
+ bool has_volume; /* Set in the device_update_flags(). */
vector<float4> curve_keys; /* co + radius */
vector<Curve> curves;
@@ -145,6 +145,7 @@ public:
BVH *bvh;
bool need_update;
+ bool need_flags_update;
MeshManager();
~MeshManager();
@@ -160,6 +161,7 @@ public:
void device_update_mesh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
void tag_update(Scene *scene);
diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp
index 4c0ee76299c..1ba0c7f7291 100644
--- a/intern/cycles/render/mesh_displace.cpp
+++ b/intern/cycles/render/mesh_displace.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "device.h"
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index e8476bfac4c..7a39811cacd 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -11,12 +11,13 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "image.h"
#include "nodes.h"
#include "svm.h"
+#include "svm_math_util.h"
#include "osl.h"
#include "sky_model.h"
@@ -173,8 +174,10 @@ static ShaderEnum image_projection_init()
{
ShaderEnum enm;
- enm.insert("Flat", 0);
- enm.insert("Box", 1);
+ enm.insert("Flat", NODE_IMAGE_PROJ_FLAT);
+ enm.insert("Box", NODE_IMAGE_PROJ_BOX);
+ enm.insert("Sphere", NODE_IMAGE_PROJ_SPHERE);
+ enm.insert("Tube", NODE_IMAGE_PROJ_TUBE);
return enm;
}
@@ -265,14 +268,15 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset);
}
- if(projection == "Flat") {
+ if(projection != "Box") {
compiler.add_node(NODE_TEX_IMAGE,
slot,
compiler.encode_uchar4(
vector_offset,
color_out->stack_offset,
alpha_out->stack_offset,
- srgb));
+ srgb),
+ projection_enum[projection]);
}
else {
compiler.add_node(NODE_TEX_IMAGE_BOX,
@@ -284,7 +288,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
srgb),
__float_as_int(projection_blend));
}
-
+
if(vector_offset != vector_in->stack_offset)
compiler.stack_clear_offset(vector_in->type, vector_offset);
}
@@ -1945,6 +1949,8 @@ void EmissionNode::compile(OSLCompiler& compiler)
BackgroundNode::BackgroundNode()
: ShaderNode("background")
{
+ special_type = SHADER_SPECIAL_TYPE_BACKGROUND;
+
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f);
add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
@@ -2165,13 +2171,18 @@ GeometryNode::GeometryNode()
add_output("Incoming", SHADER_SOCKET_VECTOR);
add_output("Parametric", SHADER_SOCKET_POINT);
add_output("Backfacing", SHADER_SOCKET_FLOAT);
+ add_output("Pointiness", SHADER_SOCKET_FLOAT);
}
void GeometryNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if(shader->has_surface) {
- if(!output("Tangent")->links.empty())
+ if(!output("Tangent")->links.empty()) {
attributes->add(ATTR_STD_GENERATED);
+ }
+ if(!output("Pointiness")->links.empty()) {
+ attributes->add(ATTR_STD_POINTINESS);
+ }
}
ShaderNode::attributes(shader, attributes);
@@ -2181,11 +2192,16 @@ void GeometryNode::compile(SVMCompiler& compiler)
{
ShaderOutput *out;
NodeType geom_node = NODE_GEOMETRY;
+ NodeType attr_node = NODE_ATTR;
- if(bump == SHADER_BUMP_DX)
+ if(bump == SHADER_BUMP_DX) {
geom_node = NODE_GEOMETRY_BUMP_DX;
- else if(bump == SHADER_BUMP_DY)
+ attr_node = NODE_ATTR_BUMP_DX;
+ }
+ else if(bump == SHADER_BUMP_DY) {
geom_node = NODE_GEOMETRY_BUMP_DY;
+ attr_node = NODE_ATTR_BUMP_DY;
+ }
out = output("Position");
if(!out->links.empty()) {
@@ -2228,6 +2244,15 @@ void GeometryNode::compile(SVMCompiler& compiler)
compiler.stack_assign(out);
compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, out->stack_offset);
}
+
+ out = output("Pointiness");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(attr_node,
+ ATTR_STD_POINTINESS,
+ out->stack_offset,
+ NODE_ATTR_FLOAT);
+ }
}
void GeometryNode::compile(OSLCompiler& compiler)
@@ -2257,6 +2282,8 @@ TextureCoordinateNode::TextureCoordinateNode()
add_output("Reflection", SHADER_SOCKET_NORMAL);
from_dupli = false;
+ use_transform = false;
+ ob_tfm = transform_identity();
}
void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attributes)
@@ -2344,7 +2371,14 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler)
out = output("Object");
if(!out->links.empty()) {
compiler.stack_assign(out);
- compiler.add_node(texco_node, NODE_TEXCO_OBJECT, out->stack_offset);
+ compiler.add_node(texco_node, NODE_TEXCO_OBJECT, out->stack_offset, use_transform);
+ if(use_transform) {
+ Transform ob_itfm = transform_inverse(ob_tfm);
+ compiler.add_node(ob_itfm.x);
+ compiler.add_node(ob_itfm.y);
+ compiler.add_node(ob_itfm.z);
+ compiler.add_node(ob_itfm.w);
+ }
}
out = output("Camera");
@@ -2385,7 +2419,10 @@ void TextureCoordinateNode::compile(OSLCompiler& compiler)
compiler.parameter("is_background", true);
if(compiler.output_type() == SHADER_TYPE_VOLUME)
compiler.parameter("is_volume", true);
-
+ compiler.parameter("use_transform", use_transform);
+ Transform ob_itfm = transform_transpose(transform_inverse(ob_tfm));
+ compiler.parameter("object_itfm", ob_itfm);
+
compiler.parameter("from_dupli", from_dupli);
compiler.add(this, "node_texture_coordinate");
@@ -3540,14 +3577,34 @@ void WireframeNode::compile(SVMCompiler& compiler)
{
ShaderInput *size_in = input("Size");
ShaderOutput *fac_out = output("Fac");
-
+ NodeBumpOffset bump_offset = NODE_BUMP_OFFSET_CENTER;
+ if(bump == SHADER_BUMP_DX) {
+ bump_offset = NODE_BUMP_OFFSET_DX;
+ }
+ else if(bump == SHADER_BUMP_DY) {
+ bump_offset = NODE_BUMP_OFFSET_DY;
+ }
compiler.stack_assign(size_in);
compiler.stack_assign(fac_out);
- compiler.add_node(NODE_WIREFRAME, size_in->stack_offset, fac_out->stack_offset, use_pixel_size);
+ compiler.add_node(NODE_WIREFRAME,
+ size_in->stack_offset,
+ fac_out->stack_offset,
+ compiler.encode_uchar4(use_pixel_size,
+ bump_offset,
+ 0, 0));
}
void WireframeNode::compile(OSLCompiler& compiler)
{
+ if(bump == SHADER_BUMP_DX) {
+ compiler.parameter("bump_offset", "dx");
+ }
+ else if(bump == SHADER_BUMP_DY) {
+ compiler.parameter("bump_offset", "dy");
+ }
+ else {
+ compiler.parameter("bump_offset", "center");
+ }
compiler.parameter("use_pixel_size", use_pixel_size);
compiler.add(this, "node_wireframe");
}
@@ -3669,7 +3726,7 @@ static ShaderEnum math_type_init()
enm.insert("Less Than", NODE_MATH_LESS_THAN);
enm.insert("Greater Than", NODE_MATH_GREATER_THAN);
enm.insert("Modulo", NODE_MATH_MODULO);
- enm.insert("Absolute", NODE_MATH_ABSOLUTE);
+ enm.insert("Absolute", NODE_MATH_ABSOLUTE);
return enm;
}
@@ -3682,9 +3739,24 @@ void MathNode::compile(SVMCompiler& compiler)
ShaderInput *value2_in = input("Value2");
ShaderOutput *value_out = output("Value");
+ compiler.stack_assign(value_out);
+
+ /* Optimize math node without links to a single value node. */
+ if(value1_in->link == NULL && value2_in->link == NULL) {
+ float optimized_value = svm_math((NodeMath)type_enum[type],
+ value1_in->value.x,
+ value2_in->value.x);
+ if(use_clamp) {
+ optimized_value = clamp(optimized_value, 0.0f, 1.0f);
+ }
+ compiler.add_node(NODE_VALUE_F,
+ __float_as_int(optimized_value),
+ value_out->stack_offset);
+ return;
+ }
+
compiler.stack_assign(value1_in);
compiler.stack_assign(value2_in);
- compiler.stack_assign(value_out);
compiler.add_node(NODE_MATH, type_enum[type], value1_in->stack_offset, value2_in->stack_offset);
compiler.add_node(NODE_MATH, value_out->stack_offset);
@@ -3738,11 +3810,31 @@ void VectorMathNode::compile(SVMCompiler& compiler)
ShaderOutput *value_out = output("Value");
ShaderOutput *vector_out = output("Vector");
- compiler.stack_assign(vector1_in);
- compiler.stack_assign(vector2_in);
compiler.stack_assign(value_out);
compiler.stack_assign(vector_out);
+ /* Optimize vector math node without links to a single value node. */
+ if(vector1_in->link == NULL && vector2_in->link == NULL) {
+ float optimized_value;
+ float3 optimized_vector;
+ svm_vector_math(&optimized_value,
+ &optimized_vector,
+ (NodeVectorMath)type_enum[type],
+ vector1_in->value,
+ vector2_in->value);
+
+ compiler.add_node(NODE_VALUE_F,
+ __float_as_int(optimized_value),
+ value_out->stack_offset);
+
+ compiler.add_node(NODE_VALUE_V, vector_out->stack_offset);
+ compiler.add_node(NODE_VALUE_V, optimized_vector);
+ return;
+ }
+
+ compiler.stack_assign(vector1_in);
+ compiler.stack_assign(vector2_in);
+
compiler.add_node(NODE_VECTOR_MATH, type_enum[type], vector1_in->stack_offset, vector2_in->stack_offset);
compiler.add_node(NODE_VECTOR_MATH, value_out->stack_offset, vector_out->stack_offset);
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 31b6f4e50c4..0ec0fce512f 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __NODES_H__
@@ -357,8 +357,11 @@ public:
SHADER_NODE_CLASS(TextureCoordinateNode)
void attributes(Shader *shader, AttributeRequestSet *attributes);
bool has_spatial_varying() { return true; }
-
+ bool has_object_dependency() { return use_transform; }
+
bool from_dupli;
+ bool use_transform;
+ Transform ob_tfm;
};
class UVMapNode : public ShaderNode {
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 46ddab235d9..1225125b57e 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "device.h"
@@ -221,6 +221,7 @@ vector<float> Object::motion_times()
ObjectManager::ObjectManager()
{
need_update = true;
+ need_flags_update = true;
}
ObjectManager::~ObjectManager()
@@ -318,6 +319,9 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
mtfm_pre = mtfm_pre * itfm;
mtfm_post = mtfm_post * itfm;
}
+ else {
+ flag |= SD_OBJECT_HAS_VERTEX_MOTION;
+ }
memcpy(&objects_vector[i*OBJECT_VECTOR_SIZE+0], &mtfm_pre, sizeof(float4)*3);
memcpy(&objects_vector[i*OBJECT_VECTOR_SIZE+3], &mtfm_post, sizeof(float4)*3);
@@ -401,10 +405,11 @@ void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *sc
void ObjectManager::device_update_flags(Device *device, DeviceScene *dscene,
Scene *scene, Progress& progress)
{
- if(!need_update)
+ if(!need_update && !need_flags_update)
return;
need_update = false;
+ need_flags_update = false;
if(scene->objects.size() == 0)
return;
@@ -424,6 +429,9 @@ void ObjectManager::device_update_flags(Device *device, DeviceScene *dscene,
if(object->mesh->has_volume) {
object_flag[object_index] |= SD_OBJECT_HAS_VOLUME;
}
+ else {
+ object_flag[object_index] &= ~SD_OBJECT_HAS_VOLUME;
+ }
foreach(Object *volume_object, volume_objects) {
if(object == volume_object) {
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 2c69b83a2e9..acc08a0e204 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __OBJECT_H__
@@ -70,6 +70,7 @@ public:
class ObjectManager {
public:
bool need_update;
+ bool need_flags_update;
ObjectManager();
~ObjectManager();
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index f57e16471a1..9d6f412d9ce 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "device.h"
@@ -30,6 +30,7 @@
#include "osl_shader.h"
#include "util_foreach.h"
+#include "util_logging.h"
#include "util_md5.h"
#include "util_path.h"
#include "util_progress.h"
@@ -188,12 +189,14 @@ void OSLShaderManager::shading_system_init()
if(ss_shared_users == 0) {
services_shared = new OSLRenderServices();
- ss_shared = OSL::ShadingSystem::create(services_shared, ts_shared, &errhandler);
+ ss_shared = new OSL::ShadingSystem(services_shared, ts_shared, &errhandler);
ss_shared->attribute("lockgeom", 1);
ss_shared->attribute("commonspace", "world");
ss_shared->attribute("searchpath:shader", path_get("shader"));
//ss_shared->attribute("greedyjit", 1);
+ VLOG(1) << "Using shader search path: " << path_get("shader");
+
/* our own ray types */
static const char *raytypes[] = {
"camera", /* PATH_RAY_CAMERA */
@@ -235,7 +238,7 @@ void OSLShaderManager::shading_system_free()
ss_shared_users--;
if(ss_shared_users == 0) {
- OSL::ShadingSystem::destroy(ss_shared);
+ delete ss_shared;
ss_shared = NULL;
delete services_shared;
@@ -248,11 +251,11 @@ void OSLShaderManager::shading_system_free()
bool OSLShaderManager::osl_compile(const string& inputfile, const string& outputfile)
{
-#if OSL_LIBRARY_VERSION_CODE < 10500
- typedef string string_view;
-#endif
-
+#if OSL_LIBRARY_VERSION_CODE < 10602
vector<string_view> options;
+#else
+ vector<string> options;
+#endif
string stdosl_path;
string shader_path = path_get("shader");
@@ -261,13 +264,13 @@ bool OSLShaderManager::osl_compile(const string& inputfile, const string& output
options.push_back(outputfile);
/* specify standard include path */
- options.push_back("-I");
- options.push_back(shader_path);
+ string include_path_arg = string("-I") + shader_path;
+ options.push_back(include_path_arg);
stdosl_path = path_get("shader/stdosl.h");
/* compile */
- OSL::OSLCompiler *compiler = OSL::OSLCompiler::create();
+ OSL::OSLCompiler *compiler = new OSL::OSLCompiler();
bool ok = compiler->compile(string_view(inputfile), options, string_view(stdosl_path));
delete compiler;
@@ -564,6 +567,10 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
if(node->has_spatial_varying())
current_shader->has_heterogeneous_volume = true;
}
+
+ if(node->has_object_dependency()) {
+ current_shader->has_object_dependency = true;
+ }
}
void OSLCompiler::parameter(const char *name, float f)
@@ -748,11 +755,7 @@ OSL::ShadingAttribStateRef OSLCompiler::compile_type(Shader *shader, ShaderGraph
current_type = type;
-#if OSL_LIBRARY_VERSION_CODE >= 10501
OSL::ShadingAttribStateRef group = ss->ShaderGroupBegin(shader->name.c_str());
-#else
- ss->ShaderGroupBegin(shader->name.c_str());
-#endif
ShaderNode *output = graph->output();
set<ShaderNode*> dependencies;
@@ -780,13 +783,7 @@ OSL::ShadingAttribStateRef OSLCompiler::compile_type(Shader *shader, ShaderGraph
ss->ShaderGroupEnd();
-#if OSL_LIBRARY_VERSION_CODE >= 10501
return group;
-#else
- OSL::ShadingAttribStateRef group = ss->state();
- ss->clear_state();
- return group;
-#endif
}
void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
@@ -815,6 +812,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
shader->has_volume = false;
shader->has_displacement = false;
shader->has_heterogeneous_volume = false;
+ shader->has_object_dependency = false;
/* generate surface shader */
if(shader->used && graph && output->input("Surface")->link) {
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index 5824e2ace64..bc6a9d8fbbd 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __OSL_H__
diff --git a/intern/cycles/render/particles.cpp b/intern/cycles/render/particles.cpp
index 255effa86dd..f2f154cdab4 100644
--- a/intern/cycles/render/particles.cpp
+++ b/intern/cycles/render/particles.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "device.h"
diff --git a/intern/cycles/render/particles.h b/intern/cycles/render/particles.h
index a606722f9c3..bf2b6b77015 100644
--- a/intern/cycles/render/particles.h
+++ b/intern/cycles/render/particles.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __PARTICLES_H__
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 3662c29587e..524574f096d 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdlib.h>
@@ -36,6 +36,11 @@
#include "util_foreach.h"
#include "util_progress.h"
+#ifdef WITH_CYCLES_DEBUG
+# include "util_guarded_allocator.h"
+# include "util_logging.h"
+#endif
+
CCL_NAMESPACE_BEGIN
Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
@@ -153,81 +158,98 @@ void Scene::device_update(Device *device_, Progress& progress)
progress.set_status("Updating Shaders");
shader_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Images");
image_manager->device_update(device, &dscene, progress);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Background");
background->device_update(device, &dscene, this);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
+
+ progress.set_status("Updating Camera");
+ camera->device_update(device, &dscene, this);
+
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Objects");
object_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
- progress.set_status("Updating Meshes");
- mesh_manager->device_update(device, &dscene, this, progress);
+ progress.set_status("Updating Meshes Flags");
+ mesh_manager->device_update_flags(device, &dscene, this, progress);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Objects Flags");
object_manager->device_update_flags(device, &dscene, this, progress);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
+
+ progress.set_status("Updating Meshes");
+ mesh_manager->device_update(device, &dscene, this, progress);
+
+ if(progress.get_cancel() || device->have_error()) return;
+
+ progress.set_status("Updating Camera Volume");
+ camera->device_update_volume(device, &dscene, this);
+
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Hair Systems");
curve_system_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Lookup Tables");
lookup_tables->device_update(device, &dscene);
- if(progress.get_cancel()) return;
-
- /* TODO(sergey): Make sure camera is not needed above. */
- progress.set_status("Updating Camera");
- camera->device_update(device, &dscene, this);
-
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Lights");
light_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Particle Systems");
particle_system_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Film");
film->device_update(device, &dscene, this);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Integrator");
integrator->device_update(device, &dscene, this);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Lookup Tables");
lookup_tables->device_update(device, &dscene);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
progress.set_status("Updating Baking");
bake_manager->device_update(device, &dscene, this, progress);
- if(progress.get_cancel()) return;
+ if(progress.get_cancel() || device->have_error()) return;
+
+ if(device->have_error() == false) {
+ progress.set_status("Updating Device", "Writing constant memory");
+ device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
+ }
- progress.set_status("Updating Device", "Writing constant memory");
- device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
+#ifdef WITH_CYCLES_DEBUG
+ VLOG(1) << "System memory statistics after full device sync:\n"
+ << " Usage: " << util_guarded_get_mem_used() << "\n"
+ << " Peak: " << util_guarded_get_mem_peak();
+#endif
}
Scene::MotionType Scene::need_motion(bool advanced_shading)
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 5d205225d97..53c3a95903c 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SCENE_H__
@@ -26,6 +26,7 @@
#include "util_param.h"
#include "util_string.h"
+#include "util_system.h"
#include "util_thread.h"
#include "util_types.h"
#include "util_vector.h"
@@ -135,11 +136,7 @@ public:
bvh_type = BVH_DYNAMIC;
use_bvh_cache = false;
use_bvh_spatial_split = false;
-#ifdef __QBVH__
- use_qbvh = true;
-#else
use_qbvh = false;
-#endif
persistent_data = false;
}
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 9fcd9fa85f5..99826aa4349 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <string.h>
@@ -199,8 +199,7 @@ void Session::run_gpu()
paused_time = 0.0;
last_update_time = time_dt();
- if(!params.background)
- progress.set_start_time(start_time + paused_time);
+ progress.set_render_start_time(start_time + paused_time);
while(!progress.get_cancel()) {
/* advance to next tile */
@@ -233,6 +232,7 @@ void Session::run_gpu()
if(!params.background)
progress.set_start_time(start_time + paused_time);
+ progress.set_render_start_time(start_time + paused_time);
update_status_time(pause, no_tiles);
progress.set_update();
@@ -251,7 +251,7 @@ void Session::run_gpu()
update_scene();
if(!device->error_message().empty())
- progress.set_cancel(device->error_message());
+ progress.set_error(device->error_message());
if(progress.get_cancel())
break;
@@ -292,7 +292,7 @@ void Session::run_gpu()
}
if(!device->error_message().empty())
- progress.set_cancel(device->error_message());
+ progress.set_error(device->error_message());
tiles_written = update_progressive_refine(progress.get_cancel());
@@ -517,6 +517,7 @@ void Session::run_cpu()
if(!params.background)
progress.set_start_time(start_time + paused_time);
+ progress.set_render_start_time(start_time + paused_time);
update_status_time(pause, no_tiles);
progress.set_update();
@@ -540,7 +541,7 @@ void Session::run_cpu()
update_scene();
if(!device->error_message().empty())
- progress.set_cancel(device->error_message());
+ progress.set_error(device->error_message());
if(progress.get_cancel())
break;
@@ -558,7 +559,7 @@ void Session::run_cpu()
need_tonemap = true;
if(!device->error_message().empty())
- progress.set_cancel(device->error_message());
+ progress.set_error(device->error_message());
}
device->task_wait();
@@ -580,7 +581,7 @@ void Session::run_cpu()
}
if(!device->error_message().empty())
- progress.set_cancel(device->error_message());
+ progress.set_error(device->error_message());
tiles_written = update_progressive_refine(progress.get_cancel());
}
@@ -604,7 +605,7 @@ void Session::load_kernels()
if(message.empty())
message = "Failed loading render kernel, see console for errors";
- progress.set_cancel(message);
+ progress.set_error(message);
progress.set_status("Error", message);
progress.set_update();
return;
@@ -665,7 +666,8 @@ void Session::reset_(BufferParams& buffer_params, int samples)
paused_time = 0.0;
if(!params.background)
- progress.set_start_time(start_time + paused_time);
+ progress.set_start_time(start_time);
+ progress.set_render_start_time(start_time);
}
void Session::reset(BufferParams& buffer_params, int samples)
@@ -887,7 +889,7 @@ bool Session::update_progressive_refine(bool cancel)
double current_time = time_dt();
- if (current_time - last_update_time < 1.0) {
+ if (current_time - last_update_time < params.progressive_update_timeout) {
/* if last sample was processed, we need to write buffers anyway */
if (!write)
return false;
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 9da7a0aafa3..c77652d3722 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SESSION_H__
@@ -59,6 +59,7 @@ public:
double cancel_timeout;
double reset_timeout;
double text_timeout;
+ double progressive_update_timeout;
ShadingSystem shadingsystem;
@@ -80,6 +81,7 @@ public:
cancel_timeout = 0.1;
reset_timeout = 0.1;
text_timeout = 1.0;
+ progressive_update_timeout = 1.0;
shadingsystem = SHADINGSYSTEM_SVM;
tile_order = TILE_CENTER;
@@ -101,6 +103,7 @@ public:
&& cancel_timeout == params.cancel_timeout
&& reset_timeout == params.reset_timeout
&& text_timeout == params.text_timeout
+ && progressive_update_timeout == params.progressive_update_timeout
&& tile_order == params.tile_order
&& shadingsystem == params.shadingsystem); }
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 2a3969b6188..5899c562f72 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "background.h"
@@ -21,6 +21,7 @@
#include "light.h"
#include "mesh.h"
#include "nodes.h"
+#include "object.h"
#include "osl.h"
#include "scene.h"
#include "shader.h"
@@ -150,6 +151,7 @@ Shader::Shader()
has_displacement = false;
has_bssrdf_bump = false;
has_heterogeneous_volume = false;
+ has_object_dependency = false;
used = false;
@@ -194,6 +196,7 @@ void Shader::tag_update(Scene *scene)
* e.g. surface attributes when there is only a volume shader. this could
* be more fine grained but it's better than nothing */
OutputNode *output = graph->output();
+ bool prev_has_volume = has_volume;
has_surface = has_surface || output->input("Surface")->link;
has_volume = has_volume || output->input("Volume")->link;
has_displacement = has_displacement || output->input("Displacement")->link;
@@ -215,6 +218,11 @@ void Shader::tag_update(Scene *scene)
need_update_attributes = true;
scene->mesh_manager->need_update = true;
}
+
+ if(has_volume != prev_has_volume) {
+ scene->mesh_manager->need_flags_update = true;
+ scene->object_manager->need_flags_update = true;
+ }
}
void Shader::tag_used(Scene *scene)
@@ -359,6 +367,8 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
flag |= SD_VOLUME_MIS;
if(shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC)
flag |= SD_VOLUME_CUBIC;
+ if(shader->graph_bump)
+ flag |= SD_HAS_BUMP;
/* regular shader */
shader_flag[i++] = flag;
@@ -378,8 +388,10 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
KernelTables *ktables = &dscene->data.tables;
if(has_converter_blackbody && blackbody_table_offset == TABLE_OFFSET_INVALID) {
- vector<float> table = blackbody_table();
- blackbody_table_offset = scene->lookup_tables->add_table(dscene, table);
+ if(blackbody_table.size() == 0) {
+ blackbody_table = blackbody_table_build();
+ }
+ blackbody_table_offset = scene->lookup_tables->add_table(dscene, blackbody_table);
ktables->blackbody_offset = (int)blackbody_table_offset;
}
@@ -390,10 +402,10 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
/* beckmann lookup table */
if(beckmann_table_offset == TABLE_OFFSET_INVALID) {
- vector<float> table;
- beckmann_table_build(table);
- beckmann_table_offset = scene->lookup_tables->add_table(dscene, table);
-
+ if(beckmann_table.size() == 0) {
+ beckmann_table_build(beckmann_table);
+ }
+ beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table);
ktables->beckmann_offset = (int)beckmann_table_offset;
}
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index b267731abe5..1dee47c7731 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -11,13 +11,22 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SHADER_H__
#define __SHADER_H__
#ifdef WITH_OSL
+# if defined(_MSC_VER)
+/* Prevent OSL from polluting the context with weird macros from windows.h.
+ * TODO(sergey): Ideally it's only enough to have class/struct declarations in
+ * the header and skip header include here.
+ */
+# define NOGDI
+# define NOMINMAX
+# define WIN32_LEAN_AND_MEAN
+# endif
# include <OSL/oslexec.h>
#endif
@@ -97,6 +106,7 @@ public:
bool has_converter_blackbody;
bool has_bssrdf_bump;
bool has_heterogeneous_volume;
+ bool has_object_dependency;
/* requested mesh attributes */
AttributeRequestSet attributes;
@@ -161,6 +171,9 @@ protected:
typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
AttributeIDMap unique_attribute_id;
+ vector<float> blackbody_table;
+ vector<float> beckmann_table;
+
size_t blackbody_table_offset;
size_t beckmann_table_offset;
};
diff --git a/intern/cycles/render/sobol.h b/intern/cycles/render/sobol.h
index b5eaa67db3e..574f148b9a2 100644
--- a/intern/cycles/render/sobol.h
+++ b/intern/cycles/render/sobol.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SOBOL_H__
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 13c63d9420c..2e3abfcffb9 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "device.h"
@@ -393,6 +393,10 @@ void SVMCompiler::generate_node(ShaderNode *node, set<ShaderNode*>& done)
/* detect if we have a blackbody converter, to prepare lookup table */
if(node->has_converter_blackbody())
current_shader->has_converter_blackbody = true;
+
+ if(node->has_object_dependency()) {
+ current_shader->has_object_dependency = true;
+ }
}
void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done)
@@ -713,6 +717,7 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in
shader->has_volume = false;
shader->has_displacement = false;
shader->has_heterogeneous_volume = false;
+ shader->has_object_dependency = false;
/* generate surface shader */
compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h
index c1dd96e4d80..4b390fb88f9 100644
--- a/intern/cycles/render/svm.h
+++ b/intern/cycles/render/svm.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SVM_H__
diff --git a/intern/cycles/render/tables.cpp b/intern/cycles/render/tables.cpp
index a8d502c432d..faf7ea3409b 100644
--- a/intern/cycles/render/tables.cpp
+++ b/intern/cycles/render/tables.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "device.h"
diff --git a/intern/cycles/render/tables.h b/intern/cycles/render/tables.h
index 059940cbeb6..4efa09fa3c1 100644
--- a/intern/cycles/render/tables.h
+++ b/intern/cycles/render/tables.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __TABLES_H__
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index e37d8e5f8a1..675f49ec300 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "tile.h"
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index 7796518b6bc..c9bdc86f029 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __TILE_H__
diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp
index 05ff5ca4b65..44bab066dde 100644
--- a/intern/cycles/subd/subd_dice.cpp
+++ b/intern/cycles/subd/subd_dice.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "camera.h"
@@ -117,8 +117,8 @@ void EdgeDice::stitch_triangles(Patch *patch, vector<int>& outer, vector<int>& i
}
else {
/* length of diagonals */
- float len1 = len(mesh_P[inner[i]] - mesh_P[outer[j+1]]);
- float len2 = len(mesh_P[outer[j]] - mesh_P[inner[i+1]]);
+ float len1 = len_squared(mesh_P[inner[i]] - mesh_P[outer[j+1]]);
+ float len2 = len_squared(mesh_P[outer[j]] - mesh_P[inner[i+1]]);
/* use smallest diagonal */
if(len1 < len2)
diff --git a/intern/cycles/subd/subd_dice.h b/intern/cycles/subd/subd_dice.h
index 9cf5b0d50b8..b7e61748779 100644
--- a/intern/cycles/subd/subd_dice.h
+++ b/intern/cycles/subd/subd_dice.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SUBD_DICE_H__
diff --git a/intern/cycles/subd/subd_patch.cpp b/intern/cycles/subd/subd_patch.cpp
index fe9fa791813..0db46ec492d 100644
--- a/intern/cycles/subd/subd_patch.cpp
+++ b/intern/cycles/subd/subd_patch.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/* Parts adapted from code in the public domain in NVidia Mesh Tools. */
diff --git a/intern/cycles/subd/subd_patch.h b/intern/cycles/subd/subd_patch.h
index 48f35d78711..9be4606c248 100644
--- a/intern/cycles/subd/subd_patch.h
+++ b/intern/cycles/subd/subd_patch.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SUBD_PATCH_H__
diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp
index 6bbf4af3f85..df4d451e8eb 100644
--- a/intern/cycles/subd/subd_split.cpp
+++ b/intern/cycles/subd/subd_split.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "camera.h"
diff --git a/intern/cycles/subd/subd_split.h b/intern/cycles/subd/subd_split.h
index 3f9a2721977..df4935ee624 100644
--- a/intern/cycles/subd/subd_split.h
+++ b/intern/cycles/subd/subd_split.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __SUBD_SPLIT_H__
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index 842d5efac79..0acb9e9304c 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -5,12 +5,12 @@ set(INC
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_DIR}
)
set(SRC
+ util_aligned_malloc.cpp
util_cache.cpp
- util_dynlib.cpp
util_logging.cpp
util_md5.cpp
util_path.cpp
@@ -22,6 +22,10 @@ set(SRC
util_transform.cpp
)
+if(NOT CYCLES_STANDALONE_REPOSITORY)
+ add_definitions(-DWITH_GLEW_MX)
+endif()
+
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
list(APPEND SRC
util_view.cpp
@@ -30,11 +34,12 @@ endif()
set(SRC_HEADERS
util_algorithm.h
+ util_aligned_malloc.h
util_args.h
+ util_atomic.h
util_boundbox.h
util_cache.h
util_debug.h
- util_dynlib.h
util_foreach.h
util_function.h
util_half.h
@@ -44,6 +49,7 @@ set(SRC_HEADERS
util_logging.h
util_map.h
util_math.h
+ util_math_fast.h
util_md5.h
util_opengl.h
util_optimization.h
@@ -68,6 +74,15 @@ set(SRC_HEADERS
util_xml.h
)
+if(WITH_CYCLES_DEBUG)
+ list(APPEND SRC
+ util_guarded_allocator.cpp
+ )
+ list(APPEND SRC_HEADERS
+ util_guarded_allocator.h
+ )
+endif()
+
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
diff --git a/intern/cycles/util/util_algorithm.h b/intern/cycles/util/util_algorithm.h
index 5865f3f04bb..5c79c00cc98 100644
--- a/intern/cycles/util/util_algorithm.h
+++ b/intern/cycles/util/util_algorithm.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_ALGORITHM_H__
diff --git a/intern/cycles/util/util_aligned_malloc.cpp b/intern/cycles/util/util_aligned_malloc.cpp
new file mode 100644
index 00000000000..9ff857e3543
--- /dev/null
+++ b/intern/cycles/util/util_aligned_malloc.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2011-2015 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "util_aligned_malloc.h"
+#include "util_guarded_allocator.h"
+
+#include <cassert>
+
+/* Adopted from Libmv. */
+
+#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
+/* Needed for memalign on Linux and _aligned_alloc on Windows. */
+# ifdef FREE_WINDOWS
+/* Make sure _aligned_malloc is included. */
+# ifdef __MSVCRT_VERSION__
+# undef __MSVCRT_VERSION__
+# endif
+# define __MSVCRT_VERSION__ 0x0700
+# endif /* FREE_WINDOWS */
+# include <malloc.h>
+#else
+/* Apple's malloc is 16-byte aligned, and does not have malloc.h, so include
+ * stdilb instead.
+ */
+# include <cstdlib>
+#endif
+
+CCL_NAMESPACE_BEGIN
+
+void *util_aligned_malloc(size_t size, int alignment)
+{
+#ifdef WITH_BLENDER_GUARDEDALLOC
+ return MEM_mallocN_aligned(size, alignment, "Cycles Aligned Alloc");
+#endif
+#ifdef _WIN32
+ return _aligned_malloc(size, alignment);
+#elif defined(__APPLE__)
+ /* On Mac OS X, both the heap and the stack are guaranteed 16-byte aligned so
+ * they work natively with SSE types with no further work.
+ */
+ assert(alignment == 16);
+ return malloc(size);
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
+ void *result;
+ if (posix_memalign(&result, alignment, size)) {
+ /* Non-zero means allocation error
+ * either no allocation or bad alignment value.
+ */
+ return NULL;
+ }
+ return result;
+#else /* This is for Linux. */
+ return memalign(alignment, size);
+#endif
+}
+
+void util_aligned_free(void *ptr)
+{
+#if defined(WITH_BLENDER_GUARDEDALLOC)
+ if(ptr != NULL) {
+ MEM_freeN(ptr);
+ }
+#elif defined(_WIN32)
+ _aligned_free(ptr);
+#else
+ free(ptr);
+#endif
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_aligned_malloc.h b/intern/cycles/util/util_aligned_malloc.h
new file mode 100644
index 00000000000..ecc0f28c376
--- /dev/null
+++ b/intern/cycles/util/util_aligned_malloc.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011-2015 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UTIL_ALIGNED_MALLOC_H__
+#define __UTIL_ALIGNED_MALLOC_H__
+
+#include "util_types.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Allocate block of size bytes at least aligned to a given value. */
+void *util_aligned_malloc(size_t size, int alignment);
+
+/* Free memory allocated by util_aligned_malloc. */
+void util_aligned_free(void *ptr);
+
+CCL_NAMESPACE_END
+
+#endif /* __UTIL_ALIGNED_MALLOC_H__ */
diff --git a/intern/cycles/util/util_args.h b/intern/cycles/util/util_args.h
index 55933c895bf..a53fc061758 100644
--- a/intern/cycles/util/util_args.h
+++ b/intern/cycles/util/util_args.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_ARGS_H__
diff --git a/intern/cycles/util/util_atomic.h b/intern/cycles/util/util_atomic.h
new file mode 100644
index 00000000000..7bbd97b8667
--- /dev/null
+++ b/intern/cycles/util/util_atomic.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UTIL_ATOMIC_H__
+#define __UTIL_ATOMIC_H__
+
+/* Using atomic ops header from Blender. */
+#include "atomic_ops.h"
+
+ATOMIC_INLINE void atomic_update_max_z(size_t *maximum_value, size_t value)
+{
+ size_t prev_value = *maximum_value;
+ while (prev_value < value) {
+ if (atomic_cas_z(maximum_value, prev_value, value) != prev_value) {
+ break;
+ }
+ }
+}
+
+#endif /* __UTIL_ATOMIC_H__ */
diff --git a/intern/cycles/util/util_boundbox.h b/intern/cycles/util/util_boundbox.h
index a71e0399619..cef5adc0a61 100644
--- a/intern/cycles/util/util_boundbox.h
+++ b/intern/cycles/util/util_boundbox.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_BOUNDBOX_H__
diff --git a/intern/cycles/util/util_cache.cpp b/intern/cycles/util/util_cache.cpp
index e20c3a67b75..5eebfb18155 100644
--- a/intern/cycles/util/util_cache.cpp
+++ b/intern/cycles/util/util_cache.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdio.h>
@@ -24,12 +24,6 @@
#include "util_path.h"
#include "util_types.h"
-#include <boost/version.hpp>
-
-#if (BOOST_VERSION < 104400)
-# define BOOST_FILESYSTEM_VERSION 2
-#endif
-
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
diff --git a/intern/cycles/util/util_cache.h b/intern/cycles/util/util_cache.h
index bfb2877a22b..9d001a6f1ff 100644
--- a/intern/cycles/util/util_cache.h
+++ b/intern/cycles/util/util_cache.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_CACHE_H__
diff --git a/intern/cycles/util/util_color.h b/intern/cycles/util/util_color.h
index 53b3d72de67..d3598f84b94 100644
--- a/intern/cycles/util/util_color.h
+++ b/intern/cycles/util/util_color.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_COLOR_H__
diff --git a/intern/cycles/util/util_debug.h b/intern/cycles/util/util_debug.h
index 79fac506b98..6b61a49fcc3 100644
--- a/intern/cycles/util/util_debug.h
+++ b/intern/cycles/util/util_debug.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_DEBUG_H__
diff --git a/intern/cycles/util/util_dynlib.cpp b/intern/cycles/util/util_dynlib.cpp
deleted file mode 100644
index 587cad607c8..00000000000
--- a/intern/cycles/util/util_dynlib.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2011-2013 Blender Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-#include <stdlib.h>
-
-#include "util_dynlib.h"
-
-#ifdef _WIN32
-
-#include <windows.h>
-
-CCL_NAMESPACE_BEGIN
-
-struct DynamicLibrary {
- HMODULE module;
-};
-
-DynamicLibrary *dynamic_library_open(const char *name)
-{
- HMODULE module = LoadLibrary(name);
-
- if(!module)
- return NULL;
-
- DynamicLibrary *lib = new DynamicLibrary();
- lib->module = module;
-
- return lib;
-}
-
-void *dynamic_library_find(DynamicLibrary *lib, const char *name)
-{
- return (void*)GetProcAddress(lib->module, name);
-}
-
-void dynamic_library_close(DynamicLibrary *lib)
-{
- FreeLibrary(lib->module);
- delete lib;
-}
-
-CCL_NAMESPACE_END
-
-#else
-
-#include <dlfcn.h>
-
-CCL_NAMESPACE_BEGIN
-
-struct DynamicLibrary {
- void *module;
-};
-
-DynamicLibrary *dynamic_library_open(const char *name)
-{
- void *module = dlopen(name, RTLD_NOW);
-
- if(!module)
- return NULL;
-
- DynamicLibrary *lib = new DynamicLibrary();
- lib->module = module;
-
- return lib;
-}
-
-void *dynamic_library_find(DynamicLibrary *lib, const char *name)
-{
- return dlsym(lib->module, name);
-}
-
-void dynamic_library_close(DynamicLibrary *lib)
-{
- dlclose(lib->module);
- delete lib;
-}
-
-CCL_NAMESPACE_END
-
-#endif
-
diff --git a/intern/cycles/util/util_foreach.h b/intern/cycles/util/util_foreach.h
index df3277fbf37..065bd33ebd2 100644
--- a/intern/cycles/util/util_foreach.h
+++ b/intern/cycles/util/util_foreach.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_FOREACH_H__
diff --git a/intern/cycles/util/util_function.h b/intern/cycles/util/util_function.h
index 6aa014a08a6..7a312efaad7 100644
--- a/intern/cycles/util/util_function.h
+++ b/intern/cycles/util/util_function.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_FUNCTION_H__
diff --git a/intern/cycles/util/util_guarded_allocator.cpp b/intern/cycles/util/util_guarded_allocator.cpp
new file mode 100644
index 00000000000..8de6e254cbf
--- /dev/null
+++ b/intern/cycles/util/util_guarded_allocator.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011-2015 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "util_guarded_allocator.h"
+#include "util_stats.h"
+
+CCL_NAMESPACE_BEGIN
+
+static Stats global_stats;
+
+/* Internal API. */
+
+void util_guarded_mem_alloc(size_t n)
+{
+ global_stats.mem_alloc(n);
+}
+
+void util_guarded_mem_free(size_t n)
+{
+ global_stats.mem_free(n);
+}
+
+/* Public API. */
+
+size_t util_guarded_get_mem_used(void)
+{
+ return global_stats.mem_used;
+}
+
+size_t util_guarded_get_mem_peak(void)
+{
+ return global_stats.mem_peak;
+}
+
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_guarded_allocator.h b/intern/cycles/util/util_guarded_allocator.h
new file mode 100644
index 00000000000..263199417c4
--- /dev/null
+++ b/intern/cycles/util/util_guarded_allocator.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2011-2015 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UTIL_GUARDED_ALLOCATOR_H__
+#define __UTIL_GUARDED_ALLOCATOR_H__
+
+/* Define this in order to use Blender's guarded allocator to keep
+ * track of allocated buffers, their sizes and peak memory usage.
+ *
+ * This is usually a bad level call, but it's really handy to keep
+ * track of overall peak memory consumption during the scene
+ * synchronization step.
+ */
+#undef WITH_BLENDER_GUARDEDALLOC
+
+#include <memory>
+
+#include "util_types.h"
+
+#ifdef WITH_BLENDER_GUARDEDALLOC
+# include "../../guardedalloc/MEM_guardedalloc.h"
+#endif
+
+CCL_NAMESPACE_BEGIN
+
+/* Internal use only. */
+void util_guarded_mem_alloc(size_t n);
+void util_guarded_mem_free(size_t n);
+
+/* Guarded allocator for the use with STL. */
+template <typename T>
+class GuardedAllocator: public std::allocator<T> {
+public:
+ template<typename _Tp1>
+ struct rebind {
+ typedef GuardedAllocator<_Tp1> other;
+ };
+
+ T *allocate(size_t n, const void *hint = 0)
+ {
+ util_guarded_mem_alloc(n * sizeof(T));
+#ifdef WITH_BLENDER_GUARDEDALLOC
+ return (T*)MEM_mallocN(n * sizeof(T), "Cycles Alloc");
+#else
+ return std::allocator<T>::allocate(n, hint);
+#endif
+ }
+
+ void deallocate(T *p, size_t n)
+ {
+ util_guarded_mem_free(n * sizeof(T));
+#ifdef WITH_BLENDER_GUARDEDALLOC
+ MEM_freeN((void*)p);
+#else
+ std::allocator<T>::deallocate(p, n);
+#endif
+ }
+
+ GuardedAllocator() : std::allocator<T>() { }
+ GuardedAllocator(const GuardedAllocator &a) : std::allocator<T>(a) { }
+ template <class U>
+ GuardedAllocator(const GuardedAllocator<U> &a) : std::allocator<T>(a) { }
+ ~GuardedAllocator() { }
+};
+
+/* Get memory usage and peak from the guarded STL allocator. */
+size_t util_guarded_get_mem_used(void);
+size_t util_guarded_get_mem_peak(void);
+
+CCL_NAMESPACE_END
+
+#endif /* __UTIL_GUARDED_ALLOCATOR_H__ */
diff --git a/intern/cycles/util/util_half.h b/intern/cycles/util/util_half.h
index 397133618be..76941569bd2 100644
--- a/intern/cycles/util/util_half.h
+++ b/intern/cycles/util/util_half.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_HALF_H__
diff --git a/intern/cycles/util/util_hash.h b/intern/cycles/util/util_hash.h
index edd2448efa4..bbbedc22a47 100644
--- a/intern/cycles/util/util_hash.h
+++ b/intern/cycles/util/util_hash.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_HASH_H__
diff --git a/intern/cycles/util/util_image.h b/intern/cycles/util/util_image.h
index 4b8140e7a7a..bb8a31c6fec 100644
--- a/intern/cycles/util/util_image.h
+++ b/intern/cycles/util/util_image.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_IMAGE_H__
diff --git a/intern/cycles/util/util_list.h b/intern/cycles/util/util_list.h
index 2aa0b7381e3..6cb27e6defe 100644
--- a/intern/cycles/util/util_list.h
+++ b/intern/cycles/util/util_list.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_LIST_H__
diff --git a/intern/cycles/util/util_logging.cpp b/intern/cycles/util/util_logging.cpp
index 0722f16cf45..03041723e15 100644
--- a/intern/cycles/util/util_logging.cpp
+++ b/intern/cycles/util/util_logging.cpp
@@ -11,15 +11,63 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <util_logging.h>
#include "util_math.h"
+#include <stdio.h>
+#ifdef _MSC_VER
+# define snprintf _snprintf
+#endif
+
CCL_NAMESPACE_BEGIN
+void util_logging_init(const char *argv0)
+{
+#ifdef WITH_CYCLES_LOGGING
+ using CYCLES_GFLAGS_NAMESPACE::SetCommandLineOption;
+
+ /* Make it so FATAL messages are always print into console. */
+ char severity_fatal[32];
+ snprintf(severity_fatal, sizeof(severity_fatal), "%d",
+ google::GLOG_FATAL);
+
+ google::InitGoogleLogging(argv0);
+ SetCommandLineOption("logtostderr", "1");
+ SetCommandLineOption("v", "0");
+ SetCommandLineOption("stderrthreshold", severity_fatal);
+ SetCommandLineOption("minloglevel", severity_fatal);
+#else
+ (void) argv0;
+#endif
+}
+
+void util_logging_start(void)
+{
+#ifdef WITH_CYCLES_LOGGING
+ using CYCLES_GFLAGS_NAMESPACE::SetCommandLineOption;
+ SetCommandLineOption("logtostderr", "1");
+ SetCommandLineOption("v", "2");
+ SetCommandLineOption("stderrthreshold", "1");
+ SetCommandLineOption("minloglevel", "0");
+#endif
+}
+
+void util_logging_verbosity_set(int verbosity)
+{
+#ifdef WITH_CYCLES_LOGGING
+ using CYCLES_GFLAGS_NAMESPACE::SetCommandLineOption;
+ char val[10];
+ snprintf(val, sizeof(val), "%d", verbosity);
+ SetCommandLineOption("v", val);
+#else
+ (void) verbosity;
+#endif
+}
+
std::ostream& operator <<(std::ostream &os,
const float3 &value)
{
diff --git a/intern/cycles/util/util_logging.h b/intern/cycles/util/util_logging.h
index 991789e7460..7fc42ac355a 100644
--- a/intern/cycles/util/util_logging.h
+++ b/intern/cycles/util/util_logging.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_LOGGING_H__
@@ -43,7 +43,11 @@ public:
#endif
-class float3;
+struct float3;
+
+void util_logging_init(const char *argv0);
+void util_logging_start(void);
+void util_logging_verbosity_set(int verbosity);
std::ostream& operator <<(std::ostream &os,
const float3 &value);
diff --git a/intern/cycles/util/util_map.h b/intern/cycles/util/util_map.h
index 77500e4712d..54d6a8d6424 100644
--- a/intern/cycles/util/util_map.h
+++ b/intern/cycles/util/util_map.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_MAP_H__
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index c332e1709db..a4d49681a38 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_MATH_H__
@@ -71,6 +71,13 @@ CCL_NAMESPACE_BEGIN
#define M_SQRT2_F ((float)1.41421356237309504880) /* sqrt(2) */
#endif
+#ifndef M_LN2_F
+#define M_LN2_F ((float)0.6931471805599453) /* ln(2) */
+#endif
+
+#ifndef M_LN10_F
+#define M_LN10_F ((float)2.3025850929940457) /* ln(10) */
+#endif
/* Scalar */
@@ -124,6 +131,24 @@ ccl_device_inline double min(double a, double b)
return (a < b)? a: b;
}
+/* These 2 guys are templated for usage with registers data.
+ *
+ * NOTE: Since this is CPU-only functions it is ok to use references here.
+ * But for other devices we'll need to be careful about this.
+ */
+
+template<typename T>
+ccl_device_inline T min4(const T& a, const T& b, const T& c, const T& d)
+{
+ return min(min(a,b),min(c,d));
+}
+
+template<typename T>
+ccl_device_inline T max4(const T& a, const T& b, const T& c, const T& d)
+{
+ return max(max(a,b),max(c,d));
+}
+
#endif
ccl_device_inline float min4(float a, float b, float c, float d)
@@ -314,6 +339,12 @@ ccl_device_inline float2 normalize_len(const float2 a, float *t)
return a/(*t);
}
+ccl_device_inline float2 safe_normalize(const float2 a)
+{
+ float t = len(a);
+ return (t)? a/t: a;
+}
+
ccl_device_inline bool operator==(const float2 a, const float2 b)
{
return (a.x == b.x && a.y == b.y);
@@ -510,6 +541,12 @@ ccl_device_inline float3 normalize_len(const float3 a, float *t)
return a/(*t);
}
+ccl_device_inline float3 safe_normalize(const float3 a)
+{
+ float t = len(a);
+ return (t)? a/t: a;
+}
+
#ifndef __KERNEL_OPENCL__
ccl_device_inline bool operator==(const float3 a, const float3 b)
@@ -817,6 +854,12 @@ ccl_device_inline float4 normalize(const float4 a)
return a/len(a);
}
+ccl_device_inline float4 safe_normalize(const float4 a)
+{
+ float t = len(a);
+ return (t)? a/t: a;
+}
+
ccl_device_inline float4 min(float4 a, float4 b)
{
#ifdef __KERNEL_SSE__
@@ -1414,23 +1457,52 @@ ccl_device bool ray_quad_intersect(
}
/* projections */
-ccl_device bool map_to_sphere(float *r_u, float *r_v,
- const float x, const float y, const float z)
+ccl_device_inline float2 map_to_tube(const float3 co)
{
- float len = sqrtf(x * x + y * y + z * z);
- if(len > 0.0f) {
- if(UNLIKELY(x == 0.0f && y == 0.0f)) {
- *r_u = 0.0f; /* othwise domain error */
+ float len, u, v;
+ len = sqrtf(co.x * co.x + co.y * co.y);
+ if (len > 0.0f) {
+ u = (1.0f - (atan2f(co.x / len, co.y / len) / M_PI_F)) * 0.5f;
+ v = (co.x + 1.0f) * 0.5f;
+ }
+ else {
+ u = v = 0.0f;
+ }
+ return make_float2(u, v);
+}
+
+ccl_device_inline float2 map_to_sphere(const float3 co)
+{
+ float l = len(co);
+ float u, v;
+ if(l > 0.0f) {
+ if(UNLIKELY(co.x == 0.0f && co.y == 0.0f)) {
+ u = 0.0f; /* othwise domain error */
}
else {
- *r_u = (1.0f - atan2f(x, y) / M_PI_F) / 2.0f;
+ u = (1.0f - atan2f(co.x, co.y) / M_PI_F) / 2.0f;
}
- *r_v = 1.0f - safe_acosf(z / len) / M_PI_F;
- return true;
+ v = 1.0f - safe_acosf(co.z / l) / M_PI_F;
}
else {
- *r_v = *r_u = 0.0f; /* to avoid un-initialized variables */
- return false;
+ u = v = 0.0f;
+ }
+ return make_float2(u, v);
+}
+
+ccl_device_inline int util_max_axis(float3 vec)
+{
+ if(vec.x > vec.y) {
+ if(vec.x > vec.z)
+ return 0;
+ else
+ return 2;
+ }
+ else {
+ if(vec.y > vec.z)
+ return 1;
+ else
+ return 2;
}
}
diff --git a/intern/cycles/util/util_math_fast.h b/intern/cycles/util/util_math_fast.h
new file mode 100644
index 00000000000..4ad81e9c015
--- /dev/null
+++ b/intern/cycles/util/util_math_fast.h
@@ -0,0 +1,611 @@
+/*
+ * Adapted from OpenImageIO library with this license:
+ *
+ * Copyright 2008-2014 Larry Gritz and the other authors and contributors.
+ * All Rights Reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the software's owners nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * (This is the Modified BSD License)
+ *
+ * A few bits here are based upon code from NVIDIA that was also released
+ * under the same modified BSD license, and marked as:
+ * Copyright 2004 NVIDIA Corporation. All Rights Reserved.
+ *
+ * Some parts of this file were first open-sourced in Open Shading Language,
+ * then later moved here. The original copyright notice was:
+ * Copyright (c) 2009-2014 Sony Pictures Imageworks Inc., et al.
+ *
+ * Many of the math functions were copied from or inspired by other
+ * public domain sources or open source packages with compatible licenses.
+ * The individual functions give references were applicable.
+ */
+
+#ifndef __UTIL_FAST_MATH__
+#define __UTIL_FAST_MATH__
+
+CCL_NAMESPACE_BEGIN
+
+/* TODO(sergey): Make sure it does not conflict with SSE intrinsics. */
+ccl_device_inline float madd(const float a, const float b, const float c)
+{
+ /* NOTE: In the future we may want to explicitly ask for a fused
+ * multiply-add in a specialized version for float.
+ *
+ * NOTE: GCC/ICC will turn this (for float) into a FMA unless
+ * explicitly asked not to, clang seems to leave the code alone.
+ */
+ return a * b + c;
+}
+
+/*
+ * FAST & APPROXIMATE MATH
+ *
+ * The functions named "fast_*" provide a set of replacements to libm that
+ * are much faster at the expense of some accuracy and robust handling of
+ * extreme values. One design goal for these approximation was to avoid
+ * branches as much as possible and operate on single precision values only
+ * so that SIMD versions should be straightforward ports We also try to
+ * implement "safe" semantics (ie: clamp to valid range where possible)
+ * natively since wrapping these inline calls in another layer would be
+ * wasteful.
+ *
+ * Some functions are fast_safe_*, which is both a faster approximation as
+ * well as clamped input domain to ensure no NaN, Inf, or divide by zero.
+ */
+
+/* Round to nearest integer, returning as an int. */
+ccl_device_inline int fast_rint(float x)
+{
+ /* used by sin/cos/tan range reduction. */
+#ifdef __KERNEL_SSE4__
+ /* Single roundps instruction on SSE4.1+ (for gcc/clang at least). */
+ return float_to_int(rintf(x));
+#else
+ /* emulate rounding by adding/substracting 0.5. */
+ return float_to_int(x + copysignf(0.5f, x));
+#endif
+}
+
+ccl_device float fast_sinf(float x)
+{
+ /* Very accurate argument reduction from SLEEF,
+ * starts failing around x=262000
+ *
+ * Results on: [-2pi,2pi].
+ *
+ * Examined 2173837240 values of sin: 0.00662760244 avg ulp diff, 2 max ulp,
+ * 1.19209e-07 max error
+ */
+ int q = fast_rint(x * M_1_PI_F);
+ float qf = q;
+ x = madd(qf, -0.78515625f*4, x);
+ x = madd(qf, -0.00024187564849853515625f*4, x);
+ x = madd(qf, -3.7747668102383613586e-08f*4, x);
+ x = madd(qf, -1.2816720341285448015e-12f*4, x);
+ x = M_PI_2_F - (M_PI_2_F - x); /* Crush denormals */
+ float s = x * x;
+ if((q & 1) != 0) x = -x;
+ /* This polynomial approximation has very low error on [-pi/2,+pi/2]
+ * 1.19209e-07 max error in total over [-2pi,+2pi]. */
+ float u = 2.6083159809786593541503e-06f;
+ u = madd(u, s, -0.0001981069071916863322258f);
+ u = madd(u, s, +0.00833307858556509017944336f);
+ u = madd(u, s, -0.166666597127914428710938f);
+ u = madd(s, u * x, x);
+ /* For large x, the argument reduction can fail and the polynomial can be
+ * evaluated with arguments outside the valid internal. Just clamp the bad
+ * values away (setting to 0.0f means no branches need to be generated). */
+ if(fabsf(u) > 1.0f) {
+ u = 0.0f;
+ }
+ return u;
+}
+
+ccl_device float fast_cosf(float x)
+{
+ /* Same argument reduction as fast_sinf(). */
+ int q = fast_rint(x * M_1_PI_F);
+ float qf = q;
+ x = madd(qf, -0.78515625f*4, x);
+ x = madd(qf, -0.00024187564849853515625f*4, x);
+ x = madd(qf, -3.7747668102383613586e-08f*4, x);
+ x = madd(qf, -1.2816720341285448015e-12f*4, x);
+ x = M_PI_2_F - (M_PI_2_F - x); /* Crush denormals. */
+ float s = x * x;
+ /* Polynomial from SLEEF's sincosf, max error is
+ * 4.33127e-07 over [-2pi,2pi] (98% of values are "exact"). */
+ float u = -2.71811842367242206819355e-07f;
+ u = madd(u, s, +2.47990446951007470488548e-05f);
+ u = madd(u, s, -0.00138888787478208541870117f);
+ u = madd(u, s, +0.0416666641831398010253906f);
+ u = madd(u, s, -0.5f);
+ u = madd(u, s, +1.0f);
+ if((q & 1) != 0) {
+ u = -u;
+ }
+ if(fabsf(u) > 1.0f) {
+ u = 0.0f;
+ }
+ return u;
+}
+
+ccl_device void fast_sincosf(float x, float* sine, float* cosine)
+{
+ /* Same argument reduction as fast_sin. */
+ int q = fast_rint(x * M_1_PI_F);
+ float qf = q;
+ x = madd(qf, -0.78515625f*4, x);
+ x = madd(qf, -0.00024187564849853515625f*4, x);
+ x = madd(qf, -3.7747668102383613586e-08f*4, x);
+ x = madd(qf, -1.2816720341285448015e-12f*4, x);
+ x = M_PI_2_F - (M_PI_2_F - x); // crush denormals
+ float s = x * x;
+ /* NOTE: same exact polynomials as fast_sinf() and fast_cosf() above. */
+ if((q & 1) != 0) {
+ x = -x;
+ }
+ float su = 2.6083159809786593541503e-06f;
+ su = madd(su, s, -0.0001981069071916863322258f);
+ su = madd(su, s, +0.00833307858556509017944336f);
+ su = madd(su, s, -0.166666597127914428710938f);
+ su = madd(s, su * x, x);
+ float cu = -2.71811842367242206819355e-07f;
+ cu = madd(cu, s, +2.47990446951007470488548e-05f);
+ cu = madd(cu, s, -0.00138888787478208541870117f);
+ cu = madd(cu, s, +0.0416666641831398010253906f);
+ cu = madd(cu, s, -0.5f);
+ cu = madd(cu, s, +1.0f);
+ if((q & 1) != 0) {
+ cu = -cu;
+ }
+ if(fabsf(su) > 1.0f) {
+ su = 0.0f;
+ }
+ if(fabsf(cu) > 1.0f) {
+ cu = 0.0f;
+ }
+ *sine = su;
+ *cosine = cu;
+}
+
+/* NOTE: this approximation is only valid on [-8192.0,+8192.0], it starts
+ * becoming really poor outside of this range because the reciprocal amplifies
+ * errors.
+ */
+ccl_device float fast_tanf(float x)
+{
+ /* Derived from SLEEF implementation.
+ *
+ * Note that we cannot apply the "denormal crush" trick everywhere because
+ * we sometimes need to take the reciprocal of the polynomial
+ */
+ int q = fast_rint(x * 2.0f * M_1_PI_F);
+ float qf = q;
+ x = madd(qf, -0.78515625f*2, x);
+ x = madd(qf, -0.00024187564849853515625f*2, x);
+ x = madd(qf, -3.7747668102383613586e-08f*2, x);
+ x = madd(qf, -1.2816720341285448015e-12f*2, x);
+ if((q & 1) == 0) {
+ /* Crush denormals (only if we aren't inverting the result later). */
+ x = M_PI_4_F - (M_PI_4_F - x);
+ }
+ float s = x * x;
+ float u = 0.00927245803177356719970703f;
+ u = madd(u, s, 0.00331984995864331722259521f);
+ u = madd(u, s, 0.0242998078465461730957031f);
+ u = madd(u, s, 0.0534495301544666290283203f);
+ u = madd(u, s, 0.133383005857467651367188f);
+ u = madd(u, s, 0.333331853151321411132812f);
+ u = madd(s, u * x, x);
+ if((q & 1) != 0) {
+ u = -1.0f / u;
+ }
+ return u;
+}
+
+/* Fast, approximate sin(x*M_PI) with maximum absolute error of 0.000918954611.
+ *
+ * Adapted from http://devmaster.net/posts/9648/fast-and-accurate-sine-cosine#comment-76773
+ */
+ccl_device float fast_sinpif(float x)
+{
+ /* Fast trick to strip the integral part off, so our domain is [-1, 1]. */
+ const float z = x - ((x + 25165824.0f) - 25165824.0f);
+ const float y = z - z * fabsf(z);
+ const float Q = 3.10396624f;
+ const float P = 3.584135056f; /* P = 16-4*Q */
+ return y * (Q + P * fabsf(y));
+
+ /* The original article used used inferior constants for Q and P and
+ * so had max error 1.091e-3.
+ *
+ * The optimal value for Q was determined by exhaustive search, minimizing
+ * the absolute numerical error relative to float(std::sin(double(phi*M_PI)))
+ * over the interval [0,2] (which is where most of the invocations happen).
+ *
+ * The basic idea of this approximation starts with the coarse approximation:
+ * sin(pi*x) ~= f(x) = 4 * (x - x * abs(x))
+ *
+ * This approximation always _over_ estimates the target. On the otherhand,
+ * the curve:
+ * sin(pi*x) ~= f(x) * abs(f(x)) / 4
+ *
+ * always lies _under_ the target. Thus we can simply numerically search for
+ * the optimal constant to LERP these curves into a more precise
+ * approximation.
+ *
+ * After folding the constants together and simplifying the resulting math,
+ * we end up with the compact implementation above.
+ *
+ * NOTE: this function actually computes sin(x * pi) which avoids one or two
+ * mults in many cases and guarantees exact values at integer periods.
+ */
+}
+
+/* Fast approximate cos(x*M_PI) with ~0.1% absolute error. */
+ccl_device_inline float fast_cospif(float x)
+{
+ return fast_sinpif(x+0.5f);
+}
+
+ccl_device float fast_acosf(float x)
+{
+ const float f = fabsf(x);
+ /* clamp and crush denormals. */
+ const float m = (f < 1.0f) ? 1.0f - (1.0f - f) : 1.0f;
+ /* Based on http://www.pouet.net/topic.php?which=9132&page=2
+ * 85% accurate (ulp 0)
+ * Examined 2130706434 values of acos: 15.2000597 avg ulp diff, 4492 max ulp, 4.51803e-05 max error // without "denormal crush"
+ * Examined 2130706434 values of acos: 15.2007108 avg ulp diff, 4492 max ulp, 4.51803e-05 max error // with "denormal crush"
+ */
+ const float a = sqrtf(1.0f - m) *
+ (1.5707963267f + m * (-0.213300989f + m *
+ (0.077980478f + m * -0.02164095f)));
+ return x < 0 ? M_PI_F - a : a;
+}
+
+ccl_device float fast_asinf(float x)
+{
+ /* Based on acosf approximation above.
+ * Max error is 4.51133e-05 (ulps are higher because we are consistently off
+ * by a little amount).
+ */
+ const float f = fabsf(x);
+ /* Clamp and crush denormals. */
+ const float m = (f < 1.0f) ? 1.0f - (1.0f - f) : 1.0f;
+ const float a = M_PI_2_F - sqrtf(1.0f - m) *
+ (1.5707963267f + m * (-0.213300989f + m *
+ (0.077980478f + m * -0.02164095f)));
+ return copysignf(a, x);
+}
+
+ccl_device float fast_atanf(float x)
+{
+ const float a = fabsf(x);
+ const float k = a > 1.0f ? 1 / a : a;
+ const float s = 1.0f - (1.0f - k); /* Crush denormals. */
+ const float t = s * s;
+ /* http://mathforum.org/library/drmath/view/62672.html
+ * Examined 4278190080 values of atan: 2.36864877 avg ulp diff, 302 max ulp, 6.55651e-06 max error // (with denormals)
+ * Examined 4278190080 values of atan: 171160502 avg ulp diff, 855638016 max ulp, 6.55651e-06 max error // (crush denormals)
+ */
+ float r = s * madd(0.43157974f, t, 1.0f) /
+ madd(madd(0.05831938f, t, 0.76443945f), t, 1.0f);
+ if(a > 1.0f) {
+ /* TODO(sergey): Is it M_PI_2_F? */
+ r = 1.570796326794896557998982f - r;
+ }
+ return copysignf(r, x);
+}
+
+ccl_device float fast_atan2f(float y, float x)
+{
+ /* Based on atan approximation above.
+ *
+ * The special cases around 0 and infinity were tested explicitly.
+ *
+ * The only case not handled correctly is x=NaN,y=0 which returns 0 instead
+ * of nan.
+ */
+ const float a = fabsf(x);
+ const float b = fabsf(y);
+
+ const float k = (b == 0) ? 0.0f : ((a == b) ? 1.0f : (b > a ? a / b : b / a));
+ const float s = 1.0f - (1.0f - k); /* Crush denormals */
+ const float t = s * s;
+
+ float r = s * madd(0.43157974f, t, 1.0f) /
+ madd(madd(0.05831938f, t, 0.76443945f), t, 1.0f);
+
+ if(b > a) {
+ /* Account for arg reduction. */
+ /* TODO(sergey): Is it M_PI_2_F? */
+ r = 1.570796326794896557998982f - r;
+ }
+ /* Test sign bit of x. */
+ if(__float_as_uint(x) & 0x80000000u) {
+ r = M_PI_F - r;
+ }
+ return copysignf(r, y);
+}
+
+/* Based on:
+ *
+ * https://github.com/LiraNuna/glsl-sse2/blob/master/source/vec4.h
+ *
+ */
+ccl_device float fast_log2f(float x)
+{
+ /* NOTE: clamp to avoid special cases and make result "safe" from large
+ * negative values/nans. */
+ clamp(x, FLT_MIN, FLT_MAX);
+ unsigned bits = __float_as_uint(x);
+ int exponent = (int)(bits >> 23) - 127;
+ float f = __uint_as_float((bits & 0x007FFFFF) | 0x3f800000) - 1.0f;
+ /* Examined 2130706432 values of log2 on [1.17549435e-38,3.40282347e+38]:
+ * 0.0797524457 avg ulp diff, 3713596 max ulp, 7.62939e-06 max error.
+ * ulp histogram:
+ * 0 = 97.46%
+ * 1 = 2.29%
+ * 2 = 0.11%
+ */
+ float f2 = f * f;
+ float f4 = f2 * f2;
+ float hi = madd(f, -0.00931049621349f, 0.05206469089414f);
+ float lo = madd(f, 0.47868480909345f, -0.72116591947498f);
+ hi = madd(f, hi, -0.13753123777116f);
+ hi = madd(f, hi, 0.24187369696082f);
+ hi = madd(f, hi, -0.34730547155299f);
+ lo = madd(f, lo, 1.442689881667200f);
+ return ((f4 * hi) + (f * lo)) + exponent;
+}
+
+ccl_device_inline float fast_logf(float x)
+{
+ /* Examined 2130706432 values of logf on [1.17549435e-38,3.40282347e+38]:
+ * 0.313865375 avg ulp diff, 5148137 max ulp, 7.62939e-06 max error.
+ */
+ return fast_log2f(x) * M_LN2_F;
+}
+
+ccl_device_inline float fast_log10(float x)
+{
+ /* Examined 2130706432 values of log10f on [1.17549435e-38,3.40282347e+38]:
+ * 0.631237033 avg ulp diff, 4471615 max ulp, 3.8147e-06 max error.
+ */
+ return fast_log2f(x) * M_LN2_F / M_LN10_F;
+}
+
+ccl_device float fast_logb(float x)
+{
+ /* Don't bother with denormals. */
+ x = fabsf(x);
+ clamp(x, FLT_MIN, FLT_MAX);
+ unsigned bits = __float_as_uint(x);
+ return (int)(bits >> 23) - 127;
+}
+
+ccl_device float fast_exp2f(float x)
+{
+ /* Clamp to safe range for final addition. */
+ clamp(x, -126.0f, 126.0f);
+ /* Range reduction. */
+ int m = (int)x; x -= m;
+ x = 1.0f - (1.0f - x); /* Crush denormals (does not affect max ulps!). */
+ /* 5th degree polynomial generated with sollya
+ * Examined 2247622658 values of exp2 on [-126,126]: 2.75764912 avg ulp diff,
+ * 232 max ulp.
+ *
+ * ulp histogram:
+ * 0 = 87.81%
+ * 1 = 4.18%
+ */
+ float r = 1.33336498402e-3f;
+ r = madd(x, r, 9.810352697968e-3f);
+ r = madd(x, r, 5.551834031939e-2f);
+ r = madd(x, r, 0.2401793301105f);
+ r = madd(x, r, 0.693144857883f);
+ r = madd(x, r, 1.0f);
+ /* Multiply by 2 ^ m by adding in the exponent. */
+ /* NOTE: left-shift of negative number is undefined behavior. */
+ return __uint_as_float(__float_as_uint(r) + ((unsigned)m << 23));
+}
+
+ccl_device_inline float fast_expf(float x)
+{
+ /* Examined 2237485550 values of exp on [-87.3300018,87.3300018]:
+ * 2.6666452 avg ulp diff, 230 max ulp.
+ */
+ return fast_exp2f(x / M_LN2_F);
+}
+
+ccl_device_inline float fast_exp10(float x)
+{
+ /* Examined 2217701018 values of exp10 on [-37.9290009,37.9290009]:
+ * 2.71732409 avg ulp diff, 232 max ulp.
+ */
+ return fast_exp2f(x * M_LN10_F / M_LN2_F);
+}
+
+ccl_device_inline float fast_expm1f(float x)
+{
+ if(fabsf(x) < 1e-5f) {
+ x = 1.0f - (1.0f - x); /* Crush denormals. */
+ return madd(0.5f, x * x, x);
+ }
+ else {
+ return fast_expf(x) - 1.0f;
+ }
+}
+
+ccl_device float fast_sinhf(float x)
+{
+ float a = fabsf(x);
+ if(a > 1.0f) {
+ /* Examined 53389559 values of sinh on [1,87.3300018]:
+ * 33.6886442 avg ulp diff, 178 max ulp. */
+ float e = fast_expf(a);
+ return copysignf(0.5f * e - 0.5f / e, x);
+ }
+ else {
+ a = 1.0f - (1.0f - a); /* Crush denorms. */
+ float a2 = a * a;
+ /* Degree 7 polynomial generated with sollya. */
+ /* Examined 2130706434 values of sinh on [-1,1]: 1.19209e-07 max error. */
+ float r = 2.03945513931e-4f;
+ r = madd(r, a2, 8.32990277558e-3f);
+ r = madd(r, a2, 0.1666673421859f);
+ r = madd(r * a, a2, a);
+ return copysignf(r, x);
+ }
+}
+
+ccl_device_inline float fast_coshf(float x)
+{
+ /* Examined 2237485550 values of cosh on [-87.3300018,87.3300018]:
+ * 1.78256726 avg ulp diff, 178 max ulp.
+ */
+ float e = fast_expf(fabsf(x));
+ return 0.5f * e + 0.5f / e;
+}
+
+ccl_device_inline float fast_tanhf(float x)
+{
+ /* Examined 4278190080 values of tanh on [-3.40282347e+38,3.40282347e+38]:
+ * 3.12924e-06 max error.
+ */
+ /* NOTE: ulp error is high because of sub-optimal handling around the origin. */
+ float e = fast_expf(2.0f * fabsf(x));
+ return copysignf(1.0f - 2.0f / (1.0f + e), x);
+}
+
+ccl_device float fast_safe_powf(float x, float y)
+{
+ if(y == 0) return 1.0f; /* x^1=1 */
+ if(x == 0) return 0.0f; /* 0^y=0 */
+ float sign = 1.0f;
+ if(x < 0.0f) {
+ /* if x is negative, only deal with integer powers
+ * powf returns NaN for non-integers, we will return 0 instead.
+ */
+ int ybits = __float_as_int(y) & 0x7fffffff;
+ if(ybits >= 0x4b800000) {
+ // always even int, keep positive
+ }
+ else if(ybits >= 0x3f800000) {
+ /* Bigger than 1, check. */
+ int k = (ybits >> 23) - 127; /* Get exponent. */
+ int j = ybits >> (23 - k); /* Shift out possible fractional bits. */
+ if((j << (23 - k)) == ybits) { /* rebuild number and check for a match. */
+ /* +1 for even, -1 for odd. */
+ sign = __int_as_float(0x3f800000 | (j << 31));
+ }
+ else {
+ /* Not an integer. */
+ return 0.0f;
+ }
+ }
+ else {
+ /* Not an integer. */
+ return 0.0f;
+ }
+ }
+ return sign * fast_exp2f(y * fast_log2f(fabsf(x)));
+}
+
+/* TODO(sergey): Check speed with our erf functions implementation from
+ * bsdf_microfaset.h.
+ */
+
+ccl_device float fast_erff(float x)
+{
+ /* Examined 1082130433 values of erff on [0,4]: 1.93715e-06 max error. */
+ /* Abramowitz and Stegun, 7.1.28. */
+ const float a1 = 0.0705230784f;
+ const float a2 = 0.0422820123f;
+ const float a3 = 0.0092705272f;
+ const float a4 = 0.0001520143f;
+ const float a5 = 0.0002765672f;
+ const float a6 = 0.0000430638f;
+ const float a = fabsf(x);
+ const float b = 1.0f - (1.0f - a); /* Crush denormals. */
+ const float r = madd(madd(madd(madd(madd(madd(a6, b, a5), b, a4), b, a3), b, a2), b, a1), b, 1.0f);
+ const float s = r * r; /* ^2 */
+ const float t = s * s; /* ^4 */
+ const float u = t * t; /* ^8 */
+ const float v = u * u; /* ^16 */
+ return copysignf(1.0f - 1.0f / v, x);
+}
+
+ccl_device_inline float fast_erfcf(float x)
+{
+ /* Examined 2164260866 values of erfcf on [-4,4]: 1.90735e-06 max error.
+ *
+ * ulp histogram:
+ *
+ * 0 = 80.30%
+ */
+ return 1.0f - fast_erff(x);
+}
+
+ccl_device float fast_ierff(float x)
+{
+ /* From: Approximating the erfinv function by Mike Giles. */
+ /* To avoid trouble at the limit, clamp input to 1-eps. */
+ float a = fabsf(x);
+ if(a > 0.99999994f) {
+ a = 0.99999994f;
+ }
+ float w = -fast_logf((1.0f - a) * (1.0f + a)), p;
+ if(w < 5.0f) {
+ w = w - 2.5f;
+ p = 2.81022636e-08f;
+ p = madd(p, w, 3.43273939e-07f);
+ p = madd(p, w, -3.5233877e-06f);
+ p = madd(p, w, -4.39150654e-06f);
+ p = madd(p, w, 0.00021858087f);
+ p = madd(p, w, -0.00125372503f);
+ p = madd(p, w, -0.00417768164f);
+ p = madd(p, w, 0.246640727f);
+ p = madd(p, w, 1.50140941f);
+ }
+ else {
+ w = sqrtf(w) - 3.0f;
+ p = -0.000200214257f;
+ p = madd(p, w, 0.000100950558f);
+ p = madd(p, w, 0.00134934322f);
+ p = madd(p, w, -0.00367342844f);
+ p = madd(p, w, 0.00573950773f);
+ p = madd(p, w, -0.0076224613f);
+ p = madd(p, w, 0.00943887047f);
+ p = madd(p, w, 1.00167406f);
+ p = madd(p, w, 2.83297682f);
+ }
+ return p * x;
+}
+
+CCL_NAMESPACE_END
+
+#endif /* __UTIL_FAST_MATH__ */
diff --git a/intern/cycles/util/util_md5.cpp b/intern/cycles/util/util_md5.cpp
index add0d18c742..b2a32c45287 100644
--- a/intern/cycles/util/util_md5.cpp
+++ b/intern/cycles/util/util_md5.cpp
@@ -152,8 +152,8 @@ void MD5Hash::process(const uint8_t *data /*[64]*/)
* a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
- t = a + F(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
+ t = a + F(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, T1);
SET(d, a, b, c, 1, 12, T2);
@@ -178,8 +178,8 @@ void MD5Hash::process(const uint8_t *data /*[64]*/)
* a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
- t = a + G(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
+ t = a + G(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, T17);
SET(d, a, b, c, 6, 9, T18);
@@ -230,8 +230,8 @@ void MD5Hash::process(const uint8_t *data /*[64]*/)
* a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
- t = a + I(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
+ t = a + I(b,c,d) + X[k] + Ti;\
+ a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, T49);
SET(d, a, b, c, 7, 10, T50);
diff --git a/intern/cycles/util/util_opengl.h b/intern/cycles/util/util_opengl.h
index 667a5db653d..0b5462e0a09 100644
--- a/intern/cycles/util/util_opengl.h
+++ b/intern/cycles/util/util_opengl.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_OPENGL_H__
@@ -20,6 +20,12 @@
/* OpenGL header includes, used everywhere we use OpenGL, to deal with
* platform differences in one central place. */
-#include "glew-mx.h"
+#ifdef WITH_GLEW_MX
+# include "glew-mx.h"
+#else
+# include <GL/glew.h>
+# define mxCreateContext() glewInit()
+# define mxMakeCurrentContext(x) (x)
+#endif
#endif /* __UTIL_OPENGL_H__ */
diff --git a/intern/cycles/util/util_optimization.h b/intern/cycles/util/util_optimization.h
index 2feb3d6ab7e..b230bb1a627 100644
--- a/intern/cycles/util/util_optimization.h
+++ b/intern/cycles/util/util_optimization.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_OPTIMIZATION_H__
@@ -130,6 +130,9 @@
/* MinGW64 has conflicting declarations for these SSE headers in <windows.h>.
* Since we can't avoid including <windows.h>, better only include that */
+#define NOGDI
+#define NOMINMAX
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
diff --git a/intern/cycles/util/util_param.h b/intern/cycles/util/util_param.h
index ef20ff0fcd2..69bcbf80a78 100644
--- a/intern/cycles/util/util_param.h
+++ b/intern/cycles/util/util_param.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_PARAM_H__
diff --git a/intern/cycles/util/util_path.cpp b/intern/cycles/util/util_path.cpp
index aa424045ece..e8f1ec81763 100644
--- a/intern/cycles/util/util_path.cpp
+++ b/intern/cycles/util/util_path.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "util_debug.h"
@@ -25,12 +25,6 @@ OIIO_NAMESPACE_USING
#include <stdio.h>
-#include <boost/version.hpp>
-
-#if (BOOST_VERSION < 104400)
-# define BOOST_FILESYSTEM_VERSION 2
-#endif
-
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
@@ -49,6 +43,25 @@ static string from_boost(const boost::filesystem::path& path)
return path.string().c_str();
}
+static char *path_specials(const string& sub)
+{
+ static bool env_init = false;
+ static char *env_shader_path;
+ static char *env_kernel_path;
+ if(!env_init) {
+ env_shader_path = getenv("CYCLES_SHADER_PATH");
+ env_kernel_path = getenv("CYCLES_KERNEL_PATH");
+ env_init = true;
+ }
+ if(env_shader_path != NULL && sub == "shader") {
+ return env_shader_path;
+ }
+ else if(env_shader_path != NULL && sub == "kernel") {
+ return env_kernel_path;
+ }
+ return NULL;
+}
+
void path_init(const string& path, const string& user_path)
{
cached_path = path;
@@ -62,6 +75,10 @@ void path_init(const string& path, const string& user_path)
string path_get(const string& sub)
{
+ char *special = path_specials(sub);
+ if(special != NULL)
+ return special;
+
if(cached_path == "")
cached_path = path_dirname(Sysutil::this_program_path());
@@ -78,11 +95,7 @@ string path_user_get(const string& sub)
string path_filename(const string& path)
{
-#if (BOOST_FILESYSTEM_VERSION == 2)
- return to_boost(path).filename();
-#else
return from_boost(to_boost(path).filename());
-#endif
}
string path_dirname(const string& path)
@@ -261,11 +274,7 @@ void path_cache_clear_except(const string& name, const set<string>& except)
boost::filesystem::directory_iterator it(dir), it_end;
for(; it != it_end; it++) {
-#if (BOOST_FILESYSTEM_VERSION == 2)
- string filename = from_boost(it->path().filename());
-#else
string filename = from_boost(it->path().filename().string());
-#endif
if(boost::starts_with(filename, name))
if(except.find(filename) == except.end())
diff --git a/intern/cycles/util/util_path.h b/intern/cycles/util/util_path.h
index fd9ea11740d..b81d71d1c0f 100644
--- a/intern/cycles/util/util_path.h
+++ b/intern/cycles/util/util_path.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_PATH_H__
diff --git a/intern/cycles/util/util_progress.h b/intern/cycles/util/util_progress.h
index e721a3f5047..0ff48630a81 100644
--- a/intern/cycles/util/util_progress.h
+++ b/intern/cycles/util/util_progress.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_PROGRESS_H__
@@ -38,6 +38,7 @@ public:
sample = 0;
start_time = time_dt();
total_time = 0.0f;
+ render_time = 0.0f;
tile_time = 0.0f;
status = "Initializing";
substatus = "";
@@ -46,6 +47,8 @@ public:
update_cb = NULL;
cancel = false;
cancel_message = "";
+ error = false;
+ error_message = "";
cancel_cb = NULL;
}
@@ -59,7 +62,7 @@ public:
thread_scoped_lock lock(progress.progress_mutex);
progress.get_status(status, substatus);
- progress.get_tile(tile, total_time, tile_time);
+ progress.get_tile(tile, total_time, render_time, tile_time);
sample = progress.get_sample();
@@ -71,7 +74,9 @@ public:
tile = 0;
sample = 0;
start_time = time_dt();
+ render_start_time = time_dt();
total_time = 0.0f;
+ render_time = 0.0f;
tile_time = 0.0f;
status = "Initializing";
substatus = "";
@@ -79,6 +84,8 @@ public:
sync_substatus = "";
cancel = false;
cancel_message = "";
+ error = false;
+ error_message = "";
}
/* cancel */
@@ -108,6 +115,28 @@ public:
cancel_cb = function;
}
+ /* error */
+ void set_error(const string& error_message_)
+ {
+ thread_scoped_lock lock(progress_mutex);
+ error_message = error_message_;
+ error = true;
+ /* If error happens we also stop rendering. */
+ cancel_message = error_message_;
+ cancel = true;
+ }
+
+ bool get_error()
+ {
+ return error;
+ }
+
+ string get_error_message()
+ {
+ thread_scoped_lock lock(progress_mutex);
+ return error_message;
+ }
+
/* tile and timing information */
void set_start_time(double start_time_)
@@ -117,21 +146,30 @@ public:
start_time = start_time_;
}
+ void set_render_start_time(double render_start_time_)
+ {
+ thread_scoped_lock lock(progress_mutex);
+
+ render_start_time = render_start_time_;
+ }
+
void set_tile(int tile_, double tile_time_)
{
thread_scoped_lock lock(progress_mutex);
tile = tile_;
total_time = time_dt() - start_time;
+ render_time = time_dt() - render_start_time;
tile_time = tile_time_;
}
- void get_tile(int& tile_, double& total_time_, double& tile_time_)
+ void get_tile(int& tile_, double& total_time_, double& render_time_, double& tile_time_)
{
thread_scoped_lock lock(progress_mutex);
tile_ = tile;
total_time_ = (total_time > 0.0)? total_time: 0.0;
+ render_time_ = (render_time > 0.0)? render_time: 0.0;
tile_time_ = tile_time;
}
@@ -169,6 +207,7 @@ public:
status = status_;
substatus = substatus_;
total_time = time_dt() - start_time;
+ render_time = time_dt() - render_start_time;
}
set_update();
@@ -180,6 +219,7 @@ public:
thread_scoped_lock lock(progress_mutex);
substatus = substatus_;
total_time = time_dt() - start_time;
+ render_time = time_dt() - render_start_time;
}
set_update();
@@ -192,6 +232,7 @@ public:
sync_status = status_;
sync_substatus = substatus_;
total_time = time_dt() - start_time;
+ render_time = time_dt() - render_start_time;
}
set_update();
@@ -204,6 +245,7 @@ public:
thread_scoped_lock lock(progress_mutex);
sync_substatus = substatus_;
total_time = time_dt() - start_time;
+ render_time = time_dt() - render_start_time;
}
set_update();
@@ -247,8 +289,8 @@ protected:
int tile; /* counter for rendered tiles */
int sample; /* counter of rendered samples, global for all tiles */
- double start_time;
- double total_time;
+ double start_time, render_start_time;
+ double total_time, render_time;
double tile_time;
string status;
@@ -259,6 +301,9 @@ protected:
volatile bool cancel;
string cancel_message;
+
+ volatile bool error;
+ string error_message;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_set.h b/intern/cycles/util/util_set.h
index 6078114e714..73a2bf19899 100644
--- a/intern/cycles/util/util_set.h
+++ b/intern/cycles/util/util_set.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_SET_H__
diff --git a/intern/cycles/util/util_simd.cpp b/intern/cycles/util/util_simd.cpp
index 0436823e62a..eb9e32800e1 100644
--- a/intern/cycles/util/util_simd.cpp
+++ b/intern/cycles/util/util_simd.cpp
@@ -12,7 +12,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifdef WITH_KERNEL_SSE2
diff --git a/intern/cycles/util/util_simd.h b/intern/cycles/util/util_simd.h
index 39506a6359b..625f26c1316 100644
--- a/intern/cycles/util/util_simd.h
+++ b/intern/cycles/util/util_simd.h
@@ -12,7 +12,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_SIMD_TYPES_H__
diff --git a/intern/cycles/util/util_sseb.h b/intern/cycles/util/util_sseb.h
index be510256dd3..6e669701f3b 100644
--- a/intern/cycles/util/util_sseb.h
+++ b/intern/cycles/util/util_sseb.h
@@ -12,7 +12,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_SSEB_H__
@@ -119,14 +119,29 @@ template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const sseb sh
return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0));
}
+template<> __forceinline const sseb shuffle<0, 1, 0, 1>( const sseb& a ) {
+ return _mm_movelh_ps(a, a);
+}
+
+template<> __forceinline const sseb shuffle<2, 3, 2, 3>( const sseb& a ) {
+ return _mm_movehl_ps(a, a);
+}
+
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const sseb shuffle( const sseb& a, const sseb& b ) {
return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
}
+template<> __forceinline const sseb shuffle<0, 1, 0, 1>( const sseb& a, const sseb& b ) {
+ return _mm_movelh_ps(a, b);
+}
+
+template<> __forceinline const sseb shuffle<2, 3, 2, 3>( const sseb& a, const sseb& b ) {
+ return _mm_movehl_ps(b, a);
+}
+
#if defined(__KERNEL_SSE3__)
template<> __forceinline const sseb shuffle<0, 0, 2, 2>( const sseb& a ) { return _mm_moveldup_ps(a); }
template<> __forceinline const sseb shuffle<1, 1, 3, 3>( const sseb& a ) { return _mm_movehdup_ps(a); }
-template<> __forceinline const sseb shuffle<0, 1, 0, 1>( const sseb& a ) { return _mm_castpd_ps(_mm_movedup_pd (a)); }
#endif
#if defined(__KERNEL_SSE41__)
@@ -153,6 +168,16 @@ __forceinline bool none ( const sseb& b ) { return _mm_movemask_ps(b) == 0x
__forceinline size_t movemask( const sseb& a ) { return _mm_movemask_ps(a); }
+////////////////////////////////////////////////////////////////////////////////
+/// Debug Functions
+////////////////////////////////////////////////////////////////////////////////
+
+ccl_device_inline void print_sseb(const char *label, const sseb &a)
+{
+ printf("%s: %df %df %df %d\n",
+ label, a[0], a[1], a[2], a[3]);
+}
+
#endif
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_ssef.h b/intern/cycles/util/util_ssef.h
index f4236cc616e..e625fa63568 100644
--- a/intern/cycles/util/util_ssef.h
+++ b/intern/cycles/util/util_ssef.h
@@ -12,7 +12,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_SSEF_H__
@@ -119,6 +119,9 @@ __forceinline const ssef operator^(const ssef& a, const ssei& b) { return _mm_xo
__forceinline const ssef operator&(const ssef& a, const ssef& b) { return _mm_and_ps(a.m128,b.m128); }
__forceinline const ssef operator&(const ssef& a, const ssei& b) { return _mm_and_ps(a.m128,_mm_castsi128_ps(b.m128)); }
+__forceinline const ssef operator|(const ssef& a, const ssef& b) { return _mm_or_ps(a.m128,b.m128); }
+__forceinline const ssef operator|(const ssef& a, const ssei& b) { return _mm_or_ps(a.m128,_mm_castsi128_ps(b.m128)); }
+
__forceinline const ssef andnot(const ssef& a, const ssef& b) { return _mm_andnot_ps(a.m128,b.m128); }
__forceinline const ssef min(const ssef& a, const ssef& b) { return _mm_min_ps(a.m128,b.m128); }
@@ -159,8 +162,8 @@ __forceinline const ssef nmsub(const ssef& a, const ssef& b, const ssef& c) { re
#else
__forceinline const ssef madd (const ssef& a, const ssef& b, const ssef& c) { return a*b+c; }
__forceinline const ssef msub (const ssef& a, const ssef& b, const ssef& c) { return a*b-c; }
-__forceinline const ssef nmadd(const ssef& a, const ssef& b, const ssef& c) { return -a*b-c;}
-__forceinline const ssef nmsub(const ssef& a, const ssef& b, const ssef& c) { return c-a*b; }
+__forceinline const ssef nmadd(const ssef& a, const ssef& b, const ssef& c) { return c-a*b;}
+__forceinline const ssef nmsub(const ssef& a, const ssef& b, const ssef& c) { return -a*b-c; }
#endif
////////////////////////////////////////////////////////////////////////////////
@@ -267,10 +270,30 @@ template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssef sh
return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(i3, i2, i1, i0)));
}
+template<> __forceinline const ssef shuffle<0, 1, 0, 1>(const ssef& a) {
+ return _mm_movelh_ps(a, a);
+}
+
+template<> __forceinline const ssef shuffle<2, 3, 2, 3>(const ssef& a) {
+ return _mm_movehl_ps(a, a);
+}
+
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssef shuffle(const ssef& a, const ssef& b) {
return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
}
+template<size_t i0> __forceinline const ssef shuffle(const ssef& a, const ssef& b) {
+ return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i0, i0, i0, i0));
+}
+
+template<> __forceinline const ssef shuffle<0, 1, 0, 1>(const ssef& a, const ssef& b) {
+ return _mm_movelh_ps(a, b);
+}
+
+template<> __forceinline const ssef shuffle<2, 3, 2, 3>(const ssef& a, const ssef& b) {
+ return _mm_movehl_ps(b, a);
+}
+
#if defined(__KERNEL_SSSE3__)
__forceinline const ssef shuffle8(const ssef& a, const ssei& shuf) {
return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf));
@@ -280,18 +303,19 @@ __forceinline const ssef shuffle8(const ssef& a, const ssei& shuf) {
#if defined(__KERNEL_SSE3__)
template<> __forceinline const ssef shuffle<0, 0, 2, 2>(const ssef& b) { return _mm_moveldup_ps(b); }
template<> __forceinline const ssef shuffle<1, 1, 3, 3>(const ssef& b) { return _mm_movehdup_ps(b); }
-template<> __forceinline const ssef shuffle<0, 1, 0, 1>(const ssef& b) { return _mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(b))); }
#endif
template<size_t i0> __forceinline const ssef shuffle(const ssef& b) {
return shuffle<i0,i0,i0,i0>(b);
}
-#if defined(__KERNEL_SSE41__) && !defined(__GNUC__)
-template<size_t i> __forceinline float extract (const ssef& a) { return _mm_cvtss_f32(_mm_extract_ps(a,i)); }
-#else
-template<size_t i> __forceinline float extract (const ssef& a) { return _mm_cvtss_f32(shuffle<i,i,i,i>(a)); }
+#if defined(__KERNEL_AVX__)
+__forceinline const ssef shuffle(const ssef& a, const ssei& shuf) {
+ return _mm_permutevar_ps(a, shuf);
+}
#endif
+
+template<size_t i> __forceinline float extract (const ssef& a) { return _mm_cvtss_f32(shuffle<i,i,i,i>(a)); }
template<> __forceinline float extract<0>(const ssef& a) { return _mm_cvtss_f32(a); }
#if defined(__KERNEL_SSE41__)
@@ -347,6 +371,8 @@ __forceinline size_t select_max(const ssef& v) { return __bsf(movemask(v == vred
__forceinline size_t select_min(const sseb& valid, const ssef& v) { const ssef a = select(valid,v,ssef(pos_inf)); return __bsf(movemask(valid &(a == vreduce_min(a)))); }
__forceinline size_t select_max(const sseb& valid, const ssef& v) { const ssef a = select(valid,v,ssef(neg_inf)); return __bsf(movemask(valid &(a == vreduce_max(a)))); }
+__forceinline size_t movemask( const ssef& a ) { return _mm_movemask_ps(a); }
+
////////////////////////////////////////////////////////////////////////////////
/// Memory load and store operations
////////////////////////////////////////////////////////////////////////////////
@@ -580,6 +606,20 @@ ccl_device_inline const ssef set_sign_bit(const ssef &a)
return a ^ cast(ssei(S1 << 31, S2 << 31, S3 << 31, S4 << 31));
}
+////////////////////////////////////////////////////////////////////////////////
+/// Debug Functions
+////////////////////////////////////////////////////////////////////////////////
+
+ccl_device_inline void print_ssef(const char *label, const ssef &a)
+{
+ printf("%s: %.8f %.8f %.8f %.8f\n",
+ label,
+ (double)a[0],
+ (double)a[1],
+ (double)a[2],
+ (double)a[3]);
+}
+
#endif
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_ssei.h b/intern/cycles/util/util_ssei.h
index 5f5a8686e35..5f62569268c 100644
--- a/intern/cycles/util/util_ssei.h
+++ b/intern/cycles/util/util_ssei.h
@@ -12,7 +12,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_SSEI_H__
@@ -190,8 +190,8 @@ __forceinline const ssei select( const int mask, const ssei& t, const ssei& f )
// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
-__forceinline ssei unpacklo( const ssei& a, const ssei& b ) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a.m128), _mm_castsi128_ps(b.m128))); }
-__forceinline ssei unpackhi( const ssei& a, const ssei& b ) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a.m128), _mm_castsi128_ps(b.m128))); }
+__forceinline ssei unpacklo( const ssei& a, const ssei& b ) { return _mm_unpacklo_epi32(a, b); }
+__forceinline ssei unpackhi( const ssei& a, const ssei& b ) { return _mm_unpackhi_epi32(a, b); }
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssei shuffle( const ssei& a ) {
return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0));
@@ -201,12 +201,6 @@ template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const ssei sh
return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0)));
}
-#if defined(__KERNEL_SSE3__)
-template<> __forceinline const ssei shuffle<0, 0, 2, 2>( const ssei& a ) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(a))); }
-template<> __forceinline const ssei shuffle<1, 1, 3, 3>( const ssei& a ) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(a))); }
-template<> __forceinline const ssei shuffle<0, 1, 0, 1>( const ssei& a ) { return _mm_castpd_si128(_mm_movedup_pd (_mm_castsi128_pd(a))); }
-#endif
-
template<size_t i0> __forceinline const ssei shuffle( const ssei& b ) {
return shuffle<i0,i0,i0,i0>(b);
}
@@ -286,6 +280,16 @@ __forceinline void store4i_nt(void* ptr, const ssei& v) {
#endif
}
+////////////////////////////////////////////////////////////////////////////////
+/// Debug Functions
+////////////////////////////////////////////////////////////////////////////////
+
+ccl_device_inline void print_ssei(const char *label, const ssei &a)
+{
+ printf("%s: %df %df %df %d\n",
+ label, a[0], a[1], a[2], a[3]);
+}
+
#endif
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_stats.h b/intern/cycles/util/util_stats.h
index 8758b823084..ce27067dc5e 100644
--- a/intern/cycles/util/util_stats.h
+++ b/intern/cycles/util/util_stats.h
@@ -11,12 +11,14 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_STATS_H__
#define __UTIL_STATS_H__
+#include "util_atomic.h"
+
CCL_NAMESPACE_BEGIN
class Stats {
@@ -24,14 +26,13 @@ public:
Stats() : mem_used(0), mem_peak(0) {}
void mem_alloc(size_t size) {
- mem_used += size;
- if(mem_used > mem_peak)
- mem_peak = mem_used;
+ atomic_add_z(&mem_used, size);
+ atomic_update_max_z(&mem_peak, mem_used);
}
void mem_free(size_t size) {
assert(mem_used >= size);
- mem_used -= size;
+ atomic_sub_z(&mem_used, size);
}
size_t mem_used;
diff --git a/intern/cycles/util/util_string.cpp b/intern/cycles/util/util_string.cpp
index f38d8d3282f..8675ff3679d 100644
--- a/intern/cycles/util/util_string.cpp
+++ b/intern/cycles/util/util_string.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdarg.h>
diff --git a/intern/cycles/util/util_string.h b/intern/cycles/util/util_string.h
index 6808f085834..fa1671fd1ee 100644
--- a/intern/cycles/util/util_string.h
+++ b/intern/cycles/util/util_string.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_STRING_H__
diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp
index 7c0445577e2..7206455debd 100644
--- a/intern/cycles/util/util_system.cpp
+++ b/intern/cycles/util/util_system.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "util_system.h"
@@ -135,24 +135,42 @@ struct CPUCapabilities {
bool bmi2;
};
+static void system_cpu_capabilities_override(CPUCapabilities *caps)
+{
+ /* Only capabilities which affects on cycles kernel. */
+ if(getenv("CYCLES_CPU_NO_AVX2")) {
+ caps->avx2 = false;
+ }
+ if(getenv("CYCLES_CPU_NO_AVX")) {
+ caps->avx = false;
+ }
+ if(getenv("CYCLES_CPU_NO_SSE41")) {
+ caps->sse41 = false;
+ }
+ if(getenv("CYCLES_CPU_NO_SSE3")) {
+ caps->sse3 = false;
+ }
+ if(getenv("CYCLES_CPU_NO_SSE2")) {
+ caps->sse2 = false;
+ }
+ if(getenv("CYCLES_CPU_NO_SSE")) {
+ caps->sse = false;
+ }
+}
+
static CPUCapabilities& system_cpu_capabilities()
{
static CPUCapabilities caps;
static bool caps_init = false;
if(!caps_init) {
- int result[4], num; //, num_ex;
+ int result[4], num;
memset(&caps, 0, sizeof(caps));
__cpuid(result, 0);
num = result[0];
-#if 0
- __cpuid(result, 0x80000000);
- num_ex = result[0];
-#endif
-
if(num >= 1) {
__cpuid(result, 0x00000001);
caps.mmx = (result[3] & ((int)1 << 23)) != 0;
@@ -190,15 +208,7 @@ static CPUCapabilities& system_cpu_capabilities()
caps.avx2 = (result[1] & ((int)1 << 5)) != 0;
}
-#if 0
- if(num_ex >= 0x80000001) {
- __cpuid(result, 0x80000001);
- caps.x64 = (result[3] & ((int)1 << 29)) != 0;
- caps.sse4a = (result[2] & ((int)1 << 6)) != 0;
- caps.fma4 = (result[2] & ((int)1 << 16)) != 0;
- caps.xop = (result[2] & ((int)1 << 11)) != 0;
- }
-#endif
+ system_cpu_capabilities_override(&caps);
caps_init = true;
}
diff --git a/intern/cycles/util/util_system.h b/intern/cycles/util/util_system.h
index 0e8868c7dfc..4e7e00f85fd 100644
--- a/intern/cycles/util/util_system.h
+++ b/intern/cycles/util/util_system.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_SYSTEM_H__
diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp
index 14a81ecbb05..e43b26ddfe2 100644
--- a/intern/cycles/util/util_task.cpp
+++ b/intern/cycles/util/util_task.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include "util_debug.h"
diff --git a/intern/cycles/util/util_task.h b/intern/cycles/util/util_task.h
index 42a1e2f5a58..8fac12e9987 100644
--- a/intern/cycles/util/util_task.h
+++ b/intern/cycles/util/util_task.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_TASK_H__
diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h
index f2698d043fb..fbbb9b42e31 100644
--- a/intern/cycles/util/util_thread.h
+++ b/intern/cycles/util/util_thread.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_THREAD_H__
diff --git a/intern/cycles/util/util_time.cpp b/intern/cycles/util/util_time.cpp
index dd91b024940..9668b0f9882 100644
--- a/intern/cycles/util/util_time.cpp
+++ b/intern/cycles/util/util_time.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdlib.h>
diff --git a/intern/cycles/util/util_time.h b/intern/cycles/util/util_time.h
index 3df17272e2f..14ffea7f3da 100644
--- a/intern/cycles/util/util_time.h
+++ b/intern/cycles/util/util_time.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_TIME_H__
diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp
index 14613558501..0a1c09ae3d5 100644
--- a/intern/cycles/util/util_transform.cpp
+++ b/intern/cycles/util/util_transform.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
/*
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index 5b3dbe42f69..ac97fa53084 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_TRANSFORM_H__
@@ -216,12 +216,13 @@ ccl_device_inline Transform transform_rotate(float angle, float3 axis)
0.0f, 0.0f, 0.0f, 1.0f);
}
+/* Euler is assumed to be in XYZ order. */
ccl_device_inline Transform transform_euler(float3 euler)
{
return
- transform_rotate(euler.x, make_float3(1.0f, 0.0f, 0.0f)) *
+ transform_rotate(euler.z, make_float3(0.0f, 0.0f, 1.0f)) *
transform_rotate(euler.y, make_float3(0.0f, 1.0f, 0.0f)) *
- transform_rotate(euler.z, make_float3(0.0f, 0.0f, 1.0f));
+ transform_rotate(euler.x, make_float3(1.0f, 0.0f, 0.0f));
}
ccl_device_inline Transform transform_orthographic(float znear, float zfar)
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index 2a199e591bf..187675e74bf 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_TYPES_H__
@@ -33,11 +33,7 @@
#ifndef __KERNEL_GPU__
-# ifdef NDEBUG
-# define ccl_device static inline
-# else
-# define ccl_device static
-# endif
+#define ccl_device static inline
#define ccl_device_noinline static
#define ccl_global
#define ccl_constant
@@ -53,11 +49,7 @@
#define ccl_try_align(...) /* not support for function arguments (error C2719) */
#endif
#define ccl_may_alias
-# ifdef NDEBUG
-# define ccl_always_inline __forceinline
-# else
-# define ccl_always_inline
-# endif
+#define ccl_always_inline __forceinline
#define ccl_maybe_unused
#else
@@ -272,6 +264,19 @@ struct ccl_try_align(16) float4 {
__forceinline float& operator[](int i) { return *(&x + i); }
};
+template<typename T>
+class vector3
+{
+public:
+ T x, y, z;
+
+ ccl_always_inline vector3() {}
+ ccl_always_inline vector3(const T& a)
+ : x(a), y(a), z(a) {}
+ ccl_always_inline vector3(const T& x, const T& y, const T& z)
+ : x(x), y(y), z(z) {}
+};
+
#endif
#ifndef __KERNEL_GPU__
@@ -476,18 +481,32 @@ enum InterpolationType {
# define UNLIKELY(x) (x)
#endif
+#if defined(__cplusplus) && ((__cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1800))
+# define HAS_CPP11_FEATURES
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+# if defined(HAS_CPP11_FEATURES)
+/* Some magic to be sure we don't have reference in the type. */
+template<typename T> static inline T decltype_helper(T x) { return x; }
+# define TYPEOF(x) decltype(decltype_helper(x))
+# else
+# define TYPEOF(x) typeof(x)
+# endif
+#endif
+
/* Causes warning:
* incompatible types when assigning to type 'Foo' from type 'Bar'
* ... the compiler optimizes away the temp var */
#ifdef __GNUC__
#define CHECK_TYPE(var, type) { \
- typeof(var) *__tmp; \
+ TYPEOF(var) *__tmp; \
__tmp = (type *)NULL; \
(void)__tmp; \
} (void)0
#define CHECK_TYPE_PAIR(var_a, var_b) { \
- typeof(var_a) *__tmp; \
+ TYPEOF(var_a) *__tmp; \
__tmp = (typeof(var_b) *)NULL; \
(void)__tmp; \
} (void)0
diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h
index cc6e8a371ed..92c3f116c69 100644
--- a/intern/cycles/util/util_vector.h
+++ b/intern/cycles/util/util_vector.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_VECTOR_H__
@@ -22,31 +22,73 @@
#include <string.h>
#include <vector>
+#include "util_aligned_malloc.h"
#include "util_types.h"
-CCL_NAMESPACE_BEGIN
+#ifdef WITH_CYCLES_DEBUG
+# include "util_guarded_allocator.h"
+#endif
-using std::vector;
+CCL_NAMESPACE_BEGIN
-static inline void *malloc_aligned(size_t size, size_t alignment)
+/* Vector
+ *
+ * Own subclass-ed vestion of std::vector. Subclass is needed because:
+ *
+ * - When building with WITH_CYCLES_DEBUG we need to use own allocator which
+ * keeps track of used/peak memory.
+ *
+ * - Have method to ensure capacity is re-set to 0.
+ */
+template<typename value_type>
+class vector : public std::vector<value_type
+#ifdef WITH_CYCLES_DEBUG
+ , GuardedAllocator<value_type>
+#endif
+ >
{
- void *data = (void*)malloc(size + sizeof(void*) + alignment - 1);
+public:
+#ifdef WITH_CYCLES_DEBUG
+ typedef GuardedAllocator<value_type> allocator_type;
+#else
+ typedef std::allocator<value_type> allocator_type;
+#endif
- union { void *ptr; size_t offset; } u;
- u.ptr = (char*)data + sizeof(void*);
- u.offset = (u.offset + alignment - 1) & ~(alignment - 1);
- *(((void**)u.ptr) - 1) = data;
+ /* Default constructor. */
+ explicit vector() : std::vector<value_type, allocator_type>() { }
- return u.ptr;
-}
+ /* Fill constructor. */
+ explicit vector(size_t n, const value_type& val = value_type())
+ : std::vector<value_type, allocator_type>(n, val) { }
-static inline void free_aligned(void *ptr)
-{
- if(ptr) {
- void *data = *(((void**)ptr) - 1);
- free(data);
+ /* Range constructor. */
+ template <class InputIterator>
+ vector (InputIterator first, InputIterator last)
+ : std::vector<value_type, allocator_type>(first, last) { }
+
+ /* Copy constructor. */
+ vector(const vector &x) : std::vector<value_type, allocator_type>(x) { }
+
+ void shrink_to_fit(void)
+ {
+#if __cplusplus < 201103L
+ vector<value_type>().swap(*this);
+#else
+ std::vector<value_type, allocator_type>::shrink_to_fit();
+#endif
}
-}
+
+ void free_memory(void) {
+ std::vector<value_type, allocator_type>::resize(0);
+ shrink_to_fit();
+ }
+
+ /* Some external API might demand working with std::vector. */
+ operator std::vector<value_type>()
+ {
+ return std::vector<value_type>(*this);
+ }
+};
/* Array
*
@@ -74,7 +116,7 @@ public:
datasize = 0;
}
else {
- data = (T*)malloc_aligned(sizeof(T)*newsize, alignment);
+ data = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment);
datasize = newsize;
}
}
@@ -91,7 +133,7 @@ public:
datasize = 0;
}
else {
- data = (T*)malloc_aligned(sizeof(T)*from.datasize, alignment);
+ data = (T*)util_aligned_malloc(sizeof(T)*from.datasize, alignment);
memcpy(data, from.data, from.datasize*sizeof(T));
datasize = from.datasize;
}
@@ -105,10 +147,7 @@ public:
data = NULL;
if(datasize > 0) {
- data = (T*)malloc_aligned(sizeof(T)*datasize, alignment);
- memcpy(data, &from[0], datasize*sizeof(T));
- free_aligned(data);
- data = (T*)malloc_aligned(sizeof(T)*datasize, alignment);
+ data = (T*)util_aligned_malloc(sizeof(T)*datasize, alignment);
memcpy(data, &from[0], datasize*sizeof(T));
}
@@ -117,7 +156,7 @@ public:
~array()
{
- free_aligned(data);
+ util_aligned_free(data);
}
void resize(size_t newsize)
@@ -126,10 +165,10 @@ public:
clear();
}
else if(newsize != datasize) {
- T *newdata = (T*)malloc_aligned(sizeof(T)*newsize, alignment);
+ T *newdata = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment);
if(data) {
memcpy(newdata, data, ((datasize < newsize)? datasize: newsize)*sizeof(T));
- free_aligned(data);
+ util_aligned_free(data);
}
data = newdata;
@@ -139,7 +178,7 @@ public:
void clear()
{
- free_aligned(data);
+ util_aligned_free(data);
data = NULL;
datasize = 0;
}
diff --git a/intern/cycles/util/util_view.cpp b/intern/cycles/util/util_view.cpp
index fe08389fe3f..e77ebb2fe3e 100644
--- a/intern/cycles/util/util_view.cpp
+++ b/intern/cycles/util/util_view.cpp
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#include <stdio.h>
diff --git a/intern/cycles/util/util_view.h b/intern/cycles/util/util_view.h
index 65d890eb6af..5def0564175 100644
--- a/intern/cycles/util/util_view.h
+++ b/intern/cycles/util/util_view.h
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_VIEW_H__
diff --git a/intern/cycles/util/util_xml.h b/intern/cycles/util/util_xml.h
index 9d1ebc2114a..cfd0afc95f7 100644
--- a/intern/cycles/util/util_xml.h
+++ b/intern/cycles/util/util_xml.h
@@ -11,15 +11,15 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
#ifndef __UTIL_XML_H__
#define __UTIL_XML_H__
-/* PugiXML from OpenImageIO is used for XML parsing. */
+/* PugiXML is used for XML parsing. */
-#include <OpenImageIO/pugixml.hpp>
+#include <pugixml.hpp>
CCL_NAMESPACE_BEGIN
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 6f30cecab61..dc55a81b0d8 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -152,7 +152,7 @@ elseif(APPLE AND NOT WITH_X11)
intern/GHOST_WindowCocoa.h
)
- if (NOT WITH_GL_EGL)
+ if(NOT WITH_GL_EGL)
list(APPEND SRC
intern/GHOST_ContextCGL.mm
@@ -192,7 +192,7 @@ elseif(WITH_X11)
intern/GHOST_WindowX11.h
)
- if (NOT WITH_GL_EGL)
+ if(NOT WITH_GL_EGL)
list(APPEND SRC
intern/GHOST_ContextGLX.cpp
@@ -272,7 +272,7 @@ elseif(WIN32)
intern/GHOST_TaskbarWin32.h
)
- if (NOT WITH_GL_EGL)
+ if(NOT WITH_GL_EGL)
list(APPEND SRC
intern/GHOST_ContextWGL.cpp
@@ -280,6 +280,16 @@ elseif(WIN32)
)
endif()
+ if(WITH_INPUT_IME)
+ add_definitions(-DWITH_INPUT_IME)
+
+ list(APPEND SRC
+ intern/GHOST_ImeWin32.cpp
+
+ intern/GHOST_ImeWin32.h
+ )
+ endif()
+
if(WITH_INPUT_NDOF)
list(APPEND SRC
intern/GHOST_NDOFManagerWin32.cpp
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 7b47f0526a2..5f01a13b64e 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -186,8 +186,7 @@ extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const int stereoVisual,
- const GHOST_TUns16 numOfAASamples);
+ GHOST_GLSettings glSettings);
/**
* Returns the window user data.
@@ -897,6 +896,30 @@ extern int GHOST_UseNativePixels(void);
*/
extern float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle);
+/**
+ * Enable IME attached to the given window, i.e. allows user-input
+ * events to be dispatched to the IME.
+ * \param windowhandle Window handle of the caller
+ * \param x Requested x-coordinate of the rectangle
+ * \param y Requested y-coordinate of the rectangle
+ * \param w Requested width of the rectangle
+ * \param h Requested height of the rectangle
+ * \param complete Whether or not to complete the ongoing composition
+ * true: Start a new composition
+ * false: Move the IME windows to the given position without finishing it.
+ */
+extern void GHOST_BeginIME(GHOST_WindowHandle windowhandle,
+ GHOST_TInt32 x,
+ GHOST_TInt32 y,
+ GHOST_TInt32 w,
+ GHOST_TInt32 h,
+ int complete);
+/**
+ * Disable the IME attached to the given window, i.e. prohibits any user-input
+ * events from being dispatched to the IME.
+ * \param windowhandle The window handle of the caller
+ */
+extern void GHOST_EndIME(GHOST_WindowHandle windowhandle);
#ifdef __cplusplus
}
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 19f36319949..93ccc0fc947 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -250,9 +250,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 = false,
+ GHOST_GLSettings glSettings,
const bool exclusive = false,
- const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0) = 0;
/**
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 71dc193a81b..3f8215dc7c2 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -331,6 +331,29 @@ public:
virtual float getNativePixelSize(void) = 0;
+#ifdef WITH_INPUT_IME
+ /**
+ * Enable IME attached to the given window, i.e. allows user-input
+ * events to be dispatched to the IME.
+ * \param x Requested x-coordinate of the rectangle
+ * \param y Requested y-coordinate of the rectangle
+ * \param w Requested width of the rectangle
+ * \param h Requested height of the rectangle
+ * \param complete Whether or not to complete the ongoing composition
+ * true: Start a new composition
+ * false: Move the IME windows to the given position without finishing it.
+ */
+ virtual void beginIME(
+ GHOST_TInt32 x, GHOST_TInt32 y,
+ GHOST_TInt32 w, GHOST_TInt32 h,
+ int completed) = 0;
+
+ /**
+ * Disable the IME attached to the given window, i.e. prohibits any user-input
+ * events from being dispatched to the IME.
+ */
+ virtual void endIME() = 0;
+#endif /* WITH_INPUT_IME */
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IWindow")
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 7333ba025a5..eccbaadb71d 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -50,6 +50,17 @@ typedef unsigned short GHOST_TUns16;
typedef int GHOST_TInt32;
typedef unsigned int GHOST_TUns32;
+typedef struct {
+ GHOST_TUns16 numOfAASamples;
+ int flags;
+} GHOST_GLSettings;
+
+typedef enum {
+ GHOST_glStereoVisual = (1 << 0),
+ GHOST_glWarnSupport = (1 << 1)
+} GHOST_GLFlags;
+
+
#ifdef _MSC_VER
typedef __int64 GHOST_TInt64;
typedef unsigned __int64 GHOST_TUns64;
@@ -190,6 +201,10 @@ typedef enum {
GHOST_kEventTimer,
+ GHOST_kEventImeCompositionStart,
+ GHOST_kEventImeComposition,
+ GHOST_kEventImeCompositionEnd,
+
GHOST_kNumEventTypes
} GHOST_TEventType;
@@ -436,6 +451,22 @@ typedef struct {
GHOST_TEventDataPtr data;
} GHOST_TEventDragnDropData;
+/** similar to wmImeData */
+typedef struct {
+ /** size_t */
+ GHOST_TUserDataPtr result_len, composite_len;
+ /** char * utf8 encoding */
+ GHOST_TUserDataPtr result, composite;
+ /** Cursor position in the IME composition. */
+ int cursor_position;
+ /** Represents the position of the beginning of the selection */
+ int target_start;
+ /** Represents the position of the end of the selection */
+ int target_end;
+ /** custom temporal data */
+ GHOST_TUserDataPtr tmp;
+} GHOST_TEventImeData;
+
typedef struct {
int count;
GHOST_TUns8 **strings;
diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript
index 5a4572c164d..025559e11a4 100644
--- a/intern/ghost/SConscript
+++ b/intern/ghost/SConscript
@@ -154,6 +154,14 @@ if env['BF_GHOST_DEBUG']:
else:
sources.remove('intern' + os.sep + 'GHOST_EventPrinter.cpp')
+if env['WITH_BF_IME'] and window_system in ('win32-vc', 'win32-mingw', 'win64-vc', 'win64-mingw'):
+ defs.append('WITH_INPUT_IME')
+elif env['WITH_BF_IME']:
+ print "IME input is only supported on Windows! Please disable WITH_BF_IME!"
+ Exit()
+else:
+ sources.remove('intern' + os.sep + 'GHOST_ImeWin32.cpp')
+
if env['WITH_BF_3DMOUSE']:
defs.append('WITH_INPUT_NDOF')
diff --git a/intern/ghost/intern/GHOST_Buttons.h b/intern/ghost/intern/GHOST_Buttons.h
index 6b0d74e7eb9..0aa93a2fad0 100644
--- a/intern/ghost/intern/GHOST_Buttons.h
+++ b/intern/ghost/intern/GHOST_Buttons.h
@@ -48,26 +48,26 @@ struct GHOST_Buttons {
*/
GHOST_Buttons();
- virtual ~GHOST_Buttons();
+ ~GHOST_Buttons();
/**
* Returns the state of a single button.
* \param mask Key button to return.
* \return The state of the button (pressed == true).
*/
- virtual bool get(GHOST_TButtonMask mask) const;
+ bool get(GHOST_TButtonMask mask) const;
/**
* Updates the state of a single button.
* \param mask Button state to update.
* \param down The new state of the button.
*/
- virtual void set(GHOST_TButtonMask mask, bool down);
+ void set(GHOST_TButtonMask mask, bool down);
/**
* Sets the state of all buttons to up.
*/
- virtual void clear();
+ void clear();
GHOST_TUns8 m_ButtonLeft : 1;
GHOST_TUns8 m_ButtonMiddle : 1;
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 5a2e638f01a..8d01e8ac3a6 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -140,14 +140,12 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const int stereoVisual,
- const GHOST_TUns16 numOfAASamples)
+ GHOST_GLSettings glSettings)
{
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
return (GHOST_WindowHandle) system->createWindow(title, left, top, width, height,
- state, type, stereoVisual != 0, false,
- numOfAASamples);
+ state, type, glSettings, false);
}
GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle)
@@ -915,3 +913,21 @@ float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle)
return 1.0f;
}
+#ifdef WITH_INPUT_IME
+
+void GHOST_BeginIME(GHOST_WindowHandle windowhandle,
+ GHOST_TInt32 x, GHOST_TInt32 y,
+ GHOST_TInt32 w, GHOST_TInt32 h,
+ int complete)
+{
+ GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ window->beginIME(x, y, w, h, complete);
+}
+
+void GHOST_EndIME(GHOST_WindowHandle windowhandle)
+{
+ GHOST_IWindow *window = (GHOST_IWindow *) windowhandle;
+ window->endIME();
+}
+
+#endif /* WITH_INPUT_IME */
diff --git a/intern/ghost/intern/GHOST_CallbackEventConsumer.h b/intern/ghost/intern/GHOST_CallbackEventConsumer.h
index 770ebdc8b78..3505d651fa3 100644
--- a/intern/ghost/intern/GHOST_CallbackEventConsumer.h
+++ b/intern/ghost/intern/GHOST_CallbackEventConsumer.h
@@ -57,7 +57,7 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_CallbackEventConsumer(void)
+ ~GHOST_CallbackEventConsumer(void)
{
}
@@ -66,7 +66,7 @@ public:
* \param event The event that can be handled or ignored.
* \return Indication as to whether the event was handled.
*/
- virtual bool processEvent(GHOST_IEvent *event);
+ bool processEvent(GHOST_IEvent *event);
protected:
/** The call-back routine invoked. */
diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h
index 99d995bcbb1..92fdbfc53de 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.h
+++ b/intern/ghost/intern/GHOST_ContextCGL.h
@@ -72,53 +72,53 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_ContextCGL();
+ ~GHOST_ContextCGL();
/**
* Swaps front and back buffers of a window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess swapBuffers();
+ GHOST_TSuccess swapBuffers();
/**
* Activates the drawing context of this window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess activateDrawingContext();
+ GHOST_TSuccess activateDrawingContext();
/**
* Call immediately after new to initialize. If this fails then immediately delete the object.
* \return Indication as to whether initialization has succeeded.
*/
- virtual GHOST_TSuccess initializeDrawingContext();
+ GHOST_TSuccess initializeDrawingContext();
/**
* Removes references to native handles from this context and then returns
* \return GHOST_kSuccess if it is OK for the parent to release the handles and
* GHOST_kFailure if releasing the handles will interfere with sharing
*/
- virtual GHOST_TSuccess releaseNativeHandles();
+ GHOST_TSuccess releaseNativeHandles();
/**
* Sets the swap interval for swapBuffers.
* \param interval The swap interval to use.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess setSwapInterval(int interval);
+ GHOST_TSuccess setSwapInterval(int interval);
/**
* Gets the current swap interval for swapBuffers.
* \param intervalOut Variable to store the swap interval if it can be read.
* \return Whether the swap interval can be read.
*/
- virtual GHOST_TSuccess getSwapInterval(int&);
+ GHOST_TSuccess getSwapInterval(int&);
/**
* Updates the drawing context of this window.
* Needed whenever the window is changed.
* \return Indication of success.
*/
- virtual GHOST_TSuccess updateDrawingContext();
+ GHOST_TSuccess updateDrawingContext();
//protected:
// inline void activateCGLEW() const {
@@ -140,7 +140,7 @@ private:
const int m_contextFlags;
const int m_contextResetNotificationStrategy;
- /** The opgnGL drawing context */
+ /** The OpenGL drawing context */
NSOpenGLContext *m_openGLContext;
//static CGLEWContext *s_cglewContext;
diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm
index c55935d43ba..57cf53af11c 100644
--- a/intern/ghost/intern/GHOST_ContextCGL.mm
+++ b/intern/ghost/intern/GHOST_ContextCGL.mm
@@ -75,9 +75,10 @@ GHOST_ContextCGL::GHOST_ContextCGL(
GHOST_ContextCGL::~GHOST_ContextCGL()
{
if (m_openGLContext != nil) {
- if (m_openGLContext == [NSOpenGLContext currentContext])
+ if (m_openGLContext == [NSOpenGLContext currentContext]) {
[NSOpenGLContext clearCurrentContext];
[m_openGLView clearGLContext];
+ }
if (m_openGLContext != s_sharedOpenGLContext || s_sharedCount == 1) {
assert(s_sharedCount > 0);
@@ -192,11 +193,8 @@ static void makeAttribList(
* Maybe a command line flag is better... */
if (getenv("BLENDER_SOFTWAREGL")) {
attribs.push_back(NSOpenGLPFARendererID);
-#if defined(__ppc__) || defined(__ppc64__)
- attribs.push_back(kCGLRendererAppleSWID);
-#else
- // attribs.push_back(kCGLRendererGenericFloatID);
-#endif
+
+ attribs.push_back(kCGLRendererGenericFloatID);
}
else {
attribs.push_back(NSOpenGLPFAAccelerated);
diff --git a/intern/ghost/intern/GHOST_ContextEGL.h b/intern/ghost/intern/GHOST_ContextEGL.h
index 5e458139ade..70c26c940fc 100644
--- a/intern/ghost/intern/GHOST_ContextEGL.h
+++ b/intern/ghost/intern/GHOST_ContextEGL.h
@@ -75,39 +75,39 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_ContextEGL();
+ ~GHOST_ContextEGL();
/**
* Swaps front and back buffers of a window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess swapBuffers();
+ GHOST_TSuccess swapBuffers();
/**
* Activates the drawing context of this window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess activateDrawingContext();
+ GHOST_TSuccess activateDrawingContext();
/**
* Call immediately after new to initialize. If this fails then immediately delete the object.
* \return Indication as to whether initialization has succeeded.
*/
- virtual GHOST_TSuccess initializeDrawingContext();
+ GHOST_TSuccess initializeDrawingContext();
/**
* Removes references to native handles from this context and then returns
* \return GHOST_kSuccess if it is OK for the parent to release the handles and
* GHOST_kFailure if releasing the handles will interfere with sharing
*/
- virtual GHOST_TSuccess releaseNativeHandles();
+ GHOST_TSuccess releaseNativeHandles();
/**
* Sets the swap interval for swapBuffers.
* \param interval The swap interval to use.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess setSwapInterval(int interval);
+ GHOST_TSuccess setSwapInterval(int interval);
/**
* Gets the current swap interval for swapBuffers.
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp
index 726614c48b1..c4e1346456e 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.cpp
+++ b/intern/ghost/intern/GHOST_ContextGLX.cpp
@@ -54,6 +54,7 @@ GHOST_ContextGLX::GHOST_ContextGLX(
GHOST_TUns16 numOfAASamples,
Window window,
Display *display,
+ XVisualInfo *visualInfo,
int contextProfileMask,
int contextMajorVersion,
int contextMinorVersion,
@@ -61,13 +62,13 @@ GHOST_ContextGLX::GHOST_ContextGLX(
int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual, numOfAASamples),
m_display(display),
+ m_visualInfo(visualInfo),
m_window(window),
m_contextProfileMask(contextProfileMask),
m_contextMajorVersion(contextMajorVersion),
m_contextMinorVersion(contextMinorVersion),
m_contextFlags(contextFlags),
m_contextResetNotificationStrategy(contextResetNotificationStrategy),
- m_visualInfo(NULL),
m_context(None)
#ifdef WITH_GLEW_MX
,
@@ -104,8 +105,6 @@ GHOST_ContextGLX::~GHOST_ContextGLX()
delete m_glxewContext;
#endif
}
-
- XFree(m_visualInfo);
}
@@ -145,121 +144,6 @@ void GHOST_ContextGLX::initContextGLXEW()
GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
{
- /* Set up the minimum attributes that we require and see if
- * X can find us a visual matching those requirements. */
-
- std::vector<int> attribs;
- attribs.reserve(40);
-
- int glx_major, glx_minor; /* GLX version: major.minor */
-
- if (!glXQueryVersion(m_display, &glx_major, &glx_minor)) {
- fprintf(stderr,
- "%s:%d: X11 glXQueryVersion() failed, "
- "verify working openGL system!\n",
- __FILE__, __LINE__);
-
- /* exit if this is the first window */
- if (s_sharedContext == NULL) {
- fprintf(stderr, "initial window could not find the GLX extension, exit!\n");
- exit(EXIT_FAILURE);
- }
-
- return GHOST_kFailure;
- }
-
-#ifdef GHOST_OPENGL_ALPHA
- const bool needAlpha = true;
-#else
- const bool needAlpha = false;
-#endif
-
-#ifdef GHOST_OPENGL_STENCIL
- const bool needStencil = true;
-#else
- const bool needStencil = false;
-#endif
-
- /* Find the display with highest samples, starting at level requested */
- int actualSamples = m_numOfAASamples;
- for (;;) {
- attribs.clear();
-
- if (m_stereoVisual)
- attribs.push_back(GLX_STEREO);
-
- attribs.push_back(GLX_RGBA);
-
- attribs.push_back(GLX_DOUBLEBUFFER);
-
- attribs.push_back(GLX_RED_SIZE);
- attribs.push_back(1);
-
- attribs.push_back(GLX_BLUE_SIZE);
- attribs.push_back(1);
-
- attribs.push_back(GLX_GREEN_SIZE);
- attribs.push_back(1);
-
- attribs.push_back(GLX_DEPTH_SIZE);
- attribs.push_back(1);
-
- if (needAlpha) {
- attribs.push_back(GLX_ALPHA_SIZE);
- attribs.push_back(1);
- }
-
- if (needStencil) {
- attribs.push_back(GLX_STENCIL_SIZE);
- attribs.push_back(1);
- }
-
- /* GLX >= 1.4 required for multi-sample */
- if (actualSamples > 0 && ((glx_major > 1) || (glx_major == 1 && glx_minor >= 4))) {
- attribs.push_back(GLX_SAMPLE_BUFFERS);
- attribs.push_back(1);
-
- attribs.push_back(GLX_SAMPLES);
- attribs.push_back(actualSamples);
- }
-
- attribs.push_back(None);
-
- m_visualInfo = glXChooseVisual(m_display, DefaultScreen(m_display), &attribs[0]);
-
- /* Any sample level or even zero, which means oversampling disabled, is good
- * but we need a valid visual to continue */
- if (m_visualInfo != NULL) {
- if (actualSamples < m_numOfAASamples) {
- fprintf(stderr,
- "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
- "Substituting one that uses %d samples.\n",
- m_numOfAASamples, actualSamples);
- }
- break;
- }
-
- if (actualSamples == 0) {
- /* All options exhausted, cannot continue */
- fprintf(stderr,
- "%s:%d: X11 glXChooseVisual() failed, "
- "verify working openGL system!\n",
- __FILE__, __LINE__);
-
- if (s_sharedContext == None) {
- fprintf(stderr, "initial window could not find the GLX extension, exit!\n");
- exit(1);
- }
-
- return GHOST_kFailure;
- }
- else {
- --actualSamples;
- }
- }
-
- m_numOfAASamples = actualSamples;
-
#ifdef WITH_X11_XINPUT
/* use our own event handlers to avoid exiting blender,
* this would happen for eg:
diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h
index d32adf3338d..b33c0b5252a 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.h
+++ b/intern/ghost/intern/GHOST_ContextGLX.h
@@ -46,7 +46,11 @@ extern "C" GLXEWContext *glxewContext;
#ifndef GHOST_OPENGL_GLX_CONTEXT_FLAGS
-#define GHOST_OPENGL_GLX_CONTEXT_FLAGS 0
+# ifdef WITH_GPU_DEBUG
+# define GHOST_OPENGL_GLX_CONTEXT_FLAGS GLX_CONTEXT_DEBUG_BIT_ARB
+# else
+# define GHOST_OPENGL_GLX_CONTEXT_FLAGS 0
+# endif
#endif
#ifndef GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY
@@ -65,6 +69,7 @@ public:
GHOST_TUns16 numOfAASamples,
Window window,
Display *display,
+ XVisualInfo *visualInfo,
int contextProfileMask,
int contextMajorVersion,
int contextMinorVersion,
@@ -74,46 +79,46 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_ContextGLX();
+ ~GHOST_ContextGLX();
/**
* Swaps front and back buffers of a window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess swapBuffers();
+ GHOST_TSuccess swapBuffers();
/**
* Activates the drawing context of this window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess activateDrawingContext();
+ GHOST_TSuccess activateDrawingContext();
/**
* Call immediately after new to initialize. If this fails then immediately delete the object.
* \return Indication as to whether initialization has succeeded.
*/
- virtual GHOST_TSuccess initializeDrawingContext();
+ GHOST_TSuccess initializeDrawingContext();
/**
* Removes references to native handles from this context and then returns
* \return GHOST_kSuccess if it is OK for the parent to release the handles and
* GHOST_kFailure if releasing the handles will interfere with sharing
*/
- virtual GHOST_TSuccess releaseNativeHandles();
+ GHOST_TSuccess releaseNativeHandles();
/**
* Sets the swap interval for swapBuffers.
* \param interval The swap interval to use.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess setSwapInterval(int interval);
+ GHOST_TSuccess setSwapInterval(int interval);
/**
* Gets the current swap interval for swapBuffers.
* \param intervalOut Variable to store the swap interval if it can be read.
* \return Whether the swap interval can be read.
*/
- virtual GHOST_TSuccess getSwapInterval(int &intervalOut);
+ GHOST_TSuccess getSwapInterval(int &intervalOut);
protected:
inline void activateGLXEW() const {
@@ -126,6 +131,7 @@ private:
void initContextGLXEW();
Display *m_display;
+ XVisualInfo *m_visualInfo;
Window m_window;
const int m_contextProfileMask;
@@ -134,8 +140,6 @@ private:
const int m_contextFlags;
const int m_contextResetNotificationStrategy;
- XVisualInfo *m_visualInfo;
-
GLXContext m_context;
#ifdef WITH_GLEW_MX
diff --git a/intern/ghost/intern/GHOST_ContextNone.h b/intern/ghost/intern/GHOST_ContextNone.h
index c36873c039f..80cce76190d 100644
--- a/intern/ghost/intern/GHOST_ContextNone.h
+++ b/intern/ghost/intern/GHOST_ContextNone.h
@@ -51,44 +51,44 @@ public:
* Dummy function
* \return Always succeeds
*/
- virtual GHOST_TSuccess swapBuffers();
+ GHOST_TSuccess swapBuffers();
/**
* Dummy function
* \return Always succeeds
*/
- virtual GHOST_TSuccess activateDrawingContext();
+ GHOST_TSuccess activateDrawingContext();
/**
* Dummy function
* \return Always succeeds
*/
- virtual GHOST_TSuccess updateDrawingContext();
+ GHOST_TSuccess updateDrawingContext();
/**
* Dummy function
* \return Always succeeds
*/
- virtual GHOST_TSuccess initializeDrawingContext();
+ GHOST_TSuccess initializeDrawingContext();
/**
* Dummy function
* \return Always succeeds
*/
- virtual GHOST_TSuccess releaseNativeHandles();
+ GHOST_TSuccess releaseNativeHandles();
/**
* Dummy function
* \return Always succeeds
*/
- virtual GHOST_TSuccess setSwapInterval(int interval);
+ GHOST_TSuccess setSwapInterval(int interval);
/**
* Dummy function
* \param intervalOut Gets whatever was set by setSwapInterval
* \return Always succeeds
*/
- virtual GHOST_TSuccess getSwapInterval(int &intervalOut);
+ GHOST_TSuccess getSwapInterval(int &intervalOut);
private:
int m_swapInterval;
diff --git a/intern/ghost/intern/GHOST_ContextSDL.h b/intern/ghost/intern/GHOST_ContextSDL.h
index 5edf1a0aee8..61f339c1bc2 100644
--- a/intern/ghost/intern/GHOST_ContextSDL.h
+++ b/intern/ghost/intern/GHOST_ContextSDL.h
@@ -40,7 +40,11 @@ extern "C" {
#ifndef GHOST_OPENGL_SDL_CONTEXT_FLAGS
-#define GHOST_OPENGL_SDL_CONTEXT_FLAGS 0
+# ifdef WITH_GPU_DEBUG
+# define GHOST_OPENGL_SDL_CONTEXT_FLAGS SDL_GL_CONTEXT_DEBUG_FLAG
+# else
+# define GHOST_OPENGL_SDL_CONTEXT_FLAGS 0
+# endif
#endif
#ifndef GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY
@@ -67,46 +71,46 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_ContextSDL();
+ ~GHOST_ContextSDL();
/**
* Swaps front and back buffers of a window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess swapBuffers();
+ GHOST_TSuccess swapBuffers();
/**
* Activates the drawing context of this window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess activateDrawingContext();
+ GHOST_TSuccess activateDrawingContext();
/**
* Call immediately after new to initialize. If this fails then immediately delete the object.
* \return Indication as to whether initialization has succeeded.
*/
- virtual GHOST_TSuccess initializeDrawingContext();
+ GHOST_TSuccess initializeDrawingContext();
/**
* Removes references to native handles from this context and then returns
* \return GHOST_kSuccess if it is OK for the parent to release the handles and
* GHOST_kFailure if releasing the handles will interfere with sharing
*/
- virtual GHOST_TSuccess releaseNativeHandles();
+ GHOST_TSuccess releaseNativeHandles();
/**
* Sets the swap interval for swapBuffers.
* \param interval The swap interval to use.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess setSwapInterval(int interval);
+ GHOST_TSuccess setSwapInterval(int interval);
/**
* Gets the current swap interval for swapBuffers.
* \param intervalOut Variable to store the swap interval if it can be read.
* \return Whether the swap interval can be read.
*/
- virtual GHOST_TSuccess getSwapInterval(int &intervalOut);
+ GHOST_TSuccess getSwapInterval(int &intervalOut);
private:
SDL_Window *m_window;
diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp b/intern/ghost/intern/GHOST_ContextWGL.cpp
index 312600c01d4..055737481ae 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.cpp
+++ b/intern/ghost/intern/GHOST_ContextWGL.cpp
@@ -48,6 +48,7 @@ HGLRC GHOST_ContextWGL::s_sharedHGLRC = NULL;
int GHOST_ContextWGL::s_sharedCount = 0;
bool GHOST_ContextWGL::s_singleContextMode = false;
+bool GHOST_ContextWGL::s_warn_old = false;
/* Intel video-cards don't work fine with multiple contexts and
@@ -732,13 +733,17 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
iPixelFormat = choose_pixel_format(m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB);
- if (iPixelFormat == 0)
- goto error;
+ if (iPixelFormat == 0) {
+ ::wglMakeCurrent(prevHDC, prevHGLRC);
+ return GHOST_kFailure;
+ }
lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD);
- if (!WIN32_CHK(lastPFD != 0))
- goto error;
+ if (!WIN32_CHK(lastPFD != 0)) {
+ ::wglMakeCurrent(prevHDC, prevHGLRC);
+ return GHOST_kFailure;
+ }
if (needAlpha && chosenPFD.cAlphaBits == 0)
fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n");
@@ -746,8 +751,10 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
if (needStencil && chosenPFD.cStencilBits == 0)
fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n");
- if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD)))
- goto error;
+ if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) {
+ ::wglMakeCurrent(prevHDC, prevHGLRC);
+ return GHOST_kFailure;
+ }
activateWGLEW();
@@ -844,37 +851,65 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
m_hGLRC = s_sharedHGLRC;
}
- if (!WIN32_CHK(m_hGLRC != NULL))
- goto error;
+ if (!WIN32_CHK(m_hGLRC != NULL)) {
+ ::wglMakeCurrent(prevHDC, prevHGLRC);
+ return GHOST_kFailure;
+ }
if (s_sharedHGLRC == NULL)
s_sharedHGLRC = m_hGLRC;
s_sharedCount++;
- if (!s_singleContextMode && s_sharedHGLRC != m_hGLRC && !WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC)))
- goto error;
+ if (!s_singleContextMode && s_sharedHGLRC != m_hGLRC && !WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC))) {
+ ::wglMakeCurrent(prevHDC, prevHGLRC);
+ return GHOST_kFailure;
+ }
- if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC)))
- goto error;
+ if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
+ ::wglMakeCurrent(prevHDC, prevHGLRC);
+ return GHOST_kFailure;
+ }
initContextGLEW();
initClearGL();
::SwapBuffers(m_hDC);
+ const char *vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
+ const char *renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
+ const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
+
#ifndef NDEBUG
- reportContextString("Vendor", m_dummyVendor, reinterpret_cast<const char*>(glGetString(GL_VENDOR)));
- reportContextString("Renderer", m_dummyRenderer, reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
- reportContextString("Version", m_dummyVersion, reinterpret_cast<const char*>(glGetString(GL_VERSION)));
+ reportContextString("Vendor", m_dummyVendor, vendor);
+ reportContextString("Renderer", m_dummyRenderer, renderer);
+ reportContextString("Version", m_dummyVersion, version);
#endif
- return GHOST_kSuccess;
-
-error:
- ::wglMakeCurrent(prevHDC, prevHGLRC);
+ if (!s_warn_old) {
+ if ((strcmp(vendor, "Microsoft Corporation") == 0 ||
+ strcmp(renderer, "GDI Generic") == 0) && version[0] == '1' && version[0] == '1')
+ {
+ MessageBox(m_hWnd, "Your system does not use 3D hardware acceleration.\n"
+ "Such systems can cause stability problems in Blender and they are unsupported.\n\n"
+ "This may be caused by:\n"
+ "* A missing or faulty graphics driver installation.\n"
+ " Blender needs a graphics card driver to work correctly.\n"
+ "* Accessing Blender through a remote connection.\n"
+ "* Using Blender through a virtual machine.\n\n"
+ "Disable this message in <User Preferences - Interface - Warn On Deprecated OpenGL>",
+ "Blender - Can't detect 3D hardware accelerated Driver!", MB_OK | MB_ICONWARNING);
+ }
+ else if (version[0] == '1' && version[2] < '4') {
+ MessageBox(m_hWnd, "The OpenGL version provided by your graphics driver version is too low\n"
+ "Blender requires version 1.4 and may not work correctly\n\n"
+ "Disable this message in <User Preferences - Interface - Warn On Deprecated OpenGL>",
+ "Blender - Unsupported Graphics Driver!", MB_OK | MB_ICONWARNING);
+ }
+ s_warn_old = true;
+ }
- return GHOST_kFailure;
+ return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h
index f2a5171c579..9f4f6fab58a 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.h
+++ b/intern/ghost/intern/GHOST_ContextWGL.h
@@ -45,7 +45,11 @@ extern "C" WGLEWContext *wglewContext;
#endif
#ifndef GHOST_OPENGL_WGL_CONTEXT_FLAGS
-#define GHOST_OPENGL_WGL_CONTEXT_FLAGS 0
+# ifdef WITH_GPU_DEBUG
+# define GHOST_OPENGL_WGL_CONTEXT_FLAGS WGL_CONTEXT_DEBUG_BIT_ARB
+# else
+# define GHOST_OPENGL_WGL_CONTEXT_FLAGS 0
+# endif
#endif
#ifndef GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY
@@ -73,46 +77,48 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_ContextWGL();
+ ~GHOST_ContextWGL();
/**
* Swaps front and back buffers of a window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess swapBuffers();
+ GHOST_TSuccess swapBuffers();
/**
* Activates the drawing context of this window.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess activateDrawingContext();
+ GHOST_TSuccess activateDrawingContext();
/**
* Call immediately after new to initialize. If this fails then immediately delete the object.
* \return Indication as to whether initialization has succeeded.
*/
- virtual GHOST_TSuccess initializeDrawingContext();
+ GHOST_TSuccess initializeDrawingContext();
/**
* Removes references to native handles from this context and then returns
* \return GHOST_kSuccess if it is OK for the parent to release the handles and
* GHOST_kFailure if releasing the handles will interfere with sharing
*/
- virtual GHOST_TSuccess releaseNativeHandles();
+ GHOST_TSuccess releaseNativeHandles();
/**
* Sets the swap interval for swapBuffers.
* \param interval The swap interval to use.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess setSwapInterval(int interval);
+ GHOST_TSuccess setSwapInterval(int interval);
/**
* Gets the current swap interval for swapBuffers.
* \param intervalOut Variable to store the swap interval if it can be read.
* \return Whether the swap interval can be read.
*/
- virtual GHOST_TSuccess getSwapInterval(int &intervalOut);
+ GHOST_TSuccess getSwapInterval(int &intervalOut);
+
+ static void unSetWarningOld(){s_warn_old = true;}
protected:
inline void activateWGLEW() const {
@@ -154,8 +160,8 @@ private:
void initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD);
- HDC m_hDC;
HWND m_hWnd;
+ HDC m_hDC;
const int m_contextProfileMask;
const int m_contextMajorVersion;
@@ -179,6 +185,7 @@ private:
static int s_sharedCount;
static bool s_singleContextMode;
+ static bool s_warn_old;
};
#endif // __GHOST_CONTEXTWGL_H__
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
index 1f17b4dd976..bfed2e0d37e 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
@@ -58,7 +58,7 @@ public:
* \param numDisplays The number of displays on this system.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
+ GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
/**
* Returns the number of display settings for this display device.
@@ -66,7 +66,7 @@ public:
* \param setting The number of settings of the display device with this index.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
+ GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
/**
* Returns the current setting for this display device.
@@ -75,7 +75,7 @@ public:
* \param setting The setting of the display device with this index.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
+ GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
/**
* Returns the current setting for this display device.
@@ -83,7 +83,7 @@ public:
* \param setting The current setting of the display device with this index.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
+ GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
/**
* Changes the current setting for this display device.
@@ -91,7 +91,7 @@ public:
* \param setting The current setting of the display device with this index.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
+ GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
protected:
//Do not cache values as OS X supports screen hot plug
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.h b/intern/ghost/intern/GHOST_DisplayManagerWin32.h
index ced4ceac044..801ad29f45a 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerWin32.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.h
@@ -58,7 +58,7 @@ public:
* \param numDisplays The number of displays on this system.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
+ GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
/**
* Returns the number of display settings for this display device.
@@ -66,7 +66,7 @@ public:
* \param setting The number of settings of the display device with this index.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
+ GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
/**
* Returns the current setting for this display device.
@@ -75,7 +75,7 @@ public:
* \param setting The setting of the display device with this index.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
+ GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
/**
* Returns the current setting for this display device.
@@ -83,7 +83,7 @@ public:
* \param setting The current setting of the display device with this index.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
+ GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
/**
* Changes the current setting for this display device.
@@ -91,7 +91,7 @@ public:
* \param setting The current setting of the display device with this index.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
+ GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
protected:
};
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.h b/intern/ghost/intern/GHOST_DropTargetWin32.h
index fb85feffde0..56bae1fd1b2 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.h
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.h
@@ -89,7 +89,7 @@ public:
* Destructor
* Do NOT destroy directly. Use Release() instead to make COM happy.
*/
- virtual ~GHOST_DropTargetWin32();
+ ~GHOST_DropTargetWin32();
private:
diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h
index ea4d603be83..6a715498b87 100644
--- a/intern/ghost/intern/GHOST_Event.h
+++ b/intern/ghost/intern/GHOST_Event.h
@@ -59,7 +59,7 @@ public:
* Returns the event type.
* \return The event type.
*/
- virtual GHOST_TEventType getType()
+ GHOST_TEventType getType()
{
return m_type;
}
@@ -68,7 +68,7 @@ public:
* Returns the time this event was generated.
* \return The event generation time.
*/
- virtual GHOST_TUns64 getTime()
+ GHOST_TUns64 getTime()
{
return m_time;
}
@@ -78,7 +78,7 @@ public:
* or NULL if it is a 'system' event.
* \return The generating window.
*/
- virtual GHOST_IWindow *getWindow()
+ GHOST_IWindow *getWindow()
{
return m_window;
}
@@ -87,7 +87,7 @@ public:
* Returns the event data.
* \return The event data.
*/
- virtual GHOST_TEventDataPtr getData()
+ GHOST_TEventDataPtr getData()
{
return m_data;
}
diff --git a/intern/ghost/intern/GHOST_EventManager.h b/intern/ghost/intern/GHOST_EventManager.h
index 8e513b4ee76..c8b5d1debe5 100644
--- a/intern/ghost/intern/GHOST_EventManager.h
+++ b/intern/ghost/intern/GHOST_EventManager.h
@@ -58,27 +58,27 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_EventManager();
+ ~GHOST_EventManager();
/**
* Returns the number of events currently on the stack.
* \return The number of events on the stack.
*/
- virtual GHOST_TUns32 getNumEvents();
+ GHOST_TUns32 getNumEvents();
/**
* Returns the number of events of a certain type currently on the stack.
* \param type The type of events to be counted.
* \return The number of events on the stack of this type.
*/
- virtual GHOST_TUns32 getNumEvents(GHOST_TEventType type);
+ GHOST_TUns32 getNumEvents(GHOST_TEventType type);
/**
* Return the event at the top of the stack without removal.
* Do not delete the event!
* \return The event at the top of the stack.
*/
- virtual GHOST_IEvent *peekEvent();
+ GHOST_IEvent *peekEvent();
/**
* Pushes an event on the stack.
@@ -86,47 +86,47 @@ public:
* Do not delete the event!
* \param event The event to push on the stack.
*/
- virtual GHOST_TSuccess pushEvent(GHOST_IEvent *event);
+ GHOST_TSuccess pushEvent(GHOST_IEvent *event);
/**
* Dispatches the given event directly, bypassing the event stack.
* \return Indication as to whether any of the consumers handled the event.
*/
- virtual bool dispatchEvent(GHOST_IEvent *event);
+ bool dispatchEvent(GHOST_IEvent *event);
/**
* Dispatches the event at the back of the stack.
* The event will be removed from the stack.
* \return Indication as to whether any of the consumers handled the event.
*/
- virtual bool dispatchEvent();
+ bool dispatchEvent();
/**
* Dispatches all the events on the stack.
* The event stack will be empty afterwards.
* \return Indication as to whether any of the consumers handled the events.
*/
- virtual bool dispatchEvents();
+ bool dispatchEvents();
/**
* Adds a consumer to the list of event consumers.
* \param consumer The consumer added to the list.
* \return Indication as to whether addition has succeeded.
*/
- virtual GHOST_TSuccess addConsumer(GHOST_IEventConsumer *consumer);
+ GHOST_TSuccess addConsumer(GHOST_IEventConsumer *consumer);
/**
* Removes a consumer from the list of event consumers.
* \param consumer The consumer removed from the list.
* \return Indication as to whether removal has succeeded.
*/
- virtual GHOST_TSuccess removeConsumer(GHOST_IEventConsumer *consumer);
+ GHOST_TSuccess removeConsumer(GHOST_IEventConsumer *consumer);
/**
* Removes all events for a window from the stack.
* \param window The window to remove events for.
*/
- virtual void
+ void
removeWindowEvents(
GHOST_IWindow *window
);
@@ -138,7 +138,7 @@ public:
* \param type The type of events to be removed.
* \param window The window to remove the events for.
*/
- virtual void
+ void
removeTypeEvents(
GHOST_TEventType type,
GHOST_IWindow *window = NULL
@@ -150,12 +150,12 @@ protected:
* Delete the event after use!
* \return The event at the top of the stack.
*/
- virtual GHOST_IEvent *popEvent();
+ GHOST_IEvent *popEvent();
/**
* Removes all events from the stack.
*/
- virtual void disposeEvents();
+ void disposeEvents();
/** A stack with events. */
typedef std::deque<GHOST_IEvent *> TEventStack;
diff --git a/intern/ghost/intern/GHOST_EventPrinter.h b/intern/ghost/intern/GHOST_EventPrinter.h
index 280d4208413..0cbb7ca467d 100644
--- a/intern/ghost/intern/GHOST_EventPrinter.h
+++ b/intern/ghost/intern/GHOST_EventPrinter.h
@@ -49,7 +49,7 @@ public:
* \param event The event that can be handled or not.
* \return Indication as to whether the event was handled.
*/
- virtual bool processEvent(GHOST_IEvent *event);
+ bool processEvent(GHOST_IEvent *event);
protected:
/**
diff --git a/intern/ghost/intern/GHOST_ImeWin32.cpp b/intern/ghost/intern/GHOST_ImeWin32.cpp
new file mode 100644
index 00000000000..af5a2ed7097
--- /dev/null
+++ b/intern/ghost/intern/GHOST_ImeWin32.cpp
@@ -0,0 +1,520 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (c) 2010 The Chromium Authors. All rights reserved.
+ * All rights reserved.
+ *
+ * The Original Code is: some of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+
+/** \file ghost/intern/GHOST_ImeWin32.cpp
+ * \ingroup GHOST
+ */
+
+#ifdef WITH_INPUT_IME
+
+#include "GHOST_C-api.h"
+#include "GHOST_ImeWin32.h"
+#include "GHOST_WindowWin32.h"
+#include "utfconv.h"
+
+
+GHOST_ImeWin32::GHOST_ImeWin32()
+ : ime_status_(false),
+ input_language_id_(LANG_USER_DEFAULT),
+ is_composing_(false),
+ system_caret_(false),
+ caret_rect_(-1, -1, 0, 0),
+ is_first(true),
+ is_enable(true)
+{
+}
+
+
+GHOST_ImeWin32::~GHOST_ImeWin32()
+{
+}
+
+
+bool GHOST_ImeWin32::SetInputLanguage()
+{
+ /**
+ * Retrieve the current keyboard layout from Windows and determine whether
+ * or not the current input context has IMEs.
+ * Also save its input language for language-specific operations required
+ * while composing a text.
+ */
+ HKL keyboard_layout = ::GetKeyboardLayout(0);
+ input_language_id_ = reinterpret_cast<LANGID>(keyboard_layout);
+ ime_status_ = ::ImmIsIME(keyboard_layout);
+ return ime_status_;
+}
+
+
+void GHOST_ImeWin32::CreateImeWindow(HWND window_handle)
+{
+ /**
+ * When a user disables TSF (Text Service Framework) and CUAS (Cicero
+ * Unaware Application Support), Chinese IMEs somehow ignore function calls
+ * to ::ImmSetCandidateWindow(), i.e. they do not move their candidate
+ * window to the position given as its parameters, and use the position
+ * of the current system caret instead, i.e. it uses ::GetCaretPos() to
+ * retrieve the position of their IME candidate window.
+ * Therefore, we create a temporary system caret for Chinese IMEs and use
+ * it during this input context.
+ * Since some third-party Japanese IME also uses ::GetCaretPos() to determine
+ * their window position, we also create a caret for Japanese IMEs.
+ */
+ if (PRIMARYLANGID(input_language_id_) == LANG_CHINESE ||
+ PRIMARYLANGID(input_language_id_) == LANG_JAPANESE) {
+ if (!system_caret_) {
+ if (::CreateCaret(window_handle, NULL, 1, 1)) {
+ system_caret_ = true;
+ }
+ }
+ }
+ /* Restore the positions of the IME windows. */
+ UpdateImeWindow(window_handle);
+}
+
+
+void GHOST_ImeWin32::SetImeWindowStyle(HWND window_handle, UINT message, WPARAM wparam, LPARAM lparam, BOOL *handled)
+{
+ /**
+ * To prevent the IMM (Input Method Manager) from displaying the IME
+ * composition window, Update the styles of the IME windows and EXPLICITLY
+ * call ::DefWindowProc() here.
+ * NOTE(hbono): We can NEVER let WTL call ::DefWindowProc() when we update
+ * the styles of IME windows because the 'lparam' variable is a local one
+ * and all its updates disappear in returning from this function, i.e. WTL
+ * does not call ::DefWindowProc() with our updated 'lparam' value but call
+ * the function with its original value and over-writes our window styles.
+ */
+ *handled = TRUE;
+ lparam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
+ ::DefWindowProc(window_handle, message, wparam, lparam);
+}
+
+
+void GHOST_ImeWin32::DestroyImeWindow(HWND window_handle)
+{
+ /* Destroy the system caret if we have created for this IME input context. */
+ if (system_caret_) {
+ ::DestroyCaret();
+ system_caret_ = false;
+ }
+}
+
+
+void GHOST_ImeWin32::MoveImeWindow(HWND window_handle, HIMC imm_context)
+{
+ int x = caret_rect_.m_l;
+ int y = caret_rect_.m_t;
+ const int kCaretMargin = 1;
+ /**
+ * As written in a comment in GHOST_ImeWin32::CreateImeWindow(),
+ * Chinese IMEs ignore function calls to ::ImmSetCandidateWindow()
+ * when a user disables TSF (Text Service Framework) and CUAS (Cicero
+ * Unaware Application Support).
+ * On the other hand, when a user enables TSF and CUAS, Chinese IMEs
+ * ignore the position of the current system caret and uses the
+ * parameters given to ::ImmSetCandidateWindow() with its 'dwStyle'
+ * parameter CFS_CANDIDATEPOS.
+ * Therefore, we do not only call ::ImmSetCandidateWindow() but also
+ * set the positions of the temporary system caret if it exists.
+ */
+ CANDIDATEFORM candidate_position = { 0, CFS_CANDIDATEPOS, { x, y },
+ { 0, 0, 0, 0 } };
+ ::ImmSetCandidateWindow(imm_context, &candidate_position);
+ if (system_caret_) {
+ switch (PRIMARYLANGID(input_language_id_)) {
+ case LANG_JAPANESE:
+ ::SetCaretPos(x, y + caret_rect_.getHeight());
+ break;
+ default:
+ ::SetCaretPos(x, y);
+ break;
+ }
+ }
+ if (PRIMARYLANGID(input_language_id_) == LANG_KOREAN) {
+ /**
+ * Chinese IMEs and Japanese IMEs require the upper-left corner of
+ * the caret to move the position of their candidate windows.
+ * On the other hand, Korean IMEs require the lower-left corner of the
+ * caret to move their candidate windows.
+ */
+ y += kCaretMargin;
+ }
+ /**
+ * Japanese IMEs and Korean IMEs also use the rectangle given to
+ * ::ImmSetCandidateWindow() with its 'dwStyle' parameter CFS_EXCLUDE
+ * to move their candidate windows when a user disables TSF and CUAS.
+ * Therefore, we also set this parameter here.
+ */
+ CANDIDATEFORM exclude_rectangle = { 0, CFS_EXCLUDE, { x, y },
+ { x, y, x + caret_rect_.getWidth(), y + caret_rect_.getHeight() } };
+ ::ImmSetCandidateWindow(imm_context, &exclude_rectangle);
+}
+
+
+void GHOST_ImeWin32::UpdateImeWindow(HWND window_handle)
+{
+ /* Just move the IME window attached to the given window. */
+ if (caret_rect_.m_l >= 0 && caret_rect_.m_t >= 0) {
+ HIMC imm_context = ::ImmGetContext(window_handle);
+ if (imm_context) {
+ MoveImeWindow(window_handle, imm_context);
+ ::ImmReleaseContext(window_handle, imm_context);
+ }
+ }
+}
+
+
+void GHOST_ImeWin32::CleanupComposition(HWND window_handle)
+{
+ /**
+ * Notify the IMM attached to the given window to complete the ongoing
+ * composition, (this case happens when the given window is de-activated
+ * while composing a text and re-activated), and reset the omposition status.
+ */
+ if (is_composing_) {
+ HIMC imm_context = ::ImmGetContext(window_handle);
+ if (imm_context) {
+ ::ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
+ ::ImmReleaseContext(window_handle, imm_context);
+ }
+ ResetComposition(window_handle);
+ }
+}
+
+
+void GHOST_ImeWin32::CheckFirst(HWND window_handle)
+{
+ if (is_first) {
+ this->EndIME(window_handle);
+ is_first = false;
+ }
+}
+
+
+void GHOST_ImeWin32::ResetComposition(HWND window_handle)
+{
+ /* Currently, just reset the composition status. */
+ is_composing_ = false;
+}
+
+
+void GHOST_ImeWin32::CompleteComposition(HWND window_handle, HIMC imm_context)
+{
+ /**
+ * We have to confirm there is an ongoing composition before completing it.
+ * This is for preventing some IMEs from getting confused while completing an
+ * ongoing composition even if they do not have any ongoing compositions.)
+ */
+ if (is_composing_) {
+ ::ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
+ ResetComposition(window_handle);
+ }
+}
+
+
+void GHOST_ImeWin32::GetCaret(HIMC imm_context, LPARAM lparam, ImeComposition *composition)
+{
+ /**
+ * This operation is optional and language-dependent because the caret
+ * style is depended on the language, e.g.:
+ * * Korean IMEs: the caret is a blinking block,
+ * (It contains only one hangul character);
+ * * Chinese IMEs: the caret is a blinking line,
+ * (i.e. they do not need to retrieve the target selection);
+ * * Japanese IMEs: the caret is a selection (or underlined) block,
+ * (which can contain one or more Japanese characters).
+ */
+ int target_start = -1;
+ int target_end = -1;
+ switch (PRIMARYLANGID(input_language_id_)) {
+ case LANG_KOREAN:
+ if (lparam & CS_NOMOVECARET) {
+ target_start = 0;
+ target_end = 1;
+ }
+ break;
+ case LANG_CHINESE:
+ {
+ int clause_size = ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, NULL, 0);
+ if (clause_size) {
+ static std::vector<unsigned long> clauses;
+ clause_size = clause_size / sizeof(clauses[0]);
+ clauses.resize(clause_size);
+ ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, &clauses[0],
+ sizeof(clauses[0]) *clause_size);
+ if (composition->cursor_position == composition->ime_string.size()) {
+ target_start = clauses[clause_size - 2];
+ target_end = clauses[clause_size - 1];
+ }
+ else {
+ for (int i = 0; i < clause_size - 1; i++) {
+ if (clauses[i] == composition->cursor_position) {
+ target_start = clauses[i];
+ target_end = clauses[i + 1];
+ break;
+ }
+ }
+ }
+ }
+ else {
+ if (composition->cursor_position != -1) {
+ target_start = composition->cursor_position;
+ target_end = composition->ime_string.size();
+ }
+ }
+ break;
+ }
+ case LANG_JAPANESE:
+
+ /**
+ * For Japanese IMEs, the robustest way to retrieve the caret
+ * is scanning the attribute of the latest composition string and
+ * retrieving the begining and the end of the target clause, i.e.
+ * a clause being converted.
+ */
+ if (lparam & GCS_COMPATTR) {
+ int attribute_size = ::ImmGetCompositionStringW(imm_context,
+ GCS_COMPATTR,
+ NULL, 0);
+ if (attribute_size > 0) {
+ char *attribute_data = new char[attribute_size];
+ if (attribute_data) {
+ ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR,
+ attribute_data, attribute_size);
+ for (target_start = 0; target_start < attribute_size;
+ ++target_start) {
+ if (IsTargetAttribute(attribute_data[target_start]))
+ break;
+ }
+ for (target_end = target_start; target_end < attribute_size;
+ ++target_end) {
+ if (!IsTargetAttribute(attribute_data[target_end]))
+ break;
+ }
+ if (target_start == attribute_size) {
+ /**
+ * This composition clause does not contain any target clauses,
+ * i.e. this clauses is an input clause.
+ * We treat whole this clause as a target clause.
+ */
+ target_end = target_start;
+ target_start = 0;
+ }
+ if (target_start != -1 && target_start < attribute_size &&
+ attribute_data[target_start] == ATTR_TARGET_NOTCONVERTED)
+ {
+ composition->cursor_position = target_start;
+ }
+ }
+ delete[] attribute_data;
+ }
+ }
+ break;
+ }
+ composition->target_start = target_start;
+ composition->target_end = target_end;
+}
+
+
+bool GHOST_ImeWin32::GetString(HIMC imm_context, WPARAM lparam, int type, ImeComposition *composition)
+{
+ bool result = false;
+ if (lparam & type) {
+ int string_size = ::ImmGetCompositionStringW(imm_context, type, NULL, 0);
+ if (string_size > 0) {
+ int string_length = string_size / sizeof(wchar_t);
+ wchar_t *string_data = new wchar_t[string_length + 1];
+ string_data[string_length] = '\0';
+ if (string_data) {
+ /* Fill the given ImeComposition object. */
+ ::ImmGetCompositionStringW(imm_context, type,
+ string_data, string_size);
+ composition->string_type = type;
+ composition->ime_string = string_data;
+ result = true;
+ }
+ delete[] string_data;
+ }
+ }
+ return result;
+}
+
+
+bool GHOST_ImeWin32::GetResult(HWND window_handle, LPARAM lparam, ImeComposition *composition)
+{
+ bool result = false;
+ HIMC imm_context = ::ImmGetContext(window_handle);
+ if (imm_context) {
+ /* Copy the result string to the ImeComposition object. */
+ result = GetString(imm_context, lparam, GCS_RESULTSTR, composition);
+ /**
+ * Reset all the other parameters because a result string does not
+ * have composition attributes.
+ */
+ composition->cursor_position = -1;
+ composition->target_start = -1;
+ composition->target_end = -1;
+ ::ImmReleaseContext(window_handle, imm_context);
+ }
+ return result;
+}
+
+
+bool GHOST_ImeWin32::GetComposition(HWND window_handle, LPARAM lparam, ImeComposition *composition)
+{
+ bool result = false;
+ HIMC imm_context = ::ImmGetContext(window_handle);
+ if (imm_context) {
+ /* Copy the composition string to the ImeComposition object. */
+ result = GetString(imm_context, lparam, GCS_COMPSTR, composition);
+
+ /* Retrieve the cursor position in the IME composition. */
+ int cursor_position = ::ImmGetCompositionStringW(imm_context, GCS_CURSORPOS, NULL, 0);
+ composition->cursor_position = cursor_position;
+ composition->target_start = -1;
+ composition->target_end = -1;
+
+ /* Retrieve the target selection and Update the ImeComposition object. */
+ GetCaret(imm_context, lparam, composition);
+
+ /* Mark that there is an ongoing composition. */
+ is_composing_ = true;
+
+ ::ImmReleaseContext(window_handle, imm_context);
+ }
+ return result;
+}
+
+
+void GHOST_ImeWin32::EndIME(HWND window_handle)
+{
+ /**
+ * A renderer process have moved its input focus to a password input
+ * when there is an ongoing composition, e.g. a user has clicked a
+ * mouse button and selected a password input while composing a text.
+ * For this case, we have to complete the ongoing composition and
+ * clean up the resources attached to this object BEFORE DISABLING THE IME.
+ */
+ if (!is_enable) return;
+ is_enable = false;
+ CleanupComposition(window_handle);
+ ::ImmAssociateContextEx(window_handle, NULL, 0);
+ eventImeData.composite_len = 0;
+}
+
+
+void GHOST_ImeWin32::BeginIME(HWND window_handle, const GHOST_Rect &caret_rect, bool complete)
+{
+ if (is_enable && complete) return;
+ is_enable = true;
+ /**
+ * Load the default IME context.
+ * NOTE(hbono)
+ * IMM ignores this call if the IME context is loaded. Therefore, we do
+ * not have to check whether or not the IME context is loaded.
+ */
+ ::ImmAssociateContextEx(window_handle, NULL, IACE_DEFAULT);
+ /* Complete the ongoing composition and move the IME windows. */
+ HIMC imm_context = ::ImmGetContext(window_handle);
+ if (imm_context) {
+ if (complete) {
+ /**
+ * A renderer process have moved its input focus to another edit
+ * control when there is an ongoing composition, e.g. a user has
+ * clicked a mouse button and selected another edit control while
+ * composing a text.
+ * For this case, we have to complete the ongoing composition and
+ * hide the IME windows BEFORE MOVING THEM.
+ */
+ CompleteComposition(window_handle, imm_context);
+ }
+ /**
+ * Save the caret position, and Update the position of the IME window.
+ * This update is used for moving an IME window when a renderer process
+ * resize/moves the input caret.
+ */
+ if (caret_rect.m_l >= 0 && caret_rect.m_t >= 0) {
+ caret_rect_ = caret_rect;
+ MoveImeWindow(window_handle, imm_context);
+ }
+ ::ImmReleaseContext(window_handle, imm_context);
+ }
+}
+
+
+static void convert_utf16_to_utf8_len(std::wstring s, int &len)
+{
+ if (len >= 0 && len <= s.size())
+ len = count_utf_8_from_16(s.substr(0, len).c_str()) - 1;
+ else
+ len = -1;
+}
+
+
+static size_t updateUtf8Buf(ImeComposition &info)
+{
+ size_t len = count_utf_8_from_16(info.ime_string.c_str());
+ info.utf8_buf.resize(len);
+ conv_utf_16_to_8(info.ime_string.c_str(), &info.utf8_buf[0], len);
+ convert_utf16_to_utf8_len(info.ime_string, info.cursor_position);
+ convert_utf16_to_utf8_len(info.ime_string, info.target_start);
+ convert_utf16_to_utf8_len(info.ime_string, info.target_end);
+ return len - 1;
+}
+
+
+void GHOST_ImeWin32::UpdateInfo(HWND window_handle)
+{
+ int res = this->GetResult(window_handle, GCS_RESULTSTR, &resultInfo);
+ int comp = this->GetComposition(window_handle, GCS_COMPSTR | GCS_COMPATTR, &compInfo);
+ /* convert wchar to utf8 */
+ if (res) {
+ eventImeData.result_len = (GHOST_TUserDataPtr)updateUtf8Buf(resultInfo);
+ eventImeData.result = &resultInfo.utf8_buf[0];
+ }
+ else {
+ eventImeData.result = 0;
+ eventImeData.result_len = 0;
+ }
+ if (comp) {
+ eventImeData.composite_len = (GHOST_TUserDataPtr)updateUtf8Buf(compInfo);
+ eventImeData.composite = &compInfo.utf8_buf[0];
+ eventImeData.cursor_position = compInfo.cursor_position;
+ eventImeData.target_start = compInfo.target_start;
+ eventImeData.target_end = compInfo.target_end;
+ }
+ else {
+ eventImeData.composite = 0;
+ eventImeData.composite_len = 0;
+ eventImeData.cursor_position = -1;
+ eventImeData.target_start = -1;
+ eventImeData.target_end = -1;
+ }
+}
+
+#endif // WITH_INPUT_IME
diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h
new file mode 100644
index 00000000000..bfd9a49d785
--- /dev/null
+++ b/intern/ghost/intern/GHOST_ImeWin32.h
@@ -0,0 +1,405 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (c) 2010 The Chromium Authors. All rights reserved.
+ * All rights reserved.
+ *
+ * The Original Code is: some of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+*/
+
+/** \file ghost/intern/GHOST_ImeWin32.h
+ * \ingroup GHOST
+ */
+
+#ifndef __GHOST_IME_H__
+#define __GHOST_IME_H__
+
+#ifdef WITH_INPUT_IME
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <string>
+
+#include "GHOST_Event.h"
+#include "GHOST_Rect.h"
+#include <vector>
+
+class GHOST_EventIME : public GHOST_Event
+{
+public:
+ /**
+ * Constructor.
+ * \param msec The time this event was generated.
+ * \param type The type of key event.
+ * \param key The key code of the key.
+ */
+ GHOST_EventIME(GHOST_TUns64 msec,
+ GHOST_TEventType type,
+ GHOST_IWindow *window, void *customdata)
+ : GHOST_Event(msec, type, window)
+ {
+ this->m_data = customdata;
+ }
+
+};
+
+
+/**
+ * This header file defines a struct and a class used for encapsulating IMM32
+ * APIs, controls IMEs attached to a window, and enables the 'on-the-spot'
+ * input without deep knowledge about the APIs, i.e. knowledge about the
+ * language-specific and IME-specific behaviors.
+ * The following items enumerates the simplest steps for an (window)
+ * application to control its IMEs with the struct and the class defined
+ * this file.
+ * 1. Add an instance of the GHOST_ImeWin32 class to its window class.
+ * (The GHOST_ImeWin32 class needs a window handle.)
+ * 2. Add messages handlers listed in the following subsections, follow the
+ * instructions written in each subsection, and use the GHOST_ImeWin32 class.
+ * 2.1. WM_IME_SETCONTEXT (0x0281)
+ * Call the functions listed below:
+ * - GHOST_ImeWin32::CreateImeWindow();
+ * - GHOST_ImeWin32::CleanupComposition(), and;
+ * - GHOST_ImeWin32::SetImeWindowStyle().
+ * An application MUST prevent from calling ::DefWindowProc().
+ * 2.2. WM_IME_STARTCOMPOSITION (0x010D)
+ * Call the functions listed below:
+ * - GHOST_ImeWin32::CreateImeWindow(), and;
+ * - GHOST_ImeWin32::ResetComposition().
+ * An application MUST prevent from calling ::DefWindowProc().
+ * 2.3. WM_IME_COMPOSITION (0x010F)
+ * Call the functions listed below:
+ * - GHOST_ImeWin32::UpdateImeWindow();
+ * - GHOST_ImeWin32::GetResult();
+ * - GHOST_ImeWin32::GetComposition(), and;
+ * - GHOST_ImeWin32::ResetComposition() (optional).
+ * An application MUST prevent from calling ::DefWindowProc().
+ * 2.4. WM_IME_ENDCOMPOSITION (0x010E)
+ * Call the functions listed below:
+ * - GHOST_ImeWin32::ResetComposition(), and;
+ * - GHOST_ImeWin32::DestroyImeWindow().
+ * An application CAN call ::DefWindowProc().
+ * 2.5. WM_INPUTLANGCHANGE (0x0051)
+ * Call the functions listed below:
+ * - GHOST_ImeWin32::SetInputLanguage().
+ * An application CAN call ::DefWindowProc().
+ */
+
+/* This struct represents the status of an ongoing composition. */
+struct ImeComposition {
+ /* Represents the cursor position in the IME composition. */
+ int cursor_position;
+
+ /* Represents the position of the beginning of the selection */
+ int target_start;
+
+ /* Represents the position of the end of the selection */
+ int target_end;
+
+ /**
+ * Represents the type of the string in the 'ime_string' parameter.
+ * Its possible values and description are listed below:
+ * Value Description
+ * 0 The parameter is not used.
+ * GCS_RESULTSTR The parameter represents a result string.
+ * GCS_COMPSTR The parameter represents a composition string.
+ */
+ int string_type;
+
+ /* Represents the string retrieved from IME (Input Method Editor) */
+ std::wstring ime_string;
+ std::vector<char> utf8_buf;
+ std::vector<unsigned char> format;
+};
+
+/**
+ * This class controls the IMM (Input Method Manager) through IMM32 APIs and
+ * enables it to retrieve the string being controled by the IMM. (I wrote
+ * a note to describe the reason why I do not use 'IME' but 'IMM' below.)
+ * NOTE(hbono):
+ * Fortunately or unfortunately, TSF (Text Service Framework) and
+ * CUAS (Cicero Unaware Application Support) allows IMM32 APIs for
+ * retrieving not only the inputs from IMEs (Input Method Editors), used
+ * only for inputting East-Asian language texts, but also the ones from
+ * tablets (on Windows XP Tablet PC Edition and Windows Vista), voice
+ * recognizers (e.g. ViaVoice and Microsoft Office), etc.
+ * We can disable TSF and CUAS in Windows XP Tablet PC Edition. On the other
+ * hand, we can NEVER disable either TSF or CUAS in Windows Vista, i.e.
+ * THIS CLASS IS NOT ONLY USED ON THE INPUT CONTEXTS OF EAST-ASIAN
+ * LANGUAGES BUT ALSO USED ON THE INPUT CONTEXTS OF ALL LANGUAGES.
+ */
+class GHOST_ImeWin32 {
+public:
+ GHOST_ImeWin32();
+ ~GHOST_ImeWin32();
+
+ /* Retrieves whether or not there is an ongoing composition. */
+ bool is_composing() const {return is_composing_;}
+
+ /**
+ * Retrieves the input language from Windows and update it.
+ * Return values
+ * * true
+ * The given input language has IMEs.
+ * * false
+ * The given input language does not have IMEs.
+ */
+ bool SetInputLanguage();
+
+ /**
+ * Create the IME windows, and allocate required resources for them.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void CreateImeWindow(HWND window_handle);
+
+ /**
+ * Update the style of the IME windows.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ * * message [in] (UINT)
+ * * wparam [in] (WPARAM)
+ * * lparam [in] (LPARAM)
+ * Represent the windows message of the caller.
+ * These parameters are used for verifying if this function is called
+ * in a handler function for WM_IME_SETCONTEXT messages because this
+ * function uses ::DefWindowProc() to update the style.
+ * A caller just has to pass the input parameters for the handler
+ * function without modifications.
+ * * handled [out] (BOOL*)
+ * Returns ::DefWindowProc() is really called in this function.
+ * PLEASE DO NOT CALL ::DefWindowProc() IF THIS VALUE IS TRUE!
+ * All the window styles set in this function are over-written when
+ * calling ::DefWindowProc() after returning this function.
+ */
+ void SetImeWindowStyle(HWND window_handle, UINT message,
+ WPARAM wparam, LPARAM lparam, BOOL* handled);
+
+ /**
+ * Destroy the IME windows and all the resources attached to them.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void DestroyImeWindow(HWND window_handle);
+
+ /**
+ * Update the position of the IME windows.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void UpdateImeWindow(HWND window_handle);
+
+ /**
+ * Clean up the all resources attached to the given GHOST_ImeWin32 object, and
+ * reset its composition status.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void CleanupComposition(HWND window_handle);
+
+ /**
+ * Reset the composition status.
+ * Cancel the ongoing composition if it exists.
+ * NOTE(hbono): This method does not release the allocated resources.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void ResetComposition(HWND window_handle);
+
+ /**
+ * Retrieve a composition result of the ongoing composition if it exists.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ * * lparam [in] (LPARAM)
+ * Specifies the updated members of the ongoing composition, and must be
+ * the same parameter of a WM_IME_COMPOSITION message handler.
+ * This parameter is used for checking if the ongoing composition has
+ * its result string,
+ * * composition [out] (ImeComposition)
+ * Represents the struct contains the composition result.
+ * Return values
+ * * true
+ * The ongoing composition has a composition result.
+ * * false
+ * The ongoing composition does not have composition results.
+ * Remarks
+ * This function is designed for being called from WM_IME_COMPOSITION
+ * message handlers.
+ */
+ bool GetResult(HWND window_handle, LPARAM lparam,
+ ImeComposition* composition);
+
+ /**
+ * Retrieve the current composition status of the ongoing composition.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ * * lparam [in] (LPARAM)
+ * Specifies the updated members of the ongoing composition, and must be
+ * the same parameter of a WM_IME_COMPOSITION message handler.
+ * This parameter is used for checking if the ongoing composition has
+ * its result string,
+ * * composition [out] (ImeComposition)
+ * Represents the struct contains the composition status.
+ * Return values
+ * * true
+ * The status of the ongoing composition is updated.
+ * * false
+ * The status of the ongoing composition is not updated.
+ * Remarks
+ * This function is designed for being called from WM_IME_COMPOSITION
+ * message handlers.
+ */
+ bool GetComposition(HWND window_handle, LPARAM lparam,
+ ImeComposition* composition);
+
+ /**
+ * Enable the IME attached to the given window, i.e. allows user-input
+ * events to be dispatched to the IME.
+ * In Chrome, this function is used when:
+ * * a renderer process moves its input focus to another edit control, or;
+ * * a renrerer process moves the position of the focused edit control.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ * * caret_rect [in] (const gfx::Rect&)
+ * Represent the rectangle of the input caret.
+ * This rectangle is used for controlling the positions of IME windows.
+ * * complete [in] (bool)
+ * Represents whether or not to complete the ongoing composition.
+ * + true
+ * After finishing the ongoing composition and close its IME windows,
+ * start another composition and display its IME windows to the given
+ * position.
+ * + false
+ * Just move the IME windows of the ongoing composition to the given
+ * position without finishing it.
+ */
+ void BeginIME(HWND window_handle,
+ const GHOST_Rect& caret_rect,
+ bool complete);
+
+ /**
+ * Disable the IME attached to the given window, i.e. prohibits any user-input
+ * events from being dispatched to the IME.
+ * In Chrome, this function is used when:
+ * * a renreder process sets its input focus to a password input.
+ * Parameters
+ * * window_handle [in] (HWND)
+ * Represents the window handle of the caller.
+ */
+ void EndIME(HWND window_handle);
+
+ /* Updatg resultInfo and compInfo */
+ void UpdateInfo(HWND window_handle);
+
+ /* disable ime when start up */
+ void CheckFirst(HWND window_handle);
+
+ ImeComposition resultInfo, compInfo;
+ GHOST_TEventImeData eventImeData;
+
+protected:
+ /* Determines whether or not the given attribute represents a target (a.k.a. a selection). */
+ bool IsTargetAttribute(char attribute) const {
+ return (attribute == ATTR_TARGET_CONVERTED ||
+ attribute == ATTR_TARGET_NOTCONVERTED);
+ }
+
+ /* Retrieve the target area. */
+ void GetCaret(HIMC imm_context, LPARAM lparam,
+ ImeComposition* composition);
+
+ /* Update the position of the IME windows. */
+ void MoveImeWindow(HWND window_handle, HIMC imm_context);
+
+ /* Complete the ongoing composition if it exists. */
+ void CompleteComposition(HWND window_handle, HIMC imm_context);
+
+ /* Retrieve a string from the IMM. */
+ bool GetString(HIMC imm_context, WPARAM lparam, int type,
+ ImeComposition* composition);
+
+private:
+ /**
+ * Represents whether or not there is an ongoing composition in a browser
+ * process, i.e. whether or not a browser process is composing a text.
+ */
+ bool is_composing_;
+
+ /**
+ * This value represents whether or not the current input context has IMEs.
+ * The following table shows the list of IME status:
+ * Value Description
+ * false The current input language does not have IMEs.
+ * true The current input language has IMEs.
+ */
+ bool ime_status_;
+
+ /**
+ * The current input Language ID retrieved from Windows, which consists of:
+ * * Primary Language ID (bit 0 to bit 9), which shows a natunal language
+ * (English, Korean, Chinese, Japanese, etc.) and;
+ * * Sub-Language ID (bit 10 to bit 15), which shows a geometrical region
+ * the language is spoken (For English, United States, United Kingdom,
+ * Australia, Canada, etc.)
+ * The following list enumerates some examples for the Language ID:
+ * * "en-US" (0x0409)
+ * MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
+ * * "ko-KR" (0x0412)
+ * MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN);
+ * * "zh-TW" (0x0404)
+ * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL);
+ * * "zh-CN" (0x0804)
+ * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED);
+ * * "ja-JP" (0x0411)
+ * MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), etc.
+ * (See <winnt.h> for other available values.)
+ * This Language ID is used for processing language-specific operations in
+ * IME functions.
+ */
+ LANGID input_language_id_;
+
+ /**
+ * Represents whether or not the current input context has created a system
+ * caret to set the position of its IME candidate window.
+ * * true: it creates a system caret.
+ * * false: it does not create a system caret.
+ */
+ bool system_caret_;
+
+ /* The rectangle of the input caret retrieved from a renderer process. */
+ GHOST_Rect caret_rect_;
+
+ /* used for disable ime when start up */
+ bool is_first, is_enable;
+};
+
+#endif // WITH_INPUT_IME
+#endif // __GHOST_IME_H__
diff --git a/intern/ghost/intern/GHOST_ModifierKeys.h b/intern/ghost/intern/GHOST_ModifierKeys.h
index 8189006f602..75173f5a525 100644
--- a/intern/ghost/intern/GHOST_ModifierKeys.h
+++ b/intern/ghost/intern/GHOST_ModifierKeys.h
@@ -47,7 +47,7 @@ struct GHOST_ModifierKeys {
*/
GHOST_ModifierKeys();
- virtual ~GHOST_ModifierKeys();
+ ~GHOST_ModifierKeys();
/**
* Returns the modifier key's key code from a modifier key mask.
@@ -62,26 +62,26 @@ struct GHOST_ModifierKeys {
* \param mask. Key state to return.
* \return The state of the key (pressed == true).
*/
- virtual bool get(GHOST_TModifierKeyMask mask) const;
+ bool get(GHOST_TModifierKeyMask mask) const;
/**
* Updates the state of a single modifier key.
* \param mask. Key state to update.
* \param down. The new state of the key.
*/
- virtual void set(GHOST_TModifierKeyMask mask, bool down);
+ void set(GHOST_TModifierKeyMask mask, bool down);
/**
* Sets the state of all modifier keys to up.
*/
- virtual void clear();
+ void clear();
/**
* Determines whether to modifier key states are equal.
* \param keys. The modifier key state to compare to.
* \return Indication of equality.
*/
- virtual bool equals(const GHOST_ModifierKeys& keys) const;
+ bool equals(const GHOST_ModifierKeys& keys) const;
/** Bitfield that stores the appropriate key state. */
GHOST_TUns8 m_LeftShift : 1;
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index 9bd6226d5c2..27285e49e9e 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -146,8 +146,8 @@ static const NDOF_ButtonT SpaceExplorer_HID_map[] = {
NDOF_BUTTON_ROTATE
};
-/* this is the older SpacePilot (sans Pro)
- * thanks to polosson for info about this device */
+// this is the older SpacePilot (sans Pro)
+// thanks to polosson for info about this device
static const NDOF_ButtonT SpacePilot_HID_map[] = {
NDOF_BUTTON_1,
NDOF_BUTTON_2,
@@ -190,17 +190,17 @@ static const NDOF_ButtonT Generic_HID_map[] = {
static const int genericButtonCount = sizeof(Generic_HID_map) / sizeof(NDOF_ButtonT);
GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System &sys)
- : m_system(sys),
- m_deviceType(NDOF_UnknownDevice), /* each platform has its own device detection code */
- m_buttonCount(genericButtonCount),
- m_buttonMask(0),
- m_hidMap(Generic_HID_map),
- m_buttons(0),
- m_motionTime(0),
- m_prevMotionTime(0),
- m_motionState(GHOST_kNotStarted),
- m_motionEventPending(false),
- m_deadZone(0.0f)
+ : m_system(sys),
+ m_deviceType(NDOF_UnknownDevice), // each platform has its own device detection code
+ m_buttonCount(genericButtonCount),
+ m_buttonMask(0),
+ m_hidMap(Generic_HID_map),
+ m_buttons(0),
+ m_motionTime(0),
+ m_prevMotionTime(0),
+ m_motionState(GHOST_kNotStarted),
+ m_motionEventPending(false),
+ m_deadZone(0.0f)
{
// to avoid the rare situation where one triple is updated and
// the other is not, initialize them both here:
@@ -228,7 +228,7 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
// that I don't have access to. Thanks!
switch (vendor_id) {
- case 0x046D: // Logitech (3Dconnexion)
+ case 0x046D: // Logitech (3Dconnexion was a subsidiary)
switch (product_id) {
// -- current devices --
case 0xC626: // full-size SpaceNavigator
@@ -281,6 +281,29 @@ bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short produ
printf("ndof: unknown Logitech product %04hx\n", product_id);
}
break;
+ case 0x256F: // 3Dconnexion
+ switch (product_id) {
+ case 0xC62E: // plugged in
+ case 0xC62F: // wireless
+ puts("ndof: using SpaceMouse Wireless");
+ m_deviceType = NDOF_SpaceMouseWireless;
+ m_buttonCount = 2;
+ m_hidMap = Modern3Dx_HID_map;
+ break;
+ case 0xC631: // plugged in
+ case 0xC632: // wireless
+ puts("ndof: using SpaceMouse Pro Wireless");
+ m_deviceType = NDOF_SpaceMouseProWireless;
+ m_buttonCount = 27;
+ // ^^ actually has 15 buttons, but their HID codes range from 0 to 26
+ m_buttonMask = 0x07C0F137;
+ m_hidMap = Modern3Dx_HID_map;
+ break;
+
+ default:
+ printf("ndof: unknown 3Dconnexion product %04hx\n", product_id);
+ }
+ break;
default:
printf("ndof: unknown device %04hx:%04hx\n", vendor_id, product_id);
}
@@ -390,9 +413,9 @@ void GHOST_NDOFManager::updateButtons(int button_bits, GHOST_TUns64 time)
void GHOST_NDOFManager::setDeadZone(float dz)
{
- if (dz < 0.f) {
+ if (dz < 0.0f) {
// negative values don't make sense, so clamp at zero
- dz = 0.f;
+ dz = 0.0f;
}
else if (dz > 0.5f) {
// warn the rogue user/developer, but allow it
@@ -405,14 +428,14 @@ void GHOST_NDOFManager::setDeadZone(float dz)
static bool atHomePosition(GHOST_TEventNDOFMotionData *ndof)
{
-#define HOME(foo) (ndof->foo == 0.f)
+#define HOME(foo) (ndof->foo == 0.0f)
return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz);
#undef HOME
}
static bool nearHomePosition(GHOST_TEventNDOFMotionData *ndof, float threshold)
{
- if (threshold == 0.f) {
+ if (threshold == 0.0f) {
return atHomePosition(ndof);
}
else {
@@ -442,7 +465,7 @@ bool GHOST_NDOFManager::sendMotionEvent()
// scale axis values here to normalize them to around +/- 1
// they are scaled again for overall sensitivity in the WM based on user prefs
- const float scale = 1.f / 350.f; // 3Dconnexion devices send +/- 350 usually
+ const float scale = 1.0f / 350.0f; // 3Dconnexion devices send +/- 350 usually
data->tx = scale * m_translation[0];
data->ty = scale * m_translation[1];
diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h
index 0b2080e36a9..48a4881afb1 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.h
+++ b/intern/ghost/intern/GHOST_NDOFManager.h
@@ -20,7 +20,7 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-
+
#ifndef __GHOST_NDOFMANAGER_H__
#define __GHOST_NDOFMANAGER_H__
@@ -38,6 +38,8 @@ typedef enum {
NDOF_SpaceExplorer,
NDOF_SpacePilotPro,
NDOF_SpaceMousePro,
+ NDOF_SpaceMouseWireless,
+ NDOF_SpaceMouseProWireless,
// older devices
NDOF_SpacePilot,
diff --git a/intern/ghost/intern/GHOST_NDOFManagerX11.cpp b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
index 8e6f9994e51..de44b36c73e 100644
--- a/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
@@ -42,8 +42,8 @@ GHOST_NDOFManagerX11::GHOST_NDOFManagerX11(GHOST_System& sys)
#define MAX_LINE_LENGTH 100
- /* look for USB devices with Logitech's vendor ID */
- FILE *command_output = popen("lsusb -d 046d:", "r");
+ /* look for USB devices with Logitech or 3Dconnexion's vendor ID */
+ FILE *command_output = popen("lsusb | grep '046d:\|256f:'", "r");
if (command_output) {
char line[MAX_LINE_LENGTH] = {0};
while (fgets(line, MAX_LINE_LENGTH, command_output)) {
@@ -58,7 +58,7 @@ GHOST_NDOFManagerX11::GHOST_NDOFManagerX11(GHOST_System& sys)
}
else {
#ifdef DEBUG
- /* annoying for official builds, just adds noise and most prople don't own these */
+ /* annoying for official builds, just adds noise and most people don't own these */
puts("ndof: spacenavd not found");
/* This isn't a hard error, just means the user doesn't have a 3D mouse. */
#endif
@@ -81,11 +81,11 @@ bool GHOST_NDOFManagerX11::available()
* this causes any proceeding event to have a very high 'dt' (time delta),
* many seconds for eg, causing the view to jump.
*
- * this workaround expect's continuous events, if we miss a motion event,
+ * this workaround expects continuous events, if we miss a motion event,
* immediately send a dummy event with no motion to ensure the finished state is reached.
*/
#define USE_FINISH_GLITCH_WORKAROUND
-
+/* TODO: make this available on all platforms */
#ifdef USE_FINISH_GLITCH_WORKAROUND
static bool motion_test_prev = false;
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index d1f2d5d87c8..fef8fda7da3 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -350,6 +350,12 @@ GHOST_TSuccess GHOST_System::exit()
GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings,
const bool stereoVisual, const GHOST_TUns16 numOfAASamples)
{
+ GHOST_GLSettings glSettings = {0};
+
+ if (stereoVisual)
+ glSettings.flags |= GHOST_glStereoVisual;
+ glSettings.numOfAASamples = numOfAASamples;
+
/* note: don't use getCurrentDisplaySetting() because on X11 we may
* be zoomed in and the desktop may be bigger then the viewport. */
GHOST_ASSERT(m_displayManager, "GHOST_System::createFullScreenWindow(): invalid display manager");
@@ -359,9 +365,8 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const
0, 0, settings.xPixels, settings.yPixels,
GHOST_kWindowStateNormal,
GHOST_kDrawingContextTypeOpenGL,
- stereoVisual,
- true, /* exclusive */
- numOfAASamples);
+ glSettings,
+ true /* exclusive */);
return (*window == NULL) ? GHOST_kFailure : GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 79230b0f505..4f689ce43c9 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -97,7 +97,7 @@ public:
* \param userData Placeholder for user data.
* \return A timer task (0 if timer task installation failed).
*/
- virtual GHOST_ITimerTask *installTimer(GHOST_TUns64 delay,
+ GHOST_ITimerTask *installTimer(GHOST_TUns64 delay,
GHOST_TUns64 interval,
GHOST_TimerProcPtr timerProc,
GHOST_TUserDataPtr userData = NULL);
@@ -107,7 +107,7 @@ public:
* \param timerTask Timer task to be removed.
* \return Indication of success.
*/
- virtual GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask);
+ GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask);
/***************************************************************************************
* Display/window management functionality
@@ -126,14 +126,14 @@ public:
* \param window Pointer to the window to be disposed.
* \return Indication of success.
*/
- virtual GHOST_TSuccess disposeWindow(GHOST_IWindow *window);
+ GHOST_TSuccess disposeWindow(GHOST_IWindow *window);
/**
* Returns whether a window is valid.
* \param window Pointer to the window to be checked.
* \return Indication of validity.
*/
- virtual bool validWindow(GHOST_IWindow *window);
+ bool validWindow(GHOST_IWindow *window);
/**
* Begins full screen mode.
@@ -143,7 +143,7 @@ public:
* This window is invalid after full screen has been ended.
* \return Indication of success.
*/
- virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window,
+ GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window,
const bool stereoVisual, const GHOST_TUns16 numOfAASamples = 0);
/**
@@ -153,26 +153,26 @@ public:
*
* \return Indication of success.
*/
- virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window);
+ GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window);
/**
* Ends full screen mode.
* \return Indication of success.
*/
- virtual GHOST_TSuccess endFullScreen(void);
+ GHOST_TSuccess endFullScreen(void);
/**
* Returns current full screen mode status.
* \return The current status.
*/
- virtual bool getFullScreen(void);
+ bool getFullScreen(void);
/**
* Native pixel size support (MacBook 'retina').
* \return The pixel size in float.
*/
- virtual bool useNativePixel(void);
+ bool useNativePixel(void);
bool m_nativePixel;
/***************************************************************************************
@@ -192,21 +192,21 @@ public:
* The event stack will be empty afterwards.
* \return Indication as to whether any of the consumers handled the events.
*/
- virtual bool dispatchEvents();
+ bool dispatchEvents();
/**
* Adds the given event consumer to our list.
* \param consumer The event consumer to add.
* \return Indication of success.
*/
- virtual GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer);
+ GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer);
/**
* Remove the given event consumer to our list.
* \param consumer The event consumer to remove.
* \return Indication of success.
*/
- virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer);
+ GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer);
/***************************************************************************************
* Cursor management functionality
@@ -227,7 +227,7 @@ public:
* \param isDown The state of a modifier key (true == pressed).
* \return Indication of success.
*/
- virtual GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const;
+ GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const;
/**
* Returns the state of a mouse button (ouside the message queue).
@@ -235,7 +235,7 @@ public:
* \param isDown Button state.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const;
+ GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const;
/***************************************************************************************
* Other (internal) functionality.
@@ -247,28 +247,28 @@ public:
* Do not delete the event!
* \param event The event to push on the stack.
*/
- virtual GHOST_TSuccess pushEvent(GHOST_IEvent *event);
+ GHOST_TSuccess pushEvent(GHOST_IEvent *event);
/**
* \return The timer manager.
*/
- inline virtual GHOST_TimerManager *getTimerManager() const;
+ inline GHOST_TimerManager *getTimerManager() const;
/**
* \return A pointer to our event manager.
*/
- virtual inline GHOST_EventManager *getEventManager() const;
+ inline GHOST_EventManager *getEventManager() const;
/**
* \return A pointer to our window manager.
*/
- virtual inline GHOST_WindowManager *getWindowManager() const;
+ inline GHOST_WindowManager *getWindowManager() const;
#ifdef WITH_INPUT_NDOF
/**
* \return A pointer to our n-degree of freedom manager.
*/
- virtual inline GHOST_NDOFManager *getNDOFManager() const;
+ inline GHOST_NDOFManager *getNDOFManager() const;
#endif
/**
@@ -326,7 +326,7 @@ protected:
* \param window The window created.
* \return Indication of success.
*/
- virtual GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings,
+ GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings,
const bool stereoVisual, const GHOST_TUns16 numOfAASamples = 0);
/** The display manager (platform dependent). */
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index 9b30abe75d5..a86575abade 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -71,7 +71,7 @@ public:
* Based on ANSI clock() routine.
* \return The number of milliseconds.
*/
- virtual GHOST_TUns64 getMilliSeconds() const;
+ GHOST_TUns64 getMilliSeconds() const;
/***************************************************************************************
* Display/window management functionality
@@ -81,18 +81,18 @@ public:
* Returns the number of displays on this system.
* \return The number of displays.
*/
- virtual GHOST_TUns8 getNumDisplays() const;
+ GHOST_TUns8 getNumDisplays() const;
/**
* Returns the dimensions of the main display on this system.
* \return The dimension of the main display.
*/
- virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
+ void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
/** Returns the combine dimensions of all monitors.
* \return The dimension of the workspace.
*/
- virtual void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
+ void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
/**
* Create a new window.
@@ -110,7 +110,7 @@ public:
* \param parentWindow Parent (embedder) window
* \return The new window (or 0 if creation failed).
*/
- virtual GHOST_IWindow *createWindow(
+ GHOST_IWindow *createWindow(
const STR_String& title,
GHOST_TInt32 left,
GHOST_TInt32 top,
@@ -118,9 +118,8 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const bool stereoVisual = false,
- const bool exclusive = false,
- const GHOST_TUns16 numOfAASamples = 0,
+ GHOST_GLSettings glSettings,
+ const bool exclusive = false,
const GHOST_TEmbedderWindowID parentWindow = 0
);
@@ -133,7 +132,7 @@ public:
* \param waitForEvent Flag to wait for an event (or return immediately).
* \return Indication of the presence of events.
*/
- virtual bool processEvents(bool waitForEvent);
+ bool processEvents(bool waitForEvent);
/**
* Handle User request to quit, from Menu bar Quit, and Cmd+Q
@@ -169,7 +168,7 @@ public:
* \param y The y-coordinate of the cursor.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
+ GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
/**
* Updates the location of the cursor (location in screen coordinates).
@@ -177,7 +176,7 @@ public:
* \param y The y-coordinate of the cursor.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
+ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
/***************************************************************************************
* Access to mouse button and keyboard states.
@@ -188,28 +187,28 @@ public:
* \param keys The state of all modifier keys (true == pressed).
* \return Indication of success.
*/
- virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
+ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
/**
* Returns the state of the mouse buttons (ouside the message queue).
* \param buttons The state of the buttons.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
+ GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
/**
* Returns Clipboard data
* \param selection Indicate which buffer to return
* \return Returns the selected buffer
*/
- virtual GHOST_TUns8 *getClipboard(bool selection) const;
+ GHOST_TUns8 *getClipboard(bool selection) const;
/**
* Puts buffer to system clipboard
* \param buffer The buffer to be copied
* \param selection Indicates which buffer to copy too, only used on X11
*/
- virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
+ void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
/**
* Handles a window event. Called by GHOST_WindowCocoa window delegate
@@ -268,7 +267,7 @@ protected:
* For now, it just registers the window class (WNDCLASS).
* \return A success value.
*/
- virtual GHOST_TSuccess init();
+ GHOST_TSuccess init();
/**
* Performs the actual cursor position update (location in screen coordinates).
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 236002e9744..095c738e1e0 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -22,6 +22,7 @@
*
* Contributors: Maarten Gribnau 05/2001
* Damien Plisson 09/2009
+ * Jens Verwiebe 10/2014
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -56,6 +57,7 @@
#include "AssertMacros.h"
+
#pragma mark KeyMap, mouse converters
static GHOST_TButtonMask convertButton(int button)
@@ -203,6 +205,7 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
return GHOST_kKeyUnknown;
default:
+ {
/* alphanumerical or punctuation key that is remappable in int'l keyboards */
if ((recvChar >= 'A') && (recvChar <= 'Z')) {
return (GHOST_TKey) (recvChar - 'A' + GHOST_kKeyA);
@@ -211,27 +214,25 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
return (GHOST_TKey) (recvChar - 'a' + GHOST_kKeyA);
}
else {
-
- /* Leopard and Snow Leopard 64bit compatible API*/
- CFDataRef uchrHandle; /*the keyboard layout*/
- TISInputSourceRef kbdTISHandle;
-
- kbdTISHandle = TISCopyCurrentKeyboardLayoutInputSource();
- uchrHandle = (CFDataRef)TISGetInputSourceProperty(kbdTISHandle,kTISPropertyUnicodeKeyLayoutData);
- CFRelease(kbdTISHandle);
-
- /*get actual character value of the "remappable" keys in int'l keyboards,
- if keyboard layout is not correctly reported (e.g. some non Apple keyboards in Tiger),
- then fallback on using the received charactersIgnoringModifiers */
- if (uchrHandle)
- {
- UInt32 deadKeyState=0;
- UniCharCount actualStrLength=0;
+ /* Leopard and Snow Leopard 64bit compatible API*/
+ CFDataRef uchrHandle; /*the keyboard layout*/
+ TISInputSourceRef kbdTISHandle;
- UCKeyTranslate((UCKeyboardLayout*)CFDataGetBytePtr(uchrHandle), rawCode, keyAction, 0,
- LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &deadKeyState, 1, &actualStrLength, &recvChar);
+ kbdTISHandle = TISCopyCurrentKeyboardLayoutInputSource();
+ uchrHandle = (CFDataRef)TISGetInputSourceProperty(kbdTISHandle,kTISPropertyUnicodeKeyLayoutData);
+ CFRelease(kbdTISHandle);
- }
+ /*get actual character value of the "remappable" keys in int'l keyboards,
+ if keyboard layout is not correctly reported (e.g. some non Apple keyboards in Tiger),
+ then fallback on using the received charactersIgnoringModifiers */
+ if (uchrHandle) {
+ UInt32 deadKeyState=0;
+ UniCharCount actualStrLength=0;
+
+ UCKeyTranslate((UCKeyboardLayout*)CFDataGetBytePtr(uchrHandle), rawCode, keyAction, 0,
+ LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &deadKeyState, 1, &actualStrLength, &recvChar);
+
+ }
switch (recvChar) {
case '-': return GHOST_kKeyMinus;
@@ -249,10 +250,29 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
return GHOST_kKeyUnknown;
}
}
+ }
}
return GHOST_kKeyUnknown;
}
+#pragma mark Utility functions
+
+#define FIRSTFILEBUFLG 512
+static bool g_hasFirstFile = false;
+static char g_firstFileBuf[512];
+
+//TODO:Need to investigate this. Function called too early in creator.c to have g_hasFirstFile == true
+extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
+{
+ if (g_hasFirstFile) {
+ strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1);
+ buf[FIRSTFILEBUFLG - 1] = '\0';
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
#pragma mark Cocoa objects
@@ -313,8 +333,6 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
@end
-
-
#pragma mark initialization/finalization
GHOST_SystemCocoa::GHOST_SystemCocoa()
@@ -512,9 +530,8 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- bool stereoVisual,
+ GHOST_GLSettings glSettings,
const bool exclusive,
- const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow
)
{
@@ -533,7 +550,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
// Add contentRect.origin.y to respect docksize
bottom = bottom > contentRect.origin.y ? bottom + contentRect.origin.y : contentRect.origin.y;
- window = new GHOST_WindowCocoa (this, title, left, bottom, width, height, state, type, stereoVisual, numOfAASamples);
+ window = new GHOST_WindowCocoa (this, title, left, bottom, width, height, state, type, ((glSettings.flags & GHOST_glStereoVisual) != 0), glSettings.numOfAASamples);
if (window->getValid()) {
// Store the pointer to the window
@@ -636,7 +653,6 @@ GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const
}
-
#pragma mark Event handlers
/**
@@ -1573,7 +1589,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
}
-
#pragma mark Clipboard get/set
GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const
diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h
index 77a741c2efb..868416cd227 100644
--- a/intern/ghost/intern/GHOST_SystemNULL.h
+++ b/intern/ghost/intern/GHOST_SystemNULL.h
@@ -75,12 +75,12 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- bool stereoVisual,
+ GHOST_GLSettings glSettings,
bool exclusive,
- const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow)
{
- return new GHOST_WindowNULL(this, title, left, top, width, height, state, parentWindow, type, stereoVisual, 1);
+ return new GHOST_WindowNULL(this, title, left, top, width, height, state, parentWindow, type,
+ ((glSettings.flags & GHOST_glStereoVisual) != 0), 1);
}
};
diff --git a/intern/ghost/intern/GHOST_SystemPathsCocoa.h b/intern/ghost/intern/GHOST_SystemPathsCocoa.h
index cd8d161ff9c..1c76284857c 100644
--- a/intern/ghost/intern/GHOST_SystemPathsCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemPathsCocoa.h
@@ -57,20 +57,20 @@ public:
* "unpack and run" path, then look for properly installed path, including versioning.
* \return Unsigned char string pointing to system dir (eg /usr/share/blender/).
*/
- virtual const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const;
+ const GHOST_TUns8 *getSystemDir(int version, const char *versionstr) const;
/**
* Determine the base dir in which user configuration is stored, including versioning.
* If needed, it will create the base directory.
* \return Unsigned char string pointing to user dir (eg ~/.blender/).
*/
- virtual const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
+ const GHOST_TUns8 *getUserDir(int version, const char *versionstr) const;
/**
* Determine the directory of the current binary
* \return Unsigned char string pointing to the binary dir
*/
- virtual const GHOST_TUns8 *getBinaryDir() const;
+ const GHOST_TUns8 *getBinaryDir() const;
/**
* Add the file to the operating system most recently used files
diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.h b/intern/ghost/intern/GHOST_SystemPathsWin32.h
index c074a7902b8..b63d20bfcbd 100644
--- a/intern/ghost/intern/GHOST_SystemPathsWin32.h
+++ b/intern/ghost/intern/GHOST_SystemPathsWin32.h
@@ -60,7 +60,7 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_SystemPathsWin32();
+ ~GHOST_SystemPathsWin32();
/**
* Determine the base dir in which shared resources are located. It will first try to use
diff --git a/intern/ghost/intern/GHOST_SystemPathsX11.h b/intern/ghost/intern/GHOST_SystemPathsX11.h
index 1b5710e0f57..23cc2e4b104 100644
--- a/intern/ghost/intern/GHOST_SystemPathsX11.h
+++ b/intern/ghost/intern/GHOST_SystemPathsX11.h
@@ -48,7 +48,7 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_SystemPathsX11();
+ ~GHOST_SystemPathsX11();
/**
* Determine the base dir in which shared resources are located. It will first try to use
diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp
index 1d2401e6f71..8561dbfd639 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.cpp
+++ b/intern/ghost/intern/GHOST_SystemSDL.cpp
@@ -67,9 +67,8 @@ GHOST_SystemSDL::createWindow(const STR_String& title,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const bool stereoVisual,
+ GHOST_GLSettings glSettings,
const bool exclusive,
- const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow
)
{
@@ -78,8 +77,8 @@ GHOST_SystemSDL::createWindow(const STR_String& title,
window = new GHOST_WindowSDL(this, title,
left, top, width, height,
state, parentWindow, type,
- stereoVisual, exclusive,
- numOfAASamples);
+ ((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive,
+ glSettings.numOfAASamples);
if (window) {
if (GHOST_kWindowStateFullScreen == state) {
diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h
index 5ad4fe09833..6f4ecec586b 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.h
+++ b/intern/ghost/intern/GHOST_SystemSDL.h
@@ -108,9 +108,8 @@ private:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const bool stereoVisual,
+ GHOST_GLSettings glSettings,
const bool exclusive = false,
- const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0
);
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 0767ad5a8f9..27eb387e9f8 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -31,11 +31,6 @@
* \author Maarten Gribnau
*/
-#ifdef WITH_GHOST_DEBUG
-# include <iostream>
-#endif
-
-#include <stdio.h> // [mce] temporary debug, remove soon!
#include "GHOST_SystemWin32.h"
#include "GHOST_EventDragnDrop.h"
@@ -152,7 +147,7 @@ static void initRawInput()
if (RegisterRawInputDevices(devices, DEVICE_COUNT, sizeof(RAWINPUTDEVICE)))
; // yay!
else
- printf("could not register for RawInput: %d\n", (int)GetLastError());
+ GHOST_PRINTF("could not register for RawInput: %d\n", (int)GetLastError());
#undef DEVICE_COUNT
}
@@ -231,12 +226,11 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(
GHOST_TInt32 left, GHOST_TInt32 top,
GHOST_TUns32 width, GHOST_TUns32 height,
GHOST_TWindowState state, GHOST_TDrawingContextType type,
- bool wantStereoVisual,
+ GHOST_GLSettings glSettings,
const bool exclusive,
- const GHOST_TUns16 wantNumOfAASamples,
const GHOST_TEmbedderWindowID parentWindow)
{
- GHOST_Window *window =
+ GHOST_WindowWin32 *window =
new GHOST_WindowWin32(
this,
title,
@@ -246,8 +240,9 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(
height,
state,
type,
- wantStereoVisual,
- wantNumOfAASamples,
+ ((glSettings.flags & GHOST_glStereoVisual) != 0),
+ ((glSettings.flags & GHOST_glWarnSupport) != 0),
+ glSettings.numOfAASamples,
parentWindow);
if (window->getValid()) {
@@ -432,7 +427,7 @@ GHOST_TSuccess GHOST_SystemWin32::exit()
return GHOST_System::exit();
}
-GHOST_TKey GHOST_SystemWin32::hardKey(GHOST_IWindow *window, RAWINPUT const &raw, int *keyDown, char *vk)
+GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, int *keyDown, char *vk)
{
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
GHOST_TKey key = GHOST_kKeyUnknown;
@@ -444,7 +439,7 @@ GHOST_TKey GHOST_SystemWin32::hardKey(GHOST_IWindow *window, RAWINPUT const &raw
unsigned int msg = raw.data.keyboard.Message;
*keyDown = !(raw.data.keyboard.Flags & RI_KEY_BREAK) && msg != WM_KEYUP && msg != WM_SYSKEYUP;
- key = this->convertKey(window, raw.data.keyboard.VKey, raw.data.keyboard.MakeCode, (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0)));
+ key = this->convertKey(raw.data.keyboard.VKey, raw.data.keyboard.MakeCode, (raw.data.keyboard.Flags & (RI_KEY_E1 | RI_KEY_E0)));
// extra handling of modifier keys: don't send repeats out from GHOST
if (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt) {
@@ -508,19 +503,24 @@ GHOST_TKey GHOST_SystemWin32::hardKey(GHOST_IWindow *window, RAWINPUT const &raw
//! note: this function can be extended to include other exotic cases as they arise.
// This function was added in response to bug [#25715]
-GHOST_TKey GHOST_SystemWin32::processSpecialKey(GHOST_IWindow *window, short vKey, short scanCode) const
+// This is going to be a long list [T42426]
+GHOST_TKey GHOST_SystemWin32::processSpecialKey(short vKey, short scanCode) const
{
GHOST_TKey key = GHOST_kKeyUnknown;
switch (PRIMARYLANGID(m_langId)) {
case LANG_FRENCH:
if (vKey == VK_OEM_8) key = GHOST_kKeyF13; // oem key; used purely for shortcuts .
break;
+ case LANG_ENGLISH:
+ if (SUBLANGID(m_langId) == SUBLANG_ENGLISH_UK && vKey == VK_OEM_8) // "`¬"
+ key = GHOST_kKeyAccentGrave;
+ break;
}
return key;
}
-GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, short vKey, short scanCode, short extend) const
+GHOST_TKey GHOST_SystemWin32::convertKey(short vKey, short scanCode, short extend) const
{
GHOST_TKey key;
@@ -628,7 +628,7 @@ GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, short vKey, shor
case VK_SCROLL: key = GHOST_kKeyScrollLock; break;
case VK_CAPITAL: key = GHOST_kKeyCapsLock; break;
case VK_OEM_8:
- key = ((GHOST_SystemWin32 *)getSystem())->processSpecialKey(window, vKey, scanCode);
+ key = ((GHOST_SystemWin32 *)getSystem())->processSpecialKey(vKey, scanCode);
break;
case VK_MEDIA_PLAY_PAUSE: key = GHOST_kKeyMediaPlay; break;
case VK_MEDIA_STOP: key = GHOST_kKeyMediaStop; break;
@@ -645,18 +645,17 @@ GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, short vKey, shor
GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(
GHOST_TEventType type,
- GHOST_IWindow *window,
+ GHOST_WindowWin32 *window,
GHOST_TButtonMask mask)
{
return new GHOST_EventButton(getSystem()->getMilliSeconds(), type, window, mask);
}
-GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, GHOST_IWindow *Iwindow)
+GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type, GHOST_WindowWin32 *window)
{
GHOST_TInt32 x_screen, y_screen;
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *) getSystem();
- GHOST_WindowWin32 *window = (GHOST_WindowWin32 *) Iwindow;
system->getCursorPosition(x_screen, y_screen);
@@ -708,7 +707,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_TEventType type,
}
-GHOST_EventWheel *GHOST_SystemWin32::processWheelEvent(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam)
+GHOST_EventWheel *GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam)
{
// short fwKeys = LOWORD(wParam); // key flags
int zDelta = (short) HIWORD(wParam); // wheel rotation
@@ -723,12 +722,12 @@ GHOST_EventWheel *GHOST_SystemWin32::processWheelEvent(GHOST_IWindow *window, WP
}
-GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINPUT const &raw)
+GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw)
{
int keyDown = 0;
char vk;
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- GHOST_TKey key = system->hardKey(window, raw, &keyDown, &vk);
+ GHOST_TKey key = system->hardKey(raw, &keyDown, &vk);
GHOST_EventKey *event;
if (key != GHOST_kKeyUnknown) {
@@ -763,10 +762,8 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINP
}
event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, key, ascii, utf8_char);
-
-#ifdef GHOST_DEBUG
- std::cout << ascii << std::endl;
-#endif
+
+ // GHOST_PRINTF("%c\n", ascii); // we already get this info via EventPrinter
}
else {
event = 0;
@@ -775,26 +772,35 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINP
}
-GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_IWindow *window)
+GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window)
{
- GHOST_System *system = (GHOST_System *)getSystem();
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
if (type == GHOST_kEventWindowActivate) {
system->getWindowManager()->setActiveWindow(window);
- ((GHOST_WindowWin32 *)window)->bringTabletContextToFront();
+ window->bringTabletContextToFront();
}
return new GHOST_Event(system->getMilliSeconds(), type, window);
}
+#ifdef WITH_INPUT_IME
+GHOST_Event *GHOST_SystemWin32::processImeEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TEventImeData *data)
+{
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ return new GHOST_EventIME(system->getMilliSeconds(), type, window, data);
+}
+#endif
+
+
GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(
GHOST_TEventType eventType,
GHOST_TDragnDropTypes draggedObjectType,
- GHOST_IWindow *window,
+ GHOST_WindowWin32 *window,
int mouseX, int mouseY,
void *data)
{
- GHOST_SystemWin32 *system = ((GHOST_SystemWin32 *)getSystem());
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
return system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
eventType,
draggedObjectType,
@@ -824,7 +830,7 @@ bool GHOST_SystemWin32::processNDOF(RAWINPUT const &raw)
if (info.dwType == RIM_TYPEHID)
m_ndofManager->setDevice(info.hid.dwVendorId, info.hid.dwProductId);
else
- puts("<!> not a HID device... mouse/kb perhaps?");
+ GHOST_PRINT("<!> not a HID device... mouse/kb perhaps?\n");
firstEvent = false;
}
@@ -869,7 +875,7 @@ bool GHOST_SystemWin32::processNDOF(RAWINPUT const &raw)
m_ndofManager->updateRotation(r, now);
// I've never gotten one of these, has anyone else?
- puts("ndof: combined T + R");
+ GHOST_PRINT("ndof: combined T + R\n");
}
break;
}
@@ -898,7 +904,8 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
bool eventHandled = false;
LRESULT lResult = 0;
- GHOST_SystemWin32 *system = ((GHOST_SystemWin32 *)getSystem());
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+ GHOST_EventManager *eventManager = system->getEventManager();
GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized");
if (hwnd) {
@@ -907,8 +914,13 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
switch (msg) {
// we need to check if new key layout has AltGr
case WM_INPUTLANGCHANGE:
+ {
system->handleKeyboardChange();
+#ifdef WITH_INPUT_IME
+ window->getImeInput()->SetInputLanguage();
+#endif
break;
+ }
////////////////////////////////////////////////////////////////////////
// Keyboard events, processed
////////////////////////////////////////////////////////////////////////
@@ -944,6 +956,60 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
}
break;
}
+#ifdef WITH_INPUT_IME
+ ////////////////////////////////////////////////////////////////////////
+ // IME events, processed, read more in GHOST_IME.h
+ ////////////////////////////////////////////////////////////////////////
+ case WM_IME_SETCONTEXT:
+ {
+ GHOST_ImeWin32 *ime = window->getImeInput();
+ ime->SetInputLanguage();
+ ime->CreateImeWindow(hwnd);
+ ime->CleanupComposition(hwnd);
+ ime->CheckFirst(hwnd);
+ break;
+ }
+ case WM_IME_STARTCOMPOSITION:
+ {
+ GHOST_ImeWin32 *ime = window->getImeInput();
+ eventHandled = true;
+ /* remove input event before start comp event, avoid redundant input */
+ eventManager->removeTypeEvents(GHOST_kEventKeyDown, window);
+ ime->CreateImeWindow(hwnd);
+ ime->ResetComposition(hwnd);
+ event = processImeEvent(
+ GHOST_kEventImeCompositionStart,
+ window,
+ &ime->eventImeData);
+ break;
+ }
+ case WM_IME_COMPOSITION:
+ {
+ GHOST_ImeWin32 *ime = window->getImeInput();
+ eventHandled = true;
+ ime->UpdateImeWindow(hwnd);
+ ime->UpdateInfo(hwnd);
+ event = processImeEvent(
+ GHOST_kEventImeComposition,
+ window,
+ &ime->eventImeData);
+ break;
+ }
+ case WM_IME_ENDCOMPOSITION:
+ {
+ GHOST_ImeWin32 *ime = window->getImeInput();
+ eventHandled = true;
+ /* remove input event after end comp event, avoid redundant input */
+ eventManager->removeTypeEvents(GHOST_kEventKeyDown, window);
+ ime->ResetComposition(hwnd);
+ ime->DestroyImeWindow(hwnd);
+ event = processImeEvent(
+ GHOST_kEventImeCompositionEnd,
+ window,
+ &ime->eventImeData);
+ break;
+ }
+#endif /* WITH_INPUT_IME */
////////////////////////////////////////////////////////////////////////
// Keyboard events, ignored
////////////////////////////////////////////////////////////////////////
@@ -994,11 +1060,11 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
// Tablet events, processed
////////////////////////////////////////////////////////////////////////
case WT_PACKET:
- ((GHOST_WindowWin32 *)window)->processWin32TabletEvent(wParam, lParam);
+ window->processWin32TabletEvent(wParam, lParam);
break;
case WT_CSRCHANGE:
case WT_PROXIMITY:
- ((GHOST_WindowWin32 *)window)->processWin32TabletInitEvent();
+ window->processWin32TabletInitEvent();
break;
////////////////////////////////////////////////////////////////////////
// Mouse events, processed
@@ -1058,19 +1124,15 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* until it finds a window that processes it.
*/
- /* Get the winow under the mouse and send event to it's queue. */
+ /* Get the window under the mouse and send event to its queue. */
POINT mouse_pos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
- HWND mouse_hwnd = WindowFromPoint(mouse_pos);
+ HWND mouse_hwnd = ChildWindowFromPoint(HWND_DESKTOP, mouse_pos);
GHOST_WindowWin32 *mouse_window = (GHOST_WindowWin32 *)::GetWindowLongPtr(mouse_hwnd, GWLP_USERDATA);
if (mouse_window != NULL) {
event = processWheelEvent(mouse_window, wParam, lParam);
}
else {
- /* If it happened so window under the mouse is not found (which i'm not
- * really sure might happen), then we add event to the focused window
- * in order to avoid some possible negative side effects.
- * - sergey -
- */
+ /* Happens when mouse is not over any of blender's windows. */
event = processWheelEvent(window, wParam, lParam);
}
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 79fed06c6a5..e615ef164c8 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -53,6 +53,8 @@ class GHOST_EventWheel;
class GHOST_EventWindow;
class GHOST_EventDragnDrop;
+class GHOST_WindowWin32;
+
/**
* WIN32 Implementation of GHOST_System class.
* \see GHOST_System.
@@ -69,7 +71,7 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_SystemWin32();
+ ~GHOST_SystemWin32();
/***************************************************************************************
** Time(r) functionality
@@ -81,7 +83,7 @@ public:
* This overloaded method uses the high frequency timer if available.
* \return The number of milliseconds.
*/
- virtual GHOST_TUns64 getMilliSeconds() const;
+ GHOST_TUns64 getMilliSeconds() const;
/***************************************************************************************
** Display/window management functionality
@@ -91,19 +93,19 @@ public:
* Returns the number of displays on this system.
* \return The number of displays.
*/
- virtual GHOST_TUns8 getNumDisplays() const;
+ GHOST_TUns8 getNumDisplays() const;
/**
* Returns the dimensions of the main display on this system.
* \return The dimension of the main display.
*/
- virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
+ void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
/**
* Returns the dimensions of all displays on this system.
* \return The dimension of the main display.
*/
- virtual void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
+ void getAllDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
/**
* Create a new window.
@@ -121,13 +123,12 @@ public:
* \param parentWindow Parent (embedder) window
* \return The new window (or 0 if creation failed).
*/
- virtual GHOST_IWindow *createWindow(
+ GHOST_IWindow *createWindow(
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 = false,
- const bool exclusive = false,
- const GHOST_TUns16 numOfAASamples = 0,
+ GHOST_GLSettings glSettings,
+ const bool exclusive = false,
const GHOST_TEmbedderWindowID parentWindow = 0);
/***************************************************************************************
@@ -139,7 +140,7 @@ public:
* \param waitForEvent Flag to wait for an event (or return immediately).
* \return Indication of the presence of events.
*/
- virtual bool processEvents(bool waitForEvent);
+ bool processEvents(bool waitForEvent);
/***************************************************************************************
@@ -152,7 +153,7 @@ public:
* \param y The y-coordinate of the cursor.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
+ GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
/**
* Updates the location of the cursor (location in screen coordinates).
@@ -160,7 +161,7 @@ public:
* \param y The y-coordinate of the cursor.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
+ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
/***************************************************************************************
** Access to mouse button and keyboard states.
@@ -171,28 +172,28 @@ public:
* \param keys The state of all modifier keys (true == pressed).
* \return Indication of success.
*/
- virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
+ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
/**
* Returns the state of the mouse buttons (ouside the message queue).
* \param buttons The state of the buttons.
* \return Indication of success.
*/
- virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
+ GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
/**
* Returns unsinged char from CUT_BUFFER0
* \param selection Used by X11 only
* \return Returns the Clipboard
*/
- virtual GHOST_TUns8 *getClipboard(bool selection) const;
+ GHOST_TUns8 *getClipboard(bool selection) const;
/**
* Puts buffer to system clipboard
* \param selection Used by X11 only
* \return No return
*/
- virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
+ void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
/**
* Creates a drag'n'drop event and pushes it immediately onto the event queue.
@@ -204,13 +205,13 @@ public:
* \param window The window on which the event occurred
* \return Indication whether the event was handled.
*/
- static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_IWindow *window, int mouseX, int mouseY, void *data);
+ static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType, GHOST_WindowWin32 *window, int mouseX, int mouseY, void *data);
/**
* Confirms quitting he program when there is just one window left open
* in the application
*/
- virtual int confirmQuit(GHOST_IWindow *window) const;
+ int confirmQuit(GHOST_IWindow *window) const;
protected:
/**
@@ -218,42 +219,31 @@ protected:
* For now, it just registers the window class (WNDCLASS).
* \return A success value.
*/
- virtual GHOST_TSuccess init();
+ GHOST_TSuccess init();
/**
* Closes the system down.
* \return A success value.
*/
- virtual GHOST_TSuccess exit();
+ GHOST_TSuccess exit();
/**
* Converts raw WIN32 key codes from the wndproc to GHOST keys.
- * \param window-> The window for this handling
* \param vKey The virtual key from hardKey
- * \param ScanCode The ScanCode of pressed key (simular to PS/2 Set 1)
+ * \param ScanCode The ScanCode of pressed key (similar to PS/2 Set 1)
* \param extend Flag if key is not primly (left or right)
* \return The GHOST key (GHOST_kKeyUnknown if no match).
*/
- virtual GHOST_TKey convertKey(GHOST_IWindow *window, short vKey, short ScanCode, short extend) const;
+ GHOST_TKey convertKey(short vKey, short ScanCode, short extend) const;
/**
* Catches raw WIN32 key codes from WM_INPUT in the wndproc.
- * \param window The window for this handling
* \param raw RawInput structure with detailed info about the key event
* \param keyDown Pointer flag that specify if a key is down
* \param vk Pointer to virtual key
* \return The GHOST key (GHOST_kKeyUnknown if no match).
*/
- virtual GHOST_TKey hardKey(GHOST_IWindow *window, RAWINPUT const& raw, int *keyDown, char *vk);
-
- /**
- * Creates modifier key event(s) and updates the key data stored locally (m_modifierKeys).
- * With the modifier keys, we want to distinguish left and right keys.
- * Sometimes this is not possible (Windows ME for instance). Then, we want
- * events generated for both keys.
- * \param window The window receiving the event (the active window).
- */
- GHOST_EventKey *processModifierKeys(GHOST_IWindow *window);
+ GHOST_TKey hardKey(RAWINPUT const& raw, int *keyDown, char *vk);
/**
* Creates mouse button event.
@@ -262,7 +252,7 @@ protected:
* \param mask The button mask of this event.
* \return The event created.
*/
- static GHOST_EventButton *processButtonEvent(GHOST_TEventType type, GHOST_IWindow *window, GHOST_TButtonMask mask);
+ static GHOST_EventButton *processButtonEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TButtonMask mask);
/**
* Creates cursor event.
@@ -270,7 +260,7 @@ protected:
* \param window The window receiving the event (the active window).
* \return The event created.
*/
- static GHOST_EventCursor *processCursorEvent(GHOST_TEventType type, GHOST_IWindow *Iwindow);
+ static GHOST_EventCursor *processCursorEvent(GHOST_TEventType type, GHOST_WindowWin32 *window);
/**
* Creates a mouse wheel event.
@@ -278,7 +268,7 @@ protected:
* \param wParam The wParam from the wndproc
* \param lParam The lParam from the wndproc
*/
- static GHOST_EventWheel *processWheelEvent(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam);
+ static GHOST_EventWheel *processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam);
/**
* Creates a key event and updates the key data stored locally (m_modifierKeys).
@@ -287,16 +277,15 @@ protected:
* \param window The window receiving the event (the active window).
* \param raw RawInput structure with detailed info about the key event
*/
- static GHOST_EventKey *processKeyEvent(GHOST_IWindow *window, RAWINPUT const& raw);
+ static GHOST_EventKey *processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const& raw);
/**
* Process special keys (VK_OEM_*), to see if current key layout
* gives us anything special, like ! on french AZERTY.
- * \param window The window receiving the event (the active window).
* \param vKey The virtual key from hardKey
* \param ScanCode The ScanCode of pressed key (simular to PS/2 Set 1)
*/
- virtual GHOST_TKey processSpecialKey(GHOST_IWindow *window, short vKey, short scanCode) const;
+ GHOST_TKey processSpecialKey(short vKey, short scanCode) const;
/**
* Creates a window event.
@@ -304,7 +293,18 @@ protected:
* \param window The window receiving the event (the active window).
* \return The event created.
*/
- static GHOST_Event *processWindowEvent(GHOST_TEventType type, GHOST_IWindow *window);
+ static GHOST_Event *processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window);
+
+#ifdef WITH_INPUT_IME
+ /**
+ * Creates a IME event.
+ * \param type The type of event to create.
+ * \param window The window receiving the event (the active window).
+ * \param data IME data.
+ * \return The event created.
+ */
+ static GHOST_Event *processImeEvent(GHOST_TEventType type, GHOST_WindowWin32 *window, GHOST_TEventImeData *data);
+#endif // WITH_INPUT_IME
/**
* Handles minimum window size.
@@ -327,19 +327,19 @@ protected:
* Returns the local state of the modifier keys (from the message queue).
* \param keys The state of the keys.
*/
- inline virtual void retrieveModifierKeys(GHOST_ModifierKeys& keys) const;
+ inline void retrieveModifierKeys(GHOST_ModifierKeys& keys) const;
/**
* Stores the state of the modifier keys locally.
* For internal use only!
* param keys The new state of the modifier keys.
*/
- inline virtual void storeModifierKeys(const GHOST_ModifierKeys& keys);
+ inline void storeModifierKeys(const GHOST_ModifierKeys& keys);
/**
* Check current key layout for AltGr
*/
- inline virtual void handleKeyboardChange(void);
+ inline void handleKeyboardChange(void);
/**
* Windows call back routine for our window class.
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 75a9223d6a3..241ce9728cc 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -32,6 +32,11 @@
* \ingroup GHOST
*/
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include <X11/XKBlib.h> /* allow detectable autorepeate */
+#include <X11/Xutil.h>
+
#include "GHOST_SystemX11.h"
#include "GHOST_WindowX11.h"
#include "GHOST_WindowManager.h"
@@ -52,11 +57,6 @@
#include "GHOST_Debug.h"
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-#include <X11/XKBlib.h> /* allow detectable autorepeate */
-#include <X11/Xutil.h>
-
#ifdef WITH_XF86KEYSYM
#include <X11/XF86keysym.h>
#endif
@@ -289,31 +289,26 @@ getAllDisplayDimensions(
*/
GHOST_IWindow *
GHOST_SystemX11::
-createWindow(
- const STR_String& title,
+createWindow(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,
+ GHOST_GLSettings glSettings,
const bool exclusive,
- const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow)
{
GHOST_WindowX11 *window = 0;
if (!m_display) return 0;
-
-
-
window = new GHOST_WindowX11(this, m_display, title,
left, top, width, height,
state, parentWindow, type,
- stereoVisual, exclusive,
- numOfAASamples);
+ ((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive,
+ glSettings.numOfAASamples);
if (window) {
/* Both are now handle in GHOST_WindowX11.cpp
@@ -1181,7 +1176,11 @@ GHOST_SystemX11::processEvent(XEvent *xe)
default:
{
#ifdef WITH_X11_XINPUT
- if (xe->type == m_xtablet.MotionEvent) {
+ if (xe->type == m_xtablet.MotionEvent ||
+ xe->type == m_xtablet.MotionEventEraser ||
+ xe->type == m_xtablet.PressEvent ||
+ xe->type == m_xtablet.PressEventEraser)
+ {
XDeviceMotionEvent *data = (XDeviceMotionEvent *)xe;
const unsigned char axis_first = data->first_axis;
const unsigned char axes_end = axis_first + data->axes_count; /* after the last */
@@ -1874,8 +1873,11 @@ GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType,
}
#endif
-#ifdef WITH_X11_XINPUT
-/*
+#if defined(USE_X11_ERROR_HANDLERS) || defined(WITH_X11_XINPUT)
+/*
+ * These callbacks can be used for debugging, so we can breakpoint on an X11 error.
+
+ *
* Dummy function to get around IO Handler exiting if device invalid
* Basically it will not crash blender now if you have a X device that
* is configured but not plugged in.
@@ -1896,7 +1898,9 @@ int GHOST_X11_ApplicationIOErrorHandler(Display *display)
/* No exit! - but keep lint happy */
return 0;
}
+#endif
+#ifdef WITH_X11_XINPUT
/* These C functions are copied from Wine 1.1.13's wintab.c */
#define BOOL int
#define TRUE 1
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index be149cbb773..4004bda11cb 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -75,7 +75,7 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_SystemX11();
+ ~GHOST_SystemX11();
GHOST_TSuccess
@@ -151,9 +151,8 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- const bool stereoVisual,
+ GHOST_GLSettings glSettings,
const bool exclusive = false,
- const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0
);
@@ -286,6 +285,12 @@ public:
int MotionEvent;
int ProxInEvent;
int ProxOutEvent;
+ int PressEvent;
+
+ int MotionEventEraser;
+ int ProxInEventEraser;
+ int ProxOutEventEraser;
+ int PressEventEraser;
int PressureLevels;
int XtiltLevels, YtiltLevels;
diff --git a/intern/ghost/intern/GHOST_TimerManager.h b/intern/ghost/intern/GHOST_TimerManager.h
index b94175e9ff8..6cf4bcf40eb 100644
--- a/intern/ghost/intern/GHOST_TimerManager.h
+++ b/intern/ghost/intern/GHOST_TimerManager.h
@@ -58,19 +58,19 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_TimerManager();
+ ~GHOST_TimerManager();
/**
* Returns the number of timer tasks.
* \return The number of events on the stack.
*/
- virtual GHOST_TUns32 getNumTimers();
+ GHOST_TUns32 getNumTimers();
/**
* Returns whether this timer task ins in our list.
* \return Indication of presence.
*/
- virtual bool getTimerFound(GHOST_TimerTask *timer);
+ bool getTimerFound(GHOST_TimerTask *timer);
/**
* Adds a timer task to the list.
@@ -78,7 +78,7 @@ public:
* \param timer The timer task added to the list.
* \return Indication as to whether addition has succeeded.
*/
- virtual GHOST_TSuccess addTimer(GHOST_TimerTask *timer);
+ GHOST_TSuccess addTimer(GHOST_TimerTask *timer);
/**
* Removes a timer task from the list.
@@ -86,21 +86,21 @@ public:
* \param timer The timer task to be removed from the list.
* \return Indication as to whether removal has succeeded.
*/
- virtual GHOST_TSuccess removeTimer(GHOST_TimerTask *timer);
+ GHOST_TSuccess removeTimer(GHOST_TimerTask *timer);
/**
* Finds the soonest time the next timer would fire.
* \return The soonest time the next timer would fire,
* or GHOST_kFireTimeNever if no timers exist.
*/
- virtual GHOST_TUns64 nextFireTime();
+ GHOST_TUns64 nextFireTime();
/**
* Checks all timer tasks to see if they are expired and fires them if needed.
* \param time The current time.
* \return True if any timers were fired.
*/
- virtual bool fireTimers(GHOST_TUns64 time);
+ bool fireTimers(GHOST_TUns64 time);
/**
* Checks this timer task to see if they are expired and fires them if needed.
@@ -108,7 +108,7 @@ public:
* \param task The timer task to check and optionally fire.
* \return True if the timer fired.
*/
- virtual bool fireTimer(GHOST_TUns64 time, GHOST_TimerTask *task);
+ bool fireTimer(GHOST_TUns64 time, GHOST_TimerTask *task);
protected:
/**
diff --git a/intern/ghost/intern/GHOST_TimerTask.h b/intern/ghost/intern/GHOST_TimerTask.h
index e33788ec826..201ed144712 100644
--- a/intern/ghost/intern/GHOST_TimerTask.h
+++ b/intern/ghost/intern/GHOST_TimerTask.h
@@ -68,7 +68,7 @@ public:
* Returns the timer start time.
* \return The timer start time.
*/
- inline virtual GHOST_TUns64 getStart() const
+ inline GHOST_TUns64 getStart() const
{
return m_start;
}
@@ -77,7 +77,7 @@ public:
* Changes the timer start time.
* \param start The timer start time.
*/
- virtual void setStart(GHOST_TUns64 start)
+ void setStart(GHOST_TUns64 start)
{
m_start = start;
}
@@ -86,7 +86,7 @@ public:
* Returns the timer interval.
* \return The timer interval.
*/
- inline virtual GHOST_TUns64 getInterval() const
+ inline GHOST_TUns64 getInterval() const
{
return m_interval;
}
@@ -95,7 +95,7 @@ public:
* Changes the timer interval.
* \param interval The timer interval.
*/
- virtual void setInterval(GHOST_TUns64 interval)
+ void setInterval(GHOST_TUns64 interval)
{
m_interval = interval;
}
@@ -104,7 +104,7 @@ public:
* Returns the time the timerProc will be called.
* \return The time the timerProc will be called.
*/
- inline virtual GHOST_TUns64 getNext() const
+ inline GHOST_TUns64 getNext() const
{
return m_next;
}
@@ -113,7 +113,7 @@ public:
* Changes the time the timerProc will be called.
* \param next The time the timerProc will be called.
*/
- virtual void setNext(GHOST_TUns64 next)
+ void setNext(GHOST_TUns64 next)
{
m_next = next;
}
@@ -122,7 +122,7 @@ public:
* Returns the timer callback.
* \return the timer callback.
*/
- inline virtual GHOST_TimerProcPtr getTimerProc() const
+ inline GHOST_TimerProcPtr getTimerProc() const
{
return m_timerProc;
}
@@ -131,7 +131,7 @@ public:
* Changes the timer callback.
* \param The timer callback.
*/
- inline virtual void setTimerProc(const GHOST_TimerProcPtr timerProc)
+ inline void setTimerProc(const GHOST_TimerProcPtr timerProc)
{
m_timerProc = timerProc;
}
@@ -140,7 +140,7 @@ public:
* Returns the timer user data.
* \return The timer user data.
*/
- inline virtual GHOST_TUserDataPtr getUserData() const
+ inline GHOST_TUserDataPtr getUserData() const
{
return m_userData;
}
@@ -149,7 +149,7 @@ public:
* Changes the time user data.
* \param data The timer user data.
*/
- virtual void setUserData(const GHOST_TUserDataPtr userData)
+ void setUserData(const GHOST_TUserDataPtr userData)
{
m_userData = userData;
}
@@ -158,7 +158,7 @@ public:
* Returns the auxiliary storage room.
* \return The auxiliary storage room.
*/
- inline virtual GHOST_TUns32 getAuxData() const
+ inline GHOST_TUns32 getAuxData() const
{
return m_auxData;
}
@@ -167,7 +167,7 @@ public:
* Changes the auxiliary storage room.
* \param auxData The auxiliary storage room.
*/
- virtual void setAuxData(GHOST_TUns32 auxData)
+ void setAuxData(GHOST_TUns32 auxData)
{
m_auxData = auxData;
}
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index e470e40d43a..b78a690fcad 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -119,14 +119,14 @@ public:
* Returns the current cursor shape.
* \return The current cursor shape.
*/
- inline virtual GHOST_TStandardCursor getCursorShape() const;
+ inline GHOST_TStandardCursor getCursorShape() const;
/**
* Set the shape of the cursor.
* \param cursor The new cursor shape type id.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape);
+ GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape);
/**
* Set the shape of the cursor to a custom cursor.
@@ -136,47 +136,47 @@ public:
* \param hotY The Y coordinate of the cursor hotspot.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 bitmap[16][2],
- GHOST_TUns8 mask[16][2],
- int hotX,
- int hotY);
-
- virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
- GHOST_TUns8 *mask,
- int sizex, int sizey,
- int hotX, int hotY,
- int fg_color, int bg_color);
-
+ GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TUns8 mask[16][2],
+ int hotX,
+ int hotY);
+
+ GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
+ GHOST_TUns8 *mask,
+ int sizex, int sizey,
+ int hotX, int hotY,
+ int fg_color, int bg_color);
+
/**
* Returns the visibility state of the cursor.
* \return The visibility state of the cursor.
*/
- inline virtual bool getCursorVisibility() const;
- inline virtual GHOST_TGrabCursorMode getCursorGrabMode() const;
- inline virtual bool getCursorGrabModeIsWarp() const;
- inline virtual void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
- inline virtual void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
- inline virtual void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y);
+ inline bool getCursorVisibility() const;
+ inline GHOST_TGrabCursorMode getCursorGrabMode() const;
+ inline bool getCursorGrabModeIsWarp() const;
+ inline void getCursorGrabInitPos(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
+ inline void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const;
+ inline void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y);
/**
* Shows or hides the cursor.
* \param visible The new visibility state of the cursor.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setCursorVisibility(bool visible);
+ GHOST_TSuccess setCursorVisibility(bool visible);
/**
* Sets the cursor grab.
* \param mode The new grab state of the cursor.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]);
+ GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]);
/**
* Gets the cursor grab region, if unset the window is used.
* reset when grab is disabled.
*/
- virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect& bounds);
+ GHOST_TSuccess getCursorGrabBounds(GHOST_Rect& bounds);
/**
* Sets the progress bar value displayed in the window/application icon
@@ -198,30 +198,30 @@ public:
* \param interval The swap interval to use.
* \return A boolean success indicator.
*/
- virtual GHOST_TSuccess setSwapInterval(int interval);
+ GHOST_TSuccess setSwapInterval(int interval);
/**
* Gets the current swap interval for swapBuffers.
* \return An integer.
*/
- virtual GHOST_TSuccess getSwapInterval(int& intervalOut);
+ GHOST_TSuccess getSwapInterval(int& intervalOut);
/**
* Gets the current swap interval for swapBuffers.
* \return Number of AA Samples (0 if there is no multisample buffer)
*/
- virtual GHOST_TUns16 getNumOfAASamples();
+ GHOST_TUns16 getNumOfAASamples();
/**
* Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
*/
- virtual void setAcceptDragOperation(bool canAccept);
+ void setAcceptDragOperation(bool canAccept);
/**
* Returns acceptance of the dropped object
* Usually called by the "object dropped" event handling function
*/
- virtual bool canAcceptDragOperation() const;
+ bool canAcceptDragOperation() const;
/**
* Sets the window "modified" status, indicating unsaved changes
@@ -240,7 +240,7 @@ public:
* Returns the type of drawing context used in this window.
* \return The current type of drawing context.
*/
- inline virtual GHOST_TDrawingContextType getDrawingContextType();
+ inline GHOST_TDrawingContextType getDrawingContextType();
/**
* Tries to install a rendering context in this window.
@@ -249,7 +249,7 @@ public:
* \param type The type of rendering context installed.
* \return Indication as to whether installation has succeeded.
*/
- virtual GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type);
+ GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type);
/**
* Swaps front and back buffers of a window.
@@ -268,13 +268,13 @@ public:
* whenever the window is changed.
* \return Indication of success.
*/
- virtual GHOST_TSuccess updateDrawingContext();
+ GHOST_TSuccess updateDrawingContext();
/**
* Returns the window user data.
* \return The window user data.
*/
- inline virtual GHOST_TUserDataPtr getUserData() const
+ inline GHOST_TUserDataPtr getUserData() const
{
return m_userData;
}
@@ -283,18 +283,34 @@ public:
* Changes the window user data.
* \param data The window user data.
*/
- virtual void setUserData(const GHOST_TUserDataPtr userData)
+ void setUserData(const GHOST_TUserDataPtr userData)
{
m_userData = userData;
}
- virtual float getNativePixelSize(void)
+ float getNativePixelSize(void)
{
if (m_nativePixelSize > 0.0f)
return m_nativePixelSize;
return 1.0f;
}
+#ifdef WITH_INPUT_IME
+ virtual void beginIME(GHOST_TInt32 x,
+ GHOST_TInt32 y,
+ GHOST_TInt32 w,
+ GHOST_TInt32 h,
+ int completed)
+ {
+ /* do nothing temporarily if not in windows */
+ }
+
+ virtual void endIME()
+ {
+ /* do nothing temporarily if not in windows */
+ }
+#endif /* WITH_INPUT_IME */
+
protected:
/**
* Tries to install a rendering context in this window.
@@ -336,7 +352,7 @@ protected:
GHOST_TSuccess releaseNativeHandles();
- /** The the of drawing context installed in this window. */
+ /** The drawing context installed in this window. */
GHOST_TDrawingContextType m_drawingContextType;
/** The window user data */
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index ac0973684d3..3ed88086184 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -81,77 +81,77 @@ public:
* Destructor.
* Closes the window and disposes resources allocated.
*/
- virtual ~GHOST_WindowCocoa();
+ ~GHOST_WindowCocoa();
/**
* Returns indication as to whether the window is valid.
* \return The validity of the window.
*/
- virtual bool getValid() const;
+ bool getValid() const;
/**
* Returns the associated NSWindow object
* \return The associated NSWindow object
*/
- virtual void *getOSWindow() const;
+ void *getOSWindow() const;
/**
* Sets the title displayed in the title bar.
* \param title The title to display in the title bar.
*/
- virtual void setTitle(const STR_String& title);
+ void setTitle(const STR_String& title);
/**
* Returns the title displayed in the title bar.
* \param title The title displayed in the title bar.
*/
- virtual void getTitle(STR_String& title) const;
+ void getTitle(STR_String& title) const;
/**
* Returns the window rectangle dimensions.
* The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
* \param bounds The bounding rectangle of the window.
*/
- virtual void getWindowBounds(GHOST_Rect& bounds) const;
+ void getWindowBounds(GHOST_Rect& bounds) const;
/**
* Returns the client rectangle dimensions.
* The left and top members of the rectangle are always zero.
* \param bounds The bounding rectangle of the client area of the window.
*/
- virtual void getClientBounds(GHOST_Rect& bounds) const;
+ void getClientBounds(GHOST_Rect& bounds) const;
/**
* Resizes client rectangle width.
* \param width The new width of the client area of the window.
*/
- virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
+ GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
/**
* Resizes client rectangle height.
* \param height The new height of the client area of the window.
*/
- virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
+ GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
/**
* Resizes client rectangle.
* \param width The new width of the client area of the window.
* \param height The new height of the client area of the window.
*/
- virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
+ GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
/**
* Returns the state of the window (normal, minimized, maximized).
* \return The state of the window.
*/
- virtual GHOST_TWindowState getState() const;
+ GHOST_TWindowState getState() const;
/**
* Sets the window "modified" status, indicating unsaved changes
* \param isUnsavedChanges Unsaved changes or not
* \return Indication of success.
*/
- virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
+ GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
/**
* Converts a point in screen coordinates to client rectangle coordinates
@@ -160,7 +160,7 @@ public:
* \param outX The x-coordinate in the client rectangle.
* \param outY The y-coordinate in the client rectangle.
*/
- virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+ void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
/**
* Converts a point in screen coordinates to client rectangle coordinates
@@ -169,7 +169,7 @@ public:
* \param outX The x-coordinate on the screen.
* \param outY The y-coordinate on the screen.
*/
- virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+ void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
/**
* Converts a point in screen coordinates to client rectangle coordinates
@@ -202,16 +202,16 @@ public:
* \param state The state of the window.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setState(GHOST_TWindowState state);
+ GHOST_TSuccess setState(GHOST_TWindowState state);
/**
* Sets the order of the window (bottom, top).
* \param order The order of the window.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
+ GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
- virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
+ void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
const GHOST_TabletData *GetTabletData()
{
@@ -227,15 +227,15 @@ public:
* Sets the progress bar value displayed in the window/application icon
* \param progress The progress % (0.0 to 1.0)
*/
- virtual GHOST_TSuccess setProgressBar(float progress);
+ GHOST_TSuccess setProgressBar(float progress);
/**
* Hides the progress bar icon
*/
- virtual GHOST_TSuccess endProgressBar();
+ GHOST_TSuccess endProgressBar();
- virtual void setNativePixelSize(void);
+ void setNativePixelSize(void);
GHOST_TSuccess beginFullScreen() const {return GHOST_kFailure;}
@@ -254,40 +254,40 @@ protected:
* \param type The type of rendering context create.
* \return Indication of success.
*/
- virtual GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
/**
* Invalidates the contents of this window.
* \return Indication of success.
*/
- virtual GHOST_TSuccess invalidate();
+ GHOST_TSuccess invalidate();
/**
* Sets the cursor visibility on the window using
* native window system calls.
*/
- virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
+ GHOST_TSuccess setWindowCursorVisibility(bool visible);
/**
* Sets the cursor grab on the window using
* native window system calls.
*/
- virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
+ GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
/**
* Sets the cursor shape on the window using
* native window system calls.
*/
- virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+ GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
/**
* Sets the cursor shape on the window using
* native window system calls.
*/
- virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color);
- virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
/** The window containing the OpenGL view */
CocoaWindow *m_window;
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index 6fb73a34e5d..2914b36b9a7 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -23,6 +23,7 @@
* Contributor(s): Maarten Gribnau 05/2001
* Damien Plisson 10/2009
* Jason Wilkins 02/2014
+ * Jens Verwiebe 10/2014
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -45,8 +46,6 @@
# include <Carbon/Carbon.h>
#endif
-
-
#include <sys/sysctl.h>
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
@@ -77,7 +76,6 @@ enum {
- (void)windowDidChangeBackingProperties:(NSNotification *)notification;
@end
-
@implementation CocoaWindowDelegate : NSObject
- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa
{
@@ -88,6 +86,8 @@ enum {
- (void)windowDidBecomeKey:(NSNotification *)notification
{
systemCocoa->handleWindowEvent(GHOST_kEventWindowActivate, associatedWindow);
+ // work around for broken appswitching when combining cmd-tab and missioncontrol
+ [(NSWindow*)associatedWindow->getOSWindow() orderFrontRegardless];
}
- (void)windowDidResignKey:(NSNotification *)notification
@@ -171,6 +171,7 @@ enum {
- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
- (GHOST_SystemCocoa*)systemCocoa;
@end
+
@implementation CocoaWindow
- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa
{
@@ -261,8 +262,6 @@ enum {
@end
-
-
#pragma mark NSOpenGLView subclass
//We need to subclass it in order to give Cocoa the feeling key events are trapped
@interface CocoaOpenGLView : NSOpenGLView <NSTextInput>
@@ -277,6 +276,7 @@ enum {
}
- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
@end
+
@implementation CocoaOpenGLView
- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa
@@ -645,6 +645,8 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
m_lionStyleFullScreen = true;
}
+ [NSApp activateIgnoringOtherApps:YES]; // raise application to front, important for new blender instance animation play case
+
[pool drain];
}
@@ -1326,7 +1328,16 @@ GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress)
return GHOST_kSuccess;
}
-
+static void postNotification()
+{
+ NSUserNotification *notification = [[NSUserNotification alloc] init];
+ notification.title = @"Blender progress notification";
+ notification.informativeText = @"Calculation is finished";
+ notification.soundName = NSUserNotificationDefaultSoundName;
+ [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
+ [notification release];
+}
+
GHOST_TSuccess GHOST_WindowCocoa::endProgressBar()
{
if (!m_progressBarVisible) return GHOST_kFailure;
@@ -1344,15 +1355,10 @@ GHOST_TSuccess GHOST_WindowCocoa::endProgressBar()
// With OSX 10.8 and later, we can use notifications to inform the user when the progress reached 100%
// Atm. just fire this when the progressbar ends, the behavior is controlled in the NotificationCenter
// If Blender is not frontmost window, a message pops up with sound, in any case an entry in notifications
-//PR commented temporarily
-// if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) {
-// NSUserNotification *notification = [[NSUserNotification alloc] init];
-// notification.title = @"Blender progress notification";
-// notification.informativeText = @"Calculation ended";
-// notification.soundName = NSUserNotificationDefaultSoundName;
-// [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
-// [notification release];
-// }
+
+ if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) {
+ postNotification();
+ }
[dockIcon release];
@@ -1360,8 +1366,6 @@ GHOST_TSuccess GHOST_WindowCocoa::endProgressBar()
return GHOST_kSuccess;
}
-
-
#pragma mark Cursor handling
void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h
index 8297e4d24d2..e868a9b0416 100644
--- a/intern/ghost/intern/GHOST_WindowManager.h
+++ b/intern/ghost/intern/GHOST_WindowManager.h
@@ -55,7 +55,7 @@ public:
/**
* Destructor.
*/
- virtual ~GHOST_WindowManager();
+ ~GHOST_WindowManager();
/**
* Add a window to our list.
@@ -63,67 +63,67 @@ public:
* \param window Pointer to the window to be added.
* \return Indication of success.
*/
- virtual GHOST_TSuccess addWindow(GHOST_IWindow *window);
+ GHOST_TSuccess addWindow(GHOST_IWindow *window);
/**
* Remove a window from our list.
* \param window Pointer to the window to be removed.
* \return Indication of success.
*/
- virtual GHOST_TSuccess removeWindow(const GHOST_IWindow *window);
+ GHOST_TSuccess removeWindow(const GHOST_IWindow *window);
/**
* Returns whether the window is in our list.
* \param window Pointer to the window to query.
* \return A boolean indicator.
*/
- virtual bool getWindowFound(const GHOST_IWindow *window) const;
+ bool getWindowFound(const GHOST_IWindow *window) const;
/**
* Returns whether one of the windows is fullscreen.
* \return A boolean indicator.
*/
- virtual bool getFullScreen(void) const;
+ bool getFullScreen(void) const;
/**
* Returns pointer to the full-screen window.
* \return The full-screen window (NULL if not in full-screen).
*/
- virtual GHOST_IWindow *getFullScreenWindow(void) const;
+ GHOST_IWindow *getFullScreenWindow(void) const;
/**
* Activates fullscreen mode for a window.
* \param window The window displayed fullscreen.
* \return Indication of success.
*/
- virtual GHOST_TSuccess beginFullScreen(GHOST_IWindow *window, const bool stereoVisual);
+ GHOST_TSuccess beginFullScreen(GHOST_IWindow *window, const bool stereoVisual);
/**
* Closes fullscreen mode down.
* \return Indication of success.
*/
- virtual GHOST_TSuccess endFullScreen(void);
+ GHOST_TSuccess endFullScreen(void);
/**
* Sets new window as active window (the window receiving events).
* There can be only one window active which should be in the current window list.
* \param window The new active window.
*/
- virtual GHOST_TSuccess setActiveWindow(GHOST_IWindow *window);
+ GHOST_TSuccess setActiveWindow(GHOST_IWindow *window);
/**
* Returns the active window (the window receiving events).
* There can be only one window active which should be in the current window list.
* \return window The active window (or NULL if there is none).
*/
- virtual GHOST_IWindow *getActiveWindow(void) const;
+ GHOST_IWindow *getActiveWindow(void) const;
/**
* Set this window to be inactive (not receiving events).
* \param window The window to deactivate.
*/
- virtual void setWindowInactive(const GHOST_IWindow *window);
+ void setWindowInactive(const GHOST_IWindow *window);
/**
@@ -140,7 +140,7 @@ public:
* \param osWindow The OS window object/handle
* \return The associated window, null if none corresponds
*/
- virtual GHOST_IWindow *getWindowAssociatedWithOSWindow(void *osWindow);
+ GHOST_IWindow *getWindowAssociatedWithOSWindow(void *osWindow);
/**
* Return true if any windows has a modified status
diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h
index 0cdb161f40d..80a1274a2a9 100644
--- a/intern/ghost/intern/GHOST_WindowNULL.h
+++ b/intern/ghost/intern/GHOST_WindowNULL.h
@@ -96,7 +96,7 @@ private:
* \param type The type of rendering context create.
* \return Indication of success.
*/
- virtual GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) {return NULL;}
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) {return NULL;}
};
diff --git a/intern/ghost/intern/GHOST_WindowSDL.h b/intern/ghost/intern/GHOST_WindowSDL.h
index d446c220c2e..5f658e8ad01 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.h
+++ b/intern/ghost/intern/GHOST_WindowSDL.h
@@ -105,7 +105,7 @@ protected:
* \param type The type of rendering context create.
* \return Indication of success.
*/
- virtual GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
GHOST_TSuccess
setWindowCursorGrab(GHOST_TGrabCursorMode mode);
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 64ea7192616..efcb389363d 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -62,8 +62,7 @@ extern "C" {
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
-GHOST_WindowWin32::GHOST_WindowWin32(
- GHOST_SystemWin32 *system,
+GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
const STR_String &title,
GHOST_TInt32 left,
GHOST_TInt32 top,
@@ -71,7 +70,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- bool wantStereoVisual,
+ bool wantStereoVisual, bool warnOld,
GHOST_TUns16 wantNumOfAASamples,
GHOST_TEmbedderWindowID parentwindowhwnd)
: GHOST_Window(width, height, state,
@@ -97,6 +96,13 @@ GHOST_WindowWin32::GHOST_WindowWin32(
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+#if !defined(WITH_GL_EGL)
+ if (!warnOld)
+ GHOST_ContextWGL::unSetWarningOld();
+#else
+ (void)(warnOld);
+#endif
+
if (!GetVersionEx((OSVERSIONINFO *)&versionInfo)) {
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx((OSVERSIONINFO *)&versionInfo)) {
@@ -1050,3 +1056,16 @@ GHOST_TSuccess GHOST_WindowWin32::endProgressBar()
return GHOST_kFailure;
}
+
+#ifdef WITH_INPUT_IME
+void GHOST_WindowWin32::beginIME(GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed)
+{
+ m_imeImput.BeginIME(m_hWnd, GHOST_Rect(x, y - h, x, y), (bool)completed);
+}
+
+
+void GHOST_WindowWin32::endIME()
+{
+ m_imeImput.EndIME(m_hWnd);
+}
+#endif /* WITH_INPUT_IME */
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 7b12d8c583e..1eaef243df9 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -39,6 +39,9 @@
#include "GHOST_Window.h"
#include "GHOST_TaskbarWin32.h"
+#ifdef WITH_INPUT_IME
+# include "GHOST_ImeWin32.h"
+#endif
#include <wintab.h>
#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
@@ -87,6 +90,7 @@ public:
GHOST_TWindowState state,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
bool wantStereoVisual = false,
+ bool warnOld = false,
GHOST_TUns16 wantNumOfAASamples = 0,
GHOST_TEmbedderWindowID parentWindowHwnd = 0
);
@@ -95,70 +99,70 @@ public:
* Destructor.
* Closes the window and disposes resources allocated.
*/
- virtual ~GHOST_WindowWin32();
+ ~GHOST_WindowWin32();
/**
* Returns indication as to whether the window is valid.
* \return The validity of the window.
*/
- virtual bool getValid() const;
+ bool getValid() const;
/**
* Access to the handle of the window.
* \return The handle of the window.
*/
- virtual HWND getHWND() const;
+ HWND getHWND() const;
/**
* Sets the title displayed in the title bar.
* \param title The title to display in the title bar.
*/
- virtual void setTitle(const STR_String& title);
+ void setTitle(const STR_String& title);
/**
* Returns the title displayed in the title bar.
* \param title The title displayed in the title bar.
*/
- virtual void getTitle(STR_String& title) const;
+ void getTitle(STR_String& title) const;
/**
* Returns the window rectangle dimensions.
* The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
* \param bounds The bounding rectangle of the window.
*/
- virtual void getWindowBounds(GHOST_Rect& bounds) const;
+ void getWindowBounds(GHOST_Rect& bounds) const;
/**
* Returns the client rectangle dimensions.
* The left and top members of the rectangle are always zero.
* \param bounds The bounding rectangle of the client area of the window.
*/
- virtual void getClientBounds(GHOST_Rect& bounds) const;
+ void getClientBounds(GHOST_Rect& bounds) const;
/**
* Resizes client rectangle width.
* \param width The new width of the client area of the window.
*/
- virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
+ GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
/**
* Resizes client rectangle height.
* \param height The new height of the client area of the window.
*/
- virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
+ GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
/**
* Resizes client rectangle.
* \param width The new width of the client area of the window.
* \param height The new height of the client area of the window.
*/
- virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
+ GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
/**
* Returns the state of the window (normal, minimized, maximized).
* \return The state of the window.
*/
- virtual GHOST_TWindowState getState() const;
+ GHOST_TWindowState getState() const;
/**
* Converts a point in screen coordinates to client rectangle coordinates
@@ -167,7 +171,7 @@ public:
* \param outX The x-coordinate in the client rectangle.
* \param outY The y-coordinate in the client rectangle.
*/
- virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+ void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
/**
* Converts a point in screen coordinates to client rectangle coordinates
@@ -176,39 +180,39 @@ public:
* \param outX The x-coordinate on the screen.
* \param outY The y-coordinate on the screen.
*/
- virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+ void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
/**
* Sets the state of the window (normal, minimized, maximized).
* \param state The state of the window.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setState(GHOST_TWindowState state);
+ GHOST_TSuccess setState(GHOST_TWindowState state);
/**
* Sets the order of the window (bottom, top).
* \param order The order of the window.
* \return Indication of success.
*/
- virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
+ GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
/**
/**
* Invalidates the contents of this window.
*/
- virtual GHOST_TSuccess invalidate();
+ GHOST_TSuccess invalidate();
/**
* Sets the progress bar value displayed in the window/application icon
* \param progress The progress %
*/
- virtual GHOST_TSuccess setProgressBar(float progress);
+ GHOST_TSuccess setProgressBar(float progress);
/**
* Hides the progress bar in the icon
*/
- virtual GHOST_TSuccess endProgressBar();
+ GHOST_TSuccess endProgressBar();
/**
@@ -253,42 +257,53 @@ public:
/** if the window currently resizing */
bool m_inLiveResize;
+#ifdef WITH_INPUT_IME
+ GHOST_ImeWin32 *getImeInput() {return &m_imeImput;}
+
+ void beginIME(
+ GHOST_TInt32 x, GHOST_TInt32 y,
+ GHOST_TInt32 w, GHOST_TInt32 h,
+ int completed);
+
+ void endIME();
+#endif /* WITH_INPUT_IME */
+
private:
/**
* \param type The type of rendering context create.
* \return Indication of success.
*/
- virtual GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
/**
* Sets the cursor visibility on the window using
* native window system calls.
*/
- virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
+ GHOST_TSuccess setWindowCursorVisibility(bool visible);
/**
* Sets the cursor grab on the window using native window system calls.
* Using registerMouseClickEvent.
* \param mode GHOST_TGrabCursorMode.
*/
- virtual GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
+ GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode);
/**
* Sets the cursor shape on the window using
* native window system calls.
*/
- virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+ GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
/**
* Sets the cursor shape on the window using
* native window system calls.
*/
- virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
+ GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2],
GHOST_TUns8 mask[16][2],
int hotX, int hotY);
- virtual GHOST_TSuccess setWindowCustomCursorShape(
+ GHOST_TSuccess setWindowCustomCursorShape(
GHOST_TUns8 *bitmap,
GHOST_TUns8 *mask,
int sizex,
@@ -339,6 +354,11 @@ private:
/** Hwnd to parent window */
GHOST_TEmbedderWindowID m_parentWindowHwnd;
+
+#ifdef WITH_INPUT_IME
+ /** Handle input method editors event */
+ GHOST_ImeWin32 m_imeImput;
+#endif
};
#endif // __GHOST_WINDOWWIN32_H__
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 97f8ae73d2d..613b4dfe4be 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -29,6 +29,10 @@
* \ingroup GHOST
*/
+/* For standard X11 cursors */
+#include <X11/cursorfont.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
#include "GHOST_WindowX11.h"
#include "GHOST_SystemX11.h"
@@ -45,11 +49,6 @@
# include "GHOST_ContextGLX.h"
#endif
-
-/* For standard X11 cursors */
-#include <X11/cursorfont.h>
-#include <X11/Xatom.h>
-
#if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
# include <strings.h>
#endif
@@ -57,6 +56,9 @@
#include <cstring>
#include <cstdio>
+/* gethostname */
+#include <unistd.h>
+
#include <algorithm>
#include <string>
@@ -72,6 +74,9 @@ typedef struct {
#define MWM_HINTS_DECORATIONS (1L << 1)
+#ifndef HOST_NAME_MAX
+# define HOST_NAME_MAX 64
+#endif
// #define GHOST_X11_GRAB
@@ -153,7 +158,118 @@ static long BLENDER_ICON_48x48x32[] = {
4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303,
};
+static XVisualInfo *x11_visualinfo_from_glx(
+ Display *display,
+ bool stereoVisual, GHOST_TUns16 *r_numOfAASamples)
+{
+ XVisualInfo *visualInfo = NULL;
+ GHOST_TUns16 numOfAASamples = *r_numOfAASamples;
+ /* Set up the minimum attributes that we require and see if
+ * X can find us a visual matching those requirements. */
+
+ std::vector<int> attribs;
+ attribs.reserve(40);
+
+ int glx_major, glx_minor; /* GLX version: major.minor */
+
+ if (!glXQueryVersion(display, &glx_major, &glx_minor)) {
+ fprintf(stderr,
+ "%s:%d: X11 glXQueryVersion() failed, "
+ "verify working openGL system!\n",
+ __FILE__, __LINE__);
+
+ return NULL;
+ }
+
+#ifdef GHOST_OPENGL_ALPHA
+ const bool needAlpha = true;
+#else
+ const bool needAlpha = false;
+#endif
+
+#ifdef GHOST_OPENGL_STENCIL
+ const bool needStencil = true;
+#else
+ const bool needStencil = false;
+#endif
+ /* Find the display with highest samples, starting at level requested */
+ GHOST_TUns16 actualSamples = numOfAASamples;
+ for (;;) {
+ attribs.clear();
+
+ if (stereoVisual)
+ attribs.push_back(GLX_STEREO);
+
+ attribs.push_back(GLX_RGBA);
+
+ attribs.push_back(GLX_DOUBLEBUFFER);
+
+ attribs.push_back(GLX_RED_SIZE);
+ attribs.push_back(1);
+
+ attribs.push_back(GLX_BLUE_SIZE);
+ attribs.push_back(1);
+
+ attribs.push_back(GLX_GREEN_SIZE);
+ attribs.push_back(1);
+
+ attribs.push_back(GLX_DEPTH_SIZE);
+ attribs.push_back(1);
+
+ if (needAlpha) {
+ attribs.push_back(GLX_ALPHA_SIZE);
+ attribs.push_back(1);
+ }
+
+ if (needStencil) {
+ attribs.push_back(GLX_STENCIL_SIZE);
+ attribs.push_back(1);
+ }
+
+ /* GLX >= 1.4 required for multi-sample */
+ if (actualSamples > 0 && ((glx_major > 1) || (glx_major == 1 && glx_minor >= 4))) {
+ attribs.push_back(GLX_SAMPLE_BUFFERS);
+ attribs.push_back(1);
+
+ attribs.push_back(GLX_SAMPLES);
+ attribs.push_back(actualSamples);
+ }
+
+ attribs.push_back(None);
+
+ visualInfo = glXChooseVisual(display, DefaultScreen(display), &attribs[0]);
+
+ /* Any sample level or even zero, which means oversampling disabled, is good
+ * but we need a valid visual to continue */
+ if (visualInfo != NULL) {
+ if (actualSamples < numOfAASamples) {
+ fprintf(stderr,
+ "Warning! Unable to find a multisample pixel format that supports exactly %d samples. "
+ "Substituting one that uses %d samples.\n",
+ numOfAASamples, actualSamples);
+ }
+ break;
+ }
+
+ if (actualSamples == 0) {
+ /* All options exhausted, cannot continue */
+ fprintf(stderr,
+ "%s:%d: X11 glXChooseVisual() failed, "
+ "verify working openGL system!\n",
+ __FILE__, __LINE__);
+
+ return NULL;
+ }
+ else {
+ --actualSamples;
+ }
+ }
+
+ *r_numOfAASamples = actualSamples;
+
+ return visualInfo;
+}
GHOST_WindowX11::
GHOST_WindowX11(
@@ -172,6 +288,7 @@ GHOST_WindowX11(
const GHOST_TUns16 numOfAASamples)
: GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples),
m_display(display),
+ m_visualInfo(NULL),
m_normal_state(GHOST_kWindowStateNormal),
m_system(system),
m_valid_setup(false),
@@ -180,7 +297,20 @@ GHOST_WindowX11(
m_custom_cursor(None),
m_visible_cursor(None)
{
- int natom;
+ if (type == GHOST_kDrawingContextTypeOpenGL) {
+ m_visualInfo = x11_visualinfo_from_glx(m_display, stereoVisual, &m_wantNumOfAASamples);
+ }
+ else {
+ XVisualInfo tmp = {0};
+ int n;
+ m_visualInfo = XGetVisualInfo(m_display, 0, &tmp, &n);
+ }
+
+ /* exit if this is the first window */
+ if (m_visualInfo == NULL) {
+ fprintf(stderr, "initial window could not find the GLX extension, exit!\n");
+ exit(EXIT_FAILURE);
+ }
unsigned int xattributes_valuemask = 0;
@@ -206,24 +336,28 @@ GHOST_WindowX11(
xattributes.override_redirect = True;
}
+ xattributes_valuemask |= CWColormap;
+ xattributes.colormap = XCreateColormap(
+ m_display,
+ RootWindow(m_display, m_visualInfo->screen),
+ m_visualInfo->visual,
+ AllocNone
+ );
+
/* create the window! */
if (parentWindow == 0) {
- m_window = XCreateWindow(m_display,
- RootWindow(m_display, DefaultScreen(m_display)),
- left,
- top,
- width,
- height,
- 0, /* no border. */
- CopyFromParent,
- InputOutput,
- CopyFromParent,
- xattributes_valuemask,
- &xattributes
- );
+ m_window = XCreateWindow(
+ m_display,
+ RootWindow(m_display, m_visualInfo->screen),
+ left, top, width, height,
+ 0, /* no border. */
+ m_visualInfo->depth,
+ InputOutput,
+ m_visualInfo->visual,
+ xattributes_valuemask,
+ &xattributes);
}
else {
-
Window root_return;
int x_return, y_return;
unsigned int w_return, h_return, border_w_return, depth_return;
@@ -237,19 +371,16 @@ GHOST_WindowX11(
height = h_return;
- m_window = XCreateWindow(m_display,
- parentWindow, /* reparent against embedder */
- left,
- top,
- width,
- height,
- 0, /* no border. */
- CopyFromParent,
- InputOutput,
- CopyFromParent,
- xattributes_valuemask,
- &xattributes
- );
+ m_window = XCreateWindow(
+ m_display,
+ parentWindow, /* reparent against embedder */
+ left, top, width, height,
+ 0, /* no border. */
+ m_visualInfo->depth,
+ InputOutput,
+ m_visualInfo->visual,
+ xattributes_valuemask,
+ &xattributes);
XSelectInput(m_display, parentWindow, SubstructureNotifyMask);
@@ -301,36 +432,43 @@ GHOST_WindowX11(
m_post_state = GHOST_kWindowStateNormal;
}
+
/* Create some hints for the window manager on how
* we want this window treated. */
+ {
+ XSizeHints *xsizehints = XAllocSizeHints();
+ xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
+ xsizehints->x = left;
+ xsizehints->y = top;
+ xsizehints->width = width;
+ xsizehints->height = height;
+ xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */
+ xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */
+ xsizehints->max_width = 65535;
+ xsizehints->max_height = 65535;
+ XSetWMNormalHints(m_display, m_window, xsizehints);
+ XFree(xsizehints);
+ }
+
+
+ /* XClassHint, title */
+ {
+ XClassHint *xclasshint = XAllocClassHint();
+ const int len = title.Length() + 1;
+ char *wmclass = (char *)malloc(sizeof(char) * len);
+ memcpy(wmclass, title.ReadPtr(), len * sizeof(char));
+ xclasshint->res_name = wmclass;
+ xclasshint->res_class = wmclass;
+ XSetClassHint(m_display, m_window, xclasshint);
+ free(wmclass);
+ XFree(xclasshint);
+ }
- XSizeHints *xsizehints = XAllocSizeHints();
- xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
- xsizehints->x = left;
- xsizehints->y = top;
- xsizehints->width = width;
- xsizehints->height = height;
- xsizehints->min_width = 320; /* size hints, could be made apart of the ghost api */
- xsizehints->min_height = 240; /* limits are also arbitrary, but should not allow 1x1 window */
- xsizehints->max_width = 65535;
- xsizehints->max_height = 65535;
- XSetWMNormalHints(m_display, m_window, xsizehints);
- XFree(xsizehints);
-
- XClassHint *xclasshint = XAllocClassHint();
- const int len = title.Length() + 1;
- char *wmclass = (char *)malloc(sizeof(char) * len);
- strncpy(wmclass, (const char *)title, sizeof(char) * len);
- xclasshint->res_name = wmclass;
- xclasshint->res_class = wmclass;
- XSetClassHint(m_display, m_window, xclasshint);
- free(wmclass);
- XFree(xclasshint);
/* The basic for a good ICCCM "work" */
if (m_system->m_atom.WM_PROTOCOLS) {
Atom atoms[2];
- natom = 0;
+ int natom = 0;
if (m_system->m_atom.WM_DELETE_WINDOW) {
atoms[natom] = m_system->m_atom.WM_DELETE_WINDOW;
@@ -352,21 +490,49 @@ GHOST_WindowX11(
m_xic = NULL;
#endif
+
/* Set the window hints */
- XWMHints *xwmhints = XAllocWMHints();
- xwmhints->initial_state = NormalState;
- xwmhints->input = True;
- xwmhints->flags = InputHint | StateHint;
- XSetWMHints(display, m_window, xwmhints);
- XFree(xwmhints);
- /* done setting the hints */
+ {
+ XWMHints *xwmhints = XAllocWMHints();
+ xwmhints->initial_state = NormalState;
+ xwmhints->input = True;
+ xwmhints->flags = InputHint | StateHint;
+ XSetWMHints(display, m_window, xwmhints);
+ XFree(xwmhints);
+ }
+
/* set the icon */
- Atom _NET_WM_ICON = XInternAtom(m_display, "_NET_WM_ICON", False);
- XChangeProperty(m_display, m_window, _NET_WM_ICON, XA_CARDINAL,
- 32, PropModeReplace, (unsigned char *)BLENDER_ICON_48x48x32,
- BLENDER_ICON_48x48x32[0] * BLENDER_ICON_48x48x32[1] + 2);
- /* done setting the icon */
+ {
+ Atom _NET_WM_ICON = XInternAtom(m_display, "_NET_WM_ICON", False);
+ XChangeProperty(m_display, m_window, _NET_WM_ICON, XA_CARDINAL,
+ 32, PropModeReplace, (unsigned char *)BLENDER_ICON_48x48x32,
+ BLENDER_ICON_48x48x32[0] * BLENDER_ICON_48x48x32[1] + 2);
+ }
+
+ /* set the process ID (_NET_WM_PID) */
+ {
+ Atom _NET_WM_PID = XInternAtom(m_display, "_NET_WM_PID", False);
+ pid_t pid = getpid();
+ XChangeProperty(m_display, m_window, _NET_WM_PID, XA_CARDINAL,
+ 32, PropModeReplace, (unsigned char *)&pid, 1);
+ }
+
+
+ /* set the hostname (WM_CLIENT_MACHINE) */
+ {
+ char hostname[HOST_NAME_MAX];
+ char *text_array[1];
+ XTextProperty text_prop;
+
+ gethostname(hostname, sizeof(hostname));
+ hostname[sizeof(hostname) - 1] = '\0';
+ text_array[0] = hostname;
+
+ XStringListToTextProperty(text_array, 1, &text_prop);
+ XSetWMClientMachine(m_display, m_window, &text_prop);
+ XFree(text_prop.value);
+ }
#ifdef WITH_X11_XINPUT
initXInputDevices();
@@ -374,6 +540,7 @@ GHOST_WindowX11(
m_tabletData.Active = GHOST_kTabletModeNone;
#endif
+
/* now set up the rendering context. */
if (setDrawingContextType(type) == GHOST_kSuccess) {
m_valid_setup = true;
@@ -442,23 +609,32 @@ void GHOST_WindowX11::initXInputDevices()
if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
if (version->present) {
GHOST_SystemX11::GHOST_TabletX11 &xtablet = m_system->GetXTablet();
- XEventClass xevents[10], ev;
+ XEventClass xevents[8], ev;
int dcount = 0;
+ /* With modern XInput (xlib 1.6.2 at least and/or evdev 2.9.0) and some 'no-name' tablets
+ * like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
+ * otherwise we do not get any tablet motion event once pen is pressed... See T43367.
+ */
+
if (xtablet.StylusDevice) {
DeviceMotionNotify(xtablet.StylusDevice, xtablet.MotionEvent, ev);
if (ev) xevents[dcount++] = ev;
+ DeviceButtonPress(xtablet.StylusDevice, xtablet.PressEvent, ev);
+ if (ev) xevents[dcount++] = ev;
ProximityIn(xtablet.StylusDevice, xtablet.ProxInEvent, ev);
if (ev) xevents[dcount++] = ev;
ProximityOut(xtablet.StylusDevice, xtablet.ProxOutEvent, ev);
if (ev) xevents[dcount++] = ev;
}
if (xtablet.EraserDevice) {
- DeviceMotionNotify(xtablet.EraserDevice, xtablet.MotionEvent, ev);
+ DeviceMotionNotify(xtablet.EraserDevice, xtablet.MotionEventEraser, ev);
+ if (ev) xevents[dcount++] = ev;
+ DeviceButtonPress(xtablet.EraserDevice, xtablet.PressEventEraser, ev);
if (ev) xevents[dcount++] = ev;
- ProximityIn(xtablet.EraserDevice, xtablet.ProxInEvent, ev);
+ ProximityIn(xtablet.EraserDevice, xtablet.ProxInEventEraser, ev);
if (ev) xevents[dcount++] = ev;
- ProximityOut(xtablet.EraserDevice, xtablet.ProxOutEvent, ev);
+ ProximityOut(xtablet.EraserDevice, xtablet.ProxOutEventEraser, ev);
if (ev) xevents[dcount++] = ev;
}
@@ -602,7 +778,7 @@ screenToClient(
Window temp;
XTranslateCoordinates(m_display,
- RootWindow(m_display, DefaultScreen(m_display)),
+ RootWindow(m_display, m_visualInfo->screen),
m_window,
inX, inY,
&ax, &ay,
@@ -625,7 +801,7 @@ clientToScreen(
XTranslateCoordinates(
m_display,
m_window,
- RootWindow(m_display, DefaultScreen(m_display)),
+ RootWindow(m_display, m_visualInfo->screen),
inX, inY,
&ax, &ay,
&temp);
@@ -648,7 +824,7 @@ void GHOST_WindowX11::icccmSetState(int state)
xev.xclient.format = 32;
xev.xclient.message_type = m_system->m_atom.WM_CHANGE_STATE;
xev.xclient.data.l[0] = state;
- XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
+ XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
}
@@ -694,7 +870,7 @@ void GHOST_WindowX11::netwmMaximized(bool set)
xev.xclient.data.l[2] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
- XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
+ XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
@@ -750,7 +926,7 @@ void GHOST_WindowX11::netwmFullScreen(bool set)
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
- XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
+ XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen),
False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
@@ -969,7 +1145,7 @@ setOrder(
xev.xclient.data.l[3] = 0;
xev.xclient.data.l[4] = 0;
- root = RootWindow(m_display, DefaultScreen(m_display)),
+ root = RootWindow(m_display, m_visualInfo->screen),
eventmask = SubstructureRedirectMask | SubstructureNotifyMask;
XSendEvent(m_display, root, False, eventmask, &xev);
@@ -1068,6 +1244,10 @@ GHOST_WindowX11::
XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
}
+ if (m_visualInfo) {
+ XFree(m_visualInfo);
+ }
+
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
if (m_xic) {
XDestroyIC(m_xic);
@@ -1095,6 +1275,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
m_wantNumOfAASamples,
m_window,
m_display,
+ m_visualInfo,
GLX_CONTEXT_OPENGL_CORE_PROFILE_BIT,
3, 2,
GHOST_OPENGL_GLX_CONTEXT_FLAGS,
@@ -1105,6 +1286,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
m_wantNumOfAASamples,
m_window,
m_display,
+ m_visualInfo,
GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
2, 0,
GHOST_OPENGL_GLX_CONTEXT_FLAGS,
@@ -1115,6 +1297,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
m_wantNumOfAASamples,
m_window,
m_display,
+ m_visualInfo,
0, // profile bit
0, 0,
GHOST_OPENGL_GLX_CONTEXT_FLAGS,
@@ -1231,13 +1414,13 @@ getEmptyCursor(
) {
if (!m_empty_cursor) {
Pixmap blank;
- XColor dummy;
+ XColor dummy = {0};
char data[1] = {0};
/* make a blank cursor */
blank = XCreateBitmapFromData(
m_display,
- RootWindow(m_display, DefaultScreen(m_display)),
+ RootWindow(m_display, m_visualInfo->screen),
data, 1, 1
);
@@ -1356,7 +1539,7 @@ setWindowCustomCursorShape(
int fg_color,
int bg_color)
{
- Colormap colormap = DefaultColormap(m_display, DefaultScreen(m_display));
+ Colormap colormap = DefaultColormap(m_display, m_visualInfo->screen);
Pixmap bitmap_pix, mask_pix;
XColor fg, bg;
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index 3255751be93..eaa8a5327f7 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -35,6 +35,7 @@
#include "GHOST_Window.h"
#include <X11/Xlib.h>
+#include <X11/Xutil.h>
// For tablets
#ifdef WITH_X11_XINPUT
# include <X11/extensions/XInput.h>
@@ -232,7 +233,7 @@ protected:
* \param type The type of rendering context create.
* \return Indication of success.
*/
- virtual GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
+ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type);
/**
* Sets the cursor visibility on the window using
@@ -319,6 +320,8 @@ private:
Window m_window;
Display *m_display;
+ XVisualInfo *m_visualInfo;
+
GHOST_TWindowState m_normal_state;
/** A pointer to the typed system class. */
diff --git a/intern/glew-mx/CMakeLists.txt b/intern/glew-mx/CMakeLists.txt
index bdb39251df0..8b692b5136c 100644
--- a/intern/glew-mx/CMakeLists.txt
+++ b/intern/glew-mx/CMakeLists.txt
@@ -25,6 +25,9 @@
set(INC
.
+)
+
+set(INC_SYS
${GLEW_INCLUDE_PATH}
)
diff --git a/intern/glew-mx/SConscript b/intern/glew-mx/SConscript
index 1f050f0af8b..5c70958816c 100644
--- a/intern/glew-mx/SConscript
+++ b/intern/glew-mx/SConscript
@@ -9,8 +9,8 @@ sources = ['intern/glew-mx.c']
defs = env['BF_GL_DEFINITIONS']
incs = [
- '.',
- env['BF_GLEW_INC'],
- ]
+ '.',
+ env['BF_GLEW_INC'],
+ ]
-env.BlenderLib ( 'extern_glew_mx', sources, incs, defs, libtype=['intern','player'], priority=[10, 185] )
+env.BlenderLib('intern_glew_mx', sources, incs, defs, libtype=['intern','player'], priority=[50, 185])
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index f0a69f99385..05a98c1a4e5 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -177,7 +177,23 @@ extern "C" {
/** Get the peak memory usage in bytes, including mmap allocations. */
extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT;
-#define MEM_SAFE_FREE(v) if (v) { MEM_freeN(v); v = NULL; } (void)0
+#ifdef __GNUC__
+#define MEM_SAFE_FREE(v) do { \
+ typeof(&(v)) _v = &(v); \
+ if (*_v) { \
+ MEM_freeN(*_v); \
+ *_v = NULL; \
+ } \
+} while (0)
+#else
+#define MEM_SAFE_FREE(v) do { \
+ void ** _v = (void **)&(v); \
+ if (*_v) { \
+ MEM_freeN(*_v); \
+ *_v = NULL; \
+ } \
+} while (0)
+#endif
/* overhead for lockfree allocator (use to avoid slop-space) */
#define MEM_SIZE_OVERHEAD sizeof(size_t)
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index a379837c552..1fd85a0c9f5 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -17,6 +17,7 @@
*
* Contributor(s): Brecht Van Lommel
* Campbell Barton
+ * Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index ecc54882447..bdcace243d9 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -22,6 +22,7 @@
*
* Contributor(s): Brecht Van Lommel
* Campbell Barton
+ * Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -1147,7 +1148,7 @@ size_t MEM_guarded_get_peak_memory(void)
void MEM_guarded_reset_peak_memory(void)
{
mem_lock_thread();
- peak_mem = 0;
+ peak_mem = mem_in_use;
mem_unlock_thread();
}
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index eaa60202f3c..a80d67c3e80 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -134,6 +134,14 @@ void MEM_lockfree_freeN(void *vmemh)
MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
size_t len = MEM_lockfree_allocN_len(vmemh);
+ if (vmemh == NULL) {
+ print_error("Attempt to free NULL pointer\n");
+#ifdef WITH_ASSERT_ABORT
+ abort();
+#endif
+ return;
+ }
+
atomic_sub_u(&totblock, 1);
atomic_sub_z(&mem_in_use, len);
@@ -470,7 +478,7 @@ unsigned int MEM_lockfree_get_memory_blocks_in_use(void)
/* dummy */
void MEM_lockfree_reset_peak_memory(void)
{
- peak_mem = 0;
+ peak_mem = mem_in_use;
}
size_t MEM_lockfree_get_peak_memory(void)
diff --git a/intern/locale/CMakeLists.txt b/intern/locale/CMakeLists.txt
index 5d70c449234..5d933f326f7 100644
--- a/intern/locale/CMakeLists.txt
+++ b/intern/locale/CMakeLists.txt
@@ -38,7 +38,9 @@ set(SRC
if(APPLE)
# Cocoa code to read the locale on OSX
- list(APPEND SRC osx_user_locale.mm)
+ list(APPEND SRC
+ osx_user_locale.mm
+ )
endif()
if(WITH_HEADLESS)
diff --git a/intern/memutil/MEM_CacheLimiter.h b/intern/memutil/MEM_CacheLimiter.h
index bbe6ace2456..3e8ae7e5a4d 100644
--- a/intern/memutil/MEM_CacheLimiter.h
+++ b/intern/memutil/MEM_CacheLimiter.h
@@ -130,7 +130,7 @@ private:
T * data;
int refcount;
- typename std::list<MEM_CacheLimiterHandle<T> *, MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator me;
+ int pos;
MEM_CacheLimiter<T> * parent;
};
@@ -146,29 +146,32 @@ public:
}
~MEM_CacheLimiter() {
- for (iterator it = queue.begin(); it != queue.end(); it++) {
- delete *it;
+ int i;
+ for (i = 0; i < queue.size(); i++) {
+ delete queue[i];
}
}
MEM_CacheLimiterHandle<T> *insert(T * elem) {
queue.push_back(new MEM_CacheLimiterHandle<T>(elem, this));
- iterator it = queue.end();
- --it;
- queue.back()->me = it;
+ queue.back()->pos = queue.size() - 1;
return queue.back();
}
void unmanage(MEM_CacheLimiterHandle<T> *handle) {
- queue.erase(handle->me);
+ int pos = handle->pos;
+ queue[pos] = queue.back();
+ queue[pos]->pos = pos;
+ queue.pop_back();
delete handle;
}
size_t get_memory_in_use() {
size_t size = 0;
if (data_size_func) {
- for (iterator it = queue.begin(); it != queue.end(); it++) {
- size += data_size_func((*it)->get()->get_data());
+ int i;
+ for (i = 0; i < queue.size(); i++) {
+ size += data_size_func(queue[i]->get()->get_data());
}
}
else {
@@ -226,11 +229,11 @@ public:
* least priority element anyway.
*/
if (item_priority_func == NULL) {
+ queue[handle->pos] = queue.back();
+ queue[handle->pos]->pos = handle->pos;
+ queue.pop_back();
queue.push_back(handle);
- queue.erase(handle->me);
- iterator it = queue.end();
- --it;
- handle->me = it;
+ handle->pos = queue.size() - 1;
}
}
@@ -244,7 +247,7 @@ public:
private:
typedef MEM_CacheLimiterHandle<T> *MEM_CacheElementPtr;
- typedef std::list<MEM_CacheElementPtr, MEM_Allocator<MEM_CacheElementPtr> > MEM_CacheQueue;
+ typedef std::vector<MEM_CacheElementPtr, MEM_Allocator<MEM_CacheElementPtr> > MEM_CacheQueue;
typedef typename MEM_CacheQueue::iterator iterator;
/* Check whether element can be destroyed when enforcing cache limits */
@@ -277,11 +280,10 @@ private:
}
else {
int best_match_priority = 0;
- iterator it;
int i;
- for (it = queue.begin(), i = 0; it != queue.end(); it++, i++) {
- MEM_CacheElementPtr elem = *it;
+ for (i = 0; i < queue.size(); i++) {
+ MEM_CacheElementPtr elem = queue[i];
if (!can_destroy_element(elem))
continue;
diff --git a/intern/memutil/MEM_RefCounted.h b/intern/memutil/MEM_RefCounted.h
index 9da0103f6a3..88eaccf9732 100644
--- a/intern/memutil/MEM_RefCounted.h
+++ b/intern/memutil/MEM_RefCounted.h
@@ -41,7 +41,7 @@
* An object with reference counting.
* Base class for objects with reference counting.
* When a shared object is ceated, it has reference count == 1.
- * If the the reference count of a shared object reaches zero, the object self-destructs.
+ * If the reference count of a shared object reaches zero, the object self-destructs.
* The default destructor of this object has been made protected on purpose.
* This disables the creation of shared objects on the stack.
*
@@ -72,7 +72,7 @@ public:
/**
* Decreases the reference count of this object.
- * If the the reference count reaches zero, the object self-destructs.
+ * If the reference count reaches zero, the object self-destructs.
* @return the new reference count.
*/
inline virtual int decRef();
diff --git a/intern/memutil/MEM_RefCountedC-Api.h b/intern/memutil/MEM_RefCountedC-Api.h
index a611482a991..79b0b6efb66 100644
--- a/intern/memutil/MEM_RefCountedC-Api.h
+++ b/intern/memutil/MEM_RefCountedC-Api.h
@@ -64,7 +64,7 @@ extern int MEM_RefCountedIncRef(MEM_TRefCountedObjectPtr shared);
/**
* Decreases the reference count of this object.
- * If the the reference count reaches zero, the object self-destructs.
+ * If the reference count reaches zero, the object self-destructs.
* @param shared The object to query.
* @return The new reference count.
*/
diff --git a/intern/opennl/superlu/heap_relax_snode.c b/intern/opennl/superlu/heap_relax_snode.c
index d4b3e229224..cd88179bbb7 100644
--- a/intern/opennl/superlu/heap_relax_snode.c
+++ b/intern/opennl/superlu/heap_relax_snode.c
@@ -99,7 +99,7 @@ heap_relax_snode (
}
j++;
/* Search for a new leaf */
- while ( descendants[j] != 0 && j < n ) j++;
+ while ( j < n && descendants[j] != 0 ) j++;
}
#if ( PRNTlevel>=1 )
diff --git a/intern/opennl/superlu/relax_snode.c b/intern/opennl/superlu/relax_snode.c
index 49f600533a8..4a9265e0fde 100644
--- a/intern/opennl/superlu/relax_snode.c
+++ b/intern/opennl/superlu/relax_snode.c
@@ -66,7 +66,7 @@ relax_snode (
relax_end[snode_start] = j; /* Last column is recorded */
j++;
/* Search for a new leaf */
- while ( descendants[j] != 0 && j < n ) j++;
+ while ( j < n && descendants[j] != 0 ) j++;
}
/*printf("No of relaxed snodes: %d; relaxed columns: %d\n",
diff --git a/intern/opennl/superlu/smemory.c b/intern/opennl/superlu/smemory.c
index a76f60a1758..c3b28a90e62 100644
--- a/intern/opennl/superlu/smemory.c
+++ b/intern/opennl/superlu/smemory.c
@@ -483,7 +483,7 @@ void
else lword = sizeof(double);
if ( Glu->MemModel == SYSTEM ) {
- new_mem = (void *) SUPERLU_MALLOC(new_len * lword);
+ new_mem = (void *) SUPERLU_MALLOC((size_t)new_len * (size_t)lword);
/* new_mem = (void *) calloc(new_len, lword); */
if ( no_expand != 0 ) {
tries = 0;
@@ -494,7 +494,7 @@ void
if ( ++tries > 10 ) return (NULL);
alpha = Reduce(alpha);
new_len = alpha * *prev_len;
- new_mem = (void *) SUPERLU_MALLOC(new_len * lword);
+ new_mem = (void *) SUPERLU_MALLOC((size_t)new_len * (size_t)lword);
/* new_mem = (void *) calloc(new_len, lword); */
}
}
@@ -509,7 +509,7 @@ void
} else { /* MemModel == USER */
if ( no_expand == 0 ) {
- new_mem = suser_malloc(new_len * lword, HEAD);
+ new_mem = suser_malloc((size_t)new_len * (size_t)lword, HEAD);
if ( NotDoubleAlign(new_mem) &&
(type == LUSUP || type == UCOL) ) {
old_mem = new_mem;
diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp
index ef5cac97eaf..a55ab8785c8 100644
--- a/intern/smoke/intern/FLUID_3D.cpp
+++ b/intern/smoke/intern/FLUID_3D.cpp
@@ -1867,7 +1867,7 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd)
}
-void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame, float *heat,
+void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *heat,
float *r, float *g, float *b, int total_cells, float dt)
{
float burning_rate = *_burning_rate;
@@ -1880,15 +1880,15 @@ void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame
float orig_fuel = fuel[index];
float orig_smoke = smoke[index];
float smoke_emit = 0.0f;
- float react_coord = 0.0f;
-
+ float flame = 0.0f;
+
/* process fuel */
fuel[index] -= burning_rate * dt;
if (fuel[index] < 0.0f) fuel[index] = 0.0f;
/* process reaction coordinate */
if (orig_fuel > FLT_EPSILON) {
react[index] *= fuel[index]/orig_fuel;
- react_coord = react[index];
+ flame = pow(react[index], 0.5f);
}
else {
react[index] = 0.0f;
@@ -1899,19 +1899,11 @@ void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame
smoke_emit = (smoke_emit + 0.5f) * (orig_fuel-fuel[index]) * 0.1f * flame_smoke;
smoke[index] += smoke_emit;
CLAMP(smoke[index], 0.0f, 1.0f);
-
- /* model flame temperature curve from the reaction coordinate (fuel) */
- if (react_coord>0.0f) {
- /* do a smooth falloff for rest of the values */
- flame[index] = pow(react_coord, 0.5f);
- }
- else
- flame[index] = 0.0f;
-
+
/* set fluid temperature from the flame temperature profile */
- if (heat && flame[index])
- heat[index] = (1.0f-flame[index])*ignition_point + flame[index]*temp_max;
-
+ if (heat && flame)
+ heat[index] = (1.0f - flame)*ignition_point + flame*temp_max;
+
/* mix new color */
if (r && smoke_emit > FLT_EPSILON) {
float smoke_factor = smoke[index]/(orig_smoke+smoke_emit);
@@ -1920,4 +1912,22 @@ void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame
b[index] = (b[index] + _flame_smoke_color[2] * smoke_emit) * smoke_factor;
}
}
+}
+
+void FLUID_3D::updateFlame(float *react, float *flame, int total_cells)
+{
+ for (int index = 0; index < total_cells; index++)
+ {
+ /* model flame temperature curve from the reaction coordinate (fuel)
+ * TODO: Would probably be best to get rid of whole "flame" data field.
+ * Currently it's just sqrt mirror of reaction coordinate, and therefore
+ * basically just waste of memory and disk space...
+ */
+ if (react[index]>0.0f) {
+ /* do a smooth falloff for rest of the values */
+ flame[index] = pow(react[index], 0.5f);
+ }
+ else
+ flame[index] = 0.0f;
+ }
} \ No newline at end of file
diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h
index df192c77c38..b0fab50b843 100644
--- a/intern/smoke/intern/FLUID_3D.h
+++ b/intern/smoke/intern/FLUID_3D.h
@@ -214,8 +214,9 @@ struct FLUID_3D
float *_flame_vorticity; // RNA pointer
float *_ignition_temp; // RNA pointer
float *_max_temp; // RNA pointer
- void processBurn(float *fuel, float *smoke, float *react, float *flame, float *heat,
+ void processBurn(float *fuel, float *smoke, float *react, float *heat,
float *r, float *g, float *b, int total_cells, float dt);
+ void updateFlame(float *react, float *flame, int total_cells);
// boundary setting functions
static void copyBorderX(float* field, Vec3Int res, int zBegin, int zEnd);
diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp
index 3a61b3903c3..462af5b12b4 100644
--- a/intern/smoke/intern/smoke_API.cpp
+++ b/intern/smoke/intern/smoke_API.cpp
@@ -88,19 +88,27 @@ extern "C" void smoke_manta_export(SmokeModifierData *smd)
extern "C" void smoke_step(FLUID_3D *fluid, float gravity[3], float dtSubdiv)
{
if (fluid->_fuel) {
- fluid->processBurn(fluid->_fuel, fluid->_density, fluid->_react, fluid->_flame, fluid->_heat,
+ fluid->processBurn(fluid->_fuel, fluid->_density, fluid->_react, fluid->_heat,
fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, (*fluid->_dtFactor)*dtSubdiv);
}
fluid->step(dtSubdiv, gravity);
+
+ if (fluid->_fuel) {
+ fluid->updateFlame(fluid->_react, fluid->_flame, fluid->_totalCells);
+ }
}
extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
{
if (wt->_fuelBig) {
- fluid->processBurn(wt->_fuelBig, wt->_densityBig, wt->_reactBig, wt->_flameBig, 0,
+ fluid->processBurn(wt->_fuelBig, wt->_densityBig, wt->_reactBig, 0,
wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, fluid->_dt);
}
- wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles);
+ wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles);
+
+ if (wt->_fuelBig) {
+ fluid->updateFlame(wt->_reactBig, wt->_flameBig, wt->_totalCellsBig);
+ }
}
extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate,
@@ -606,4 +614,4 @@ extern "C" int cell_index_3D(int index_2d, int sizex,int sizey, int sizez)
return int(sizey * 0.5) * sizex +
(index_2d % (sizex)) +
int(index_2d/(sizex)) * sizex * sizey;
-} \ No newline at end of file
+}
diff --git a/intern/smoke/intern/spectrum.cpp b/intern/smoke/intern/spectrum.cpp
index e1c2b4d1e42..15e4d0cf2e5 100644
--- a/intern/smoke/intern/spectrum.cpp
+++ b/intern/smoke/intern/spectrum.cpp
@@ -363,7 +363,7 @@ static void spectrum_to_xyz(double (*spec_intens)(double wavelength),
Calculate, by Planck's radiation law, the emittance of a black body
of temperature bbTemp at the given wavelength (in metres). */
-double bbTemp = 5000; /* Hidden temperature argument
+static double bbTemp = 5000; /* Hidden temperature argument
to BB_SPECTRUM. */
static double bb_spectrum(double wavelength)
{
diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg
index ed5e84778f9..f67d67f0b1a 100644
--- a/release/datafiles/blender_icons.svg
+++ b/release/datafiles/blender_icons.svg
@@ -27,6 +27,137 @@
<defs
id="defs4">
<linearGradient
+ inkscape:collect="always"
+ id="linearGradient20043">
+ <stop
+ style="stop-color:#f6e18c;stop-opacity:1;"
+ offset="0"
+ id="stop20045" />
+ <stop
+ style="stop-color:#f6e18c;stop-opacity:0;"
+ offset="1"
+ id="stop20047" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient20020">
+ <stop
+ style="stop-color:#f6e18c;stop-opacity:1;"
+ offset="0"
+ id="stop20022" />
+ <stop
+ style="stop-color:#f6e18c;stop-opacity:0;"
+ offset="1"
+ id="stop20024" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18512">
+ <stop
+ id="stop18514"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop18516"
+ offset="1"
+ style="stop-color:#f20000;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18495"
+ inkscape:collect="always">
+ <stop
+ id="stop18497"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop18499"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18479"
+ inkscape:collect="always">
+ <stop
+ id="stop18481"
+ offset="0"
+ style="stop-color:#8d8d8d;stop-opacity:1;" />
+ <stop
+ id="stop18483"
+ offset="1"
+ style="stop-color:#8d8d8d;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18414">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop18416" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop18418" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18370"
+ inkscape:collect="always">
+ <stop
+ id="stop18372"
+ offset="0"
+ style="stop-color:#afafaf;stop-opacity:1;" />
+ <stop
+ id="stop18374"
+ offset="1"
+ style="stop-color:#afafaf;stop-opacity:0;" />
+ </linearGradient>
+ <marker
+ inkscape:stockid="Arrow1Lstart"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Lstart"
+ style="overflow:visible">
+ <path
+ id="path17576"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
+ transform="scale(0.8) translate(12.5,0)" />
+ </marker>
+ <linearGradient
+ id="linearGradient17566"
+ inkscape:collect="always">
+ <stop
+ id="stop17568"
+ offset="0"
+ style="stop-color:#cad8ee;stop-opacity:1;" />
+ <stop
+ id="stop17570"
+ offset="1"
+ style="stop-color:#cad8ee;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17560">
+ <stop
+ id="stop17562"
+ offset="0"
+ style="stop-color:#ffe991;stop-opacity:1;" />
+ <stop
+ id="stop17564"
+ offset="1"
+ style="stop-color:#ffe991;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient17542"
+ inkscape:collect="always">
+ <stop
+ id="stop17544"
+ offset="0"
+ style="stop-color:#799ed3;stop-opacity:1;" />
+ <stop
+ id="stop17546"
+ offset="1"
+ style="stop-color:#799ed3;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
id="linearGradient17265">
<stop
style="stop-color:#ffb769;stop-opacity:1;"
@@ -4796,26 +4927,6 @@
y1="-35.483223"
x2="408.75"
y2="-40.000008" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient37542"
- id="linearGradient17429"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.081988,0,0,1.0833333,-394.58897,440.54169)"
- x1="326.51352"
- y1="32.007874"
- x2="347.91187"
- y2="57.261913" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient319"
- id="linearGradient17431"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1.0983862,0,0,1.0999999,-400.00857,439.95001)"
- x1="317.30908"
- y1="22.7787"
- x2="330.87869"
- y2="38.161732" />
<mask
maskUnits="userSpaceOnUse"
id="mask17570">
@@ -21987,15 +22098,6 @@
y2="360.82117" />
<linearGradient
inkscape:collect="always"
- xlink:href="#linearGradient29757"
- id="linearGradient29763"
- x1="-224.85715"
- y1="205.71428"
- x2="-214.42857"
- y2="206"
- gradientUnits="userSpaceOnUse" />
- <linearGradient
- inkscape:collect="always"
xlink:href="#linearGradient23705-0"
id="linearGradient22892-4"
gradientUnits="userSpaceOnUse"
@@ -29053,6 +29155,1062 @@
id="linearGradient17872"
xlink:href="#linearGradient319-36-40-2-4"
inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient23974-41">
+ <stop
+ id="stop23976-66"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-15"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient319-68">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-221" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-90" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1610-84">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop1611-86" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop1612-6" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient9030-4">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop9032-3" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop9034-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient16500-8">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop16502-0" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop16504-648" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient16605">
+ <stop
+ id="stop16607"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop16609"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient18105-1">
+ <stop
+ id="stop18107-7"
+ offset="0"
+ style="stop-color:#162d50;stop-opacity:1" />
+ <stop
+ id="stop18109-8"
+ offset="1"
+ style="stop-color:#1e3e70;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17542"
+ id="linearGradient18237"
+ gradientUnits="userSpaceOnUse"
+ x1="231.35262"
+ y1="465.73871"
+ x2="246.08743"
+ y2="465.14655"
+ gradientTransform="matrix(0.86988738,-0.49325039,0.49325039,0.86988738,0,0.02266763)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17566"
+ id="linearGradient18239"
+ gradientUnits="userSpaceOnUse"
+ x1="430.78629"
+ y1="290.24094"
+ x2="440.83713"
+ y2="286.97058" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-41"
+ id="linearGradient18243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.728189,0,0,1.727271,-142.53857,-4.802156)"
+ x1="107.39532"
+ y1="58.065113"
+ x2="127.70434"
+ y2="58.065113" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-68"
+ id="linearGradient18245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1000194,0,0,1.0998287,110.29549,-8.6726854)"
+ x1="30.389694"
+ y1="95.008034"
+ x2="65.52562"
+ y2="93.69249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-84"
+ id="linearGradient18247"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-6,0)"
+ x1="483.00034"
+ y1="163"
+ x2="476.68781"
+ y2="162.85956" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030-4"
+ id="linearGradient18249"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(342.00029,383.00889)"
+ x1="123.36729"
+ y1="-219.24783"
+ x2="134.30893"
+ y2="-218.00888" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16500-8"
+ id="linearGradient18251"
+ gradientUnits="userSpaceOnUse"
+ x1="475.00034"
+ y1="155"
+ x2="469.75034"
+ y2="155" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-41"
+ id="linearGradient18253"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(14.285126,-0.22103087)"
+ x1="442.81525"
+ y1="290.49384"
+ x2="436.5"
+ y2="290.5249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105-1"
+ id="linearGradient18255"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(20.285126,-0.22097087)"
+ x1="445.99902"
+ y1="288.5"
+ x2="407.3793"
+ y2="288.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17560-4"
+ id="linearGradient18241-0"
+ gradientUnits="userSpaceOnUse"
+ x1="327.77432"
+ y1="251.04707"
+ x2="335.80118"
+ y2="247.0696" />
+ <linearGradient
+ id="linearGradient17560-4">
+ <stop
+ id="stop17562-3"
+ offset="0"
+ style="stop-color:#ffe991;stop-opacity:1;" />
+ <stop
+ id="stop17564-1"
+ offset="1"
+ style="stop-color:#ffe991;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18370"
+ id="linearGradient18368"
+ x1="432.83759"
+ y1="289.15814"
+ x2="441.44028"
+ y2="283.54819"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ y2="245.78732"
+ x2="335.8941"
+ y1="251.04707"
+ x1="327.77432"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient18313-9"
+ xlink:href="#linearGradient17560-4-9"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient17560-4-9">
+ <stop
+ id="stop17562-3-7"
+ offset="0"
+ style="stop-color:#ffe991;stop-opacity:1;" />
+ <stop
+ id="stop17564-1-4"
+ offset="1"
+ style="stop-color:#ffe991;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18414"
+ id="linearGradient18420"
+ x1="333.8428"
+ y1="253.4225"
+ x2="327.0369"
+ y2="243.12526"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18414-5"
+ id="linearGradient18420-1"
+ x1="333.8428"
+ y1="253.4225"
+ x2="327.0369"
+ y2="243.12526"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient18414-5">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop18416-8" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop18418-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18479"
+ id="linearGradient18476"
+ x1="427.86765"
+ y1="284.7648"
+ x2="431.31277"
+ y2="278.92789"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.46468729,2.0195829)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18495"
+ id="linearGradient18493"
+ x1="323.68958"
+ y1="248.71513"
+ x2="335.125"
+ y2="245.5"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20020"
+ id="linearGradient20026"
+ x1="331.22147"
+ y1="249.03816"
+ x2="336.11465"
+ y2="244.64084"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20043"
+ id="linearGradient20049"
+ x1="148.21956"
+ y1="506.48343"
+ x2="155.67555"
+ y2="506.45177"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ y2="30.023426"
+ x2="278.25537"
+ y1="3.6831069"
+ x1="253.78497"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient39254-5"
+ xlink:href="#linearGradient17555"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient17555">
+ <stop
+ style="stop-color:#000000;stop-opacity:0.49803922;"
+ offset="0"
+ id="stop17557" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.49803922;"
+ offset="1"
+ id="stop17559" />
+ </linearGradient>
+ <radialGradient
+ r="6.9000001"
+ fy="206.40076"
+ fx="756.83508"
+ cy="206.40076"
+ cx="756.83508"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient39256-9"
+ xlink:href="#linearGradient17549"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient17549">
+ <stop
+ id="stop17551"
+ offset="0"
+ style="stop-color:#7f7f7f;stop-opacity:1;" />
+ <stop
+ id="stop17553"
+ offset="1"
+ style="stop-color:#7f7f7f;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ y2="249"
+ x2="93.0625"
+ y1="241.125"
+ x1="87"
+ gradientTransform="translate(670,-33)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient39258-0"
+ xlink:href="#linearGradient17543"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient17543">
+ <stop
+ id="stop17545"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:0.87628865;" />
+ <stop
+ id="stop17547"
+ offset="1.0000000"
+ style="stop-color:#fffffe;stop-opacity:0.0000000;" />
+ </linearGradient>
+ <linearGradient
+ y2="305"
+ x2="758"
+ y1="300.83292"
+ x1="754.28558"
+ gradientTransform="translate(0,-95.999998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16784"
+ xlink:href="#linearGradient17530"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient17530">
+ <stop
+ style="stop-color:#7f7f7f;stop-opacity:1;"
+ offset="0"
+ id="stop17532" />
+ <stop
+ style="stop-color:#7f7f7f;stop-opacity:0;"
+ offset="1"
+ id="stop17534" />
+ </linearGradient>
+ <linearGradient
+ y2="305"
+ x2="758"
+ y1="300.83292"
+ x1="754.28558"
+ gradientTransform="translate(0,-95.999998)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient16880"
+ xlink:href="#linearGradient17530"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18370"
+ id="linearGradient16720"
+ gradientUnits="userSpaceOnUse"
+ x1="432.83759"
+ y1="289.15814"
+ x2="441.44028"
+ y2="283.54819" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-4"
+ id="linearGradient16940"
+ gradientUnits="userSpaceOnUse"
+ x1="258.94861"
+ y1="285.63672"
+ x2="237.92474"
+ y2="261.44183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-4-3"
+ id="linearGradient16943"
+ gradientUnits="userSpaceOnUse"
+ x1="258.94861"
+ y1="285.63672"
+ x2="237.92474"
+ y2="261.44183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17073"
+ id="linearGradient16945"
+ gradientUnits="userSpaceOnUse"
+ x1="240.40633"
+ y1="261.35129"
+ x2="240.41891"
+ y2="273.68066" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16824-1"
+ id="linearGradient16947"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1749798,0,0,-1.2083376,211.53456,46.373264)"
+ x1="4.9106402"
+ y1="8.3244486"
+ x2="8.5571098"
+ y2="12.702949" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16850-5"
+ id="linearGradient16949"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0895881,0,0,-1.1205216,210.97915,45.429444)"
+ x1="5.1938357"
+ y1="8.7375145"
+ x2="7.5092869"
+ y2="11.3536" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756-2-8"
+ id="linearGradient16951"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0850614,-0.0361511,0.02414524,-1.0240584,201.95206,45.554604)"
+ x1="4.155818"
+ y1="5.3683834"
+ x2="6.5799594"
+ y2="7.7035389" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43009-7"
+ id="linearGradient16953"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.7118707,-0.00216237,-0.00556412,-1.3288889,207.1884,56.557374)"
+ x1="5.6458621"
+ y1="11.418204"
+ x2="7.3551626"
+ y2="13.092201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17073"
+ id="linearGradient17001"
+ gradientUnits="userSpaceOnUse"
+ x1="240.40633"
+ y1="261.35129"
+ x2="240.41891"
+ y2="273.68066" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16824-1"
+ id="linearGradient17003"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.1749798,0,0,-1.2083376,211.53456,46.373264)"
+ x1="4.9106402"
+ y1="8.3244486"
+ x2="8.5571098"
+ y2="12.702949" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16850-5"
+ id="linearGradient17005"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0895881,0,0,-1.1205216,210.97915,45.429444)"
+ x1="5.1938357"
+ y1="8.7375145"
+ x2="7.5092869"
+ y2="11.3536" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756-2-8"
+ id="linearGradient17007"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.0850614,-0.0361511,0.02414524,-1.0240584,201.95206,45.554604)"
+ x1="4.155818"
+ y1="5.3683834"
+ x2="6.5799594"
+ y2="7.7035389" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43009-7"
+ id="linearGradient17009"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.7118707,-0.00216237,-0.00556412,-1.3288889,207.1884,56.557374)"
+ x1="5.6458621"
+ y1="11.418204"
+ x2="7.3551626"
+ y2="13.092201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient43009-7"
+ id="linearGradient17014"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.7118707,0.00216237,0.00556412,1.3288889,342.98254,460.43356)"
+ x1="5.6458621"
+ y1="11.418204"
+ x2="7.3551626"
+ y2="13.092201" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20756-2-8"
+ id="linearGradient17018"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0850614,0.0361511,-0.02414524,1.0240584,348.21888,471.43633)"
+ x1="4.155818"
+ y1="5.3683834"
+ x2="6.5799594"
+ y2="7.7035389" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient16850-5"
+ id="linearGradient17022"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0895881,0,0,1.1205216,339.19179,471.56149)"
+ x1="5.1938357"
+ y1="8.7375145"
+ x2="7.5092869"
+ y2="11.3536" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#radialGradient16824-1"
+ id="linearGradient17026"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1749798,0,0,1.2083376,338.63638,470.61767)"
+ x1="4.9106402"
+ y1="8.3244486"
+ x2="8.5571098"
+ y2="12.702949" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17073"
+ id="linearGradient17030"
+ gradientUnits="userSpaceOnUse"
+ x1="240.40633"
+ y1="261.35129"
+ x2="240.41891"
+ y2="273.68066"
+ gradientTransform="matrix(-0.9285719,0,0,-0.9072647,533.78355,492.13787)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17073"
+ id="linearGradient17055"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9285719,0,0,-0.9072647,533.78355,492.13787)"
+ x1="240.40633"
+ y1="261.35129"
+ x2="240.41891"
+ y2="273.68066" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-4"
+ id="linearGradient17057"
+ gradientUnits="userSpaceOnUse"
+ x1="258.94861"
+ y1="285.63672"
+ x2="237.92474"
+ y2="261.44183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1610-4-3"
+ id="linearGradient17059"
+ gradientUnits="userSpaceOnUse"
+ x1="258.94861"
+ y1="285.63672"
+ x2="237.92474"
+ y2="261.44183" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17073"
+ id="linearGradient17079"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.9285719,0,0,-0.9072647,533.78355,492.13787)"
+ x1="240.40633"
+ y1="261.35129"
+ x2="240.41891"
+ y2="273.68066" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-29-7-8"
+ id="linearGradient17149"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,461.01011,-167)"
+ x1="368.97806"
+ y1="249.99998"
+ x2="393.85385"
+ y2="249.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854-0-6-9"
+ id="linearGradient17151"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,461.01011,-167)"
+ x1="388.86502"
+ y1="244.02"
+ x2="391.43173"
+ y2="239.2338" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-29-7-8"
+ id="linearGradient17157"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,461.01011,-167)"
+ x1="368.97806"
+ y1="249.99998"
+ x2="393.85385"
+ y2="249.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854-0-6-9"
+ id="linearGradient17159"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,461.01011,-167)"
+ x1="388.86502"
+ y1="244.02"
+ x2="391.43173"
+ y2="239.2338" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27854-0-6-9"
+ id="linearGradient17162"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,782.48614,-14.46331)"
+ x1="388.86502"
+ y1="244.02"
+ x2="391.43173"
+ y2="239.2338" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-29-7-8"
+ id="linearGradient17165"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,1,-1,0,782.48614,-14.46331)"
+ x1="368.97806"
+ y1="249.99998"
+ x2="393.85385"
+ y2="249.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-29-1"
+ id="linearGradient17175"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,461.01011,-167)"
+ x1="409.93588"
+ y1="249.99998"
+ x2="385.11514"
+ y2="249.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-29-1"
+ id="linearGradient17181"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,461.01011,-167)"
+ x1="409.93588"
+ y1="249.99998"
+ x2="385.11514"
+ y2="249.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542-29-1"
+ id="linearGradient17185"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-1,-1,0,740.48614,764.46331)"
+ x1="409.93588"
+ y1="249.99998"
+ x2="385.11514"
+ y2="249.99998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18414"
+ id="linearGradient17206"
+ gradientUnits="userSpaceOnUse"
+ x1="333.8428"
+ y1="253.4225"
+ x2="327.0369"
+ y2="243.12526" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18479"
+ id="linearGradient17208"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.46468729,2.0195829)"
+ x1="427.86765"
+ y1="284.7648"
+ x2="431.31277"
+ y2="278.92789" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18495"
+ id="linearGradient17210"
+ gradientUnits="userSpaceOnUse"
+ x1="323.68958"
+ y1="248.71513"
+ x2="335.125"
+ y2="245.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20020"
+ id="linearGradient17212"
+ gradientUnits="userSpaceOnUse"
+ x1="331.22147"
+ y1="249.03816"
+ x2="336.11465"
+ y2="244.64084" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17555"
+ id="linearGradient17215"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.888889,0,0,1,513.5,184.50451)"
+ x1="253.78497"
+ y1="3.6831069"
+ x2="278.25537"
+ y2="30.023426" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17549"
+ id="radialGradient17217"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.3817213,-0.4377393,0.4780868,0.4169055,368.09749,451.76937)"
+ cx="756.83508"
+ cy="206.40076"
+ fx="756.83508"
+ fy="206.40076"
+ r="6.9000001" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17543"
+ id="linearGradient17219"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(670,-33)"
+ x1="87"
+ y1="241.125"
+ x2="93.0625"
+ y2="249" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient17530"
+ id="linearGradient17221"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-95.999998)"
+ x1="754.28558"
+ y1="300.83292"
+ x2="758"
+ y2="305" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18370"
+ id="linearGradient17223"
+ gradientUnits="userSpaceOnUse"
+ x1="432.83759"
+ y1="289.15814"
+ x2="441.44028"
+ y2="283.54819" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18370"
+ id="linearGradient17225"
+ gradientUnits="userSpaceOnUse"
+ x1="432.83759"
+ y1="289.15814"
+ x2="441.44028"
+ y2="283.54819" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient20020"
+ id="linearGradient17236"
+ gradientUnits="userSpaceOnUse"
+ x1="331.22147"
+ y1="249.03816"
+ x2="336.11465"
+ y2="244.64084"
+ gradientTransform="translate(-0.01702303,0.01679543)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18495"
+ id="linearGradient17239"
+ gradientUnits="userSpaceOnUse"
+ x1="323.68958"
+ y1="248.71513"
+ x2="335.125"
+ y2="245.5"
+ gradientTransform="translate(4.554861e-6,8.3724231e-8)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18479"
+ id="linearGradient17243"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0087429,0,0,0.97482999,-108.39487,-30.511198)"
+ x1="427.86765"
+ y1="284.7648"
+ x2="431.31277"
+ y2="278.92789" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18414"
+ id="linearGradient17247"
+ gradientUnits="userSpaceOnUse"
+ x1="333.8428"
+ y1="253.4225"
+ x2="327.0369"
+ y2="243.12526"
+ gradientTransform="translate(4.554861e-6,8.3724231e-8)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient17442"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.081988,0,0,1.0833333,-394.58897,440.54169)"
+ x1="326.51352"
+ y1="32.007874"
+ x2="347.91187"
+ y2="57.261913" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient17444"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0983862,0,0,1.0999999,-400.00857,439.95001)"
+ x1="317.30908"
+ y1="22.7787"
+ x2="330.87869"
+ y2="38.161732" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient18105-2-9"
+ id="linearGradient18618"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.04935997,1.9792524)"
+ x1="492.95264"
+ y1="267.42996"
+ x2="496.73859"
+ y2="270.36874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient15531-9-5"
+ id="linearGradient18620"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,383.02168,218.70121)"
+ x1="116.41398"
+ y1="53.197613"
+ x2="109.72195"
+ y2="43.434277" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-27-5"
+ id="linearGradient18622"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993234,0,0,1.0050357,383.02168,218.70121)"
+ x1="116.41398"
+ y1="53.197613"
+ x2="104.06187"
+ y2="53.601826" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27277-1-8"
+ id="linearGradient18624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.04935997,1.9965991)"
+ x1="501.19104"
+ y1="270.69452"
+ x2="488.93024"
+ y2="272.60611" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient21327-63-5"
+ id="linearGradient18626"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.04935997,0.97920913)"
+ x1="500.71924"
+ y1="270.24997"
+ x2="477"
+ y2="274" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient27301-6-2"
+ id="linearGradient18628"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.04936017,-0.04091017)"
+ x1="497"
+ y1="264"
+ x2="507.125"
+ y2="276.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37542"
+ id="linearGradient18663"
+ gradientUnits="userSpaceOnUse"
+ x1="98.858559"
+ y1="80.045052"
+ x2="135.00615"
+ y2="122.92735" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18665"
+ gradientUnits="userSpaceOnUse"
+ x1="130.75166"
+ y1="245.03757"
+ x2="129.24866"
+ y2="243.31177" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319"
+ id="linearGradient18667"
+ gradientUnits="userSpaceOnUse"
+ x1="126.37006"
+ y1="112.31642"
+ x2="144.22272"
+ y2="129.82761" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient9030"
+ id="linearGradient18669"
+ gradientUnits="userSpaceOnUse"
+ x1="190.68166"
+ y1="244.14676"
+ x2="174.75458"
+ y2="226.33672" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-39"
+ id="linearGradient18721-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,244.3928,19.4113)"
+ x1="-88.73024"
+ y1="-120.6127"
+ x2="-78.787354"
+ y2="-128.30418" />
+ <linearGradient
+ id="linearGradient23974-39">
+ <stop
+ id="stop23976-8"
+ offset="0"
+ style="stop-color:#2561b7;stop-opacity:1;" />
+ <stop
+ id="stop23978-23"
+ offset="1"
+ style="stop-color:#f9fbff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320-9"
+ id="linearGradient18728-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,222.97812,19.5574)"
+ x1="68.688324"
+ y1="51.42366"
+ x2="72.671516"
+ y2="55.501457" />
+ <linearGradient
+ id="linearGradient31320-9">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop31322-6" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop31324-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262-6"
+ id="linearGradient18765-5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,309.42934,-349.44584)"
+ x1="-26.207859"
+ y1="252.77303"
+ x2="-5.4963508"
+ y2="253.15045" />
+ <linearGradient
+ id="linearGradient14262-6">
+ <stop
+ id="stop14264-29"
+ offset="0"
+ style="stop-color:#2661b6;stop-opacity:1;" />
+ <stop
+ id="stop14266-9"
+ offset="1"
+ style="stop-color:#c1d7f8;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-61"
+ id="linearGradient18712-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="103.65562"
+ y1="49.547874"
+ x2="120.79755"
+ y2="57.84819" />
+ <linearGradient
+ id="linearGradient319-61">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop320-47" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop321-45" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient23974-39"
+ id="linearGradient16862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,244.3928,19.4113)"
+ x1="-88.73024"
+ y1="-120.6127"
+ x2="-78.787354"
+ y2="-128.30418" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient31320-9"
+ id="linearGradient16864"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,222.97812,19.5574)"
+ x1="68.688324"
+ y1="51.42366"
+ x2="72.671516"
+ y2="55.501457" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient14262-6"
+ id="linearGradient16866"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.004219,0,0,0.980922,309.42934,-349.44584)"
+ x1="-26.207859"
+ y1="252.77303"
+ x2="-5.4963508"
+ y2="253.15045" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient319-61"
+ id="linearGradient16868"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.8167109,0,0,0.8433415,239.34332,-149.78578)"
+ x1="103.65562"
+ y1="49.547874"
+ x2="120.79755"
+ y2="57.84819" />
</defs>
<sodipodi:namedview
id="base"
@@ -29064,14 +30222,14 @@
objecttolerance="10000"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="8"
- inkscape:cx="475.21328"
- inkscape:cy="281.82297"
+ inkscape:zoom="7.2069341"
+ inkscape:cx="381.96928"
+ inkscape:cy="408.8621"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1920"
- inkscape:window-height="980"
+ inkscape:window-height="995"
inkscape:window-x="0"
inkscape:window-y="28"
inkscape:snap-nodes="false"
@@ -37073,7 +38231,7 @@
<g
transform="matrix(0,1,1,0,-174,194)"
style="display:inline;enable-background:new"
- id="g106468-0">
+ id="ICON_DOWNARROW_HLT">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
@@ -37108,7 +38266,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_redone 5a.png"
transform="translate(440.42789,-242.41778)"
- id="g14713">
+ id="ICON_FILE_BACKUP">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
@@ -37222,7 +38380,7 @@
id="path14745" />
<path
transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1.0000004 0 1 1 -2,0 1,1.0000004 0 1 1 2,0 z"
sodipodi:ry="1.0000004"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -37239,7 +38397,7 @@
</g>
<path
transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -37261,11 +38419,11 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(3.25,0,0,3.25,-62.875,313.125)" />
<path
transform="matrix(2,0,0,2,-46,385)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -37281,7 +38439,7 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
<path
inkscape:connector-curvature="0"
@@ -37301,149 +38459,7 @@
inkscape:export-ydpi="90" />
</g>
<g
- style="display:inline;enable-background:new"
- id="g14765"
- inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_big_redone 5a.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- transform="translate(1090.1244,-109.28264)">
- <rect
- ry="0"
- rx="2.4004419"
- y="336.28265"
- x="-78.124435"
- height="48"
- width="48"
- id="rect14767"
- style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- sodipodi:nodetypes="cccccc"
- id="path14769"
- d="m -60.624426,339.78264 22.999995,0 0,41 -32.999995,0 0,-31 10,-10 z"
- style="fill:url(#linearGradient14814);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccc"
- id="path14771"
- style="opacity:0.7;fill:none;stroke:url(#linearGradient14816);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.56470588"
- d="m -38.874431,340.78264 c -4.875,0 -21.749995,0 -21.749995,0 m -8.9447,8.5 -0.0553,30"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011-8)"
- d="m 115,444 12,0 -1,-11 -11,11 z"
- id="path14773"
- sodipodi:nodetypes="cccc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- clip-path="url(#clipPath13106-0)"
- inkscape:connector-curvature="0"
- transform="translate(-186.12444,-93.717362)" />
- <path
- sodipodi:nodetypes="ccc"
- id="path14775"
- style="fill:none;stroke:url(#linearGradient14818);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m -68.624426,350.03264 9,-2.5 0,-6"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- clip-path="none"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- d="m -70.624426,349.03264 0,31.75 32.999995,0 0,-41 -23.749995,0 -9.25,9.25 z"
- style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- id="path14777"
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011-8)"
- d="m 116,443 11,1 -2,-10 -9,9 z"
- id="path14779"
- sodipodi:nodetypes="cccc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- clip-path="url(#clipPath13106-0)"
- inkscape:connector-curvature="0"
- transform="translate(-186.12444,-93.717362)" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- sodipodi:nodetypes="cccccc"
- id="path14781"
- d="m -70.124426,349.28264 0.0108,0.72434 9.9892,-2.72434 0,-7 -1,0 -9,9 z"
- style="fill:#ffffff;fill-opacity:0.75294118;fill-rule:evenodd;stroke:none"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- d="m -38.624431,341.28264 0,38.5 -30.499995,0"
- style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- id="path14783"
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0" />
- <g
- transform="matrix(0.5406242,0,0,0.5829534,-67.987756,347.93806)"
- inkscape:label="Layer 1"
- id="g14785">
- <path
- sodipodi:type="arc"
- style="opacity:0.54857142;fill:url(#radialGradient14820);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path14788"
- sodipodi:cx="28.019106"
- sodipodi:cy="38.98439"
- sodipodi:rx="15.467961"
- sodipodi:ry="5.3033009"
- d="m 43.487067,38.98439 c 0,2.928932 -6.925242,5.303301 -15.467961,5.303301 -8.542719,0 -15.467961,-2.374369 -15.467961,-5.303301 0,-2.928932 6.925242,-5.303301 15.467961,-5.303301 8.542719,0 15.467961,2.374369 15.467961,5.303301 z"
- transform="matrix(1.274286,0,0,1.377124,-7.569123,-16.70193)" />
- <path
- style="fill:#f57900;fill-rule:evenodd;stroke:#aa4400;stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
- id="path14790"
- d="m 16.048489,28.093447 c 0.0098,0.576682 0.196474,1.697902 0.471116,2.577425 0.581566,1.854137 1.56684,3.572658 2.939126,5.086496 1.407488,1.553118 3.138519,2.803227 5.139315,3.68976 2.105357,0.931573 4.384795,1.407488 6.750134,1.403741 2.365339,-0.005 4.644601,-0.488686 6.74896,-1.427017 2.00002,-0.895288 3.731043,-2.148391 5.13754,-3.705517 1.369207,-1.519844 2.352576,-3.241114 2.934089,-5.096258 0.294262,-0.938353 0.476921,-1.889392 0.553238,-2.845308 0.07331,-0.939306 0.04204,-1.883511 -0.09183,-2.823792 -0.259981,-1.835599 -0.896294,-3.556847 -1.872652,-5.12758 -0.895541,-1.441699 -2.047808,-2.70454 -3.417268,-3.766975 0,0 0.002,-0.002 0.002,-0.002 0,0 -13.828458,-10.6197195 -13.828458,-10.6197195 -0.01176,-0.00978 -0.02252,-0.019551 -0.03529,-0.028344 -0.909003,-0.6959264 -3.879837,-0.7738945 -4.87679,-0.075035 -1.01067,0.7057021 -1.091821,1.8092613 -0.195527,2.5482146 1.899775,1.4997633 2.656207,2.2801589 4.566507,3.7797379 0,0 -14.852491,0.167033 -14.852491,0.167033 -1.994685,0 -3.1682609,0.947915 -3.4153947,2.333683 -0.2180771,1.222836 0.7479213,2.738129 2.4800217,2.738129 2.956573,0.0039 5.942111,-0.0069 8.909215,-0.01272 0,0 -16.01999,12.453223 -16.01999,12.453223 -0.020527,0.01564 -0.041053,0.02933 -0.06158,0.04497 -1.4974197,1.148389 -1.9831951,3.059322 -1.0399808,4.268393 0.9598323,1.22959 2.9977653,1.230588 4.5147288,0.006 0,0 8.677593,-7.102098 8.677593,-7.102098 0,0 -0.12511,0.959824 -0.116333,1.535532 l 1e-6,2.6e-5 0,0 0,0 z"
- sodipodi:nodetypes="csssssssssscccsscccscccssccc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:type="arc"
- style="fill:url(#linearGradient14822);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path14792"
- sodipodi:cx="31.1875"
- sodipodi:cy="25.75"
- sodipodi:rx="11.5625"
- sodipodi:ry="10.125"
- d="m 42.75,25.75 c 0,5.591883 -5.176708,10.125 -11.5625,10.125 -6.385792,0 -11.5625,-4.533117 -11.5625,-10.125 0,-5.591883 5.176708,-10.125 11.5625,-10.125 6.385792,0 11.5625,4.533117 11.5625,10.125 z"
- transform="matrix(0.8018194,0,0,0.8471126,6.257567,4.5089892)" />
- <path
- sodipodi:nodetypes="csssssscssscsssccssscscccsccssssccscsscccssssc"
- id="path14794"
- d="m 25.8125,6.40625 c -0.334829,4.572e-4 -0.72202,0.089606 -0.90625,0.21875 4.5e-4,0.010412 4.5e-4,0.020838 0,0.03125 -0.212626,0.1484635 -0.188235,0.1956271 -0.1875,0.1875 0.0092,0.010621 -0.0072,-4.246e-4 0.03125,0.03125 0.01962,0.00828 0.03527,0.012546 0.0625,0.03125 0.01676,0.01151 0.01357,0.014555 0.03125,0.03125 0.193748,0.1576058 4.954976,4.005164 4.954976,4.005164 0.489837,0.39864 0.677395,1.066352 0.46875,1.65625 -0.115662,0.32703 -0.422813,0.541217 -0.6875,0.59375 -0.264687,0.05253 -0.498447,0.03054 -0.71875,0.03125 -5.639658,0.05119 -16.87989,0.03851 -16.87989,0.03851 -0.4102,2.75e-4 -0.935835,0.115997 -1.34375,0.34375 -0.407915,0.227753 -0.6637862,0.523861 -0.6875002,0.90625 -0.024417,0.393728 0.098829,0.605767 0.3437502,0.78125 0.244921,0.175483 0.614978,0.25 0.875,0.25 0,0 8.8125,0 8.8125,0 0.600305,-7.28e-4 1.223895,0.311058 1.4375,0.9375 0.04676,0.137121 0.06335,0.269976 0.0625,0.40625 -8.49e-4,0.136274 -0.02214,0.268794 -0.09375,0.375 -0.143211,0.212412 -0.319507,0.298568 -0.5,0.4375 0,0 -15.7871819,12.746851 -15.856336,12.800078 C 5.0310984,30.500117 5,30.53125 5,30.53125 5.0100745,30.519077 5.000335,30.499512 5,30.5 L 4.8125,30.3125 c 0.012336,0.02165 0.014481,0.03307 0.03125,0.0625 0.063558,0.0774 0.125,0.15625 0.125,0.15625 -0.00585,0.0056 -0.031233,0.03124 -0.03125,0.03125 0,0 -0.043442,-0.09921 -0.09375,-0.1875 0.037843,0.09884 0.06253,0.218739 0.0625,0.21875 -0.4662091,0.37119 -0.7783348,0.889746 -0.875,1.28125 -0.1043319,0.422581 -0.046,0.62455 0.125,0.84375 0.2999827,0.384295 1.3975356,0.595547 2.40625,-0.21875 0,0 8.65625,-7.09375 8.65625,-7.09375 0.473718,-0.387074 1.1446,-0.458625 1.6875,-0.15625 0.544608,0.303331 0.798054,0.927572 0.71875,1.53125 0,0 -0.0626,0.908319 -0.0625,1.25 2e-6,0.0085 -1.19e-4,0.02348 0,0.03125 0.192796,2.523718 1.400736,4.762818 3.03125,6.71875 2.801818,3.089095 6.627659,4.401619 10.75,4.5625 4.113324,-0.043 7.964529,-1.606111 10.75,-4.625 2.546631,-3.125326 3.513872,-6.363859 3.15625,-9.375 C 44.891575,22.325847 43.222923,19.516566 40.4375,17.25 35.951885,13.599946 31.206991,10.168434 26.59375,6.625 26.57515,6.610386 26.56455,6.59802 26.5625,6.59375 26.43835,6.498703 26.144223,6.4057899 25.8125,6.40625 z"
- style="opacity:0.4857143;fill:none;stroke:url(#linearGradient14825);stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#3465a4;fill-rule:evenodd;stroke:none"
- id="path14796"
- d="m 25.708956,26.064593 c 0.07649,-1.397943 0.759369,-2.631914 1.78592,-3.505519 1.010226,-0.858782 2.366788,-1.383145 3.848625,-1.383145 1.480894,0 2.837456,0.524363 3.847446,1.383145 1.027685,0.873605 1.709741,2.106651 1.787122,3.504594 0.07927,1.438713 -0.49591,2.77459 -1.504012,3.764001 -1.027686,1.007933 -2.493008,1.640678 -4.130556,1.640678 -1.63849,0 -3.103814,-0.632745 -4.131451,-1.640678 -1.00914,-0.989411 -1.58234,-2.325288 -1.503094,-3.763076 l 0,0 0,0 0,0 z"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.51999996;fill:url(#radialGradient14827);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 25.8125,6.03125 c -0.404852,5.53e-4 -2.204797,-0.059029 -2.48145,0.1349032 -0.280209,0.195652 -0.335403,0.376484 -0.34375,0.46875 -0.0083,0.092266 -0.01539,0.17648 0.1875,0.34375 0.01899,0.015735 0.04457,0.014317 0.0625,0.03125 0.124258,0.101028 4.748869,4.1248618 4.748869,4.1248618 0.373658,0.304091 0.504393,0.795817 0.34375,1.25 -0.160635,0.454191 -0.580748,0.373449 -1.0625,0.375 -5.634142,0.05114 -15.087371,-0.129601 -15.087371,-0.129601 -0.952967,6.38e-4 -2.339958,0.524782 -2.4062504,1.59375 -0.063562,1.024947 0.9247974,1.4375 1.5937504,1.4375 0,-1e-6 8.8125,0 8.8125,0 0.488364,-5.92e-4 0.936141,0.225277 1.09375,0.6875 0.157609,0.462231 -0.01926,0.514621 -0.40625,0.8125 0,0 -16.086298,13.088586 -16.086298,13.088586 -0.00142,0.0014 -0.029829,-0.0014 -0.03125,0 -0.064037,0.04879 -0.054226,0.04875 -0.03125,0.03125 -0.5536758,0.424619 -0.9087886,1.004019 -1.03125,1.5 -0.1224536,0.495981 -0.04661,0.856152 0.1875,1.15625 0.4788333,0.613413 1.777612,0.754857 2.90625,-0.15625 1e-7,10e-7 8.65625,-7.09375 8.65625,-7.09375 0.361955,-0.295753 0.872897,-0.352437 1.28125,-0.125 0.408345,0.227436 0.623381,0.692814 0.5625,1.15625 0,-1e-6 -0.0997,0.953636 -0.09375,1.34375 0.09498,1.301756 0.451616,2.521825 0.989039,3.664234 C 20.799917,36.321089 27.770982,19.392853 44.1875,21.03125 43.339652,19.54368 42.151282,18.185293 40.65625,16.96875 36.159865,13.309932 31.42016,9.882897 26.8125,6.34375 26.805335,6.338858 26.788292,6.317553 26.78125,6.3125 26.570707,6.151312 26.216591,6.030689 25.8125,6.03125 z"
- id="path14798"
- sodipodi:nodetypes="csssscsccsscsccssssscsscccsssc"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- <g
- id="g20347"
+ id="ICON_SMOOTHCURVE"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -37477,7 +38493,7 @@
</g>
</g>
<g
- id="g20291"
+ id="ICON_LINCURVE"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -37509,7 +38525,7 @@
</g>
</g>
<g
- id="g20301"
+ id="ICON_SHARPCURVE"
transform="translate(0,2)">
<rect
y="176"
@@ -37543,7 +38559,7 @@
</g>
</g>
<g
- id="g20337"
+ id="ICON_SPHERECURVE"
transform="translate(0,2)">
<rect
y="176"
@@ -37564,7 +38580,7 @@
sodipodi:cy="40"
sodipodi:rx="6"
sodipodi:ry="6"
- d="m 36.5,40 c 0,3.313708 -2.686292,6 -6,6 -3.313708,0 -6,-2.686292 -6,-6 0,0 0,0 0,0"
+ d="m 36.5,40 a 6,6 0 1 1 -12,0"
sodipodi:start="0"
sodipodi:end="3.1415927"
sodipodi:open="true"
@@ -37580,7 +38596,7 @@
sodipodi:open="true"
sodipodi:end="3.1415927"
sodipodi:start="0"
- d="m 36.5,40 c 0,3.313708 -2.686292,6 -6,6 -3.313708,0 -6,-2.686292 -6,-6 0,0 0,0 0,0"
+ d="m 36.5,40 a 6,6 0 1 1 -12,0"
sodipodi:ry="6"
sodipodi:rx="6"
sodipodi:cy="40"
@@ -37591,7 +38607,7 @@
</g>
</g>
<g
- id="g20311"
+ id="ICON_ROOTCURVE"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -37608,7 +38624,7 @@
sodipodi:open="true"
sodipodi:end="3.1415927"
sodipodi:start="0"
- d="m 36.5,40 c 0,3.313708 -2.686292,6 -6,6 -3.313708,0 -6,-2.686292 -6,-6 0,0 0,0 0,0"
+ d="m 36.5,40 a 6,6 0 1 1 -12,0"
sodipodi:ry="6"
sodipodi:rx="6"
sodipodi:cy="40"
@@ -37632,7 +38648,7 @@
sodipodi:cy="40"
sodipodi:rx="6"
sodipodi:ry="6"
- d="m 36.5,40 c 0,3.313708 -2.686292,6 -6,6 -3.313708,0 -6,-2.686292 -6,-6 0,0 0,0 0,0"
+ d="m 36.5,40 a 6,6 0 1 1 -12,0"
sodipodi:start="0"
sodipodi:end="3.1415927"
sodipodi:open="true" />
@@ -37640,7 +38656,7 @@
</g>
<g
style="display:inline"
- id="g18862"
+ id="ICON_NOCURVE"
transform="translate(259,151)">
<rect
y="28"
@@ -37675,7 +38691,7 @@
</g>
<g
style="display:inline"
- id="g18856"
+ id="ICON_RNDCURVE"
transform="translate(260,151)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -37709,7 +38725,7 @@
</g>
</g>
<g
- id="g33683"
+ id="ICON_PROP_CON"
transform="translate(0,2)">
<rect
y="176"
@@ -37735,7 +38751,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -37753,14 +38769,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
</g>
<g
- id="g33690"
+ id="ICON_PROP_ON"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -37787,7 +38803,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -37796,7 +38812,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -37810,7 +38826,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -37828,7 +38844,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -37841,14 +38857,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
</g>
<g
- id="g12431"
+ id="ICON_OUTLINER_OB_EMPTY"
transform="translate(0,128)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -37884,7 +38900,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
transform="matrix(1.0911926,0,0,1.176776,253.08415,-79.548088)"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
sodipodi:ry="1.5"
sodipodi:rx="1.5"
sodipodi:cy="14.5"
@@ -38042,7 +39058,7 @@
</g>
</g>
<g
- id="g24997"
+ id="ICON_OUTLINER_OB_CURVE"
transform="translate(0,128)">
<rect
ry="0"
@@ -38153,7 +39169,7 @@
</g>
</g>
<g
- id="g10687"
+ id="ICON_OUTLINER_DATA_CURVE"
transform="translate(0,128)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -38231,7 +39247,7 @@
</g>
</g>
<g
- id="g21376"
+ id="ICON_GHOST"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -38328,10 +39344,7 @@
</g>
</g>
<g
- id="g10203"
- transform="translate(-211.20006,170)" />
- <g
- id="g21567"
+ id="ICON_ROTATECOLLECTION"
transform="translate(-0.9687515,1.9789998)">
<g
transform="matrix(1.0019536,0,0,1,-173.76637,169.95095)"
@@ -38351,7 +39364,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -38376,7 +39389,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -38385,7 +39398,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -38437,7 +39450,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -38454,7 +39467,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -38495,7 +39508,7 @@
</g>
</g>
<g
- id="g21647"
+ id="ICON_ROTATECENTER"
transform="translate(-1,1.9790001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -38527,7 +39540,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -38536,7 +39549,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -38556,7 +39569,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -38573,7 +39586,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -38614,7 +39627,7 @@
</g>
</g>
<g
- id="g21623"
+ id="ICON_ROTACTIVE"
transform="translate(-0.9999786,1.9982099)">
<g
transform="matrix(0.9999986,0,0,1,-170.19957,169.98079)"
@@ -38644,7 +39657,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -38659,7 +39672,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -38676,7 +39689,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -38698,7 +39711,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -38707,7 +39720,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -38754,7 +39767,7 @@
</g>
</g>
<g
- id="g21519"
+ id="ICON_CURSOR"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
@@ -38778,7 +39791,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 141.08637,118 c 0,5.0181 -4.06811,9.08607 -9.08637,9.08607 -5.01826,0 -9.08637,-4.06797 -9.08637,-9.08607 0,-5.0181 4.06811,-9.08607 9.08637,-9.08607 5.01826,0 9.08637,4.06797 9.08637,9.08607 z"
+ d="m 141.08637,118 a 9.0863705,9.0860729 0 1 1 -18.17274,0 9.0863705,9.0860729 0 1 1 18.17274,0 z"
sodipodi:ry="9.0860729"
sodipodi:rx="9.0863705"
sodipodi:cy="118"
@@ -38804,113 +39817,14 @@
sodipodi:cy="118"
sodipodi:rx="9.0863705"
sodipodi:ry="9.0860729"
- d="m 141.08637,118 c 0,5.0181 -4.06811,9.08607 -9.08637,9.08607 -5.01826,0 -9.08637,-4.06797 -9.08637,-9.08607 0,-5.0181 4.06811,-9.08607 9.08637,-9.08607 5.01826,0 9.08637,4.06797 9.08637,9.08607 z"
+ d="m 141.08637,118 a 9.0863705,9.0860729 0 1 1 -18.17274,0 9.0863705,9.0860729 0 1 1 18.17274,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
</g>
<g
- id="g21663"
- transform="translate(0,2)">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect21661"
- width="16"
- height="16"
- x="215"
- y="176" />
- <g
- transform="translate(-87.98837,-19.85)"
- id="g21392"
- style="display:inline">
- <g
- id="g11189"
- style="opacity:0.05"
- transform="translate(-62.011627,236.84995)">
- <rect
- style="fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect11191"
- width="2.9998775"
- height="3"
- x="366.5"
- y="-39.5"
- ry="1.375"
- rx="1.375" />
- <rect
- ry="1.375"
- y="-39.5"
- x="371.5"
- height="3"
- width="2.9998775"
- id="rect11193"
- style="fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- rx="1.375" />
- <rect
- style="fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect11195"
- width="2.9998775"
- height="3"
- x="376.5"
- y="-39.5"
- ry="1.375"
- rx="1.375" />
- </g>
- <rect
- style="fill:none;stroke:#22467e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect11197"
- width="2.9998775"
- height="3"
- x="304.48837"
- y="197.34995"
- ry="1.375"
- rx="1.375" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="path11199"
- d="m 304.98827,197.84994 c 0.6667,0 1.3334,1e-5 2.0001,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.6667,0 -1.3334,-1e-5 -2.0001,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
- style="fill:#c3dbff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- inkscape:connector-curvature="0" />
- <rect
- ry="1.375"
- y="197.34995"
- x="309.48837"
- height="3"
- width="2.9998775"
- id="rect11201"
- style="fill:none;stroke:#22467e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- rx="1.375" />
- <path
- style="fill:#c3dbff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- d="m 309.98827,197.84994 c 0.6667,0 1.3334,1e-5 2.0001,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.6667,0 -1.3334,-1e-5 -2.0001,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
- id="path11203"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <rect
- style="fill:none;stroke:#22467e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect11205"
- width="2.9998775"
- height="3"
- x="314.48837"
- y="197.34995"
- ry="1.375"
- rx="1.375" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="path11207"
- d="m 314.98827,197.84994 c 0.6667,0 1.3334,1e-5 2.0001,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.6667,0 -1.3334,-1e-5 -2.0001,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
- style="fill:#c3dbff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- <g
- id="g11724"
+ id="ICON_LAYER_ACTIVE"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -38944,7 +39858,7 @@
</g>
</g>
<g
- id="g11718"
+ id="ICON_LAYER_USED"
transform="translate(0,2)">
<rect
y="113"
@@ -38978,7 +39892,7 @@
</g>
</g>
<g
- id="g11764"
+ id="ICON_NDOF_TURN"
transform="translate(0,2)">
<rect
y="113"
@@ -39051,7 +39965,7 @@
sodipodi:cy="-222"
sodipodi:rx="3.3084693"
sodipodi:ry="1.2798798"
- d="m 111.30847,-222 c 0,0.70686 -1.48125,1.27988 -3.30847,1.27988 -1.82722,0 -3.30847,-0.57302 -3.30847,-1.27988 0,-0.70686 1.48125,-1.27988 3.30847,-1.27988 1.82722,0 3.30847,0.57302 3.30847,1.27988 z"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
transform="matrix(1.0307577,0,0,0.9140456,39.651558,-39.251735)" />
<path
sodipodi:nodetypes="cssss"
@@ -39075,7 +39989,7 @@
</g>
</g>
<g
- id="g11730"
+ id="ICON_NDOF_TRANS"
transform="translate(0,2)">
<rect
y="113"
@@ -39116,7 +40030,7 @@
sodipodi:cy="-222"
sodipodi:rx="3.3084693"
sodipodi:ry="1.2798798"
- d="m 111.30847,-222 c 0,0.70686 -1.48125,1.27988 -3.30847,1.27988 -1.82722,0 -3.30847,-0.57302 -3.30847,-1.27988 0,-0.70686 1.48125,-1.27988 3.30847,-1.27988 1.82722,0 3.30847,0.57302 3.30847,1.27988 z"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
transform="matrix(1.0307577,0,0,0.9140456,39.651558,-39.251735)" />
<path
sodipodi:nodetypes="cssss"
@@ -39175,7 +40089,7 @@
</g>
</g>
<g
- id="g11749"
+ id="ICON_NDOF_FLY"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -39210,7 +40124,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(1.0307577,0,0,0.9140456,39.651558,-39.251735)"
- d="m 111.30847,-222 c 0,0.70686 -1.48125,1.27988 -3.30847,1.27988 -1.82722,0 -3.30847,-0.57302 -3.30847,-1.27988 0,-0.70686 1.48125,-1.27988 3.30847,-1.27988 1.82722,0 3.30847,0.57302 3.30847,1.27988 z"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
sodipodi:ry="1.2798798"
sodipodi:rx="3.3084693"
sodipodi:cy="-222"
@@ -39255,7 +40169,7 @@
</g>
</g>
<g
- id="g23801"
+ id="ICON_NDOF_DOM"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -39298,7 +40212,7 @@
sodipodi:cy="14.5"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
transform="matrix(1.176776,0,0,1.176776,-12.47787,-2.548088)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -39366,7 +40280,7 @@
sodipodi:cy="14.5"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -39437,16 +40351,8 @@
ry="0" />
</g>
</g>
- <rect
- style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect15876"
- width="16"
- height="16"
- x="110"
- y="409"
- ry="0" />
- <g
- id="g20862"
+ <g
+ id="ICON_ANIM_DATA"
transform="translate(168,65.000007)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -39477,7 +40383,7 @@
</g>
</g>
<g
- id="g10534"
+ id="ICON_SCRIPT"
transform="translate(0,128.00001)">
<rect
y="428"
@@ -39556,7 +40462,7 @@
</g>
</g>
<g
- id="g10512"
+ id="ICON_RADIO"
transform="translate(0,128.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -39595,7 +40501,7 @@
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -39619,7 +40525,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" />
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
</g>
<path
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
@@ -39668,7 +40574,7 @@
</g>
</g>
<path
- d="m 139.7074,118 c 0,4.26593 -3.45072,7.72414 -7.7074,7.72414 -4.25668,0 -7.7074,-3.45821 -7.7074,-7.72414 0,-4.26593 3.45072,-7.72414 7.7074,-7.72414 4.25668,0 7.7074,3.45821 7.7074,7.72414 z"
+ d="m 139.7074,118 a 7.7074003,7.7241406 0 1 1 -15.4148,0 7.7074003,7.7241406 0 1 1 15.4148,0 z"
sodipodi:ry="7.7241406"
sodipodi:rx="7.7074003"
sodipodi:cy="118"
@@ -39722,7 +40628,7 @@
</g>
<g
style="display:inline"
- id="g21197"
+ id="ICON_BONE_DATA"
transform="translate(20,319.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -39797,7 +40703,7 @@
</g>
<g
style="display:inline"
- id="g24682"
+ id="ICON_DISCLOSURE_TRI_RIGHT"
transform="translate(-166,402)">
<rect
y="217"
@@ -39824,7 +40730,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -39864,7 +40770,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -39882,7 +40788,7 @@
</g>
<g
style="display:inline"
- id="g24609"
+ id="ICON_INLINK"
transform="translate(307.00001,487.05412)">
<rect
y="111"
@@ -39920,7 +40826,7 @@
</g>
</g>
<g
- id="g106468">
+ id="ICON_RIGHTARROW">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
@@ -39950,7 +40856,7 @@
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
- id="g29910">
+ id="ICON_DOWNARROW">
<rect
transform="matrix(0,1,-1,0,0,0)"
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -39982,7 +40888,7 @@
</g>
<g
style="display:inline"
- id="g24559"
+ id="ICON_DOT"
transform="translate(259,508.00001)">
<rect
y="111"
@@ -39996,7 +40902,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -40007,7 +40913,7 @@
</g>
<g
style="display:inline"
- id="g24623"
+ id="ICON_ZOOMOUT"
transform="translate(-112,487.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -40045,7 +40951,7 @@
</g>
<g
style="display:inline"
- id="g24617"
+ id="ICON_ZOOMIN"
transform="translate(-113,487.00001)">
<rect
y="111"
@@ -40080,7 +40986,7 @@
</g>
<g
style="display:inline"
- id="g24629"
+ id="ICON_PLUS"
transform="translate(-128,487.00001)">
<rect
y="132"
@@ -40107,7 +41013,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -40147,7 +41053,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -40165,7 +41071,7 @@
</g>
<g
style="display:inline"
- id="g24604"
+ id="ICON_LINK"
transform="translate(305,487.00001)">
<rect
y="111"
@@ -40186,13 +41092,13 @@
sodipodi:cy="119.5"
sodipodi:rx="5.5"
sodipodi:ry="5.5"
- d="m 196,119.5 c 0,3.03757 -2.46243,5.5 -5.5,5.5 -3.03757,0 -5.5,-2.46243 -5.5,-5.5 0,-3.03757 2.46243,-5.5 5.5,-5.5 3.03757,0 5.5,2.46243 5.5,5.5 z"
+ d="m 196,119.5 a 5.5,5.5 0 1 1 -11,0 5.5,5.5 0 1 1 11,0 z"
transform="matrix(0.61819,0,0,0.618186,73.23488,45.12681)" />
</g>
</g>
<g
style="display:inline"
- id="g24582"
+ id="ICON_RADIOBUT_OFF"
transform="translate(114.02028,508.00993)">
<rect
y="111"
@@ -40205,7 +41111,7 @@
id="g24576">
<path
transform="matrix(1.4256767,0,0,1.4314068,-320.1963,68.175135)"
- d="m 333.29445,35.5 c 0,1.543333 -1.25112,2.794451 -2.79445,2.794451 -1.54333,0 -2.79445,-1.251118 -2.79445,-2.794451 0,-1.543333 1.25112,-2.794451 2.79445,-2.794451 1.54333,0 2.79445,1.251118 2.79445,2.794451 z"
+ d="m 333.29445,35.5 a 2.7944512,2.7944512 0 1 1 -5.5889,0 2.7944512,2.7944512 0 1 1 5.5889,0 z"
sodipodi:ry="2.7944512"
sodipodi:rx="2.7944512"
sodipodi:cy="35.5"
@@ -40215,7 +41121,7 @@
sodipodi:type="arc" />
<path
transform="matrix(1.2885487,0,0,1.2885617,-274.87525,73.246084)"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="35.5"
@@ -40231,13 +41137,13 @@
sodipodi:cy="35.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.288521,0,0,-1.2885339,576.8463,164.73299)" />
</g>
</g>
<g
style="opacity:0.6;display:inline"
- id="g24923"
+ id="ICON_RIGHTARROW_THIN"
transform="translate(4,529.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -40281,7 +41187,7 @@
</g>
<g
style="display:inline"
- id="g24911"
+ id="ICON_TRIA_DOWN"
transform="translate(28,550.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -40313,7 +41219,7 @@
</g>
<g
style="display:inline"
- id="g24917"
+ id="ICON_TRIA_RIGHT"
transform="translate(27,550.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -40345,7 +41251,7 @@
</g>
<g
style="display:inline"
- id="g25461"
+ id="ICON_DOTSDOWN"
transform="translate(444,424.00001)">
<rect
y="174"
@@ -40410,7 +41316,7 @@
</g>
<g
style="display:inline"
- id="g25412"
+ id="ICON_DOTSUP"
transform="translate(443,424.00001)">
<rect
y="174"
@@ -40479,7 +41385,7 @@
</g>
<g
style="display:inline"
- id="g25528"
+ id="ICON_AUTO"
transform="translate(93,445.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -40509,7 +41415,7 @@
sodipodi:cy="165"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 148,165 c 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z"
+ d="m 148,165 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(1.5,0,0,1.5,-73.5,-83.5)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -40528,7 +41434,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
transform="matrix(1.5,0,0,1.5,-66.5,-83.5)"
- d="m 148,165 c 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z"
+ d="m 148,165 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="165"
@@ -40539,7 +41445,7 @@
</g>
</g>
<g
- id="g35472"
+ id="ICON_VIEWZOOM"
transform="translate(0,128.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -40569,7 +41475,7 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.4308622,0,0,1.4308687,469.36987,363.18486)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -40597,7 +41503,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
transform="matrix(-1.4308622,0,0,1.4308687,469.36987,363.18486)"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="78.5"
@@ -40623,13 +41529,13 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)" />
<g
id="g35307">
<path
transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -40645,13 +41551,13 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)" />
</g>
<path
inkscape:transform-center-y="-6.490455"
inkscape:transform-center-x="-3.3976162"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="135"
@@ -40683,7 +41589,7 @@
</g>
<g
style="display:inline"
- id="g21566"
+ id="ICON_WORDWRAP_OFF"
transform="translate(-206,-205)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -40727,7 +41633,7 @@
</g>
<g
style="display:inline"
- id="g21557"
+ id="ICON_WORDWRAP_ON"
transform="translate(-205,-205)">
<rect
y="236"
@@ -40774,7 +41680,7 @@
</g>
<g
style="display:inline"
- id="g21497"
+ id="ICON_SYNTAX_ON"
transform="translate(97,5)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -40872,7 +41778,7 @@
</g>
<g
style="display:inline"
- id="g21514"
+ id="ICON_SYNTAX_OFF"
transform="translate(96.030183,5)">
<rect
y="26"
@@ -40955,7 +41861,7 @@
</g>
</g>
<g
- id="g11969"
+ id="ICON_LINENUMBERS_ON"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -41008,7 +41914,7 @@
</g>
</g>
<g
- id="g11979"
+ id="ICON_LINENUMBERS_OFF"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -41058,24 +41964,9 @@
</g>
</g>
<g
- id="g15785"
- transform="translate(-168.02763,373.00001)" />
- <g
- id="g15789"
- transform="translate(-168.02763,380.00001)" />
- <g
- transform="translate(-163.02763,375.00001)"
- id="g15795" />
- <g
- id="g15801"
- transform="translate(-163.02763,371.00001)" />
- <g
- transform="translate(-163.02763,382.00001)"
- id="g15807" />
- <g
style="display:inline"
transform="translate(150,389)"
- id="g22272">
+ id="ICON_MOD_CURVE">
<g
id="g22274"
transform="translate(-30,0)">
@@ -41178,7 +42069,7 @@
</g>
<g
style="display:inline"
- id="g31233"
+ id="ICON_MATPLANE"
transform="translate(-58,-17)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -41217,7 +42108,7 @@
</g>
<g
style="display:inline"
- id="g31226"
+ id="ICON_MATSPHERE"
transform="translate(-57,-17)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -41237,7 +42128,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -41254,7 +42145,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -41268,14 +42159,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
</g>
<g
- id="g31393"
+ id="ICON_ALIASED"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -41329,7 +42220,7 @@
</g>
<g
style="display:inline"
- id="g31442"
+ id="ICON_SEQ_LUMA_WAVEFORM"
transform="translate(-235,4)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -41370,7 +42261,7 @@
</g>
<g
style="display:inline"
- id="g31515"
+ id="ICON_CLIPUV_DEHLT"
transform="translate(18,130)">
<rect
y="27"
@@ -41398,7 +42289,7 @@
sodipodi:cy="35.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(1.000048,0,0,0.999998,-0.01591645,12.000064)" />
<path
style="opacity:0.6;fill:none;stroke:url(#linearGradient15711);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5;display:inline"
@@ -41414,78 +42305,76 @@
sodipodi:cy="35.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(0.857099,0,0,0.857147,47.22893,17.071296)" />
</g>
</g>
<g
- transform="translate(39,130)"
- id="g27524"
- style="opacity:0.2;display:inline">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect27526"
- width="16"
- height="16"
- x="323"
- y="27" />
+ id="ICON_CLIPUV_HLT">
<g
- style="display:inline"
- id="g27528"
- transform="translate(0.01612278,-12)">
+ style="opacity:0.2;display:inline"
+ id="g27524"
+ transform="translate(39,130)">
<rect
- y="41.500015"
- x="324.50003"
- height="12"
- width="12"
- id="rect27530"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline" />
- <path
- transform="matrix(1.000048,0,0,0.999998,-0.01591645,12.000064)"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
- sodipodi:ry="3.5"
- sodipodi:rx="3.5"
- sodipodi:cy="35.5"
- sodipodi:cx="330.5"
- id="path27532"
- style="fill:url(#linearGradient27540);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- sodipodi:type="arc" />
- <path
- sodipodi:nodetypes="ccc"
- id="path27534"
- d="m 335.50002,42.500013 -10,0 0,10 L 335.5,52.5 l 0,-10"
- style="opacity:0.6;fill:none;stroke:url(#linearGradient27542);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5;display:inline"
- inkscape:connector-curvature="0" />
- <path
- transform="matrix(0.857099,0,0,0.857147,47.22893,17.071296)"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
- sodipodi:ry="3.5"
- sodipodi:rx="3.5"
- sodipodi:cy="35.5"
- sodipodi:cx="330.5"
- id="path27536"
- style="fill:none;stroke:url(#linearGradient27544);stroke-width:1.16669464;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
- sodipodi:type="arc" />
+ y="27"
+ x="323"
+ height="16"
+ width="16"
+ id="rect27526"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(0.01612278,-12)"
+ id="g27528"
+ style="display:inline">
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="rect27530"
+ width="12"
+ height="12"
+ x="324.50003"
+ y="41.500015" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient27540);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ id="path27532"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(1.000048,0,0,0.999998,-0.01591645,12.000064)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient27542);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5;display:inline"
+ d="m 335.50002,42.500013 -10,0 0,10 L 335.5,52.5 l 0,-10"
+ id="path27534"
+ sodipodi:nodetypes="ccc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient27544);stroke-width:1.16669464;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="path27536"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(0.857099,0,0,0.857147,47.22893,17.071296)" />
+ </g>
</g>
- </g>
- <g
- style="display:inline"
- id="g31523"
- transform="translate(19,130)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect31513"
width="16"
height="16"
- x="343"
- y="27" />
+ x="362"
+ y="157" />
<g
- transform="translate(0.01612278,0)"
+ transform="translate(19.016123,130)"
id="g10864"
style="display:inline">
<path
transform="matrix(1.142871,0,0,1.142855,-27.218817,-5.0713453)"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="35.5"
@@ -41501,12 +42390,12 @@
sodipodi:cy="35.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(0.857099,0,0,0.857147,67.228993,5.071249)" />
</g>
</g>
<g
- id="g31658"
+ id="ICON_SEQ_HISTOGRAM"
transform="translate(63,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -41548,7 +42437,7 @@
</g>
<g
style="display:inline"
- id="g31429"
+ id="ICON_SEQ_CHROMA_SCOPE"
transform="translate(-234,4)">
<rect
y="6"
@@ -41623,7 +42512,7 @@
</g>
<g
transform="translate(-21,-418)"
- id="g31674">
+ id="ICON_SEQ_PREVIEW">
<rect
y="428"
x="47"
@@ -41664,7 +42553,7 @@
</g>
</g>
<g
- id="g11938"
+ id="ICON_IMAGEFILE"
transform="translate(0,2)">
<rect
y="8"
@@ -41731,7 +42620,7 @@
</g>
</g>
<g
- id="g10845"
+ id="ICON_MOD_WAVE"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -41774,7 +42663,7 @@
</g>
</g>
<g
- id="g13136"
+ id="ICON_MOD_SUBSURF"
transform="translate(0,2)">
<rect
y="260"
@@ -41847,7 +42736,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -41865,7 +42754,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -41873,100 +42762,7 @@
</g>
</g>
<g
- id="g10823"
- transform="translate(0,2)">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect31968"
- width="16"
- height="16"
- x="68"
- y="260" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="path12863"
- d="m 70.562559,271.5 0.24994,0.25 9,-9 -0.24994,-0.25 -9,0 0,9 z"
- style="fill:url(#linearGradient24189);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccccc"
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- d="m 70.562559,271.5 -6e-5,-9 9,5e-5 m -4.99994,4.89995 0,-4.8 m 0.89997,3.9 -4.8,0"
- style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
- id="path12865"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="path12867"
- d="m 71.562559,265.51369 0,-2.01369 1.99998,0"
- style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.00000119px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- <g
- id="g24198"
- style="opacity:0.4">
- <path
- id="path12861"
- d="m 72.562559,273.5 -0.25006,-0.25 9,-9 0.25006,0.25 0,9 -9,0 z"
- style="fill:url(#linearGradient24209);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
- sodipodi:nodetypes="cccccc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- style="fill:none;stroke:url(#linearGradient24192);stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;display:inline"
- d="m 80.499999,265.5 0,7 -7,0"
- id="path27953"
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccc"
- id="path12869"
- d="m 81.562559,264.5 0,9 -9,-5e-5"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- </g>
- <path
- style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.00000119px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- d="m 75.562559,265.51369 0,-2.01369 1.99998,0"
- id="path12871"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="path12873"
- d="m 71.562579,269.51369 0,-2.01369 1.99998,0"
- style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.00000119px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- </g>
- <path
- style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="M 71,277 83,265"
- id="path42252"
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0" />
- <g
- id="g14009"
- transform="translate(1,-0.01245054)" />
- <g
- id="g17702"
+ id="ICON_FACESEL_HLT"
transform="translate(-1e-5,127)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -42026,7 +42822,7 @@
</g>
<g
style="display:inline"
- id="g23022"
+ id="ICON_SPACE3"
transform="translate(19,-17)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -42055,7 +42851,7 @@
</g>
<g
style="display:inline"
- id="g23028"
+ id="ICON_SPACE2"
transform="translate(18.067322,-17)">
<rect
y="237"
@@ -42084,7 +42880,7 @@
</g>
<g
style="display:inline"
- id="g23056"
+ id="ICON_MARKER_HLT"
transform="translate(118,4)">
<rect
y="216"
@@ -42128,7 +42924,7 @@
</g>
<g
style="display:inline"
- id="g23048"
+ id="ICON_PMARKER_ACT"
transform="translate(35,4.96982)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -42172,7 +42968,7 @@
</g>
<g
style="display:inline"
- id="g23040"
+ id="ICON_PMARKER_SEL"
transform="translate(36,4.96982)">
<rect
y="215.03018"
@@ -42216,7 +43012,7 @@
</g>
<g
style="display:inline"
- id="g23034"
+ id="ICON_PMARKER"
transform="translate(37,5)">
<rect
y="215"
@@ -42248,7 +43044,7 @@
</g>
<g
style="display:inline"
- id="g23114"
+ id="ICON_MARKER"
transform="translate(-81,46)">
<rect
y="174"
@@ -42280,7 +43076,7 @@
</g>
<g
style="display:inline"
- id="g23160"
+ id="ICON_FF"
transform="translate(-316,25)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -42330,7 +43126,7 @@
</g>
<g
style="display:inline"
- id="g23168"
+ id="ICON_REW"
transform="translate(-315.95126,25)">
<rect
y="195"
@@ -42390,7 +43186,7 @@
</g>
<g
style="display:inline"
- id="g23154"
+ id="ICON_PLAY"
transform="translate(-317,25)">
<rect
y="195"
@@ -42422,7 +43218,7 @@
</g>
<g
style="display:inline"
- id="g23136"
+ id="ICON_PAUSE"
transform="translate(-194,25)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -42491,7 +43287,7 @@
</g>
<g
style="display:inline"
- id="g23146"
+ id="ICON_REC"
transform="translate(-318,25)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -42518,7 +43314,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -42544,7 +43340,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -42552,7 +43348,7 @@
</g>
</g>
<g
- id="g24423">
+ id="ICON_NEXT_KEYFRAME">
<rect
y="220"
x="131"
@@ -42595,7 +43391,7 @@
</g>
<g
style="display:inline"
- id="g23235"
+ id="ICON_PREV_KEYFRAME"
transform="translate(-74,46)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -42638,99 +43434,80 @@
</g>
</g>
<g
- id="g23738"
- transform="matrix(0.9375966,0,0,0.937515,141.13219,-26.987026)"
- style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1">
+ id="ICON_ANTIALIASED">
+ <rect
+ y="31"
+ x="131"
+ height="16"
+ width="16"
+ id="rect10527"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- transform="matrix(0.83365,0,0,0.857522,-5.083283,31.57021)"
- id="g23740"
- style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1">
- <g
- transform="translate(-1.863085e-7,0.53333)"
- id="g23742"
- style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1">
- <g
- transform="translate(0.533324,-1.066663)"
- id="g23744"
- style="fill:none;stroke:#000000;stroke-width:0.99968439;stroke-opacity:1" />
- </g>
- </g>
- </g>
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect10527"
- width="16"
- height="16"
- x="131"
- y="31" />
- <g
- style="display:inline"
- id="g10530"
- transform="matrix(1.1658027,0,0,1.1657997,-11.289717,-221.05607)"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <path
- transform="matrix(0.629932,0,0,0.6236653,45.764188,149.53247)"
- sodipodi:type="arc"
- style="opacity:0.1;fill:none;stroke:#ffffff;stroke-width:5.47410154;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="path23603"
- sodipodi:cx="132"
- sodipodi:cy="118"
- sodipodi:rx="8"
- sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <path
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
- sodipodi:ry="8"
- sodipodi:rx="8"
- sodipodi:cy="118"
- sodipodi:cx="132"
- id="path10532"
- style="fill:none;stroke:#000000;stroke-width:2.25806689;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- sodipodi:type="arc"
- transform="matrix(0.629932,0,0,0.6236653,45.764188,149.53247)" />
- <g
- id="g11317">
- <path
- sodipodi:type="arc"
- style="opacity:0.8;fill:url(#linearGradient11333);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.6060524;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path11331"
- sodipodi:cx="132"
- sodipodi:cy="118"
- sodipodi:rx="8"
- sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- transform="matrix(-0.5326189,-0.05995148,0.06070777,-0.5287352,192.0574,293.4132)" />
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(1.1658027,0,0,1.1657997,-11.289717,-221.05607)"
+ id="g10530"
+ style="display:inline">
<path
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
sodipodi:cx="132"
- id="path10536"
- style="fill:none;stroke:url(#linearGradient10540);stroke-width:1.78041101;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path23603"
+ style="opacity:0.1;fill:none;stroke:#ffffff;stroke-width:5.47410154;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.629932,0,0,0.6236653,45.764188,149.53247)" />
+ <path
+ transform="matrix(0.629932,0,0,0.6236653,45.764188,149.53247)"
sodipodi:type="arc"
- transform="matrix(0.4812861,0,0,0.4822895,65.395173,166.1609)" />
+ style="fill:none;stroke:#000000;stroke-width:2.25806689;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path10532"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ id="g11317">
+ <path
+ transform="matrix(-0.5326189,-0.05995148,0.06070777,-0.5287352,192.0574,293.4132)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path11331"
+ style="opacity:0.8;fill:url(#linearGradient11333);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.6060524;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.4812861,0,0,0.4822895,65.395173,166.1609)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient10540);stroke-width:1.78041101;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path10536"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
</g>
</g>
<g
- id="g16279"
- transform="translate(318,7.00009)" />
- <g
- id="g28089"
+ id="ICON_MOD_DISPLACE"
transform="translate(0,2)">
<rect
y="260"
@@ -42812,66 +43589,7 @@
</g>
</g>
<g
- id="g16397"
- transform="matrix(1.045454,0,0,1.0610941,-16.32706,109.05266)"
- style="opacity:0.45"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <g
- id="g16403"
- transform="matrix(1.000037,0,0,1.0187902,152.96764,39.785579)"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <g
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- transform="matrix(0.9375,0,0,0.9375,192.125,77.25821)"
- id="g16405"
- style="display:inline">
- <g
- id="g16407"
- style="fill:#000000;fill-opacity:1"
- transform="matrix(1,0,0,1.037041,0,-6.074721)" />
- <g
- transform="translate(-84.26666,-72.24656)"
- id="g16409">
- <g
- transform="translate(1.070738,1.59725)"
- id="g16411">
- <g
- id="g16413"
- transform="matrix(0.83365,0,0,0.857522,-5.083283,31.57021)">
- <g
- id="g16415"
- transform="translate(-1.863085e-7,0.53333)">
- <g
- id="g16417"
- transform="translate(0.533324,-1.066663)" />
- </g>
- </g>
- </g>
- </g>
- <g
- id="g16419"
- transform="matrix(0.903797,0,0,0.872724,-4.64464,27.13735)" />
- <g
- id="g16421" />
- </g>
- </g>
- <g
- id="g16425"
- transform="matrix(1.000872,0,0,1.0462972,140.88404,50.499099)"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <g
- id="g28330"
- transform="translate(315.99999,18.99998)" />
- <g
- id="g28446"
+ id="ICON_MOD_UVPROJECT"
transform="translate(0,-18.999939)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -43010,145 +43728,8 @@
</g>
</g>
<g
- id="g12156"
- transform="translate(-130.97687,-108)" />
- <g
- transform="translate(-517,612.99998)"
- id="g12564"
- style="display:inline">
- <rect
- y="-183"
- x="543"
- height="16"
- width="16"
- id="rect12566"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- id="g12568">
- <rect
- style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect12570"
- width="2.9998772"
- height="3"
- x="554.50031"
- y="-181.49998"
- ry="1.4999386"
- rx="1.4999386" />
- <path
- sodipodi:nodetypes="cccc"
- id="path12572"
- d="m 546.00017,-179.49999 5,9.5 5,-9.5 -10,0 z"
- style="fill:none;stroke:#2b1600;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
- <rect
- rx="1.4999386"
- ry="1.4999386"
- y="-181.49998"
- x="544.50043"
- height="3"
- width="2.9998772"
- id="rect12574"
- style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect12576"
- width="2.9998772"
- height="3"
- x="549.5"
- y="-171.5"
- ry="1.4999386"
- rx="1.4999386" />
- <path
- style="fill:none;stroke:#ffad55;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 546.00017,-179.53678 5,9.5 5,-9.5 -10,0 z"
- id="path12578"
- sodipodi:nodetypes="cccc"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="path12580"
- d="m 557.00046,-180.99998 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
- style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- d="m 552.00029,-170.99999 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
- id="path12582"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- d="m 547.00059,-180.99998 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
- id="path12584"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccc"
- id="path12586"
- d="m 546.00017,-179.53678 5,9.5 5,-9.5 -10,0 z"
- style="fill:none;stroke:url(#linearGradient12602);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
- d="m 555.5,-179.5 0,-1 1,0"
- id="path12588"
- inkscape:connector-curvature="0" />
- <path
- id="path12590"
- d="m 545.5,-179.5 0,-1 1,0"
- style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
- d="m 550.5,-169.5 0,-1 1,0"
- id="path12592"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.2;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- d="m 555,-180.34409 -0.96003,1e-5 0,2.34418 2.21003,-1e-4 0.36569,-1 -1.61569,0 0,-1.34409 z"
- id="path12594"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.5;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- d="m 552,-172 c -0.65334,0 -1.30669,1e-5 -1.96003,1e-5 0,0.33321 0,0.66641 0,0.99963 0.65334,0 1.30669,0 1.96003,0 0,-0.33322 0,-0.66643 0,-0.99964 z"
- id="path12596"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="path12598"
- d="m 547.03997,-180.34409 0.96003,1e-5 0,2.34418 -0.96003,-1.0001 0,-1.34409 z"
- style="opacity:0.2;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.5;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 545.65591,-179 1e-5,0.96003 2.34418,0 L 547,-179 l -1.34409,0 z"
- id="path12600"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- <g
transform="translate(-537,592)"
- id="g12618"
+ id="ICON_OUTLINER_DATA_MESH"
style="display:inline">
<rect
y="-183"
@@ -43229,16 +43810,153 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- transform="scale(1,-1)"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect12777"
- width="16"
- height="16"
- x="26"
- y="-446" />
- <g
- id="g12053"
+ <g
+ id="ICON_OUTLINER_OB_MESH">
+ <g
+ style="display:inline"
+ id="g12564"
+ transform="translate(-517,612.99998)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12566"
+ width="16"
+ height="16"
+ x="543"
+ y="-183" />
+ <g
+ id="g12568">
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="-181.49998"
+ x="554.50031"
+ height="3"
+ width="2.9998772"
+ id="rect12570"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2b1600;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 546.00017,-179.49999 5,9.5 5,-9.5 -10,0 z"
+ id="path12572"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect12574"
+ width="2.9998772"
+ height="3"
+ x="544.50043"
+ y="-181.49998"
+ ry="1.4999386"
+ rx="1.4999386" />
+ <rect
+ rx="1.4999386"
+ ry="1.4999386"
+ y="-171.5"
+ x="549.5"
+ height="3"
+ width="2.9998772"
+ id="rect12576"
+ style="fill:#dfa535;fill-opacity:1;fill-rule:nonzero;stroke:#2b1600;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path12578"
+ d="m 546.00017,-179.53678 5,9.5 5,-9.5 -10,0 z"
+ style="fill:none;stroke:#ffad55;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 557.00046,-180.99998 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ id="path12580"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12582"
+ d="m 552.00029,-170.99999 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-1e-5 2.0082,-1e-5 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12584"
+ d="m 547.00059,-180.99998 c -0.6694,0 -1.3388,1e-5 -2.0082,1e-5 0,0.66939 0,1.33877 0,2.00817 0.6694,0 1.3388,-10e-6 2.0082,-10e-6 0,-0.66939 0,-1.33878 0,-2.00817 z"
+ style="fill:#ffca91;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient12602);stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 546.00017,-179.53678 5,9.5 5,-9.5 -10,0 z"
+ id="path12586"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path12588"
+ d="m 555.5,-179.5 0,-1 1,0"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 545.5,-179.5 0,-1 1,0"
+ id="path12590" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path12592"
+ d="m 550.5,-169.5 0,-1 1,0"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12594"
+ d="m 555,-180.34409 -0.96003,1e-5 0,2.34418 2.21003,-1e-4 0.36569,-1 -1.61569,0 0,-1.34409 z"
+ style="opacity:0.2;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12596"
+ d="m 552,-172 c -0.65334,0 -1.30669,1e-5 -1.96003,1e-5 0,0.33321 0,0.66641 0,0.99963 0.65334,0 1.30669,0 1.96003,0 0,-0.33322 0,-0.66643 0,-0.99964 z"
+ style="opacity:0.5;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 547.03997,-180.34409 0.96003,1e-5 0,2.34418 -0.96003,-1.0001 0,-1.34409 z"
+ id="path12598"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12600"
+ d="m 545.65591,-179 1e-5,0.96003 2.34418,0 L 547,-179 l -1.34409,0 z"
+ style="opacity:0.5;fill:#964e00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000072;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <rect
+ y="-446"
+ x="26"
+ height="16"
+ width="16"
+ id="rect12777"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(1,-1)" />
+ </g>
+ <g
+ id="ICON_OUTLINER_OB_SURFACE"
transform="translate(-21,128)">
<rect
y="302"
@@ -43307,7 +44025,7 @@
</g>
</g>
<g
- id="g12219"
+ id="ICON_OUTLINER_DATA_SURFACE"
transform="translate(-20.999998,128)">
<rect
transform="scale(-1,1)"
@@ -43456,23 +44174,7 @@
</g>
</g>
<g
- id="g12249"
- style="opacity:0.65;display:inline"
- transform="translate(-98,462.06404)" />
- <g
- style="display:inline"
- transform="translate(-53.00012,422.06403)"
- id="g12255" />
- <g
- transform="translate(-98,483.06404)"
- style="opacity:0.65;display:inline"
- id="g12325" />
- <g
- id="g12327"
- transform="translate(-53.00012,443.06403)"
- style="display:inline" />
- <g
- id="g24293"
+ id="ICON_MOD_ARRAY"
transform="translate(0,2)">
<rect
y="260"
@@ -43577,66 +44279,66 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- ry="0"
- rx="0.80014729"
- y="73"
- x="257"
- height="16"
- width="16"
- id="rect11420"
- style="opacity:0;fill:#ffaaaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- id="g16042"
- transform="translate(-147,2)">
- <path
- style="fill:url(#linearGradient16039);fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 412,73.5 c -4.5,0 -7.25,0.75 -5.75,2.5 l 4.25,4.5 0,6.25 3,-2 0,-4.25 c 1.48333,-1.72541 2.75638,-2.81017 4.25,-4.5 1.5,-1.75 -1.25,-2.5 -5.75,-2.5 z"
- id="path11422"
- sodipodi:nodetypes="cccccccc"
- inkscape:connector-curvature="0" />
- <path
- style="fill:url(#radialGradient16034);fill-opacity:1;stroke:url(#linearGradient16036);stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 418.24999,74.499997 c -0.005,1.49998 -1.49999,2.000009 -6.25,2.000009 -4.74999,0 -6.25738,-0.500029 -6.24999,-2.000009 0.005,-1.000014 1.5,-1.999986 6.24999,-1.999986 4.75001,0 6.24506,0.999972 6.25,1.999986 z"
- id="path11424"
- sodipodi:nodetypes="csssc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccccc"
- id="path11426"
- d="m 410.89062,80.47656 0,5.75 2.20704,-1.585938 0,-4.164062 -0.40829,0 -1.79875,0 z"
- style="fill:url(#linearGradient16031);fill-rule:evenodd;stroke:none"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cc"
- id="path11428"
- d="m 412.5,85.25 0,-4.25"
- style="opacity:0.15;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#cccccc;stroke-width:0.99999988;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 406.5,75 c 0,-1.75 2.5,-1.5 5.5,-1.49999 3,1e-5 5.5,-0.25001 5.5,1.25001"
- id="path12224"
- sodipodi:nodetypes="csc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="csssc"
- id="path12211"
- d="m 417.49999,74.50002 c 10e-6,1.74998 -1.4838,1.99999 -5.50001,1.99999 -4.01617,0 -5.49583,-0.50001 -5.49999,-1.99999 -0.004,-1.50002 1.48382,-2.00001 5.49999,-2.00001 4.01621,0 5.49583,0.49999 5.50001,2.00001 z"
- style="fill:none;stroke:url(#linearGradient16027);stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.15;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- d="m 411.27412,80.5 2.13816,0"
- id="path12238"
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0" />
- </g>
<g
- id="g11534"
- transform="translate(21,-1)" />
+ id="ICON_FILTER">
+ <rect
+ style="opacity:0;fill:#ffaaaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect11420"
+ width="16"
+ height="16"
+ x="257"
+ y="73"
+ rx="0.80014729"
+ ry="0" />
+ <g
+ transform="translate(-147,2)"
+ id="g16042">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc"
+ id="path11422"
+ d="m 412,73.5 c -4.5,0 -7.25,0.75 -5.75,2.5 l 4.25,4.5 0,6.25 3,-2 0,-4.25 c 1.48333,-1.72541 2.75638,-2.81017 4.25,-4.5 1.5,-1.75 -1.25,-2.5 -5.75,-2.5 z"
+ style="fill:url(#linearGradient16039);fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csssc"
+ id="path11424"
+ d="m 418.24999,74.499997 c -0.005,1.49998 -1.49999,2.000009 -6.25,2.000009 -4.74999,0 -6.25738,-0.500029 -6.24999,-2.000009 0.005,-1.000014 1.5,-1.999986 6.24999,-1.999986 4.75001,0 6.24506,0.999972 6.25,1.999986 z"
+ style="fill:url(#radialGradient16034);fill-opacity:1;stroke:url(#linearGradient16036);stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient16031);fill-rule:evenodd;stroke:none"
+ d="m 410.89062,80.47656 0,5.75 2.20704,-1.585938 0,-4.164062 -0.40829,0 -1.79875,0 z"
+ id="path11426"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 412.5,85.25 0,-4.25"
+ id="path11428"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc"
+ id="path12224"
+ d="m 406.5,75 c 0,-1.75 2.5,-1.5 5.5,-1.49999 3,1e-5 5.5,-0.25001 5.5,1.25001"
+ style="fill:none;stroke:#cccccc;stroke-width:0.99999988;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient16027);stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 417.49999,74.50002 c 10e-6,1.74998 -1.4838,1.99999 -5.50001,1.99999 -4.01617,0 -5.49583,-0.50001 -5.49999,-1.99999 -0.004,-1.50002 1.48382,-2.00001 5.49999,-2.00001 4.01621,0 5.49583,0.49999 5.50001,2.00001 z"
+ id="path12211"
+ sodipodi:nodetypes="csssc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path12238"
+ d="m 411.27412,80.5 2.13816,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </g>
+ </g>
<g
- id="g17375"
+ id="ICON_OUTLINER_OB_FONT"
transform="translate(10.000031,192.5)"
inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\Browser icons ver 1\font_file SMALL.png"
inkscape:export-xdpi="90"
@@ -43682,23 +44384,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g31245"
- transform="matrix(0.425032,0.424791,0.425032,-0.424791,-342.55466,249.47119)"
- style="display:inline" />
- <g
- transform="translate(-157,15.000007)"
- style="opacity:0.5"
- id="g13244" />
- <g
- id="g13375"
- style="opacity:0.3"
- transform="translate(-177.01509,15.000007)" />
- <g
- id="g13383"
- style="opacity:0.5"
- transform="translate(-143,15.000007)" />
- <g
- id="g14144"
+ id="ICON_SCULPTMODE_HLT"
transform="translate(289,331.00001)">
<rect
y="183"
@@ -43761,22 +44447,7 @@
</g>
</g>
<g
- transform="matrix(-1.0226846,0,0,1.0218469,-86.775576,130.3547)"
- id="g17210">
- <g
- id="g17212"
- transform="matrix(0.83365,0,0,0.857522,-5.083283,31.57021)">
- <g
- id="g17214"
- transform="translate(-1.863085e-7,0.53333)">
- <g
- id="g17216"
- transform="translate(0.533324,-1.066663)" />
- </g>
- </g>
- </g>
- <g
- id="g13705"
+ id="ICON_MATCUBE"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -43830,7 +44501,7 @@
</g>
</g>
<g
- id="g17610"
+ id="ICON_SETTINGS"
transform="translate(-20.999893,190.97867)"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -43970,7 +44641,7 @@
</g>
</g>
<g
- id="g13494"
+ id="ICON_CHECKBOX_DEHLT"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="translate(0,128.00001)">
@@ -44013,7 +44684,7 @@
transform="scale(-1,-1)" />
</g>
<g
- id="g28870"
+ id="ICON_CHECKBOX_HLT"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g13494.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -44066,62 +44737,65 @@
inkscape:connector-curvature="0" />
</g>
<g
- transform="translate(135,508.00993)"
- id="g13515"
- style="display:inline">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect13517"
- width="16"
- height="16"
- x="143"
- y="111" />
+ id="ICON_RADIOBUT_ON">
<g
- id="g13519">
- <path
- sodipodi:type="arc"
- style="fill:#e6e6e6;fill-opacity:0.25490196;fill-rule:nonzero;stroke:none;display:inline"
- id="path13521"
- sodipodi:cx="330.5"
- sodipodi:cy="35.5"
- sodipodi:rx="2.7944512"
- sodipodi:ry="2.7944512"
- d="m 333.29445,35.5 c 0,1.543333 -1.25112,2.794451 -2.79445,2.794451 -1.54333,0 -2.79445,-1.251118 -2.79445,-2.794451 0,-1.543333 1.25112,-2.794451 2.79445,-2.794451 1.54333,0 2.79445,1.251118 2.79445,2.794451 z"
- transform="matrix(1.4256767,0,0,1.4314068,-320.1963,68.175135)" />
- <path
- sodipodi:type="arc"
- style="opacity:0.4;fill:none;stroke:url(#linearGradient13527);stroke-width:0.77606368;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
- id="path13523"
- sodipodi:cx="330.5"
- sodipodi:cy="35.5"
- sodipodi:rx="3.5"
- sodipodi:ry="3.5"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
- transform="matrix(1.2885487,0,0,1.2885617,-274.87525,73.246084)" />
- <path
- transform="matrix(-1.288521,0,0,-1.2885339,576.8463,164.73299)"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
- sodipodi:ry="3.5"
- sodipodi:rx="3.5"
- sodipodi:cy="35.5"
- sodipodi:cx="330.5"
- id="path13525"
- style="opacity:0.6;fill:none;stroke:url(#linearGradient13529);stroke-width:0.77608043;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
- sodipodi:type="arc" />
+ style="display:inline"
+ id="g13515"
+ transform="translate(135,508.00993)">
+ <rect
+ y="111"
+ x="143"
+ height="16"
+ width="16"
+ id="rect13517"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g13519">
+ <path
+ transform="matrix(1.4256767,0,0,1.4314068,-320.1963,68.175135)"
+ d="m 333.29445,35.5 a 2.7944512,2.7944512 0 1 1 -5.5889,0 2.7944512,2.7944512 0 1 1 5.5889,0 z"
+ sodipodi:ry="2.7944512"
+ sodipodi:rx="2.7944512"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path13521"
+ style="fill:#e6e6e6;fill-opacity:0.25490196;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.2885487,0,0,1.2885617,-274.87525,73.246084)"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path13523"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient13527);stroke-width:0.77606368;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.6;fill:none;stroke:url(#linearGradient13529);stroke-width:0.77608043;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline"
+ id="path13525"
+ sodipodi:cx="330.5"
+ sodipodi:cy="35.5"
+ sodipodi:rx="3.5"
+ sodipodi:ry="3.5"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.288521,0,0,-1.2885339,576.8463,164.73299)" />
+ </g>
</g>
+ <path
+ transform="matrix(0.8543143,0,0,0.8543231,3.66123,596.67148)"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="35.5"
+ sodipodi:cx="330.5"
+ id="path15120"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ sodipodi:type="arc" />
</g>
- <path
- sodipodi:type="arc"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- id="path15120"
- sodipodi:cx="330.5"
- sodipodi:cy="35.5"
- sodipodi:rx="3.5"
- sodipodi:ry="3.5"
- d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
- transform="matrix(0.8543143,0,0,0.8543231,3.66123,596.67148)" />
- <g
- id="g18811"
+ <g
+ id="ICON_MOD_EDGESPLIT"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -44193,7 +44867,7 @@
</g>
</g>
<g
- id="g14548"
+ id="ICON_HOOK"
transform="translate(0,23)">
<rect
y="239"
@@ -44212,7 +44886,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(0.8675713,0,0,-1.199958,80.598976,391.9948)"
- d="m 93.25,125 c 0,0.69036 -0.783502,1.25 -1.75,1.25 -0.966498,0 -1.75,-0.55964 -1.75,-1.25 0,-0.69036 0.783502,-1.25 1.75,-1.25 0.966498,0 1.75,0.55964 1.75,1.25 z"
+ d="m 93.25,125 a 1.75,1.25 0 1 1 -3.5,0 1.75,1.25 0 1 1 3.5,0 z"
sodipodi:ry="1.25"
sodipodi:rx="1.75"
sodipodi:cy="125"
@@ -44234,11 +44908,11 @@
sodipodi:cy="125"
sodipodi:rx="1.75"
sodipodi:ry="1.25"
- d="m 93.25,125 c 0,0.69036 -0.783502,1.25 -1.75,1.25 -0.966498,0 -1.75,-0.55964 -1.75,-1.25 0,-0.69036 0.783502,-1.25 1.75,-1.25 0.966498,0 1.75,0.55964 1.75,1.25 z"
+ d="m 93.25,125 a 1.75,1.25 0 1 1 -3.5,0 1.75,1.25 0 1 1 3.5,0 z"
transform="matrix(0.8540253,0,0,-1.199954,81.814709,391.9942)" />
<path
transform="matrix(0.8540253,0,0,-1.199954,81.814709,391.9942)"
- d="m 93.25,125 c 0,0.69036 -0.783502,1.25 -1.75,1.25 -0.966498,0 -1.75,-0.55964 -1.75,-1.25 0,-0.69036 0.783502,-1.25 1.75,-1.25 0.966498,0 1.75,0.55964 1.75,1.25 z"
+ d="m 93.25,125 a 1.75,1.25 0 1 1 -3.5,0 1.75,1.25 0 1 1 3.5,0 z"
sodipodi:ry="1.25"
sodipodi:rx="1.75"
sodipodi:cy="125"
@@ -44263,7 +44937,7 @@
</g>
<g
transform="translate(349,127.99988)"
- id="g26256">
+ id="ICON_BLENDER">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect26258"
@@ -44283,7 +44957,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1.0000004 0 1 1 -2,0 1,1.0000004 0 1 1 2,0 z"
sodipodi:ry="1.0000004"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -44300,7 +44974,7 @@
</g>
<path
transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -44322,11 +44996,11 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(3.25,0,0,3.25,-62.875,313.125)" />
<path
transform="matrix(2,0,0,2,-46,385)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -44342,7 +45016,7 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
<path
sodipodi:nodetypes="cccccc"
@@ -44353,7 +45027,7 @@
</g>
</g>
<g
- id="g15201"
+ id="ICON_TEXTURE_DATA"
transform="translate(0,128.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -44396,10 +45070,7 @@
</g>
</g>
<g
- transform="translate(-174.00091,22.99815)"
- id="g15532" />
- <g
- id="g15356"
+ id="ICON_FCURVE"
transform="translate(-21,128.00001)">
<rect
y="344"
@@ -44446,7 +45117,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\Browser icons ver 1\font_file SMALL.png"
transform="translate(-73.999969,234.50001)"
- id="g15369">
+ id="ICON_FONT_DATA">
<rect
y="237.5"
x="162.99997"
@@ -44487,7 +45158,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g14355"
+ id="ICON_ANIM"
transform="translate(0,128.00001)">
<rect
y="428"
@@ -44518,17 +45189,8 @@
</g>
</g>
<g
- transform="translate(-111.96756,-108)"
- id="g15923">
- <g
- id="g15925" />
- </g>
- <g
- transform="translate(189.19394,55.494451)"
- id="g15616" />
- <g
style="display:inline"
- id="g16518"
+ id="ICON_SCENE"
transform="translate(0,64.000007)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -44582,7 +45244,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(1.3955004,0,0,1.2452423,11.18333,-121.72474)" />
<rect
rx="0.5078125"
@@ -44595,7 +45257,7 @@
style="opacity:0.25;fill:none;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
transform="matrix(1.5770887,0,0,1.5999841,-3.50675,-301.69208)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -44611,11 +45273,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(1.1794014,0,0,0.8999954,27.50686,48.952303)" />
<path
transform="matrix(1.1827463,0,0,1.2,27.245789,-99.900024)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -44631,7 +45293,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.790122,0,0,0.787736,57.870479,107.05649)" />
<g
id="g16548"
@@ -44644,7 +45306,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.7901234,0,0,0.2000006,9.8760061,395.5997)" />
<path
sodipodi:nodetypes="csccc"
@@ -44689,11 +45351,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(1.1827463,0,0,1.2,27.245789,-99.900024)" />
<path
transform="matrix(0.8888868,0,0,0.8862026,50.166822,57.626266)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -44709,7 +45371,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.1975308,0,0,0.1999991,103.0926,401.10045)" />
<path
sodipodi:type="arc"
@@ -44719,13 +45381,13 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(-0.8867575,0.06148883,-0.06130315,-0.8840797,219.44126,941.51187)" />
</g>
</g>
<g
style="display:inline"
- id="g21847"
+ id="ICON_RESTRICT_RENDER_OFF"
transform="translate(24,422.99999)"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -44793,7 +45455,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.7834486,0,0,0.2000006,10.413535,395.5997)" />
<path
sodipodi:nodetypes="csccc"
@@ -44839,7 +45501,7 @@
transform="translate(1.1408497e-7,0.5000446)">
<path
transform="matrix(1.187982,0,0,1.0569758,379.83032,-513.21497)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -44855,11 +45517,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(1.3827154,0,0,1.4028327,364.1482,-688.72206)" />
<path
transform="matrix(0.987526,0,0,0.8124641,394.9733,-392.80617)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -44875,11 +45537,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.9848328,0,0,0.9992585,395.19018,-485.12778)" />
<path
transform="matrix(0.591154,0,0,0.5887513,425.87219,-279.05319)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -44889,7 +45551,7 @@
sodipodi:type="arc" />
<path
transform="matrix(0.9913883,0,0,1.0058976,394.67318,-488.46061)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -44905,11 +45567,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.6941559,0,0,0.6920597,417.67198,-331.15708)" />
<path
transform="matrix(0.1975308,0,0,0.1999991,456.0926,-84.399595)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -44919,7 +45581,7 @@
sodipodi:type="arc" />
<path
transform="matrix(-0.6760501,-0.1575078,0.1570322,-0.6740085,446.07727,367.34791)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -44938,7 +45600,7 @@
</g>
<g
transform="translate(45,422.99999)"
- id="g22102"
+ id="ICON_RESTRICT_RENDER_ON"
style="opacity:0.25;display:inline">
<rect
ry="0"
@@ -44998,7 +45660,7 @@
id="g22118">
<path
transform="matrix(0.7834486,0,0,0.2000006,10.413535,395.5997)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -45056,11 +45718,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(1.187982,0,0,1.0569758,379.83032,-513.21497)" />
<path
transform="matrix(1.3827154,0,0,1.4028327,364.1482,-688.72206)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -45076,11 +45738,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.987526,0,0,0.8124641,394.9733,-392.80617)" />
<path
transform="matrix(0.9848328,0,0,0.9992585,395.19018,-485.12778)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -45096,7 +45758,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.591154,0,0,0.5887513,425.87219,-279.05319)" />
<path
sodipodi:type="arc"
@@ -45106,11 +45768,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.9913883,0,0,1.0058976,394.67318,-488.46061)" />
<path
transform="matrix(0.6941559,0,0,0.6920597,417.84876,-330.91401)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -45126,7 +45788,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.1975308,0,0,0.1999991,456.07844,-84.89955)" />
</g>
<path
@@ -45139,7 +45801,7 @@
</g>
<g
transform="translate(-272,478.06251)"
- id="g30185"
+ id="ICON_OUTLINER_OB_CAMERA"
style="opacity:0.98000004;display:inline"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -45159,9 +45821,9 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" />
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
<path
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45171,7 +45833,7 @@
sodipodi:type="arc"
transform="matrix(1.3340954,0,0,1.3333333,-184.1736,-187.16666)" />
<path
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45198,7 +45860,7 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 440.514,108.7895 c -0.15988,-1.64913 1.04738,-3.11561 2.6965,-3.2755 1.64913,-0.15988 3.11561,1.04738 3.2755,2.6965 0.15988,1.64913 -1.04738,3.11561 -2.6965,3.2755 -0.37605,0.0365 -0.75561,0.002 -1.1187,-0.10287" />
+ d="m 440.514,108.7895 a 3,3 0 1 1 2.1568,2.59363" />
<path
transform="matrix(1.1662469,0,0,1.1666676,-109.73384,-169.08343)"
sodipodi:type="arc"
@@ -45208,12 +45870,12 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" />
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
<path
sodipodi:open="true"
sodipodi:end="5.930273"
sodipodi:start="0.96146912"
- d="m 445.21695,110.9601 c -1.35868,0.94824 -3.22881,0.61552 -4.17705,-0.74315 -0.94824,-1.35868 -0.61552,-3.22881 0.74315,-4.17705 1.35868,-0.94824 3.22881,-0.61552 4.17705,0.74315 0.14695,0.21056 0.26626,0.43911 0.35501,0.68005"
+ d="m 445.21695,110.9601 a 3,3 0 1 1 1.09816,-3.497"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45238,7 +45900,7 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" />
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
<rect
y="-43"
x="407"
@@ -45247,7 +45909,7 @@
id="rect30207"
style="fill:#2b2200;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45320,7 +45982,7 @@
</g>
<g
style="opacity:0.98000004;display:inline"
- id="g30282"
+ id="ICON_OUTLINER_DATA_CAMERA"
transform="translate(-271.99542,457.0625)">
<rect
style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -45330,7 +45992,7 @@
x="403"
y="-48" />
<path
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45348,7 +46010,7 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" />
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
<path
transform="matrix(1.1662469,0,0,1.1666676,-103.72925,-170.08344)"
sodipodi:type="arc"
@@ -45358,7 +46020,7 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" />
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
<path
style="fill:#787878;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 407.5,-39.5 0,1.999993 -2,0 0,2 2,0 0,1 1,1 5,7e-6 0,-1 2.99542,0 1.5,1 0.25,0 0,-5 -0.25,0 -1.5,1 -2.99542,0 0,-2 -6,0 z"
@@ -45366,7 +46028,7 @@
sodipodi:nodetypes="cccccccccccccccccc"
inkscape:connector-curvature="0" />
<path
- d="m 440.514,108.7895 c -0.15988,-1.64913 1.04738,-3.11561 2.6965,-3.2755 1.64913,-0.15988 3.11561,1.04738 3.2755,2.6965 0.15988,1.64913 -1.04738,3.11561 -2.6965,3.2755 -0.37605,0.0365 -0.75561,0.002 -1.1187,-0.10287"
+ d="m 440.514,108.7895 a 3,3 0 1 1 2.1568,2.59363"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45379,7 +46041,7 @@
sodipodi:end="8.1340281"
sodipodi:open="true" />
<path
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45397,7 +46059,7 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 445.21695,110.9601 c -1.35868,0.94824 -3.22881,0.61552 -4.17705,-0.74315 -0.94824,-1.35868 -0.61552,-3.22881 0.74315,-4.17705 1.35868,-0.94824 3.22881,-0.61552 4.17705,0.74315 0.14695,0.21056 0.26626,0.43911 0.35501,0.68005"
+ d="m 445.21695,110.9601 a 3,3 0 1 1 1.09816,-3.497"
sodipodi:start="0.96146912"
sodipodi:end="5.930273"
sodipodi:open="true" />
@@ -45409,7 +46071,7 @@
x="409"
y="-41" />
<path
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45434,7 +46096,7 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" />
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
<rect
y="-43.99012"
x="413.00003"
@@ -45499,7 +46161,7 @@
</g>
<g
style="opacity:0.98000004;display:inline"
- id="g30350"
+ id="ICON_CAMERA_DATA"
transform="translate(-145.99542,541.00002)">
<rect
style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -45509,7 +46171,7 @@
x="403"
y="-48" />
<path
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45527,7 +46189,7 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" />
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
<path
transform="matrix(1.1662469,0,0,1.1666676,-103.72925,-170.08344)"
sodipodi:type="arc"
@@ -45537,7 +46199,7 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" />
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
<path
style="fill:#787878;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 407.5,-39.5 0,1.999993 -2,0 0,2 2,0 0,1 1,1 5,7e-6 0,-1 2.99542,0 1.5,1 0.25,0 0,-5 -0.25,0 -1.5,1 -2.99542,0 0,-2 -6,0 z"
@@ -45545,7 +46207,7 @@
sodipodi:nodetypes="cccccccccccccccccc"
inkscape:connector-curvature="0" />
<path
- d="m 440.514,108.7895 c -0.15988,-1.64913 1.04738,-3.11561 2.6965,-3.2755 1.64913,-0.15988 3.11561,1.04738 3.2755,2.6965 0.15988,1.64913 -1.04738,3.11561 -2.6965,3.2755 -0.37605,0.0365 -0.75561,0.002 -1.1187,-0.10287"
+ d="m 440.514,108.7895 a 3,3 0 1 1 2.1568,2.59363"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45558,7 +46220,7 @@
sodipodi:end="8.1340281"
sodipodi:open="true" />
<path
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45576,7 +46238,7 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 445.21695,110.9601 c -1.35868,0.94824 -3.22881,0.61552 -4.17705,-0.74315 -0.94824,-1.35868 -0.61552,-3.22881 0.74315,-4.17705 1.35868,-0.94824 3.22881,-0.61552 4.17705,0.74315 0.14695,0.21056 0.26626,0.43911 0.35501,0.68005"
+ d="m 445.21695,110.9601 a 3,3 0 1 1 1.09816,-3.497"
sodipodi:start="0.96146912"
sodipodi:end="5.930273"
sodipodi:open="true" />
@@ -45588,7 +46250,7 @@
x="409"
y="-41" />
<path
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z"
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="108.5"
@@ -45613,7 +46275,7 @@
sodipodi:cy="108.5"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m 446.5,108.5 c 0,1.65685 -1.34315,3 -3,3 -1.65685,0 -3,-1.34315 -3,-3 0,-1.65685 1.34315,-3 3,-3 1.65685,0 3,1.34315 3,3 z" />
+ d="m 446.5,108.5 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z" />
<rect
y="-43.99012"
x="413.00003"
@@ -45676,153 +46338,107 @@
id="rect30392"
style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17352"
- width="16"
- height="16"
- x="194"
- y="10" />
- <g
- id="g40205">
- <rect
- y="11.546152"
- x="195.49998"
- height="12.953857"
- width="13.016124"
- id="rect17356"
- style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- ry="0" />
- <rect
- ry="0"
- style="fill:url(#linearGradient40202);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17358"
- width="11.000001"
- height="11.046139"
- x="197.01611"
- y="12.00001" />
- <g
- transform="translate(146.99999,-417.99999)"
- id="g40036">
- <g
- id="g39822"
- transform="translate(-146.99999,417.99999)">
- <rect
- y="12"
- x="196"
- height="3"
- width="3"
- id="rect39628"
- style="fill:#106386;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- y="15"
- x="199"
- height="3"
- width="3"
- id="rect39636"
- style="fill:#ba0036;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#9f0022;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect39670"
- width="3"
- height="3"
- x="202"
- y="12" />
- <rect
- style="fill:#688c7f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect39676"
- width="3"
- height="3"
- x="205"
- y="15" />
- <rect
- style="fill:#b77100;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect39678"
- width="3"
- height="3"
- x="196"
- y="18" />
- <rect
- style="fill:#a67c58;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect39684"
- width="3"
- height="3"
- x="199"
- y="21" />
- <rect
- y="18"
- x="202"
- height="3"
- width="3"
- id="rect39686"
- style="fill:#7a2537;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- y="21"
- x="205"
- height="3"
- width="3"
- id="rect39692"
- style="fill:#869c2b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
- </g>
- <path
- sodipodi:nodetypes="ccc"
- id="path17363"
- d="m 207.51769,12.50001 -11.0177,0 0,11 11.0177,0 0,-11"
- style="fill:none;stroke:url(#linearGradient40189);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- </g>
- <rect
- y="10"
- x="174"
- height="16"
- width="16"
- id="rect39978"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- id="g17366"
- transform="translate(286,-429)">
+ id="ICON_IMAGE_RGB">
+ <rect
+ y="10"
+ x="194"
+ height="16"
+ width="16"
+ id="rect17352"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- id="g17368"
- transform="translate(16,-32)">
+ id="g40205">
<rect
- y="471"
- x="-45"
- height="16"
- width="16"
- id="rect17370"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ ry="0"
+ style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17356"
+ width="13.016124"
+ height="12.953857"
+ x="195.49998"
+ y="11.546152" />
<rect
- y="472.5"
- x="-43.483856"
- height="13"
- width="12.983856"
- id="rect17372"
- style="fill:url(#linearGradient17429);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline" />
+ y="12.00001"
+ x="197.01611"
+ height="11.046139"
+ width="11.000001"
+ id="rect17358"
+ style="fill:url(#linearGradient40202);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <g
+ id="g40036"
+ transform="translate(146.99999,-417.99999)">
+ <g
+ transform="translate(-146.99999,417.99999)"
+ id="g39822">
+ <rect
+ style="fill:#106386;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39628"
+ width="3"
+ height="3"
+ x="196"
+ y="12" />
+ <rect
+ style="fill:#ba0036;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39636"
+ width="3"
+ height="3"
+ x="199"
+ y="15" />
+ <rect
+ y="12"
+ x="202"
+ height="3"
+ width="3"
+ id="rect39670"
+ style="fill:#9f0022;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="15"
+ x="205"
+ height="3"
+ width="3"
+ id="rect39676"
+ style="fill:#688c7f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="18"
+ x="196"
+ height="3"
+ width="3"
+ id="rect39678"
+ style="fill:#b77100;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="21"
+ x="199"
+ height="3"
+ width="3"
+ id="rect39684"
+ style="fill:#a67c58;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#7a2537;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39686"
+ width="3"
+ height="3"
+ x="202"
+ y="18" />
+ <rect
+ style="fill:#869c2b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect39692"
+ width="3"
+ height="3"
+ x="205"
+ y="21" />
+ </g>
+ </g>
<path
- sodipodi:nodetypes="cccc"
- id="path17374"
- d="m -31.5,473.50001 -10.983862,0 0,11"
- style="fill:none;stroke:url(#linearGradient17431);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5;display:inline"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient40189);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 207.51769,12.50001 -11.0177,0 0,11 11.0177,0 0,-11"
+ id="path17363"
+ sodipodi:nodetypes="ccc" />
</g>
- <rect
- y="443"
- x="-25"
- height="5"
- width="5"
- id="rect17376"
- style="fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17379"
- width="5"
- height="5"
- x="-22"
- y="446" />
</g>
<g
- id="g32743"
+ id="ICON_IMAGE_ALPHA"
transform="translate(9.471,32.00923)">
<rect
y="-22.009235"
@@ -45855,55 +46471,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g17336"
- transform="translate(275,-385.99999)"
- style="opacity:0.25">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17338"
- width="16"
- height="16"
- x="-60"
- y="396" />
- <g
- id="g17340">
- <rect
- y="397.54614"
- x="-58.500015"
- height="12.953857"
- width="13.016124"
- id="rect17342"
- style="fill:url(#linearGradient32725);fill-opacity:1;fill-rule:nonzero;stroke:#333333;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- ry="0" />
- <rect
- ry="0"
- style="fill:url(#linearGradient32727);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17344"
- width="11.000001"
- height="11.046139"
- x="-56.983894"
- y="398" />
- <path
- style="fill:url(#linearGradient32729);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m -58,398 0,2 2,0 0,-2 -2,0 z m 2,2 0,2 2,0 0,-2 -2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 2,0 0,2 2,0 0,-2 -2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 2,0 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m 0,2 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m 0,2 0,2 2,0 0,-2 -2,0 z m -2,0 -2,0 0,2 2,0 0,-2 z m -2,0 0,-2 -2,0 0,2 2,0 z m -2,0 -2,0 0,2 2,0 0,-2 z m -2,0 0,-2 -2,0 0,2 2,0 z m 0,-2 2,0 0,-2 -2,0 0,2 z m 0,-2 0,-2 -2,0 0,2 2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 2,0 0,2 2,0 0,-2 -2,0 z"
- id="path17346"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccc"
- id="path17348"
- d="m -46.482307,398.50001 -11.017704,0 0,11 11.017704,0 0,-11"
- style="opacity:0.45;fill:none;stroke:url(#linearGradient32731);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- <path
- style="opacity:0.65;fill:none;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 217.5,24.000005 11.5,-11.5"
- id="path17578"
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0" />
- <g
- id="g17152"
+ id="ICON_LOCKVIEW_ON"
transform="translate(339,-210)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -46028,7 +46596,7 @@
</g>
</g>
<g
- id="g18489"
+ id="ICON_LOCKVIEW_OFF"
transform="translate(287,-54.93125)">
<g
id="g18491"
@@ -46173,7 +46741,7 @@
</g>
</g>
<g
- id="g18658"
+ id="ICON_FONTPREVIEW"
transform="translate(-147.04123,1.9815)">
<rect
y="71.018501"
@@ -46247,7 +46815,7 @@
</g>
<g
transform="translate(2,529.00001)"
- id="g18738"
+ id="ICON_FULLSCREEN"
style="display:inline">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -46308,7 +46876,7 @@
</g>
<g
transform="translate(256.9902,446.00001)"
- id="g18759"
+ id="ICON_MENU_PANEL"
style="display:inline">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -46372,7 +46940,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g18864"
+ id="ICON_SPLITSCREEN"
transform="translate(210,253.00005)">
<rect
y="345"
@@ -46461,7 +47029,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g17204"
+ id="ICON_LONGDISPLAY"
transform="translate(290,-291)">
<g
transform="translate(-204,295)"
@@ -46527,7 +47095,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g17183"
+ id="ICON_SHORTDISPLAY"
transform="translate(294,-291)">
<g
style="display:inline"
@@ -46618,7 +47186,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g41473">
+ id="ICON_SCENE_DATA">
<g
id="g20803"
transform="translate(-116.99998,424.00001)">
@@ -46633,11 +47201,11 @@
sodipodi:cy="192.5"
sodipodi:rx="1.75"
sodipodi:ry="1.75"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
transform="matrix(1.9999998,0,0,2.0000014,-462.99991,-192.00026)" />
<path
transform="matrix(1.4285718,0,0,1.4285718,-197.57158,-82.000059)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -46653,7 +47221,7 @@
sodipodi:cy="192.5"
sodipodi:rx="1.75"
sodipodi:ry="1.75"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
transform="matrix(0.8571429,0,0,0.8571429,67.857123,27.999992)" />
</g>
<rect
@@ -46695,7 +47263,7 @@
sodipodi:cy="-222"
sodipodi:rx="3.3084693"
sodipodi:ry="1.2798798"
- d="m 111.30847,-222 c 0,0.70686 -1.48125,1.27988 -3.30847,1.27988 -1.82722,0 -3.30847,-0.57302 -3.30847,-1.27988 0,-0.70686 1.48125,-1.27988 3.30847,-1.27988 1.82722,0 3.30847,0.57302 3.30847,1.27988 z"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
transform="matrix(0.9067635,0,0,1.3047091,374.56954,447.97555)" />
<path
sodipodi:nodetypes="cccsccc"
@@ -46711,7 +47279,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -46725,7 +47293,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -46737,7 +47305,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -46757,7 +47325,7 @@
</g>
</g>
<g
- id="g17123"
+ id="ICON_PARTICLEMODE"
transform="translate(207.01492,72.000007)">
<rect
y="442"
@@ -46786,7 +47354,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g17299"
+ id="ICON_GO_LEFT"
transform="translate(-21,128.00001)">
<g
transform="translate(464,422)"
@@ -46875,22 +47443,8 @@
</g>
</g>
<g
- id="g17117" />
- <g
- id="g17121"
- transform="translate(9,0)" />
- <g
- transform="translate(6,4)"
- id="g17128" />
- <g
- id="g17136"
- transform="translate(1,6)" />
- <g
- id="g17149"
- transform="translate(8,7)" />
- <g
style="display:inline"
- id="g22103"
+ id="ICON_GAME"
transform="translate(-10,466.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -46985,7 +47539,7 @@
y="328.03571" />
<path
transform="matrix(1.6666708,0,0,1.6666633,-190.66784,-215.66559)"
- d="m 287.5,325 c 0,0.82843 -0.67157,1.5 -1.5,1.5 -0.82843,0 -1.5,-0.67157 -1.5,-1.5 0,-0.82843 0.67157,-1.5 1.5,-1.5 0.82843,0 1.5,0.67157 1.5,1.5 z"
+ d="m 287.5,325 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
sodipodi:ry="1.5"
sodipodi:rx="1.5"
sodipodi:cy="325"
@@ -47015,7 +47569,7 @@
sodipodi:cy="325"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="m 287.5,325 c 0,0.82843 -0.67157,1.5 -1.5,1.5 -0.82843,0 -1.5,-0.67157 -1.5,-1.5 0,-0.82843 0.67157,-1.5 1.5,-1.5 0.82843,0 1.5,0.67157 1.5,1.5 z"
+ d="m 287.5,325 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
transform="matrix(1.333351,0,0,1.333345,-95.338377,-107.33714)" />
<rect
y="331"
@@ -47064,7 +47618,7 @@
</g>
</g>
<g
- id="g34058"
+ id="ICON_SORTBYEXT"
transform="translate(0,12)">
<path
sodipodi:nodetypes="cccccc"
@@ -47167,7 +47721,7 @@
</g>
<g
style="display:inline"
- id="g22429"
+ id="ICON_UGLYPACKAGE"
transform="translate(542.99004,484.00118)">
<rect
y="9"
@@ -47249,16 +47803,9 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17123"
- width="1"
- height="0"
- x="90"
- y="523" />
<g
style="display:inline"
- id="g18470"
+ id="ICON_HAIR"
transform="matrix(-1,0,0,1,269,-561)">
<rect
style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -47288,7 +47835,7 @@
</g>
<g
style="display:inline"
- id="g22771"
+ id="ICON_PHYSICS"
transform="translate(-186,487.00001)">
<g
id="g21832"
@@ -47372,7 +47919,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -47385,7 +47932,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -47395,7 +47942,7 @@
</g>
<g
style="display:inline"
- id="g35565"
+ id="ICON_PINNED"
transform="translate(147,527.00001)"
inkscape:export-filename="/home/wolter/Documenten/Blender/Icons/Fake2.png"
inkscape:export-xdpi="90"
@@ -47414,7 +47961,7 @@
id="g34916">
<path
transform="translate(58.032932,-27.838387)"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="-32"
@@ -47430,7 +47977,7 @@
sodipodi:cy="-32"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(1.4285714,0,0,1.4274429,55.5,-11.825777)" />
</g>
<g
@@ -47444,11 +47991,11 @@
sodipodi:cy="-32"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(1.1751782,0,0,1.1751782,56.000001,-1.2882925)" />
<path
transform="matrix(0.9994022,0,0,0.9994021,56.002092,-6.9152216)"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="-32"
@@ -47464,7 +48011,7 @@
sodipodi:cy="-32"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(0.774689,0,0,0.7805148,56.890573,-14.812697)" />
<path
sodipodi:type="arc"
@@ -47474,11 +48021,11 @@
sodipodi:cy="-32"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(1.0042021,0,0,1.0042021,55.985293,-6.7448206)" />
<path
transform="matrix(0.9108044,0,0,0.9108044,55.985293,-9.7335486)"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="-32"
@@ -47492,7 +48039,7 @@
id="g34934">
<path
transform="matrix(0.8571429,0,0,0.8571429,58.032932,-32.409816)"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="-32"
@@ -47508,11 +48055,11 @@
sodipodi:cy="-32"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(0.7142853,0,0,0.7142853,58.032932,-36.981258)" />
<path
transform="translate(58.032932,-27.838387)"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="-32"
@@ -47528,14 +48075,14 @@
sodipodi:cy="-32"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 3.5,-32 c 0,1.932997 -1.5670034,3.5 -3.5,3.5 -1.9329966,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.5670034,-3.5 3.5,-3.5 1.9329966,0 3.5,1.567003 3.5,3.5 z"
+ d="m 3.5,-32 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(0.8571429,0,0,0.8571429,58.032932,-32.409816)" />
</g>
</g>
</g>
<g
style="display:inline"
- id="g35712"
+ id="ICON_UNPINNED"
transform="translate(307,636)"
inkscape:export-filename="/home/wolter/Documenten/Blender/Icons/Fake1.png"
inkscape:export-xdpi="90"
@@ -47646,19 +48193,8 @@
inkscape:connector-curvature="0" />
</g>
<g
- style="fill:#d45500;fill-opacity:1;display:inline"
- transform="translate(47,-247.0151)"
- id="g51988" />
- <rect
- y="73"
- x="277.99997"
- height="16"
- width="16"
- id="rect51964"
- style="opacity:0.01000001;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
style="opacity:0.65;display:inline"
- id="g11875"
+ id="ICON_SNAP_OFF"
transform="translate(-334,109.04419)">
<path
style="fill:#ff0000;fill-opacity:0.75;fill-rule:evenodd;stroke:url(#linearGradient68937);stroke-width:2.4000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -47725,7 +48261,7 @@
</g>
<g
transform="translate(-313,109)"
- id="g51645"
+ id="ICON_SNAP_ON"
style="display:inline">
<rect
style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
@@ -47794,7 +48330,7 @@
</g>
</g>
<g
- id="g28545"
+ id="ICON_SNAP_SURFACE"
transform="translate(21,-19)">
<g
style="opacity:0.8;display:inline"
@@ -47812,7 +48348,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -47829,7 +48365,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -47838,7 +48374,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -47927,7 +48463,7 @@
</g>
<g
style="display:inline"
- id="g20285"
+ id="ICON_SPEAKER"
transform="translate(0,107.00001)">
<rect
y="449"
@@ -48045,7 +48581,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g38213"
+ id="ICON_EDITMODE_HLT"
transform="translate(0,-1.00005)">
<rect
y="513.99988"
@@ -48241,7 +48777,7 @@
</g>
</g>
<g
- id="g39255"
+ id="ICON_IMGDISPLAY"
transform="translate(-21,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -48379,7 +48915,7 @@
<g
style="display:inline"
transform="translate(168,-37)"
- id="g39106">
+ id="ICON_SNAP_VERTEX">
<g
style="opacity:0.5;display:inline"
id="g39108"
@@ -48508,7 +49044,7 @@
<g
style="display:inline"
transform="translate(168,-37)"
- id="g39140">
+ id="ICON_SNAP_EDGE">
<g
transform="translate(90,-142)"
id="g39142"
@@ -48652,7 +49188,7 @@
<g
style="display:inline"
transform="translate(168,-37)"
- id="g39172">
+ id="ICON_SNAP_FACE">
<g
style="opacity:0.5;display:inline"
id="g39174"
@@ -48752,7 +49288,7 @@
</g>
</g>
<g
- id="g28811"
+ id="ICON_MATERIAL_DATA"
transform="translate(0,128.00001)">
<rect
y="365"
@@ -48769,7 +49305,7 @@
inkscape:export-ydpi="90"
transform="matrix(1.0004639,0,0,0.9963165,-69.122722,304.28985)">
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -48795,7 +49331,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -48805,7 +49341,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -48818,7 +49354,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -48842,7 +49378,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -48854,7 +49390,7 @@
</g>
</g>
<g
- id="g40234">
+ id="ICON_OBJECT_DATAMODE">
<rect
y="514.00012"
x="5"
@@ -48929,17 +49465,13 @@
</g>
<g
style="display:inline"
- id="g57337"
- transform="translate(10,254)" />
- <g
- style="display:inline"
- id="g57399"
+ id="ICON_MATERIAL"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(1.0004639,0,0,0.9963165,-237.12363,495.28986)">
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -48965,7 +49497,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -48975,7 +49507,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -48988,7 +49520,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -49012,7 +49544,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -49024,7 +49556,7 @@
</g>
<g
style="display:inline"
- id="g22832"
+ id="ICON_MOD_CLOTH"
transform="translate(73,-15)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -49116,7 +49648,7 @@
</g>
<g
transform="translate(-105,-229)"
- id="g22900"
+ id="ICON_PLAY_AUDIO"
style="display:inline">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -49234,7 +49766,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g23411"
+ id="ICON_MOD_EXPLODE"
transform="translate(-399,-19)">
<rect
transform="scale(-1,1)"
@@ -49269,7 +49801,7 @@
sodipodi:cy="-222"
sodipodi:rx="3.3084693"
sodipodi:ry="1.2798798"
- d="m 111.30847,-222 c 0,0.70686 -1.48125,1.27988 -3.30847,1.27988 -1.82722,0 -3.30847,-0.57302 -3.30847,-1.27988 0,-0.70686 1.48125,-1.27988 3.30847,-1.27988 1.82722,0 3.30847,0.57302 3.30847,1.27988 z"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
transform="matrix(0.9067635,0,0,1.3047091,374.56954,447.97555)" />
<path
sodipodi:nodetypes="cccsccc"
@@ -49463,7 +49995,7 @@
</g>
</g>
<g
- id="g22853"
+ id="ICON_MOD_MESHDEFORM"
transform="translate(4.2e-4,2.056923)">
<g
style="display:inline"
@@ -49598,7 +50130,7 @@
</g>
</g>
<g
- id="g40939"
+ id="ICON_MOD_BUILD"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -49696,7 +50228,7 @@
</g>
</g>
<g
- id="g40825"
+ id="ICON_MOD_BOOLEAN"
transform="translate(0,1)">
<rect
y="260"
@@ -49767,11 +50299,9 @@
</g>
</g>
<g
- id="g23613" />
- <g
style="display:inline;enable-background:new"
transform="translate(404,214.02012)"
- id="g13021">
+ id="ICON_MOD_BEVEL">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect12989"
@@ -49823,116 +50353,7 @@
</g>
</g>
<g
- style="display:inline;enable-background:new"
- transform="translate(-0.9999998,2.020123)"
- id="g23516">
- <rect
- style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23518"
- width="16"
- height="16"
- x="489"
- y="260" />
- <path
- sodipodi:nodetypes="cssc"
- d="m 499.5,261.50004 -4.5,2 c -1.94148,0.86288 -2.18285,2.53884 -3,4.5 l -1.25,3"
- style="fill:none;stroke:#0b1728;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path23520"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccccccccc"
- id="path23522"
- d="m 503,268.00008 0,2.99996 -3,1.5 c -3,1.5 -6.25,1.5 -10,1.49996 l 0,-2.49996 c 0.5,-0.99996 1.75,-2.75004 5,-4.00004 l 4,-1.5 1,0 3,1.25 0,0.75008 z"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
- inkscape:connector-curvature="0" />
- <path
- id="path23524"
- d="m 495,267.5 4,-1.5 1,0 3,1.25 0,0.75004 0,2.75 -3,1.5 -10,1.5 0,-1.75 c 0.5,-1 1.77456,-3.24182 5,-4.50004 z"
- style="fill:#c2d4ef;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
- sodipodi:nodetypes="cccccccccc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- id="path23542"
- style="fill:none;stroke:url(#linearGradient23555);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 496.75,263.00004 c -3,1.5 -2.75,8.5 2.25,7"
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0" />
- <path
- style="fill:url(#linearGradient23581);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 519.82031,262 c 0.5,-0.16016 0.35115,-1.44373 -0.66015,-1 l -3.91016,1.75 c -2.5,0.75 -2.85099,2.90496 -3.82813,5.08203 L 510,271 l 0,3 c 3.76795,10e-6 7,0 10,-1.5 0.59071,-0.29535 2.31945,-1.15973 3,-1.5 l 0,-3 c -0.71506,0.35798 -2.3836,1.1918 -3,1.5 -0.45529,0.22765 -0.90706,0.42996 -1.375,0.59375 -4.60397,1.02313 -4.54405,-5.38421 -1.625,-6.84375 l 2.82031,-1.25 z"
- transform="translate(-20,0)"
- id="path23526"
- sodipodi:nodetypes="cccsccsccsccc"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- style="fill:none;stroke:url(#linearGradient23550);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 490.5,273.51739 c 3.76795,0 5.75,-4e-5 8.75,-1.25004 0.60963,-0.25401 2.56945,-1.15973 3.25,-1.5"
- id="path23528"
- sodipodi:nodetypes="csc"
- inkscape:connector-curvature="0" />
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23530"
- width="2"
- height="1"
- x="497"
- y="267" />
- <g
- id="g23575"
- style="fill:#000000">
- <rect
- style="opacity:0.8;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23532"
- width="2"
- height="1"
- x="497"
- y="268" />
- <rect
- y="267"
- x="496"
- height="1.5"
- width="1"
- id="rect23534"
- style="opacity:0.6;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="opacity:0.6;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23536"
- width="1"
- height="1.5"
- x="499"
- y="267" />
- <rect
- y="266.5"
- x="497"
- height="0.5"
- width="2"
- id="rect23538"
- style="opacity:0.5;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
- <path
- sodipodi:nodetypes="csc"
- id="path23540"
- d="m 490.5,272.5 c 3.76795,0 5.75,-4e-5 8.75,-1.25004 0.60963,-0.25401 2.56945,-1.15973 3.25,-1.5"
- style="fill:none;stroke:url(#linearGradient23585);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- id="path23546"
- style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 499.5,261.50004 -3.07779,1.36791 L 495,263.50004 c -1.94148,0.86288 -2.18285,2.53884 -3,4.5 l -1.25,3"
- sodipodi:nodetypes="ccssc"
- inkscape:connector-curvature="0" />
- </g>
- <g
- id="g23587"
+ id="ICON_CONSTRAINT_DATA"
transform="translate(-42.01991,-103.9242)">
<rect
transform="matrix(0,-1,1,0,0,0)"
@@ -50009,7 +50430,7 @@
</g>
</g>
<g
- id="g22800"
+ id="ICON_MOD_SIMPLEDEFORM"
transform="translate(-21,2)">
<rect
y="260"
@@ -50051,7 +50472,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g23347"
+ id="ICON_TEXTURE_SHADED"
transform="translate(251.98387,128)"
style="display:inline">
<rect
@@ -50076,7 +50497,7 @@
inkscape:export-ydpi="90"
transform="matrix(1.0004639,0,0,0.9963165,-237.11238,367.28985)">
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -50097,7 +50518,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -50106,7 +50527,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -50134,7 +50555,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -50143,7 +50564,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -50160,7 +50581,7 @@
</g>
</g>
<g
- id="g22826"
+ id="ICON_MOD_MASK"
transform="translate(21,-18.979877)">
<rect
y="281"
@@ -50270,7 +50691,7 @@
</g>
</g>
<g
- id="g24003"
+ id="ICON_SNAP_VOLUME"
transform="translate(210,-37)"
style="display:inline">
<g
@@ -50368,7 +50789,7 @@
transform="translate(-1081.9421,-238.02038)" />
</g>
<g
- id="g24311"
+ id="ICON_ORTHO"
transform="translate(-16.99965,-228.99997)">
<g
style="opacity:0.55"
@@ -50548,21 +50969,8 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- style="opacity:0.01000001;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23719"
- width="0"
- height="0"
- x="547"
- y="255" />
- <g
- id="g24088"
- transform="translate(341,-57.00032)" />
- <g
- transform="translate(361,-56.00032)"
- id="g24276" />
<g
- id="g23953"
+ id="ICON_MONKEY"
transform="translate(-60,60)">
<rect
y="-29"
@@ -50622,11 +51030,11 @@
sodipodi:cy="-23"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="translate(0.5,-0.46875)" />
<path
transform="matrix(1.2143583,0,0,1.1512108,-28.054112,2.9290602)"
- d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="-23"
@@ -50636,7 +51044,7 @@
sodipodi:type="arc" />
<path
transform="matrix(0.8392157,0,0,0.8382979,21.884318,-4.2140957)"
- d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="-23"
@@ -50665,7 +51073,7 @@
sodipodi:cy="-23"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(1.2116904,0,0,1.1282344,-22.693138,2.3776257)" />
<path
sodipodi:type="arc"
@@ -50675,7 +51083,7 @@
sodipodi:cy="-23"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(0.8392157,0,0,0.8382979,26.893134,-4.2140957)" />
<path
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
@@ -50699,7 +51107,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g24504"
+ id="ICON_MOD_SHRINKWRAP"
transform="translate(-21,-19)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -50752,7 +51160,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(0.9067635,0,0,1.2421435,374.56954,430.00586)"
- d="m 111.30847,-222 c 0,0.70686 -1.48125,1.27988 -3.30847,1.27988 -1.82722,0 -3.30847,-0.57302 -3.30847,-1.27988 0,-0.70686 1.48125,-1.27988 3.30847,-1.27988 1.82722,0 3.30847,0.57302 3.30847,1.27988 z"
+ d="m 111.30847,-222 a 3.3084693,1.2798798 0 1 1 -6.61694,0 3.3084693,1.2798798 0 1 1 6.61694,0 z"
sodipodi:ry="1.2798798"
sodipodi:rx="3.3084693"
sodipodi:cy="-222"
@@ -50805,7 +51213,7 @@
</g>
</g>
<g
- id="g24095"
+ id="ICON_MOD_CAST"
transform="translate(126,23)">
<g
style="opacity:0.45;display:inline"
@@ -50829,7 +51237,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -50846,7 +51254,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -50860,7 +51268,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -50902,7 +51310,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -50915,7 +51323,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -50936,7 +51344,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41107"
+ id="ICON_MOD_SOFT"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -50991,7 +51399,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41132"
+ id="ICON_POSE_DATA"
transform="translate(237.98389,298.06154)">
<rect
inkscape:export-ydpi="90"
@@ -51047,7 +51455,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41146"
+ id="ICON_ARMATURE_DATA"
transform="translate(78,299.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -51120,7 +51528,7 @@
</g>
<g
transform="translate(28.983879,319.02657)"
- id="g41999"
+ id="ICON_POSE_HLT"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -51217,7 +51625,7 @@
</g>
<g
transform="translate(120,68)"
- id="g42071"
+ id="ICON_MOD_ARMATURE"
style="display:inline;enable-background:new">
<rect
y="194"
@@ -51290,7 +51698,7 @@
</g>
<g
transform="translate(-111,236)"
- id="g42095"
+ id="ICON_OUTLINER_OB_ARMATURE"
style="display:inline;enable-background:new">
<rect
y="194"
@@ -51372,7 +51780,7 @@
</g>
<g
transform="translate(113.22629,214.3098)"
- id="g42123"
+ id="ICON_OUTLINER_DATA_POSE"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -51466,7 +51874,7 @@
</g>
</g>
<g
- id="g42258"
+ id="ICON_OUTLINER_DATA_ARMATURE"
transform="translate(0,86)">
<g
transform="translate(-111,129)"
@@ -51580,26 +51988,7 @@
</g>
</g>
<g
- id="g22051"
- transform="translate(67,200.06499)"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- style="display:inline" />
- <g
- id="g40816"
- transform="translate(-23,0)">
- <g
- id="g40830" />
- </g>
- <g
- id="g23451"
- transform="translate(-393.99971,438.98222)" />
- <g
- id="g23461"
- transform="matrix(0.8342485,0,0,0.8354168,-433.47749,469.22699)" />
- <g
- id="g23710"
+ id="ICON_PLUG"
transform="translate(399,24.000007)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\x.png"
inkscape:export-xdpi="90"
@@ -51644,7 +52033,7 @@
</g>
<path
transform="matrix(0.9,0,0,0.9,7.6,60.3)"
- d="m 80.166667,603 c 0,2.30119 -1.865481,4.16667 -4.166667,4.16667 -2.301186,0 -4.166667,-1.86548 -4.166667,-4.16667 0,-2.30119 1.865481,-4.16667 4.166667,-4.16667 2.301186,0 4.166667,1.86548 4.166667,4.16667 z"
+ d="m 80.166667,603 a 4.1666665,4.1666665 0 1 1 -8.333334,0 4.1666665,4.1666665 0 1 1 8.333334,0 z"
sodipodi:ry="4.1666665"
sodipodi:rx="4.1666665"
sodipodi:cy="603"
@@ -51667,18 +52056,8 @@
x="77"
y="602" />
</g>
- <rect
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\s.png"
- y="262"
- x="194"
- height="16"
- width="16"
- id="rect23619"
- style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- id="g23350"
+ <g
+ id="ICON_PARTICLES"
transform="translate(0,128.00001)">
<rect
y="427.99997"
@@ -52039,7 +52418,7 @@
</g>
</g>
<g
- id="g23415"
+ id="ICON_PARTICLE_DATA"
transform="translate(62.999992,65.000007)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -52400,368 +52779,381 @@
</g>
</g>
<g
- transform="translate(-21.000008,-166)"
- id="g23639">
+ id="ICON_MOD_PARTICLES">
<rect
- y="427.99997"
- x="215"
- height="16"
+ style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23619"
width="16"
- id="rect23641"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\s.png"
- y="427.99997"
- x="215"
height="16"
- width="16"
- id="rect23643"
- style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ x="194"
+ y="262"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\s.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
<g
- id="g23645">
- <g
- id="g23647">
- <g
- id="g23649">
- <path
- inkscape:transform-center-y="-1.75"
- sodipodi:nodetypes="ccccccc"
- id="path23651"
- d="m 229.97728,432.50003 0,0 -2.86364,-0.81818 -1.22727,0.20455 0,1.22727 1.22727,0.20455 2.86364,-0.81819 0,0 0,0 0,0 z"
- style="fill:none;stroke:url(#linearGradient23797);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- sodipodi:nodetypes="ccccccc"
- id="path23653"
- d="m 226.5,435.97731 0,0 0.81819,-2.86364 -0.20455,-1.22727 -1.22727,0 -0.20455,1.22727 0.81818,2.86364 0,0 0,0 0,0 z"
- style="fill:none;stroke:url(#linearGradient23799);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- sodipodi:nodetypes="ccccccc"
- id="path23655"
- d="m 223.02273,432.50003 0,0 2.86364,0.81819 1.22727,-0.20455 0,-1.22727 -1.22727,-0.20455 -2.86364,0.81818 0,0 0,0 0,0 z"
- style="fill:none;stroke:url(#linearGradient23801);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- sodipodi:nodetypes="ccccccc"
- id="path23668"
- d="m 226.5,429.02276 0,0 -0.81818,2.86364 0.20455,1.22727 1.22727,0 0.20455,-1.22727 -0.81819,-2.86364 0,0 0,0 0,0 z"
- style="fill:none;stroke:url(#linearGradient23803);stroke-width:2.04500008;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- </g>
- <g
- id="g23670">
- <path
- inkscape:transform-center-y="-1.75"
- id="path23672"
- d="m 226.09091,428.00003 -0.4091,3.68182 0.20455,1.43182 1.22727,0 0.20455,-1.43182 -0.40909,-3.68182 -0.81818,0 0,0 0,0 0,0 z"
- style="fill:url(#linearGradient23805);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- id="path23674"
- d="m 231,432.09094 -3.68182,-0.40909 -1.43182,0.20454 0,1.22728 1.43182,0.20454 3.68182,-0.40909 0,-0.81818 0,0 0,0 0,0 z"
- style="fill:url(#linearGradient23807);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- id="path23676"
- d="m 226.09091,437.00003 -0.4091,-3.68182 0.20455,-1.43182 1.22727,0 0.20455,1.43182 -0.40909,3.68182 -0.81818,0 0,0 0,0 0,0 z"
- style="fill:url(#linearGradient23809);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- id="path23678"
- d="m 221.99999,432.90912 3.68182,0.40909 1.43182,-0.20454 0,-1.22728 -1.43182,-0.20454 -3.68182,0.40909 0,0.81818 0,0 0,0 0,0 z"
- style="fill:url(#linearGradient23811);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- </g>
- <g
- transform="translate(141,-197.00002)"
- id="g23680">
- <rect
- y="628.25"
- x="85"
- height="2.5"
- width="1"
- id="rect23682"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- transform="matrix(0,1,-1,0,0,0)"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23684"
- width="1"
- height="2.5"
- x="629"
- y="-86.75" />
- </g>
- </g>
+ id="g23639"
+ transform="translate(-21.000008,-166)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23641"
+ width="16"
+ height="16"
+ x="215"
+ y="427.99997" />
+ <rect
+ style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23643"
+ width="16"
+ height="16"
+ x="215"
+ y="427.99997"
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\s.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
<g
- id="g23686"
- transform="translate(0,-4)">
+ id="g23645">
<g
- id="g23688">
- <path
- inkscape:transform-center-y="-1.75"
- sodipodi:nodetypes="ccccccc"
- id="path23690"
- d="m 224.75,442.5 0,0 -3.5,-1 -1.5,0.25 0,1.5 1.5,0.25 3.5,-1 z"
- style="fill:none;stroke:url(#linearGradient23813);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- sodipodi:nodetypes="ccccccc"
- id="path23692"
- d="m 220.5,446.75 0,0 0.75001,-3.5 -1e-5,-1.5 -1.5,0 1e-5,1.5 0.74999,3.5 z"
- style="fill:none;stroke:url(#linearGradient23815);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- sodipodi:nodetypes="ccccccc"
- id="path23695"
- d="m 216.25,442.5 0,0 3.50001,0.75 1.49999,0 0,-1.5 -1.49999,0 -3.50001,0.75 z"
- style="fill:none;stroke:url(#linearGradient23817);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- sodipodi:nodetypes="ccccccc"
- id="path23697"
- d="m 220.5,438.25 0,0 -0.74999,3.75 -1e-5,1.25 1.5,0 1e-5,-1.25 -0.75001,-3.75 z"
- style="fill:none;stroke:url(#linearGradient23819);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- </g>
- <g
- id="g23700">
- <path
- inkscape:transform-center-y="-1.75"
- id="path23702"
- d="m 220,437 -0.5,4.5 0.25,1.75 1.5,0 0.25,-1.75 -0.5,-4.5 -1,0 z"
- style="fill:url(#linearGradient23821);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- id="path23704"
- d="m 226,442 -4.5,-0.5 -1.75,0.25 0,1.5 1.75,0.25 4.5,-0.5 0,-1 z"
- style="fill:url(#linearGradient23823);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- id="path23706"
- d="m 220,448 -0.5,-4.5 0.25,-1.75 1.5,0 0.25,1.75 -0.5,4.5 -1,0 z"
- style="fill:url(#linearGradient23825);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.75"
- id="path23708"
- d="m 215,443 4.5,0.5 1.75,-0.25 0,-1.5 -1.75,-0.25 -4.5,0.5 0,1 z"
- style="fill:url(#linearGradient23827);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- </g>
- <g
- transform="translate(135,-187.00002)"
- id="g23713">
- <rect
- y="628"
- x="85"
- height="2.9999599"
- width="1"
- id="rect23715"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- transform="matrix(0,1,-1,0,0,0)"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23717"
- width="1"
- height="3"
- x="629"
- y="-87" />
+ id="g23647">
+ <g
+ id="g23649">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23797);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 229.97728,432.50003 0,0 -2.86364,-0.81818 -1.22727,0.20455 0,1.22727 1.22727,0.20455 2.86364,-0.81819 0,0 0,0 0,0 z"
+ id="path23651"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23799);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 226.5,435.97731 0,0 0.81819,-2.86364 -0.20455,-1.22727 -1.22727,0 -0.20455,1.22727 0.81818,2.86364 0,0 0,0 0,0 z"
+ id="path23653"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23801);stroke-width:2.04545569;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 223.02273,432.50003 0,0 2.86364,0.81819 1.22727,-0.20455 0,-1.22727 -1.22727,-0.20455 -2.86364,0.81818 0,0 0,0 0,0 z"
+ id="path23655"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23803);stroke-width:2.04500008;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 226.5,429.02276 0,0 -0.81818,2.86364 0.20455,1.22727 1.22727,0 0.20455,-1.22727 -0.81819,-2.86364 0,0 0,0 0,0 z"
+ id="path23668"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ </g>
+ <g
+ id="g23670">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23805);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 226.09091,428.00003 -0.4091,3.68182 0.20455,1.43182 1.22727,0 0.20455,-1.43182 -0.40909,-3.68182 -0.81818,0 0,0 0,0 0,0 z"
+ id="path23672"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23807);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 231,432.09094 -3.68182,-0.40909 -1.43182,0.20454 0,1.22728 1.43182,0.20454 3.68182,-0.40909 0,-0.81818 0,0 0,0 0,0 z"
+ id="path23674"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23809);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 226.09091,437.00003 -0.4091,-3.68182 0.20455,-1.43182 1.22727,0 0.20455,1.43182 -0.40909,3.68182 -0.81818,0 0,0 0,0 0,0 z"
+ id="path23676"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23811);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 221.99999,432.90912 3.68182,0.40909 1.43182,-0.20454 0,-1.22728 -1.43182,-0.20454 -3.68182,0.40909 0,0.81818 0,0 0,0 0,0 z"
+ id="path23678"
+ inkscape:transform-center-y="-1.75" />
+ </g>
+ <g
+ id="g23680"
+ transform="translate(141,-197.00002)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23682"
+ width="1"
+ height="2.5"
+ x="85"
+ y="628.25" />
+ <rect
+ y="-86.75"
+ x="629"
+ height="2.5"
+ width="1"
+ id="rect23684"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ </g>
</g>
- </g>
- <g
- id="g23719"
- transform="translate(0,4)">
- <path
- inkscape:transform-center-y="-1.25"
- sodipodi:nodetypes="ccccccc"
- id="path23728"
- d="m 218.75004,424.50004 -0.5,0 -0.50004,1.74996 0.25004,1.75004 1,0 0.24996,-1.75004 -0.49996,-1.74996 z"
- style="fill:none;stroke:url(#linearGradient23829);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:url(#linearGradient23831);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 221.50004,427.75004 0,-0.5 -1.74996,-0.50004 -1.75004,0.25004 0,1 1.75004,0.24996 1.74996,-0.49996 z"
- id="path23736"
- sodipodi:nodetypes="ccccccc"
- inkscape:transform-center-y="-1.25"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:url(#linearGradient23833);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 215.50004,427.25004 0,0.5 1.74996,0.50004 1.75004,-0.25004 0,-1 -1.75004,-0.24996 -1.74996,0.49996 z"
- id="path23738"
- sodipodi:nodetypes="ccccccc"
- inkscape:transform-center-y="-1.25"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:url(#linearGradient23835);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 218.25004,430.50004 0.5,0 0.50004,-1.74996 -0.25004,-1.75004 -1,0 -0.24996,1.75004 0.49996,1.74996 z"
- id="path23740"
- sodipodi:nodetypes="ccccccc"
- inkscape:transform-center-y="-1.25"
- inkscape:connector-curvature="0" />
- <path
- inkscape:transform-center-y="-1.49998"
- id="path23742"
- d="m 218.00004,424.00004 -0.12109,2.86328 0.1211,1.13676 0.99999,-4e-5 0.125,-1.125 -0.125,-2.875 -1,0 0,0 0,0 0,0 z"
- style="fill:url(#linearGradient23837);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccccc"
- style="fill:url(#linearGradient23839);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 222.00004,427.00004 -2.86328,-0.12109 -1.13676,0.12109 4e-5,1 1.125,0.125 2.875,-0.125 0,-1 z"
- id="path23744"
- inkscape:transform-center-y="-1.49998"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccccc"
- style="fill:url(#linearGradient23841);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 219.00004,431.00004 0.12109,-2.86328 -0.1211,-1.13676 -0.99999,4e-5 -0.125,1.125 0.125,2.875 1,0 0,0 0,0 0,0 z"
- id="path23746"
- inkscape:transform-center-y="-1.49998"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccccc"
- style="fill:url(#linearGradient23843);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 215.00004,428.00004 2.86328,0.12109 1.13676,-0.12109 -4e-5,-1 -1.125,-0.125 -2.875,0.125 0,1 z"
- id="path23748"
- inkscape:transform-center-y="-1.49998"
- inkscape:connector-curvature="0" />
<g
- transform="translate(133.00004,-201.99996)"
- id="g23751">
- <rect
- y="628.5"
- x="85"
- height="2"
- width="1"
- id="rect23753"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- transform="matrix(0,1,-1,0,0,0)"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23755"
- width="1"
- height="2"
- x="629"
- y="-86.5" />
+ transform="translate(0,-4)"
+ id="g23686">
+ <g
+ id="g23688">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23813);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224.75,442.5 0,0 -3.5,-1 -1.5,0.25 0,1.5 1.5,0.25 3.5,-1 z"
+ id="path23690"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23815);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 220.5,446.75 0,0 0.75001,-3.5 -1e-5,-1.5 -1.5,0 1e-5,1.5 0.74999,3.5 z"
+ id="path23692"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23817);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 216.25,442.5 0,0 3.50001,0.75 1.49999,0 0,-1.5 -1.49999,0 -3.50001,0.75 z"
+ id="path23695"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23819);stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 220.5,438.25 0,0 -0.74999,3.75 -1e-5,1.25 1.5,0 1e-5,-1.25 -0.75001,-3.75 z"
+ id="path23697"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ </g>
+ <g
+ id="g23700">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23821);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 220,437 -0.5,4.5 0.25,1.75 1.5,0 0.25,-1.75 -0.5,-4.5 -1,0 z"
+ id="path23702"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23823);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 226,442 -4.5,-0.5 -1.75,0.25 0,1.5 1.75,0.25 4.5,-0.5 0,-1 z"
+ id="path23704"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23825);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 220,448 -0.5,-4.5 0.25,-1.75 1.5,0 0.25,1.75 -0.5,4.5 -1,0 z"
+ id="path23706"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23827);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 215,443 4.5,0.5 1.75,-0.25 0,-1.5 -1.75,-0.25 -4.5,0.5 0,1 z"
+ id="path23708"
+ inkscape:transform-center-y="-1.75" />
+ </g>
+ <g
+ id="g23713"
+ transform="translate(135,-187.00002)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23715"
+ width="1"
+ height="2.9999599"
+ x="85"
+ y="628" />
+ <rect
+ y="-87"
+ x="629"
+ height="3"
+ width="1"
+ id="rect23717"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ </g>
</g>
- </g>
- <g
- id="g23757"
- transform="translate(0,-4)">
<g
- transform="translate(0,-6.4549394)"
- id="g23759">
+ transform="translate(0,4)"
+ id="g23719">
<path
- inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23829);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 218.75004,424.50004 -0.5,0 -0.50004,1.74996 0.25004,1.75004 1,0 0.24996,-1.75004 -0.49996,-1.74996 z"
+ id="path23728"
sodipodi:nodetypes="ccccccc"
- id="path23767"
- d="m 230.20453,450.95187 0,0 -2.22727,-0.63574 -0.95454,0.15894 0,0.9536 0.95454,0.15893 2.22727,-0.63573 0,0 0,0 0,0 z"
- style="fill:none;stroke:url(#linearGradient23845);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
+ inkscape:transform-center-y="-1.25" />
<path
- inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-y="-1.25"
sodipodi:nodetypes="ccccccc"
- id="path23770"
- d="m 227.49999,453.65374 0,0 0.63637,-2.22507 -0.15909,-0.9536 -0.95455,0 -0.15909,0.9536 0.63636,2.22507 z"
- style="fill:none;stroke:url(#linearGradient23847);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
+ id="path23736"
+ d="m 221.50004,427.75004 0,-0.5 -1.74996,-0.50004 -1.75004,0.25004 0,1 1.75004,0.24996 1.74996,-0.49996 z"
+ style="fill:none;stroke:url(#linearGradient23831);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
- inkscape:transform-center-y="-1.75"
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-y="-1.25"
sodipodi:nodetypes="ccccccc"
- id="path23774"
- d="m 224.79546,450.95187 0,0 2.22727,0.63574 0.95454,-0.15894 0,-0.9536 -0.95454,-0.15893 -2.22727,0.63573 0,0 0,0 0,0 z"
- style="fill:none;stroke:url(#linearGradient23849);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
+ id="path23738"
+ d="m 215.50004,427.25004 0,0.5 1.74996,0.50004 1.75004,-0.25004 0,-1 -1.75004,-0.24996 -1.74996,0.49996 z"
+ style="fill:none;stroke:url(#linearGradient23833);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
- style="fill:none;stroke:url(#linearGradient23851);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 227.5,448.25 0,0 -0.63637,2.22507 0.15909,0.9536 0.95455,0 0.15909,-0.9536 L 227.5,448.25 z"
- id="path23776"
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-y="-1.25"
sodipodi:nodetypes="ccccccc"
- inkscape:transform-center-y="-1.75"
- inkscape:connector-curvature="0" />
- </g>
- <g
- id="g23778">
+ id="path23740"
+ d="m 218.25004,430.50004 0.5,0 0.50004,-1.74996 -0.25004,-1.75004 -1,0 -0.24996,1.75004 0.49996,1.74996 z"
+ style="fill:none;stroke:url(#linearGradient23835);stroke-width:1.58491683;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
- inkscape:transform-center-y="-1.75"
- id="path23780"
- d="m 227.18182,441.00653 -0.31818,2.86081 0.15909,1.11253 0.95454,0 0.15909,-1.11253 -0.31818,-2.86081 -0.63636,0 0,0 0,0 0,0 z"
- style="fill:url(#linearGradient23853);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
+ style="fill:url(#linearGradient23837);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 218.00004,424.00004 -0.12109,2.86328 0.1211,1.13676 0.99999,-4e-5 0.125,-1.125 -0.125,-2.875 -1,0 0,0 0,0 0,0 z"
+ id="path23742"
+ inkscape:transform-center-y="-1.49998" />
<path
- inkscape:transform-center-y="-1.75"
- id="path23782"
- d="m 231,444.1852 -2.86364,-0.31786 -1.11363,0.15893 0,0.9536 1.11363,0.15894 2.86364,-0.31787 0,-0.63574 0,0 0,0 0,0 z"
- style="fill:url(#linearGradient23856);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-y="-1.49998"
+ id="path23744"
+ d="m 222.00004,427.00004 -2.86328,-0.12109 -1.13676,0.12109 4e-5,1 1.125,0.125 2.875,-0.125 0,-1 z"
+ style="fill:url(#linearGradient23839);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc" />
<path
- inkscape:transform-center-y="-1.75"
- id="path23784"
- d="m 227.18182,447.99961 -0.31818,-2.8608 0.15909,-1.11254 0.95454,0 0.15909,1.11254 -0.31818,2.8608 -0.63636,0 0,0 0,0 0,0 z"
- style="fill:url(#linearGradient23858);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-y="-1.49998"
+ id="path23746"
+ d="m 219.00004,431.00004 0.12109,-2.86328 -0.1211,-1.13676 -0.99999,4e-5 -0.125,1.125 0.125,2.875 1,0 0,0 0,0 0,0 z"
+ style="fill:url(#linearGradient23841);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc" />
<path
- inkscape:transform-center-y="-1.75"
- id="path23786"
- d="m 224.00001,444.82094 2.86363,0.31787 1.11363,-0.15894 0,-0.9536 -1.11363,-0.15893 -2.86363,0.31786 0,0.63574 0,0 0,0 0,0 z"
- style="fill:url(#linearGradient23860);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- </g>
- <g
- id="g23788">
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-y="-1.49998"
+ id="path23748"
+ d="m 215.00004,428.00004 2.86328,0.12109 1.13676,-0.12109 -4e-5,-1 -1.125,-0.125 -2.875,0.125 0,1 z"
+ style="fill:url(#linearGradient23843);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccccc" />
<g
- transform="translate(141.99999,-184.99353)"
- id="g23791">
+ id="g23751"
+ transform="translate(133.00004,-201.99996)">
<rect
- y="628.5"
- x="85"
- height="2"
- width="1"
- id="rect23793"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- transform="matrix(0,1,-1,0,0,0)"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23795"
+ id="rect23753"
width="1"
height="2"
+ x="85"
+ y="628.5" />
+ <rect
+ y="-86.5"
x="629"
- y="-86.5" />
+ height="2"
+ width="1"
+ id="rect23755"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ </g>
+ </g>
+ <g
+ transform="translate(0,-4)"
+ id="g23757">
+ <g
+ id="g23759"
+ transform="translate(0,-6.4549394)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23845);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 230.20453,450.95187 0,0 -2.22727,-0.63574 -0.95454,0.15894 0,0.9536 0.95454,0.15893 2.22727,-0.63573 0,0 0,0 0,0 z"
+ id="path23767"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23847);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 227.49999,453.65374 0,0 0.63637,-2.22507 -0.15909,-0.9536 -0.95455,0 -0.15909,0.9536 0.63636,2.22507 z"
+ id="path23770"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient23849);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224.79546,450.95187 0,0 2.22727,0.63574 0.95454,-0.15894 0,-0.9536 -0.95454,-0.15893 -2.22727,0.63573 0,0 0,0 0,0 z"
+ id="path23774"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-y="-1.75"
+ sodipodi:nodetypes="ccccccc"
+ id="path23776"
+ d="m 227.5,448.25 0,0 -0.63637,2.22507 0.15909,0.9536 0.95455,0 0.15909,-0.9536 L 227.5,448.25 z"
+ style="fill:none;stroke:url(#linearGradient23851);stroke-width:1.59012127;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g23778">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23853);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 227.18182,441.00653 -0.31818,2.86081 0.15909,1.11253 0.95454,0 0.15909,-1.11253 -0.31818,-2.86081 -0.63636,0 0,0 0,0 0,0 z"
+ id="path23780"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23856);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 231,444.1852 -2.86364,-0.31786 -1.11363,0.15893 0,0.9536 1.11363,0.15894 2.86364,-0.31787 0,-0.63574 0,0 0,0 0,0 z"
+ id="path23782"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23858);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 227.18182,447.99961 -0.31818,-2.8608 0.15909,-1.11254 0.95454,0 0.15909,1.11254 -0.31818,2.8608 -0.63636,0 0,0 0,0 0,0 z"
+ id="path23784"
+ inkscape:transform-center-y="-1.75" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:url(#linearGradient23860);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 224.00001,444.82094 2.86363,0.31787 1.11363,-0.15894 0,-0.9536 -1.11363,-0.15893 -2.86363,0.31786 0,0.63574 0,0 0,0 0,0 z"
+ id="path23786"
+ inkscape:transform-center-y="-1.75" />
+ </g>
+ <g
+ id="g23788">
+ <g
+ id="g23791"
+ transform="translate(141.99999,-184.99353)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23793"
+ width="1"
+ height="2"
+ x="85"
+ y="628.5" />
+ <rect
+ y="-86.5"
+ x="629"
+ height="2"
+ width="1"
+ id="rect23795"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,-1,0,0,0)" />
+ </g>
</g>
</g>
</g>
</g>
</g>
<g
- id="g24300"
+ id="ICON_BUTS"
transform="translate(-49,6.0000069)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
inkscape:export-xdpi="90"
@@ -52904,7 +53296,7 @@
</g>
</g>
<g
- id="g24339"
+ id="ICON_IMASEL"
transform="translate(0,128.00001)">
<rect
y="407"
@@ -53005,11 +53397,7 @@
</g>
</g>
<g
- style="fill:#d45500;fill-opacity:1;display:inline"
- transform="translate(-65,-169.00755)"
- id="g24176" />
- <g
- id="g24393"
+ id="ICON_FILESEL"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -53106,208 +53494,219 @@
</g>
</g>
<g
- id="g22846"
- transform="translate(84,86)">
+ id="ICON_OUTLINER_DATA_LAMP">
<rect
ry="0"
- y="323"
- x="26"
+ y="409"
+ x="110"
height="16"
width="16"
- id="rect22783"
+ id="rect15876"
style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- id="g22817">
- <path
- style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
- id="path22788"
- sodipodi:nodetypes="cssssssc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cssssssc"
- id="path22790"
- d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
- style="opacity:0.9;fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 33,338 2,0 0,1 -2,-10e-6 L 33,338 z"
- id="path22792"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" />
+ transform="translate(84,86)"
+ id="g22846">
<rect
- style="fill:#24221c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect22794"
- width="6"
- height="4.75"
- x="31"
- y="333.25"
- rx="0.765625"
- ry="0.765625" />
- <rect
- y="334"
- x="32"
- height="3"
- width="4"
- id="rect22796"
- style="fill:#736c54;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- transform="matrix(1.0666667,0,0,1,-233.7,254.00667)"
- style="fill:url(#linearGradient22892);fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 249.09375,80 c -0.37566,0.05708 -0.59375,0.300736 -0.59375,0.5 0,0.227729 0.26882,0.500002 0.75,0.5 0.48959,-2e-6 2.86976,-0.0067 3.35937,-0.0067 0.4812,0 0.75,-0.272259 0.75,-0.5 0,-0.227736 -0.2688,-0.499998 -0.75,-0.5 L 249.25,80 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z m 0,2 c -0.37566,0.05708 -0.59375,0.300738 -0.59375,0.5 0,0.227729 0.26882,0.500003 0.75,0.5 l 3.35937,-0.0067 c 0.4812,0 0.75,-0.272257 0.75,-0.5 0,-0.227736 -0.2688,-0.499997 -0.75,-0.5 C 252.11976,81.993327 249.7396,82 249.25,82 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z"
- id="path22798"
- sodipodi:nodetypes="cssssccccsccsssc"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- id="path22800"
- d="m 32.25,336.24999 1.25,0"
- style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- d="m 32.25,334.24999 1.25,0"
- id="path22802"
- inkscape:connector-curvature="0" />
- <rect
- y="336"
- x="37"
- height="1"
- width="0.25"
- id="rect22804"
- style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect22807"
- width="0.25"
- height="1"
- x="37"
- y="334" />
- <rect
- style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect22809"
- width="0.25"
- height="1"
- x="30.75"
- y="336" />
- <rect
- y="334"
- x="30.75"
- height="1"
- width="0.25"
- id="rect22812"
- style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- transform="matrix(1.1428575,0,0,1.1249998,-252.2858,245.25001)"
- d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
- id="path22814"
- style="fill:url(#linearGradient22954);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
- inkscape:radius="0.5"
- sodipodi:type="inkscape:offset" />
- <path
- sodipodi:type="inkscape:offset"
- inkscape:radius="0.5"
- inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
- style="opacity:0.6;fill:url(#radialGradient22952);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path22816"
- d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
- transform="matrix(1.1428578,0,0,1.1562502,-252.28587,242.81248)" />
- <path
- d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
- style="fill:none;stroke:url(#linearGradient22928);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
- id="path22818"
- inkscape:connector-curvature="0" />
- <path
- transform="matrix(0.9552133,0,0,0.9315985,-40.901258,-140.2522)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- sodipodi:ry="2.5"
- sodipodi:rx="2.5312502"
- sodipodi:cy="502"
- sodipodi:cx="78"
- id="path22820"
- style="opacity:0.25;fill:url(#radialGradient22950);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
- sodipodi:ry="1"
- sodipodi:rx="1"
- sodipodi:cy="135"
- sodipodi:cx="64"
- id="path22822"
- style="opacity:0.9;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
- sodipodi:type="arc"
- transform="matrix(0.99567,0,-0.00787885,1,-30.663533,191)" />
- <path
- id="path22824"
- style="fill:none;stroke:url(#radialGradient22922);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
- d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
- inkscape:connector-curvature="0" />
- <rect
- y="333"
- x="31.5"
- height="0.75"
- width="5"
- id="rect22826"
- style="opacity:0.85;fill:#3d3829;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="ccccc"
- id="path22828"
- d="m 32.5,337.01145 3,-0.0115 0,1 -3,0.0114 0,-0.99999 0,9e-5 0,0 0,0 z"
- style="fill:#6c6753;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccc"
- id="path22830"
- d="m 33,330 0,2.75 2,0 0,-2.75 -2,0 z"
- style="opacity:0.2;fill:url(#linearGradient22917);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <rect
- y="328"
- x="32"
- height="1"
- width="1"
- id="rect22832"
- style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- d="m 32.875,333.12498 c 0,-1.39113 -0.517691,-2.25114 -1.113536,-2.77529 C 31.064459,329.73656 30.5,328.93567 30.5,327.93988 c 0,-1.84706 1.637,-3.43989 3.5,-3.43989 1.863,0 3.5,1.59283 3.5,3.43989 0,0.99579 -0.564459,1.79668 -1.261464,2.40981 -0.595845,0.52415 -1.113536,1.38416 -1.113536,2.77529"
- style="fill:none;stroke:url(#radialGradient23727);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
- id="path22836"
- sodipodi:nodetypes="csscssc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccc"
- id="path22838"
- d="m 33,338.00001 0.5,0 0,1 L 33,339 l 0,-0.99999 z"
- style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- <rect
- y="329"
- x="33"
- height="1"
- width="2"
- id="rect23759"
- style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23761"
- width="1"
- height="1"
- x="35"
- y="328" />
+ style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22783"
+ width="16"
+ height="16"
+ x="26"
+ y="323"
+ ry="0" />
+ <g
+ id="g22817">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssssc"
+ id="path22788"
+ d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.9;fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 38.5,327.9 c 0,1.37785 -0.5625,2.19999 -1.6875,3.29999 -1.125,1.1 0,3.3 -1.40625,3.3 l -2.8125,0 c -1.40625,0 -0.28125,-2.2 -1.40625,-3.3 -1.125,-1.1 -1.6875,-1.93254 -1.6875,-3.29999 0,-2.4288 2.016,-4.4 4.5,-4.4 2.484,0 4.5,1.9712 4.5,4.4 z"
+ id="path22790"
+ sodipodi:nodetypes="cssssssc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path22792"
+ d="m 33,338 2,0 0,1 -2,-10e-6 L 33,338 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ ry="0.765625"
+ rx="0.765625"
+ y="333.25"
+ x="31"
+ height="4.75"
+ width="6"
+ id="rect22794"
+ style="fill:#24221c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#736c54;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22796"
+ width="4"
+ height="3"
+ x="32"
+ y="334" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssssccccsccsssc"
+ id="path22798"
+ d="m 249.09375,80 c -0.37566,0.05708 -0.59375,0.300736 -0.59375,0.5 0,0.227729 0.26882,0.500002 0.75,0.5 0.48959,-2e-6 2.86976,-0.0067 3.35937,-0.0067 0.4812,0 0.75,-0.272259 0.75,-0.5 0,-0.227736 -0.2688,-0.499998 -0.75,-0.5 L 249.25,80 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z m 0,2 c -0.37566,0.05708 -0.59375,0.300738 -0.59375,0.5 0,0.227729 0.26882,0.500003 0.75,0.5 l 3.35937,-0.0067 c 0.4812,0 0.75,-0.272257 0.75,-0.5 0,-0.227736 -0.2688,-0.499997 -0.75,-0.5 C 252.11976,81.993327 249.7396,82 249.25,82 c -0.0601,0 -0.10258,-0.0082 -0.15625,0 z"
+ style="fill:url(#linearGradient22892);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ transform="matrix(1.0666667,0,0,1,-233.7,254.00667)" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 32.25,336.24999 1.25,0"
+ id="path22800"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path22802"
+ d="m 32.25,334.24999 1.25,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22804"
+ width="0.25"
+ height="1"
+ x="37"
+ y="336" />
+ <rect
+ y="334"
+ x="37"
+ height="1"
+ width="0.25"
+ id="rect22807"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="336"
+ x="30.75"
+ height="1"
+ width="0.25"
+ id="rect22809"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22812"
+ width="0.25"
+ height="1"
+ x="30.75"
+ y="334" />
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="0.5"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ style="fill:url(#linearGradient22954);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path22814"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ transform="matrix(1.1428575,0,0,1.1249998,-252.2858,245.25001)" />
+ <path
+ transform="matrix(1.1428578,0,0,1.1562502,-252.28587,242.81248)"
+ d="m 250.5,70 c -1.92579,0 -3.5,1.570388 -3.5,3.5 0,1.036273 0.43284,1.981065 1.15625,2.625 0.12299,0.109481 0.35065,0.504334 0.5,0.875 0.0747,0.185333 0.1355,0.365966 0.21875,0.53125 0.0416,0.08264 0.0782,0.159602 0.15625,0.25 0.0781,0.0904 0.22443,0.218751 0.46875,0.21875 l 2,0 c 0.24442,0 0.3907,-0.128341 0.46875,-0.21875 0.078,-0.09041 0.11462,-0.167341 0.15625,-0.25 0.0832,-0.165318 0.14407,-0.345883 0.21875,-0.53125 0.14936,-0.370734 0.3774,-0.765984 0.5,-0.875 C 253.56794,75.481034 254,74.536495 254,73.5 254,71.570387 252.42579,70 250.5,70 z"
+ id="path22816"
+ style="opacity:0.6;fill:url(#radialGradient22952);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.61155295;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:original="M 250.5 70.5 C 248.844 70.5 247.5 71.84032 247.5 73.5 C 247.5 74.394207 247.88111 75.199102 248.5 75.75 C 249.02979 76.22159 249.25 77.500001 249.5 77.5 C 249.75 77.5 251.25 77.500001 251.5 77.5 C 251.75 77.5 251.97036 76.220976 252.5 75.75 C 253.11956 75.199071 253.5 74.394767 253.5 73.5 C 253.5 71.840318 252.156 70.5 250.5 70.5 z "
+ inkscape:radius="0.5"
+ sodipodi:type="inkscape:offset" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path22818"
+ style="fill:none;stroke:url(#linearGradient22928);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient22950);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path22820"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.9552133,0,0,0.9315985,-40.901258,-140.2522)" />
+ <path
+ transform="matrix(0.99567,0,-0.00787885,1,-30.663533,191)"
+ sodipodi:type="arc"
+ style="opacity:0.9;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path22822"
+ sodipodi:cx="64"
+ sodipodi:cy="135"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 34.000001,324.48827 c 1.932,0 3.5,1.50111 3.5,3.35068 0,0.99715 -0.455735,1.89301 -1.178554,2.50697 -0.617914,0.52487 -1.154779,1.38605 -1.154779,2.77907 m -1.166667,-8.63672 c -1.932001,0 -3.500001,1.50111 -3.500001,3.35068 0,0.99715 0.455736,1.89301 1.178556,2.50697 0.617913,0.52487 1.154778,1.38605 1.154778,2.77907"
+ style="fill:none;stroke:url(#radialGradient22922);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ id="path22824" />
+ <rect
+ style="opacity:0.85;fill:#3d3829;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22826"
+ width="5"
+ height="0.75"
+ x="31.5"
+ y="333" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#6c6753;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 32.5,337.01145 3,-0.0115 0,1 -3,0.0114 0,-0.99999 0,9e-5 0,0 0,0 z"
+ id="path22828"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.2;fill:url(#linearGradient22917);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 33,330 0,2.75 2,0 0,-2.75 -2,0 z"
+ id="path22830"
+ sodipodi:nodetypes="ccccc" />
+ <rect
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect22832"
+ width="1"
+ height="1"
+ x="32"
+ y="328" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscssc"
+ id="path22836"
+ style="fill:none;stroke:url(#radialGradient23727);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
+ d="m 32.875,333.12498 c 0,-1.39113 -0.517691,-2.25114 -1.113536,-2.77529 C 31.064459,329.73656 30.5,328.93567 30.5,327.93988 c 0,-1.84706 1.637,-3.43989 3.5,-3.43989 1.863,0 3.5,1.59283 3.5,3.43989 0,0.99579 -0.564459,1.79668 -1.261464,2.40981 -0.595845,0.52415 -1.113536,1.38416 -1.113536,2.77529" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.3;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 33,338.00001 0.5,0 0,1 L 33,339 l 0,-0.99999 z"
+ id="path22838"
+ sodipodi:nodetypes="ccccc" />
+ <rect
+ style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23759"
+ width="2"
+ height="1"
+ x="33"
+ y="329" />
+ <rect
+ y="328"
+ x="35"
+ height="1"
+ width="1"
+ id="rect23761"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
</g>
</g>
<g
- id="g23767"
+ id="ICON_OUTLINER_OB_LAMP"
transform="translate(84,107.00001)">
<rect
style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -53433,7 +53832,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.9552133,0,0,0.9315985,-40.901258,-140.2522)" />
<path
transform="matrix(0.99567,0,-0.00787885,1,-30.654936,191)"
@@ -53444,7 +53843,7 @@
sodipodi:cy="135"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -53508,7 +53907,7 @@
</g>
</g>
<g
- id="g23912"
+ id="ICON_LAMP"
transform="translate(-21,233.00001)">
<rect
style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -53634,7 +54033,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.9552133,0,0,0.9315985,-40.901258,-140.2522)" />
<path
transform="matrix(0.99567,0,-0.00787885,1,-30.663533,191)"
@@ -53645,7 +54044,7 @@
sodipodi:cy="135"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -53709,113 +54108,123 @@
</g>
</g>
<g
- id="g25056"
- transform="translate(-168,2)">
+ id="ICON_NEWFOLDER">
+ <rect
+ style="opacity:0.01000001;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect51964"
+ width="16"
+ height="16"
+ x="277.99997"
+ y="73" />
<g
- style="opacity:0.75"
- id="g24996">
- <rect
- y="71"
- x="446"
- height="16"
- width="16"
- id="rect24939"
- style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ transform="translate(-168,2)"
+ id="g25056">
<g
- id="g24941"
- transform="translate(359,-336)">
- <path
- style="fill:url(#linearGradient25073);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 89.5,410.5 0,9.49245 1.5,1.5 8.5,0 0,-9.99245 -7,0 0,-1 -3,0 z"
- id="path24943"
- sodipodi:nodetypes="cccccccc"
- inkscape:connector-curvature="0" />
+ id="g24996"
+ style="opacity:0.75">
+ <rect
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24939"
+ width="16"
+ height="16"
+ x="446"
+ y="71" />
<g
- transform="translate(-361,287.99994)"
- id="g24945"
- style="display:inline" />
- <path
- style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient25075);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 92.5,414.4849 10,0.0151 0,5.50755 -1.5,1.49245 -10,0 0,-2 1.5,0 0,-5.0151 z"
- id="path24947"
- sodipodi:nodetypes="cccccccc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccccc"
- style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
- d="m 91.5,420.49245 -1.01563,-0.98437 0,-8.02344 1.01563,0.0154 0,1 7,0"
- id="path24949"
- inkscape:connector-curvature="0" />
+ transform="translate(359,-336)"
+ id="g24941">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc"
+ id="path24943"
+ d="m 89.5,410.5 0,9.49245 1.5,1.5 8.5,0 0,-9.99245 -7,0 0,-1 -3,0 z"
+ style="fill:url(#linearGradient25073);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="display:inline"
+ id="g24945"
+ transform="translate(-361,287.99994)" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc"
+ id="path24947"
+ d="m 92.5,414.4849 10,0.0151 0,5.50755 -1.5,1.49245 -10,0 0,-2 1.5,0 0,-5.0151 z"
+ style="fill:#d1c595;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient25075);stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24949"
+ d="m 91.5,420.49245 -1.01563,-0.98437 0,-8.02344 1.01563,0.0154 0,1 7,0"
+ style="opacity:0.5;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="cccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path24951"
+ d="m 93,420.5 7.5,0"
+ style="opacity:0.18999999;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient25077);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 101.5,415.50755 -8,-0.008 0,4 -1.5,1.5 -1.5,-1.5"
+ id="path24953" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#2a2512;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 89.5,410.5 0,9.49245 1.5,1.5 10,0.0151 1.5,-1.49245 0,-5.50755 -3,-0.008 0,-2.9849 -7,-0.0151 0,-1 -3,0 0,4.5e-4 0,0 0,0 z"
+ id="path24957"
+ sodipodi:nodetypes="ccccccccccc" />
+ </g>
+ </g>
+ <g
+ transform="matrix(0.9986805,0,0,1,129.4308,-202)"
+ id="g25007"
+ style="display:inline">
+ <rect
+ ry="1.2018067"
+ style="opacity:0.4;fill:none;stroke:#fac900;stroke-width:4.00264168;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect25009"
+ width="3.0039635"
+ height="3"
+ x="318.99011"
+ y="275"
+ rx="1.2018067" />
+ <rect
+ ry="1.2018068"
+ rx="1.2018068"
+ y="275"
+ x="318.99011"
+ height="3"
+ width="3.0039637"
+ id="rect25011"
+ style="opacity:0.8;fill:none;stroke:#e6b800;stroke-width:2.00132084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
- sodipodi:nodetypes="cc"
- style="opacity:0.18999999;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
- d="m 93,420.5 7.5,0"
- id="path24951"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path32046"
+ d="m 318.99011,278 c 0,-1.00003 3e-5,-2.00003 3e-5,-3.00006 1.00131,0 2.00262,0 3.00393,0 0,1.00003 -3e-5,2.00003 -3e-5,3.00006 -1.00131,0 -2.00262,0 -3.00393,0 z"
+ style="fill:#aa8800;fill-opacity:1;fill-rule:nonzero;stroke:none" />
<path
- id="path24953"
- d="m 101.5,415.50755 -8,-0.008 0,4 -1.5,1.5 -1.5,-1.5"
- style="opacity:0.8;fill:none;stroke:url(#linearGradient25077);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path25013"
+ d="m 318.48945,276 c 1.33509,0 2.67017,10e-6 4.00526,10e-6 0,0.33335 0,0.6667 0,1.00005 -1.33509,0 -2.67017,-1e-5 -4.00526,-1e-5 0,-0.33335 0,-0.6667 0,-1.00005 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
<path
- sodipodi:nodetypes="ccccccccccc"
- id="path24957"
- d="m 89.5,410.5 0,9.49245 1.5,1.5 10,0.0151 1.5,-1.49245 0,-5.50755 -3,-0.008 0,-2.9849 -7,-0.0151 0,-1 -3,0 0,4.5e-4 0,0 0,0 z"
- style="fill:none;stroke:#2a2512;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 319.99139,278.50006 c 0,-1.33337 10e-6,-2.66669 10e-6,-4.00006 0.33379,0 0.66758,0 1.00137,0 0,1.33337 -1e-5,2.66669 -1e-5,4.00006 -0.33379,0 -0.66758,0 -1.00137,0 z"
+ id="path25015"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
</g>
</g>
- <g
- style="display:inline"
- id="g25007"
- transform="matrix(0.9986805,0,0,1,129.4308,-202)">
- <rect
- rx="1.2018067"
- y="275"
- x="318.99011"
- height="3"
- width="3.0039635"
- id="rect25009"
- style="opacity:0.4;fill:none;stroke:#fac900;stroke-width:4.00264168;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- ry="1.2018067" />
- <rect
- style="opacity:0.8;fill:none;stroke:#e6b800;stroke-width:2.00132084;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.39511889;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect25011"
- width="3.0039637"
- height="3"
- x="318.99011"
- y="275"
- rx="1.2018068"
- ry="1.2018068" />
- <path
- style="fill:#aa8800;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 318.99011,278 c 0,-1.00003 3e-5,-2.00003 3e-5,-3.00006 1.00131,0 2.00262,0 3.00393,0 0,1.00003 -3e-5,2.00003 -3e-5,3.00006 -1.00131,0 -2.00262,0 -3.00393,0 z"
- id="path32046"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 318.48945,276 c 1.33509,0 2.67017,10e-6 4.00526,10e-6 0,0.33335 0,0.6667 0,1.00005 -1.33509,0 -2.67017,-1e-5 -4.00526,-1e-5 0,-0.33335 0,-0.6667 0,-1.00005 z"
- id="path25013"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="path25015"
- d="m 319.99139,278.50006 c 0,-1.33337 10e-6,-2.66669 10e-6,-4.00006 0.33379,0 0.66758,0 1.00137,0 0,1.33337 -1e-5,2.66669 -1e-5,4.00006 -0.33379,0 -0.66758,0 -1.00137,0 z"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- inkscape:connector-curvature="0" />
- </g>
</g>
<g
- id="g42026"
+ id="ICON_BOOKMARKS"
transform="translate(-126,2)"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -53969,7 +54378,7 @@
</g>
</g>
<g
- id="g62487"
+ id="ICON_OUTLINER_DATA_LATTICE"
transform="translate(0,128)">
<rect
transform="matrix(0,1,1,0,0,0)"
@@ -54035,7 +54444,7 @@
</g>
</g>
<g
- id="g62412"
+ id="ICON_OUTLINER_OB_LATTICE"
transform="translate(1,127)">
<rect
transform="matrix(0,1,1,0,0,0)"
@@ -54184,7 +54593,7 @@
</g>
</g>
<g
- id="g62543"
+ id="ICON_MOD_LATTICE"
transform="translate(1,2)">
<rect
transform="matrix(0,1,1,0,0,0)"
@@ -54252,7 +54661,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g24707"
+ id="ICON_OUTLINER_OB_META"
transform="translate(-210,128)">
<rect
y="302"
@@ -54290,9 +54699,9 @@
sodipodi:cy="79.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 211,79.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z" />
+ d="m 211,79.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z" />
<path
- d="m 211,79.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 211,79.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="79.5"
@@ -54320,7 +54729,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g23140"
+ id="ICON_IPO"
transform="translate(32,248.99993)"
mask="url(#mask23189)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
@@ -54382,7 +54791,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(54,277.99993)"
- id="g24129"
+ id="ICON_NLA"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -54464,7 +54873,7 @@
</g>
<g
transform="translate(2,298)"
- id="g40315"
+ id="ICON_VIEW3D"
style="display:inline;enable-background:new"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
inkscape:export-xdpi="90"
@@ -54544,7 +54953,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(12.401337,137.46985)"
- id="g40381"
+ id="ICON_SCRIPTWIN"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -54606,162 +55015,165 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- y="535"
- x="320"
- height="16"
- width="16"
- id="rect40397"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
<g
- transform="translate(18.016113,298.07385)"
- id="g40399"
- style="display:inline;enable-background:new"
- inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <path
- sodipodi:nodetypes="cccccc"
- id="path40401"
- d="m 309.21778,249.41313 5.01611,0.013 c 1.29844,0 2.25,-0.80274 2.25,-2.25 l 0.0161,-4.48698 c 0,-1.29844 -0.95156,-2.25 -2.25,-2.25 l -1.75,0"
- style="opacity:0.6;fill:none;stroke:#191919;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <rect
- style="opacity:0.01000001;fill:none;stroke:#e8a930;stroke-width:2.99999928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect40403"
- width="1.9930685"
- height="1.9947703"
- x="309.50693"
- y="239.5"
- ry="0.99734437"
- rx="0.98426884" />
- <path
- style="fill:none;stroke:#bcd0f5;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 310.98389,249.42615 3,0 c 1.29844,0 2.5,-1.20156 2.5,-2.5 l 0.0161,-3.93424 c 0,-1.29844 -1.20156,-2.55274 -2.5,-2.55274 l -1.5,0"
- id="path40406"
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0" />
- <rect
- style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect40408"
- width="7.0161614"
- height="5.9999523"
- x="302.46777"
- y="246.42619"
- ry="1.5185405"
- rx="1.7691951"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
+ id="ICON_NODETREE">
<rect
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- rx="0.0128693"
- ry="0.010695697"
- y="246.92615"
- x="302.96777"
- height="4.9999976"
- width="6.0161119"
- id="rect40410"
- style="fill:url(#linearGradient40736);fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- rx="1.5194846"
- ry="1.4892343"
- y="237.42615"
- x="305.49991"
- height="5.9341388"
- width="6.9999981"
- id="rect40412"
- style="fill:none;stroke:#000000;stroke-width:0.99999958;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
- <rect
- style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect40414"
- width="4.0322218"
- height="0.99999762"
- x="303.96777"
- y="247.92615"
- ry="0.0053478414"
- rx="0.0086254831"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <rect
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- rx="0"
- ry="0"
- y="247.42625"
- x="303.46777"
- height="3.9999583"
- width="5.0161114"
- id="rect40416"
- style="opacity:0.8;fill:none;stroke:url(#linearGradient40738);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
- <rect
- style="fill:url(#linearGradient40740);fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect40418"
- width="5.9999843"
- height="5.0000072"
- x="306"
- y="237.92615"
- ry="0"
- rx="0"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <rect
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40397"
+ width="16"
+ height="16"
+ x="320"
+ y="535" />
+ <g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- rx="0.0071879062"
- ry="0.0053478414"
- y="238.92615"
- x="306.98389"
- height="0.99999762"
- width="4.0322237"
- id="rect40420"
- style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- style="opacity:0.8;fill:none;stroke:url(#linearGradient40742);stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect40422"
- width="5.0067563"
- height="3.9560828"
- x="306.5"
- y="238.41525"
- ry="0"
- rx="0"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <rect
- ry="0"
- y="248.43787"
- x="309.48389"
- height="1.9882908"
- width="2"
- id="rect40424"
- style="fill:#ffb72a;fill-opacity:1;fill-rule:nonzero;stroke:#553800;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- rx="0" />
- <rect
- rx="0"
- style="fill:#ffb72a;fill-opacity:1;fill-rule:nonzero;stroke:#553800;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect40426"
- width="2"
- height="1.9882908"
- x="312.48389"
- y="239.43787"
- ry="0" />
+ inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
+ style="display:inline;enable-background:new"
+ id="g40399"
+ transform="translate(18.016113,298.07385)">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.6;fill:none;stroke:#191919;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 309.21778,249.41313 5.01611,0.013 c 1.29844,0 2.25,-0.80274 2.25,-2.25 l 0.0161,-4.48698 c 0,-1.29844 -0.95156,-2.25 -2.25,-2.25 l -1.75,0"
+ id="path40401"
+ sodipodi:nodetypes="cccccc" />
+ <rect
+ rx="0.98426884"
+ ry="0.99734437"
+ y="239.5"
+ x="309.50693"
+ height="1.9947703"
+ width="1.9930685"
+ id="rect40403"
+ style="opacity:0.01000001;fill:none;stroke:#e8a930;stroke-width:2.99999928;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path40406"
+ d="m 310.98389,249.42615 3,0 c 1.29844,0 2.5,-1.20156 2.5,-2.5 l 0.0161,-3.93424 c 0,-1.29844 -1.20156,-2.55274 -2.5,-2.55274 l -1.5,0"
+ style="fill:none;stroke:#bcd0f5;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ rx="1.7691951"
+ ry="1.5185405"
+ y="246.42619"
+ x="302.46777"
+ height="5.9999523"
+ width="7.0161614"
+ id="rect40408"
+ style="fill:none;stroke:#000000;stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ style="fill:url(#linearGradient40736);fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect40410"
+ width="6.0161119"
+ height="4.9999976"
+ x="302.96777"
+ y="246.92615"
+ ry="0.010695697"
+ rx="0.0128693"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:0.99999958;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect40412"
+ width="6.9999981"
+ height="5.9341388"
+ x="305.49991"
+ y="237.42615"
+ ry="1.4892343"
+ rx="1.5194846"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ rx="0.0086254831"
+ ry="0.0053478414"
+ y="247.92615"
+ x="303.96777"
+ height="0.99999762"
+ width="4.0322218"
+ id="rect40414"
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient40738);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect40416"
+ width="5.0161114"
+ height="3.9999583"
+ x="303.46777"
+ y="247.42625"
+ ry="0"
+ rx="0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ rx="0"
+ ry="0"
+ y="237.92615"
+ x="306"
+ height="5.0000072"
+ width="5.9999843"
+ id="rect40418"
+ style="fill:url(#linearGradient40740);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect40420"
+ width="4.0322237"
+ height="0.99999762"
+ x="306.98389"
+ y="238.92615"
+ ry="0.0053478414"
+ rx="0.0071879062"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ rx="0"
+ ry="0"
+ y="238.41525"
+ x="306.5"
+ height="3.9560828"
+ width="5.0067563"
+ id="rect40422"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient40742);stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ rx="0"
+ style="fill:#ffb72a;fill-opacity:1;fill-rule:nonzero;stroke:#553800;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40424"
+ width="2"
+ height="1.9882908"
+ x="309.48389"
+ y="248.43787"
+ ry="0" />
+ <rect
+ ry="0"
+ y="239.43787"
+ x="312.48389"
+ height="1.9882908"
+ width="2"
+ id="rect40426"
+ style="fill:#ffb72a;fill-opacity:1;fill-rule:nonzero;stroke:#553800;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="0" />
+ </g>
</g>
<g
style="display:inline;enable-background:new"
- id="g40520"
+ id="ICON_SOUND"
transform="translate(-1,128)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
inkscape:export-xdpi="90"
@@ -54806,7 +55218,7 @@
</g>
<g
style="opacity:0.96000001;display:inline;enable-background:new"
- id="g40602"
+ id="ICON_TIME"
transform="translate(0,128)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
inkscape:export-xdpi="90"
@@ -54834,7 +55246,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -54850,7 +55262,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -54938,7 +55350,7 @@
</g>
<g
transform="translate(9,297.99992)"
- id="g40632"
+ id="ICON_TEXT"
style="display:inline;enable-background:new"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
inkscape:export-xdpi="90"
@@ -55029,7 +55441,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g40518"
+ id="ICON_CONSOLE"
transform="translate(18.999997,-40.99992)">
<g
style="display:inline"
@@ -55119,7 +55531,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g24081"
+ id="ICON_NODE"
transform="translate(405,-17.000053)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\x.png"
inkscape:export-xdpi="90"
@@ -55199,19 +55611,9 @@
y="641.5" />
</g>
</g>
- <rect
- y="534.99994"
- x="131"
- height="16"
- width="16"
- id="rect23324"
- style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g22298.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
<g
style="display:inline;enable-background:new"
- id="g23326"
+ id="ICON_NODE_SEL"
transform="translate(426,-17.000053)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\x.png"
inkscape:export-xdpi="90"
@@ -55295,7 +55697,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g42357.png"
- id="g42663"
+ id="ICON_SEQ_SEQUENCER"
transform="translate(-198,-247)"
style="display:inline;enable-background:new">
<rect
@@ -55376,7 +55778,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g25594"
+ id="ICON_FILE_MOVIE"
transform="translate(-306,-275)">
<g
style="display:inline"
@@ -55605,7 +56007,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g25988"
+ id="ICON_FILE_SOUND"
transform="translate(-152,-151)">
<g
transform="translate(-272,34)"
@@ -55722,13 +56124,13 @@
sodipodi:cy="554"
sodipodi:rx="4.5"
sodipodi:ry="2.25"
- d="m 57.5,554 c 0,1.24264 -2.014719,2.25 -4.5,2.25 -2.485281,0 -4.5,-1.00736 -4.5,-2.25 0,-1.24264 2.014719,-2.25 4.5,-2.25 2.485281,0 4.5,1.00736 4.5,2.25 z"
+ d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z"
transform="matrix(0.7630859,-0.2494396,0.2996015,0.9926766,-151.92281,17.77746)" />
<path
clip-path="url(#clipPath20586)"
inkscape:transform-center-y="0.3813435"
transform="matrix(0.3848865,-0.1700959,0.2278131,0.3626733,-93.107467,361.59408)"
- d="m 57.5,554 c 0,1.24264 -2.014719,2.25 -4.5,2.25 -2.485281,0 -4.5,-1.00736 -4.5,-2.25 0,-1.24264 2.014719,-2.25 4.5,-2.25 2.485281,0 4.5,1.00736 4.5,2.25 z"
+ d="m 57.5,554 a 4.5,2.25 0 1 1 -9,0 4.5,2.25 0 1 1 9,0 z"
sodipodi:ry="2.25"
sodipodi:rx="4.5"
sodipodi:cy="554"
@@ -55750,7 +56152,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g25963"
+ id="ICON_FILE_TEXT"
transform="translate(-86,-139)">
<g
transform="translate(-262,-147)"
@@ -55860,7 +56262,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g25933"
+ id="ICON_FILE_FONT"
transform="translate(-107,-115)">
<g
id="g25393"
@@ -56005,7 +56407,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g25672"
+ id="ICON_FILE_BLEND"
transform="translate(-348,-155)">
<g
transform="translate(-126,60.000002)"
@@ -56131,7 +56533,7 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1.0000004"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1.0000004 0 1 1 -2,0 1,1.0000004 0 1 1 2,0 z"
transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)" />
<path
sodipodi:nodetypes="cccc"
@@ -56148,7 +56550,7 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)" />
<path
id="path25721"
@@ -56158,7 +56560,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(3.25,0,0,3.25,-62.875,313.125)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -56174,11 +56576,11 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(2,0,0,2,-46,385)" />
<path
transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -56203,7 +56605,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g25822"
+ id="ICON_FILE_FOLDER"
transform="translate(273,-334)">
<rect
y="407"
@@ -56264,7 +56666,7 @@
</g>
<g
transform="translate(371,90.000008)"
- id="g26093">
+ id="ICON_UI">
<rect
style="opacity:0;fill:#cccccc;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect26095"
@@ -56403,7 +56805,7 @@
</g>
</g>
<g
- id="g28119"
+ id="ICON_RESTRICT_VIEW_OFF"
transform="translate(0,127.99999)">
<rect
y="302"
@@ -56421,7 +56823,7 @@
sodipodi:nodetypes="ccscz"
inkscape:connector-curvature="0" />
<path
- d="m 434.99991,14.5 c 0,1.609518 -1.79082,2.91429 -3.99991,2.91429 -2.20909,0 -3.99991,-1.304772 -3.99991,-2.91429 0,-1.609518 1.79082,-2.91429 3.99991,-2.91429 2.20909,0 3.99991,1.304772 3.99991,2.91429 z"
+ d="m 434.99991,14.5 a 3.9999149,2.91429 0 1 1 -7.99982,0 3.9999149,2.91429 0 1 1 7.99982,0 z"
sodipodi:ry="2.91429"
sodipodi:rx="3.9999149"
sodipodi:cy="14.5"
@@ -56431,7 +56833,7 @@
sodipodi:type="arc"
transform="matrix(0.7500463,0,0,1.0294111,88.73017,294.07354)" />
<path
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="135"
@@ -56454,7 +56856,7 @@
id="rect27926"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
<path
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="135"
@@ -56466,7 +56868,7 @@
</g>
</g>
<g
- id="g27932"
+ id="ICON_RESTRICT_VIEW_ON"
transform="translate(4e-6,127.99999)">
<g
transform="translate(0.4838899,-6.2084382e-8)"
@@ -56505,7 +56907,7 @@
y="302" />
</g>
<g
- id="g27416"
+ id="ICON_VISIBLE_IPO_ON"
transform="translate(105,-82)">
<rect
style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
@@ -56531,7 +56933,7 @@
sodipodi:cy="14.5"
sodipodi:rx="3.9999149"
sodipodi:ry="2.91429"
- d="m 434.99991,14.5 c 0,1.609518 -1.79082,2.91429 -3.99991,2.91429 -2.20909,0 -3.99991,-1.304772 -3.99991,-2.91429 0,-1.609518 1.79082,-2.91429 3.99991,-2.91429 2.20909,0 3.99991,1.304772 3.99991,2.91429 z" />
+ d="m 434.99991,14.5 a 3.9999149,2.91429 0 1 1 -7.99982,0 3.9999149,2.91429 0 1 1 7.99982,0 z" />
<path
transform="matrix(2.249956,0,0,2.251405,267.75278,4.81032)"
sodipodi:type="arc"
@@ -56541,7 +56943,7 @@
sodipodi:cy="135"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z" />
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" />
<path
id="path27428"
d="m 412,306.5 c -3.5,0 -5,1.5 -6.5,3 1.5,1.5 2.75,4 6.5,4 3.75,0 5,-2.5 6.5,-4 -1.5,-1.5 -3,-3 -6.5,-3 z"
@@ -56564,12 +56966,12 @@
sodipodi:cy="135"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z" />
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" />
</g>
</g>
<g
transform="translate(62.983887,-82)"
- id="g27434">
+ id="ICON_VISIBLE_IPO_OFF">
<g
id="g27436"
transform="translate(0.4838899,-6.2084382e-8)">
@@ -56608,7 +57010,7 @@
</g>
<g
transform="translate(147,170.00001)"
- id="g27500">
+ id="ICON_LAMP_DATA">
<rect
style="opacity:0;fill:#4d4d4d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect27514"
@@ -56733,7 +57135,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.9552133,0,0,0.9315985,-40.901258,-140.2522)" />
<path
transform="matrix(0.99567,0,-0.00787885,1,-30.663533,191)"
@@ -56744,7 +57146,7 @@
sodipodi:cy="135"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -56807,14 +57209,55 @@
style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
</g>
- <path
- style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 263,16 0,3 1,0 0,-2 2,0 0,-1 -3,0 z"
- id="rect28902"
- inkscape:connector-curvature="0" />
+ <g
+ id="ICON_IMAGE_ZDEPTH">
+ <g
+ id="g17368"
+ transform="translate(302,-461)">
+ <rect
+ y="471"
+ x="-45"
+ height="16"
+ width="16"
+ id="rect17370"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="472.5"
+ x="-43.483856"
+ height="13"
+ width="12.983856"
+ id="rect17372"
+ style="fill:url(#linearGradient17442);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5;display:inline" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path17374"
+ d="m -31.5,473.50001 -10.983862,0 0,11"
+ style="fill:none;stroke:url(#linearGradient17444);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0.5;display:inline"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="14"
+ x="261"
+ height="5"
+ width="5"
+ id="rect17376"
+ style="fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17379"
+ width="5"
+ height="5"
+ x="264"
+ y="17" />
+ <path
+ inkscape:connector-curvature="0"
+ id="rect28902"
+ d="m 263,16 0,3 1,0 0,-2 2,0 0,-1 -3,0 z"
+ style="opacity:0.25;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
<g
style="display:inline;enable-background:new"
- id="g28080"
+ id="ICON_MOD_FLUIDSIM"
transform="translate(-823,-175)">
<rect
y="416"
@@ -56829,7 +57272,7 @@
id="g28085">
<path
transform="matrix(1.1162596,0,0,1.1065394,67.801614,-350.49863)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -56845,7 +57288,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(-1.3568764,-0.3150232,0.3151738,-1.348049,102.81491,906.57916)" />
</g>
<path
@@ -56868,7 +57311,7 @@
sodipodi:cy="425"
sodipodi:rx="1.5"
sodipodi:ry="1"
- d="m 880,425 c 0,0.55228 -0.67157,1 -1.5,1 -0.82843,0 -1.5,-0.44772 -1.5,-1 0,-0.55228 0.67157,-1 1.5,-1 0.82843,0 1.5,0.44772 1.5,1 z"
+ d="m 880,425 a 1.5,1 0 1 1 -3,0 1.5,1 0 1 1 3,0 z"
transform="matrix(0.6434675,-0.7329672,0.7942866,0.5945179,-26.858149,815.24158)" />
<path
inkscape:transform-center-y="-7.1785015"
@@ -56880,7 +57323,7 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.2857095,0,0,1.2857143,1210.8559,325.57143)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -56888,7 +57331,7 @@
</g>
<g
transform="translate(-94.999994,403.00001)"
- id="g30296"
+ id="ICON_BORDERMOVE"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -57088,7 +57531,7 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.4627004,0,0,1.4628053,551.73128,85.525552)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -57134,7 +57577,7 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.2468441,0,0,1.246865,503.16273,106.89331)" />
</g>
<path
@@ -57160,7 +57603,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
transform="matrix(-1.4627004,0,0,1.4628053,551.73128,85.525552)"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="78.5"
@@ -57182,11 +57625,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)" />
<path
transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -57196,7 +57639,7 @@
sodipodi:type="arc" />
</g>
<path
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="135"
@@ -57215,7 +57658,7 @@
</g>
</g>
<g
- id="g28857">
+ id="ICON_MOD_MULTIRES">
<rect
y="241.00877"
x="68.001282"
@@ -57240,7 +57683,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -57255,7 +57698,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -57314,7 +57757,7 @@
</g>
</g>
<g
- id="g56105">
+ id="ICON_DISK_DRIVE">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect29107"
@@ -57390,7 +57833,7 @@
</g>
<g
transform="translate(-0.1658249,128.41502)"
- id="g27744">
+ id="ICON_WORLD_DATA">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect27746"
@@ -57412,13 +57855,13 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(0.787566,0,0,0.779223,26.709197,21.3179)" />
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -57442,7 +57885,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" />
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
<path
sodipodi:nodetypes="cc"
id="path27757"
@@ -57460,7 +57903,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -57470,7 +57913,7 @@
sodipodi:type="arc"
transform="matrix(0.6657538,0,0,0.6588051,42.794535,35.527157)" />
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -57485,24 +57928,7 @@
</g>
</g>
<g
- style="fill:none;stroke:#ffffff;stroke-width:1.50000143;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="translate(-323.1613,214)"
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="g28643" />
- <g
- id="g29500" />
- <g
- transform="translate(1,24.000004)"
- id="g29613"
- style="opacity:0.3" />
- <g
- style="opacity:0.3"
- id="g29692"
- transform="translate(0,18)" />
- <g
- id="g34067"
+ id="ICON_SNAP_PEEL_OBJECT"
transform="translate(0,2)">
<g
id="g31771"
@@ -57605,24 +58031,7 @@
</g>
</g>
<g
- transform="matrix(-0.767131,0,0,0.788662,369.34347,270.08667)"
- style="fill:#000000;fill-opacity:1"
- id="g33443"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <g
- transform="matrix(-0.693332,0,0,0.663699,372.90657,295.34421)"
- id="g33445"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <g
- id="g33447"
- style="opacity:0.3"
- transform="matrix(-1,0,0,1,762.99997,233.00003)" />
- <g
- id="g31977"
+ id="ICON_CURVE_DATA"
transform="translate(63,212.00001)">
<rect
ry="0"
@@ -57701,7 +58110,7 @@
</g>
<g
style="display:inline"
- id="g32016"
+ id="ICON_MESH_DATA"
transform="translate(-474,676.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -57783,7 +58192,7 @@
</g>
</g>
<g
- id="g32042"
+ id="ICON_LATTICE_DATA"
transform="translate(83,212.00001)">
<rect
y="68"
@@ -57849,7 +58258,7 @@
</g>
</g>
<g
- id="g25012"
+ id="ICON_SURFACE_DATA"
transform="translate(-83.999998,191)">
<rect
transform="scale(-1,1)"
@@ -57998,7 +58407,7 @@
</g>
</g>
<g
- id="g32145"
+ id="ICON_EMPTY_DATA"
transform="translate(147,191.00001)">
<g
transform="translate(-138,212)"
@@ -58037,7 +58446,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
transform="matrix(1.176776,0,0,1.176776,-12.47787,-2.548088)"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
sodipodi:ry="1.5"
sodipodi:rx="1.5"
sodipodi:cy="14.5"
@@ -58216,7 +58625,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g52805"
+ id="ICON_WPAINT_HLT"
transform="translate(185,94.000007)">
<rect
style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -58326,94 +58735,97 @@
</g>
</g>
</g>
- <rect
- style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect52845"
- width="16"
- height="16"
- x="89"
- y="514" />
<g
- mask="url(#mask38474)"
- transform="translate(-254.01612,339.00001)"
- id="g52847">
+ id="ICON_TPAINT_HLT">
<rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
- id="rect52849"
- width="12.871031"
- height="13.001007"
- x="343.51614"
- y="175.49899" />
- <path
- style="fill:url(#linearGradient53129);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 344.01612,176 0,3 3,0 0,-3 -3,0 z m 3,3 0,3 3,0 0,-3 -3,0 z m 3,0 3,0 0,-3 -3,0 0,3 z m -3,3 -3,0 0,3 3,0 0,-3 z"
- id="path52851"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="path52853"
- d="m 344.50621,187.50705 0,-11.00155 10.89034,0"
- style="opacity:0.9;fill:none;stroke:url(#linearGradient53131);stroke-width:0.9999997px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
- inkscape:connector-curvature="0" />
- </g>
- <g
- transform="translate(-414.98389,546.98571)"
- style="display:inline;enable-background:new"
- id="g52855">
- <path
- sodipodi:nodetypes="ccccc"
- id="path52857"
- d="m 506.48389,-17.45862 0,-1 c 4.75,-1 2.25,-4.5 6.31852,-4.187139 0.70341,0.496889 0.93148,1.187139 0.93148,2.122782 0,3.064357 -2.5,3.314357 -7.25,3.064357 l 0,0 0,0 0,0 z"
- style="fill:#9d6c53;fill-opacity:1;fill-rule:evenodd;stroke:#241f1c;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.7;fill:url(#radialGradient53133);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 505.98389,-17.522977 c 5.75,-0.75 2.71305,-4.172284 6.75,-5.25 0.70341,0.496889 1.61991,1.711436 1.75268,2.186272 0,3.572675 -4.12319,3.136436 -8.50268,3.063728 l 0,0 0,0 0,0 z"
- id="path52859"
- sodipodi:nodetypes="cccc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccc"
- id="path52861"
- d="m 515.48389,-25.95862 -2.75,3.25 1.75,2.25 3,-3"
- style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- style="fill:url(#linearGradient53135);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 514.98389,-24.95862 -2.25,2.5 1.37109,1.875 2.37891,-2.375 -1.5,-2 z"
- id="path52863"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#2b0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 519.48389,-30.45862 -5,5.75 2,2.25 3,-3"
- id="path52865"
- sodipodi:nodetypes="cccc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccc"
- id="path52867"
- d="m 519.98389,-30.70862 -5.75,6.5 1.75,1.75 4,-3.75 0,-4.5 z"
- style="fill:url(#linearGradient53137);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.23326063;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- d="m 513.48389,-22.45862 6,-7"
- id="path52869"
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.4;fill:none;stroke:url(#linearGradient53139);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
- d="m 511.98389,-21.772977 -1.25,1.25 c -0.96702,0.819679 -0.76749,2.123051 -3.25,2.314357"
- id="path52871"
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0" />
+ y="514"
+ x="89"
+ height="16"
+ width="16"
+ id="rect52845"
+ style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g52847"
+ transform="translate(-254.01612,339.00001)"
+ mask="url(#mask38474)">
+ <rect
+ y="175.49899"
+ x="343.51614"
+ height="13.001007"
+ width="12.871031"
+ id="rect52849"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path52851"
+ d="m 344.01612,176 0,3 3,0 0,-3 -3,0 z m 3,3 0,3 3,0 0,-3 -3,0 z m 3,0 3,0 0,-3 -3,0 0,3 z m -3,3 -3,0 0,3 3,0 0,-3 z"
+ style="fill:url(#linearGradient53129);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.9;fill:none;stroke:url(#linearGradient53131);stroke-width:0.9999997px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 344.50621,187.50705 0,-11.00155 10.89034,0"
+ id="path52853"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ id="g52855"
+ style="display:inline;enable-background:new"
+ transform="translate(-414.98389,546.98571)">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#9d6c53;fill-opacity:1;fill-rule:evenodd;stroke:#241f1c;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 506.48389,-17.45862 0,-1 c 4.75,-1 2.25,-4.5 6.31852,-4.187139 0.70341,0.496889 0.93148,1.187139 0.93148,2.122782 0,3.064357 -2.5,3.314357 -7.25,3.064357 l 0,0 0,0 0,0 z"
+ id="path52857"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path52859"
+ d="m 505.98389,-17.522977 c 5.75,-0.75 2.71305,-4.172284 6.75,-5.25 0.70341,0.496889 1.61991,1.711436 1.75268,2.186272 0,3.572675 -4.12319,3.136436 -8.50268,3.063728 l 0,0 0,0 0,0 z"
+ style="opacity:0.7;fill:url(#radialGradient53133);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#0b1728;stroke-width:0.89999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 515.48389,-25.95862 -2.75,3.25 1.75,2.25 3,-3"
+ id="path52861"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path52863"
+ d="m 514.98389,-24.95862 -2.25,2.5 1.37109,1.875 2.37891,-2.375 -1.5,-2 z"
+ style="fill:url(#linearGradient53135);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path52865"
+ d="m 519.48389,-30.45862 -5,5.75 2,2.25 3,-3"
+ style="fill:none;stroke:#2b0000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient53137);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.23326063;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 519.98389,-30.70862 -5.75,6.5 1.75,1.75 4,-3.75 0,-4.5 z"
+ id="path52867"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path52869"
+ d="m 513.48389,-22.45862 6,-7"
+ style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path52871"
+ d="m 511.98389,-21.772977 -1.25,1.25 c -0.96702,0.819679 -0.76749,2.123051 -3.25,2.314357"
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient53139);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline" />
+ </g>
</g>
<g
style="display:inline;enable-background:new"
- id="g52873"
+ id="ICON_VPAINT_HLT"
transform="translate(120,94.000007)">
<rect
y="420"
@@ -58504,7 +58916,7 @@
</g>
<g
transform="translate(318,94.000007)"
- id="g52903"
+ id="ICON_LIGHTPAINT"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -58626,7 +59038,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(0.8490785,0,0,0.8469086,71.921104,-98.093334)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -58638,7 +59050,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="135"
@@ -58752,11 +59164,7 @@
</g>
</g>
<g
- id="g77742"
- style="fill:#ffeeaa;display:inline"
- transform="translate(-870.9421,-297.02038)" />
- <g
- id="g33404"
+ id="ICON_RETOPO"
transform="translate(-20.999997,23)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -58776,7 +59184,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -58793,7 +59201,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -58807,7 +59215,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -58903,7 +59311,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g50822"
+ id="ICON_OOPS"
transform="translate(74,89.000007)">
<rect
style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -59056,7 +59464,7 @@
style="opacity:0.1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
- id="g33837"
+ id="ICON_SNAP_NORMAL"
transform="translate(-42,23)">
<rect
style="opacity:0.01000001;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -59077,7 +59485,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -59094,7 +59502,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -59108,7 +59516,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -59159,7 +59567,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(84,-124)"
- id="g36191"
+ id="ICON_GRID"
mask="url(#mask25369)">
<rect
y="281"
@@ -59193,190 +59601,193 @@
id="path36201"
inkscape:connector-curvature="0" />
</g>
- <path
- inkscape:transform-center-y="-6.547647"
- inkscape:transform-center-x="-6.5102284"
- sodipodi:type="arc"
- style="fill:url(#radialGradient24523);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
- id="path36205"
- sodipodi:cx="258.5"
- sodipodi:cy="78.5"
- sodipodi:rx="3.5"
- sodipodi:ry="3.5"
- d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
- transform="matrix(-1.5002341,0,0,1.5000004,549.81053,465.24998)"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <path
- style="opacity:0.96000001;fill:#ff8400;fill-opacity:1;fill-rule:evenodd;stroke:#2b2200;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 159.5,582.50001 0,5.40625 c 0.75032,0.38395 1.59977,0.59375 2.5,0.59375 0.90022,0 1.74968,-0.2098 2.5,-0.59375 l 0,-5.40625 -5,0 z"
- id="path36207"
- inkscape:connector-curvature="0" />
- <path
- id="path36209"
- d="m 160.5,586.25001 0,-2.75 3,0"
- style="opacity:0.76799999;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.96000001;fill:#ff8400;fill-opacity:1;fill-rule:evenodd;stroke:#2b2200;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 165.5,587.25001 c -1.25,1 -2.5,1.25 -3,1.25 l 0,3 2.98688,0 0.0131,-4.25 2e-5,0 0,0 0,0 z"
- id="path36211"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.672;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- d="m 163.5,590.50001 0,-2"
- id="path36213"
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0" />
- <rect
- y="577"
- x="152"
- height="16"
- width="16"
- id="rect36215"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- sodipodi:nodetypes="cc"
- id="path36217"
- d="m 156.5,588.50001 1.5,-1.5"
- style="opacity:0.96000001;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- transform="matrix(-1.5002341,0,0,1.5000004,549.81053,465.24998)"
- d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
- sodipodi:ry="3.5"
- sodipodi:rx="3.5"
- sodipodi:cy="78.5"
- sodipodi:cx="258.5"
- id="path36220"
- style="opacity:0.48000004;fill:url(#radialGradient24519);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
- sodipodi:type="arc"
- inkscape:transform-center-x="-6.5102284"
- inkscape:transform-center-y="-6.547647" />
- <path
- inkscape:transform-center-y="-6.8594309"
- inkscape:transform-center-x="-6.8191649"
- sodipodi:type="arc"
- style="opacity:0.96000001;fill:none;stroke:#000000;stroke-width:0.57272732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
- id="path36222"
- sodipodi:cx="258.5"
- sodipodi:cy="78.5"
- sodipodi:rx="3.5"
- sodipodi:ry="3.5"
- d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
- transform="matrix(-1.5714299,0,0,1.5714268,568.21462,459.64301)"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <path
- style="opacity:0.96000001;fill:none;stroke:#28170b;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="M 153.86319,591.13808 156.25,588.75001"
- id="path36224"
- sodipodi:nodetypes="cc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.96000001;fill:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 156.5,588.50001 1.5,-1.5"
- id="path36226"
- sodipodi:nodetypes="cc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
<g
- style="opacity:0.96000001"
- id="g36228"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- transform="matrix(1.0988734,0,0,1.0981343,-23.179949,357.33845)">
+ id="ICON_ZOOM_SELECTED">
<path
- inkscape:transform-center-y="-4.9844055"
- inkscape:transform-center-x="-4.9755572"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.5002341,0,0,1.5000004,549.81053,465.24998)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36205"
+ style="fill:url(#radialGradient24523);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
sodipodi:type="arc"
- style="fill:url(#linearGradient24511);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient24513);stroke-width:0.79652983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
- id="path36230"
+ inkscape:transform-center-x="-6.5102284"
+ inkscape:transform-center-y="-6.547647" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path36207"
+ d="m 159.5,582.50001 0,5.40625 c 0.75032,0.38395 1.59977,0.59375 2.5,0.59375 0.90022,0 1.74968,-0.2098 2.5,-0.59375 l 0,-5.40625 -5,0 z"
+ style="opacity:0.96000001;fill:#ff8400;fill-opacity:1;fill-rule:evenodd;stroke:#2b2200;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.76799999;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 160.5,586.25001 0,-2.75 3,0"
+ id="path36209" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path36211"
+ d="m 165.5,587.25001 c -1.25,1 -2.5,1.25 -3,1.25 l 0,3 2.98688,0 0.0131,-4.25 2e-5,0 0,0 0,0 z"
+ style="opacity:0.96000001;fill:#ff8400;fill-opacity:1;fill-rule:evenodd;stroke:#2b2200;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path36213"
+ d="m 163.5,590.50001 0,-2"
+ style="opacity:0.672;fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36215"
+ width="16"
+ height="16"
+ x="152"
+ y="577" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.96000001;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 156.5,588.50001 1.5,-1.5"
+ id="path36217"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:transform-center-y="-6.547647"
+ inkscape:transform-center-x="-6.5102284"
+ sodipodi:type="arc"
+ style="opacity:0.48000004;fill:url(#radialGradient24519);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.63636374;marker:none;display:inline"
+ id="path36220"
sodipodi:cx="258.5"
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
- transform="matrix(-1.14287,0,0,1.142863,463.9317,115.80133)" />
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ transform="matrix(-1.5002341,0,0,1.5000004,549.81053,465.24998)"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ transform="matrix(-1.5714299,0,0,1.5714268,568.21462,459.64301)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36222"
+ style="opacity:0.96000001;fill:none;stroke:#000000;stroke-width:0.57272732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-6.8191649"
+ inkscape:transform-center-y="-6.8594309" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36224"
+ d="M 153.86319,591.13808 156.25,588.75001"
+ style="opacity:0.96000001;fill:none;stroke:#28170b;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36226"
+ d="m 156.5,588.50001 1.5,-1.5"
+ style="opacity:0.96000001;fill:none;stroke:#cccccc;stroke-width:1.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<g
- id="g36232">
+ transform="matrix(1.0988734,0,0,1.0981343,-23.179949,357.33845)"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="g36228"
+ style="opacity:0.96000001">
<path
- transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- sodipodi:ry="2.5"
- sodipodi:rx="2.5312502"
- sodipodi:cy="502"
- sodipodi:cx="78"
- id="path36234"
- style="opacity:0.25;fill:url(#radialGradient24515);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
+ transform="matrix(-1.14287,0,0,1.142863,463.9317,115.80133)"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
+ sodipodi:ry="3.5"
+ sodipodi:rx="3.5"
+ sodipodi:cy="78.5"
+ sodipodi:cx="258.5"
+ id="path36230"
+ style="fill:url(#linearGradient24511);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient24513);stroke-width:0.79652983;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline"
+ sodipodi:type="arc"
+ inkscape:transform-center-x="-4.9755572"
+ inkscape:transform-center-y="-4.9844055" />
+ <g
+ id="g36232">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.25;fill:url(#radialGradient24515);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path36234"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)" />
+ <path
+ transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path36236"
+ style="opacity:0.25;fill:url(#radialGradient24517);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
<path
+ transform="matrix(0.9100226,0,0,0.9106329,108.4468,80.751664)"
sodipodi:type="arc"
- style="opacity:0.25;fill:url(#radialGradient24517);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path36236"
- sodipodi:cx="78"
- sodipodi:cy="502"
- sodipodi:rx="2.5312502"
- sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)" />
+ style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
+ id="path36238"
+ sodipodi:cx="64"
+ sodipodi:cy="135"
+ sodipodi:rx="1"
+ sodipodi:ry="1"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
+ inkscape:transform-center-x="-3.1120555"
+ inkscape:transform-center-y="-5.7593212" />
</g>
<path
- inkscape:transform-center-y="-5.7593212"
- inkscape:transform-center-x="-3.1120555"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
- sodipodi:ry="1"
- sodipodi:rx="1"
- sodipodi:cy="135"
- sodipodi:cx="64"
- id="path36238"
- style="opacity:0.7;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.74699998;marker:none;display:inline"
- sodipodi:type="arc"
- transform="matrix(0.9100226,0,0,0.9106329,108.4468,80.751664)" />
+ inkscape:connector-curvature="0"
+ style="opacity:0.96000001;fill:none;stroke:#a05a2c;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 153.75,591.25001 2.5,-2.5"
+ id="path36240"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path36242"
+ d="m 153.25,591.00001 2.75,-2.75"
+ style="opacity:0.672;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ style="opacity:0.48000004;fill:none;stroke:#2b2200;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 164.5,585.25001 0,-2.75 -5,0 0,2.75"
+ id="path36244" />
</g>
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- sodipodi:nodetypes="cc"
- id="path36240"
- d="m 153.75,591.25001 2.5,-2.5"
- style="opacity:0.96000001;fill:none;stroke:#a05a2c;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.672;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 153.25,591.00001 2.75,-2.75"
- id="path36242"
- sodipodi:nodetypes="cc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- id="path36244"
- d="m 164.5,585.25001 0,-2.75 -5,0 0,2.75"
- style="opacity:0.48000004;fill:none;stroke:#2b2200;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="cccc"
- inkscape:connector-curvature="0" />
<g
style="opacity:0.96000001;display:inline;enable-background:new"
- id="g36246"
+ id="ICON_ZOOM_ALL"
transform="translate(60,59)">
<rect
style="opacity:0;fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -59484,7 +59895,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
transform="matrix(-1.4627004,0,0,1.4628053,551.73128,85.525552)"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="78.5"
@@ -59529,7 +59940,7 @@
id="g36286">
<path
transform="matrix(-1.2468441,0,0,1.246865,503.16273,106.89331)"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="78.5"
@@ -59566,7 +59977,7 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.4627004,0,0,1.4628053,551.73128,85.525552)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -59577,7 +59988,7 @@
id="g36296">
<path
transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -59593,7 +60004,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)" />
</g>
<path
@@ -59605,13 +60016,13 @@
sodipodi:cy="135"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z" />
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z" />
</g>
</g>
</g>
<g
transform="translate(42,41)"
- id="g36304"
+ id="ICON_ZOOM_PREVIOUS"
style="opacity:0.96000001;display:inline;enable-background:new">
<path
inkscape:transform-center-y="-6.5435007"
@@ -59623,7 +60034,7 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.5000024,0,0,1.4990511,528.75064,424.32781)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -59657,7 +60068,7 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.5714299,0,0,1.5714268,505.21462,331.643)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -59696,13 +60107,13 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)" />
<g
id="g36324">
<path
transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -59718,13 +60129,13 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)" />
</g>
<path
inkscape:transform-center-y="-5.7593212"
inkscape:transform-center-x="-3.1120555"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="135"
@@ -59762,7 +60173,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g36339"
+ id="ICON_COLOR"
transform="translate(-294,339)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -59785,7 +60196,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -59803,7 +60214,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -59819,7 +60230,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -59837,7 +60248,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -59852,7 +60263,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -59871,7 +60282,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -59888,7 +60299,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -59897,7 +60308,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -59909,7 +60320,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -59922,7 +60333,7 @@
</g>
<g
transform="translate(105,41)"
- id="g36367"
+ id="ICON_ZOOM_IN"
style="opacity:0.96000001;display:inline;enable-background:new">
<g
id="g36369"
@@ -59953,7 +60364,7 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.5714299,0,0,1.5714268,505.21462,331.643)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -59992,13 +60403,13 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)" />
<g
id="g36385">
<path
transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -60014,13 +60425,13 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)" />
</g>
<path
inkscape:transform-center-y="-5.7593212"
inkscape:transform-center-x="-3.1120555"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="135"
@@ -60059,7 +60470,7 @@
sodipodi:cy="78.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(-1.5002341,0,0,1.5000004,486.81053,424.24997)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -60093,14 +60504,14 @@
</g>
<g
transform="translate(105,41)"
- id="g36407"
+ id="ICON_ZOOM_OUT"
style="opacity:0.96000001;display:inline;enable-background:new">
<path
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
transform="matrix(-1.5000024,0,0,1.4990511,507.75064,424.32781)"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="78.5"
@@ -60134,7 +60545,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
transform="matrix(-1.5714299,0,0,1.5714268,505.21462,331.643)"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="78.5"
@@ -60170,7 +60581,7 @@
id="g36423">
<path
transform="matrix(-1.14287,0,0,1.142863,463.9317,115.7853)"
- d="m 262,78.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 262,78.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="78.5"
@@ -60190,11 +60601,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(1.1162596,0,0,1.1065394,80.948334,-350.49863)" />
<path
transform="matrix(-1.087144,-0.2518404,0.2525206,-1.0776772,126.97246,766.619)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -60212,7 +60623,7 @@
sodipodi:cy="135"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 65,135 c 0,0.55228 -0.447715,1 -1,1 -0.552285,0 -1,-0.44772 -1,-1 0,-0.55228 0.447715,-1 1,-1 0.552285,0 1,0.44772 1,1 z"
+ d="m 65,135 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
inkscape:transform-center-x="-3.1120555"
inkscape:transform-center-y="-5.7593212" />
</g>
@@ -60247,7 +60658,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g36441"
+ id="ICON_SNAP_INCREMENT"
transform="translate(107,-124)">
<g
style="opacity:0.85;display:inline;enable-background:new"
@@ -60295,7 +60706,7 @@
style="display:inline">
<path
transform="matrix(1.142871,0,0,1.142855,-27.218817,-5.0713453)"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
sodipodi:ry="3.5"
sodipodi:rx="3.5"
sodipodi:cy="35.5"
@@ -60311,7 +60722,7 @@
sodipodi:cy="35.5"
sodipodi:rx="3.5"
sodipodi:ry="3.5"
- d="m 334,35.5 c 0,1.932997 -1.567,3.5 -3.5,3.5 -1.933,0 -3.5,-1.567003 -3.5,-3.5 0,-1.932997 1.567,-3.5 3.5,-3.5 1.933,0 3.5,1.567003 3.5,3.5 z"
+ d="m 334,35.5 a 3.5,3.5 0 1 1 -7,0 3.5,3.5 0 1 1 7,0 z"
transform="matrix(0.857099,0,0,0.857147,67.228993,5.071249)" />
</g>
<g
@@ -60389,7 +60800,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g36486"
+ id="ICON_HELP"
transform="translate(-44.309303,267.47333)">
<rect
y="309.52667"
@@ -60535,7 +60946,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -60543,7 +60954,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -60562,7 +60973,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -60580,7 +60991,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -60589,7 +61000,7 @@
</g>
<g
style="opacity:0.96000001;display:inline;enable-background:new"
- id="g36540"
+ id="ICON_STRANDS"
inkscape:label="Layer 1"
transform="translate(-211.14286,264.78067)">
<g
@@ -60684,7 +61095,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g36570"
+ id="ICON_UNLINKED"
transform="translate(21,254)">
<rect
y="321"
@@ -60780,7 +61191,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g36612"
+ id="ICON_LINKED"
transform="translate(0,275)">
<g
transform="translate(-226,210)"
@@ -60931,7 +61342,7 @@
<g
transform="matrix(-1,0,0,1,530,548)"
style="opacity:0.9;display:inline;enable-background:new"
- id="g36668">
+ id="ICON_GHOST_ENABLED">
<rect
style="opacity:0;fill:#aaccff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.4000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect36670"
@@ -61017,7 +61428,7 @@
</g>
<g
transform="translate(47,571)"
- id="g36699"
+ id="ICON_HAND"
style="display:inline;enable-background:new">
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -61072,7 +61483,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g36882"
+ id="ICON_RENDER_REGION"
transform="translate(-21,254)">
<rect
ry="0"
@@ -61249,7 +61660,7 @@
id="g36930">
<path
transform="matrix(0.7834486,0,0,0.2000006,10.413535,395.5997)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -61307,11 +61718,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(1.187982,0,0,1.0569758,379.83032,-513.21497)" />
<path
transform="matrix(1.3827154,0,0,1.4028327,364.1482,-688.72206)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -61327,11 +61738,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.987526,0,0,0.8124641,394.9733,-392.80617)" />
<path
transform="matrix(0.9848328,0,0,0.9992585,395.19018,-485.12778)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -61347,7 +61758,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.591154,0,0,0.5887513,425.87219,-279.05319)" />
<path
sodipodi:type="arc"
@@ -61357,11 +61768,11 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.9913883,0,0,1.0058976,394.67318,-488.46061)" />
<path
transform="matrix(0.6941559,0,0,0.6920597,417.67198,-331.15708)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
@@ -61377,7 +61788,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(0.1975308,0,0,0.1999991,456.0926,-84.399595)" />
<path
sodipodi:type="arc"
@@ -61387,7 +61798,7 @@
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
transform="matrix(-0.6760501,-0.1575078,0.1570322,-0.6740085,446.07727,367.34791)" />
</g>
<path
@@ -61405,275 +61816,273 @@
inkscape:connector-curvature="0" />
</g>
<g
- style="display:inline;enable-background:new"
- id="g36970"
- transform="translate(62.999998,254)">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect36972"
- width="16"
- height="16"
- x="215"
- y="-339"
- transform="scale(1,-1)" />
- <path
- style="opacity:0.2;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 220,324 0,1 -2,0 0,2 -1,0 0,2 -1,0 0,6 1,0 0,2 1,0 2,0 0,-1 1,0 0,-2 1,0 0,-2 1,0 0,-1 1,0 3,0 0,-1 1,0 1,0 0,-4 -1,0 0,-1 -1,0 0,-1 -3,0 -1,0 -1,0 -1,0 -1,0 z"
- id="path36974"
- sodipodi:nodetypes="cccccccccccccccccccccccccccccccccc"
- inkscape:connector-curvature="0" />
+ id="ICON_BORDER_LASSO">
<g
- id="g36976"
- transform="translate(1,84)">
+ id="g16722">
<g
- transform="translate(5,-6.0000002e-7)"
- style="fill:#1a1a1a;display:inline;enable-background:new"
- id="g36980" />
- </g>
- <g
- id="g37010"
- style="fill:#321900">
- <rect
- transform="scale(1,-1)"
- y="-324"
- x="223"
- height="1"
- width="2"
- id="rect37012"
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- transform="scale(1,-1)"
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37014"
- width="2"
- height="1"
- x="219"
- y="-325" />
- <rect
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37016"
- width="1"
- height="1"
- x="324"
- y="227"
- transform="matrix(0,1,1,0,0,0)" />
- <rect
- y="226"
- x="323"
- height="1"
- width="1"
- id="rect37018"
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="matrix(0,1,1,0,0,0)" />
- <rect
- y="229"
- x="328"
- height="1"
- width="1"
- id="rect37020"
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="matrix(0,1,1,0,0,0)" />
- <rect
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37022"
- width="1"
- height="2"
- x="216"
- y="-329"
- transform="scale(1,-1)" />
- <rect
- transform="scale(1,-1)"
- y="-337"
- x="216"
- height="2"
- width="1"
- id="rect37024"
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37026"
- width="1"
- height="1"
- x="220"
- y="-337"
- transform="scale(1,-1)" />
- <rect
- transform="scale(1,-1)"
- y="-338"
- x="219"
- height="1"
- width="1"
- id="rect37028"
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37030"
- width="1"
- height="1"
- x="221"
- y="-334"
- transform="scale(1,-1)" />
- <rect
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37032"
- width="1"
- height="2"
- x="215"
- y="-333"
- transform="scale(1,-1)" />
- <rect
- transform="matrix(0,1,1,0,0,0)"
- y="228"
- x="325"
- height="1"
- width="1"
- id="rect37034"
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- transform="matrix(0,1,1,0,0,0)"
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37036"
- width="1"
- height="1"
- x="329"
- y="228" />
- <rect
- transform="scale(1,-1)"
- y="-333"
- x="222"
- height="1"
- width="1"
- id="rect37038"
- style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
- <g
- id="g37040"
- style="fill:#ffd42a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
- <rect
- transform="scale(1,-1)"
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37042"
- width="2"
- height="1"
- x="221"
- y="-324" />
- <rect
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37044"
- width="1"
- height="2"
- x="323"
- y="225"
- transform="matrix(0,1,1,0,0,0)" />
- <rect
- transform="matrix(0,1,1,0,0,0)"
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37046"
- width="1"
- height="1"
- x="329"
- y="227" />
- <rect
- transform="scale(1,-1)"
- y="-331"
- x="215"
- height="2"
- width="1"
- id="rect37048"
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37050"
- width="1"
- height="2"
- x="215"
- y="-335"
- transform="scale(1,-1)" />
- <rect
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37052"
- width="2"
- height="1"
- x="217"
- y="-338"
- transform="scale(1,-1)" />
- <rect
- transform="scale(1,-1)"
- y="-336"
- x="221"
- height="2"
- width="1"
- id="rect37054"
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- y="-332"
- x="222"
- height="1"
- width="1"
- id="rect37056"
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="scale(1,-1)" />
- <rect
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37058"
- width="1"
- height="1"
- x="217"
- y="-327"
- transform="scale(1,-1)" />
- <rect
- transform="scale(1,-1)"
- y="-326"
- x="218"
- height="1"
- width="1"
- id="rect37060"
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- transform="matrix(0,1,1,0,0,0)"
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37062"
- width="2"
- height="1"
- x="326"
- y="229" />
- <rect
- transform="scale(1,-1)"
- style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37064"
- width="1"
- height="1"
- x="223"
- y="-331" />
+ style="display:inline;enable-background:new"
+ id="g36970"
+ transform="translate(62.999998,254)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect36972"
+ width="16"
+ height="16"
+ x="215"
+ y="-339"
+ transform="scale(1,-1)" />
+ <path
+ style="opacity:0.2;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 220,324 0,1 -2,0 0,2 -1,0 0,2 -1,0 0,6 1,0 0,2 1,0 2,0 0,-1 1,0 0,-2 1,0 0,-2 1,0 0,-1 1,0 3,0 0,-1 1,0 1,0 0,-4 -1,0 0,-1 -1,0 0,-1 -3,0 -1,0 -1,0 -1,0 -1,0 z"
+ id="path36974"
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccc"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g37010"
+ style="fill:#321900">
+ <rect
+ transform="scale(1,-1)"
+ y="-324"
+ x="223"
+ height="1"
+ width="2"
+ id="rect37012"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37014"
+ width="2"
+ height="1"
+ x="219"
+ y="-325" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37016"
+ width="1"
+ height="1"
+ x="324"
+ y="227"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ y="226"
+ x="323"
+ height="1"
+ width="1"
+ id="rect37018"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ y="229"
+ x="328"
+ height="1"
+ width="1"
+ id="rect37020"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37022"
+ width="1"
+ height="2"
+ x="216"
+ y="-329"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-337"
+ x="216"
+ height="2"
+ width="1"
+ id="rect37024"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37026"
+ width="1"
+ height="1"
+ x="220"
+ y="-337"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-338"
+ x="219"
+ height="1"
+ width="1"
+ id="rect37028"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37030"
+ width="1"
+ height="1"
+ x="221"
+ y="-334"
+ transform="scale(1,-1)" />
+ <rect
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37032"
+ width="1"
+ height="2"
+ x="215"
+ y="-333"
+ transform="scale(1,-1)" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ y="228"
+ x="325"
+ height="1"
+ width="1"
+ id="rect37034"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37036"
+ width="1"
+ height="1"
+ x="329"
+ y="228" />
+ <rect
+ transform="scale(1,-1)"
+ y="-333"
+ x="222"
+ height="1"
+ width="1"
+ id="rect37038"
+ style="fill:#321900;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g37040"
+ style="fill:#ffd42a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37042"
+ width="2"
+ height="1"
+ x="221"
+ y="-324" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37044"
+ width="1"
+ height="2"
+ x="323"
+ y="225"
+ transform="matrix(0,1,1,0,0,0)" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37046"
+ width="1"
+ height="1"
+ x="329"
+ y="227" />
+ <rect
+ transform="scale(1,-1)"
+ y="-331"
+ x="215"
+ height="2"
+ width="1"
+ id="rect37048"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37050"
+ width="1"
+ height="2"
+ x="215"
+ y="-335"
+ transform="scale(1,-1)" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37052"
+ width="2"
+ height="1"
+ x="217"
+ y="-338"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-336"
+ x="221"
+ height="2"
+ width="1"
+ id="rect37054"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="-332"
+ x="222"
+ height="1"
+ width="1"
+ id="rect37056"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(1,-1)" />
+ <rect
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37058"
+ width="1"
+ height="1"
+ x="217"
+ y="-327"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-326"
+ x="218"
+ height="1"
+ width="1"
+ id="rect37060"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ transform="matrix(0,1,1,0,0,0)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37062"
+ width="2"
+ height="1"
+ x="326"
+ y="229" />
+ <rect
+ transform="scale(1,-1)"
+ style="fill:#ff982a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37064"
+ width="1"
+ height="1"
+ x="223"
+ y="-331" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccc"
+ id="path37066"
+ d="m 220.9438,324.0562 0,1 6,0 0,-1 -6,0 z m 6,1 0,1 1,0 0,-1 -1,0 z m 1,1 0,1 1,0 0,-1 -1,0 z m -7,-1 -2,0 0,1 2,0 0,-1 z m -2,1 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,2 1,0 0,-2 z m -1,2 -1,0 0,6 1,0 0,-6 z m 0,5.75 0,2.25 1,0 0,-2 -1,-0.25 z"
+ style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ style="fill:url(#linearGradient106628);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 287.75,590.75 1.75,-1.5 1.99177,3.7253 1.75,-1 L 291.5,588.5 l 2.5,0 -6.25,-6.25 z"
+ id="path45378-1-5-6-2"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 288.34375,583.75 0,5.75"
+ id="path17845-9-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
</g>
<path
- sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccc"
- id="path37066"
- d="m 220.9438,324.0562 0,1 6,0 0,-1 -6,0 z m 6,1 0,1 1,0 0,-1 -1,0 z m 1,1 0,1 1,0 0,-1 -1,0 z m -7,-1 -2,0 0,1 2,0 0,-1 z m -2,1 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,2 1,0 0,-2 z m -1,2 -1,0 0,6 1,0 0,-6 z m 0,5.75 0,2.25 1,0 0,-2 -1,-0.25 z"
- style="opacity:0.15;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0"
+ id="path17835-7-2"
+ d="m 287.54419,581.36742 7,7.25 -3,0 1.69346,3.25845 -1.75,1 -1.69346,-3.50845 -2.25,2.25 z"
+ style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
- <path
- style="fill:url(#linearGradient106628);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 287.75,590.75 1.75,-1.5 1.99177,3.7253 1.75,-1 L 291.5,588.5 l 2.5,0 -6.25,-6.25 z"
- id="path45378-1-5-6-2"
- sodipodi:nodetypes="cccccccc"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 287.54419,581.36742 7,7.25 -3,0 1.69346,3.25845 -1.75,1 -1.69346,-3.50845 -2.25,2.25 z"
- id="path17835-7-2"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccc" />
- <path
- style="fill:none;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 288.34375,583.75 0,5.75"
- id="path17845-9-1"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
<g
style="opacity:0.96000001;display:inline;enable-background:new"
- id="g37068"
+ id="ICON_FREEZE"
transform="translate(126,86)">
<rect
style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -61796,7 +62205,7 @@
sodipodi:cy="330.5"
sodipodi:rx="2"
sodipodi:ry="2"
- d="m 266.5,330.5 c 0,1.10457 -0.89543,2 -2,2 -1.10457,0 -2,-0.89543 -2,-2 0,-1.10457 0.89543,-2 2,-2 1.10457,0 2,0.89543 2,2 z" />
+ d="m 266.5,330.5 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z" />
</g>
<path
style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
@@ -61847,7 +62256,7 @@
style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
- d="m 266.5,330.5 c 0,1.10457 -0.89543,2 -2,2 -1.10457,0 -2,-0.89543 -2,-2 0,-1.10457 0.89543,-2 2,-2 1.10457,0 2,0.89543 2,2 z"
+ d="m 266.5,330.5 a 2,2 0 1 1 -4,0 2,2 0 1 1 4,0 z"
sodipodi:ry="2"
sodipodi:rx="2"
sodipodi:cy="330.5"
@@ -61878,7 +62287,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g37138"
+ id="ICON_GROUP_VERTEX"
transform="translate(147.01612,401.00818)">
<rect
transform="scale(1,-1)"
@@ -61961,7 +62370,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(420,44)"
- id="g37166">
+ id="ICON_GROUP_UVS">
<rect
style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect37168"
@@ -61995,12 +62404,12 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" />
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
<path
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -62017,7 +62426,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -62039,7 +62448,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -62056,7 +62465,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -62070,7 +62479,7 @@
<g
transform="translate(-499.98389,503.95862)"
style="display:inline;enable-background:new"
- id="g37229">
+ id="ICON_BRUSH_DATA">
<path
sodipodi:nodetypes="ccccc"
id="path37231"
@@ -62122,7 +62531,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g37307"
+ id="ICON_GROUP_BONE"
transform="translate(-42,86)">
<g
id="g37309"
@@ -62217,7 +62626,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g37339"
+ id="ICON_GROUP_VCOL"
transform="translate(-84,65)">
<rect
transform="scale(-1,-1)"
@@ -62313,7 +62722,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -62329,7 +62738,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -62347,7 +62756,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -62363,7 +62772,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -62381,7 +62790,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -62395,7 +62804,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -62410,7 +62819,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -62428,14 +62837,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
</g>
<g
- id="g37816"
+ id="ICON_ARROW_LEFTRIGHT"
transform="translate(0,2)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -62487,7 +62896,7 @@
</g>
<g
transform="translate(-58,340)"
- id="g41151"
+ id="ICON_MESH_PLANE"
style="display:inline;enable-background:new">
<rect
y="48"
@@ -62526,7 +62935,7 @@
</g>
<g
transform="translate(-15,340)"
- id="g41161"
+ id="ICON_MESH_UVSPHERE"
style="display:inline;enable-background:new">
<rect
y="48"
@@ -62551,7 +62960,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -62560,7 +62969,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -62577,7 +62986,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -62590,7 +62999,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41175"
+ id="ICON_MESH_CUBE"
transform="translate(-21,359)">
<rect
y="29"
@@ -62646,7 +63055,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(3,417)"
- id="g41191">
+ id="ICON_MESH_MONKEY">
<rect
style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect41193"
@@ -62699,7 +63108,7 @@
style="fill:#f9f9f9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
transform="translate(0.5,-0.46875)"
- d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="-23"
@@ -62715,7 +63124,7 @@
sodipodi:cy="-23"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(1.2143583,0,0,1.1512108,-28.054112,2.9290602)" />
<path
sodipodi:type="arc"
@@ -62725,7 +63134,7 @@
sodipodi:cy="-23"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(0.8392157,0,0,0.8382979,21.884318,-4.2140957)" />
<rect
style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -62742,7 +63151,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(1.2116904,0,0,1.1282344,-22.693138,2.3776257)"
- d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="-23"
@@ -62752,7 +63161,7 @@
sodipodi:type="arc" />
<path
transform="matrix(0.8392157,0,0,0.8382979,26.893134,-4.2140957)"
- d="m 134,-23 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
+ d="m 134,-23 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="-23"
@@ -62782,7 +63191,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41229"
+ id="ICON_MESH_ICOSPHERE"
transform="translate(169,365)">
<rect
y="23"
@@ -62873,7 +63282,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41255"
+ id="ICON_MESH_GRID"
transform="translate(231,348)">
<rect
y="40"
@@ -62989,7 +63398,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41283"
+ id="ICON_MESH_CIRCLE"
transform="translate(275,332)">
<rect
y="56"
@@ -63002,7 +63411,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -63019,7 +63428,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -63033,7 +63442,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -63041,7 +63450,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -63053,7 +63462,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41295"
+ id="ICON_MESH_CYLINDER"
transform="translate(380,233)">
<rect
y="155"
@@ -63095,7 +63504,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41309"
+ id="ICON_MESH_TORUS"
transform="translate(401,212)">
<rect
style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -63136,12 +63545,12 @@
sodipodi:cy="40.5"
sodipodi:rx="6.5"
sodipodi:ry="2.5"
- d="m -213.5,40.5 c 0,1.380712 -2.91015,2.5 -6.5,2.5 -3.58985,0 -6.5,-1.119288 -6.5,-2.5 0,-1.380712 2.91015,-2.5 6.5,-2.5 3.58985,0 6.5,1.119288 6.5,2.5 z"
+ d="m -213.5,40.5 a 6.5,2.5 0 1 1 -13,0 6.5,2.5 0 1 1 13,0 z"
transform="matrix(0.9999986,0,0,1.799999,-2.971883e-4,111.10004)" />
</g>
<g
style="display:inline;enable-background:new"
- id="g41323"
+ id="ICON_MESH_CONE"
transform="translate(422,192)">
<rect
y="196"
@@ -63171,7 +63580,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41333"
+ id="ICON_CURVE_BEZCURVE"
transform="translate(472,230)">
<rect
style="opacity:0.01000001;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -63326,7 +63735,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41381"
+ id="ICON_CURVE_NCURVE"
transform="matrix(0,1,1,0,99,651)">
<rect
y="137"
@@ -63480,7 +63889,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41431"
+ id="ICON_CURVE_NCIRCLE"
transform="translate(565.49991,277.875)">
<g
transform="translate(-23.5,-18.875)"
@@ -63546,7 +63955,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -63554,7 +63963,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -63567,7 +63976,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41459"
+ id="ICON_SURFACE_NCIRCLE"
transform="translate(311,278)">
<g
transform="translate(0,-19)"
@@ -63635,7 +64044,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -63652,7 +64061,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -63666,7 +64075,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -63674,7 +64083,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -63687,7 +64096,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41493"
+ id="ICON_CURVE_BEZCIRCLE"
transform="translate(455,122.97748)">
<rect
y="244.02252"
@@ -63760,7 +64169,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -63768,7 +64177,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -63799,7 +64208,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41527"
+ id="ICON_SURFACE_NCURVE"
transform="translate(70.968338,302.76882)">
<rect
transform="matrix(0,1,1,0,0,0)"
@@ -63995,7 +64404,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41587"
+ id="ICON_SURFACE_NCYLINDER"
transform="translate(375,231.00851)">
<rect
style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -64092,7 +64501,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41623"
+ id="ICON_SURFACE_NSURFACE"
transform="translate(258.99995,102)">
<rect
transform="scale(-1,1)"
@@ -64260,7 +64669,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41680"
+ id="ICON_SURFACE_NTORUS"
transform="translate(338.00016,191)">
<g
id="g41682"
@@ -64347,7 +64756,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(0.9999986,0,0,1.799999,-2.971883e-4,111.10004)"
- d="m -213.5,40.5 c 0,1.380712 -2.91015,2.5 -6.5,2.5 -3.58985,0 -6.5,-1.119288 -6.5,-2.5 0,-1.380712 2.91015,-2.5 6.5,-2.5 3.58985,0 6.5,1.119288 6.5,2.5 z"
+ d="m -213.5,40.5 a 6.5,2.5 0 1 1 -13,0 6.5,2.5 0 1 1 13,0 z"
sodipodi:ry="2.5"
sodipodi:rx="6.5"
sodipodi:cy="40.5"
@@ -64358,7 +64767,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41715"
+ id="ICON_SURFACE_NSPHERE"
transform="translate(300.99985,63)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -64430,7 +64839,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -64447,7 +64856,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -64461,7 +64870,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64475,7 +64884,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41749"
+ id="ICON_CURVE_PATH"
transform="matrix(1,0,0,-1,496,768)">
<rect
transform="scale(-1,1)"
@@ -64579,7 +64988,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g42152"
+ id="ICON_META_CUBE"
transform="translate(272.99917,170)">
<g
transform="translate(83.990361,105)"
@@ -64594,7 +65003,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64602,7 +65011,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -64620,7 +65029,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64633,7 +65042,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64683,7 +65092,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g42181"
+ id="ICON_META_CAPSULE"
transform="translate(335.99917,149.00001)">
<g
style="opacity:0.5"
@@ -64693,7 +65102,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -64711,7 +65120,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64719,7 +65128,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -64732,7 +65141,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -64784,7 +65193,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g42207"
+ id="ICON_META_PLANE"
transform="translate(251.99917,191.00001)">
<g
transform="translate(83.990364,83.999999)"
@@ -64799,7 +65208,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64807,7 +65216,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -64825,7 +65234,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64838,7 +65247,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64873,7 +65282,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g42225"
+ id="ICON_META_BALL"
transform="translate(293.99917,128.01655)">
<g
id="g42227">
@@ -64890,7 +65299,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64898,7 +65307,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -64916,7 +65325,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64929,7 +65338,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64946,7 +65355,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -64963,7 +65372,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -64977,7 +65386,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -64985,7 +65394,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g42247"
+ id="ICON_META_ELLIPSOID"
transform="translate(315,107)">
<g
transform="translate(83.990364,168)"
@@ -65000,7 +65409,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65008,7 +65417,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65026,7 +65435,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65039,7 +65448,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65102,7 +65511,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Pracowniaa\Pulpit\Browser icons ver 1\font_file SMALL.png"
transform="translate(10.00003,171.5)"
- id="g42279">
+ id="ICON_OUTLINER_DATA_FONT">
<rect
y="237.5"
x="162.99997"
@@ -65227,7 +65636,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g35366"
+ id="ICON_META_DATA"
transform="translate(333.02099,358)">
<rect
y="135"
@@ -65249,7 +65658,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65257,7 +65666,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65275,7 +65684,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65323,7 +65732,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65341,7 +65750,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65349,7 +65758,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65371,7 +65780,7 @@
sodipodi:cy="292.5"
sodipodi:rx="4"
sodipodi:ry="4"
- d="m 223.5,292.5 c 0,2.20914 -1.79086,4 -4,4 -2.20914,0 -4,-1.79086 -4,-4 0,-2.20914 1.79086,-4 4,-4 2.20914,0 4,1.79086 4,4 z"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
transform="translate(20,0)" />
<path
sodipodi:type="arc"
@@ -65381,11 +65790,11 @@
sodipodi:cy="292.5"
sodipodi:rx="4"
sodipodi:ry="4"
- d="m 223.5,292.5 c 0,2.20914 -1.79086,4 -4,4 -2.20914,0 -4,-1.79086 -4,-4 0,-2.20914 1.79086,-4 4,-4 2.20914,0 4,1.79086 4,4 z"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
transform="matrix(0.875,0,0,0.875,47.4375,36.5625)" />
<path
transform="matrix(0.7060003,0,0,0.7060647,84.532933,85.976064)"
- d="m 223.5,292.5 c 0,2.20914 -1.79086,4 -4,4 -2.20914,0 -4,-1.79086 -4,-4 0,-2.20914 1.79086,-4 4,-4 2.20914,0 4,1.79086 4,4 z"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
sodipodi:ry="4"
sodipodi:rx="4"
sodipodi:cy="292.5"
@@ -65395,7 +65804,7 @@
sodipodi:type="arc" />
<path
transform="matrix(0.875,0,0,0.875,47.4375,36.5625)"
- d="m 223.5,292.5 c 0,2.20914 -1.79086,4 -4,4 -2.20914,0 -4,-1.79086 -4,-4 0,-2.20914 1.79086,-4 4,-4 2.20914,0 4,1.79086 4,4 z"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
sodipodi:ry="4"
sodipodi:rx="4"
sodipodi:cy="292.5"
@@ -65407,7 +65816,7 @@
</g>
<g
transform="translate(291,273.9804)"
- id="g35428"
+ id="ICON_OUTLINER_DATA_META"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#dcdcdc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -65424,7 +65833,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65442,7 +65851,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65450,7 +65859,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65508,7 +65917,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65516,7 +65925,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65534,7 +65943,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65545,7 +65954,7 @@
style="opacity:0.9;display:inline;enable-background:new">
<path
transform="translate(20,0)"
- d="m 223.5,292.5 c 0,2.20914 -1.79086,4 -4,4 -2.20914,0 -4,-1.79086 -4,-4 0,-2.20914 1.79086,-4 4,-4 2.20914,0 4,1.79086 4,4 z"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
sodipodi:ry="4"
sodipodi:rx="4"
sodipodi:cy="292.5"
@@ -65555,7 +65964,7 @@
sodipodi:type="arc" />
<path
transform="matrix(0.875,0,0,0.875,47.4375,36.5625)"
- d="m 223.5,292.5 c 0,2.20914 -1.79086,4 -4,4 -2.20914,0 -4,-1.79086 -4,-4 0,-2.20914 1.79086,-4 4,-4 2.20914,0 4,1.79086 4,4 z"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
sodipodi:ry="4"
sodipodi:rx="4"
sodipodi:cy="292.5"
@@ -65571,7 +65980,7 @@
sodipodi:cy="292.5"
sodipodi:rx="4"
sodipodi:ry="4"
- d="m 223.5,292.5 c 0,2.20914 -1.79086,4 -4,4 -2.20914,0 -4,-1.79086 -4,-4 0,-2.20914 1.79086,-4 4,-4 2.20914,0 4,1.79086 4,4 z"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
transform="matrix(0.7060003,0,0,0.7060647,84.532933,85.976064)" />
<path
sodipodi:type="arc"
@@ -65581,12 +65990,12 @@
sodipodi:cy="292.5"
sodipodi:rx="4"
sodipodi:ry="4"
- d="m 223.5,292.5 c 0,2.20914 -1.79086,4 -4,4 -2.20914,0 -4,-1.79086 -4,-4 0,-2.20914 1.79086,-4 4,-4 2.20914,0 4,1.79086 4,4 z"
+ d="m 223.5,292.5 a 4,4 0 1 1 -8,0 4,4 0 1 1 8,0 z"
transform="matrix(0.875,0,0,0.875,47.4375,36.5625)" />
</g>
</g>
<g
- id="g34702"
+ id="ICON_MAT_SPHERE_SKY"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\sphere with sky.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -65605,11 +66014,11 @@
sodipodi:cy="192.5"
sodipodi:rx="1.75"
sodipodi:ry="1.75"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
transform="matrix(1.7142856,0,0,1.7142871,-330.83199,-136.46043)" />
<path
transform="matrix(1.4285718,0,0,1.4285718,-198.61789,-81.960223)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -65625,7 +66034,7 @@
sodipodi:cy="192.5"
sodipodi:rx="1.75"
sodipodi:ry="1.75"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
transform="matrix(0.8571429,0,0,0.8571429,66.810813,28.039828)" />
</g>
<rect
@@ -65649,7 +66058,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65667,7 +66076,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65680,7 +66089,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65688,7 +66097,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65728,7 +66137,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -65737,7 +66146,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65749,7 +66158,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -65761,38 +66170,8 @@
</g>
</g>
<g
- style="stroke:#ffffff;display:inline"
- transform="matrix(-1,0,0,-1,104.1613,262.99999)"
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="g34782">
- <path
- d=""
- sodipodi:nodetypes="cz"
- id="path34784"
- style="fill:none;stroke:#ffffff;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- </g>
- <path
- style="fill:none;stroke:#ffffff;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path34806"
- sodipodi:nodetypes="cz"
- d=""
- inkscape:connector-curvature="0" />
- <path
- d=""
- sodipodi:nodetypes="cz"
- id="path34696"
- style="fill:none;stroke:#ffffff;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
- <g
- transform="matrix(-1,0,0,1,-155,-228)"
- style="opacity:0.12000002"
- id="g36040" />
- <g
style="display:inline;enable-background:new"
- id="g36398"
+ id="ICON_MANIPUL"
transform="translate(-20.999985,0)">
<rect
y="157"
@@ -65942,7 +66321,7 @@
sodipodi:cy="14.5"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
transform="matrix(1.3333333,0,0,1.3333343,3,147.66665)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -65956,7 +66335,7 @@
sodipodi:cy="14.5"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -66004,7 +66383,7 @@
</g>
<g
transform="translate(105,337.99999)"
- id="g35291"
+ id="ICON_LAMP_SPOT"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -66049,14 +66428,14 @@
sodipodi:cy="35"
sodipodi:rx="1.2111344"
sodipodi:ry="4.9951267"
- d="m 182.21113,35 c 0,2.758732 -0.54224,4.995127 -1.21113,4.995127 -0.66889,0 -1.21113,-2.236395 -1.21113,-4.995127 0,-2.758732 0.54224,-4.995127 1.21113,-4.995127 0.66788,0 1.20971,2.229902 1.21113,4.984465"
+ d="m 182.21113,35 a 1.2111344,4.9951267 0 1 1 0,-0.01066"
transform="matrix(1.2491741,-1.2491602,0.7680871,0.768079,-75.108556,239.34027)"
sodipodi:start="0"
sodipodi:end="6.2810509"
sodipodi:open="true" />
<path
transform="matrix(0.9589476,-0.9192618,0.5776079,0.5780619,-15.42366,185.77921)"
- d="m 182.17638,35 c 0,3.053777 -0.52668,5.529352 -1.17638,5.529352 -0.6497,0 -1.17638,-2.475575 -1.17638,-5.529352 0,-3.053777 0.52668,-5.529352 1.17638,-5.529352 0.6497,0 1.17638,2.475575 1.17638,5.529352 z"
+ d="m 182.17638,35 a 1.1763829,5.5293522 0 1 1 -2.35276,0 1.1763829,5.5293522 0 1 1 2.35276,0 z"
sodipodi:ry="5.5293522"
sodipodi:rx="1.1763829"
sodipodi:cy="35"
@@ -66167,7 +66546,7 @@
y="59.75" />
</g>
<g
- id="g35343"
+ id="ICON_LAMP_POINT"
transform="translate(0,-7e-6)">
<rect
transform="scale(-1,-1)"
@@ -66404,7 +66783,7 @@
transform="translate(-340.00002,-121.00001)">
<path
transform="matrix(1.9999998,0,0,2.0000014,-462.99991,-192.00026)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -66420,11 +66799,11 @@
sodipodi:cy="192.5"
sodipodi:rx="1.75"
sodipodi:ry="1.75"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
transform="matrix(2.5714449,0,0,2.5714449,-728.43612,-302.00313)" />
<path
transform="matrix(1.9999748,0,0,1.9999748,-462.98824,-191.99513)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -66434,7 +66813,7 @@
sodipodi:type="arc" />
<path
transform="matrix(1.428566,0,0,1.428566,-197.56891,-81.998957)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -66454,7 +66833,7 @@
</g>
<g
transform="translate(147,337.99999)"
- id="g35443"
+ id="ICON_LAMP_SUN"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#ffe680;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.60000002;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -66479,11 +66858,11 @@
sodipodi:cy="192.5"
sodipodi:rx="1.75"
sodipodi:ry="1.75"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
transform="matrix(1.9999998,0,0,2.0000014,-790.00001,-327.00035)" />
<path
transform="matrix(2.5714622,0,0,2.5714622,-1055.4442,-437.00638)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -66493,7 +66872,7 @@
sodipodi:type="arc" />
<path
transform="matrix(2.0000089,0,0,2.0000089,-790.00413,-327.00163)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -66530,7 +66909,7 @@
</g>
<g
transform="translate(189,295.99999)"
- id="g35463"
+ id="ICON_LAMP_AREA"
style="display:inline;enable-background:new">
<rect
y="92"
@@ -66552,11 +66931,11 @@
sodipodi:cy="192.5"
sodipodi:rx="1.75"
sodipodi:ry="1.75"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
transform="matrix(2.2376043,0,0,2.2484492,-801.20081,-335.84886)" />
<path
transform="matrix(1.9004611,0,0,1.899214,-644.62036,-268.6269)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -66566,7 +66945,7 @@
sodipodi:type="arc" />
<path
transform="matrix(1.5591172,0,0,1.559203,-486.06699,-203.16445)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -66734,7 +67113,7 @@
</g>
<g
transform="translate(168,274.99999)"
- id="g35538"
+ id="ICON_LAMP_HEMI"
style="display:inline;enable-background:new">
<rect
style="opacity:0.01000001;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -66842,7 +67221,7 @@
</g>
</g>
<g
- id="g36448"
+ id="ICON_ASSET_MANAGER"
transform="translate(41.84997,0.15003049)">
<g
transform="translate(105,416)"
@@ -66973,225 +67352,227 @@
</g>
</g>
<g
- style="fill:#d45500;fill-opacity:1;display:inline"
- transform="translate(250,-41.00755)"
- id="g36511" />
- <g
- style="opacity:0.55;display:inline"
- id="g35729"
- transform="translate(69,-158)">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect35731"
- width="16"
- height="16"
- x="-64"
- y="336" />
+ id="ICON_VERTEXSEL">
<g
- transform="translate(1,0)"
- id="g35733">
+ transform="translate(69,-158)"
+ id="g35729"
+ style="opacity:0.55;display:inline">
+ <rect
+ y="336"
+ x="-64"
+ height="16"
+ width="16"
+ id="rect35731"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- transform="translate(-386,446.5)"
- id="g35735">
- <path
- id="path35737"
- d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
- style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- sodipodi:nodetypes="ccccccc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccccc"
- style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
- id="path35739"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
+ id="g35733"
+ transform="translate(1,0)">
<g
- transform="translate(179,-179)"
- id="g35741">
+ id="g35735"
+ transform="translate(-386,446.5)">
<path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
- id="path35743"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ id="path35737" />
<path
+ inkscape:connector-curvature="0"
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path35739"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="cccccc" />
+ <g
+ id="g35741"
+ transform="translate(179,-179)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path35743"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path35745"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc"
- style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
- id="path35745"
- inkscape:connector-curvature="0" />
+ id="path35747"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ style="fill:none;stroke:url(#linearGradient36713);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
+ <rect
+ y="342"
+ x="-57"
+ height="7.75"
+ width="1"
+ id="rect35749"
+ style="fill:url(#linearGradient36715);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
- style="fill:none;stroke:url(#linearGradient36713);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
- id="path35747"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path35751"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ style="fill:none;stroke:url(#linearGradient36717);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
- <rect
- style="fill:url(#linearGradient36715);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect35749"
- width="1"
- height="7.75"
- x="-57"
- y="342" />
+ </g>
+ <rect
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37868-0"
+ width="3.9785564"
+ height="4"
+ x="7.0214434"
+ y="181" />
+ <g
+ id="g35803">
<path
- style="fill:none;stroke:url(#linearGradient36717);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
- id="path35751"
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ id="path35805"
+ d="m 8.0048608,180.50566 0.036785,0 c 0.8181814,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.6586836,1.49472 -1.476865,1.49472 l -0.036785,0 c -0.8181897,0 -1.4768733,-0.66664 -1.4768733,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.6586836,-1.49473 1.4768733,-1.49473 z"
+ style="fill:none;stroke:#542b00;stroke-width:1.495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path35807"
+ d="m 9.0203881,181.00394 c -0.6673195,0 -1.334639,1e-5 -2.0019585,1e-5 0,0.66706 0,1.33411 0,2.00119 0.6673195,0 1.334639,-1e-5 2.0019585,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
</g>
</g>
<g
- transform="translate(90,-158)"
- id="g35753"
- style="opacity:0.55;display:inline">
- <rect
- y="336"
- x="-64"
- height="16"
- width="16"
- id="rect35755"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ id="ICON_EDGESEL">
<g
- id="g35757"
- transform="translate(1,0)">
+ style="opacity:0.55;display:inline"
+ id="g35753"
+ transform="translate(90,-158)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35755"
+ width="16"
+ height="16"
+ x="-64"
+ y="336" />
<g
- id="g35759"
- transform="translate(-386,446.5)">
- <path
- sodipodi:nodetypes="ccccccc"
- style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
- id="path35761"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- id="path35763"
- d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
- style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0" />
+ transform="translate(1,0)"
+ id="g35757">
<g
- id="g35765"
- transform="translate(179,-179)">
+ transform="translate(-386,446.5)"
+ id="g35759">
<path
- sodipodi:nodetypes="ccccc"
- id="path35767"
- d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
- style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ id="path35761"
+ d="m 329.5,-108.25 -5.5,2 0,6.75 5.5,3 5.5,-3 0,-6.75 -5.5,-2 z"
+ style="fill:#552200;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="ccccccc" />
<path
- id="path35769"
- d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
- style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
- sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ style="fill:#c9c9c9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06898749px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 324,-99.5 0,-7 6,-1.75 0,11.5 -0.5,0.25 -5.5,-3 z"
+ id="path35763"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
+ inkscape:export-ydpi="90" />
+ <g
+ transform="translate(179,-179)"
+ id="g35765">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89401144px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 156,79.5 0,-7 -5,-1.75 0,11.5 5,-2.75 z"
+ id="path35767"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccc"
+ style="fill:#e6e6e6;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 145,72.5 5.5,-2 5.5,2 -5.5,2.5 -5.5,-2.5 z"
+ id="path35769" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient36719);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
+ id="path35772"
+ sodipodi:nodetypes="ccccc" />
</g>
+ <rect
+ style="fill:url(#linearGradient36721);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect35774"
+ width="1"
+ height="7.75"
+ x="-57"
+ y="342" />
<path
- sodipodi:nodetypes="ccccc"
- id="path35772"
- d="m 334.5,-106.5 0,6.75 -5,2.75 -5,-2.75 0,-6.75"
- style="fill:none;stroke:url(#linearGradient36719);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient36723);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
+ id="path35776"
+ sodipodi:nodetypes="ccc" />
</g>
+ </g>
+ <rect
+ style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37868-0-4"
+ width="3.0000007"
+ height="8"
+ x="28"
+ y="182" />
+ <g
+ transform="translate(65.984093,-55.50004)"
+ id="g35809">
<rect
- y="342"
- x="-57"
- height="7.75"
- width="1"
- id="rect35774"
- style="fill:url(#linearGradient36721);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ transform="matrix(1,2.1226448e-5,0,1,0,0)"
+ y="237.00038"
+ x="-38.454918"
+ height="8.0116062"
+ width="1.9820247"
+ id="rect35811"
+ style="fill:none;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.90196078;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;display:inline"
+ id="rect35814"
+ width="0.99999994"
+ height="7.0000257"
+ x="-37.984093"
+ y="237.50137"
+ transform="matrix(1,3.6759233e-5,0,1,0,0)" />
<path
- sodipodi:nodetypes="ccc"
- id="path35776"
- d="m -61,340.65468 c 0,0 4.5,2 4.5,2 l 4.5,-2"
- style="fill:none;stroke:url(#linearGradient36723);stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;display:inline"
+ d="m -37.5,245 -0.9549,0.0112 0,-8.01161 1.982,4e-5"
+ id="path35816"
+ sodipodi:nodetypes="cccc" />
</g>
</g>
- <rect
- y="181"
- x="7.0214434"
- height="4"
- width="3.9785564"
- id="rect37868-0"
- style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- id="g35803">
- <path
- style="fill:none;stroke:#542b00;stroke-width:1.495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 8.0048608,180.50566 0.036785,0 c 0.8181814,0 1.476865,0.66665 1.476865,1.49473 l 0,1.2e-4 c 0,0.82808 -0.6586836,1.49472 -1.476865,1.49472 l -0.036785,0 c -0.8181897,0 -1.4768733,-0.66664 -1.4768733,-1.49472 l 0,-1.2e-4 c 0,-0.82808 0.6586836,-1.49473 1.4768733,-1.49473 z"
- id="path35805"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
- d="m 9.0203881,181.00394 c -0.6673195,0 -1.334639,1e-5 -2.0019585,1e-5 0,0.66706 0,1.33411 0,2.00119 0.6673195,0 1.334639,-1e-5 2.0019585,-1e-5 0,-0.66707 0,-1.33413 0,-2.00119 z"
- id="path35807"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- </g>
- <rect
- y="182"
- x="28"
- height="8"
- width="3.0000007"
- id="rect37868-0-4"
- style="opacity:0.12000002;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- id="g35809"
- transform="translate(65.984093,-55.50004)">
- <rect
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- style="fill:none;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.90196078;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
- id="rect35811"
- width="1.9820247"
- height="8.0116062"
- x="-38.454918"
- y="237.00038"
- transform="matrix(1,2.1226448e-5,0,1,0,0)" />
- <rect
- transform="matrix(1,3.6759233e-5,0,1,0,0)"
- y="237.50137"
- x="-37.984093"
- height="7.0000257"
- width="0.99999994"
- id="rect35814"
- style="fill:#ffc17d;fill-opacity:1;fill-rule:nonzero;display:inline"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <path
- sodipodi:nodetypes="cccc"
- id="path35816"
- d="m -37.5,245 -0.9549,0.0112 0,-8.01161 1.982,4e-5"
- style="fill:none;stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;display:inline"
- inkscape:connector-curvature="0" />
- </g>
- <g
- id="g106643">
+ id="ICON_FACESEL">
<g
transform="translate(111,-158)"
id="g35778"
@@ -67301,7 +67682,7 @@
</g>
<g
transform="matrix(-1,0,0,1,532,25)"
- id="g37386"
+ id="ICON_PLAY_REVERSE"
style="display:inline">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -67331,23 +67712,9 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- style="opacity:0;fill:#fffeaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- id="rect39658"
- width="1"
- height="0"
- x="-25"
- y="67" />
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- id="rect39660"
- width="0"
- height="1"
- x="-24"
- y="66" />
<g
style="display:inline;enable-background:new"
- id="g39029"
+ id="ICON_STYLUS_PRESSURE"
transform="matrix(0,1,1,0,248,835)">
<rect
style="opacity:0.01000001;fill:#909090;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -67453,7 +67820,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g39803"
+ id="ICON_MOD_SMOKE"
transform="translate(-66,268)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\sss.png"
inkscape:export-xdpi="90"
@@ -67482,7 +67849,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -67490,7 +67857,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -67563,7 +67930,7 @@
</g>
<g
transform="translate(-249,193)"
- id="g41505"
+ id="ICON_MOD_PHYSICS"
style="display:inline">
<g
style="opacity:0.85"
@@ -67649,7 +68016,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -67662,35 +68029,128 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(-0.3127677,0,0,0.3125443,475.3332,36.070149)" />
</g>
<g
- transform="translate(-21.1375,-0.42)"
- id="g42277">
+ id="ICON_MOD_DECIM">
+ <g
+ transform="translate(0,2)"
+ id="g10823">
+ <rect
+ y="260"
+ x="68"
+ height="16"
+ width="16"
+ id="rect31968"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ style="fill:url(#linearGradient24189);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 70.562559,271.5 0.24994,0.25 9,-9 -0.24994,-0.25 -9,0 0,9 z"
+ id="path12863"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path12865"
+ style="fill:none;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ d="m 70.562559,271.5 -6e-5,-9 9,5e-5 m -4.99994,4.89995 0,-4.8 m 0.89997,3.9 -4.8,0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.00000119px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 71.562559,265.51369 0,-2.01369 1.99998,0"
+ id="path12867"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <g
+ style="opacity:0.4"
+ id="g24198">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ style="fill:url(#linearGradient24209);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ d="m 72.562559,273.5 -0.25006,-0.25 9,-9 0.25006,0.25 0,9 -9,0 z"
+ id="path12861" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path27953"
+ d="m 80.499999,265.5 0,7 -7,0"
+ style="fill:none;stroke:url(#linearGradient24192);stroke-width:0.99999875;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:7.40000265;display:inline"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;display:inline"
+ d="m 81.562559,264.5 0,9 -9,-5e-5"
+ id="path12869"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path12871"
+ d="m 75.562559,265.51369 0,-2.01369 1.99998,0"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.00000119px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.7;fill:none;stroke:#ffffff;stroke-width:1.00000119px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 71.562579,269.51369 0,-2.01369 1.99998,0"
+ id="path12873"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
<path
- sodipodi:nodetypes="cccccccccc"
- id="path42279"
- style="opacity:0.75;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- d="m 99.6375,267.92 1,-1 m -4,4 1,-1 m 5,-5 1,-1 m -10,10 1,-1 m -4,4 1,-1"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path42252"
+ d="M 71,277 83,265"
+ style="opacity:0.2;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g42277"
+ transform="translate(-21.1375,-0.42)">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 99.6375,267.92 1,-1 m -4,4 1,-1 m 5,-5 1,-1 m -10,10 1,-1 m -4,4 1,-1"
+ style="opacity:0.75;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="path42279"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path42281"
+ style="fill:none;stroke:#ffefaf;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 99.6375,267.92 1,-1 m -4,4 1,-1 m 5,-5 1,-1 m -10,10 1,-1 m -4,4 1,-1"
+ sodipodi:nodetypes="cccccccccc" />
+ </g>
<path
- sodipodi:nodetypes="cccccccccc"
- d="m 99.6375,267.92 1,-1 m -4,4 1,-1 m 5,-5 1,-1 m -10,10 1,-1 m -4,4 1,-1"
- style="fill:none;stroke:#ffefaf;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path42281"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ id="path42595"
+ d="M 69.435939,276.52168 71.5,274.5"
+ style="stroke-width:1px" />
</g>
- <path
- style="stroke-width:1px"
- d="M 69.435939,276.52168 71.5,274.5"
- id="path42595"
- inkscape:connector-curvature="0" />
<g
- id="g38699"
+ id="ICON_WORLD"
transform="translate(41.834175,191.41501)">
<rect
y="364.58499"
@@ -67710,7 +68170,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -67730,9 +68190,9 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" />
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -67766,7 +68226,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -67782,12 +68242,12 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" />
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
</g>
</g>
<g
transform="translate(179.00003,444.99999)"
- id="g37955"
+ id="ICON_LOGIC"
style="display:inline">
<rect
y="90"
@@ -67888,7 +68348,7 @@
sodipodi:cy="325"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="m 287.5,325 c 0,0.82843 -0.67157,1.5 -1.5,1.5 -0.82843,0 -1.5,-0.67157 -1.5,-1.5 0,-0.82843 0.67157,-1.5 1.5,-1.5 0.82843,0 1.5,0.67157 1.5,1.5 z"
+ d="m 287.5,325 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
transform="matrix(1.6666708,0,0,1.6666633,-190.66784,-215.66559)" />
<rect
y="328.49997"
@@ -67906,7 +68366,7 @@
y="328.49997" />
<path
transform="matrix(1.333351,0,0,1.333345,-95.338377,-107.33714)"
- d="m 287.5,325 c 0,0.82843 -0.67157,1.5 -1.5,1.5 -0.82843,0 -1.5,-0.67157 -1.5,-1.5 0,-0.82843 0.67157,-1.5 1.5,-1.5 0.82843,0 1.5,0.67157 1.5,1.5 z"
+ d="m 287.5,325 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
sodipodi:ry="1.5"
sodipodi:rx="1.5"
sodipodi:cy="325"
@@ -67960,27 +68420,9 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect38023"
- width="16"
- height="16"
- x="233.39999"
- y="113.08"
- rx="0"
- ry="0" />
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect38847"
- width="16"
- height="16"
- x="190"
- y="94.362419"
- rx="0"
- ry="0" />
<g
style="display:inline;enable-background:new"
- id="g43388-8"
+ id="ICON_RNA"
transform="translate(588,446)">
<rect
y="26"
@@ -68057,7 +68499,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(273,441)"
- id="g40240">
+ id="ICON_GREASEPENCIL">
<path
id="path40242"
style="fill:#89a02c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -68145,7 +68587,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g40603-2"
+ id="ICON_RENDER_ANIMATION"
transform="translate(238,594)">
<rect
y="-122"
@@ -68295,7 +68737,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
transform="translate(56,-67)"
- id="g42945"
+ id="ICON_PREFERENCES"
style="display:inline;enable-background:new">
<rect
y="602"
@@ -68385,89 +68827,87 @@
</g>
</g>
<g
- style="display:inline"
- id="g29389"
- transform="translate(-167,402.00001)">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect29391"
- width="16"
- height="16"
- x="382"
- y="217" />
+ id="ICON_DISCLOSURE_TRI_DOWN">
<g
- style="opacity:0.8;display:inline"
- transform="matrix(0.6184922,0,0,0.6183145,308.52384,72.984237)"
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- id="g29393">
+ transform="translate(-167,402.00001)"
+ id="g29389"
+ style="display:inline">
+ <rect
+ y="217"
+ x="382"
+ height="16"
+ width="16"
+ id="rect29391"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- inkscape:export-ydpi="90"
+ id="g29393"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- transform="matrix(0.927848,0,0,0.916217,-28.19594,40.73172)"
- id="g29395"
- style="display:inline">
- <path
- transform="matrix(0.872933,0,0,0.883992,56.29135,118.6984)"
- sodipodi:type="arc"
- style="fill:url(#linearGradient29407);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.99653149;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="path29397"
- sodipodi:cx="132"
- sodipodi:cy="118"
- sodipodi:rx="8"
- sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ inkscape:export-ydpi="90"
+ transform="matrix(0.6184922,0,0,0.6183145,308.52384,72.984237)"
+ style="opacity:0.8;display:inline">
+ <g
+ style="display:inline"
+ id="g29395"
+ transform="matrix(0.927848,0,0,0.916217,-28.19594,40.73172)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- </g>
- <path
- sodipodi:nodetypes="cc"
- id="path29399"
- style="fill:none;stroke:url(#linearGradient29409);stroke-width:4.85120249;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
- d="m 134.19651,245.03757 -6.46038,0"
- inkscape:connector-curvature="0" />
- <g
- style="fill:none;stroke:url(#linearGradient29413);stroke-width:1.90771151;stroke-opacity:1;display:inline"
- id="g29401"
- transform="matrix(0.784039,0,0,0.779055,-3.508124,71.29625)"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
+ inkscape:export-ydpi="90">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ sodipodi:ry="8"
+ sodipodi:rx="8"
+ sodipodi:cy="118"
+ sodipodi:cx="132"
+ id="path29397"
+ style="fill:url(#linearGradient29407);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.99653149;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc"
+ transform="matrix(0.872933,0,0,0.883992,56.29135,118.6984)" />
+ </g>
<path
+ inkscape:connector-curvature="0"
+ d="m 134.19651,245.03757 -6.46038,0"
+ style="fill:none;stroke:url(#linearGradient29409);stroke-width:4.85120249;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ id="path29399"
+ sodipodi:nodetypes="cc" />
+ <g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
- sodipodi:ry="8"
- sodipodi:rx="8"
- sodipodi:cy="118"
- sodipodi:cx="132"
- id="path29403"
- style="fill:none;stroke:url(#linearGradient29411);stroke-width:2.48091555;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- sodipodi:type="arc"
- transform="matrix(0.8313677,0,0,0.8366298,61.774434,124.29322)" />
+ transform="matrix(0.784039,0,0,0.779055,-3.508124,71.29625)"
+ id="g29401"
+ style="fill:none;stroke:url(#linearGradient29413);stroke-width:1.90771151;stroke-opacity:1;display:inline">
+ <path
+ transform="matrix(0.8313677,0,0,0.8366298,61.774434,124.29322)"
+ sodipodi:type="arc"
+ style="fill:none;stroke:url(#linearGradient29411);stroke-width:2.48091555;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path29403"
+ sodipodi:cx="132"
+ sodipodi:cy="118"
+ sodipodi:rx="8"
+ sodipodi:ry="8"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path29405"
+ style="fill:none;stroke:#000000;stroke-width:2.42560124;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 133.78064,245.05849 -5.65893,0"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
</g>
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- sodipodi:nodetypes="cc"
- d="m 133.78064,245.05849 -5.65893,0"
- style="fill:none;stroke:#000000;stroke-width:2.42560124;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path29405"
- inkscape:connector-curvature="0" />
</g>
- </g>
- <g
- transform="translate(-167,402.00001)"
- id="g41246"
- style="display:inline">
<rect
- y="217"
- x="382"
+ y="619"
+ x="215"
height="16"
width="16"
id="rect41249"
@@ -68477,7 +68917,7 @@
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
- transform="matrix(0.6184922,0,0,0.6183145,308.52384,72.984237)"
+ transform="matrix(0.6184922,0,0,0.6183145,141.52384,474.98425)"
style="opacity:0.8;display:inline">
<g
style="display:inline"
@@ -68490,19 +68930,19 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
sodipodi:cx="132"
id="path41255"
- style="fill:url(#linearGradient41266);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.99653149;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ style="fill:url(#linearGradient18663);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.99653149;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc"
transform="matrix(0.872933,0,0,0.883992,56.29135,118.6984)" />
</g>
<path
d="m 134.19651,245.03757 -6.46038,0"
- style="fill:none;stroke:url(#linearGradient41268);stroke-width:4.85120249;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
+ style="fill:none;stroke:url(#linearGradient18665);stroke-width:4.85120249;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
id="path41257"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
@@ -68512,17 +68952,17 @@
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
transform="matrix(0.784039,0,0,0.779055,-3.508124,71.29625)"
id="g41260"
- style="fill:none;stroke:url(#linearGradient41272);stroke-width:1.90771151;stroke-opacity:1;display:inline">
+ style="fill:none;stroke:url(#linearGradient18669);stroke-width:1.90771151;stroke-opacity:1;display:inline">
<path
transform="matrix(0.8313677,0,0,0.8366298,61.774434,124.29322)"
sodipodi:type="arc"
- style="fill:none;stroke:url(#linearGradient41270);stroke-width:2.48091555;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ style="fill:none;stroke:url(#linearGradient18667);stroke-width:2.48091555;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path41262"
sodipodi:cx="132"
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -68539,7 +68979,7 @@
</g>
</g>
<g
- id="g40887">
+ id="ICON_RENDER_STILL">
<g
id="g40668">
<rect
@@ -68782,34 +69222,8 @@
</g>
</g>
<g
- transform="translate(259,168)"
- mask="url(#mask38561)"
- id="g40090" />
- <rect
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g22298.png"
- transform="scale(-1,1)"
- style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect40274"
- width="16"
- height="16"
- x="-252"
- y="514" />
- <rect
- y="514"
- x="-272"
- height="16"
- width="16"
- id="rect41293"
- style="opacity:0;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="scale(-1,1)"
- inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\RELEASES\g22298.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <g
transform="translate(1,0)"
- id="g36512">
+ id="ICON_RENDER_RESULT">
<rect
style="opacity:0.01000001;fill:#2affd5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect36514"
@@ -68872,7 +69286,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -68892,7 +69306,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -68905,7 +69319,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -68919,7 +69333,7 @@
id="g36537">
<path
transform="matrix(1.1428645,0,0,1.1428645,-416.36057,256.4986)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -68935,7 +69349,7 @@
sodipodi:cy="192.5"
sodipodi:rx="1.75"
sodipodi:ry="1.75"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
transform="matrix(0.5714297,0,0,0.5714297,-150.92912,366.49979)" />
<rect
y="476"
@@ -68956,7 +69370,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -68968,17 +69382,8 @@
</g>
</g>
<g
- transform="translate(-810.9,-131)"
- id="g40730"
- style="display:inline;enable-background:new">
- <g
- id="g40736"
- transform="translate(583.99999,91.500124)"
- style="display:inline;enable-background:new" />
- </g>
- <g
style="display:inline;enable-background:new"
- id="g39239"
+ id="ICON_FILE_BLANK"
transform="translate(-369,-131)">
<path
inkscape:export-ydpi="90"
@@ -69027,7 +69432,7 @@
</g>
<g
transform="translate(-705,268)"
- id="g36639"
+ id="ICON_FILE"
style="display:inline;enable-background:new">
<path
style="fill:url(#linearGradient36657);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
@@ -69075,7 +69480,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g37112"
+ id="ICON_GHOST_DISABLED"
transform="translate(-42,0)">
<g
transform="matrix(-1,0,0,1,887,548.02778)"
@@ -69179,7 +69584,7 @@
</g>
<g
transform="translate(87.000001,33.999969)"
- id="g37053"
+ id="ICON_RENDERLAYERS"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\render layers 2.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -69236,7 +69641,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(0.5714297,0,0,0.5714297,-362.92909,351.49978)"
- d="m 466.25,192.5 c 0,0.9665 -0.7835,1.75 -1.75,1.75 -0.9665,0 -1.75,-0.7835 -1.75,-1.75 0,-0.9665 0.7835,-1.75 1.75,-1.75 0.9665,0 1.75,0.7835 1.75,1.75 z"
+ d="m 466.25,192.5 a 1.75,1.75 0 1 1 -3.5,0 1.75,1.75 0 1 1 3.5,0 z"
sodipodi:ry="1.75"
sodipodi:rx="1.75"
sodipodi:cy="192.5"
@@ -69291,7 +69696,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -69313,7 +69718,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -69321,7 +69726,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -69334,7 +69739,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g37514"
+ id="ICON_FILE_IMAGE"
transform="translate(-327.01257,-130.96121)">
<path
inkscape:export-ydpi="90"
@@ -69455,7 +69860,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g37514-4"
+ id="ICON_IMAGE_DATA"
transform="translate(-726.01257,268.03879)">
<path
inkscape:export-ydpi="90"
@@ -69576,7 +69981,7 @@
</g>
<g
transform="translate(-167.99999,190.99999)"
- id="g71820">
+ id="ICON_TEXTURE">
<rect
y="365"
x="215"
@@ -69617,145 +70022,148 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- y="493"
- x="488.00015"
- height="16"
- width="16"
- id="rect37119"
- style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="ccccccc"
- id="path37123"
- d="m 490.00015,501 7,-3 6,2.5 0,3.74998 -6.99999,3.74999 -6.00001,-3.24999 0,-3.74998 z"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#2a2512;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
- <path
- id="path37125"
- d="m 490.00015,501 6,-2.5 6,2.5 0,0.5 -6,3 -6,-2.93442 0,-0.56558 z"
- style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none"
- sodipodi:nodetypes="ccccccc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccc"
- id="path37127"
- d="m 497.00015,501.25 0,-3.24998 -6.5,2.74998 3.5,1.75 3,-1.25 z"
- style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 497.00015,501.24998 0,-3.24998 5.5,2.24998 -3.5,1.75 -2,-0.75 z"
- id="path37129"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccc"
- id="path37131"
- d="m 502.50015,500.5 -5.5,-2.25 -6.5,2.75"
- style="fill:none;stroke:url(#linearGradient37201);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- inkscape:connector-curvature="0" />
<g
- style="display:inline;enable-background:new"
- id="g39239-1"
- transform="translate(-260.99985,289)">
+ id="ICON_PACKAGE">
+ <rect
+ style="opacity:0;fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37119"
+ width="16"
+ height="16"
+ x="488.00015"
+ y="493" />
<path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#2a2512;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 490.00015,501 7,-3 6,2.5 0,3.74998 -6.99999,3.74999 -6.00001,-3.24999 0,-3.74998 z"
+ id="path37123"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ inkscape:connector-curvature="0"
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- sodipodi:nodetypes="cccccc"
- id="path39241-6"
- d="m 756.16666,204.50001 6.33334,-1e-5 0,11.24999 -9,1e-5 -10e-6,-8.24999 2.66667,-3 z"
- style="fill:url(#linearGradient37317);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
- inkscape:connector-curvature="0" />
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="ccccccc"
+ style="fill:#999999;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 490.00015,501 6,-2.5 6,2.5 0,0.5 -6,3 -6,-2.93442 0,-0.56558 z"
+ id="path37125" />
<path
- style="opacity:0.3;fill:url(#radialGradient37319);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="M 756.16666,204.50001 762.5,204.75 l 0,10.75 -9,0 -10e-6,-7.99999 2.66667,-3 z"
- id="path39243-8"
- sodipodi:nodetypes="cccccc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
+ inkscape:connector-curvature="0"
inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 497.00015,501.25 0,-3.24998 -6.5,2.74998 3.5,1.75 3,-1.25 z"
+ id="path37127"
+ sodipodi:nodetypes="ccccc" />
<path
- sodipodi:nodetypes="cccc"
- d="m 754.5,209 0,5.5 m 3.5,-9 3.5,0"
- style="fill:none;stroke:url(#linearGradient37321);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
- id="path39245-5"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc"
+ id="path37129"
+ d="m 497.00015,501.24998 0,-3.24998 5.5,2.24998 -3.5,1.75 -2,-0.75 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
<path
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
- d="m 753,208 4,0 0,-4 -4,4 z"
- id="path39247-7"
- sodipodi:nodetypes="cccc"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient37201);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 502.50015,500.5 -5.5,-2.25 -6.5,2.75"
+ id="path37131"
+ sodipodi:nodetypes="ccc" />
+ <g
+ transform="translate(-260.99985,289)"
+ id="g39239-1"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient37317);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 756.16666,204.50001 6.33334,-1e-5 0,11.24999 -9,1e-5 -10e-6,-8.24999 2.66667,-3 z"
+ id="path39241-6"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path39243-8"
+ d="M 756.16666,204.50001 762.5,204.75 l 0,10.75 -9,0 -10e-6,-7.99999 2.66667,-3 z"
+ style="opacity:0.3;fill:url(#radialGradient37319);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path39245-5"
+ style="fill:none;stroke:url(#linearGradient37321);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 754.5,209 0,5.5 m 3.5,-9 3.5,0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path39247-7"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path39249-6"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 753.5,207.00001 0,8.49999 9,0 0,-11 -6.5,1e-5 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient37323);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 757.5,206.5 0,2 -2,0"
+ id="path39251-1" />
+ </g>
<path
+ inkscape:connector-curvature="0"
+ style="opacity:0.7;fill:url(#linearGradient37338);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 493.00015,494 7.99985,0 0,11 -7.99981,0 -4e-5,-11 0,0 0,0 0,0 z"
+ id="path37141"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- d="m 753.5,207.00001 0,8.49999 9,0 0,-11 -6.5,1e-5 -2.5,2.5 z"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path39249-6"
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0" />
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ id="path37143"
+ d="m 490.00016,504.74998 -10e-6,-3.24998 6,3 0.01,3.49883 -6.00995,-3.24885 -4e-5,0 z"
+ style="fill:#c6b77c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc" />
<path
- id="path39251-1"
- d="m 757.5,206.5 0,2 -2,0"
- style="fill:none;stroke:url(#linearGradient37323);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:#595235;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 503.00015,504.25 0,-3.24998 -7,3.49998 c 0,2.58362 0,2.93288 0,3.49998 l 7,-3.74998 z"
+ id="path37145"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.96000001;fill:none;stroke:url(#linearGradient37191);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 490.50015,501.5 0,2.99998 5.5,3 6.5,-3.49998 0,-2.99998"
+ id="path37147"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path37149"
+ d="m 490.50015,501.5 5.5,3 6.5,-3.5"
+ style="fill:none;stroke:url(#linearGradient37188);stroke-width:1.14999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 491.5,500.75 4.5,2.5 5.5,-3"
+ id="path38348"
+ sodipodi:nodetypes="ccc" />
</g>
- <path
- sodipodi:nodetypes="ccccc"
- id="path37141"
- d="m 493.00015,494 7.99985,0 0,11 -7.99981,0 -4e-5,-11 0,0 0,0 0,0 z"
- style="opacity:0.7;fill:url(#linearGradient37338);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccc"
- style="fill:#c6b77c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 490.00016,504.74998 -10e-6,-3.24998 6,3 0.01,3.49883 -6.00995,-3.24885 -4e-5,0 z"
- id="path37143"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccc"
- id="path37145"
- d="m 503.00015,504.25 0,-3.24998 -7,3.49998 c 0,2.58362 0,2.93288 0,3.49998 l 7,-3.74998 z"
- style="fill:#595235;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccc"
- id="path37147"
- d="m 490.50015,501.5 0,2.99998 5.5,3 6.5,-3.49998 0,-2.99998"
- style="opacity:0.96000001;fill:none;stroke:url(#linearGradient37191);stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:url(#linearGradient37188);stroke-width:1.14999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 490.50015,501.5 5.5,3 6.5,-3.5"
- id="path37149"
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccc"
- id="path38348"
- d="m 491.5,500.75 4.5,2.5 5.5,-3"
- style="opacity:0.25;fill:none;stroke:#000000;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:connector-curvature="0" />
<g
- id="g38317"
+ id="ICON_IMAGE_COL"
transform="translate(131,-30)">
<g
transform="translate(-45.97248,412)"
@@ -69864,7 +70272,7 @@
id="g38358" />
</g>
<g
- id="g38738"
+ id="ICON_RNA_ADD"
transform="translate(41.000016,-2e-5)">
<rect
y="472"
@@ -69987,7 +70395,7 @@
</g>
</g>
<g
- id="g28606">
+ id="ICON_SEQUENCE">
<rect
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
@@ -70102,332 +70510,335 @@
style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
- style="display:inline;enable-background:new"
- id="g37741"
- transform="translate(197.70204,-38.325069)">
+ id="ICON_STICKY_UVS_VERT">
<g
- id="g37905"
- transform="translate(0.999999,1.000006)">
- <g
- id="g37699"
- transform="translate(-40.718137,21.311275)"
- style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
- <rect
- y="181.01379"
- x="166.0161"
- height="1"
- width="1"
- id="rect37701"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37703"
- width="0.99999899"
- height="1"
- x="170.0161"
- y="177.01379" />
- <rect
- y="177.01379"
- x="168.0161"
- height="1"
- width="1"
- id="rect37705"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37707"
- width="1"
- height="1"
- x="166.0161"
- y="177.01379" />
- <rect
- y="179.01379"
- x="166.0161"
- height="1"
- width="1"
- id="rect37709"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- y="177.01379"
- x="174.0161"
- height="1"
- width="0.99999899"
- id="rect37869"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37871"
- width="1"
- height="1"
- x="172.0161"
- y="177.01379" />
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37873"
- width="1"
- height="1"
- x="166.0161"
- y="185.01379" />
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37875"
- width="1"
- height="1"
- x="166.0161"
- y="183.01379" />
- </g>
- <g
- transform="translate(-40.702034,21.325063)"
- id="g37711"
- style="fill:#000000">
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect37713"
- width="1"
- height="1"
- x="166.00002"
- y="178.00002" />
- <rect
- y="180.00002"
- x="166.00002"
- height="1"
- width="1"
- id="rect37715"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect37717"
- width="1"
- height="1"
- x="167.00002"
- y="177.00002" />
- <rect
- y="177.00002"
- x="169.00002"
- height="1"
- width="1"
- id="rect37719"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect37725"
- width="1"
- height="1"
- x="171.00002"
- y="177.00002" />
- <rect
- y="182.00002"
- x="166.00002"
- height="1"
- width="1"
- id="rect37727"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect37865"
- width="1"
- height="1"
- x="173"
- y="177.00002" />
- <rect
- y="177.00002"
- x="175"
- height="1"
- width="1"
- id="rect37867"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect37877"
- width="1"
- height="1"
- x="166"
- y="184" />
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect37879"
- width="1"
- height="1"
- x="166"
- y="186" />
- </g>
- </g>
- <path
- id="path37737"
- d="m 127.79796,207.82507 4e-5,-7.01372 6.99956,0.009 4e-4,0.0507 -4e-4,6.95427 -6.9996,0 0,-2.5e-4 z"
- style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0" />
- <g
- id="g37928"
- transform="matrix(-1,0,0,-1,260.59592,405.65013)">
+ transform="translate(197.70204,-38.325069)"
+ id="g37741"
+ style="display:inline;enable-background:new">
<g
- transform="translate(-39.718138,21.311267)"
- id="g37930"
- style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37932"
- width="1"
- height="1"
- x="166.0161"
- y="181.01379" />
- <rect
- y="177.01379"
- x="170.0161"
- height="1"
- width="0.99999899"
- id="rect37934"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37936"
- width="1"
- height="1"
- x="168.0161"
- y="177.01379" />
- <rect
- y="177.01379"
- x="166.0161"
- height="1"
- width="1"
- id="rect37938"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37941"
- width="1"
- height="1"
- x="166.0161"
- y="179.01379" />
- <rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37943"
- width="0.99999899"
- height="1"
- x="174.0161"
- y="177.01379" />
- <rect
- y="177.01379"
- x="172.0161"
- height="1"
- width="1"
- id="rect37945"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- y="185.01379"
- x="166.0161"
- height="1"
- width="1"
- id="rect37947"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- y="183.01379"
- x="166.0161"
- height="1"
- width="1"
- id="rect37949"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ transform="translate(0.999999,1.000006)"
+ id="g37905">
+ <g
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="translate(-40.718137,21.311275)"
+ id="g37699">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37701"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="181.01379" />
+ <rect
+ y="177.01379"
+ x="170.0161"
+ height="1"
+ width="0.99999899"
+ id="rect37703"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37705"
+ width="1"
+ height="1"
+ x="168.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect37707"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37709"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="179.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37869"
+ width="0.99999899"
+ height="1"
+ x="174.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="172.0161"
+ height="1"
+ width="1"
+ id="rect37871"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="185.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect37873"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="183.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect37875"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ style="fill:#000000"
+ id="g37711"
+ transform="translate(-40.702034,21.325063)">
+ <rect
+ y="178.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect37713"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37715"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="180.00002" />
+ <rect
+ y="177.00002"
+ x="167.00002"
+ height="1"
+ width="1"
+ id="rect37717"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37719"
+ width="1"
+ height="1"
+ x="169.00002"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="171.00002"
+ height="1"
+ width="1"
+ id="rect37725"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37727"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="182.00002" />
+ <rect
+ y="177.00002"
+ x="173"
+ height="1"
+ width="1"
+ id="rect37865"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37867"
+ width="1"
+ height="1"
+ x="175"
+ y="177.00002" />
+ <rect
+ y="184"
+ x="166"
+ height="1"
+ width="1"
+ id="rect37877"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ y="186"
+ x="166"
+ height="1"
+ width="1"
+ id="rect37879"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
</g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 127.79796,207.82507 4e-5,-7.01372 6.99956,0.009 4e-4,0.0507 -4e-4,6.95427 -6.9996,0 0,-2.5e-4 z"
+ id="path37737" />
<g
- style="fill:#000000"
- id="g37951"
- transform="translate(-39.702035,21.325055)">
- <rect
- y="178.00002"
- x="166.00002"
- height="1"
- width="1"
- id="rect37953"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect37955"
- width="1"
- height="1"
- x="166.00002"
- y="180.00002" />
- <rect
- y="177.00002"
- x="167.00002"
- height="1"
- width="1"
- id="rect37958"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect37960"
- width="1"
- height="1"
- x="169.00002"
- y="177.00002" />
- <rect
- y="177.00002"
- x="171.00002"
- height="1"
- width="1"
- id="rect37962"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect37964"
- width="1"
- height="1"
- x="166.00002"
- y="182.00002" />
- <rect
- y="177.00002"
- x="173"
- height="1"
- width="1"
- id="rect37966"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect37968"
- width="1"
- height="1"
- x="175"
- y="177.00002" />
- <rect
- y="184"
- x="166"
- height="1"
- width="1"
- id="rect37970"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- <rect
- y="186"
- x="166"
- height="1"
- width="1"
- id="rect37972"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ transform="matrix(-1,0,0,-1,260.59592,405.65013)"
+ id="g37928">
+ <g
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="g37930"
+ transform="translate(-39.718138,21.311267)">
+ <rect
+ y="181.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect37932"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37934"
+ width="0.99999899"
+ height="1"
+ x="170.0161"
+ y="177.01379" />
+ <rect
+ y="177.01379"
+ x="168.0161"
+ height="1"
+ width="1"
+ id="rect37936"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37938"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="177.01379" />
+ <rect
+ y="179.01379"
+ x="166.0161"
+ height="1"
+ width="1"
+ id="rect37941"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="177.01379"
+ x="174.0161"
+ height="1"
+ width="0.99999899"
+ id="rect37943"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37945"
+ width="1"
+ height="1"
+ x="172.0161"
+ y="177.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37947"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="185.01379" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37949"
+ width="1"
+ height="1"
+ x="166.0161"
+ y="183.01379" />
+ </g>
+ <g
+ transform="translate(-39.702035,21.325055)"
+ id="g37951"
+ style="fill:#000000">
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37953"
+ width="1"
+ height="1"
+ x="166.00002"
+ y="178.00002" />
+ <rect
+ y="180.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect37955"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37958"
+ width="1"
+ height="1"
+ x="167.00002"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="169.00002"
+ height="1"
+ width="1"
+ id="rect37960"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37962"
+ width="1"
+ height="1"
+ x="171.00002"
+ y="177.00002" />
+ <rect
+ y="182.00002"
+ x="166.00002"
+ height="1"
+ width="1"
+ id="rect37964"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37966"
+ width="1"
+ height="1"
+ x="173"
+ y="177.00002" />
+ <rect
+ y="177.00002"
+ x="175"
+ height="1"
+ width="1"
+ id="rect37968"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37970"
+ width="1"
+ height="1"
+ x="166"
+ y="184" />
+ <rect
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="rect37972"
+ width="1"
+ height="1"
+ x="166"
+ y="186" />
+ </g>
</g>
</g>
+ <rect
+ rx="0"
+ ry="0"
+ y="-161.5"
+ x="331.50012"
+ height="3"
+ width="2.9998772"
+ id="rect37338"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(-1,1)"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37368"
+ width="2.9998772"
+ height="3"
+ x="-324.49988"
+ y="168.5"
+ ry="0"
+ rx="0" />
</g>
- <rect
- transform="scale(1,-1)"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37338"
- width="2.9998772"
- height="3"
- x="331.50012"
- y="-161.5"
- ry="0"
- rx="0" />
- <rect
- rx="0"
- ry="0"
- y="168.5"
- x="-324.49988"
- height="3"
- width="2.9998772"
- id="rect37368"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- transform="scale(-1,1)" />
- <g
- id="g38402"
+ <g
+ id="ICON_STICKY_UVS_LOC"
transform="translate(-21,0)">
<g
style="display:inline;enable-background:new"
@@ -70833,7 +71244,7 @@
rx="0" />
</g>
<g
- id="g38397"
+ id="ICON_STICKY_UVS_DISABLE"
transform="translate(20.999878,0)">
<rect
rx="0"
@@ -70864,7 +71275,7 @@
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
- id="g38011"
+ id="ICON_UV_SYNC_SELECT"
transform="translate(436,-380)">
<rect
y="516"
@@ -71112,7 +71523,7 @@
</g>
</g>
<g
- id="g37508"
+ id="ICON_SHAPEKEY_DATA"
transform="translate(525,27.999998)">
<g
style="opacity:0.7"
@@ -71231,7 +71642,7 @@
</g>
<path
transform="matrix(1.99999,0,0,1.99999,571.48293,-823.49525)"
- d="m -92,477.5 c 0,0.27614 -0.223858,0.5 -0.5,0.5 -0.276142,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.223858,-0.5 0.5,-0.5 0.276142,0 0.5,0.22386 0.5,0.5 z"
+ d="m -92,477.5 a 0.5,0.5 0 1 1 -1,0 0.5,0.5 0 1 1 1,0 z"
sodipodi:ry="0.5"
sodipodi:rx="0.5"
sodipodi:cy="477.5"
@@ -71243,7 +71654,7 @@
</g>
</g>
<g
- id="g37565">
+ id="ICON_ROTATE">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
@@ -71260,7 +71671,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -71269,7 +71680,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71335,58 +71746,160 @@
inkscape:connector-curvature="0" />
</g>
<g
- transform="translate(41.928411,-437)"
- id="g37575">
- <rect
- y="617"
- x="173"
- height="16"
- width="16"
- id="rect37577"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ id="ICON_ALIGN">
<g
- transform="translate(-290,397)"
- id="g37579"
- style="display:inline">
+ transform="translate(0,2)"
+ id="g21663">
+ <rect
+ y="176"
+ x="215"
+ height="16"
+ width="16"
+ id="rect21661"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- id="g37582">
+ style="display:inline"
+ id="g21392"
+ transform="translate(-87.98837,-19.85)">
<g
- transform="translate(20.029029,0)"
- style="opacity:0.85"
- id="g37584">
- <path
- d="m 447.72097,225.25 -3.25,3.25 3.25,3.25 m 6.5,-6.5 3.25,3.25 -3.25,3.25"
- style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path37586"
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0" />
- <path
- id="path37588"
- d="m 444.54256,228.5 11.66489,0 0,0"
- style="fill:none;stroke:#000000;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:connector-curvature="0" />
+ transform="translate(-62.011627,236.84995)"
+ style="opacity:0.05"
+ id="g11189">
+ <rect
+ rx="1.375"
+ ry="1.375"
+ y="-39.5"
+ x="366.5"
+ height="3"
+ width="2.9998775"
+ id="rect11191"
+ style="fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ rx="1.375"
+ style="fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect11193"
+ width="2.9998775"
+ height="3"
+ x="371.5"
+ y="-39.5"
+ ry="1.375" />
+ <rect
+ rx="1.375"
+ ry="1.375"
+ y="-39.5"
+ x="376.5"
+ height="3"
+ width="2.9998775"
+ id="rect11195"
+ style="fill:none;stroke:#447cce;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
+ <rect
+ rx="1.375"
+ ry="1.375"
+ y="197.34995"
+ x="304.48837"
+ height="3"
+ width="2.9998775"
+ id="rect11197"
+ style="fill:none;stroke:#22467e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#c3dbff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 304.98827,197.84994 c 0.6667,0 1.3334,1e-5 2.0001,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.6667,0 -1.3334,-1e-5 -2.0001,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ id="path11199"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ rx="1.375"
+ style="fill:none;stroke:#22467e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect11201"
+ width="2.9998775"
+ height="3"
+ x="309.48837"
+ y="197.34995"
+ ry="1.375" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ id="path11203"
+ d="m 309.98827,197.84994 c 0.6667,0 1.3334,1e-5 2.0001,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.6667,0 -1.3334,-1e-5 -2.0001,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ style="fill:#c3dbff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ rx="1.375"
+ ry="1.375"
+ y="197.34995"
+ x="314.48837"
+ height="3"
+ width="2.9998775"
+ id="rect11205"
+ style="fill:none;stroke:#22467e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#c3dbff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+ d="m 314.98827,197.84994 c 0.6667,0 1.3334,1e-5 2.0001,1e-5 0,0.66668 0,1.33337 0,2.00005 -0.6667,0 -1.3334,-1e-5 -2.0001,-1e-5 0,-0.66668 0,-1.33337 0,-2.00005 z"
+ id="path11207"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <g
+ id="g37575"
+ transform="translate(41.928411,-437)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect37577"
+ width="16"
+ height="16"
+ x="173"
+ y="617" />
+ <g
+ style="display:inline"
+ id="g37579"
+ transform="translate(-290,397)">
<g
- transform="translate(20.029029,0)"
- id="g37591">
- <path
- sodipodi:nodetypes="cc"
- style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- d="m 444.47097,228.5 13,0"
- id="path37593"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccccc"
- id="path37606"
- style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 447.72097,225.25 -3.25,3.25 3.25,3.25 m 6.5,-6.5 3.25,3.25 -3.25,3.25"
- inkscape:connector-curvature="0" />
+ id="g37582">
+ <g
+ id="g37584"
+ style="opacity:0.85"
+ transform="translate(20.029029,0)">
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path37586"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 447.72097,225.25 -3.25,3.25 3.25,3.25 m 6.5,-6.5 3.25,3.25 -3.25,3.25" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:2.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:12.66808051;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 444.54256,228.5 11.66489,0 0,0"
+ id="path37588" />
+ </g>
+ <g
+ id="g37591"
+ transform="translate(20.029029,0)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path37593"
+ d="m 444.47097,228.5 13,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 447.72097,225.25 -3.25,3.25 3.25,3.25 m 6.5,-6.5 3.25,3.25 -3.25,3.25"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path37606"
+ sodipodi:nodetypes="cccccc" />
+ </g>
</g>
</g>
</g>
</g>
<g
- id="g37577"
+ id="ICON_BBOX"
transform="translate(-105,-63)">
<g
style="opacity:0.8;display:inline;enable-background:new"
@@ -71399,7 +71912,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71416,14 +71929,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
<path
transform="matrix(0.5705005,0,0,0.5705012,53.193935,156.18087)"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71457,7 +71970,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g14409"
+ id="ICON_SOLID"
transform="translate(4.7892764e-7,23)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -71477,7 +71990,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71494,7 +72007,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -71503,7 +72016,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71516,7 +72029,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g14396"
+ id="ICON_SMOOTH"
transform="translate(4.7892764e-7,23)">
<rect
y="92"
@@ -71536,7 +72049,7 @@
transform="matrix(0.928617,0,0,0.931035,10.2435,15.47372)"
id="g15313">
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71553,7 +72066,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71569,7 +72082,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -71578,7 +72091,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71604,7 +72117,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g37996"
+ id="ICON_POTATO"
transform="translate(113.00001,1)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -71614,7 +72127,7 @@
x="-24.00001"
y="114" />
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71643,12 +72156,12 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" />
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
<path
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71666,7 +72179,7 @@
</g>
<g
transform="translate(4.7892764e-7,23)"
- id="g38272"
+ id="ICON_WIRE"
style="display:inline;enable-background:new">
<g
id="g37676">
@@ -71682,7 +72195,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71701,7 +72214,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
transform="matrix(0.8125001,0,0,0.8125002,-73.250026,4.1249738)" />
<path
inkscape:export-ydpi="90"
@@ -71714,7 +72227,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="10.07671"
- d="m 140,118 c 0,5.56521 -3.58172,10.07671 -8,10.07671 -4.37076,0 -7.9325,-4.4185 -7.99907,-9.92322"
+ d="m 140,118 a 8,10.07671 0 0 1 -15.99907,0.15349"
sodipodi:start="0"
sodipodi:end="3.12636"
transform="matrix(0.8077059,0,0,-0.2072667,-72.578821,124.6156)"
@@ -71724,7 +72237,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71741,7 +72254,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.37076,0 -7.9325,-3.50789 -7.99907,-7.87814"
+ d="m 140,118 a 8,8 0 0 1 -15.99907,0.12186"
sodipodi:start="0"
sodipodi:end="3.12636"
sodipodi:open="true"
@@ -71759,7 +72272,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
transform="matrix(0.6875009,0,0,0.687501,-56.75013,18.874887)" />
<path
inkscape:export-ydpi="90"
@@ -71772,14 +72285,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.38113,0 7.94728,3.52395 7.99943,7.90477"
+ d="m 140,118 a 8,8 0 1 1 -5.7e-4,-0.0952"
sodipodi:start="0"
sodipodi:end="6.2712816"
sodipodi:open="true"
transform="matrix(0,0.7811136,-0.34375,0,74.562502,-3.1287373)" />
<path
transform="matrix(0.9374995,0,0,0.9374996,-89.749939,-10.62495)"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -71793,7 +72306,7 @@
</g>
</g>
<g
- id="g39510"
+ id="ICON_CANCEL"
transform="translate(-570,274)">
<path
sodipodi:nodetypes="ccccccccc"
@@ -71831,7 +72344,7 @@
</g>
</g>
<g
- id="g40247"
+ id="ICON_OBJECT_DATA"
transform="translate(63,-21.000002)">
<rect
style="opacity:0;fill:#f6d0a6;fill-opacity:1;fill-rule:evenodd;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -71907,7 +72420,7 @@
</g>
<g
transform="translate(508.99432,90)"
- id="g38556">
+ id="ICON_UV_FACESEL">
<rect
transform="matrix(0,1,1,0,0,0)"
style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.0999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -72004,7 +72517,7 @@
</g>
<g
transform="translate(505.99432,90)"
- id="g38644">
+ id="ICON_UV_ISLANDSEL">
<rect
y="-185.99432"
x="46"
@@ -72090,7 +72603,7 @@
</g>
</g>
<g
- id="g39152"
+ id="ICON_UV_EDGESEL"
transform="translate(507.99432,90)">
<rect
transform="matrix(0,1,1,0,0,0)"
@@ -72265,7 +72778,7 @@
</g>
</g>
<g
- id="g29977">
+ id="ICON_UV_VERTEXSEL">
<rect
y="257"
x="136"
@@ -72422,7 +72935,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g39098"
+ id="ICON_PLUGIN"
transform="translate(42,63)">
<rect
ry="0"
@@ -72516,7 +73029,7 @@
</g>
<g
transform="translate(-105,212.00008)"
- id="g39237"
+ id="ICON_QUESTION"
style="display:inline;enable-background:new">
<g
inkscape:export-ydpi="90"
@@ -72555,7 +73068,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -72571,7 +73084,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -72600,7 +73113,7 @@
</g>
<g
transform="translate(-3.0078133e-8,128.00008)"
- id="g39694"
+ id="ICON_INFO"
style="display:inline;enable-background:new">
<g
inkscape:export-ydpi="90"
@@ -72639,7 +73152,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -72655,7 +73168,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -72706,98 +73219,149 @@
</g>
</g>
<g
- id="g40264"
- transform="translate(21,0)"
- mask="url(#mask40306)">
- <rect
- ry="0"
- style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect40266"
- width="13.016124"
- height="12.953857"
- x="195.49998"
- y="11.546152" />
- <rect
- y="12.00001"
- x="197.01611"
- height="11.046139"
- width="11.000001"
- id="rect40268"
- style="fill:url(#linearGradient40295);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- ry="0" />
+ id="ICON_IMAGE_RGB_ALPHA">
<g
- id="g40270"
- transform="translate(146.99999,-417.99999)">
+ style="opacity:0.25"
+ transform="translate(275,-385.99999)"
+ id="g17336">
+ <rect
+ y="396"
+ x="-60"
+ height="16"
+ width="16"
+ id="rect17338"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- transform="translate(-146.99999,417.99999)"
- id="g40272">
- <rect
- style="fill:#106386;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect40276"
- width="3"
- height="3"
- x="196"
- y="12" />
- <rect
- style="fill:#ba0036;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect40278"
- width="3"
- height="3"
- x="199"
- y="15" />
- <rect
- y="12"
- x="202"
- height="3"
- width="3"
- id="rect40280"
- style="fill:#9f0022;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- y="15"
- x="205"
- height="3"
- width="3"
- id="rect40282"
- style="fill:#688c7f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- y="18"
- x="196"
- height="3"
- width="3"
- id="rect40284"
- style="fill:#b77100;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- y="21"
- x="199"
- height="3"
- width="3"
- id="rect40286"
- style="fill:#a67c58;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ id="g17340">
<rect
- style="fill:#7a2537;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect40288"
- width="3"
- height="3"
- x="202"
- y="18" />
+ ry="0"
+ style="fill:url(#linearGradient32725);fill-opacity:1;fill-rule:nonzero;stroke:#333333;stroke-width:0.99999994;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17342"
+ width="13.016124"
+ height="12.953857"
+ x="-58.500015"
+ y="397.54614" />
<rect
- style="fill:#869c2b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect40290"
- width="3"
- height="3"
- x="205"
- y="21" />
+ y="398"
+ x="-56.983894"
+ height="11.046139"
+ width="11.000001"
+ id="rect17344"
+ style="fill:url(#linearGradient32727);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path17346"
+ d="m -58,398 0,2 2,0 0,-2 -2,0 z m 2,2 0,2 2,0 0,-2 -2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 2,0 0,2 2,0 0,-2 -2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 2,0 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m 0,2 0,2 2,0 0,-2 -2,0 z m 0,2 -2,0 0,2 2,0 0,-2 z m 0,2 0,2 2,0 0,-2 -2,0 z m -2,0 -2,0 0,2 2,0 0,-2 z m -2,0 0,-2 -2,0 0,2 2,0 z m -2,0 -2,0 0,2 2,0 0,-2 z m -2,0 0,-2 -2,0 0,2 2,0 z m 0,-2 2,0 0,-2 -2,0 0,2 z m 0,-2 0,-2 -2,0 0,2 2,0 z m 2,0 2,0 0,-2 -2,0 0,2 z m 2,0 0,2 2,0 0,-2 -2,0 z"
+ style="fill:url(#linearGradient32729);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:0.45;fill:none;stroke:url(#linearGradient32731);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m -46.482307,398.50001 -11.017704,0 0,11 11.017704,0 0,-11"
+ id="path17348"
+ sodipodi:nodetypes="ccc" />
</g>
</g>
<path
- style="fill:none;stroke:url(#linearGradient40297);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- d="m 207.51769,12.50001 -11.0177,0 0,11 11.0177,0 0,-11"
- id="path40292"
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0" />
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path17578"
+ d="m 217.5,24.000005 11.5,-11.5"
+ style="opacity:0.65;fill:none;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <g
+ mask="url(#mask40306)"
+ transform="translate(21,0)"
+ id="g40264">
+ <rect
+ y="11.546152"
+ x="195.49998"
+ height="12.953857"
+ width="13.016124"
+ id="rect40266"
+ style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ ry="0" />
+ <rect
+ ry="0"
+ style="fill:url(#linearGradient40295);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00207269;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40268"
+ width="11.000001"
+ height="11.046139"
+ x="197.01611"
+ y="12.00001" />
+ <g
+ transform="translate(146.99999,-417.99999)"
+ id="g40270">
+ <g
+ id="g40272"
+ transform="translate(-146.99999,417.99999)">
+ <rect
+ y="12"
+ x="196"
+ height="3"
+ width="3"
+ id="rect40276"
+ style="fill:#106386;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="15"
+ x="199"
+ height="3"
+ width="3"
+ id="rect40278"
+ style="fill:#ba0036;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:#9f0022;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40280"
+ width="3"
+ height="3"
+ x="202"
+ y="12" />
+ <rect
+ style="fill:#688c7f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40282"
+ width="3"
+ height="3"
+ x="205"
+ y="15" />
+ <rect
+ style="fill:#b77100;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40284"
+ width="3"
+ height="3"
+ x="196"
+ y="18" />
+ <rect
+ style="fill:#a67c58;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect40286"
+ width="3"
+ height="3"
+ x="199"
+ y="21" />
+ <rect
+ y="18"
+ x="202"
+ height="3"
+ width="3"
+ id="rect40288"
+ style="fill:#7a2537;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ y="21"
+ x="205"
+ height="3"
+ width="3"
+ id="rect40290"
+ style="fill:#869c2b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path40292"
+ d="m 207.51769,12.50001 -11.0177,0 0,11 11.0177,0 0,-11"
+ style="fill:none;stroke:url(#linearGradient40297);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </g>
</g>
<g
- id="g39333"
+ id="ICON_COPYDOWN"
transform="translate(0,-62.1)">
<rect
style="opacity:0.01000001;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -72940,7 +73504,7 @@
</g>
</g>
<g
- id="g39306"
+ id="ICON_PASTEDOWN"
transform="translate(-1,-62)">
<rect
y="198"
@@ -73083,7 +73647,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g40848"
+ id="ICON_LINK_AREA"
transform="translate(232,503)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -73276,7 +73840,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g40697"
+ id="ICON_URL"
transform="translate(455.99408,547.99927)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\URL link 1.png"
inkscape:export-xdpi="90"
@@ -73350,13 +73914,13 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(0.787566,0,0,0.779223,26.709197,21.3179)" />
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -73380,7 +73944,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z" />
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z" />
<path
sodipodi:nodetypes="cc"
id="path40271"
@@ -73398,7 +73962,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -73408,7 +73972,7 @@
sodipodi:type="arc"
transform="matrix(0.6429129,0,0,0.6362007,45.809534,38.194473)" />
<path
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -73424,7 +73988,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g41840"
+ id="ICON_NEW"
transform="translate(497,652)">
<rect
y="-75"
@@ -73550,7 +74114,7 @@
<g
transform="translate(378,684)"
style="display:inline;enable-background:new"
- id="g39156">
+ id="ICON_COPY_ID">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect40773"
@@ -73673,7 +74237,7 @@
</g>
</g>
<g
- id="g39528">
+ id="ICON_PASTEFLIPDOWN">
<g
clip-path="url(#clipPath40902)"
id="g40560"
@@ -73841,7 +74405,7 @@
</g>
</g>
<g
- id="g39560">
+ id="ICON_PASTEFLIPUP">
<g
clip-path="url(#clipPath40897)"
id="g40506"
@@ -74009,15 +74573,8 @@
</g>
</g>
<g
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- transform="matrix(0.5478212,-0.56064,0.5419177,0.5545983,197.19518,557.21673)"
- id="g38570"
- style="stroke-width:5.41920376;stroke-miterlimit:4;stroke-dasharray:none;display:inline" />
- <g
transform="translate(-1.0992584e-6,128)"
- id="g44264">
+ id="ICON_OUTLINER_DATA_EMPTY">
<g
id="g44266"
style="opacity:0.8;display:inline"
@@ -74058,7 +74615,7 @@
sodipodi:cy="14.5"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
transform="matrix(1.176776,0,0,1.176776,-12.47787,-2.548088)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -74233,7 +74790,7 @@
rx="0" />
</g>
<g
- id="g43843">
+ id="ICON_ERROR">
<g
transform="translate(20,-30.990313)"
id="g39499">
@@ -74293,7 +74850,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g44081"
+ id="ICON_FILE_PARENT"
transform="translate(0,1)">
<rect
style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -74355,7 +74912,7 @@
</g>
</g>
<g
- id="g44124">
+ id="ICON_FILE_REFRESH">
<rect
y="73"
x="341"
@@ -74471,7 +75028,7 @@
</g>
</g>
<g
- id="g44097">
+ id="ICON_BACK">
<rect
y="52"
x="320"
@@ -74540,7 +75097,7 @@
</g>
<g
transform="translate(-1,0)"
- id="g44111">
+ id="ICON_FORWARD">
<rect
style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect44093"
@@ -76409,9 +76966,151 @@
</g>
</g>
</g>
+ <g
+ style="display:inline;enable-background:new"
+ id="g14765"
+ inkscape:export-filename="/home/georg/Arbeitsfläche/2012/Blender Coding/Patch #2a/icon_big_redone 5a.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ transform="translate(1090.1244,-109.28264)">
+ <rect
+ ry="0"
+ rx="2.4004419"
+ y="336.28265"
+ x="-78.124435"
+ height="48"
+ width="48"
+ id="rect14767"
+ style="opacity:0;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path14769"
+ d="m -60.624426,339.78264 22.999995,0 0,41 -32.999995,0 0,-31 10,-10 z"
+ style="fill:url(#linearGradient14814);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path14771"
+ style="opacity:0.7;fill:none;stroke:url(#linearGradient14816);stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.56470588"
+ d="m -38.874431,340.78264 c -4.875,0 -21.749995,0 -21.749995,0 m -8.9447,8.5 -0.0553,30"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.2;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter63011-8)"
+ d="m 115,444 12,0 -1,-11 -11,11 z"
+ id="path14773"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106-0)"
+ inkscape:connector-curvature="0"
+ transform="translate(-186.12444,-93.717362)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path14775"
+ style="fill:none;stroke:url(#linearGradient14818);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -68.624426,350.03264 9,-2.5 0,-6"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m -70.624426,349.03264 0,31.75 32.999995,0 0,-41 -23.749995,0 -9.25,9.25 z"
+ style="fill:none;stroke:#333333;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path14777"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.16000001;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;filter:url(#filter63011-8)"
+ d="m 116,443 11,1 -2,-10 -9,9 z"
+ id="path14779"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ clip-path="url(#clipPath13106-0)"
+ inkscape:connector-curvature="0"
+ transform="translate(-186.12444,-93.717362)" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path14781"
+ d="m -70.124426,349.28264 0.0108,0.72434 9.9892,-2.72434 0,-7 -1,0 -9,9 z"
+ style="fill:#ffffff;fill-opacity:0.75294118;fill-rule:evenodd;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ d="m -38.624431,341.28264 0,38.5 -30.499995,0"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ id="path14783"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.5406242,0,0,0.5829534,-67.987756,347.93806)"
+ inkscape:label="Layer 1"
+ id="g14785">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.54857142;fill:url(#radialGradient14820);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path14788"
+ sodipodi:cx="28.019106"
+ sodipodi:cy="38.98439"
+ sodipodi:rx="15.467961"
+ sodipodi:ry="5.3033009"
+ d="m 43.487067,38.98439 c 0,2.928932 -6.925242,5.303301 -15.467961,5.303301 -8.542719,0 -15.467961,-2.374369 -15.467961,-5.303301 0,-2.928932 6.925242,-5.303301 15.467961,-5.303301 8.542719,0 15.467961,2.374369 15.467961,5.303301 z"
+ transform="matrix(1.274286,0,0,1.377124,-7.569123,-16.70193)" />
+ <path
+ style="fill:#f57900;fill-rule:evenodd;stroke:#aa4400;stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
+ id="path14790"
+ d="m 16.048489,28.093447 c 0.0098,0.576682 0.196474,1.697902 0.471116,2.577425 0.581566,1.854137 1.56684,3.572658 2.939126,5.086496 1.407488,1.553118 3.138519,2.803227 5.139315,3.68976 2.105357,0.931573 4.384795,1.407488 6.750134,1.403741 2.365339,-0.005 4.644601,-0.488686 6.74896,-1.427017 2.00002,-0.895288 3.731043,-2.148391 5.13754,-3.705517 1.369207,-1.519844 2.352576,-3.241114 2.934089,-5.096258 0.294262,-0.938353 0.476921,-1.889392 0.553238,-2.845308 0.07331,-0.939306 0.04204,-1.883511 -0.09183,-2.823792 -0.259981,-1.835599 -0.896294,-3.556847 -1.872652,-5.12758 -0.895541,-1.441699 -2.047808,-2.70454 -3.417268,-3.766975 0,0 0.002,-0.002 0.002,-0.002 0,0 -13.828458,-10.6197195 -13.828458,-10.6197195 -0.01176,-0.00978 -0.02252,-0.019551 -0.03529,-0.028344 -0.909003,-0.6959264 -3.879837,-0.7738945 -4.87679,-0.075035 -1.01067,0.7057021 -1.091821,1.8092613 -0.195527,2.5482146 1.899775,1.4997633 2.656207,2.2801589 4.566507,3.7797379 0,0 -14.852491,0.167033 -14.852491,0.167033 -1.994685,0 -3.1682609,0.947915 -3.4153947,2.333683 -0.2180771,1.222836 0.7479213,2.738129 2.4800217,2.738129 2.956573,0.0039 5.942111,-0.0069 8.909215,-0.01272 0,0 -16.01999,12.453223 -16.01999,12.453223 -0.020527,0.01564 -0.041053,0.02933 -0.06158,0.04497 -1.4974197,1.148389 -1.9831951,3.059322 -1.0399808,4.268393 0.9598323,1.22959 2.9977653,1.230588 4.5147288,0.006 0,0 8.677593,-7.102098 8.677593,-7.102098 0,0 -0.12511,0.959824 -0.116333,1.535532 l 1e-6,2.6e-5 0,0 0,0 z"
+ sodipodi:nodetypes="csssssssssscccsscccscccssccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#linearGradient14822);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path14792"
+ sodipodi:cx="31.1875"
+ sodipodi:cy="25.75"
+ sodipodi:rx="11.5625"
+ sodipodi:ry="10.125"
+ d="m 42.75,25.75 c 0,5.591883 -5.176708,10.125 -11.5625,10.125 -6.385792,0 -11.5625,-4.533117 -11.5625,-10.125 0,-5.591883 5.176708,-10.125 11.5625,-10.125 6.385792,0 11.5625,4.533117 11.5625,10.125 z"
+ transform="matrix(0.8018194,0,0,0.8471126,6.257567,4.5089892)" />
+ <path
+ sodipodi:nodetypes="csssssscssscsssccssscscccsccssssccscsscccssssc"
+ id="path14794"
+ d="m 25.8125,6.40625 c -0.334829,4.572e-4 -0.72202,0.089606 -0.90625,0.21875 4.5e-4,0.010412 4.5e-4,0.020838 0,0.03125 -0.212626,0.1484635 -0.188235,0.1956271 -0.1875,0.1875 0.0092,0.010621 -0.0072,-4.246e-4 0.03125,0.03125 0.01962,0.00828 0.03527,0.012546 0.0625,0.03125 0.01676,0.01151 0.01357,0.014555 0.03125,0.03125 0.193748,0.1576058 4.954976,4.005164 4.954976,4.005164 0.489837,0.39864 0.677395,1.066352 0.46875,1.65625 -0.115662,0.32703 -0.422813,0.541217 -0.6875,0.59375 -0.264687,0.05253 -0.498447,0.03054 -0.71875,0.03125 -5.639658,0.05119 -16.87989,0.03851 -16.87989,0.03851 -0.4102,2.75e-4 -0.935835,0.115997 -1.34375,0.34375 -0.407915,0.227753 -0.6637862,0.523861 -0.6875002,0.90625 -0.024417,0.393728 0.098829,0.605767 0.3437502,0.78125 0.244921,0.175483 0.614978,0.25 0.875,0.25 0,0 8.8125,0 8.8125,0 0.600305,-7.28e-4 1.223895,0.311058 1.4375,0.9375 0.04676,0.137121 0.06335,0.269976 0.0625,0.40625 -8.49e-4,0.136274 -0.02214,0.268794 -0.09375,0.375 -0.143211,0.212412 -0.319507,0.298568 -0.5,0.4375 0,0 -15.7871819,12.746851 -15.856336,12.800078 C 5.0310984,30.500117 5,30.53125 5,30.53125 5.0100745,30.519077 5.000335,30.499512 5,30.5 L 4.8125,30.3125 c 0.012336,0.02165 0.014481,0.03307 0.03125,0.0625 0.063558,0.0774 0.125,0.15625 0.125,0.15625 -0.00585,0.0056 -0.031233,0.03124 -0.03125,0.03125 0,0 -0.043442,-0.09921 -0.09375,-0.1875 0.037843,0.09884 0.06253,0.218739 0.0625,0.21875 -0.4662091,0.37119 -0.7783348,0.889746 -0.875,1.28125 -0.1043319,0.422581 -0.046,0.62455 0.125,0.84375 0.2999827,0.384295 1.3975356,0.595547 2.40625,-0.21875 0,0 8.65625,-7.09375 8.65625,-7.09375 0.473718,-0.387074 1.1446,-0.458625 1.6875,-0.15625 0.544608,0.303331 0.798054,0.927572 0.71875,1.53125 0,0 -0.0626,0.908319 -0.0625,1.25 2e-6,0.0085 -1.19e-4,0.02348 0,0.03125 0.192796,2.523718 1.400736,4.762818 3.03125,6.71875 2.801818,3.089095 6.627659,4.401619 10.75,4.5625 4.113324,-0.043 7.964529,-1.606111 10.75,-4.625 2.546631,-3.125326 3.513872,-6.363859 3.15625,-9.375 C 44.891575,22.325847 43.222923,19.516566 40.4375,17.25 35.951885,13.599946 31.206991,10.168434 26.59375,6.625 26.57515,6.610386 26.56455,6.59802 26.5625,6.59375 26.43835,6.498703 26.144223,6.4057899 25.8125,6.40625 z"
+ style="opacity:0.4857143;fill:none;stroke:url(#linearGradient14825);stroke-width:1.7812928;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#3465a4;fill-rule:evenodd;stroke:none"
+ id="path14796"
+ d="m 25.708956,26.064593 c 0.07649,-1.397943 0.759369,-2.631914 1.78592,-3.505519 1.010226,-0.858782 2.366788,-1.383145 3.848625,-1.383145 1.480894,0 2.837456,0.524363 3.847446,1.383145 1.027685,0.873605 1.709741,2.106651 1.787122,3.504594 0.07927,1.438713 -0.49591,2.77459 -1.504012,3.764001 -1.027686,1.007933 -2.493008,1.640678 -4.130556,1.640678 -1.63849,0 -3.103814,-0.632745 -4.131451,-1.640678 -1.00914,-0.989411 -1.58234,-2.325288 -1.503094,-3.763076 l 0,0 0,0 0,0 z"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.51999996;fill:url(#radialGradient14827);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 25.8125,6.03125 c -0.404852,5.53e-4 -2.204797,-0.059029 -2.48145,0.1349032 -0.280209,0.195652 -0.335403,0.376484 -0.34375,0.46875 -0.0083,0.092266 -0.01539,0.17648 0.1875,0.34375 0.01899,0.015735 0.04457,0.014317 0.0625,0.03125 0.124258,0.101028 4.748869,4.1248618 4.748869,4.1248618 0.373658,0.304091 0.504393,0.795817 0.34375,1.25 -0.160635,0.454191 -0.580748,0.373449 -1.0625,0.375 -5.634142,0.05114 -15.087371,-0.129601 -15.087371,-0.129601 -0.952967,6.38e-4 -2.339958,0.524782 -2.4062504,1.59375 -0.063562,1.024947 0.9247974,1.4375 1.5937504,1.4375 0,-1e-6 8.8125,0 8.8125,0 0.488364,-5.92e-4 0.936141,0.225277 1.09375,0.6875 0.157609,0.462231 -0.01926,0.514621 -0.40625,0.8125 0,0 -16.086298,13.088586 -16.086298,13.088586 -0.00142,0.0014 -0.029829,-0.0014 -0.03125,0 -0.064037,0.04879 -0.054226,0.04875 -0.03125,0.03125 -0.5536758,0.424619 -0.9087886,1.004019 -1.03125,1.5 -0.1224536,0.495981 -0.04661,0.856152 0.1875,1.15625 0.4788333,0.613413 1.777612,0.754857 2.90625,-0.15625 1e-7,10e-7 8.65625,-7.09375 8.65625,-7.09375 0.361955,-0.295753 0.872897,-0.352437 1.28125,-0.125 0.408345,0.227436 0.623381,0.692814 0.5625,1.15625 0,-1e-6 -0.0997,0.953636 -0.09375,1.34375 0.09498,1.301756 0.451616,2.521825 0.989039,3.664234 C 20.799917,36.321089 27.770982,19.392853 44.1875,21.03125 43.339652,19.54368 42.151282,18.185293 40.65625,16.96875 36.159865,13.309932 31.42016,9.882897 26.8125,6.34375 26.805335,6.338858 26.788292,6.317553 26.78125,6.3125 26.570707,6.151312 26.216591,6.030689 25.8125,6.03125 z"
+ id="path14798"
+ sodipodi:nodetypes="csssscsccsscsccssssscsscccsssc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
</g>
<g
- id="g44575"
+ id="ICON_FULLSCREEN_ENTER"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\fullscreen.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -76516,7 +77215,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g44633"
+ id="ICON_FULLSCREEN_EXIT"
transform="translate(189.0625,-42)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\fullscreen.png"
inkscape:export-xdpi="90"
@@ -76630,7 +77329,7 @@
</g>
<g
clip-path="url(#clipPath45147)"
- id="g45199">
+ id="ICON_MODIFIER">
<g
id="g45201"
clip-path="none"
@@ -76690,7 +77389,7 @@
</g>
</g>
<g
- id="g45262">
+ id="ICON_QUIT">
<rect
style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
id="rect45264"
@@ -76728,7 +77427,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 139.98403,118.50525 c -0.27904,4.40946 -4.07982,7.75782 -8.48928,7.47878 -4.40946,-0.27904 -7.75782,-4.07982 -7.47878,-8.48928 0.25664,-4.05547 3.51283,-7.27428 7.571,-7.48408"
+ d="m 139.98403,118.50525 a 8,8 0 1 1 -8.39706,-8.49458"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -76740,7 +77439,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 139.98403,118.50525 c -0.27904,4.40946 -4.07982,7.75782 -8.48928,7.47878 -4.40946,-0.27904 -7.75782,-4.07982 -7.47878,-8.48928 0.25664,-4.05547 3.51283,-7.27428 7.571,-7.48408"
+ d="m 139.98403,118.50525 a 8,8 0 1 1 -8.39706,-8.49458"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -76760,7 +77459,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 139.98403,118.50525 c -0.27904,4.40946 -4.07982,7.75782 -8.48928,7.47878 -4.40946,-0.27904 -7.75782,-4.07982 -7.47878,-8.48928 0.25664,-4.05547 3.51283,-7.27428 7.571,-7.48408"
+ d="m 139.98403,118.50525 a 8,8 0 1 1 -8.39706,-8.49458"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -76773,7 +77472,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 139.98403,118.50525 c -0.27904,4.40946 -4.07982,7.75782 -8.48928,7.47878 -4.40946,-0.27904 -7.75782,-4.07982 -7.47878,-8.48928 0.25664,-4.05547 3.51283,-7.27428 7.571,-7.48408"
+ d="m 139.98403,118.50525 a 8,8 0 1 1 -8.39706,-8.49458"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -76793,7 +77492,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(517.99163,649)"
- id="g45287">
+ id="ICON_FILE_TICK">
<path
sodipodi:nodetypes="cccccccc"
d="m -120.49163,-67.5 c -3.75159,0.954856 -7.20393,6.261452 -9,9 l -3.5,-3.5 -0.25,0.5 3.99163,4 0.5,0 c 1.0421,-2.617689 4.16191,-8.585412 8.25837,-10 l 0,0 z"
@@ -76814,7 +77513,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g42952"
+ id="ICON_GROUP"
style="display:inline;enable-background:new"
transform="translate(433,-61)">
<rect
@@ -76911,7 +77610,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -76920,7 +77619,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -76932,7 +77631,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -76949,7 +77648,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g43828">
+ id="ICON_LIBRARY_DATA_DIRECT">
<g
transform="translate(0,128)"
id="g24024">
@@ -77010,7 +77709,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g43838"
+ id="ICON_LIBRARY_DATA_INDIRECT"
transform="translate(0,-21)"
style="opacity:0.4">
<g
@@ -77073,12 +77772,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g46790"
- transform="translate(0,12)" />
- <g
- id="g46890" />
- <g
- id="g46912"
+ id="ICON_PARTICLE_TIP"
transform="translate(547.9924,59.00343)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\strands selection modes.png"
inkscape:export-xdpi="90"
@@ -77178,7 +77872,7 @@
</g>
</g>
<g
- id="g46928"
+ id="ICON_PARTICLE_POINT"
transform="translate(547.9924,59.00343)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\strands selection modes.png"
inkscape:export-xdpi="90"
@@ -77300,7 +77994,7 @@
</g>
</g>
<g
- id="g46958"
+ id="ICON_PARTICLE_PATH"
transform="translate(547.9924,59.00343)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\strands selection modes.png"
inkscape:export-xdpi="90"
@@ -77414,7 +78108,7 @@
</g>
<g
transform="translate(-1,0)"
- id="g24914">
+ id="ICON_CONSTRAINT_BONE">
<g
id="g25430"
transform="translate(0,-21)">
@@ -77536,7 +78230,7 @@
</g>
<g
transform="translate(0.00572791,126.98898)"
- id="g25026">
+ id="ICON_CONSTRAINT">
<rect
y="403.99695"
x="-382.01102"
@@ -77614,7 +78308,7 @@
</g>
</g>
<g
- id="g23496"
+ id="ICON_LOOP_FORWARDS"
transform="matrix(-1,0,0,1,614,0)">
<rect
transform="matrix(0,1,1,0,0,0)"
@@ -77705,7 +78399,7 @@
</g>
</g>
<g
- id="g23511"
+ id="ICON_LOOP_BACK"
transform="translate(-21,0)">
<rect
style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -77784,30 +78478,8 @@
</g>
</g>
<g
- style="display:inline;enable-background:new"
- id="g21623-4"
- transform="translate(-83.999976,274.99821)">
- <g
- transform="matrix(0.9999986,0,0,1,-170.19957,169.98079)"
- id="g10260-6">
- <g
- transform="translate(39.10005,-0.04905017)"
- id="g10262-3">
- <rect
- y="6.0700502"
- x="325.10001"
- height="15.979"
- width="16.000025"
- id="rect10264-4"
- style="opacity:0;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
- </g>
- <g
- id="g10266-9" />
- </g>
- </g>
- <g
transform="matrix(-1,0,0,1,209,550)"
- id="g27862"
+ id="ICON_TRIA_LEFT"
style="display:inline">
<rect
y="69"
@@ -77839,7 +78511,7 @@
</g>
<g
transform="matrix(1,0,0,-1,70,704.00001)"
- id="g27876"
+ id="ICON_TRIA_UP"
style="display:inline">
<rect
y="69"
@@ -77871,7 +78543,7 @@
</g>
<g
transform="translate(-231,-21)"
- id="g29960"
+ id="ICON_MOD_MIRROR"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\screw modifier.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -77931,7 +78603,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -77940,7 +78612,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -77959,7 +78631,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
transform="matrix(0.5705005,0,0,0.5705012,51.746079,156.18087)" />
</g>
<g
@@ -77973,7 +78645,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -77990,14 +78662,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
<path
transform="matrix(0.5705005,0,0,0.5705012,53.193935,156.18087)"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -78011,7 +78683,7 @@
</g>
</g>
<g
- id="g29313"
+ id="ICON_PROP_OFF"
transform="translate(-21,2)"
style="opacity:0.5">
<rect
@@ -78036,7 +78708,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -78053,7 +78725,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -78067,7 +78739,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -78075,7 +78747,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -78088,7 +78760,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -78099,287 +78771,274 @@
transform="matrix(0.424906,0,0,-0.424074,114.01316,85.183325)" />
</g>
</g>
- <rect
- transform="matrix(0,1,-1,0,0,0)"
- y="-252"
- x="52"
- height="16"
- width="16"
- id="rect28680"
- style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- transform="translate(97.00005,0)"
- id="g32009">
+ transform="translate(2.00005,151)"
+ id="ICON_MAN_TRANS"
+ style="display:inline">
+ <rect
+ y="6"
+ x="3"
+ height="16"
+ width="16"
+ id="rect32013"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
style="display:inline"
- id="g32011"
- transform="translate(-95,151)">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect32013"
- width="16"
- height="16"
- x="3"
- y="6" />
- <g
- transform="translate(64,9.999984)"
- id="g32015"
- style="display:inline">
- <path
- sodipodi:nodetypes="cccc"
- id="path32032"
- d="M -55,1 -47.000051,-1.999984 -50,6 -55,1 z"
- style="fill:none;stroke:#002255;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#002255;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="M -58.250048,9.250016 -50,0.999884"
- id="path32044"
- sodipodi:nodetypes="cc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cc"
- id="path32050"
- d="M -58.250048,9.250016 -50,0.999884"
- style="fill:none;stroke:#4989e9;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.5;fill:none;stroke:url(#linearGradient32140);stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m -58,8.999884 8,-8"
- id="path32055"
- sodipodi:nodetypes="cc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#4989e9;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="M -55,1 -47.000051,-1.999984 -50,6 -55,1 z"
- id="path32057"
- sodipodi:nodetypes="cccc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccc"
- id="path32059"
- d="M -55,1 -47.000051,-1.999984 -50,6 -55,1 z"
- style="opacity:0.5;fill:url(#linearGradient32142);fill-opacity:1;fill-rule:evenodd;stroke:none"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="M -47.25,-1.75 -54.75,1"
- id="path32063"
- sodipodi:nodetypes="cc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cc"
- id="path32068"
- d="m -53,3 -5.750048,5.750016 0,0.75"
- style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- </g>
+ id="g32015"
+ transform="translate(64,9.999984)">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#002255;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M -55,1 -47.000051,-1.999984 -50,6 -55,1 z"
+ id="path32032"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path32044"
+ d="M -58.250048,9.250016 -50,0.999884"
+ style="fill:none;stroke:#002255;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#4989e9;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="M -58.250048,9.250016 -50,0.999884"
+ id="path32050"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path32055"
+ d="m -58,8.999884 8,-8"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient32140);stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccc"
+ id="path32057"
+ d="M -55,1 -47.000051,-1.999984 -50,6 -55,1 z"
+ style="fill:#4989e9;fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.5;fill:url(#linearGradient32142);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="M -55,1 -47.000051,-1.999984 -50,6 -55,1 z"
+ id="path32059"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path32063"
+ d="M -47.25,-1.75 -54.75,1"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -53,3 -5.750048,5.750016 0,0.75"
+ id="path32068"
+ sodipodi:nodetypes="cc" />
</g>
+ </g>
+ <g
+ transform="translate(4.000002,151)"
+ id="ICON_MAN_SCALE"
+ style="display:inline">
+ <rect
+ y="6"
+ x="43"
+ height="16"
+ width="16"
+ id="rect32072"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
style="display:inline"
- id="g32070"
- transform="translate(-93.000048,151)">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect32072"
- width="16"
- height="16"
- x="43"
- y="6" />
- <g
- transform="translate(64,10)"
- id="g32074"
- style="display:inline">
- <path
- sodipodi:nodetypes="cc"
- id="path32077"
- d="m -18.25,9.25 8.249996,-8.2304767"
- style="fill:none;stroke:#002255;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#002255;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m -12.999997,-2.000002 5.9999268,1.448e-4 6.72e-5,5.9998542 -6.000002,0 8e-6,-5.999999 0,0 0,0 0,0 z"
- id="path32079"
- sodipodi:nodetypes="ccccc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#4989e9;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m -18.25,9.25 8.249996,-8.24999"
- id="path32081"
- sodipodi:nodetypes="cc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cc"
- id="path32087"
- d="m -18.000004,9.00001 8,-8"
- style="opacity:0.5;fill:none;stroke:url(#linearGradient32144);stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccccc"
- id="path32089"
- d="m -12.999992,-2 5.9999248,1.448e-4 L -7,4 l -6,0 8e-6,-6 z"
- style="fill:#4989e9;fill-opacity:1;fill-rule:evenodd;stroke:none"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.5;fill:url(#linearGradient32146);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m -12.999992,-2 5.9999248,1.452e-4 L -7,4 l -6,0 8e-6,-6 z"
- id="path32104"
- sodipodi:nodetypes="ccccc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccc"
- id="path32114"
- d="m -12.749999,2.750002 0,-4.4999957 5.4999946,0"
- style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m -12.75,2.75 -6,6 0,0.75"
- id="path32118"
- sodipodi:nodetypes="cc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- </g>
+ id="g32074"
+ transform="translate(64,10)">
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#002255;stroke-width:3.70000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -18.25,9.25 8.249996,-8.2304767"
+ id="path32077"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ id="path32079"
+ d="m -12.999997,-2.000002 5.9999268,1.448e-4 6.72e-5,5.9998542 -6.000002,0 8e-6,-5.999999 0,0 0,0 0,0 z"
+ style="fill:none;stroke:#002255;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path32081"
+ d="m -18.25,9.25 8.249996,-8.24999"
+ style="fill:none;stroke:#4989e9;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient32144);stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -18.000004,9.00001 8,-8"
+ id="path32087"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:#4989e9;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m -12.999992,-2 5.9999248,1.448e-4 L -7,4 l -6,0 8e-6,-6 z"
+ id="path32089"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="ccccc"
+ id="path32104"
+ d="m -12.999992,-2 5.9999248,1.452e-4 L -7,4 l -6,0 8e-6,-6 z"
+ style="opacity:0.5;fill:url(#linearGradient32146);fill-opacity:1;fill-rule:evenodd;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m -12.749999,2.750002 0,-4.4999957 5.4999946,0"
+ id="path32114"
+ sodipodi:nodetypes="ccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cc"
+ id="path32118"
+ d="m -12.75,2.75 -6,6 0,0.75"
+ style="fill:none;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
+ </g>
+ <g
+ id="ICON_MAN_ROT">
+ <rect
+ y="157"
+ x="26"
+ height="16"
+ width="16"
+ id="rect32122"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- id="g32120"
- transform="translate(-97.000051,0)">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect32122"
- width="16"
- height="16"
- x="26"
- y="157" />
- <g
- transform="matrix(0.9187785,0,0,0.9204344,64.322274,161.35151)"
- id="g32124"
- style="display:inline">
- <path
- sodipodi:open="true"
- inkscape:transform-center-y="-5.4395256"
- inkscape:transform-center-x="5.4369478"
- sodipodi:end="1.5729572"
- sodipodi:start="0"
- transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)"
- d="m 54,-32.5 c 0,2.485281 -2.014719,4.5 -4.5,4.5 -0.0032,0 -0.0065,-4e-6 -0.0097,-1.1e-5"
- sodipodi:ry="4.5"
- sodipodi:rx="4.5"
- sodipodi:cy="-32.5"
- sodipodi:cx="49.5"
- id="path32126"
- style="fill:none;stroke:#002255;stroke-width:1.79768455;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
- sodipodi:type="arc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <path
- sodipodi:type="arc"
- style="fill:none;stroke:#4989e9;stroke-width:0.9887265;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
- id="path32128"
- sodipodi:cx="49.5"
- sodipodi:cy="-32.5"
- sodipodi:rx="4.5"
- sodipodi:ry="4.5"
- d="m 54,-32.5 c 0,2.485281 -2.014719,4.5 -4.5,4.5 -0.0032,0 -0.0065,-4e-6 -0.0097,-1.1e-5"
- transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)"
- sodipodi:start="0"
- sodipodi:end="1.5729572"
- inkscape:transform-center-x="5.4369478"
- inkscape:transform-center-y="-5.4395256"
- sodipodi:open="true"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <path
- sodipodi:open="true"
- inkscape:transform-center-y="-5.4395256"
- inkscape:transform-center-x="5.4369478"
- sodipodi:end="1.5729572"
- sodipodi:start="0"
- transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)"
- d="m 54,-32.5 c 0,2.485281 -2.014719,4.5 -4.5,4.5 -0.0032,0 -0.0065,-4e-6 -0.0097,-1.1e-5"
- sodipodi:ry="4.5"
- sodipodi:rx="4.5"
- sodipodi:cy="-32.5"
- sodipodi:cx="49.5"
- id="path32136"
- style="opacity:0.5;fill:none;stroke:url(#linearGradient32148);stroke-width:0.9887265;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
- sodipodi:type="arc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <path
- sodipodi:type="arc"
- style="fill:none;stroke:#ffffff;stroke-width:0.29357874;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
- id="path32138"
- sodipodi:cx="49.5"
- sodipodi:cy="-32.5"
- sodipodi:rx="4.5"
- sodipodi:ry="4.5"
- d="m 54,-32.5 c 0,2.485281 -2.014719,4.5 -4.5,4.5 -0.0032,0 -0.0065,-4e-6 -0.0097,-1.1e-5"
- transform="matrix(-2.587958,0,0,-2.597682,100.48861,-75.018268)"
- sodipodi:start="0"
- sodipodi:end="1.5729572"
- inkscape:transform-center-x="5.8103423"
- inkscape:transform-center-y="-5.8447483"
- sodipodi:open="true"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- </g>
+ style="display:inline"
+ id="g32124"
+ transform="matrix(0.9187785,0,0,0.9204344,64.322274,161.35151)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:type="arc"
+ style="fill:none;stroke:#002255;stroke-width:1.79768455;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ id="path32126"
+ sodipodi:cx="49.5"
+ sodipodi:cy="-32.5"
+ sodipodi:rx="4.5"
+ sodipodi:ry="4.5"
+ d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989"
+ transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)"
+ sodipodi:start="0"
+ sodipodi:end="1.5729572"
+ inkscape:transform-center-x="5.4369478"
+ inkscape:transform-center-y="-5.4395256"
+ sodipodi:open="true" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:open="true"
+ inkscape:transform-center-y="-5.4395256"
+ inkscape:transform-center-x="5.4369478"
+ sodipodi:end="1.5729572"
+ sodipodi:start="0"
+ transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)"
+ d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989"
+ sodipodi:ry="4.5"
+ sodipodi:rx="4.5"
+ sodipodi:cy="-32.5"
+ sodipodi:cx="49.5"
+ id="path32128"
+ style="fill:none;stroke:#4989e9;stroke-width:0.9887265;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ sodipodi:type="arc" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:type="arc"
+ style="opacity:0.5;fill:none;stroke:url(#linearGradient32148);stroke-width:0.9887265;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ id="path32136"
+ sodipodi:cx="49.5"
+ sodipodi:cy="-32.5"
+ sodipodi:rx="4.5"
+ sodipodi:ry="4.5"
+ d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989"
+ transform="matrix(-2.421633,0,0,-2.417581,92.2682,-69.13182)"
+ sodipodi:start="0"
+ sodipodi:end="1.5729572"
+ inkscape:transform-center-x="5.4369478"
+ inkscape:transform-center-y="-5.4395256"
+ sodipodi:open="true" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:open="true"
+ inkscape:transform-center-y="-5.8447483"
+ inkscape:transform-center-x="5.8103423"
+ sodipodi:end="1.5729572"
+ sodipodi:start="0"
+ transform="matrix(-2.587958,0,0,-2.597682,100.48861,-75.018268)"
+ d="m 54,-32.5 a 4.5,4.5 0 0 1 -4.509724,4.499989"
+ sodipodi:ry="4.5"
+ sodipodi:rx="4.5"
+ sodipodi:cy="-32.5"
+ sodipodi:cx="49.5"
+ id="path32138"
+ style="fill:none;stroke:#ffffff;stroke-width:0.29357874;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.5"
+ sodipodi:type="arc" />
</g>
</g>
<g
transform="translate(315,-441)"
- id="g31816">
+ id="ICON_SORTSIZE">
<rect
style="opacity:0;color:#000000;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.5999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect31818"
@@ -78459,7 +79118,7 @@
</g>
</g>
<g
- id="g31846"
+ id="ICON_SORTALPHA"
transform="translate(191,-420)"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\sort a-z.png"
inkscape:export-xdpi="90"
@@ -78529,7 +79188,7 @@
inkscape:connector-curvature="0" />
</g>
<g
- id="g31883"
+ id="ICON_SORTTIME"
transform="translate(189,-315)">
<g
style="opacity:0.96000001;display:inline;enable-background:new"
@@ -78724,7 +79383,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\screw modifier.png"
transform="translate(-105,-42)"
- id="g31976">
+ id="ICON_MOD_SCREW">
<rect
y="283"
x="236"
@@ -78807,7 +79466,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\sequencer + image preview.png"
- id="g32260"
+ id="ICON_SEQ_SPLITVIEW"
transform="translate(147,0)">
<g
style="display:inline;enable-background:new"
@@ -78916,7 +79575,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\mysterious PR.png"
transform="translate(-118,-465)"
- id="g32309">
+ id="ICON_PREVIEW_RANGE">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect32311"
@@ -78937,7 +79596,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -78951,7 +79610,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -79041,7 +79700,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -79052,7 +79711,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Moje dokumenty\Moje obrazy\BLENDER ICONS redesign\ver 3\recently used.png"
transform="translate(32,-86.95)"
- id="g32361">
+ id="ICON_RECOVER_LAST">
<rect
y="664"
x="414"
@@ -79077,7 +79736,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -79103,7 +79762,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -79240,7 +79899,7 @@
</g>
<g
transform="translate(0,2)"
- id="g31005">
+ id="ICON_KEY_HLT">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect31007"
@@ -79283,7 +79942,7 @@
</g>
<path
transform="matrix(1.4399775,0,0,1.4399775,-171.50748,-44.947546)"
- d="m 388.20316,122.5078 c 0,0.39264 -0.3148,0.71093 -0.70313,0.71093 -0.38832,0 -0.70312,-0.31829 -0.70312,-0.71093 0,-0.39264 0.3148,-0.71094 0.70312,-0.71094 0.38833,0 0.70313,0.3183 0.70313,0.71094 z"
+ d="m 388.20316,122.5078 a 0.70312506,0.71093756 0 1 1 -1.40625,0 0.70312506,0.71093756 0 1 1 1.40625,0 z"
sodipodi:ry="0.71093756"
sodipodi:rx="0.70312506"
sodipodi:cy="122.5078"
@@ -79294,7 +79953,7 @@
</g>
</g>
<g
- id="g31159">
+ id="ICON_KEY_DEHLT">
<g
style="opacity:0.8"
transform="translate(-21,2)"
@@ -79341,7 +80000,7 @@
</g>
<path
transform="matrix(1.4399775,0,0,1.4399775,-171.50748,-44.947546)"
- d="m 388.20316,122.5078 c 0,0.39264 -0.3148,0.71093 -0.70313,0.71093 -0.38832,0 -0.70312,-0.31829 -0.70312,-0.71093 0,-0.39264 0.3148,-0.71094 0.70312,-0.71094 0.38833,0 0.70313,0.3183 0.70313,0.71094 z"
+ d="m 388.20316,122.5078 a 0.70312506,0.71093756 0 1 1 -1.40625,0 0.70312506,0.71093756 0 1 1 1.40625,0 z"
sodipodi:ry="0.71093756"
sodipodi:rx="0.70312506"
sodipodi:cy="122.5078"
@@ -79369,7 +80028,7 @@
</g>
</g>
<g
- id="g31133"
+ id="ICON_KEYINGSET"
transform="translate(0,-21)">
<rect
y="241"
@@ -79419,7 +80078,7 @@
sodipodi:cy="122.5078"
sodipodi:rx="0.70312506"
sodipodi:ry="0.71093756"
- d="m 388.20316,122.5078 c 0,0.39264 -0.3148,0.71093 -0.70313,0.71093 -0.38832,0 -0.70312,-0.31829 -0.70312,-0.71093 0,-0.39264 0.3148,-0.71094 0.70312,-0.71094 0.38833,0 0.70313,0.3183 0.70313,0.71094 z"
+ d="m 388.20316,122.5078 a 0.70312506,0.71093756 0 1 1 -1.40625,0 0.70312506,0.71093756 0 1 1 1.40625,0 z"
transform="matrix(1.4399775,0,0,1.4399775,-171.50748,-44.947546)" />
</g>
<path
@@ -79464,7 +80123,7 @@
sodipodi:cy="122.5078"
sodipodi:rx="0.70312506"
sodipodi:ry="0.71093756"
- d="m 388.20316,122.5078 c 0,0.39264 -0.3148,0.71093 -0.70313,0.71093 -0.38832,0 -0.70312,-0.31829 -0.70312,-0.71093 0,-0.39264 0.3148,-0.71094 0.70312,-0.71094 0.38833,0 0.70313,0.3183 0.70313,0.71094 z"
+ d="m 388.20316,122.5078 a 0.70312506,0.71093756 0 1 1 -1.40625,0 0.70312506,0.71093756 0 1 1 1.40625,0 z"
transform="matrix(1.7719122,0,0,1.7719122,-300.13217,-85.612134)" />
<path
sodipodi:nodetypes="czzzz"
@@ -79476,15 +80135,9 @@
</g>
</g>
</g>
- <path
- inkscape:connector-curvature="0"
- d=""
- style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path34332"
- sodipodi:nodetypes="cc" />
<g
style="display:inline;enable-background:new"
- id="g40603-2-4"
+ id="ICON_CLIP"
transform="translate(448,657)">
<rect
y="-122"
@@ -79632,7 +80285,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g55801">
+ id="ICON_LINK_BLEND">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect26258-7"
@@ -79653,7 +80306,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1.0000004 0 1 1 -2,0 1,1.0000004 0 1 1 2,0 z"
sodipodi:ry="1.0000004"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -79670,7 +80323,7 @@
</g>
<path
transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -79692,11 +80345,11 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(3.25,0,0,3.25,-62.875,313.125)" />
<path
transform="matrix(2,0,0,2,-46,385)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -79712,7 +80365,7 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
<path
sodipodi:nodetypes="cccccc"
@@ -79770,7 +80423,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g55835">
+ id="ICON_APPEND_BLEND">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect26258-7-4"
@@ -79791,7 +80444,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(3.625,0,0,3.1690202,-67.8125,318.31703)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1.0000004 0 1 1 -2,0 1,1.0000004 0 1 1 2,0 z"
sodipodi:ry="1.0000004"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -79808,7 +80461,7 @@
</g>
<path
transform="matrix(3.5999897,0,0,3.1249932,-67.499871,320.6879)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -79830,11 +80483,11 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(3.25,0,0,3.25,-62.875,313.125)" />
<path
transform="matrix(2,0,0,2,-46,385)"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="57.5"
@@ -79850,7 +80503,7 @@
sodipodi:cy="57.5"
sodipodi:rx="1"
sodipodi:ry="1"
- d="m 14.5,57.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+ d="m 14.5,57.5 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z"
transform="matrix(4.7519907,0,0,4.1435313,-83.051884,262.12196)" />
<path
sodipodi:nodetypes="cccccc"
@@ -79968,7 +80621,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g55731">
+ id="ICON_SAVE_PREFS">
<rect
y="51.97921"
x="25.950649"
@@ -80082,7 +80735,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g55696">
+ id="ICON_RECOVER_AUTO">
<rect
transform="scale(-1,-1)"
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -80192,7 +80845,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g17770">
+ id="ICON_IMPORT">
<rect
y="51.979202"
x="88.95063"
@@ -80287,7 +80940,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -80295,7 +80948,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -80309,7 +80962,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -80379,7 +81032,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g56020">
+ id="ICON_EXPORT">
<g
transform="translate(-28.94936,-39.370919)"
id="g42956-6-7">
@@ -80467,7 +81120,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -80475,7 +81128,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -80489,7 +81142,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -80559,7 +81212,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g56270">
+ id="ICON_EXTERNAL_DATA">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect29107-06"
@@ -80623,7 +81276,7 @@
sodipodi:cy="420.25"
sodipodi:rx="2.5"
sodipodi:ry="1.75"
- d="m 751.5,420.25 c 0,0.9665 -1.11929,1.75 -2.5,1.75 -1.38071,0 -2.5,-0.7835 -2.5,-1.75 0,-0.9665 1.11929,-1.75 2.5,-1.75 1.38071,0 2.5,0.7835 2.5,1.75 z"
+ d="m 751.5,420.25 a 2.5,1.75 0 1 1 -5,0 2.5,1.75 0 1 1 5,0 z"
transform="matrix(1,0,0,0.8571429,-212,-302.2143)" />
<rect
style="fill:#66ff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -80849,7 +81502,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g56314">
+ id="ICON_LOAD_FACTORY">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect29107-4"
@@ -80913,7 +81566,7 @@
sodipodi:cy="420.25"
sodipodi:rx="2.5"
sodipodi:ry="1.75"
- d="m 751.5,420.25 c 0,0.9665 -1.11929,1.75 -2.5,1.75 -1.38071,0 -2.5,-0.7835 -2.5,-1.75 0,-0.9665 1.11929,-1.75 2.5,-1.75 1.38071,0 2.5,0.7835 2.5,1.75 z"
+ d="m 751.5,420.25 a 2.5,1.75 0 1 1 -5,0 2.5,1.75 0 1 1 5,0 z"
transform="matrix(1,0,0,0.8571429,-212,-302.2143)" />
<rect
style="fill:#66ff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -81001,7 +81654,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g56410">
+ id="ICON_SAVE_COPY">
<g
transform="translate(190.95065,3.97921)"
id="g18875-2"
@@ -81090,7 +81743,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g56383">
+ id="ICON_SAVE_AS">
<rect
style="opacity:0;color:#000000;fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.5999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect31818-2"
@@ -81180,7 +81833,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g56477">
+ id="ICON_OPEN_RECENT">
<rect
y="73"
x="299"
@@ -81233,7 +81886,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81259,7 +81912,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -81382,7 +82035,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g36339-2"
+ id="ICON_COLOR_RED"
transform="translate(63.000002,128.99999)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -81399,7 +82052,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81418,7 +82071,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81436,7 +82089,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -81452,7 +82105,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81470,7 +82123,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -81485,7 +82138,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81504,7 +82157,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -81521,7 +82174,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -81529,7 +82182,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81542,7 +82195,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g36339-2-8"
+ id="ICON_COLOR_GREEN"
transform="translate(84.000002,128.99999)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -81559,7 +82212,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81578,7 +82231,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81596,7 +82249,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -81612,7 +82265,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81630,7 +82283,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -81645,7 +82298,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81664,7 +82317,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -81681,7 +82334,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -81689,7 +82342,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81702,7 +82355,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g36339-2-9"
+ id="ICON_COLOR_BLUE"
transform="translate(104.99111,129.00001)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -81719,7 +82372,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81738,7 +82391,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81756,7 +82409,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -81772,7 +82425,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81790,7 +82443,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -81805,7 +82458,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81824,7 +82477,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 132,110 c 2.85812,0 5.49914,1.52479 6.9282,4 L 132,118 z"
+ d="m 132,110 a 8,8 0 0 1 6.9282,4 L 132,118 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -81841,7 +82494,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -81849,7 +82502,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81862,7 +82515,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g42207-2"
+ id="ICON_META_EMPTY"
transform="translate(230.94982,190.97922)">
<g
transform="translate(83.990364,83.999999)"
@@ -81877,7 +82530,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -81885,7 +82538,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81903,7 +82556,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -81916,7 +82569,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -81924,7 +82577,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -81944,7 +82597,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g16164">
+ id="ICON_MOD_DYNAMICPAINT">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect18695-5"
@@ -82054,7 +82707,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g16082">
+ id="ICON_MOD_VERTEX_WEIGHT">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect18695-2"
@@ -82249,7 +82902,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g16224">
+ id="ICON_MOD_REMESH">
<rect
y="241"
x="194"
@@ -82388,7 +83041,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g16281">
+ id="ICON_MOD_WARP">
<rect
y="241"
x="236"
@@ -82491,7 +83144,7 @@
</g>
</g>
<g
- id="g81264">
+ id="ICON_MOD_TRIANGULATE">
<rect
y="241"
x="278"
@@ -82605,7 +83258,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g16263">
+ id="ICON_MOD_OCEAN">
<rect
y="241"
x="215"
@@ -82660,8 +83313,116 @@
</g>
</g>
<g
- style="display:inline;enable-background:new"
- id="g16592">
+ id="ICON_MOD_SMOOTH">
+ <g
+ id="g23516"
+ transform="translate(-0.9999998,2.020123)"
+ style="display:inline;enable-background:new">
+ <rect
+ y="260"
+ x="489"
+ height="16"
+ width="16"
+ id="rect23518"
+ style="opacity:0;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path23520"
+ style="fill:none;stroke:#0b1728;stroke-width:2.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 499.5,261.50004 -4.5,2 c -1.94148,0.86288 -2.18285,2.53884 -3,4.5 l -1.25,3"
+ sodipodi:nodetypes="cssc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 503,268.00008 0,2.99996 -3,1.5 c -3,1.5 -6.25,1.5 -10,1.49996 l 0,-2.49996 c 0.5,-0.99996 1.75,-2.75004 5,-4.00004 l 4,-1.5 1,0 3,1.25 0,0.75008 z"
+ id="path23522"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ sodipodi:nodetypes="cccccccccc"
+ style="fill:#c2d4ef;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline;enable-background:new"
+ d="m 495,267.5 4,-1.5 1,0 3,1.25 0,0.75004 0,2.75 -3,1.5 -10,1.5 0,-1.75 c 0.5,-1 1.77456,-3.24182 5,-4.50004 z"
+ id="path23524" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ d="m 496.75,263.00004 c -3,1.5 -2.75,8.5 2.25,7"
+ style="fill:none;stroke:url(#linearGradient23555);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23542" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccsccsccsccc"
+ id="path23526"
+ transform="translate(-20,0)"
+ d="m 519.82031,262 c 0.5,-0.16016 0.35115,-1.44373 -0.66015,-1 l -3.91016,1.75 c -2.5,0.75 -2.85099,2.90496 -3.82813,5.08203 L 510,271 l 0,3 c 3.76795,10e-6 7,0 10,-1.5 0.59071,-0.29535 2.31945,-1.15973 3,-1.5 l 0,-3 c -0.71506,0.35798 -2.3836,1.1918 -3,1.5 -0.45529,0.22765 -0.90706,0.42996 -1.375,0.59375 -4.60397,1.02313 -4.54405,-5.38421 -1.625,-6.84375 l 2.82031,-1.25 z"
+ style="fill:url(#linearGradient23581);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csc"
+ id="path23528"
+ d="m 490.5,273.51739 c 3.76795,0 5.75,-4e-5 8.75,-1.25004 0.60963,-0.25401 2.56945,-1.15973 3.25,-1.5"
+ style="fill:none;stroke:url(#linearGradient23550);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <rect
+ y="267"
+ x="497"
+ height="1"
+ width="2"
+ id="rect23530"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ style="fill:#000000"
+ id="g23575">
+ <rect
+ y="268"
+ x="497"
+ height="1"
+ width="2"
+ id="rect23532"
+ style="opacity:0.8;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.6;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23534"
+ width="1"
+ height="1.5"
+ x="496"
+ y="267" />
+ <rect
+ y="267"
+ x="499"
+ height="1.5"
+ width="1"
+ id="rect23536"
+ style="opacity:0.6;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:0.5;fill:#162d50;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect23538"
+ width="2"
+ height="0.5"
+ x="497"
+ y="266.5" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ style="fill:none;stroke:url(#linearGradient23585);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 490.5,272.5 c 3.76795,0 5.75,-4e-5 8.75,-1.25004 0.60963,-0.25401 2.56945,-1.15973 3.25,-1.5"
+ id="path23540"
+ sodipodi:nodetypes="csc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccssc"
+ d="m 499.5,261.50004 -3.07779,1.36791 L 495,263.50004 c -1.94148,0.86288 -2.18285,2.53884 -3,4.5 l -1.25,3"
+ style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path23546" />
+ </g>
<rect
style="opacity:0;fill:#292929;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect23518-8"
@@ -82697,25 +83458,25 @@
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc"
d="m 495.70064,264.97925 c -1.59411,1.20331 -2.85352,5.00657 -1.83419,6.55562 0.84654,1.28647 2.26188,0.99107 4.08419,0.44438"
- style="fill:none;stroke:url(#linearGradient16573);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ style="fill:none;stroke:url(#linearGradient18618);stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path23542-7" />
<path
id="path14759-8"
d="m 497.43868,264.59926 c 0.80576,0.30416 1.37557,1.03323 1.48798,2.92233 l 3.02398,2.65977 c -0.14914,-2.63927 0.0915,-5.8212 -3.12879,-7.01803 -0.39922,-0.14837 -1.04358,-0.0621 -1.33996,0.0614 z"
- style="fill:url(#linearGradient16570);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ style="fill:url(#linearGradient18620);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cssccsccscsscc"
id="path23526-4"
d="m 497.47415,263.23002 c -0.0305,0.0127 -2.69071,1.0899 -3.08515,1.28834 -0.97345,0.48973 -2.73962,3.32869 -3.70177,5.33135 l -1.74953,3.64155 0.013,2.49908 c 3.76795,10e-6 7,0 10,-1.5 l 3,-1.5 0,-3 c -0.71506,0.35798 -2.3836,1.1918 -3,1.5 -0.45529,0.22765 -0.90706,0.42996 -1.375,0.59375 -1.77534,0.39453 -3.51362,0.44764 -3.974,-0.67129 -0.58429,-1.42008 0.52872,-4.89528 2.24297,-6.11564 0.23077,-0.16428 1.56009,-0.67849 1.59569,-0.69629 z"
- style="fill:url(#linearGradient16567);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ style="fill:url(#linearGradient18622);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.89207077px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc"
id="path23528-6"
d="m 489.45064,275.4966 c 3.76795,0 5.75,-4e-5 8.75,-1.25004 0.60963,-0.25401 2.56945,-1.15973 3.25,-1.5"
- style="fill:none;stroke:url(#linearGradient16564);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ style="fill:none;stroke:url(#linearGradient18624);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -82724,7 +83485,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
- style="fill:none;stroke:url(#linearGradient16561);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ style="fill:none;stroke:url(#linearGradient18626);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 489.45064,274.47921 c 3.76795,0 5.75,-4e-5 8.75,-1.25004 0.60963,-0.25401 2.56945,-1.15973 3.25,-1.5"
id="path23540-9"
sodipodi:nodetypes="csc" />
@@ -82732,7 +83493,7 @@
inkscape:connector-curvature="0"
sodipodi:nodetypes="csscsc"
d="m 489.67253,273.44041 2.07721,-4.14016 c 0.98497,-1.9632 2.11086,-3.89476 3.15802,-4.3308 l 2.83577,-1.18084 c 0.92808,-0.35355 2.39677,0.78516 2.88291,1.66904 0.48613,0.88389 0.68121,2.03922 0.85799,4.29312"
- style="opacity:0.8;fill:none;stroke:url(#linearGradient16558);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ style="opacity:0.8;fill:none;stroke:url(#linearGradient18628);stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path23546-3" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#1b4685;stroke-width:0.80000001;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1"
@@ -82750,7 +83511,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g14953">
+ id="ICON_SOLO_OFF">
<rect
y="198.9792"
x="4.9506397"
@@ -82790,7 +83551,7 @@
<g
transform="translate(-0.04936017,-0.02079917)"
style="display:inline;enable-background:new"
- id="g16432">
+ id="ICON_FRAME_NEXT">
<rect
y="199"
x="68"
@@ -82847,7 +83608,7 @@
<g
transform="translate(-0.04936017,-0.02079917)"
style="display:inline;enable-background:new"
- id="g16424">
+ id="ICON_FRAME_PREV">
<rect
transform="scale(-1,1)"
y="198.89999"
@@ -82904,7 +83665,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g56653">
+ id="ICON_AXIS_FRONT">
<path
inkscape:connector-curvature="0"
d="m 289.95065,114.97921 0,1 2,0 0,1 1,0 0,-1 0,-1 -3,0 z m 2,2 -1,0 0,1 1,0 0,-1 z m -1,1 -1,0 0,1 0,1 3,0 0,-1 -2,0 0,-1 z m -1,3 0,2 1,0 0,-2 -1,0 z m 1,2 0,1 1,0 0,-1 -1,0 z m 1,0 1,0 0,-2 -1,0 0,2 z m 0,1 0,2 1,0 0,-2 -1,0 z m -1,0 -1,0 0,2 1,0 0,-2 z"
@@ -83043,7 +83804,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
transform="matrix(1.3333333,0,0,1.3333343,3,147.66665)"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
sodipodi:ry="1.5"
sodipodi:rx="1.5"
sodipodi:cy="14.5"
@@ -83055,7 +83816,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
sodipodi:ry="1.5"
sodipodi:rx="1.5"
sodipodi:cy="14.5"
@@ -83103,7 +83864,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g56628">
+ id="ICON_AXIS_SIDE">
<g
transform="translate(-0.04936017,-1.0207992)"
id="g18315"
@@ -83242,7 +84003,7 @@
sodipodi:cy="14.5"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
transform="matrix(1.3333333,0,0,1.3333343,170.99998,105.66665)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -83256,7 +84017,7 @@
sodipodi:cy="14.5"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -83294,7 +84055,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g56680">
+ id="ICON_AXIS_TOP">
<g
transform="translate(-0.04936017,-1.0207992)"
id="g18312"
@@ -83433,7 +84194,7 @@
sodipodi:cy="14.5"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
transform="matrix(1.3333333,0,0,1.3333343,209.98999,105.66665)"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
@@ -83447,7 +84208,7 @@
sodipodi:cy="14.5"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="M 72,14.5 C 72,15.328427 71.328427,16 70.5,16 69.671573,16 69,15.328427 69,14.5 69,13.671573 69.671573,13 70.5,13 c 0.828427,0 1.5,0.671573 1.5,1.5 z"
+ d="m 72,14.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -83483,17 +84244,10 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect23018-5-4-2"
- width="16"
- height="16"
- x="29.270542"
- y="209.19434" />
<g
transform="translate(21.04936,0.02079773)"
style="display:inline;enable-background:new"
- id="g14953-0">
+ id="ICON_SOLO_ON">
<rect
y="198.9792"
x="4.9506397"
@@ -83532,7 +84286,7 @@
</g>
<g
transform="translate(189,-229)"
- id="g22900-8"
+ id="ICON_MUTE_IPO_OFF"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -83651,7 +84405,7 @@
</g>
<g
transform="translate(210,-229)"
- id="g22900-8-5"
+ id="ICON_MUTE_IPO_ON"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -83733,7 +84487,7 @@
</g>
<g
transform="translate(-42,-40)"
- id="g22900-8-3"
+ id="ICON_OUTLINER_DATA_SPEAKER"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -83852,7 +84606,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g17563">
+ id="ICON_OUTLINER_OB_SPEAKER">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect22902-0-2"
@@ -83984,105 +84738,108 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- y="597"
- x="383"
- height="16"
- width="16"
- id="rect18740-5"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- transform="matrix(0.78985507,0,0,0.78985507,384.77042,545.63116)"
- id="g18742-8"
- style="display:inline;enable-background:new">
- <rect
- y="70.999992"
- x="4.9838772"
- height="9.0000172"
- width="11.999999"
- id="rect38458-5"
- style="opacity:0.7;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccccc"
- style="fill:url(#linearGradient17715);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.01284409;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 17.209985,82.052175 -1.174018,1.202898 -10.0887566,0 -1.2028894,-1.202898 -1e-7,-12.622124 12.4766491,0 -0.01099,12.622124 -5e-6,0 0,0 z"
- id="path18744-0"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc"
- style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 15.536259,81.328571 -6.3832127,2e-6 0,-0.999998 6.3832127,-2e-6 0,0.999998 z"
- id="path18746-7"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc"
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- id="path18748-3"
- d="m 5.9039809,82.132474 0.025569,-11.527305 10.1868001,5.7e-5 0,11.527247 z"
- style="fill:none;stroke:url(#linearGradient17717);stroke-width:1.26605475px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
- <rect
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- y="80.356544"
- x="6.7951851"
- height="1"
- width="1"
- id="rect18750-1"
- style="fill:#d40000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
<g
- style="display:inline;enable-background:new"
- id="g43488-2-2"
- transform="matrix(0,-0.75485957,0.75485957,0,327.67313,852.33908)">
- <path
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000;stroke-width:3.57682419;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="M 326.98536,85.889717 327,76"
- id="path43490-2-2"
- sodipodi:nodetypes="cc" />
- <path
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000;stroke-width:3.57682419;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- d="m 330.97424,79.255626 -3.97425,-3.974249 -3.97424,3.974249"
- id="path43492-1-0"
- sodipodi:nodetypes="ccc" />
- </g>
- <g
- style="display:inline;enable-background:new"
- id="g43494-2-5"
- transform="matrix(0,-0.75485957,0.75485957,0,327.67313,852.33908)">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc"
- id="path43496-7-5"
- d="M 327,85.889717 327,76"
- style="fill:none;stroke:#ebebeb;stroke-width:1.72217464;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc"
- id="path43498-9-6"
- d="m 330.97424,79.255626 -3.97425,-3.974249 -3.97424,3.974249"
- style="fill:none;stroke:#ebebeb;stroke-width:1.72217464;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- style="fill:none;stroke:#ffffff;stroke-width:1.32474971;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 330.97424,79.255626 -2.24089,-2.206598"
- id="path17874"
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0" />
+ id="ICON_SCREEN_BACK">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18740-5"
+ width="16"
+ height="16"
+ x="383"
+ y="597" />
+ <g
+ style="display:inline;enable-background:new"
+ id="g18742-8"
+ transform="matrix(0.78985507,0,0,0.78985507,384.77042,545.63116)">
+ <rect
+ style="opacity:0.7;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect38458-5"
+ width="11.999999"
+ height="9.0000172"
+ x="4.9838772"
+ y="70.999992" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18744-0"
+ d="m 17.209985,82.052175 -1.174018,1.202898 -10.0887566,0 -1.2028894,-1.202898 -1e-7,-12.622124 12.4766491,0 -0.01099,12.622124 -5e-6,0 0,0 z"
+ style="fill:url(#linearGradient17715);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.01284409;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path18746-7"
+ d="m 15.536259,81.328571 -6.3832127,2e-6 0,-0.999998 6.3832127,-2e-6 0,0.999998 z"
+ style="fill:#666666;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9999994px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient17717);stroke-width:1.26605475px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
+ d="m 5.9039809,82.132474 0.025569,-11.527305 10.1868001,5.7e-5 0,11.527247 z"
+ id="path18748-3"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#d40000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18750-1"
+ width="1"
+ height="1"
+ x="6.7951851"
+ y="80.356544"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ <g
+ transform="matrix(0,-0.75485957,0.75485957,0,327.67313,852.33908)"
+ id="g43488-2-2"
+ style="display:inline;enable-background:new">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path43490-2-2"
+ d="M 326.98536,85.889717 327,76"
+ style="fill:none;stroke:#000000;stroke-width:3.57682419;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path43492-1-0"
+ d="m 330.97424,79.255626 -3.97425,-3.974249 -3.97424,3.974249"
+ style="fill:none;stroke:#000000;stroke-width:3.57682419;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0,-0.75485957,0.75485957,0,327.67313,852.33908)"
+ id="g43494-2-5"
+ style="display:inline;enable-background:new">
+ <path
+ style="fill:none;stroke:#ebebeb;stroke-width:1.72217464;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 327,85.889717 327,76"
+ id="path43496-7-5"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#ebebeb;stroke-width:1.72217464;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 330.97424,79.255626 -3.97425,-3.974249 -3.97424,3.974249"
+ id="path43498-9-6"
+ sodipodi:nodetypes="ccc"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path17874"
+ d="m 330.97424,79.255626 -2.24089,-2.206598"
+ style="fill:none;stroke:#ffffff;stroke-width:1.32474971;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
</g>
<g
style="display:inline;enable-background:new"
- id="g17941">
+ id="ICON_DRIVER">
<rect
transform="scale(-1,1)"
y="220.00047"
@@ -84126,7 +84883,7 @@
</g>
</g>
<g
- id="g20086">
+ id="ICON_UNLOCKED">
<rect
y="598"
x="299"
@@ -84214,7 +84971,7 @@
<g
transform="translate(21,0)"
style="display:inline;enable-background:new"
- id="g20086-7">
+ id="ICON_LOCKED">
<rect
y="598"
x="299"
@@ -84302,7 +85059,7 @@
<g
transform="translate(-105.02687,272.93951)"
style="display:inline;enable-background:new"
- id="g17107">
+ id="ICON_EYEDROPPER">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect18696-0-4-1"
@@ -84355,7 +85112,7 @@
<g
transform="translate(-42,231)"
style="display:inline;enable-background:new"
- id="g17942-1">
+ id="ICON_ACTION">
<rect
y="304"
x="278"
@@ -84429,7 +85186,7 @@
</g>
</g>
<g
- id="g16806">
+ id="ICON_BOIDS">
<rect
y="472"
x="257"
@@ -84498,26 +85255,9 @@
id="path16745-9" />
</g>
<g
- id="g37076-6-0-2"
- style="opacity:0.96000001;stroke:#1a1a1a;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;display:inline;enable-background:new"
- transform="translate(127.00485,107.03779)" />
- <g
- style="opacity:0.96000001;stroke:#c8c8c8;stroke-opacity:1;display:inline;enable-background:new"
- id="g37094-7-8-1"
- transform="translate(190.00485,-60.962214)">
- <g
- transform="translate(-63.000001,168)"
- id="g37096-1-5-3"
- style="stroke:#c8c8c8;stroke-width:1.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <g
- id="g37104-2-9-1"
- transform="matrix(0,1,-1,0,511,255)"
- style="stroke:#c8c8c8;stroke-width:1.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- </g>
- <g
transform="translate(105,0)"
style="opacity:0.3;display:inline;enable-background:new"
- id="g17847-0">
+ id="ICON_RESTRICT_SELECT_ON">
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc"
@@ -84547,7 +85287,7 @@
<g
transform="translate(84,0)"
style="display:inline;enable-background:new"
- id="g17847-9">
+ id="ICON_RESTRICT_SELECT_OFF">
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc"
@@ -84576,7 +85316,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g10534-1"
+ id="ICON_SCRIPTPLUGINS"
transform="translate(189.0161,-397)">
<rect
y="428"
@@ -84655,119 +85395,9 @@
</g>
</g>
<g
- style="display:inline;enable-background:new"
- id="g79830">
- <rect
- y="73"
- x="467"
- height="16"
- width="16"
- id="rect52984-1"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- id="g79032">
- <g
- style="display:inline;enable-background:new"
- id="g39239-9"
- transform="translate(-285,-131)">
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- sodipodi:nodetypes="cccccc"
- id="path39241-0"
- d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
- style="fill:url(#linearGradient39254-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
- inkscape:connector-curvature="0" />
- <path
- style="opacity:0.3;fill:url(#radialGradient39256-2);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
- id="path39243-2"
- sodipodi:nodetypes="cccccc"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="cccc"
- d="m 754.5,209 0,9.5 m 3.5,-13 7.5,0"
- style="fill:none;stroke:url(#linearGradient39258-9);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
- id="path39245-4"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
- d="m 753,208 4,0 0,-4 -4,4 z"
- id="path39247-4"
- sodipodi:nodetypes="cccc"
- inkscape:connector-curvature="0" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- d="m 753.5,207.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path39249-3"
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0" />
- <path
- id="path39251-7"
- d="m 757.5,206.5 0,2 -2,0"
- style="fill:none;stroke:url(#linearGradient16151);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- </g>
- <path
- sodipodi:nodetypes="cccccccccccccccccssc"
- inkscape:connector-curvature="0"
- id="path52980-3"
- d="m 481.21875,81.25 c -0.34507,-0.155271 -0.69504,-0.245578 -1.125,-0.34375 L 479.9375,79 l -1,0 -1,0 -0.15625,1.90625 c -0.6231,0.14227 -1.07677,0.25145 -1.59375,0.59375 l -1.75,-1.75 -1.75,1.75 1.75,1.75 c -0.34229,0.51699 -0.45148,0.97065 -0.59375,1.59375 L 471.9375,85 l 0,1 0,1 1.90625,0.15625 c 0.092,0.4031 0.17505,0.738019 0.3125,1.0625 m 2.96875,0 C 476.47574,87.692174 476.0625,86.902037 476.0625,86 c 0,-1.58782 1.28718,-2.875 2.875,-2.875 0.94357,0 1.75793,0.454854 2.28125,1.15625"
- style="color:#000000;fill:none;stroke:#000000;stroke-width:1.70000005;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- id="path52982-4"
- d="m 477.9375,79 -0.15625,1.90625 c -0.6231,0.14227 -1.07677,0.25145 -1.59375,0.59375 l -1.75,-1.5 -1.5,1.5 1.5,1.75 c -0.34229,0.51699 -0.45148,0.97065 -0.59375,1.59375 L 471.9375,85 l 0,1 0,1 1.90625,0.15625 c 0.0981,0.429533 0.18992,0.780253 0.34375,1.125 l 2.8125,0 C 476.34893,87.730943 475.9375,86.919238 475.9375,86 c 0,-1.65685 1.34315,-3 3,-3 0.96105,0 1.7947,0.453338 2.34375,1.15625 l 0,-2.875 c -0.36595,-0.173211 -0.73124,-0.270823 -1.1875,-0.375 L 479.9375,79 l -1,0 -1,0 z m 3.34375,8.8125 c -0.12902,0.1662 -0.24569,0.333041 -0.40625,0.46875 l 0.40625,0 0,-0.46875 z"
- style="color:#000000;fill:url(#linearGradient79029);fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="cssc"
- inkscape:connector-curvature="0"
- id="rect52986-8"
- d="M 481.28125,83.40625 C 480.661,82.839183 479.84801,82.5 478.9375,82.5 c -1.93397,0 -3.5,1.566029 -3.5,3.5 0,0.881253 0.34008,1.6682 0.875,2.28125"
- style="fill:none;stroke:url(#linearGradient79025);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="ccccccccccccc"
- inkscape:connector-curvature="0"
- id="path52988-6"
- d="m 476.4375,81.75 c 0.49914,-0.213 1.64896,-0.6698 2,-0.75 l 0,-0.75 0,-0.75 1,0 m -5.25,1.25 -0.5,0.5 z m 0.5,2.75 c -0.20864,0.49552 -0.6715,1.65605 -0.75,2 l -0.75,0 -0.75,0 0,1"
- style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
- <path
- inkscape:connector-curvature="0"
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- d="m 473.43328,81.74394 1.25,-1.25"
- id="path52990-8"
- sodipodi:nodetypes="cc" />
- <path
- sodipodi:nodetypes="cssc"
- inkscape:connector-curvature="0"
- id="rect52992-4"
- d="M 481.28125,83.40625 C 480.661,82.839183 479.84801,82.5 478.9375,82.5 c -1.93397,0 -3.5,1.566029 -3.5,3.5 0,0.881253 0.34008,1.6682 0.875,2.28125"
- style="opacity:0.4;fill:none;stroke:url(#linearGradient79020);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- d="m 468.49796,75.999224 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
- id="path39249-3-7"
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- <g
transform="translate(-42.000002,-84)"
style="display:inline;enable-background:new"
- id="g81158-5">
+ id="ICON_MOD_SKIN">
<rect
y="325"
x="299"
@@ -84829,22 +85459,135 @@
y="332.52499" />
</g>
</g>
- <path
- sodipodi:type="arc"
- style="fill:none;stroke:#000000;stroke-width:0.9560194;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path81543"
- sodipodi:cx="478.90625"
- sodipodi:cy="86.03125"
- sodipodi:rx="2.34375"
- sodipodi:ry="2.34375"
- d="m 478.63139,88.358828 a 2.34375,2.34375 0 1 1 2.61786,-2.38697"
- transform="matrix(1.0460001,0,0,1.0460077,-22.029739,-4.0047766)"
- sodipodi:start="1.6883393"
- sodipodi:end="6.2578421"
- sodipodi:open="true" />
+ <g
+ id="ICON_FILE_SCRIPT">
+ <g
+ id="g79830"
+ style="display:inline;enable-background:new">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect52984-1"
+ width="16"
+ height="16"
+ x="467"
+ y="73" />
+ <g
+ id="g79032">
+ <g
+ transform="translate(-285,-131)"
+ id="g39239-9"
+ style="display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient39254-3);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ id="path39241-0"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path39243-2"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="opacity:0.3;fill:url(#radialGradient39256-2);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path39245-4"
+ style="fill:none;stroke:url(#linearGradient39258-9);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 754.5,209 0,9.5 m 3.5,-13 7.5,0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path39247-4"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path39249-3"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 753.5,207.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient16151);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 757.5,206.5 0,2 -2,0"
+ id="path39251-7" />
+ </g>
+ <path
+ style="color:#000000;fill:none;stroke:#000000;stroke-width:1.70000005;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 481.21875,81.25 c -0.34507,-0.155271 -0.69504,-0.245578 -1.125,-0.34375 L 479.9375,79 l -1,0 -1,0 -0.15625,1.90625 c -0.6231,0.14227 -1.07677,0.25145 -1.59375,0.59375 l -1.75,-1.75 -1.75,1.75 1.75,1.75 c -0.34229,0.51699 -0.45148,0.97065 -0.59375,1.59375 L 471.9375,85 l 0,1 0,1 1.90625,0.15625 c 0.092,0.4031 0.17505,0.738019 0.3125,1.0625 m 2.96875,0 C 476.47574,87.692174 476.0625,86.902037 476.0625,86 c 0,-1.58782 1.28718,-2.875 2.875,-2.875 0.94357,0 1.75793,0.454854 2.28125,1.15625"
+ id="path52980-3"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccssc" />
+ <path
+ style="color:#000000;fill:url(#linearGradient79029);fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 477.9375,79 -0.15625,1.90625 c -0.6231,0.14227 -1.07677,0.25145 -1.59375,0.59375 l -1.75,-1.5 -1.5,1.5 1.5,1.75 c -0.34229,0.51699 -0.45148,0.97065 -0.59375,1.59375 L 471.9375,85 l 0,1 0,1 1.90625,0.15625 c 0.0981,0.429533 0.18992,0.780253 0.34375,1.125 l 2.8125,0 C 476.34893,87.730943 475.9375,86.919238 475.9375,86 c 0,-1.65685 1.34315,-3 3,-3 0.96105,0 1.7947,0.453338 2.34375,1.15625 l 0,-2.875 c -0.36595,-0.173211 -0.73124,-0.270823 -1.1875,-0.375 L 479.9375,79 l -1,0 -1,0 z m 3.34375,8.8125 c -0.12902,0.1662 -0.24569,0.333041 -0.40625,0.46875 l 0.40625,0 0,-0.46875 z"
+ id="path52982-4"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:url(#linearGradient79025);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 481.28125,83.40625 C 480.661,82.839183 479.84801,82.5 478.9375,82.5 c -1.93397,0 -3.5,1.566029 -3.5,3.5 0,0.881253 0.34008,1.6682 0.875,2.28125"
+ id="rect52986-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssc" />
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 476.4375,81.75 c 0.49914,-0.213 1.64896,-0.6698 2,-0.75 l 0,-0.75 0,-0.75 1,0 m -5.25,1.25 -0.5,0.5 z m 0.5,2.75 c -0.20864,0.49552 -0.6715,1.65605 -0.75,2 l -0.75,0 -0.75,0 0,1"
+ id="path52988-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccccc" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path52990-8"
+ d="m 473.43328,81.74394 1.25,-1.25"
+ style="fill:none;stroke:#ffffff;stroke-width:1.10000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:0.4;fill:none;stroke:url(#linearGradient79020);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.26976086;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 481.28125,83.40625 C 480.661,82.839183 479.84801,82.5 478.9375,82.5 c -1.93397,0 -3.5,1.566029 -3.5,3.5 0,0.881253 0.34008,1.6682 0.875,2.28125"
+ id="rect52992-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path39249-3-7"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 468.49796,75.999224 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ </g>
+ </g>
+ <path
+ sodipodi:open="true"
+ sodipodi:end="6.2578421"
+ sodipodi:start="1.6883393"
+ transform="matrix(1.0460001,0,0,1.0460077,-22.029739,-4.0047766)"
+ d="m 478.63139,88.358828 a 2.34375,2.34375 0 1 1 2.61786,-2.38697"
+ sodipodi:ry="2.34375"
+ sodipodi:rx="2.34375"
+ sodipodi:cy="86.03125"
+ sodipodi:cx="478.90625"
+ id="path81543"
+ style="fill:none;stroke:#000000;stroke-width:0.9560194;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:type="arc" />
+ </g>
<g
style="display:inline;enable-background:new"
- id="g16724-8-3">
+ id="ICON_PANEL_CLOSE">
<rect
y="598"
x="152"
@@ -84894,7 +85637,7 @@
<g
transform="translate(252,21)"
style="display:inline;enable-background:new"
- id="g16724-8-1">
+ id="ICON_X">
<rect
y="598"
x="152"
@@ -84942,7 +85685,7 @@
</g>
</g>
<g
- id="g27438">
+ id="ICON_BORDER_RECT">
<g
transform="translate(0,-21)"
id="g23604">
@@ -85194,7 +85937,7 @@
<g
transform="translate(0.02855492,0)"
style="display:inline;enable-background:new"
- id="g15868-5">
+ id="ICON_MOD_SOLIDIFY">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect18695-6-9-6"
@@ -85272,15 +86015,8 @@
sodipodi:nodetypes="cc" />
</g>
</g>
- <path
- d="m -220,198.65625 -5.3125,8.6875 5.3125,3 5.28125,-3.0625 -5.28125,-8.625 z"
- id="path29747"
- style="opacity:0.55438597;fill:none;stroke:url(#linearGradient29763);stroke-width:1.14285719;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- inkscape:original="M -220 196.6875 L -226.71875 207.6875 L -220 211.5 L -213.3125 207.625 L -220 196.6875 z "
- inkscape:radius="-1.0141826"
- sodipodi:type="inkscape:offset" />
<g
- id="g27538">
+ id="ICON_EDIT">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect39543"
@@ -85787,37 +86523,9 @@
y="624.98871" />
</g>
</g>
- <path
- inkscape:connector-curvature="0"
- d=""
- sodipodi:nodetypes="cz"
- id="path39078-8-8-1"
- style="fill:none;stroke:#f2f2f2;stroke-width:1.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000034;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- transform="matrix(0.90885089,0,0,0.92442422,-334.35843,100.27347)"
- style="opacity:0.85"
- id="g37781-7-2-5" />
- <g
- transform="translate(-118.46,211)"
- style="opacity:0.6"
- id="g35477-3">
- <g
- id="g35480-0" />
- <g
- id="g35486-7" />
- </g>
- <g
- transform="matrix(0,1,-1,0,197.54,88)"
- id="g35493-0"
- style="opacity:0.6">
- <g
- id="g35496-1" />
- <g
- id="g35502-6" />
- </g>
<g
style="display:inline;enable-background:new"
- id="g43585-6"
+ id="ICON_FORCE_WIND"
transform="translate(72,509.96991)">
<rect
y="148"
@@ -85885,7 +86593,7 @@
inkscape:connector-curvature="0" />
<path
transform="matrix(2.5815738,0,0,1.0580577,65.140965,9.1698698)"
- d="m -40.52941,-158 c 0,2.34721 -0.434548,4.25 -0.97059,4.25 -0.536042,0 -0.97059,-1.90279 -0.97059,-4.25 0,-2.34721 0.434548,-4.25 0.97059,-4.25 0.536042,0 0.97059,1.90279 0.97059,4.25 z"
+ d="m -40.52941,-158 a 0.9705897,4.25 0 1 1 -1.94118,0 0.9705897,4.25 0 1 1 1.94118,0 z"
sodipodi:ry="4.25"
sodipodi:rx="0.9705897"
sodipodi:cy="-158"
@@ -85910,7 +86618,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g24573-8"
+ id="ICON_FORCE_DRAG"
transform="translate(189,104.96991)">
<g
id="g24558-2">
@@ -86012,7 +86720,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86029,14 +86737,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(-0.6011908,-0.06817113,0.06852359,-0.6012277,199.77148,303.44348)" />
<path
transform="matrix(0.4463965,0,0,0.4463971,69.575658,170.82515)"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86051,7 +86759,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g43234-2"
+ id="ICON_FORCE_TURBULENCE"
transform="matrix(-1,0,0,1,185,310)">
<rect
transform="scale(1,-1)"
@@ -86147,7 +86855,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86164,14 +86872,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(-0.6011908,-0.06817113,0.06852359,-0.6012277,199.77148,303.44348)" />
<path
transform="matrix(0.4463965,0,0,0.4463971,69.575658,170.82515)"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86187,7 +86895,7 @@
<g
transform="translate(0,336)"
style="display:inline;enable-background:new"
- id="g21835-7">
+ id="ICON_FORCE_FORCE">
<g
transform="translate(51,10)"
style="opacity:0.8"
@@ -86344,7 +87052,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -86353,7 +87061,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86372,13 +87080,13 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
transform="matrix(0.4463965,0,0,0.4463971,69.575658,170.82515)" />
</g>
</g>
<g
style="display:inline;enable-background:new"
- id="g45967-8"
+ id="ICON_FORCE_TEXTURE"
transform="translate(198,390)">
<g
mask="url(#mask45447-7)"
@@ -86449,7 +87157,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -86458,7 +87166,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86477,13 +87185,13 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
transform="matrix(0.4463965,0,0,0.4463971,69.575658,170.82515)" />
</g>
</g>
<g
style="display:inline;enable-background:new"
- id="g43252-2"
+ id="ICON_FORCE_VORTEX"
transform="matrix(-1,0,0,1,16.999998,490)">
<rect
transform="scale(1,-1)"
@@ -86552,7 +87260,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g45137-8"
+ id="ICON_FORCE_CHARGE"
transform="translate(156,308)">
<rect
transform="scale(1,-1)"
@@ -86583,7 +87291,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -86592,7 +87300,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86611,7 +87319,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
transform="matrix(0.5650525,0,0,0.5650532,53.91307,156.82373)" />
</g>
<g
@@ -86667,7 +87375,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86684,14 +87392,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
<path
transform="matrix(0.5719769,0,0,0.5719777,52.999044,156.00665)"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86724,7 +87432,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g24618-1"
+ id="ICON_FORCE_CURVE"
transform="translate(168,176)">
<rect
ry="0"
@@ -86846,7 +87554,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86863,14 +87571,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(-0.683022,-0.07745026,0.0778507,-0.683064,209.4726,314.325)" />
<path
transform="matrix(0.4963171,0,0,0.4963178,62.986138,164.93452)"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86885,7 +87593,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g43314-2"
+ id="ICON_FORCE_LENNARDJONES"
transform="translate(177,410)">
<rect
transform="scale(1,-1)"
@@ -86903,7 +87611,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86920,14 +87628,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(-0.2610878,-0.02960567,0.02975872,-0.2611039,35.872259,-102.36161)" />
<path
transform="matrix(0.2102357,0,0,0.2102362,-22.830954,-161.8877)"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86946,7 +87654,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -86963,14 +87671,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(-0.5000291,-0.05669783,0.0569932,-0.5000402,23.278522,10.488883)" />
<path
transform="matrix(0.4374781,0,0,0.4374622,-93.747286,-107.62054)"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -87017,7 +87725,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -87026,7 +87734,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -87045,14 +87753,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
transform="matrix(0.2102357,0,0,0.2102362,-22.830954,-161.8877)" />
</g>
</g>
<g
style="display:inline;enable-background:new"
transform="translate(135,431)"
- id="g49017-5">
+ id="ICON_FORCE_HARMONIC">
<rect
transform="scale(1,-1)"
style="opacity:0;fill:#666666;stroke:none;stroke-width:2.29999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -87091,7 +87799,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -87108,14 +87816,14 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="matrix(-0.2610878,-0.02960567,0.02975872,-0.2611039,35.872259,-102.36161)" />
<path
transform="matrix(0.2102357,0,0,0.2102362,-22.830954,-161.8877)"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -87164,7 +87872,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -87173,7 +87881,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -87192,7 +87900,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
transform="matrix(0.2102357,0,0,0.2102362,-22.830954,-161.8877)" />
</g>
</g>
@@ -87228,7 +87936,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -87237,7 +87945,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -87256,7 +87964,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
transform="matrix(0.2102357,0,0,0.2102362,-22.830954,-161.8877)" />
</g>
</g>
@@ -87290,7 +87998,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g33096-6"
+ id="ICON_FORCE_BOID"
transform="translate(189,147)">
<g
transform="translate(51,203)"
@@ -87464,7 +88172,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -87473,7 +88181,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -87492,13 +88200,13 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
transform="matrix(0.4463965,0,0,0.4463971,69.575658,170.82515)" />
</g>
</g>
<g
style="display:inline;enable-background:new"
- id="g24982-9"
+ id="ICON_FORCE_MAGNETIC"
transform="translate(21,273)">
<rect
y="73"
@@ -87555,7 +88263,7 @@
sodipodi:cy="-117.5"
sodipodi:rx="1.5"
sodipodi:ry="1.5"
- d="m -9,-117.5 c 0,0.82843 -0.6715729,1.5 -1.5,1.5 -0.828427,0 -1.5,-0.67157 -1.5,-1.5 0,-0.82843 0.671573,-1.5 1.5,-1.5 0.8284271,0 1.5,0.67157 1.5,1.5 z"
+ d="m -9,-117.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
transform="matrix(1,0,0,1.4166681,-22,49.0835)" />
<g
id="g24584-3">
@@ -87589,22 +88297,8 @@
inkscape:connector-curvature="0" />
</g>
</g>
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect37577-3"
- width="16"
- height="16"
- x="214.71344"
- y="139.35567" />
- <rect
- y="134.50435"
- x="196.07863"
- height="16"
- width="16"
- id="rect33341-6"
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <g
- id="g30024"
+ <g
+ id="ICON_AUTOMERGE_ON"
transform="translate(0.03262657,-0.06636782)">
<g
inkscape:export-ydpi="90"
@@ -87767,20 +88461,20 @@
</g>
</g>
<g
- id="g30336">
+ id="ICON_AUTOMERGE_OFF">
<g
- style="opacity:1;stroke:#646464;stroke-opacity:1"
+ style="stroke:#646464;stroke-opacity:1"
id="g44641-6-3"
transform="matrix(-1,0,0,1,565.35356,49.06678)">
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#646464;stroke-width:3.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ style="fill:none;stroke:#646464;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 347.25,100.25 -4,-4"
id="path44643-3-8"
sodipodi:nodetypes="cc" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#646464;stroke-width:3.40000010000000019;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ style="fill:none;stroke:#646464;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 343,100.25 0,-4.25 4.25,0"
id="path44645-3-3"
sodipodi:nodetypes="ccc" />
@@ -87827,7 +88521,7 @@
height="3"
width="2.9998772"
id="rect39229-9-81"
- style="fill:#e6e6e6;stroke:#969696;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265000000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ style="fill:#e6e6e6;stroke:#969696;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
@@ -87843,13 +88537,13 @@
transform="matrix(1,0,0,-1,-118.64644,239.06678)"
style="stroke:#646464;stroke-opacity:1">
<path
- style="fill:none;stroke:#646464;stroke-width:3.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ style="fill:none;stroke:#646464;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 347.25,100.25 -4,-4"
id="path44637-0-8"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
- style="fill:none;stroke:#646464;stroke-width:3.40000010000000019;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ style="fill:none;stroke:#646464;stroke-width:3.4000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 343,100.25 0,-4.25 4.25,0"
id="path44639-9-5"
sodipodi:nodetypes="ccc"
@@ -87906,222 +88600,225 @@
height="3"
width="2.9998772"
id="rect39229-9-8-3"
- style="fill:#e6e6e6;stroke:#969696;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265000000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ style="fill:#e6e6e6;stroke:#969696;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17868"
- width="16"
- height="16"
- x="467"
- y="493"
- rx="0"
- ry="0" />
- <rect
- rx="1.7356256"
- style="fill:url(#linearGradient18011);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17872"
- width="15"
- height="12"
- x="467.5"
- y="495.5"
- ry="1.7356256" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient18008);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="M 468,499.48148 468,505 c 0,0.56404 0.36784,1.00001 0.84375,1 l 12.3125,0 C 481.63216,506 482,505.56405 482,505 l 0,-5.51852 c -0.31371,0.37179 -0.76923,0.59259 -1.25,0.59259 l -11.5,0 c -0.48077,0 -0.93629,-0.2208 -1.25,-0.59259 z"
- id="path17875"
- sodipodi:nodetypes="ccccccccc" />
- <rect
- ry="1"
- y="495.5"
- x="467.5"
- height="2"
- width="15"
- id="rect17877"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- rx="1.5817194" />
- <rect
- rx="1.503511"
- ry="1.503511"
- y="495.5"
- x="467.5"
- height="12"
- width="15"
- id="rect17879"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="opacity:0.25;fill:none;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17883"
- width="13.000001"
- height="10"
- x="468.5"
- y="496.5"
- ry="0.4910686"
- rx="0.5078125" />
- <g
- transform="matrix(0.7547901,0,0,1,416.02177,0)"
- id="g17893">
- <path
- transform="matrix(0.7901234,0,0,0.2000006,9.8760061,395.5997)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- sodipodi:ry="2.5"
- sodipodi:rx="2.5312502"
- sodipodi:cy="502"
- sodipodi:cx="78"
- id="path17895"
- style="fill:none;stroke:#999999;stroke-width:2.89550138;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
+ <g
+ id="ICON_CAMERA_STEREO">
+ <rect
+ ry="0"
+ rx="0"
+ y="493"
+ x="467"
+ height="16"
+ width="16"
+ id="rect17868"
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ ry="1.7356256"
+ y="495.5"
+ x="467.5"
+ height="12"
+ width="15"
+ id="rect17872"
+ style="fill:url(#linearGradient18011);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ rx="1.7356256" />
<path
- inkscape:connector-curvature="0"
- style="fill:none;stroke:#000000;stroke-width:1.15103066;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 69.505631,495.5 0,-0.50001 c 0,-0.276 0.896,-0.5 2,-0.5 1.104,0 2,0.224 2,0.5 l 0,0.50001"
- id="path17897"
- sodipodi:nodetypes="csccc" />
+ sodipodi:nodetypes="ccccccccc"
+ id="path17875"
+ d="M 468,499.48148 468,505 c 0,0.56404 0.36784,1.00001 0.84375,1 l 12.3125,0 C 481.63216,506 482,505.56405 482,505 l 0,-5.51852 c -0.31371,0.37179 -0.76923,0.59259 -1.25,0.59259 l -11.5,0 c -0.48077,0 -0.93629,-0.2208 -1.25,-0.59259 z"
+ style="fill:url(#linearGradient18008);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ rx="1.5817194"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17877"
+ width="15"
+ height="2"
+ x="467.5"
+ y="495.5"
+ ry="1" />
+ <rect
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17879"
+ width="15"
+ height="12"
+ x="467.5"
+ y="495.5"
+ ry="1.503511"
+ rx="1.503511" />
+ <rect
+ rx="0.5078125"
+ ry="0.4910686"
+ y="496.5"
+ x="468.5"
+ height="10"
+ width="13.000001"
+ id="rect17883"
+ style="opacity:0.25;fill:none;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ id="g17893"
+ transform="matrix(0.7547901,0,0,1,416.02177,0)">
+ <path
+ sodipodi:type="arc"
+ style="fill:none;stroke:#999999;stroke-width:2.89550138;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path17895"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.7901234,0,0,0.2000006,9.8760061,395.5997)" />
+ <path
+ sodipodi:nodetypes="csccc"
+ id="path17897"
+ d="m 69.505631,495.5 0,-0.50001 c 0,-0.276 0.896,-0.5 2,-0.5 1.104,0 2,0.224 2,0.5 l 0,0.50001"
+ style="fill:none;stroke:#000000;stroke-width:1.15103066;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17899"
+ width="2.6497433"
+ height="1"
+ x="70.189362"
+ y="495" />
+ </g>
<rect
- y="495"
- x="70.189362"
+ y="497.5"
+ x="479"
+ height="1.5"
+ width="2"
+ id="rect17901"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="fill:url(#radialGradient17992);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect17903"
+ width="2"
+ height="1.5"
+ x="479"
+ y="497.5" />
+ <rect
+ y="498"
+ x="470"
height="1"
- width="2.6497433"
- id="rect17899"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- </g>
- <rect
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17901"
- width="2"
- height="1.5"
- x="479"
- y="497.5" />
- <rect
- y="497.5"
- x="479"
- height="1.5"
- width="2"
- id="rect17903"
- style="fill:url(#radialGradient17992);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect17905"
- width="1"
- height="1"
- x="470"
- y="498" />
- <use
- x="0"
- y="0"
- xlink:href="#g18103"
- id="use18134"
- transform="translate(-6.1847313,0)"
- width="602"
- height="640" />
- <g
- id="g18103"
- transform="matrix(0.81050804,0,0,0.81050804,91.905464,90.739248)">
- <path
- transform="matrix(1.5770887,0,0,1.5999841,353.49325,-294.69208)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- sodipodi:ry="2.5"
- sodipodi:rx="2.5312502"
- sodipodi:cy="502"
- sodipodi:cx="78"
- id="path17885"
- style="opacity:0.1;fill:none;stroke:#000000;stroke-width:0.62952667;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
- <path
- sodipodi:type="arc"
- style="opacity:0.7;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.75859177;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path17881"
- sodipodi:cx="78"
- sodipodi:cy="502"
- sodipodi:rx="2.5312502"
- sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- transform="matrix(1.3955004,0,0,1.2452423,368.18333,-114.72474)" />
- <path
- sodipodi:type="arc"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient18146);stroke-width:0.97061968;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path17887"
- sodipodi:cx="78"
- sodipodi:cy="502"
- sodipodi:rx="2.5312502"
- sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- transform="matrix(1.1794014,0,0,0.8999954,384.50686,55.952303)" />
- <path
- transform="matrix(1.1827463,0,0,1.2,384.24579,-92.900024)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- sodipodi:ry="2.5"
- sodipodi:rx="2.5312502"
- sodipodi:cy="502"
- sodipodi:cx="78"
- id="path17889"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#b3b3b3;stroke-width:0.83938956;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
- <path
- sodipodi:type="arc"
- style="fill:none;stroke:url(#linearGradient18149);stroke-width:1.26754272;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path17891"
- sodipodi:cx="78"
- sodipodi:cy="502"
- sodipodi:rx="2.5312502"
- sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- transform="matrix(0.790122,0,0,0.787736,414.87048,114.05649)" />
- <path
- sodipodi:type="arc"
- style="fill:none;stroke:url(#radialGradient18151);stroke-width:0.67151165;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path17907"
- sodipodi:cx="78"
- sodipodi:cy="502"
- sodipodi:rx="2.5312502"
- sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- transform="matrix(1.1827463,0,0,1.2,384.24579,-92.900024)" />
+ width="1"
+ id="rect17905"
+ style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.00000012;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <use
+ height="640"
+ width="602"
+ transform="translate(-6.1847313,0)"
+ id="use18134"
+ xlink:href="#g18103"
+ y="0"
+ x="0" />
+ <g
+ transform="matrix(0.81050804,0,0,0.81050804,91.905464,90.739248)"
+ id="g18103">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:0.62952667;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path17885"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.5770887,0,0,1.5999841,353.49325,-294.69208)" />
+ <path
+ transform="matrix(1.3955004,0,0,1.2452423,368.18333,-114.72474)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path17881"
+ style="opacity:0.7;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.75859177;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.1794014,0,0,0.8999954,384.50686,55.952303)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path17887"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient18146);stroke-width:0.97061968;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#b3b3b3;stroke-width:0.83938956;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path17889"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(1.1827463,0,0,1.2,384.24579,-92.900024)" />
+ <path
+ transform="matrix(0.790122,0,0,0.787736,414.87048,114.05649)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path17891"
+ style="fill:none;stroke:url(#linearGradient18149);stroke-width:1.26754272;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.1827463,0,0,1.2,384.24579,-92.900024)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path17907"
+ style="fill:none;stroke:url(#radialGradient18151);stroke-width:0.67151165;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient18153);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path17909"
+ sodipodi:cx="78"
+ sodipodi:cy="502"
+ sodipodi:rx="2.5312502"
+ sodipodi:ry="2.5"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(0.8888868,0,0,0.8862026,407.16682,64.626266)" />
+ <path
+ transform="matrix(0.1975308,0,0,0.1999991,460.0926,408.10045)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ sodipodi:ry="2.5"
+ sodipodi:rx="2.5312502"
+ sodipodi:cy="502"
+ sodipodi:cx="78"
+ id="path17911"
+ style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ </g>
<path
- transform="matrix(0.8888868,0,0,0.8862026,407.16682,64.626266)"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
+ transform="matrix(-0.71872408,0.04983719,-0.0496867,-0.7165537,559.14667,859.50468)"
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
sodipodi:ry="2.5"
sodipodi:rx="2.5312502"
sodipodi:cy="502"
sodipodi:cx="78"
- id="path17909"
- style="fill:url(#radialGradient18153);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path17913-5"
+ style="opacity:0.7;fill:url(#linearGradient18220);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98985863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
<path
sodipodi:type="arc"
- style="opacity:0.5;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.26754272;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path17911"
+ style="opacity:0.7;fill:url(#linearGradient18212);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98985863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18197"
sodipodi:cx="78"
sodipodi:cy="502"
sodipodi:rx="2.5312502"
sodipodi:ry="2.5"
- d="m 80.53125,502 c 0,1.38071 -1.133279,2.5 -2.53125,2.5 -1.397971,0 -2.53125,-1.11929 -2.53125,-2.5 0,-1.38071 1.133279,-2.5 2.53125,-2.5 1.397971,0 2.53125,1.11929 2.53125,2.5 z"
- transform="matrix(0.1975308,0,0,0.1999991,460.0926,408.10045)" />
+ d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
+ transform="matrix(-0.71872408,0.04983719,-0.0496867,-0.7165537,552.92989,859.50468)" />
</g>
- <path
- sodipodi:type="arc"
- style="opacity:0.69999999999999996;fill:url(#linearGradient18220);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98985862999999996;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path17913-5"
- sodipodi:cx="78"
- sodipodi:cy="502"
- sodipodi:rx="2.5312502"
- sodipodi:ry="2.5"
- d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
- transform="matrix(-0.71872408,0.04983719,-0.0496867,-0.7165537,559.14667,859.50468)" />
- <path
- transform="matrix(-0.71872408,0.04983719,-0.0496867,-0.7165537,552.92989,859.50468)"
- d="m 80.53125,502 a 2.5312502,2.5 0 1 1 -5.0625,0 2.5312502,2.5 0 1 1 5.0625,0 z"
- sodipodi:ry="2.5"
- sodipodi:rx="2.5312502"
- sodipodi:cy="502"
- sodipodi:cx="78"
- id="path18197"
- style="opacity:0.7;fill:url(#linearGradient18212);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98985863;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
<g
style="display:inline;enable-background:new"
- id="g24559-2-1"
+ id="ICON_COLLAPSEMENU"
transform="translate(279.8665,506.92392)">
<rect
y="111"
@@ -88160,7 +88857,7 @@
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Pracownia\Pulpit\sss.png"
transform="translate(102.25002,373)"
- id="g28949"
+ id="ICON_FORCE_SMOKEFLOW"
style="display:inline;enable-background:new">
<rect
style="opacity:0;fill:#808000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.89999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
@@ -88181,7 +88878,7 @@
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
sodipodi:ry="8"
sodipodi:rx="8"
sodipodi:cy="118"
@@ -88199,7 +88896,7 @@
sodipodi:cy="118"
sodipodi:rx="8"
sodipodi:ry="8"
- d="m 140,118 c 0,4.41828 -3.58172,8 -8,8 -4.41828,0 -8,-3.58172 -8,-8 0,-4.41828 3.58172,-8 8,-8 4.41828,0 8,3.58172 8,8 z"
+ d="m 140,118 a 8,8 0 1 1 -16,0 8,8 0 1 1 16,0 z"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
@@ -88267,10 +88964,10 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g24559-2"
+ id="ICON_GRIP"
transform="translate(238,508)">
<path
- style="fill:none;stroke:#c8c8c8;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.8509804;display:inline;enable-background:new"
+ style="fill:none;stroke:#c8c8c8;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.85098039;display:inline;enable-background:new"
d="m 104,121.5 14,0"
id="path16004-2-9"
inkscape:connector-curvature="0"
@@ -88296,185 +88993,177 @@
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
- style="fill:#c6cbd2;stroke:#c8c8c8;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.8509804;display:inline;enable-background:new;fill-opacity:1"
+ style="fill:#c6cbd2;fill-opacity:1;stroke:#c8c8c8;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.85098039;display:inline;enable-background:new"
d="m 104,118.5 14,0"
id="path16004-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
<g
- transform="translate(231.0079,-1.8032526e-6)"
- style="display:inline;enable-background:new"
- id="g28857-3">
+ id="ICON_LINE_DATA">
+ <path
+ id="path16893"
+ style="fill:none;stroke:#000000;stroke-width:0.87399995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 348.62424,478.9785 -2.79722,2.25264 c -0.45164,0.43278 -2.06766,1.48999 -2.83488,3.34099 -0.70812,2.10437 -1.91584,2.91305 -1.91584,2.91305 l 0.6563,0.74552 c 0,0 0.95526,-1.09547 3.13241,-1.53112 1.93333,-0.52639 3.65608,-2.44913 3.65608,-2.44913 l 2.68203,-2.62741"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0"
+ d="m 348.55771,479.10238 -2.72231,2.19232 c -0.43955,0.42119 -2.0123,1.45009 -2.75897,3.25153 -0.68915,2.048 -1.86454,2.83504 -1.86454,2.83504 l 0.63873,0.72555 c 0,0 0.92968,-1.06614 3.04853,-1.49013 1.88155,-0.51228 3.33445,-2.20812 3.57503,-2.32453 l 2.52591,-2.50648"
+ style="fill:url(#linearGradient17026);fill-opacity:1;stroke:none;display:inline;enable-background:new"
+ id="path16897" />
+ <path
+ id="path16907"
+ style="fill:url(#linearGradient17022);fill-opacity:1;stroke:none;display:inline;enable-background:new"
+ d="m 348.39209,479.42958 -2.52447,2.03299 c -0.4076,0.39058 -1.86605,1.34471 -2.55845,3.01522 -0.63908,1.89917 -1.72904,2.62901 -1.72904,2.62901 l 0.59231,0.67282 c 0,0 0.86211,-0.98866 2.82697,-1.38183 1.74481,-0.47506 3.31522,-2.1556 3.31522,-2.1556 l 2.66283,-2.30087"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0"
+ id="path42945"
+ d="m 356.4118,471.99599 -8.85401,6.78865 m 0,0 c 0.48204,0.79328 2.52273,3.35178 3.70101,3.87765 m 0,0 5.60266,-5.62151"
+ style="fill:none;stroke:#000000;stroke-width:1.05365074px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path42949"
+ d="m 356.83119,471.7858 -9.22534,7.0573 c 0.35109,1.06864 2.63524,3.37319 3.7137,3.72187 l 5.84295,-5.72212 c 0,0 -0.0685,-1.274 -0.33131,-5.05705 z"
+ style="fill:url(#linearGradient17018);fill-opacity:1;stroke:none;display:inline;enable-background:new" />
+ <path
+ style="fill:url(#linearGradient17014);fill-opacity:1;stroke:none;display:inline;enable-background:new"
+ d="m 356.93013,474.76525 c 3.9e-4,3.18201 -3.54751,10.33668 -9.15362,4.50809 0.22597,-0.4981 8.93557,-6.84627 8.93557,-6.84627 0.11742,0.85263 0.1517,1.2913 0.21806,2.33818 z"
+ id="path43017"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path42981"
+ d="m 345.11258,484.70023 c 1.615,-1.38333 1.89187,-1.62391 1.89187,-1.62391"
+ style="fill:none;stroke:#000000;stroke-width:0.73395383;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ inkscape:transform-center-y="0.24985078"
+ inkscape:transform-center-x="0.0087216242" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.48930255;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 341.55701,487.70395 c 1.57524,-1.41883 3.88653,-3.26666 3.88653,-3.26666"
+ id="path16832"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+ <g
+ id="ICON_MOD_WIREFRAME">
+ <path
+ style="fill:url(#linearGradient17079);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.80000001;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 307.67222,254.4997 6,3e-4 0,-11 -6,-3e-4 m 0,2.45891 3.65084,0 0,6.10992 -3.71241,0"
+ id="path27671-4-9-2"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="241.00877"
+ x="298.83606"
+ height="16"
+ width="16"
+ id="rect27661-8"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
- id="g17097">
- <rect
- style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect27661-8"
- width="16"
- height="16"
- x="67.828156"
- y="241.00877" />
- <g
- id="g27669-35"
- style="opacity:0.55"
- transform="translate(-167.17184,-18.991228)">
- <path
- inkscape:connector-curvature="0"
- transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
- sodipodi:nodetypes="cccc"
- id="path27671-4"
- d="m 243.50439,274.05251 -6.46154,-3.3e-4 0,-12.12435 6.46154,3.3e-4"
- style="fill:url(#linearGradient42432-1);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.87159598;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
- style="fill:none;stroke:#ffffff;stroke-width:1.08949494;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 243.50439,272.9503 -5.38461,-3.3e-4 0.001,-4.9503 -0.001,-4.96963 5.38461,3.3e-4"
- id="path27673-3"
- sodipodi:nodetypes="ccccc" />
- </g>
- <rect
- style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect27661-8-9"
- width="16"
- height="16"
- x="67.828156"
- y="241.00877" />
- <g
- id="g27669-35-7"
- style="opacity:0.55;display:inline;enable-background:new"
- transform="translate(-167.17184,-18.99123)">
- <path
- inkscape:connector-curvature="0"
- transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
- sodipodi:nodetypes="cccc"
- id="path27671-4-9"
- d="m 243.50439,274.05251 -6.46154,-3.3e-4 0,-12.12435 6.46154,3.3e-4"
- style="fill:url(#linearGradient42432-1-2);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.87159598;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
- style="fill:none;stroke:#ffffff;stroke-width:1.08949494;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 243.50439,272.9503 -5.38461,-3.3e-4 0.001,-4.9503 -0.001,-4.96963 5.38461,3.3e-4"
- id="path27673-3-9"
- sodipodi:nodetypes="ccccc" />
- </g>
- <g
- id="g27669-35-7-7"
- style="display:inline;enable-background:new"
- transform="matrix(-1,0,0,-1,319.16304,516.99093)">
- <path
- inkscape:connector-curvature="0"
- transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
- sodipodi:nodetypes="cccccccc"
- id="path27671-4-9-2"
- d="m 243.50439,261.92816 -6.46154,-3.3e-4 0,12.12435 6.46154,3.3e-4 m 0,-2.71024 -3.93168,0 0,-6.73444 3.99798,0"
- style="fill:url(#linearGradient17037);fill-opacity:1;fill-rule:nonzero;stroke:#0b1728;stroke-width:0.87159598;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- id="path16893"
- style="fill:none;stroke:#000000;stroke-width:0.87399995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
- d="m 201.5467,38.012434 2.79722,-2.25264 c 0.45164,-0.43278 2.06766,-1.48999 2.83488,-3.34099 0.70812,-2.10437 1.91584,-2.91305 1.91584,-2.91305 l -0.6563,-0.74552 c 0,0 -0.95526,1.09547 -3.13241,1.53112 -1.93333,0.52639 -3.65608,2.44913 -3.65608,2.44913 l -2.68203,2.62741"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccc" />
- <path
- sodipodi:nodetypes="cccccccc"
- inkscape:connector-curvature="0"
- d="m 201.61323,37.888554 2.72231,-2.19232 c 0.43955,-0.42119 2.0123,-1.45009 2.75897,-3.25153 0.68915,-2.048 1.86454,-2.83504 1.86454,-2.83504 l -0.63873,-0.72555 c 0,0 -0.92968,1.06614 -3.04853,1.49013 -1.88155,0.51228 -3.33445,2.20812 -3.57503,2.32453 l -2.52591,2.50648"
- style="fill:url(#linearGradient16942-1);fill-opacity:1;stroke:none;display:inline;enable-background:new"
- id="path16897" />
- <path
- id="path16907"
- style="fill:url(#linearGradient16939-4);fill-opacity:1;stroke:none;display:inline;enable-background:new"
- d="m 201.77885,37.561354 2.52447,-2.03299 c 0.4076,-0.39058 1.86605,-1.34471 2.55845,-3.01522 0.63908,-1.89917 1.72904,-2.62901 1.72904,-2.62901 l -0.59231,-0.67282 c 0,0 -0.86211,0.98866 -2.82697,1.38183 -1.74481,0.47506 -3.31522,2.1556 -3.31522,2.1556 l -2.66283,2.30087"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccc" />
- <path
- sodipodi:nodetypes="cccccc"
- inkscape:connector-curvature="0"
- id="path42945"
- d="m 193.75914,44.994944 8.85401,-6.78865 m 0,0 c -0.48204,-0.79328 -2.52273,-3.35178 -3.70101,-3.87765 m 0,0 -5.60266,5.62151"
- style="fill:none;stroke:#000000;stroke-width:1.05365074px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path42949"
- d="m 193.33975,45.205134 9.22534,-7.0573 c -0.35109,-1.06864 -2.63524,-3.37319 -3.7137,-3.72187 l -5.84295,5.72212 c 0,0 0.0685,1.274 0.33131,5.05705 z"
- style="fill:url(#linearGradient16935-4);fill-opacity:1;stroke:none;display:inline;enable-background:new" />
- <path
- style="fill:url(#linearGradient16932-1);fill-opacity:1;stroke:none;display:inline;enable-background:new"
- d="m 193.24081,42.225684 c -3.9e-4,-3.18201 3.54751,-10.33668 9.15362,-4.50809 -0.22597,0.4981 -8.93557,6.84627 -8.93557,6.84627 -0.11742,-0.85263 -0.1517,-1.2913 -0.21806,-2.33818 z"
- id="path43017"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccc" />
- <path
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0"
- id="path42981"
- d="m 205.05836,32.290704 c -1.615,1.38333 -1.89187,1.62391 -1.89187,1.62391"
- style="fill:none;stroke:#000000;stroke-width:0.73395383;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
- inkscape:transform-center-y="0.24985078"
- inkscape:transform-center-x="0.0087216242" />
- <path
- style="fill:none;stroke:#000000;stroke-width:0.48930255;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
- d="m 208.61393,29.286984 c -1.57524,1.41883 -3.88653,3.26666 -3.88653,3.26666"
- id="path16832"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- </g>
+ transform="translate(63.83606,-18.99123)"
+ style="opacity:0.55"
+ id="g27669-35">
<path
- inkscape:connector-curvature="0"
- style="opacity:0.55;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 76.711836,244.47852 5,3e-4 -9.3e-4,4.49123 9.3e-4,4.50877 -5,-3e-4"
- id="path27673-3-9-1"
- sodipodi:nodetypes="ccccc" />
- <g
- id="g27675-8"
- style="display:inline;enable-background:new"
- transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-167.52833,113.52244)">
- <path
- inkscape:connector-curvature="0"
- style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 72.837944,271.51561 7.071067,-7.07107"
- id="path27679-6"
- sodipodi:nodetypes="cc" />
- <path
- inkscape:connector-curvature="0"
- id="path42388-4"
- style="opacity:0.75;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071" />
- <path
- inkscape:connector-curvature="0"
- d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
- style="fill:none;stroke:#ffe991;stroke-width:1.19999993;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path42359-16" />
- </g>
- <g
- id="g27675-8-5"
- style="display:inline;enable-background:new"
- transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-167.52833,113.52244)">
- <path
- inkscape:connector-curvature="0"
- style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 72.837944,271.51561 7.071067,-7.07107"
- id="path27679-6-3"
- sodipodi:nodetypes="cc" />
- <path
- inkscape:connector-curvature="0"
- id="path42388-4-5"
- style="opacity:0.75;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
- d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071" />
- <path
- inkscape:connector-curvature="0"
- d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
- style="fill:none;stroke:#ffe991;stroke-width:1.19999993;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="path42359-16-5" />
- </g>
+ style="fill:url(#linearGradient17057);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.87159598;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 243.50439,274.05251 -6.46154,-3.3e-4 0,-12.12435 6.46154,3.3e-4"
+ id="path27671-4"
+ sodipodi:nodetypes="cccc"
+ transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path27673-3"
+ d="m 243.50439,272.9503 -5.38461,-3.3e-4 0.001,-4.9503 -0.001,-4.96963 5.38461,3.3e-4"
+ style="fill:none;stroke:#ffffff;stroke-width:1.08949494;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ y="241.00877"
+ x="298.83606"
+ height="16"
+ width="16"
+ id="rect27661-8-9"
+ style="opacity:0;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <g
+ transform="translate(63.83606,-18.991232)"
+ style="opacity:0.55;display:inline;enable-background:new"
+ id="g27669-35-7">
+ <path
+ style="fill:url(#linearGradient17059);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.87159598;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 243.50439,274.05251 -6.46154,-3.3e-4 0,-12.12435 6.46154,3.3e-4"
+ id="path27671-4-9"
+ sodipodi:nodetypes="cccc"
+ transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path27673-3-9"
+ d="m 243.50439,272.9503 -5.38461,-3.3e-4 0.001,-4.9503 -0.001,-4.96963 5.38461,3.3e-4"
+ style="fill:none;stroke:#ffffff;stroke-width:1.08949494;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ transform="matrix(0.9285719,0,0,0.9072647,16.387388,24.853058)"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path27673-3-9-1"
+ d="m 307.71974,244.47852 5,3e-4 -9.3e-4,4.49123 9.3e-4,4.50877 -5,-3e-4"
+ style="opacity:0.55;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,63.47957,113.52244)"
+ style="display:inline;enable-background:new"
+ id="g27675-8">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27679-6"
+ d="m 72.837944,271.51561 7.071067,-7.07107"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ style="opacity:0.75;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="path42388-4"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42359-16"
+ style="fill:none;stroke:#ffe991;stroke-width:1.19999993;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,63.47957,113.52244)"
+ style="display:inline;enable-background:new"
+ id="g27675-8-5">
+ <path
+ sodipodi:nodetypes="cc"
+ id="path27679-6-3"
+ d="m 72.837944,271.51561 7.071067,-7.07107"
+ style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ style="opacity:0.75;fill:none;stroke:#28220b;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new"
+ id="path42388-4-5"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path42359-16-5"
+ style="fill:none;stroke:#ffe991;stroke-width:1.19999993;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 71.600508,272.3995 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071 m 2.121321,-2.12133 0.707107,-0.7071 m 2.121319,-2.12133 0.707107,-0.7071"
+ inkscape:connector-curvature="0" />
</g>
</g>
<g
style="display:inline;enable-background:new"
- id="g6603"
+ id="ICON_IPO_BOUNCE"
transform="translate(168.02769,-748.47766)">
<g
id="g16520">
@@ -88510,7 +89199,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g6624"
+ id="ICON_IPO_LINEAR"
transform="translate(84.027695,-748.47996)">
<g
id="g6562">
@@ -88543,7 +89232,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g6558"
+ id="ICON_IPO_CONSTANT"
transform="translate(84.027695,-748.47989)">
<path
sodipodi:nodetypes="cccc"
@@ -88574,7 +89263,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(126.02769,-748.47996)"
- id="g4551">
+ id="ICON_IPO_SINE">
<g
id="g4553">
<path
@@ -88606,7 +89295,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g7689"
+ id="ICON_IPO_QUAD"
transform="translate(147.02769,-748.47996)">
<g
id="g7691">
@@ -88650,7 +89339,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(168.02769,-748.47989)"
- id="g7707">
+ id="ICON_IPO_CUBIC">
<g
id="g7709">
<path
@@ -88692,7 +89381,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g15886"
+ id="ICON_IPO_QUINT"
transform="translate(210.02769,-748.47996)">
<g
id="g15888">
@@ -88736,7 +89425,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(231.02769,-748.47989)"
- id="g15961">
+ id="ICON_IPO_EXPO">
<g
id="g15963">
<path
@@ -88768,7 +89457,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g16027-0"
+ id="ICON_IPO_CIRC"
transform="translate(252.02766,-748.47989)">
<g
id="g16029">
@@ -88802,7 +89491,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(189.02769,-748.48231)"
- id="g16464">
+ id="ICON_IPO_ELASTIC">
<path
sodipodi:nodetypes="ccsssssc"
style="color:#000000;fill:none;stroke:url(#linearGradient17044);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -88831,7 +89520,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g16576"
+ id="ICON_IPO_BACK"
transform="translate(210.02769,-748.47898)">
<path
inkscape:connector-curvature="0"
@@ -88862,7 +89551,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(189.02769,-748.47989)"
- id="g4468">
+ id="ICON_IPO_QUART">
<g
id="g4470">
<path
@@ -88904,7 +89593,7 @@
</g>
<g
transform="translate(336.02769,-748.47858)"
- id="g20295-7-9"
+ id="ICON_IPO_EASE_IN"
style="display:inline;enable-background:new">
<g
id="g20297-2-1">
@@ -88936,7 +89625,7 @@
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
- id="g20305-4-1"
+ id="ICON_IPO_EASE_OUT"
transform="matrix(-1,0,0,-1,467.02769,1162.2412)"
style="display:inline;enable-background:new">
<g
@@ -88970,7 +89659,7 @@
</g>
<g
transform="matrix(-1,0,0,-1,488.02769,1162.2445)"
- id="g20315-6-2"
+ id="ICON_IPO_EASE_IN_OUT"
style="display:inline;enable-background:new">
<g
id="g20317-6-4">
@@ -89004,7 +89693,7 @@
<g
style="display:inline;enable-background:new"
transform="translate(84.027695,-748.48019)"
- id="g20443-5-0">
+ id="ICON_IPO_BEZIER">
<path
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#201308;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 78.565213,960.8622 -8.130425,0"
@@ -89019,7 +89708,7 @@
style="color:#000000;fill:none;stroke:#c86800;stroke-width:1.20000005;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
transform="matrix(-0.83333333,0,0,0.83333,9.5,430.86427)"
- d="m -81,636 c 0,1.65685 -1.343146,3 -3,3 -1.656854,0 -3,-1.34315 -3,-3 0,-1.65685 1.343146,-3 3,-3 1.656854,0 3,1.34315 3,3 z"
+ d="m -81,636 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
sodipodi:ry="3"
sodipodi:rx="3"
sodipodi:cy="636"
@@ -89052,7 +89741,7 @@
sodipodi:cy="636"
sodipodi:rx="3"
sodipodi:ry="3"
- d="m -81,636 c 0,1.65685 -1.343146,3 -3,3 -1.656854,0 -3,-1.34315 -3,-3 0,-1.65685 1.343146,-3 3,-3 1.656854,0 3,1.34315 3,3 z"
+ d="m -81,636 a 3,3 0 1 1 -6,0 3,3 0 1 1 6,0 z"
transform="matrix(0.83333333,0,0,0.83333,142.49996,419.86427)" />
<path
inkscape:connector-curvature="0"
@@ -89100,7 +89789,7 @@
<g
transform="translate(-63.051518,-85.06394)"
style="display:inline;enable-background:new"
- id="g17942-1-7">
+ id="ICON_ACTION_TWEAK">
<rect
y="304"
x="278"
@@ -89270,7 +89959,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g44081-2"
+ id="ICON_NLA_PUSHDOWN"
transform="translate(-231.54762,126.06411)">
<rect
style="opacity:0;fill:#1a1a1a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.20000005;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -89350,7 +90039,7 @@
<g
transform="translate(21,0)"
style="display:inline;enable-background:new"
- id="g106643-9">
+ id="ICON_LOOPSEL">
<g
transform="translate(111,-158)"
id="g35778-7"
@@ -89436,12 +90125,12 @@
y="185" />
<g
id="g35818-3"
- style="fill:url(#radialGradient17275);display:inline;fill-opacity:1"
+ style="fill:url(#radialGradient17275);fill-opacity:1;display:inline"
transform="translate(-1080.9861,-256)">
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc"
- style="fill:url(#radialGradient17275);fill-opacity:1;fill-rule:nonzero;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.86274510000000004;stroke-dasharray:none;stroke-dashoffset:7.40000265000000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ style="fill:url(#radialGradient17275);fill-opacity:1;fill-rule:nonzero;stroke:#542b00;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.8627451;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 1130.4859,445.25 0,-7.5 6,2.75 0,8 -6,-3.25 z"
id="path35820-8"
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
@@ -89454,7 +90143,7 @@
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\blender-cvs-windows\.blender\.blender\icons\jendrzych's iconset.png"
id="path35822-7"
d="m 1136.4859,448.5 -6,-3.25 0,-7.5"
- style="fill:url(#radialGradient17275);stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265000000024;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;fill-opacity:1"
+ style="fill:url(#radialGradient17275);fill-opacity:1;stroke:#462400;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:7.40000265;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:nodetypes="ccc" />
</g>
<g
@@ -89478,7 +90167,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g24917-1"
+ id="ICON_TRIA_RIGHT_BAR"
transform="translate(405,298)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -89515,35 +90204,7 @@
</g>
<g
style="display:inline;enable-background:new"
- id="g24917-1-9"
- transform="matrix(0,1,-1,0,573,305)">
- <rect
- style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect24907-8-8"
- width="16"
- height="16"
- x="62"
- y="69" />
- <g
- id="g17605-6"
- transform="translate(-1.5467961,-0.48613592)">
- <path
- sodipodi:nodetypes="ccccccccccc"
- inkscape:connector-curvature="0"
- d="m 72.839729,82.521675 2.731705,0 0,-10.016275 -2.731705,0 L 72.84,76.59374 68.51011,72.5 67.4632,72.53125 67.5,82.49999 68.51011,82.5 72.84,78.43749 z"
- style="fill:url(#linearGradient17610-2);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000000999999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path11011-6-8" />
- <path
- style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- d="m 68.5,81.24999 0,-7.5"
- id="path11013-5-6"
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0" />
- </g>
- </g>
- <g
- style="display:inline;enable-background:new"
- id="g24917-1-7"
+ id="ICON_TRIA_LEFT_BAR"
transform="matrix(-1,0,0,1,587.07183,298.10012)">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -89579,51 +90240,310 @@
</g>
</g>
<g
- style="display:inline;enable-background:new"
- id="g24917-1-7-1"
- transform="matrix(0,-1,-1,0,615,445)">
+ id="ICON_TRIA_UP_BAR">
<rect
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect24907-8-5-7"
width="16"
height="16"
- x="62"
- y="69" />
+ x="-383"
+ y="-546"
+ transform="matrix(0,-1,-1,0,0,0)" />
+ <path
+ id="path11011-6-2-1"
+ style="fill:url(#linearGradient17165);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 532.96447,373.70707 0,-2.7317 10.01627,0 0,2.7317 -4.08834,-2.7e-4 4.09374,4.32989 -0.0312,1.04691 -9.96874,-0.0368 -1e-5,-1.01011 4.06251,-4.32989 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc"
+ id="path11013-5-7-1"
+ d="m 541.73615,378.0468 -3.75,-4 -3.75,4"
+ style="fill:none;stroke:url(#linearGradient17162);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path10830-6-2-8"
+ d="m 542.11634,371.83103 -8.26386,0 -6e-5,0.90043"
+ style="fill:none;stroke:url(#linearGradient17838);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <g
+ id="ICON_TRIA_DOWN_BAR">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect24907-8-8"
+ width="16"
+ height="16"
+ x="367"
+ y="-504"
+ transform="matrix(0,1,-1,0,0,0)" />
+ <path
+ id="path11011-6-8"
+ style="fill:url(#linearGradient17185);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 490.96446,376.29293 0,2.7317 10.01628,0 0,-2.7317 -4.08834,2.7e-4 4.09374,-4.32989 -0.0312,-1.04691 -9.96874,0.0368 -10e-6,1.01011 4.06251,4.32989 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc"
+ id="path11013-5-6"
+ d="m 492.23615,371.9532 7.5,0"
+ style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ id="path10830-6-2-8-8"
+ d="m 500.10071,377.17478 -8.26386,0 -6e-5,0.90043"
+ style="fill:none;stroke:url(#linearGradient17872);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
+ sodipodi:nodetypes="ccc" />
+ </g>
+ <g
+ id="ICON_MOD_DATA_TRANSFER">
+ <rect
+ ry="1.4918556"
+ rx="1.4927195"
+ y="241"
+ x="320"
+ height="16"
+ width="16"
+ id="rect18203"
+ style="fill:none;stroke:none" />
<g
- id="g17605-3-7"
- transform="translate(-1.5467961,-0.48613592)">
+ id="g18198"
+ transform="matrix(1.0087429,0,0,0.97482999,-108.8466,-32.496743)">
<path
- sodipodi:nodetypes="ccccccccccc"
+ style="fill:url(#linearGradient18237);fill-opacity:1;stroke:#000000;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 425.50477,292.38372 15.04989,-10.90405 -0.0101,6.77582 -9.51239,8.38266 z"
+ id="rect16727"
inkscape:connector-curvature="0"
- d="m 72.839729,82.521675 2.731705,0 0,-10.016275 -2.731705,0 L 72.84,76.59374 68.51011,72.5 67.4632,72.53125 67.5,82.49999 68.51011,82.5 72.84,78.43749 z"
- style="fill:url(#linearGradient17610-0-6);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000000999999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path11011-6-2-1" />
+ sodipodi:nodetypes="ccccc" />
<path
- style="fill:none;stroke:url(#linearGradient17614-0-2);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- d="m 68.5,73.74999 4,3.75 -4,3.75"
- id="path11013-5-7-1"
- sodipodi:nodetypes="ccc"
+ style="fill:none;stroke:url(#linearGradient18239);stroke-width:0.94270116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;enable-background:new"
+ d="m 439.79125,287.61126 -8.80214,7.81233 -3.87477,-2.96997 12.64026,-9.16307"
+ id="rect16727-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ transform="matrix(0.74622014,-0.66569926,0.64008794,0.76830165,0,0)"
+ style="fill:url(#linearGradient20049);fill-opacity:1;stroke:none"
+ d="m 155.67553,506.23194 -0.63498,0.7272 c 0,0 -7.96167,0.0866 -11.40538,0.0765 -1.63408,-0.005 -1.64706,-1.90745 -0.31608,-1.84971 3.85215,0.16711 12.35647,1.04592 12.35647,1.04592 z"
+ id="rect20031"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccsscc" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path18412"
+ d="m 321.20705,242.0789 c 2.69584,0.64081 4.09152,0.77931 6.28874,0.55186 0.26517,2.2318 0.84364,4.80456 2.06664,6.25861 -2.05408,-0.68406 -3.57488,-1.60349 -4.80908,-2.47909 -1.36678,-1.11314 -2.52984,-2.47523 -3.5463,-4.33138 z"
+ style="fill:url(#linearGradient17247);fill-opacity:1;stroke:none" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0"
+ id="rect16727-5"
+ d="m 328.56164,246.05078 c 0.74079,0.0537 1.77983,-0.45053 6.98113,-4.18925 0,3.08648 -0.0102,4.09418 -0.0102,6.60528 -0.44523,0.50349 -6.55549,5.26941 -7.72056,-6.20333 -3.16507,0.27726 -4.58746,0.0819 -7.26323,-0.75675 1.35238,2.92568 2.86698,4.41322 4.56976,5.5869 2.04461,1.35744 4.27186,2.25425 6.46319,2.69448"
+ style="fill:none;stroke:#1a1a1a;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.49803922;stroke-dasharray:none" />
+ <path
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0"
+ id="path18412-1"
+ d="m 324.68994,246.54277 c -0.64862,-0.68224 -1.98282,-2.30701 -2.71202,-3.8538 2.07872,0.5568 3.84489,0.49023 5.15615,0.37259 0.26517,2.2318 0.88783,4.31843 1.67994,5.209"
+ style="fill:none;stroke:url(#linearGradient17243);stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.49803922;stroke-dasharray:none;display:inline;enable-background:new" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path18485"
+ d="m 335.20234,242.58443 c 0,0.84375 -0.005,3.9971 -0.005,5.75999 -2.37119,1.76035 -4.7166,1.79719 -6.03803,-1.54307 1.55369,-1.16687 6.02002,-4.2052 6.02002,-4.2052 z"
+ style="fill:url(#linearGradient17239);fill-opacity:1;stroke:none" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path20010"
+ d="m 335.21342,245.56494 c 0,0 0.0166,0.39923 0.0166,1.01647 -0.82312,0.76235 -3.0673,2.74764 -4.18325,2.66033 -0.29848,-0.14345 -0.39809,-0.20898 -0.62335,-0.46278 1.10175,-0.45288 2.17708,-1.29548 4.79,-3.21402 z"
+ style="fill:url(#linearGradient17236);fill-opacity:1;stroke:none" />
+ <path
+ sodipodi:nodetypes="cssc"
+ inkscape:connector-curvature="0"
+ id="path18570"
+ d="m 329.53955,248.87963 c -1.41211,-0.48222 -3.92872,-1.40598 -4.73299,-4.22946 -0.39317,-1.38024 1.7085,-1.41702 1.92756,-0.24049 0.45159,2.42548 1.89945,3.56397 2.80543,4.46995 z"
+ style="fill:#ffe991;fill-opacity:1;stroke:none" />
+ </g>
+ <g
+ transform="translate(-264,-151.9)"
+ id="ICON_FILE_HIDDEN"
+ style="fill:url(#linearGradient17223);fill-opacity:1;display:inline;enable-background:new">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:url(#linearGradient17215);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;display:inline"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ id="path39241-60"
+ sodipodi:nodetypes="cccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ sodipodi:nodetypes="cccccc"
+ id="path39243-9"
+ d="m 756.16666,204.50001 10.33334,0 0,14.99999 -13,0 -10e-6,-11.99999 2.66667,-3 z"
+ style="opacity:0.3;fill:url(#radialGradient17217);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path39245-1"
+ style="fill:none;stroke:url(#linearGradient17219);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 754.5,209 0,9.5 m 3.5,-13 7.5,0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc"
+ id="path39247-8"
+ d="m 753,208 4,0 0,-4 -4,4 z"
+ style="fill:#ffffff;fill-opacity:0.49803922;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc"
+ id="path39249-0"
+ style="fill:none;stroke:#7f7f7f;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 753.5,207.00001 0,12.49999 13,0 0,-14.99999 -10.5,0 -2.5,2.5 z"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:url(#linearGradient17221);stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 757.5,206.5 0,2 -2,0"
+ id="path39251-2" />
+ </g>
+ <g
+ id="ICON_BLANK1"
+ transform="matrix(1.0063645,0,0,0.9519664,-3.4857036,27.417198)">
+ <rect
+ y="577.31323"
+ x="530.11182"
+ height="16.807316"
+ width="15.898812"
+ id="rect17730"
+ style="fill:none;stroke:none" />
+ </g>
+ <g
+ id="ICON_SCULPT_DYNTOPO">
+ <rect
+ y="178"
+ x="467"
+ height="16"
+ width="16"
+ id="rect18509"
+ style="fill:none;stroke:none" />
+ </g>
+ <g
+ style="display:inline;enable-background:new"
+ id="ICON_MOD_NORMALEDIT"
+ transform="translate(105,-19)">
+ <rect
+ style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect18695-8"
+ width="16"
+ height="16"
+ x="236"
+ y="260" />
+ <g
+ id="g18697-9"
+ transform="translate(-86,370.75)">
+ <path
+ style="fill:none;stroke:#0b1728;stroke-width:1.70000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 330,-107.75 -5,2 0.0372,6.324398 5,2.71875 4.99999,-2.71875 L 335,-105.75 l -5,-2 z"
+ id="path18699-5"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18719-5"
+ d="m 330.03717,-107.6131 -5,1.875 0,6.312498 5,2.71875 4.99999,-2.71875 0,-6.312498 -4.99999,-1.875 z"
+ style="fill:url(#linearGradient16862);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g18703-7"
+ transform="translate(179,-179)">
+ <path
+ id="path18707-1"
+ d="m 146.0019,73.295281 5,-1.894157 5,1.894157 -5,2.073959 -5,-2.073959 z"
+ style="fill:url(#linearGradient16864);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.06666696px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\4.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="path18763-1"
+ d="m 335,-105.5 -5,2 0,6.75 5,-2.75 0,-6 z"
+ style="fill:url(#linearGradient16866);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path18709-8"
+ d="m 334.5,-105.25 0.002,5.587357 -4.5,2.480073 -4.5,-2.480073 -0.002,-5.587357 4.5,-1.75 4.5,1.75 z"
+ style="fill:none;stroke:url(#linearGradient16868);stroke-width:0.99999982px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path18758-5"
+ style="opacity:0.8;fill:none;stroke:#d7e3f4;stroke-width:3.29999995;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ d="m 330.25,-103.25 3.25,-1.5"
+ sodipodi:nodetypes="cc"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g18737-4"
+ style="opacity:0.7" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="M 330.25,-103.25 335,-105.5"
+ style="fill:#0b1728;fill-opacity:1;fill-rule:evenodd;stroke:#0b1728;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18760-7"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 325.34712,-100.90914 4.75,-2.25"
+ style="fill:#dd23dd;fill-opacity:1;fill-rule:evenodd;stroke:#dd23dd;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18760-7-5"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 330.29093,-103.24155 -0.0238,-5.2559"
+ style="fill:#dd23dd;fill-opacity:1;fill-rule:evenodd;stroke:#dd23dd;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18760-7-5-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\Kopia blender\.blender\icons\blender's iconset.png"
+ sodipodi:nodetypes="cc"
+ d="m 330.36378,-103.20969 4.94432,1.78292"
+ style="fill:#dd23dd;fill-opacity:1;fill-rule:evenodd;stroke:#dd23dd;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path18760-7-5-6-3"
inkscape:connector-curvature="0" />
</g>
</g>
- <path
- sodipodi:nodetypes="ccc"
- style="fill:none;stroke:url(#linearGradient17838);stroke-width:0.92071104000000004px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
- d="m 542.11634,371.83103 -8.26386,0 -6e-5,0.90043"
- id="path10830-6-2-8"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="ccc"
- style="fill:none;stroke:url(#linearGradient17872);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
- d="m 500.10071,377.17478 -8.26386,0 -6e-5,0.90043"
- id="path10830-6-2-8-8"
- inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- inkscape:connector-curvature="0" />
</g>
<g
inkscape:groupmode="layer"
diff --git a/release/datafiles/blender_icons16/icon16_border_lasso.dat b/release/datafiles/blender_icons16/icon16_border_lasso.dat
index ef9aca6f770..d9f85920e42 100644
--- a/release/datafiles/blender_icons16/icon16_border_lasso.dat
+++ b/release/datafiles/blender_icons16/icon16_border_lasso.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_camera_stereo.dat b/release/datafiles/blender_icons16/icon16_camera_stereo.dat
index 0ccc1a69ee6..77fe8c0b686 100644
--- a/release/datafiles/blender_icons16/icon16_camera_stereo.dat
+++ b/release/datafiles/blender_icons16/icon16_camera_stereo.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_disclosure_tri_down.dat b/release/datafiles/blender_icons16/icon16_disclosure_tri_down.dat
index 7d2df0227b1..9933c973832 100644
--- a/release/datafiles/blender_icons16/icon16_disclosure_tri_down.dat
+++ b/release/datafiles/blender_icons16/icon16_disclosure_tri_down.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_file_hidden.dat b/release/datafiles/blender_icons16/icon16_file_hidden.dat
new file mode 100644
index 00000000000..19b5eda9d6b
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_file_hidden.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_image_rgb_alpha.dat b/release/datafiles/blender_icons16/icon16_image_rgb_alpha.dat
index d1c0facfba9..600c1af21fa 100644
--- a/release/datafiles/blender_icons16/icon16_image_rgb_alpha.dat
+++ b/release/datafiles/blender_icons16/icon16_image_rgb_alpha.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_mod_data_transfer.dat b/release/datafiles/blender_icons16/icon16_mod_data_transfer.dat
new file mode 100644
index 00000000000..bc80043da78
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_mod_data_transfer.dat
Binary files differ
diff --git a/release/datafiles/blender_icons16/icon16_mod_normaledit.dat b/release/datafiles/blender_icons16/icon16_mod_normaledit.dat
new file mode 100644
index 00000000000..1c4898f80d8
--- /dev/null
+++ b/release/datafiles/blender_icons16/icon16_mod_normaledit.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_border_lasso.dat b/release/datafiles/blender_icons32/icon32_border_lasso.dat
index 186e16524fd..8be83a26fd2 100644
--- a/release/datafiles/blender_icons32/icon32_border_lasso.dat
+++ b/release/datafiles/blender_icons32/icon32_border_lasso.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_camera_stereo.dat b/release/datafiles/blender_icons32/icon32_camera_stereo.dat
index 72464c72e06..b78b473e085 100644
--- a/release/datafiles/blender_icons32/icon32_camera_stereo.dat
+++ b/release/datafiles/blender_icons32/icon32_camera_stereo.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_disclosure_tri_down.dat b/release/datafiles/blender_icons32/icon32_disclosure_tri_down.dat
index adcfe24f575..61ef16becbe 100644
--- a/release/datafiles/blender_icons32/icon32_disclosure_tri_down.dat
+++ b/release/datafiles/blender_icons32/icon32_disclosure_tri_down.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_file_hidden.dat b/release/datafiles/blender_icons32/icon32_file_hidden.dat
new file mode 100644
index 00000000000..373fa44f192
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_file_hidden.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_image_rgb_alpha.dat b/release/datafiles/blender_icons32/icon32_image_rgb_alpha.dat
index 9822cb5843e..1ea37a941a4 100644
--- a/release/datafiles/blender_icons32/icon32_image_rgb_alpha.dat
+++ b/release/datafiles/blender_icons32/icon32_image_rgb_alpha.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_mod_data_transfer.dat b/release/datafiles/blender_icons32/icon32_mod_data_transfer.dat
new file mode 100644
index 00000000000..48881cfcc3b
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_mod_data_transfer.dat
Binary files differ
diff --git a/release/datafiles/blender_icons32/icon32_mod_normaledit.dat b/release/datafiles/blender_icons32/icon32_mod_normaledit.dat
new file mode 100644
index 00000000000..26cce5507be
--- /dev/null
+++ b/release/datafiles/blender_icons32/icon32_mod_normaledit.dat
Binary files differ
diff --git a/release/datafiles/colormanagement/config.ocio b/release/datafiles/colormanagement/config.ocio
index 1d2c730ecab..1cf9a3bb36e 100644
--- a/release/datafiles/colormanagement/config.ocio
+++ b/release/datafiles/colormanagement/config.ocio
@@ -25,7 +25,7 @@ roles:
# Default color space sequencer is working in
default_sequencer: sRGB
- # Color spaces for color picking and exture painting (not internally supported yet)
+ # Color spaces for color picking and texture painting (not internally supported yet)
color_picking: Raw
texture_paint: Raw
diff --git a/release/datafiles/ctodata.py b/release/datafiles/ctodata.py
index a81a10102dc..079f6c3b918 100755
--- a/release/datafiles/ctodata.py
+++ b/release/datafiles/ctodata.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***** BEGIN GPL LICENSE BLOCK *****
diff --git a/release/datafiles/datatoc.py b/release/datafiles/datatoc.py
index f1fce08d7dd..0caef70c912 100755
--- a/release/datafiles/datatoc.py
+++ b/release/datafiles/datatoc.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***** BEGIN GPL LICENSE BLOCK *****
diff --git a/release/datafiles/locale b/release/datafiles/locale
-Subproject 02219a4540795d90bf3668940eba6c8c37e8928
+Subproject c651e63a9a537624f639950f3127a1dee29205d
diff --git a/release/datafiles/prvicons.png b/release/datafiles/prvicons.png
index f8f744aadb3..7209385da9c 100644
--- a/release/datafiles/prvicons.png
+++ b/release/datafiles/prvicons.png
Binary files differ
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index 76bb67b7263..a3e9afe6403 100644
--- a/release/datafiles/splash.png
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/datafiles/splash_2x.png b/release/datafiles/splash_2x.png
index c0eaba50460..d45b9952633 100644
--- a/release/datafiles/splash_2x.png
+++ b/release/datafiles/splash_2x.png
Binary files differ
diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend
index 8b58493fe3a..23bb2646a54 100644
--- a/release/datafiles/startup.blend
+++ b/release/datafiles/startup.blend
Binary files differ
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject b714750bf00bd6aaf2c87afad533eb01b68861b
+Subproject 3fc5b82c6bdba2f9c954fbf497621b9bb794a1b
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
-Subproject ea70fe1bab8187b4df8bd8b4aed8314c20b0b44
+Subproject cf842d8bb7b0033ca4fa99f7ebedcbd3810fd27
diff --git a/release/scripts/freestyle/modules/freestyle/chainingiterators.py b/release/scripts/freestyle/modules/freestyle/chainingiterators.py
index 52f22b3e8be..fc9de6475b2 100644
--- a/release/scripts/freestyle/modules/freestyle/chainingiterators.py
+++ b/release/scripts/freestyle/modules/freestyle/chainingiterators.py
@@ -275,7 +275,7 @@ class pySketchyChainSilhouetteIterator(ChainingIterator):
class pySketchyChainingIterator(ChainingIterator):
"""
- Chaining iterator designed for sketchy style. It chaines the same
+ Chaining iterator designed for sketchy style. It chains the same
ViewEdge several times in order to produce multiple strokes per
ViewEdge.
"""
@@ -320,7 +320,7 @@ class pyFillOcclusionsRelativeChainingIterator(ChainingIterator):
Builds a pyFillOcclusionsRelativeChainingIterator object.
- :arg percent: The maximul length of the occluded part, expressed
+ :arg percent: The maximal length of the occluded part, expressed
in a percentage of the total chain length.
:type percent: float
"""
@@ -454,7 +454,7 @@ class pyFillOcclusionsAbsoluteAndRelativeChainingIterator(ChainingIterator):
Builds a pyFillOcclusionsAbsoluteAndRelativeChainingIterator object.
- :arg percent: The maximul length of the occluded part as a
+ :arg percent: The maximal length of the occluded part as a
percentage of the total chain length.
:type percent: float
:arg l: Absolute length.
@@ -524,7 +524,7 @@ class pyFillQi0AbsoluteAndRelativeChainingIterator(ChainingIterator):
Builds a pyFillQi0AbsoluteAndRelativeChainingIterator object.
- :arg percent: The maximul length of the occluded part as a
+ :arg percent: The maximal length of the occluded part as a
percentage of the total chain length.
:type percent: float
:arg l: Absolute length.
diff --git a/release/scripts/freestyle/modules/freestyle/shaders.py b/release/scripts/freestyle/modules/freestyle/shaders.py
index 93a7b270544..61365e8dd87 100644
--- a/release/scripts/freestyle/modules/freestyle/shaders.py
+++ b/release/scripts/freestyle/modules/freestyle/shaders.py
@@ -189,7 +189,7 @@ class pyConstantThicknessShader(StrokeShader):
class pyFXSVaryingThicknessWithDensityShader(StrokeShader):
"""
- Assings thickness to a stroke based on the density of the diffuse map.
+ Assigns thickness to a stroke based on the density of the diffuse map.
"""
def __init__(self, wsize, threshold_min, threshold_max, thicknessMin, thicknessMax):
StrokeShader.__init__(self)
@@ -600,7 +600,7 @@ class pyTimeColorShader(StrokeShader):
class pySamplingShader(StrokeShader):
"""
- Resamples the stroke, which gives the stroke the ammount of
+ Resamples the stroke, which gives the stroke the amount of
vertices specified.
"""
def __init__(self, sampling):
@@ -776,7 +776,7 @@ class pyTVertexRemoverShader(StrokeShader):
class pyHLRShader(StrokeShader):
"""
- Controlls visibility based upon the quantative invisibility (QI)
+ Controls visibility based upon the quantitative invisibility (QI)
based on hidden line removal (HLR).
"""
def shade(self, stroke):
@@ -874,7 +874,7 @@ class pyBluePrintCirclesShader(StrokeShader):
R = self.__random_radius
C = self.__random_center
- # The directions (and phases) are calculated using a seperate
+ # The directions (and phases) are calculated using a separate
# function decorated with an lru-cache. This guarantees that
# the directions (involving sin and cos) are calculated as few
# times as possible.
@@ -942,7 +942,7 @@ class pyBluePrintEllipsesShader(StrokeShader):
c = prev_center + (center - prev_center) * phase
svert.point = (c.x + r.x * direction.x, c.y + r.y * direction.y)
- # remove exessive vertices
+ # remove excess vertices
if not it.is_end:
it.increment()
for sv in tuple(it):
@@ -1004,7 +1004,7 @@ class pyBluePrintSquaresShader(StrokeShader):
points = tuple(p + rand for (p, rand) in zip(points, randomization_mat))
- # substract even from uneven; result is length four tuple of vectors
+ # subtract even from uneven; result is length four tuple of vectors
it = iter(points)
old_vecs = tuple(next(it) - current for current in it)
@@ -1028,7 +1028,7 @@ class pyBluePrintSquaresShader(StrokeShader):
# special case; remove these vertices
verticesToRemove.append(svert)
- # remove exessive vertices (if any)
+ # remove excess vertices (if any)
if not it.is_end:
it.increment()
verticesToRemove += [svert for svert in it]
@@ -1066,7 +1066,7 @@ class pyBluePrintDirectedSquaresShader(StrokeShader):
sqrt_coeff = sqrt(trace * trace - 4 * det)
lambda1, lambda2 = (trace + sqrt_coeff) / 2, (trace - sqrt_coeff) / 2
- # make sure those numers aren't to small, if they are, rooting them will yield complex numbers
+ # make sure those numbers aren't to small, if they are, rooting them will yield complex numbers
lambda1, lambda2 = max(1e-12, lambda1), max(1e-12, lambda2)
theta = atan(2 * p_var_xy / (p_var.x - p_var.y)) / 2
@@ -1119,7 +1119,7 @@ class pyBluePrintDirectedSquaresShader(StrokeShader):
# special case; remove these vertices
verticesToRemove.append(svert)
- # remove exessive vertices
+ # remove excess vertices
if not it.is_end:
it.increment()
verticesToRemove += [svert for svert in it]
diff --git a/release/scripts/freestyle/modules/freestyle/utils.py b/release/scripts/freestyle/modules/freestyle/utils.py
index 6c5e1d5887a..224734d5bfb 100644
--- a/release/scripts/freestyle/modules/freestyle/utils.py
+++ b/release/scripts/freestyle/modules/freestyle/utils.py
@@ -221,7 +221,7 @@ def iter_material_value(stroke, func, attribute):
value = rgb_to_bw(*material.diffuse[0:3])
elif attribute == 'SPEC':
value = rgb_to_bw(*material.specular[0:3])
- # line seperate
+ # line separate
elif attribute == 'LINE_R':
value = material.line[0]
elif attribute == 'LINE_G':
@@ -230,7 +230,7 @@ def iter_material_value(stroke, func, attribute):
value = material.line[2]
elif attribute == 'LINE_A':
value = material.line[3]
- # diffuse seperate
+ # diffuse separate
elif attribute == 'DIFF_R':
value = material.diffuse[0]
elif attribute == 'DIFF_G':
@@ -239,7 +239,7 @@ def iter_material_value(stroke, func, attribute):
value = material.diffuse[2]
elif attribute == 'ALPHA':
value = material.diffuse[3]
- # specular seperate
+ # specular separate
elif attribute == 'SPEC_R':
value = material.specular[0]
elif attribute == 'SPEC_G':
@@ -262,7 +262,7 @@ def iter_distance_along_stroke(stroke):
distance += (prev - curr).length
yield distance
-# -- mathmatical operations -- #
+# -- mathematical operations -- #
def stroke_curvature(it):
diff --git a/release/scripts/freestyle/modules/parameter_editor.py b/release/scripts/freestyle/modules/parameter_editor.py
index 9ac5c665f1e..d4765847450 100644
--- a/release/scripts/freestyle/modules/parameter_editor.py
+++ b/release/scripts/freestyle/modules/parameter_editor.py
@@ -97,7 +97,7 @@ from freestyle.utils import (
stroke_normal,
bound,
pairwise,
- BoundedProperty
+ BoundedProperty,
)
from _freestyle import (
blendRamp,
@@ -110,6 +110,12 @@ from mathutils import Vector
from math import pi, sin, cos, acos, radians
from itertools import cycle, tee
+# lists of callback functions
+# WARNING: highly experimental, not a stable API
+callbacks_lineset_pre = []
+callbacks_modifiers_post = []
+callbacks_lineset_post = []
+
class ColorRampModifier(StrokeShader):
"""Primitive for the color modifiers."""
@@ -274,7 +280,7 @@ class ColorAlongStrokeShader(ColorRampModifier):
class AlphaAlongStrokeShader(CurveMappingModifier):
- """Maps a curve to the alpha/transparancy of the stroke, using the curvilinear abscissa (t)."""
+ """Maps a curve to the alpha/transparency of the stroke, using the curvilinear abscissa (t)."""
def shade(self, stroke):
for svert, t in zip(stroke, iter_t2d_along_stroke(stroke)):
a = svert.attribute.alpha
@@ -878,6 +884,21 @@ class Seed:
_seed = Seed()
+def get_dashed_pattern(linestyle):
+ """Extracts the dashed pattern from the various UI options """
+ pattern = []
+ if linestyle.dash1 > 0 and linestyle.gap1 > 0:
+ pattern.append(linestyle.dash1)
+ pattern.append(linestyle.gap1)
+ if linestyle.dash2 > 0 and linestyle.gap2 > 0:
+ pattern.append(linestyle.dash2)
+ pattern.append(linestyle.gap2)
+ if linestyle.dash3 > 0 and linestyle.gap3 > 0:
+ pattern.append(linestyle.dash3)
+ pattern.append(linestyle.gap3)
+ return pattern
+
+
integration_types = {
'MEAN': IntegrationType.MEAN,
'MIN': IntegrationType.MIN,
@@ -887,13 +908,16 @@ integration_types = {
# main function for parameter processing
-
def process(layer_name, lineset_name):
scene = getCurrentScene()
layer = scene.render.layers[layer_name]
lineset = layer.freestyle_settings.linesets[lineset_name]
linestyle = lineset.linestyle
+ # execute line set pre-processing callback functions
+ for fn in callbacks_lineset_pre:
+ fn(scene, layer, lineset)
+
selection_criteria = []
# prepare selection criteria by visibility
if lineset.select_by_visibility:
@@ -1172,24 +1196,26 @@ def process(layer_name, lineset_name):
has_tex = True
if has_tex:
shaders_list.append(StrokeTextureStepShader(linestyle.texture_spacing))
+
+ # execute post-base stylization callbacks
+ for fn in callbacks_modifiers_post:
+ shaders_list.extend(fn(scene, layer, lineset))
+
# -- Stroke caps -- #
if linestyle.caps == 'ROUND':
shaders_list.append(RoundCapShader())
elif linestyle.caps == 'SQUARE':
shaders_list.append(SquareCapShader())
+
# -- Dashed line -- #
if linestyle.use_dashed_line:
- pattern = []
- if linestyle.dash1 > 0 and linestyle.gap1 > 0:
- pattern.append(linestyle.dash1)
- pattern.append(linestyle.gap1)
- if linestyle.dash2 > 0 and linestyle.gap2 > 0:
- pattern.append(linestyle.dash2)
- pattern.append(linestyle.gap2)
- if linestyle.dash3 > 0 and linestyle.gap3 > 0:
- pattern.append(linestyle.dash3)
- pattern.append(linestyle.gap3)
+ pattern = get_dashed_pattern(linestyle)
if len(pattern) > 0:
shaders_list.append(DashedLineShader(pattern))
+
# create strokes using the shaders list
Operators.create(TrueUP1D(), shaders_list)
+
+ # execute line set post-processing callback functions
+ for fn in callbacks_lineset_post:
+ fn(scene, layer, lineset)
diff --git a/release/scripts/freestyle/styles/anisotropic_diffusion.py b/release/scripts/freestyle/styles/anisotropic_diffusion.py
index b17e5c2a38c..fc136b23d82 100644
--- a/release/scripts/freestyle/styles/anisotropic_diffusion.py
+++ b/release/scripts/freestyle/styles/anisotropic_diffusion.py
@@ -19,7 +19,7 @@
# Filename : anisotropic_diffusion.py
# Author : Fredo Durand
# Date : 12/08/2004
-# Purpose : Smoothes lines using an anisotropic diffusion scheme
+# Purpose : Smooth lines using an anisotropic diffusion scheme
from freestyle.chainingiterators import ChainPredicateIterator
from freestyle.predicates import (
@@ -34,7 +34,6 @@ from freestyle.shaders import (
ConstantThicknessShader,
IncreasingColorShader,
SamplingShader,
- StrokeTextureShader,
pyDiffusion2Shader,
)
from freestyle.types import Operators, Stroke
@@ -50,7 +49,6 @@ bpred = TrueBP1D()
Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(upred))
shaders_list = [
ConstantThicknessShader(4),
- StrokeTextureShader("smoothAlpha.bmp", Stroke.OPAQUE_MEDIUM, False),
SamplingShader(2),
pyDiffusion2Shader(offset, nbIter),
IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
diff --git a/release/scripts/freestyle/styles/apriori_density.py b/release/scripts/freestyle/styles/apriori_density.py
index b52bcfbeb4e..1de2c4c0334 100644
--- a/release/scripts/freestyle/styles/apriori_density.py
+++ b/release/scripts/freestyle/styles/apriori_density.py
@@ -19,7 +19,7 @@
# Filename : apriori_density.py
# Author : Stephane Grabli
# Date : 04/08/2005
-# Purpose : Draws lines having a high a priori density
+# Purpose : Draws lines having a high a prior density
from freestyle.chainingiterators import ChainPredicateIterator
from freestyle.predicates import (
diff --git a/release/scripts/freestyle/styles/backbone_stretcher.py b/release/scripts/freestyle/styles/backbone_stretcher.py
index 3eb921ddb34..cc495f33716 100644
--- a/release/scripts/freestyle/styles/backbone_stretcher.py
+++ b/release/scripts/freestyle/styles/backbone_stretcher.py
@@ -30,7 +30,6 @@ from freestyle.predicates import (
from freestyle.shaders import (
BackboneStretcherShader,
ConstantColorShader,
- TextureAssignerShader,
)
from freestyle.types import Operators
@@ -38,7 +37,6 @@ from freestyle.types import Operators
Operators.select(QuantitativeInvisibilityUP1D(0))
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0)))
shaders_list = [
- TextureAssignerShader(4),
ConstantColorShader(0.5, 0.5, 0.5),
BackboneStretcherShader(20),
]
diff --git a/release/scripts/freestyle/styles/blueprint_circles.py b/release/scripts/freestyle/styles/blueprint_circles.py
index aade164698a..f39cda5cff9 100644
--- a/release/scripts/freestyle/styles/blueprint_circles.py
+++ b/release/scripts/freestyle/styles/blueprint_circles.py
@@ -34,7 +34,6 @@ from freestyle.predicates import (
from freestyle.shaders import (
ConstantThicknessShader,
IncreasingColorShader,
- TextureAssignerShader,
pyBluePrintCirclesShader,
pyPerlinNoise1DShader,
)
@@ -50,7 +49,6 @@ shaders_list = [
ConstantThicknessShader(5),
pyBluePrintCirclesShader(3),
pyPerlinNoise1DShader(0.1, 15, 8),
- TextureAssignerShader(4),
IncreasingColorShader(0.8, 0.8, 0.3, 0.4, 0.3, 0.3, 0.3, 0.1),
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/blueprint_ellipses.py b/release/scripts/freestyle/styles/blueprint_ellipses.py
index d0bd0c45c6c..3d977a10d1c 100644
--- a/release/scripts/freestyle/styles/blueprint_ellipses.py
+++ b/release/scripts/freestyle/styles/blueprint_ellipses.py
@@ -34,7 +34,6 @@ from freestyle.predicates import (
from freestyle.shaders import (
ConstantThicknessShader,
IncreasingColorShader,
- TextureAssignerShader,
pyBluePrintEllipsesShader,
pyPerlinNoise1DShader,
)
@@ -50,7 +49,6 @@ shaders_list = [
ConstantThicknessShader(5),
pyBluePrintEllipsesShader(3),
pyPerlinNoise1DShader(0.1, 10, 8),
- TextureAssignerShader(4),
IncreasingColorShader(0.6, 0.3, 0.3, 0.7, 0.3, 0.3, 0.3, 0.1),
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/blueprint_squares.py b/release/scripts/freestyle/styles/blueprint_squares.py
index 82ab6a80dd7..7110fe413fc 100644
--- a/release/scripts/freestyle/styles/blueprint_squares.py
+++ b/release/scripts/freestyle/styles/blueprint_squares.py
@@ -34,7 +34,6 @@ from freestyle.predicates import (
from freestyle.shaders import (
ConstantThicknessShader,
IncreasingColorShader,
- TextureAssignerShader,
pyBluePrintSquaresShader,
pyPerlinNoise1DShader,
)
@@ -50,7 +49,6 @@ shaders_list = [
ConstantThicknessShader(8),
pyBluePrintSquaresShader(2, 20),
pyPerlinNoise1DShader(0.07, 10, 8),
- TextureAssignerShader(4),
IncreasingColorShader(0.6, 0.3, 0.3, 0.7, 0.6, 0.3, 0.3, 0.3),
ConstantThicknessShader(4),
]
diff --git a/release/scripts/freestyle/styles/cartoon.py b/release/scripts/freestyle/styles/cartoon.py
index 2e2962cefe5..e630127db1a 100644
--- a/release/scripts/freestyle/styles/cartoon.py
+++ b/release/scripts/freestyle/styles/cartoon.py
@@ -20,7 +20,7 @@
# Author : Stephane Grabli
# Date : 04/08/2005
# Purpose : Draws colored lines. The color is automatically
-# infered from each object's material in a cartoon-like
+# inferred from each object's material in a cartoon-like
# fashion.
from freestyle.chainingiterators import ChainSilhouetteIterator
diff --git a/release/scripts/freestyle/styles/curvature2d.py b/release/scripts/freestyle/styles/curvature2d.py
index 66c8a6c6544..faf1223b735 100644
--- a/release/scripts/freestyle/styles/curvature2d.py
+++ b/release/scripts/freestyle/styles/curvature2d.py
@@ -30,7 +30,6 @@ from freestyle.predicates import (
)
from freestyle.shaders import (
ConstantThicknessShader,
- StrokeTextureShader,
py2DCurvatureColorShader,
)
from freestyle.types import Operators, Stroke
@@ -39,7 +38,6 @@ from freestyle.types import Operators, Stroke
Operators.select(QuantitativeInvisibilityUP1D(0))
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0)))
shaders_list = [
- StrokeTextureShader("smoothAlpha.bmp", Stroke.OPAQUE_MEDIUM, False),
ConstantThicknessShader(5),
py2DCurvatureColorShader()
]
diff --git a/release/scripts/freestyle/styles/external_contour_sketchy.py b/release/scripts/freestyle/styles/external_contour_sketchy.py
index 6a7a2333bb5..44dbda4709f 100644
--- a/release/scripts/freestyle/styles/external_contour_sketchy.py
+++ b/release/scripts/freestyle/styles/external_contour_sketchy.py
@@ -37,7 +37,6 @@ from freestyle.shaders import (
SamplingShader,
SmoothingShader,
SpatialNoiseShader,
- TextureAssignerShader,
)
from freestyle.types import Operators
@@ -51,6 +50,5 @@ shaders_list = [
IncreasingThicknessShader(4, 10),
SmoothingShader(400, 0.1, 0, 0.2, 0, 0, 0, 1),
IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
- TextureAssignerShader(4),
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/japanese_bigbrush.py b/release/scripts/freestyle/styles/japanese_bigbrush.py
index 80afeff48d0..a312bcd4358 100644
--- a/release/scripts/freestyle/styles/japanese_bigbrush.py
+++ b/release/scripts/freestyle/styles/japanese_bigbrush.py
@@ -37,7 +37,6 @@ from freestyle.shaders import (
ConstantColorShader,
ConstantThicknessShader,
SamplingShader,
- TextureAssignerShader,
TipRemoverShader,
pyNonLinearVaryingThicknessShader,
pySamplingShader,
@@ -47,7 +46,7 @@ from freestyle.types import IntegrationType, Operators
Operators.select(QuantitativeInvisibilityUP1D(0))
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0)))
-## Splits strokes at points of highest 2D curavture
+## Splits strokes at points of highest 2D curvature
## when there are too many abrupt turns in it
func = pyInverseCurvature2DAngleF0D()
Operators.recursive_split(func, pyParameterUP0D(0.2, 0.8), NotUP1D(pyHigherNumberOfTurnsUP1D(3, 0.5)), 2)
@@ -62,7 +61,6 @@ shaders_list = [
SamplingShader(50),
ConstantThicknessShader(10),
pyNonLinearVaryingThicknessShader(4, 25, 0.6),
- TextureAssignerShader(6),
ConstantColorShader(0.2, 0.2, 0.2,1.0),
TipRemoverShader(10),
]
diff --git a/release/scripts/freestyle/styles/multiple_parameterization.py b/release/scripts/freestyle/styles/multiple_parameterization.py
index bf0691f2ce1..0e224c74bbf 100644
--- a/release/scripts/freestyle/styles/multiple_parameterization.py
+++ b/release/scripts/freestyle/styles/multiple_parameterization.py
@@ -37,7 +37,6 @@ from freestyle.shaders import (
IncreasingColorShader,
IncreasingThicknessShader,
SamplingShader,
- TextureAssignerShader,
pyHLRShader,
)
from freestyle.types import Operators
@@ -52,7 +51,6 @@ shaders_list = [
IncreasingThicknessShader(1.5, 30),
ConstantColorShader(0.0, 0.0, 0.0),
IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
- TextureAssignerShader(-1),
pyHLRShader(), ## this shader draws only visible portions
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/near_lines.py b/release/scripts/freestyle/styles/near_lines.py
index b91eaea4023..5e260a22382 100644
--- a/release/scripts/freestyle/styles/near_lines.py
+++ b/release/scripts/freestyle/styles/near_lines.py
@@ -33,7 +33,6 @@ from freestyle.predicates import (
from freestyle.shaders import (
ConstantColorShader,
ConstantThicknessShader,
- TextureAssignerShader,
)
from freestyle.types import IntegrationType, Operators
@@ -42,7 +41,6 @@ upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyZSmallerUP1D(0.5, Integration
Operators.select(upred)
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
shaders_list = [
- TextureAssignerShader(-1),
ConstantThicknessShader(5),
ConstantColorShader(0.0, 0.0, 0.0),
]
diff --git a/release/scripts/freestyle/styles/qi0_not_external_contour.py b/release/scripts/freestyle/styles/qi0_not_external_contour.py
index fb3e3279b6c..3c9b8873485 100644
--- a/release/scripts/freestyle/styles/qi0_not_external_contour.py
+++ b/release/scripts/freestyle/styles/qi0_not_external_contour.py
@@ -36,7 +36,6 @@ from freestyle.shaders import (
IncreasingThicknessShader,
SamplingShader,
SpatialNoiseShader,
- TextureAssignerShader,
)
from freestyle.types import Operators
@@ -50,6 +49,5 @@ shaders_list = [
IncreasingThicknessShader(2, 5),
BackboneStretcherShader(20),
IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
- TextureAssignerShader(4),
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/sequentialsplit_sketchy.py b/release/scripts/freestyle/styles/sequentialsplit_sketchy.py
index e97e8f6da39..b980fdc87d7 100644
--- a/release/scripts/freestyle/styles/sequentialsplit_sketchy.py
+++ b/release/scripts/freestyle/styles/sequentialsplit_sketchy.py
@@ -35,7 +35,6 @@ from freestyle.shaders import (
ConstantColorShader,
IncreasingThicknessShader,
SpatialNoiseShader,
- TextureAssignerShader,
)
from freestyle.types import Nature, Operators
@@ -51,6 +50,5 @@ shaders_list = [
SpatialNoiseShader(7, 120, 2, True, True),
IncreasingThicknessShader(5, 8),
ConstantColorShader(0.2, 0.2, 0.2, 1),
- TextureAssignerShader(4),
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/sketchy_multiple_parameterization.py b/release/scripts/freestyle/styles/sketchy_multiple_parameterization.py
index 0beb6e37c21..a3ce6112165 100644
--- a/release/scripts/freestyle/styles/sketchy_multiple_parameterization.py
+++ b/release/scripts/freestyle/styles/sketchy_multiple_parameterization.py
@@ -34,7 +34,6 @@ from freestyle.shaders import (
SamplingShader,
SmoothingShader,
SpatialNoiseShader,
- TextureAssignerShader,
pyHLRShader,
)
from freestyle.types import Operators
@@ -48,7 +47,6 @@ shaders_list = [
IncreasingThicknessShader(5, 30),
SmoothingShader(100, 0.05, 0, 0.2, 0, 0, 0, 1),
IncreasingColorShader(0, 0.2, 0, 1, 0.2, 0.7, 0.2, 1),
- TextureAssignerShader(6),
pyHLRShader(),
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/sketchy_topology_broken.py b/release/scripts/freestyle/styles/sketchy_topology_broken.py
index 671bc2b1592..191d2d8bcbe 100644
--- a/release/scripts/freestyle/styles/sketchy_topology_broken.py
+++ b/release/scripts/freestyle/styles/sketchy_topology_broken.py
@@ -20,7 +20,7 @@
# Author : Stephane Grabli
# Date : 04/08/2005
# Purpose : The topology of the strokes is, first, built
-# independantly from the 3D topology of objects,
+# independently from the 3D topology of objects,
# and, second, so as to chain several times the same ViewEdge.
from freestyle.chainingiterators import pySketchyChainingIterator
@@ -34,14 +34,13 @@ from freestyle.shaders import (
SamplingShader,
SmoothingShader,
SpatialNoiseShader,
- TextureAssignerShader,
- pyBackboneStretcherNoCuspShader
+ pyBackboneStretcherNoCuspShader,
)
from freestyle.types import Operators
Operators.select(QuantitativeInvisibilityUP1D(0))
-## Chain 3 times each ViewEdge indpendantly from the
+## Chain 3 times each ViewEdge independently from the
## initial objects topology
Operators.bidirectional_chain(pySketchyChainingIterator(3))
shaders_list = [
@@ -50,9 +49,6 @@ shaders_list = [
IncreasingThicknessShader(4, 10),
SmoothingShader(100, 0.1, 0, 0.2, 0, 0, 0, 1),
pyBackboneStretcherNoCuspShader(20),
- #ConstantColorShader(0.0, 0.0, 0.0)
IncreasingColorShader(0.2, 0.2, 0.2, 1, 0.5, 0.5, 0.5, 1),
- #IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
- TextureAssignerShader(4),
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/sketchy_topology_preserved.py b/release/scripts/freestyle/styles/sketchy_topology_preserved.py
index 161654f1f97..26c7fd37964 100644
--- a/release/scripts/freestyle/styles/sketchy_topology_preserved.py
+++ b/release/scripts/freestyle/styles/sketchy_topology_preserved.py
@@ -34,7 +34,6 @@ from freestyle.shaders import (
SamplingShader,
SmoothingShader,
SpatialNoiseShader,
- TextureAssignerShader,
)
from freestyle.types import Operators
@@ -48,6 +47,5 @@ shaders_list = [
IncreasingThicknessShader(4, 8),
SmoothingShader(300, 0.05, 0, 0.2, 0, 0, 0, 0.5),
ConstantColorShader(0.6, 0.2, 0.0),
- TextureAssignerShader(4),
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/split_at_highest_2d_curvatures.py b/release/scripts/freestyle/styles/split_at_highest_2d_curvatures.py
index 3bfdb05a2db..68a80d89ea7 100644
--- a/release/scripts/freestyle/styles/split_at_highest_2d_curvatures.py
+++ b/release/scripts/freestyle/styles/split_at_highest_2d_curvatures.py
@@ -34,7 +34,6 @@ from freestyle.predicates import (
from freestyle.shaders import (
ConstantThicknessShader,
IncreasingColorShader,
- TextureAssignerShader,
)
from freestyle.types import Operators
@@ -46,6 +45,5 @@ Operators.recursive_split(func, pyParameterUP0D(0.4, 0.6), NotUP1D(pyHigherLengt
shaders_list = [
ConstantThicknessShader(10),
IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
- TextureAssignerShader(3),
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/split_at_tvertices.py b/release/scripts/freestyle/styles/split_at_tvertices.py
index 213922a03b1..8978b98f56b 100644
--- a/release/scripts/freestyle/styles/split_at_tvertices.py
+++ b/release/scripts/freestyle/styles/split_at_tvertices.py
@@ -31,7 +31,6 @@ from freestyle.predicates import (
from freestyle.shaders import (
ConstantThicknessShader,
IncreasingColorShader,
- TextureAssignerShader,
)
from freestyle.types import Nature, Operators
@@ -45,6 +44,5 @@ Operators.sequential_split(start, start, 10)
shaders_list = [
ConstantThicknessShader(5),
IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1),
- TextureAssignerShader(3),
]
Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/stroke_texture.py b/release/scripts/freestyle/styles/stroke_texture.py
deleted file mode 100644
index 614c34a6654..00000000000
--- a/release/scripts/freestyle/styles/stroke_texture.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# Filename : stroke_texture.py
-# Author : Stephane Grabli
-# Date : 04/08/2005
-# Purpose : Draws textured strokes (illustrate the StrokeTextureShader shader)
-
-from freestyle.chainingiterators import ChainSilhouetteIterator
-from freestyle.predicates import (
- NotUP1D,
- QuantitativeInvisibilityUP1D,
- TrueUP1D,
- )
-from freestyle.shaders import (
- BezierCurveShader,
- ConstantColorShader,
- ConstantThicknessShader,
- SamplingShader,
- StrokeTextureShader,
- )
-from freestyle.types import Operators, Stroke
-
-
-Operators.select(QuantitativeInvisibilityUP1D(0))
-Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0)))
-shaders_list = [
- SamplingShader(3),
- BezierCurveShader(4),
- StrokeTextureShader("washbrushAlpha.bmp", Stroke.DRY_MEDIUM, True),
- ConstantThicknessShader(40),
- ConstantColorShader(0, 0, 0, 1),
- ]
-Operators.create(TrueUP1D(), shaders_list)
diff --git a/release/scripts/freestyle/styles/uniformpruning_zsort.py b/release/scripts/freestyle/styles/uniformpruning_zsort.py
index 29b634b765b..814e140ee49 100644
--- a/release/scripts/freestyle/styles/uniformpruning_zsort.py
+++ b/release/scripts/freestyle/styles/uniformpruning_zsort.py
@@ -30,7 +30,6 @@ from freestyle.shaders import (
ConstantColorShader,
ConstantThicknessShader,
SamplingShader,
- StrokeTextureShader,
)
from freestyle.types import IntegrationType, Operators, Stroke
@@ -40,10 +39,8 @@ Operators.bidirectional_chain(ChainSilhouetteIterator())
#Operators.sequential_split(pyVertexNatureUP0D(Nature.VIEW_VERTEX), 2)
Operators.sort(pyZBP1D())
shaders_list = [
- StrokeTextureShader("smoothAlpha.bmp", Stroke.OPAQUE_MEDIUM, False),
ConstantThicknessShader(3),
SamplingShader(5.0),
ConstantColorShader(0, 0, 0, 1),
]
Operators.create(pyDensityUP1D(2, 0.05, IntegrationType.MEAN, 4), shaders_list)
-#Operators.create(pyDensityFunctorUP1D(8, 0.03, pyGetInverseProjectedZF1D(), 0, 1, IntegrationType.MEAN), shaders_list)
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py
index 88356b676d2..8c86f31022c 100644
--- a/release/scripts/modules/addon_utils.py
+++ b/release/scripts/modules/addon_utils.py
@@ -36,6 +36,15 @@ error_encoding = False
addons_fake_modules = {}
+# called only once at startup, avoids calling 'reset_all', correct but slower.
+def _initialize():
+ path_list = paths()
+ for path in path_list:
+ _bpy.utils._sys_path_ensure(path)
+ for addon in _user_preferences.addons:
+ enable(addon.module)
+
+
def paths():
# RELEASE SCRIPTS: official scripts distributed in Blender releases
addon_paths = _bpy.utils.script_paths("addons")
@@ -44,10 +53,6 @@ def paths():
# if folder addons_contrib/ exists, scripts in there will be loaded too
addon_paths += _bpy.utils.script_paths("addons_contrib")
- # EXTERN SCRIPTS: external projects scripts
- # if folder addons_extern/ exists, scripts in there will be loaded too
- addon_paths += _bpy.utils.script_paths("addons_extern")
-
return addon_paths
@@ -148,13 +153,13 @@ def modules_refresh(module_cache=addons_fake_modules):
for path in path_list:
# force all contrib addons to be 'TESTING'
- if path.endswith(("addons_contrib", "addons_extern")):
+ if path.endswith(("addons_contrib", )):
force_support = 'TESTING'
else:
force_support = None
for mod_name, mod_path in _bpy.path.module_names(path):
- modules_stale -= {mod_name}
+ modules_stale.discard(mod_name)
mod = module_cache.get(mod_name)
if mod:
if mod.__file__ != mod_path:
@@ -186,14 +191,16 @@ def modules_refresh(module_cache=addons_fake_modules):
def modules(module_cache=addons_fake_modules, refresh=True):
- if refresh:
+ if refresh or ((module_cache is addons_fake_modules) and modules._is_first):
modules_refresh(module_cache)
+ modules._is_first = False
mod_list = list(module_cache.values())
mod_list.sort(key=lambda mod: (mod.bl_info["category"],
mod.bl_info["name"],
))
return mod_list
+modules._is_first = True
def check(module_name):
@@ -244,7 +251,7 @@ def _addon_remove(module_name):
addons.remove(addon)
-def enable(module_name, default_set=True, persistent=False, handle_error=None):
+def enable(module_name, default_set=False, persistent=False, handle_error=None):
"""
Enables an addon by name.
@@ -271,11 +278,11 @@ def enable(module_name, default_set=True, persistent=False, handle_error=None):
mtime_orig = getattr(mod, "__time__", 0)
mtime_new = os.path.getmtime(mod.__file__)
if mtime_orig != mtime_new:
- import imp
+ import importlib
print("module changed on disk:", mod.__file__, "reloading...")
try:
- imp.reload(mod)
+ importlib.reload(mod)
except:
handle_error()
del sys.modules[module_name]
@@ -299,9 +306,15 @@ def enable(module_name, default_set=True, persistent=False, handle_error=None):
mod = __import__(module_name)
mod.__time__ = os.path.getmtime(mod.__file__)
mod.__addon_enabled__ = False
- except:
- handle_error()
- _addon_remove(module_name)
+ except Exception as ex:
+ # if the addon doesn't exist, dont print full traceback
+ if type(ex) is ImportError and ex.name == module_name:
+ print("addon not found: %r" % module_name)
+ else:
+ handle_error()
+
+ if default_set:
+ _addon_remove(module_name)
return None
# 2) try register collected modules
@@ -315,7 +328,8 @@ def enable(module_name, default_set=True, persistent=False, handle_error=None):
getattr(mod, "__file__", module_name))
handle_error()
del sys.modules[module_name]
- _addon_remove(module_name)
+ if default_set:
+ _addon_remove(module_name)
return None
# * OK loaded successfully! *
@@ -388,10 +402,10 @@ def reset_all(reload_scripts=False):
# first check if reload is needed before changing state.
if reload_scripts:
- import imp
+ import importlib
mod = sys.modules.get(mod_name)
if mod:
- imp.reload(mod)
+ importlib.reload(mod)
if is_enabled == is_loaded:
pass
diff --git a/release/scripts/modules/animsys_refactor.py b/release/scripts/modules/animsys_refactor.py
index aaa06c32312..39f0ad2f049 100644
--- a/release/scripts/modules/animsys_refactor.py
+++ b/release/scripts/modules/animsys_refactor.py
@@ -51,7 +51,7 @@ def classes_recursive(base_type, clss=None):
return clss
-class DataPathBuilder(object):
+class DataPathBuilder:
"""Dummy class used to parse fcurve and driver data paths."""
__slots__ = ("data_path", )
diff --git a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
index 8874ecceb77..c3b2ae9908b 100644
--- a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
+++ b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
@@ -62,6 +62,7 @@ def _gen_check_ctxt(settings):
"spell_errors": {},
}
+
def _diff_check_ctxt(check_ctxt, minus_check_ctxt):
"""Returns check_ctxt - minus_check_ctxt"""
for key in check_ctxt:
@@ -74,6 +75,7 @@ def _diff_check_ctxt(check_ctxt, minus_check_ctxt):
if warning in check_ctxt[key]:
del check_ctxt[key][warning]
+
def _gen_reports(check_ctxt):
return {
"check_ctxt": check_ctxt,
@@ -256,7 +258,7 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
bpy.types.Panel.__subclasses__() +
bpy.types.Menu.__subclasses__() +
bpy.types.UIList.__subclasses__()
- if cls.__name__ not in _rna_clss_ids}
+ if cls.__name__ not in _rna_clss_ids}
# Collect internal operators
# extend with all internal operators
@@ -264,8 +266,8 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
# XXX Do not skip INTERNAL's anymore, some of those ops show up in UI now!
# all possible operator names
#op_ids = (set(cls.bl_rna.identifier for cls in bpy.types.OperatorProperties.__subclasses__()) |
- #set(cls.bl_rna.identifier for cls in bpy.types.Operator.__subclasses__()) |
- #set(cls.bl_rna.identifier for cls in bpy.types.OperatorMacro.__subclasses__()))
+ # set(cls.bl_rna.identifier for cls in bpy.types.Operator.__subclasses__()) |
+ # set(cls.bl_rna.identifier for cls in bpy.types.OperatorMacro.__subclasses__()))
#get_instance = __import__("_bpy").ops.get_instance
#path_resolve = type(bpy.context).__base__.path_resolve
@@ -473,7 +475,6 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
return [_extract_string_merge(estr_ls, nds_ls) for estr_ls, nds_ls in bag]
-
i18n_ctxt_ids = {v for v in bpy.app.translations.contexts_C_to_py.values()}
def _ctxt_to_ctxt(node):
# We must try, to some extend, to get contexts from vars instead of only literal strings...
@@ -821,9 +822,9 @@ def dump_messages(do_messages, do_checks, settings):
# Get strings from addons' categories.
for uid, label, tip in bpy.types.WindowManager.addon_filter[1]['items'](bpy.context.window_manager, bpy.context):
- process_msg(msgs, settings.DEFAULT_CONTEXT, label, "Addons' categories", reports, None, settings)
+ process_msg(msgs, settings.DEFAULT_CONTEXT, label, "Add-ons' categories", reports, None, settings)
if tip:
- process_msg(msgs, settings.DEFAULT_CONTEXT, tip, "Addons' categories", reports, None, settings)
+ process_msg(msgs, settings.DEFAULT_CONTEXT, tip, "Add-ons' categories", reports, None, settings)
# Get strings specific to translations' menu.
for lng in settings.LANGUAGES:
diff --git a/release/scripts/modules/bl_i18n_utils/merge_po.py b/release/scripts/modules/bl_i18n_utils/merge_po.py
index d7dade22ffd..2fda42199bb 100755
--- a/release/scripts/modules/bl_i18n_utils/merge_po.py
+++ b/release/scripts/modules/bl_i18n_utils/merge_po.py
@@ -30,17 +30,20 @@
import sys
-try:
+if __package__ is None:
import settings
import utils
-except:
- from . import (settings, utils)
+else:
+ from . import (
+ settings,
+ utils,
+ )
# XXX This is a quick hack to make it work with new I18n... objects! To be reworked!
def main():
import argparse
- parser = argparse.ArgumentParser(description=""
+ parser = argparse.ArgumentParser(description=
"Merge one or more .po files into the first dest one.\n"
"If a msgkey (msgctxt, msgid) is present in more than one merged po, the one in the first file "
"wins, unless it’s marked as fuzzy and one later is not.\n"
diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py
index 300cd7ae955..920a56a628b 100644
--- a/release/scripts/modules/bl_i18n_utils/settings.py
+++ b/release/scripts/modules/bl_i18n_utils/settings.py
@@ -101,7 +101,7 @@ IMPORT_MIN_LEVEL = 0.0
# Languages in /branches we do not want to import in /trunk currently...
IMPORT_LANGUAGES_SKIP = {
- 'am_ET', 'bg_BG', 'fi_FI', 'el_GR', 'et_EE', 'ne_NP', 'pl_PL', 'ro_RO', 'uz_UZ', 'uz_UZ@cyrillic',
+ 'am_ET', 'bg_BG', 'fi_FI', 'el_GR', 'et_EE', 'ne_NP', 'ro_RO', 'uz_UZ', 'uz_UZ@cyrillic',
}
# Languages that need RTL pre-processing.
@@ -290,7 +290,6 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"flac",
"fps: %.2f",
"fps: %i",
- "fStop",
"gimbal",
"global",
"iScale",
@@ -473,6 +472,7 @@ for p in set(INTERN_PY_SYS_PATHS.split(";")):
def _do_get(ref, path):
return os.path.normpath(os.path.join(ref, path))
+
def _do_set(ref, path):
path = os.path.normpath(path)
# If given path is absolute, make it relative to current ref one (else we consider it is already the case!)
@@ -484,6 +484,7 @@ def _do_set(ref, path):
pass
return path
+
def _gen_get_set_path(ref, name):
def _get(self):
return _do_get(getattr(self, ref), getattr(self, name))
@@ -491,6 +492,7 @@ def _gen_get_set_path(ref, name):
setattr(self, name, _do_set(getattr(self, ref), value))
return _get, _set
+
def _gen_get_set_paths(ref, name):
def _get(self):
return [_do_get(getattr(self, ref), p) for p in getattr(self, name)]
@@ -498,6 +500,7 @@ def _gen_get_set_paths(ref, name):
setattr(self, name, [_do_set(getattr(self, ref), p) for p in value])
return _get, _set
+
class I18nSettings:
"""
Class allowing persistence of our settings!
diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py
index 911e1764698..524fef909e8 100644
--- a/release/scripts/modules/bl_i18n_utils/utils.py
+++ b/release/scripts/modules/bl_i18n_utils/utils.py
@@ -31,9 +31,10 @@ import sys
import tempfile
#import time
-from bl_i18n_utils import (settings,
- utils_rtl,
- )
+from bl_i18n_utils import (
+ settings,
+ utils_rtl,
+ )
import bpy
diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
index a887ebde449..4126dde1225 100644
--- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
@@ -24,7 +24,7 @@ import pickle
import re
-class SpellChecker():
+class SpellChecker:
"""
A basic spell checker.
"""
@@ -217,10 +217,10 @@ class SpellChecker():
"passepartout",
"perspectively",
"pixelate",
+ "pointiness",
"polycount",
"polygonization", "polygonalization", # yuck!
"selectability",
- "slurph",
"stitchable",
"symmetrize",
"trackability",
@@ -266,6 +266,7 @@ class SpellChecker():
"ok",
"orco",
"ortho",
+ "pano",
"persp",
"pref", "prefs",
"prev",
@@ -454,6 +455,7 @@ class SpellChecker():
"vcol", "vcols",
"vgroup", "vgroups",
"vinterlace",
+ "vse",
"wasd", "wasdqe", # keys...
"wetmap", "wetmaps",
"wpaint",
@@ -509,6 +511,7 @@ class SpellChecker():
"fov",
"fft",
"futura",
+ "fx",
"gfx",
"gl",
"glsl",
@@ -539,6 +542,7 @@ class SpellChecker():
"sdl",
"sl",
"smpte",
+ "ssao",
"svn",
"ui",
"unix",
diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py
index 3a2f9bde2c7..b0d2233b380 100644
--- a/release/scripts/modules/bpy/__init__.py
+++ b/release/scripts/modules/bpy/__init__.py
@@ -38,10 +38,10 @@ __all__ = (
from _bpy import types, props, app, data, context
# python modules
-from . import utils, path, ops
+from . import utils, path
# fake operator module
-ops = ops.ops_fake_module
+from .ops import ops_fake_module as ops
def main():
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py
index f5455ce5018..d3d9255123b 100644
--- a/release/scripts/modules/bpy/ops.py
+++ b/release/scripts/modules/bpy/ops.py
@@ -30,12 +30,13 @@ op_get_rna = ops_module.get_rna
op_get_instance = ops_module.get_instance
-class BPyOps(object):
+class BPyOps:
"""
Fake module like class.
bpy.ops
"""
+ __slots__ = ()
def __getattr__(self, module):
"""
@@ -68,7 +69,7 @@ class BPyOps(object):
return "<module like class 'bpy.ops'>"
-class BPyOpsSubMod(object):
+class BPyOpsSubMod:
"""
Utility class to fake submodules.
@@ -104,7 +105,7 @@ class BPyOpsSubMod(object):
return "<module like class 'bpy.ops.%s'>" % self._module
-class BPyOpsSubModOp(object):
+class BPyOpsSubModOp:
"""
Utility class to fake submodule operators.
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index 874efc2e131..25a6c7242e0 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -43,10 +43,11 @@ __all__ = (
import bpy as _bpy
import os as _os
-from _bpy_path import (extensions_audio,
- extensions_movie,
- extensions_image,
- )
+from _bpy_path import (
+ extensions_audio,
+ extensions_movie,
+ extensions_image,
+ )
def _getattr_bytes(var, attr):
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index b3a7a13e331..5f235ae3958 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -51,12 +51,12 @@ __all__ = (
)
from _bpy import (
- escape_identifier,
- register_class,
- unregister_class,
- blend_paths,
- resource_path,
- )
+ escape_identifier,
+ register_class,
+ unregister_class,
+ blend_paths,
+ resource_path,
+ )
from _bpy import script_paths as _bpy_script_paths
from _bpy import user_resource as _user_resource
from _bpy import _utils_units as units
@@ -185,7 +185,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
traceback.print_exc()
def test_reload(mod):
- import imp
+ import importlib
# reloading this causes internal errors
# because the classes from this module are stored internally
# possibly to refresh internal references too but for now, best not to.
@@ -193,7 +193,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
return mod
try:
- return imp.reload(mod)
+ return importlib.reload(mod)
except:
import traceback
traceback.print_exc()
@@ -244,7 +244,14 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
test_register(mod)
# deal with addons separately
- _addon_utils.reset_all(reload_scripts)
+ _initialize = getattr(_addon_utils, "_initialize", None)
+ if _initialize is not None:
+ # first time, use fast-path
+ _initialize()
+ del _addon_utils._initialize
+ else:
+ _addon_utils.reset_all(reload_scripts)
+ del _initialize
# run the active integration preset
filepath = preset_find(_user_preferences.inputs.active_keyconfig,
diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py
index d87c207e2d0..4ee5e685668 100644
--- a/release/scripts/modules/bpy_extras/anim_utils.py
+++ b/release/scripts/modules/bpy_extras/anim_utils.py
@@ -25,6 +25,7 @@ __all__ = (
import bpy
+# XXX visual keying is actually always considered as True in this code...
def bake_action(frame_start,
frame_end,
frame_step=1,
@@ -73,7 +74,7 @@ def bake_action(frame_start,
# -------------------------------------------------------------------------
# Helper Functions and vars
- def pose_frame_info(obj, do_visual_keying):
+ def pose_frame_info(obj):
matrix = {}
for name, pbone in obj.pose.bones.items():
if do_visual_keying:
@@ -84,16 +85,29 @@ def bake_action(frame_start,
return matrix
if do_parents_clear:
- def obj_frame_info(obj, do_visual_keying):
- parent = obj.parent
- matrix = obj.matrix_local if do_visual_keying else obj.matrix_local
- if parent:
- return parent.matrix_world * matrix
- else:
- return matrix.copy()
+ if do_visual_keying:
+ def obj_frame_info(obj):
+ return obj.matrix_world.copy()
+ else:
+ def obj_frame_info(obj):
+ parent = obj.parent
+ matrix = obj.matrix_basis
+ if parent:
+ return parent.matrix_world * matrix
+ else:
+ return matrix.copy()
else:
- def obj_frame_info(obj, do_visual_keying):
- return obj.matrix_local.copy() if do_visual_keying else obj.matrix_local.copy()
+ if do_visual_keying:
+ def obj_frame_info(obj):
+ parent = obj.parent
+ matrix = obj.matrix_world
+ if parent:
+ return parent.matrix_world.inverted_safe() * matrix
+ else:
+ return matrix.copy()
+ else:
+ def obj_frame_info(obj):
+ return obj.matrix_basis.copy()
# -------------------------------------------------------------------------
# Setup the Context
@@ -123,9 +137,9 @@ def bake_action(frame_start,
scene.frame_set(f)
scene.update()
if do_pose:
- pose_info.append(pose_frame_info(obj, do_visual_keying))
+ pose_info.append(pose_frame_info(obj))
if do_object:
- obj_info.append(obj_frame_info(obj, do_visual_keying))
+ obj_info.append(obj_frame_info(obj))
# -------------------------------------------------------------------------
# Create action
diff --git a/release/scripts/modules/bpy_extras/io_utils.py b/release/scripts/modules/bpy_extras/io_utils.py
index b1877a9d439..81de0d7c6f0 100644
--- a/release/scripts/modules/bpy_extras/io_utils.py
+++ b/release/scripts/modules/bpy_extras/io_utils.py
@@ -21,6 +21,7 @@
__all__ = (
"ExportHelper",
"ImportHelper",
+ "OrientationHelper",
"axis_conversion",
"axis_conversion_ensure",
"create_derived_objects",
@@ -116,6 +117,43 @@ class ImportHelper:
return _check_axis_conversion(self)
+class OrientationHelper:
+
+ def _update_axis_forward(self, context):
+ if self.axis_forward[-1] == self.axis_up[-1]:
+ self.axis_up = self.axis_up[0:-1] + 'XYZ'[('XYZ'.index(self.axis_up[-1]) + 1) % 3]
+
+ axis_forward = EnumProperty(
+ name="Forward",
+ items=(('X', "X Forward", ""),
+ ('Y', "Y Forward", ""),
+ ('Z', "Z Forward", ""),
+ ('-X', "-X Forward", ""),
+ ('-Y', "-Y Forward", ""),
+ ('-Z', "-Z Forward", ""),
+ ),
+ default='-Z',
+ update=_update_axis_forward,
+ )
+
+ def _update_axis_up(self, context):
+ if self.axis_up[-1] == self.axis_forward[-1]:
+ self.axis_forward = self.axis_forward[0:-1] + 'XYZ'[('XYZ'.index(self.axis_forward[-1]) + 1) % 3]
+
+ axis_up = EnumProperty(
+ name="Up",
+ items=(('X', "X Up", ""),
+ ('Y', "Y Up", ""),
+ ('Z', "Z Up", ""),
+ ('-X', "-X Up", ""),
+ ('-Y', "-Y Up", ""),
+ ('-Z', "-Z Up", ""),
+ ),
+ default='Y',
+ update=_update_axis_up,
+ )
+
+
# Axis conversion function, not pretty LUT
# use lookup table to convert between any axis
_axis_convert_matrix = (
diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py
index c50b320dceb..7e4c9e885e7 100644
--- a/release/scripts/modules/bpy_extras/keyconfig_utils.py
+++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py
@@ -32,7 +32,10 @@ KM_HIERARCHY = [
('View2D', 'EMPTY', 'WINDOW', []), # view 2d navigation (per region)
('View2D Buttons List', 'EMPTY', 'WINDOW', []), # view 2d with buttons navigation
('Header', 'EMPTY', 'WINDOW', []), # header stuff (per region)
- ('Grease Pencil', 'EMPTY', 'WINDOW', []), # grease pencil stuff (per region)
+
+ ('Grease Pencil', 'EMPTY', 'WINDOW', [ # grease pencil stuff (per region)
+ ('Grease Pencil Stroke Edit Mode', 'EMPTY', 'WINDOW', []),
+ ]),
('3D View', 'VIEW_3D', 'WINDOW', [ # view 3d navigation and generic stuff (select, transform)
('Object Mode', 'EMPTY', 'WINDOW', []),
@@ -56,6 +59,7 @@ KM_HIERARCHY = [
('Knife Tool Modal Map', 'EMPTY', 'WINDOW', []),
('Paint Stroke Modal', 'EMPTY', 'WINDOW', []),
+ ('Paint Curve', 'EMPTY', 'WINDOW', []),
('Object Non-modal', 'EMPTY', 'WINDOW', []), # mode change
@@ -241,7 +245,7 @@ def keyconfig_export(wm, kc, filepath):
# the default blender keyconfig, recreating the current setup from a fresh blender
# without needing to export keymaps which haven't been edited.
- class FakeKeyConfig():
+ class FakeKeyConfig:
keymaps = []
edited_kc = FakeKeyConfig()
for km in wm.keyconfigs.user.keymaps:
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index 01390760c76..13ef86b23c0 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -99,7 +99,7 @@ def add_object_align_init(context, operator):
return location * rotation
-def object_data_add(context, obdata, operator=None, use_active_layer=True):
+def object_data_add(context, obdata, operator=None, use_active_layer=True, name=None):
"""
Add an object using the view context and preference to to initialize the
location, rotation and layer.
@@ -110,6 +110,8 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True):
:type obdata: valid object data type or None.
:arg operator: The operator, checked for location and rotation properties.
:type operator: :class:`bpy.types.Operator`
+ :arg name: Optional name
+ :type name: string
:return: the newly created object in the scene.
:rtype: :class:`bpy.types.ObjectBase`
"""
@@ -119,7 +121,10 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True):
for ob in scene.objects:
ob.select = False
- obj_new = bpy.data.objects.new(obdata.name, obdata)
+ if name is None:
+ name = "Object" if obdata is None else obdata.name
+
+ obj_new = bpy.data.objects.new(name, obdata)
base = scene.objects.link(obj_new)
base.select = True
@@ -150,7 +155,7 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True):
obj_act.mode == 'EDIT' and
obj_act.type == obj_new.type):
- _obdata = bpy.data.meshes.new(obdata.name)
+ _obdata = bpy.data.meshes.new(name)
obj_act = bpy.data.objects.new(_obdata.name, _obdata)
obj_act.matrix_world = obj_new.matrix_world
scene.objects.link(obj_act)
@@ -169,7 +174,8 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True):
#scene.objects.active = obj_new
bpy.ops.object.join() # join into the active.
- bpy.data.meshes.remove(obdata)
+ if obdata:
+ bpy.data.meshes.remove(obdata)
# base is freed, set to active object
base = scene.object_bases.active
diff --git a/release/scripts/modules/bpy_extras/view3d_utils.py b/release/scripts/modules/bpy_extras/view3d_utils.py
index b25024fca9b..ec4a395f1e1 100644
--- a/release/scripts/modules/bpy_extras/view3d_utils.py
+++ b/release/scripts/modules/bpy_extras/view3d_utils.py
@@ -63,10 +63,18 @@ def region_2d_to_vector_3d(region, rv3d, coord):
return view_vector
-def region_2d_to_origin_3d(region, rv3d, coord):
+def region_2d_to_origin_3d(region, rv3d, coord, clamp=None):
"""
Return the 3d view origin from the region relative 2d coords.
+ .. note::
+
+ Orthographic views have a less obvious origin, the far clip is used to define the viewport near/far extents.
+ Since far clip can be a very large value, the result may give with numeric precision issues.
+
+ To avoid this problem, you can optionally clamp the far clip to a smaller value
+ based on the data you're operating on.
+
:arg region: region of the 3D viewport, typically bpy.context.region.
:type region: :class:`bpy.types.Region`
:arg rv3d: 3D region data, typically bpy.context.space_data.region_3d.
@@ -74,6 +82,9 @@ def region_2d_to_origin_3d(region, rv3d, coord):
:arg coord: 2d coordinates relative to the region;
(event.mouse_region_x, event.mouse_region_y) for example.
:type coord: 2d vector
+ :arg clamp: Clamp the maximum far-clip value used.
+ (negative value will move the offset away from the view_location)
+ :type clamp: float or None
:return: The origin of the viewpoint in 3d space.
:rtype: :class:`mathutils.Vector`
"""
@@ -89,6 +100,20 @@ def region_2d_to_origin_3d(region, rv3d, coord):
origin_start = ((persinv.col[0].xyz * dx) +
(persinv.col[1].xyz * dy) +
viewinv.translation)
+
+ if clamp != 0.0:
+ if rv3d.view_perspective != 'CAMERA':
+ # this value is scaled to the far clip already
+ origin_offset = persinv.col[2].xyz
+ if clamp is not None:
+ if clamp < 0.0:
+ origin_offset.negate()
+ clamp = -clamp
+ if origin_offset.length > clamp:
+ origin_offset.length = clamp
+
+ origin_start -= origin_offset
+
return origin_start
diff --git a/release/scripts/modules/bpy_restrict_state.py b/release/scripts/modules/bpy_restrict_state.py
index 4aa3c5de573..4658fddf0dc 100644
--- a/release/scripts/modules/bpy_restrict_state.py
+++ b/release/scripts/modules/bpy_restrict_state.py
@@ -29,7 +29,7 @@ __all__ = (
import bpy as _bpy
-class _RestrictContext():
+class _RestrictContext:
__slots__ = ()
_real_data = _bpy.data
# safe, the pointer never changes
@@ -44,7 +44,7 @@ class _RestrictContext():
return self._real_pref
-class _RestrictData():
+class _RestrictData:
__slots__ = ()
@@ -52,7 +52,7 @@ _context_restrict = _RestrictContext()
_data_restrict = _RestrictData()
-class RestrictBlend():
+class RestrictBlend:
__slots__ = ("context", "data")
def __enter__(self):
diff --git a/release/scripts/modules/bpyml.py b/release/scripts/modules/bpyml.py
index e942006010b..f2a73501672 100644
--- a/release/scripts/modules/bpyml.py
+++ b/release/scripts/modules/bpyml.py
@@ -57,7 +57,7 @@ class ReturnStore(tuple):
return tuple.__getitem__(self, key)
-class FunctionStore(object):
+class FunctionStore:
def __call__(self, **kwargs):
return ReturnStore((self.__class__.__name__, kwargs, []))
diff --git a/release/scripts/modules/bpyml_ui.py b/release/scripts/modules/bpyml_ui.py
index b4ad4e0b54a..dd5fc38d0eb 100644
--- a/release/scripts/modules/bpyml_ui.py
+++ b/release/scripts/modules/bpyml_ui.py
@@ -84,7 +84,7 @@ def _call_recursive(context, base, py_node):
_call_recursive(context, base_new, py_node_child)
-class BPyML_BaseUI():
+class BPyML_BaseUI:
"""
This is a mix-in class that defines a draw function
which checks for draw_data
diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py
index 66956899076..59e4f2314d8 100644
--- a/release/scripts/modules/console_python.py
+++ b/release/scripts/modules/console_python.py
@@ -226,6 +226,8 @@ execute.hooks = []
def autocomplete(context):
+ _readline_bypass()
+
from console import intellisense
sc = context.space_data
@@ -356,3 +358,14 @@ def banner(context):
sc.prompt = PROMPT
return {'FINISHED'}
+
+
+# workaround for readline crashing, see: T43491
+def _readline_bypass():
+ if "rlcompleter" in sys.modules or "readline" in sys.modules:
+ return
+
+ # prevent 'rlcompleter' from loading the real 'readline' module.
+ sys.modules["readline"] = None
+ import rlcompleter
+ del sys.modules["readline"]
diff --git a/release/scripts/modules/nodeitems_utils.py b/release/scripts/modules/nodeitems_utils.py
index 1fef6c3a019..2882a08fbd4 100644
--- a/release/scripts/modules/nodeitems_utils.py
+++ b/release/scripts/modules/nodeitems_utils.py
@@ -20,7 +20,7 @@
import bpy
-class NodeCategory():
+class NodeCategory:
@classmethod
def poll(cls, context):
return True
@@ -42,7 +42,7 @@ class NodeCategory():
self.items = items_gen
-class NodeItem():
+class NodeItem:
def __init__(self, nodetype, label=None, settings={}, poll=None):
self.nodetype = nodetype
self._label = label
@@ -73,7 +73,7 @@ class NodeItem():
ops.value = setting[1]
-class NodeItemCustom():
+class NodeItemCustom:
def __init__(self, poll=None, draw=None):
self.poll = poll
self.draw = draw
diff --git a/release/scripts/modules/rna_info.py b/release/scripts/modules/rna_info.py
index 3643ad89ea6..353362ed168 100644
--- a/release/scripts/modules/rna_info.py
+++ b/release/scripts/modules/rna_info.py
@@ -487,6 +487,12 @@ def GetInfoOperatorRNA(bl_rna):
def BuildRNAInfo():
+
+ # needed on successive calls to prevent stale data access
+ for cls in (InfoStructRNA, InfoFunctionRNA, InfoOperatorRNA, InfoPropertyRNA):
+ cls.global_lookup.clear()
+ del cls
+
# Use for faster lookups
# use rna_struct.identifier as the key for each dict
rna_struct_dict = {} # store identifier:rna lookups
diff --git a/release/scripts/modules/rna_keymap_ui.py b/release/scripts/modules/rna_keymap_ui.py
index 12d99a00d44..21d1959a037 100644
--- a/release/scripts/modules/rna_keymap_ui.py
+++ b/release/scripts/modules/rna_keymap_ui.py
@@ -236,7 +236,7 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout):
"MMB": 'MIDDLEMOUSE',
})
_EVENT_TYPE_MAP_EXTRA.update({
- "%d" % i: "NUMPAD_%d" % i for i in range(9)
+ "%d" % i: "NUMPAD_%d" % i for i in range(10)
})
# done with once off init
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index e278b0d20fe..f4649453b46 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -168,7 +168,7 @@ def draw(layout, context, context_member, property_type, use_edit=True):
assign_props(props, val_draw, key)
-class PropertyPanel():
+class PropertyPanel:
"""
The subclass should have its own poll function
and the variable '_context_path' MUST be set.
diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py
index 41f890de51f..729d6238ac3 100644
--- a/release/scripts/modules/rna_xml.py
+++ b/release/scripts/modules/rna_xml.py
@@ -331,7 +331,7 @@ def xml2rna(root_xml,
rna2xml_node(child_xml_real, subsubvalue)
else:
-# print(elems)
+ # print(elems)
if len(elems) == 1:
# sub node named by its type
diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py
index 7fd97c4d347..1b63d1d9d8d 100644
--- a/release/scripts/modules/sys_info.py
+++ b/release/scripts/modules/sys_info.py
@@ -118,6 +118,18 @@ def write_sysinfo(op):
else:
output.write("Blender was built without FFmpeg support\n")
+ if bpy.app.build_options.sdl:
+ output.write("\nSDL\n")
+ output.write(lilies)
+ output.write("Version: %s\n" % bpy.app.sdl.version_string)
+ output.write("Loading method: ")
+ if bpy.app.build_options.sdl_dynload:
+ output.write("dynamically loaded by Blender (WITH_SDL_DYNLOAD=ON)\n")
+ else:
+ output.write("linked (WITH_SDL_DYNLOAD=OFF)\n")
+ if not bpy.app.sdl.available:
+ output.write("WARNING: Blender could not load SDL library\n")
+
output.write("\nOther Libraries:\n")
output.write(lilies)
ocio = bpy.app.ocio
@@ -148,12 +160,15 @@ def write_sysinfo(op):
else:
output.write("Blender was built without Cycles support\n")
+ if not bpy.app.build_options.sdl:
+ output.write("SDL: Blender was built without SDL support\n")
+
if bpy.app.background:
output.write("\nOpenGL: missing, background mode\n")
else:
output.write("\nOpenGL\n")
output.write(lilies)
- version = bgl.glGetString(bgl.GL_RENDERER);
+ version = bgl.glGetString(bgl.GL_RENDERER)
output.write("renderer:\t%r\n" % version)
output.write("vendor:\t\t%r\n" % (bgl.glGetString(bgl.GL_VENDOR)))
output.write("version:\t%r\n" % (bgl.glGetString(bgl.GL_VERSION)))
@@ -187,6 +202,12 @@ def write_sysinfo(op):
bgl.glGetIntegerv(bgl.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, limit)
output.write("Maximum Pipeline Image Units:\t%d\n" % limit[0])
+ if bpy.app.build_options.cycles:
+ import cycles
+ output.write("\nCycles\n")
+ output.write(lilies)
+ output.write(cycles.engine.system_info())
+
output.current_line_index = 0
op.report({'INFO'}, "System information generated in 'system-info.txt'")
diff --git a/release/scripts/presets/hair_dynamics/default.py b/release/scripts/presets/hair_dynamics/default.py
new file mode 100644
index 00000000000..830d28a76f0
--- /dev/null
+++ b/release/scripts/presets/hair_dynamics/default.py
@@ -0,0 +1,17 @@
+import bpy
+psys = bpy.context.particle_system
+cloth = bpy.context.particle_system.cloth
+settings = bpy.context.particle_system.cloth.settings
+collision = bpy.context.particle_system.cloth.collision_settings
+
+settings.quality = 5
+settings.mass = 0.30000001192092896
+settings.bending_stiffness = 0.5
+psys.settings.bending_random = 0.0
+settings.bending_damping = 0.5
+settings.air_damping = 1.0
+settings.internal_friction = 0.0
+settings.density_target = 0.0
+settings.density_strength = 0.0
+settings.voxel_cell_size = 0.10000000149011612
+settings.pin_stiffness = 0.0
diff --git a/release/scripts/presets/interface_theme/back_to_black.xml b/release/scripts/presets/interface_theme/back_to_black.xml
index 0d377f9af68..6520d81b900 100644
--- a/release/scripts/presets/interface_theme/back_to_black.xml
+++ b/release/scripts/presets/interface_theme/back_to_black.xml
@@ -5,6 +5,7 @@
menu_shadow_width="12"
icon_file=""
icon_alpha="1"
+ widget_emboss="#ffffff05"
axis_x="#dc0000"
axis_y="#00dc00"
axis_z="#0000dc">
@@ -747,6 +748,7 @@
<ThemeNodeEditor node_selected="#ffffff"
node_active="#ffffff"
wire="#6eafff"
+ wire_inner="#737373"
wire_select="#0019ff"
selected_text="#7f7070"
node_backdrop="#202030bc"
@@ -970,7 +972,6 @@
locked_marker="#7f7f7f"
path_before="#ff0000"
path_after="#0000ff"
- grid="#5e5e5e"
frame_current="#1b501b"
strips="#0c0a0a"
strips_selected="#ff8c00"
diff --git a/release/scripts/presets/interface_theme/blender_24x.xml b/release/scripts/presets/interface_theme/blender_24x.xml
index 5ee0009eaaa..bb9b03d56ea 100644
--- a/release/scripts/presets/interface_theme/blender_24x.xml
+++ b/release/scripts/presets/interface_theme/blender_24x.xml
@@ -5,6 +5,7 @@
menu_shadow_width="12"
icon_file=""
icon_alpha="1"
+ widget_emboss="#ffffff05"
axis_x="#dc0000"
axis_y="#00dc00"
axis_z="#0000dc">
@@ -433,18 +434,18 @@
<nla_editor>
<ThemeNLAEditor grid="#5e5e5e"
view_sliders="#969696"
- active_action="#00000000"
- active_action_unset="#00000000"
+ active_action="#cc701a66"
+ active_action_unset="#9987614d"
strips="#0c0a0a"
strips_selected="#ff8c00"
- transition_strips="#000000"
- transition_strips_selected="#000000"
- meta_strips="#000000"
- meta_strips_selected="#000000"
- sound_strips="#000000"
- sound_strips_selected="#000000"
- tweak="#000000"
- tweak_duplicate="#000000"
+ transition_strips="#1c2630"
+ transition_strips_selected="#2e75db"
+ meta_strips="#332642"
+ meta_strips_selected="#692196"
+ sound_strips="#2b3d3d"
+ sound_strips_selected="#1f7a7a"
+ tweak="#4df31a"
+ tweak_duplicate="#d90000"
keyframe_border="#000000ff"
keyframe_border_selected="#000000ff"
frame_current="#60c040">
@@ -505,7 +506,7 @@
keyframe_jitter_selected="#61c042"
keyframe_border="#000000ff"
keyframe_border_selected="#000000ff"
- summary="#00000000">
+ summary="#cc701a66">
<space>
<ThemeSpaceGeneric back="#a0a0a0"
title="#000000"
@@ -747,6 +748,7 @@
<ThemeNodeEditor node_selected="#ffffff"
node_active="#ffffff"
wire="#000000"
+ wire_inner="#737373"
wire_select="#ffffff"
selected_text="#7f7070"
node_backdrop="#9b9b9ba0"
@@ -970,7 +972,6 @@
locked_marker="#7f7f7f"
path_before="#ff0000"
path_after="#0000ff"
- grid="#5e5e5e"
frame_current="#60c040"
strips="#0c0a0a"
strips_selected="#ff8c00"
diff --git a/release/scripts/presets/interface_theme/elsyiun.xml b/release/scripts/presets/interface_theme/elsyiun.xml
index 9b9804b5511..6734850f876 100644
--- a/release/scripts/presets/interface_theme/elsyiun.xml
+++ b/release/scripts/presets/interface_theme/elsyiun.xml
@@ -5,6 +5,7 @@
menu_shadow_width="12"
icon_file=""
icon_alpha="1"
+ widget_emboss="#ffffff05"
axis_x="#dc0000"
axis_y="#00dc00"
axis_z="#0000dc">
@@ -433,18 +434,18 @@
<nla_editor>
<ThemeNLAEditor grid="#585858"
view_sliders="#969696"
- active_action="#00000000"
- active_action_unset="#00000000"
+ active_action="#cc701a66"
+ active_action_unset="#9987614d"
strips="#0c0a0a"
strips_selected="#ff8c00"
- transition_strips="#000000"
- transition_strips_selected="#000000"
- meta_strips="#000000"
- meta_strips_selected="#000000"
- sound_strips="#000000"
- sound_strips_selected="#000000"
- tweak="#000000"
- tweak_duplicate="#000000"
+ transition_strips="#1c2630"
+ transition_strips_selected="#2e75db"
+ meta_strips="#332642"
+ meta_strips_selected="#692196"
+ sound_strips="#2b3d3d"
+ sound_strips_selected="#1f7a7a"
+ tweak="#4df31a"
+ tweak_duplicate="#d90000"
keyframe_border="#000000ff"
keyframe_border_selected="#000000ff"
frame_current="#60c040">
@@ -505,7 +506,7 @@
keyframe_jitter_selected="#61c042"
keyframe_border="#000000ff"
keyframe_border_selected="#000000ff"
- summary="#00000000">
+ summary="#cc701a66">
<space>
<ThemeSpaceGeneric back="#4b4b4b"
title="#000000"
@@ -747,6 +748,7 @@
<ThemeNodeEditor node_selected="#ffffff"
node_active="#ffffff"
wire="#000000"
+ wire_inner="#737373"
wire_select="#ffffff"
selected_text="#7f7070"
node_backdrop="#9b9b9ba0"
@@ -970,7 +972,6 @@
locked_marker="#7f7f7f"
path_before="#ff0000"
path_after="#0000ff"
- grid="#5e5e5e"
frame_current="#60c040"
strips="#0c0a0a"
strips_selected="#ff8c00"
diff --git a/release/scripts/presets/interface_theme/flatty_light.xml b/release/scripts/presets/interface_theme/flatty_light.xml
new file mode 100644
index 00000000000..e22d3471863
--- /dev/null
+++ b/release/scripts/presets/interface_theme/flatty_light.xml
@@ -0,0 +1,1175 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface menu_shadow_fac="0.3"
+ menu_shadow_width="4"
+ icon_file=""
+ icon_alpha="1"
+ widget_emboss="#00000005"
+ axis_x="#dc0000"
+ axis_y="#00dc00"
+ axis_z="#0000dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#9d9d9d"
+ inner="#b3b3b3ff"
+ inner_sel="#5680c2ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#c7c7c7"
+ inner="#dbdbdbff"
+ inner_sel="#5680c2ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#4d4d4d"
+ inner="#464646ff"
+ inner_sel="#5680c2ff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#666666"
+ inner="#2f2f2fff"
+ inner_sel="#5680c2ff"
+ item="#80b1ffff"
+ text="#dddddd"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-8"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#999999"
+ inner="#434343ff"
+ inner_sel="#5680c2ff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#808080"
+ inner="#b3b3b3ff"
+ inner_sel="#5680c2ff"
+ item="#191919ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#b8b8b8"
+ inner="#d3d3d3ff"
+ inner_sel="#5680c2ff"
+ item="#999999ff"
+ text="#1a1a1a"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-10"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#999999"
+ inner="#3c3c3cff"
+ inner_sel="#333333ff"
+ item="#5680c2ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-4"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#959595"
+ inner="#cccccccc"
+ inner_sel="#5680c2ff"
+ item="#191919ff"
+ text="#333333"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#2d2d2d"
+ inner="#434343ff"
+ inner_sel="#596880ff"
+ item="#ffffffff"
+ text="#e6e6e6"
+ text_sel="#cccccc"
+ show_shaded="FALSE"
+ shadetop="10"
+ shadedown="-10">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#000000"
+ inner="#3f3f3fff"
+ inner_sel="#5680c2ff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#1f1f1f"
+ inner="#1f1f1fef"
+ inner_sel="#5680c2ff"
+ item="#646464ff"
+ text="#e6e6e6"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_pie_menu>
+ <ThemeWidgetColors outline="#4d4d4d"
+ inner="#1a1a1aff"
+ inner_sel="#5680c2ff"
+ item="#5680c2ff"
+ text="#e6e6e6"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="10"
+ shadedown="-10">
+ </ThemeWidgetColors>
+ </wcol_pie_menu>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#1f1f1fef"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#000000"
+ inner="#00000000"
+ inner_sel="#5680c2ff"
+ item="#acacac80"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="38"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#999999"
+ inner="#50505000"
+ inner_sel="#646464b3"
+ item="#c2c2c299"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#b3b3b3"
+ inner="#ccccccff"
+ inner_sel="#646464b4"
+ item="#5094ffff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#e6e6e6"
+ inner="#00000000"
+ inner_sel="#5680c2ff"
+ item="#cccccc80"
+ text="#1a1a1a"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#73be4c"
+ inner_anim_sel="#5aa633"
+ inner_key="#f0eb64"
+ inner_key_sel="#d7d34b"
+ inner_driven="#b400ff"
+ inner_driven_sel="#9900e6"
+ blend="0.5">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#414141"
+ wire="#000000"
+ wire_edit="#808080"
+ gp_vertex="#000000"
+ gp_vertex_select="#000000"
+ gp_vertex_size="1"
+ lamp="#00000028"
+ speaker="#000000"
+ camera="#000000"
+ view_overlay="#808080"
+ empty="#000000"
+ object_selected="#f15800"
+ object_active="#ffaa40"
+ object_grouped="#083008"
+ object_grouped_active="#55bb55"
+ transform="#ffffff"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ vertex_unreferenced="#000000"
+ edge_select="#ffa000"
+ edge_seam="#db2512"
+ edge_sharp="#00ffff"
+ edge_crease="#cc0099"
+ edge_facesel="#4b4b4b"
+ freestyle_edge_mark="#7fff7f"
+ face="#00000012"
+ face_select="#ff85004d"
+ face_dot="#ff8500"
+ facedot_size="4"
+ freestyle_face_mark="#7fff7f33"
+ nurb_uline="#909000"
+ nurb_vline="#803060"
+ nurb_sel_uline="#f0ff40"
+ nurb_sel_vline="#f090a0"
+ act_spline="#db2512"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_sel_vect="#40c030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ lastsel_point="#ffffff"
+ extra_edge_len="#150806"
+ extra_edge_angle="#4d4d00"
+ extra_face_angle="#0000cc"
+ extra_face_area="#004d00"
+ editmesh_active="#ffffff80"
+ normal="#22dddd"
+ vertex_normal="#2361dd"
+ split_normal="#dd23dd"
+ bone_solid="#c8c8c8"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#60c040"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#000000"
+ skin_root="#b44d4d"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
+ <space>
+ <ThemeSpaceGradient title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#999999"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#999999e6"
+ button_title="#1a1a1a"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#cccccc"
+ tab_back="#999999ff"
+ tab_outline="#999999">
+ <gradients>
+ <ThemeGradientColors show_grad="TRUE"
+ gradient="#1b1b1b"
+ high_gradient="#3a3a3a">
+ </ThemeGradientColors>
+ </gradients>
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGradient>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#5e5e5e"
+ frame_current="#60c040"
+ window_sliders="#969696"
+ channels_region="#999999"
+ dopesheet_channel="#2e6399"
+ dopesheet_subchannel="#7aa4cc"
+ channel_group="#278c0e"
+ active_channels_group="#4db135"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="6"
+ vertex_unreferenced="#000000"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_sel_vect="#40c030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#994030"
+ handle_sel_auto_clamped="#f0af90"
+ lastsel_point="#ffffff"
+ handle_vertex="#000000"
+ handle_vertex_select="#ff8500"
+ handle_vertex_size="5">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#adadad"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#999999e6"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#999999ff"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#adadad"
+ list_title="#000000"
+ list_text="#050505"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#ff8c19"
+ scrollbar="#a0a0a0"
+ scroll_handle="#7f7070"
+ active_file="#828282"
+ active_file_text="#fafafa">
+ <space>
+ <ThemeSpaceGeneric back="#404040"
+ title="#000000"
+ text="#f1f1f1"
+ text_hi="#0f0f0f"
+ header="#b3b3b3"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#808080"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#5e5e5e"
+ view_sliders="#969696"
+ active_action="#cc701a66"
+ active_action_unset="#9987614d"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ transition_strips="#1c2630"
+ transition_strips_selected="#2e75db"
+ meta_strips="#332642"
+ meta_strips_selected="#692196"
+ sound_strips="#2b3d3d"
+ sound_strips_selected="#1f7a7a"
+ tweak="#4df31a"
+ tweak_duplicate="#d90000"
+ keyframe_border="#000000ff"
+ keyframe_border_selected="#000000ff"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#adadad"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#adadad"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#5e5e5e"
+ frame_current="#60c040"
+ value_sliders="#000000"
+ view_sliders="#969696"
+ dopesheet_channel="#2e6399"
+ dopesheet_subchannel="#7aa4cc"
+ channels="#707070"
+ channels_selected="#60c040"
+ channel_group="#278c0e"
+ active_channels_group="#4eb335"
+ long_key="#1a1515"
+ long_key_selected="#ff8c00"
+ keyframe="#e8e8e8"
+ keyframe_selected="#ffbe33"
+ keyframe_extreme="#e8b3cc"
+ keyframe_extreme_selected="#f28080"
+ keyframe_breakdown="#b3dbe8"
+ keyframe_breakdown_selected="#54bfed"
+ keyframe_jitter="#94e575"
+ keyframe_jitter_selected="#61c042"
+ keyframe_border="#000000ff"
+ keyframe_border_selected="#000000ff"
+ summary="#d3660066">
+ <space>
+ <ThemeSpaceGeneric back="#6b6b6b"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#adadad"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#adadad"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor gp_vertex="#000000"
+ gp_vertex_select="#000000"
+ gp_vertex_size="1"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ vertex_unreferenced="#000000"
+ face="#ffffff0a"
+ face_select="#ff85003c"
+ face_dot="#ff8500"
+ facedot_size="3"
+ freestyle_face_mark="#7fff7f33"
+ editmesh_active="#ffffff80"
+ wire_edit="#c0c0c0"
+ edge_select="#ff8500"
+ scope_back="#727272ff"
+ preview_stitch_face="#7f7f0033"
+ preview_stitch_edge="#ff00ff33"
+ preview_stitch_vert="#0000ff33"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#e1d2c323"
+ uv_shadow="#707070ff"
+ uv_others="#606060ff"
+ frame_current="#60c040"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="5"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
+ <space>
+ <ThemeSpaceGeneric back="#353535"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b3b3b3"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#999999b3"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor gp_vertex="#000000"
+ gp_vertex_select="#000000"
+ gp_vertex_size="1"
+ grid="#404040"
+ window_sliders="#a0a0a0"
+ movie_strip="#516987"
+ movieclip_strip="#20208f"
+ image_strip="#6d5881"
+ scene_strip="#4e983e"
+ audio_strip="#2e8f8f"
+ effect_strip="#a9547c"
+ transition_strip="#a25f6f"
+ meta_strip="#6d9183"
+ frame_current="#60c040"
+ keyframe="#ff8500"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#747474"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b3b3b3"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#959595e6"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#999999"
+ title="#181818"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b3b3b3"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#313133"
+ selected_text="#19191a"
+ cursor="#ff0000"
+ syntax_builtin="#ff1961"
+ syntax_symbols="#ff734d"
+ syntax_special="#95d600"
+ syntax_preprocessor="#ad80ff"
+ syntax_reserved="#c4753b"
+ syntax_comment="#939393"
+ syntax_string="#f6e162"
+ syntax_numbers="#50dbff">
+ <space>
+ <ThemeSpaceGeneric back="#313133"
+ title="#000000"
+ text="#e6e6e6"
+ text_hi="#ffffff"
+ header="#b3b3b3"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#5b5b5b"
+ frame_current="#60c040"
+ time_keyframe="#000000"
+ time_grease_pencil="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#a6a6a6"
+ header_text="#0b0b0b"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor gp_vertex="#000000"
+ gp_vertex_select="#000000"
+ gp_vertex_size="1"
+ node_selected="#f15800"
+ node_active="#f15800"
+ wire="#a7a7a7"
+ wire_inner="#999999"
+ wire_select="#ffa733"
+ selected_text="#7f7070"
+ node_backdrop="#e6e6e6ff"
+ converter_node="#66c4ff"
+ color_node="#ffcb4d"
+ group_node="#59b36a"
+ group_socket_node="#dfc300"
+ frame_node="#9b9b9ba0"
+ matte_node="#977474"
+ distor_node="#749797"
+ noodle_curving="0"
+ input_node="#ff6675"
+ output_node="#ff6675"
+ filter_node="#6c696f"
+ vector_node="#9999ff"
+ texture_node="#ffc399"
+ shader_node="#a7ff99"
+ script_node="#6c696f"
+ pattern_node="#6c696f"
+ layout_node="#6c696f">
+ <space>
+ <ThemeSpaceGeneric back="#474747"
+ title="#000000"
+ text="#0d0d0d"
+ text_hi="#ffffff"
+ header="#b3b3b3"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#cccccc"
+ tab_back="#999999ff"
+ tab_outline="#999999">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#999999ff"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#a5a5a5"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#646464"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b3b3b3"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#337f33"
+ selected_highlight="#7297d0">
+ <space>
+ <ThemeSpaceGeneric back="#b3b3b3"
+ title="#000000"
+ text="#1a1a1a"
+ text_hi="#ffffff"
+ header="#b3b3b3"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo info_selected="#6080ff"
+ info_selected_text="#ffffff"
+ info_error="#990000"
+ info_error_text="#ffffff"
+ info_warning="#b36a00"
+ info_warning_text="#ffffff"
+ info_info="#668000"
+ info_info_text="#ffffff"
+ info_debug="#d3d3d3"
+ info_debug_text="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#727272"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b3b3b3"
+ header_text="#1a1a1a"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#999999"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#b3b3b3"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#6080ff"
+ line_input="#ffffff"
+ line_info="#00aa00"
+ line_error="#dc6060"
+ cursor="#dc6060"
+ select="#ffffff30">
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor gp_vertex="#000000"
+ gp_vertex_select="#000000"
+ gp_vertex_size="1"
+ marker_outline="#000000"
+ marker="#7f7f00"
+ active_marker="#ffffff"
+ selected_marker="#ffff00"
+ disabled_marker="#7f0000"
+ locked_marker="#7f7f7f"
+ path_before="#ff0000"
+ path_after="#0000ff"
+ frame_current="#60c040"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="5">
+ <space>
+ <ThemeSpaceGeneric back="#393939"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#727272"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#7272727f"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#6697e6"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#c2c2c2ea"
+ back="#99999980"
+ show_header="TRUE"
+ show_back="TRUE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+ <ThemeStyle>
+ <panel_title>
+ <ThemeFontStyle points="12"
+ font_kerning_style="FITTED"
+ shadow="2"
+ shadow_offset_x="2"
+ shadow_offset_y="-2"
+ shadow_alpha="0.1"
+ shadow_value="1">
+ </ThemeFontStyle>
+ </panel_title>
+ <widget_label>
+ <ThemeFontStyle points="11"
+ font_kerning_style="FITTED"
+ shadow="1"
+ shadow_offset_x="1"
+ shadow_offset_y="-1"
+ shadow_alpha="0.2"
+ shadow_value="1">
+ </ThemeFontStyle>
+ </widget_label>
+ <widget>
+ <ThemeFontStyle points="11"
+ font_kerning_style="FITTED"
+ shadow="1"
+ shadow_offset_x="1"
+ shadow_offset_y="-1"
+ shadow_alpha="0.1"
+ shadow_value="1">
+ </ThemeFontStyle>
+ </widget>
+ </ThemeStyle>
+</bpy>
diff --git a/release/scripts/presets/interface_theme/graph.xml b/release/scripts/presets/interface_theme/graph.xml
index 669fb936948..1cb9a8985e4 100644
--- a/release/scripts/presets/interface_theme/graph.xml
+++ b/release/scripts/presets/interface_theme/graph.xml
@@ -5,6 +5,7 @@
menu_shadow_width="12"
icon_file=""
icon_alpha="1"
+ widget_emboss="#ffffff05"
axis_x="#dc0000"
axis_y="#00dc00"
axis_z="#0000dc">
@@ -286,6 +287,7 @@
editmesh_active="#00f6ff5e"
normal="#22dddd"
vertex_normal="#2361dd"
+ split_normal="#dd23dd"
bone_solid="#ffffff"
bone_pose="#00b5ff"
bone_pose_active="#fff3fa"
@@ -432,18 +434,18 @@
<nla_editor>
<ThemeNLAEditor grid="#6e6e6e"
view_sliders="#969696"
- active_action="#00000000"
- active_action_unset="#00000000"
+ active_action="#cc701a66"
+ active_action_unset="#9987614d"
strips="#0c0a0a"
strips_selected="#ff8c00"
- transition_strips="#000000"
- transition_strips_selected="#000000"
- meta_strips="#000000"
- meta_strips_selected="#000000"
- sound_strips="#000000"
- sound_strips_selected="#000000"
- tweak="#000000"
- tweak_duplicate="#000000"
+ transition_strips="#1c2630"
+ transition_strips_selected="#2e75db"
+ meta_strips="#332642"
+ meta_strips_selected="#692196"
+ sound_strips="#2b3d3d"
+ sound_strips_selected="#1f7a7a"
+ tweak="#4df31a"
+ tweak_duplicate="#d90000"
keyframe_border="#000000ff"
keyframe_border_selected="#000000ff"
frame_current="#4291dc">
@@ -746,6 +748,7 @@
<ThemeNodeEditor node_selected="#fff4f8"
node_active="#ffffff"
wire="#292929"
+ wire_inner="#737373"
wire_select="#ffffff"
selected_text="#909090"
node_backdrop="#444444ff"
@@ -969,7 +972,6 @@
locked_marker="#7f7f7f"
path_before="#ff0000"
path_after="#0000ff"
- grid="#5e5e5e"
frame_current="#60c040"
strips="#0c0a0a"
strips_selected="#ff8c00"
diff --git a/release/scripts/presets/interface_theme/hexagon.xml b/release/scripts/presets/interface_theme/hexagon.xml
index 6f24d989e79..40228e832a7 100644
--- a/release/scripts/presets/interface_theme/hexagon.xml
+++ b/release/scripts/presets/interface_theme/hexagon.xml
@@ -5,6 +5,7 @@
menu_shadow_width="12"
icon_file=""
icon_alpha="1"
+ widget_emboss="#ffffff05"
axis_x="#dc0000"
axis_y="#00dc00"
axis_z="#0000dc">
@@ -433,18 +434,18 @@
<nla_editor>
<ThemeNLAEditor grid="#5e5e5e"
view_sliders="#969696"
- active_action="#00000000"
- active_action_unset="#00000000"
+ active_action="#cc701a66"
+ active_action_unset="#9987614d"
strips="#0c0a0a"
strips_selected="#ff8c00"
- transition_strips="#000000"
- transition_strips_selected="#000000"
- meta_strips="#000000"
- meta_strips_selected="#000000"
- sound_strips="#000000"
- sound_strips_selected="#000000"
- tweak="#000000"
- tweak_duplicate="#000000"
+ transition_strips="#1c2630"
+ transition_strips_selected="#2e75db"
+ meta_strips="#332642"
+ meta_strips_selected="#692196"
+ sound_strips="#2b3d3d"
+ sound_strips_selected="#1f7a7a"
+ tweak="#4df31a"
+ tweak_duplicate="#d90000"
keyframe_border="#000000ff"
keyframe_border_selected="#000000ff"
frame_current="#60c040">
@@ -505,7 +506,7 @@
keyframe_jitter_selected="#61c042"
keyframe_border="#000000ff"
keyframe_border_selected="#000000ff"
- summary="#00000000">
+ summary="#cc701a66">
<space>
<ThemeSpaceGeneric back="#7c7e88"
title="#000000"
@@ -747,6 +748,7 @@
<ThemeNodeEditor node_selected="#ffffff"
node_active="#ffffff"
wire="#000000"
+ wire_inner="#737373"
wire_select="#ffffff"
selected_text="#7f7070"
node_backdrop="#9b9baca0"
@@ -970,7 +972,6 @@
locked_marker="#7f7f7f"
path_before="#ff0000"
path_after="#0000ff"
- grid="#5e5e5e"
frame_current="#60c040"
strips="#0c0a0a"
strips_selected="#ff8c00"
diff --git a/release/scripts/presets/interface_theme/rtheme.xml b/release/scripts/presets/interface_theme/rtheme.xml
new file mode 100644
index 00000000000..268b2e0f1ae
--- /dev/null
+++ b/release/scripts/presets/interface_theme/rtheme.xml
@@ -0,0 +1,1176 @@
+<bpy>
+ <Theme>
+ <user_interface>
+ <ThemeUserInterface menu_shadow_fac="0.5"
+ menu_shadow_width="12"
+ icon_file=""
+ icon_alpha="1"
+ widget_emboss="#ffffff05"
+ axis_x="#dc403e"
+ axis_y="#68dc50"
+ axis_z="#4040dc">
+ <wcol_regular>
+ <ThemeWidgetColors outline="#222222"
+ inner="#3f3f3fff"
+ inner_sel="#222222ff"
+ item="#000000ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_regular>
+ <wcol_tool>
+ <ThemeWidgetColors outline="#222222"
+ inner="#666666ff"
+ inner_sel="#08c1ffff"
+ item="#000000ff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="-10">
+ </ThemeWidgetColors>
+ </wcol_tool>
+ <wcol_radio>
+ <ThemeWidgetColors outline="#222222"
+ inner="#464646ff"
+ inner_sel="#05c4ffff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_radio>
+ <wcol_text>
+ <ThemeWidgetColors outline="#3d3d3b"
+ inner="#666666ff"
+ inner_sel="#999999ff"
+ item="#5a5a5aff"
+ text="#fdfdfd"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="25">
+ </ThemeWidgetColors>
+ </wcol_text>
+ <wcol_option>
+ <ThemeWidgetColors outline="#222222"
+ inner="#686868ff"
+ inner_sel="#05c4ffff"
+ item="#000000ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_option>
+ <wcol_toggle>
+ <ThemeWidgetColors outline="#302e2e"
+ inner="#999999ff"
+ inner_sel="#05c4ffff"
+ item="#5a5a5aff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_toggle>
+ <wcol_num>
+ <ThemeWidgetColors outline="#222222"
+ inner="#666666ff"
+ inner_sel="#05c4ffff"
+ item="#5a5a5aff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="-10"
+ shadedown="10">
+ </ThemeWidgetColors>
+ </wcol_num>
+ <wcol_numslider>
+ <ThemeWidgetColors outline="#222222"
+ inner="#606060ff"
+ inner_sel="#999999ff"
+ item="#3a3a3aff"
+ text="#e6e6e6"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="-10"
+ shadedown="10">
+ </ThemeWidgetColors>
+ </wcol_numslider>
+ <wcol_box>
+ <ThemeWidgetColors outline="#222222"
+ inner="#464646ff"
+ inner_sel="#646464ff"
+ item="#000000ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_box>
+ <wcol_menu>
+ <ThemeWidgetColors outline="#222222"
+ inner="#606060ff"
+ inner_sel="#08bfffff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="15"
+ shadedown="-15">
+ </ThemeWidgetColors>
+ </wcol_menu>
+ <wcol_pulldown>
+ <ThemeWidgetColors outline="#222222"
+ inner="#606060ff"
+ inner_sel="#0bc6ffff"
+ item="#ffffffff"
+ text="#888888"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_pulldown>
+ <wcol_menu_back>
+ <ThemeWidgetColors outline="#3d3d3d"
+ inner="#3d3d3de6"
+ inner_sel="#2d2d2de6"
+ item="#5f5f5fff"
+ text="#a0a0a0"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_menu_back>
+ <wcol_pie_menu>
+ <ThemeWidgetColors outline="#0a0a0a"
+ inner="#aaaaaae6"
+ inner_sel="#8c8c8cff"
+ item="#a2a2a2e6"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="TRUE"
+ shadetop="10"
+ shadedown="-10">
+ </ThemeWidgetColors>
+ </wcol_pie_menu>
+ <wcol_tooltip>
+ <ThemeWidgetColors outline="#000000"
+ inner="#191919e6"
+ inner_sel="#2d2d2de6"
+ item="#646464ff"
+ text="#ffffff"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="25"
+ shadedown="-20">
+ </ThemeWidgetColors>
+ </wcol_tooltip>
+ <wcol_menu_item>
+ <ThemeWidgetColors outline="#222222"
+ inner="#00000000"
+ inner_sel="#0bc3ffff"
+ item="#ffffffff"
+ text="#ffffff"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="38"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_menu_item>
+ <wcol_scroll>
+ <ThemeWidgetColors outline="#323232"
+ inner="#505050b4"
+ inner_sel="#646464b4"
+ item="#606060ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_scroll>
+ <wcol_progress>
+ <ThemeWidgetColors outline="#222222"
+ inner="#bebebeff"
+ inner_sel="#646464b4"
+ item="#444444ff"
+ text="#000000"
+ text_sel="#ffffff"
+ show_shaded="FALSE"
+ shadetop="5"
+ shadedown="-5">
+ </ThemeWidgetColors>
+ </wcol_progress>
+ <wcol_list_item>
+ <ThemeWidgetColors outline="#222222"
+ inner="#00000000"
+ inner_sel="#0abeffff"
+ item="#ffffffff"
+ text="#000000"
+ text_sel="#000000"
+ show_shaded="FALSE"
+ shadetop="0"
+ shadedown="0">
+ </ThemeWidgetColors>
+ </wcol_list_item>
+ <wcol_state>
+ <ThemeWidgetStateColors inner_anim="#73be4c"
+ inner_anim_sel="#5aa633"
+ inner_key="#c9ce20"
+ inner_key_sel="#d7d34b"
+ inner_driven="#b400ff"
+ inner_driven_sel="#9900e6"
+ blend="0.5">
+ </ThemeWidgetStateColors>
+ </wcol_state>
+ </ThemeUserInterface>
+ </user_interface>
+ <view_3d>
+ <ThemeView3D grid="#4c4c4c"
+ wire="#7e7e7e"
+ wire_edit="#1d1d1d"
+ gp_vertex="#000000"
+ gp_vertex_select="#ff8500"
+ gp_vertex_size="3"
+ lamp="#00000028"
+ speaker="#000000"
+ camera="#000000"
+ view_overlay="#000000"
+ empty="#000000"
+ object_selected="#69adc2"
+ object_active="#08c1ff"
+ object_grouped="#08583d"
+ object_grouped_active="#19ffce"
+ transform="#ffffff"
+ vertex="#000000"
+ vertex_select="#f0f8ff"
+ vertex_size="3"
+ vertex_unreferenced="#000000"
+ edge_select="#08c1ff"
+ edge_seam="#ff5b00"
+ edge_sharp="#ff1600"
+ edge_crease="#52514d"
+ edge_facesel="#4b4b4b"
+ freestyle_edge_mark="#7fff7f"
+ face="#00000012"
+ face_select="#08c1ff66"
+ face_dot="#49caff"
+ facedot_size="4"
+ freestyle_face_mark="#7fff7f33"
+ nurb_uline="#909000"
+ nurb_vline="#803060"
+ nurb_sel_uline="#f0ff40"
+ nurb_sel_vline="#f090a0"
+ act_spline="#db2512"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_sel_vect="#40c030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ lastsel_point="#ffffff"
+ extra_edge_len="#200000"
+ extra_edge_angle="#000000"
+ extra_face_angle="#002000"
+ extra_face_area="#000080"
+ editmesh_active="#08c1ffff"
+ normal="#22dddd"
+ vertex_normal="#2361dd"
+ split_normal="#dd23dd"
+ bone_solid="#c8c8c8"
+ bone_pose="#50c8ff"
+ bone_pose_active="#8cffff"
+ frame_current="#60c040"
+ outline_width="1"
+ bundle_solid="#c8c8c8"
+ camera_path="#000000"
+ skin_root="#b44d4d"
+ clipping_border_3d="#313131ff"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
+ <space>
+ <ThemeSpaceGradient title="#000000"
+ text="#0e0e0e"
+ text_hi="#dddddd"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#c2c2c2"
+ button_text_hi="#ffffff"
+ tab_active="#474747"
+ tab_inactive="#333333"
+ tab_back="#31313100"
+ tab_outline="#000000">
+ <gradients>
+ <ThemeGradientColors show_grad="FALSE"
+ gradient="#000000"
+ high_gradient="#36383a">
+ </ThemeGradientColors>
+ </gradients>
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGradient>
+ </space>
+ </ThemeView3D>
+ </view_3d>
+ <graph_editor>
+ <ThemeGraphEditor grid="#5b6672"
+ frame_current="#60c040"
+ window_sliders="#969696"
+ channels_region="#707070"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
+ vertex_unreferenced="#000000"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_vect="#409030"
+ handle_sel_vect="#40c030"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#994030"
+ handle_sel_auto_clamped="#f0af90"
+ lastsel_point="#ffffff"
+ handle_vertex="#000000"
+ handle_vertex_select="#ff8500"
+ handle_vertex_size="3">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#484848"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeGraphEditor>
+ </graph_editor>
+ <file_browser>
+ <ThemeFileBrowser selected_file="#ff8c19"
+ scrollbar="#a0a0a0"
+ scroll_handle="#7f7070"
+ active_file="#828282"
+ active_file_text="#fafafa">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#fafafa"
+ text_hi="#0f0f0f"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#726f6dff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#484848"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeFileBrowser>
+ </file_browser>
+ <nla_editor>
+ <ThemeNLAEditor grid="#5b6672"
+ view_sliders="#969696"
+ active_action="#cc701a66"
+ active_action_unset="#00000000"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ transition_strips="#000000"
+ transition_strips_selected="#000000"
+ meta_strips="#000000"
+ meta_strips_selected="#000000"
+ sound_strips="#000000"
+ sound_strips_selected="#000000"
+ tweak="#000000"
+ tweak_duplicate="#000000"
+ keyframe_border="#000000ff"
+ keyframe_border_selected="#000000ff"
+ frame_current="#60c040">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#484848"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNLAEditor>
+ </nla_editor>
+ <dopesheet_editor>
+ <ThemeDopeSheet grid="#5b6672"
+ frame_current="#60c040"
+ value_sliders="#000000"
+ view_sliders="#969696"
+ dopesheet_channel="#52606e"
+ dopesheet_subchannel="#7c8996"
+ channels="#707070"
+ channels_selected="#60c040"
+ channel_group="#4f6549"
+ active_channels_group="#87b17d"
+ long_key="#0c0a0a"
+ long_key_selected="#ff8c00"
+ keyframe="#f1f9ff"
+ keyframe_selected="#00dfff"
+ keyframe_extreme="#e5e2e8"
+ keyframe_extreme_selected="#f2efef"
+ keyframe_breakdown="#b3dbe8"
+ keyframe_breakdown_selected="#54bfed"
+ keyframe_jitter="#e5e2e2"
+ keyframe_jitter_selected="#beb8c0"
+ keyframe_border="#f1f9ffff"
+ keyframe_border_selected="#00dfffff"
+ summary="#cc701a66">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#484848"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeDopeSheet>
+ </dopesheet_editor>
+ <image_editor>
+ <ThemeImageEditor gp_vertex="#000000"
+ gp_vertex_select="#ff8500"
+ gp_vertex_size="3"
+ vertex="#000000"
+ vertex_select="#08c1ff"
+ vertex_size="3"
+ vertex_unreferenced="#000000"
+ face="#ffffff0a"
+ face_select="#08c1ff40"
+ face_dot="#08c1ff"
+ facedot_size="3"
+ freestyle_face_mark="#00000000"
+ editmesh_active="#08c1ffff"
+ wire_edit="#5c5c5c"
+ edge_select="#0067cb"
+ scope_back="#727272ff"
+ preview_stitch_face="#1242b026"
+ preview_stitch_edge="#08c1ff97"
+ preview_stitch_vert="#08c1ff91"
+ preview_stitch_stitchable="#00ff00ff"
+ preview_stitch_unstitchable="#ff0000ff"
+ preview_stitch_active="#e1d2c323"
+ uv_shadow="#707070ff"
+ uv_others="#606060ff"
+ frame_current="#60c040"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="5"
+ paint_curve_handle="#7fff7f7f"
+ paint_curve_pivot="#ff7f7f7f">
+ <space>
+ <ThemeSpaceGeneric back="#1d1d1d"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeImageEditor>
+ </image_editor>
+ <sequence_editor>
+ <ThemeSequenceEditor gp_vertex="#000000"
+ gp_vertex_select="#ff8500"
+ gp_vertex_size="3"
+ grid="#9098a0"
+ window_sliders="#a0a0a0"
+ movie_strip="#516987"
+ movieclip_strip="#20208f"
+ image_strip="#6d5881"
+ scene_strip="#4e983e"
+ audio_strip="#2e8f8f"
+ effect_strip="#a9547c"
+ transition_strip="#a25f6f"
+ meta_strip="#6d9183"
+ frame_current="#60c040"
+ keyframe="#ff8500"
+ draw_action="#50c8ff"
+ preview_back="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeSequenceEditor>
+ </sequence_editor>
+ <properties>
+ <ThemeProperties>
+ <space>
+ <ThemeSpaceGeneric back="#484848"
+ title="#000000"
+ text="#000000"
+ text_hi="#000000"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#dff5ff"
+ button="#484848a7"
+ button_title="#3f3a2f"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeProperties>
+ </properties>
+ <text_editor>
+ <ThemeTextEditor line_numbers_background="#404040"
+ selected_text="#c67777"
+ cursor="#ff0000"
+ syntax_builtin="#800050"
+ syntax_symbols="#4c4c4c"
+ syntax_special="#5f5f00"
+ syntax_preprocessor="#32008c"
+ syntax_reserved="#8c3c00"
+ syntax_comment="#006432"
+ syntax_string="#640000"
+ syntax_numbers="#0000c8">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTextEditor>
+ </text_editor>
+ <timeline>
+ <ThemeTimeline grid="#5b6672"
+ frame_current="#60c040"
+ time_keyframe="#ddd700"
+ time_grease_pencil="#b5e61d">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeTimeline>
+ </timeline>
+ <node_editor>
+ <ThemeNodeEditor gp_vertex="#000000"
+ gp_vertex_select="#ff8500"
+ gp_vertex_size="3"
+ node_selected="#69adc2"
+ node_active="#08c1ff"
+ wire="#7c7c7c"
+ wire_inner="#737373"
+ wire_select="#08c1ff"
+ selected_text="#7f7070"
+ node_backdrop="#9b9b9ba0"
+ converter_node="#575757"
+ color_node="#575757"
+ group_node="#729c91"
+ group_socket_node="#19ffce"
+ frame_node="#96969600"
+ matte_node="#977474"
+ distor_node="#749797"
+ noodle_curving="5"
+ input_node="#575757"
+ output_node="#ffce18"
+ filter_node="#575757"
+ vector_node="#575757"
+ texture_node="#00c6ff"
+ shader_node="#356cff"
+ script_node="#575757"
+ pattern_node="#575757"
+ layout_node="#727272">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#484848"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeNodeEditor>
+ </node_editor>
+ <logic_editor>
+ <ThemeLogicEditor>
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeLogicEditor>
+ </logic_editor>
+ <outliner>
+ <ThemeOutliner match="#337f33"
+ selected_highlight="#9098a0">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#0e0e0e"
+ text="#000000"
+ text_hi="#69deff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#484848a7"
+ button_title="#070707"
+ button_text="#000000"
+ button_text_hi="#fdfcff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeOutliner>
+ </outliner>
+ <info>
+ <ThemeInfo info_selected="#08c1ff"
+ info_selected_text="#ffffff"
+ info_error="#dc0000"
+ info_error_text="#000000"
+ info_warning="#dc8060"
+ info_warning_text="#000000"
+ info_info="#00aa00"
+ info_info_text="#000000"
+ info_debug="#c4c4c4"
+ info_debug_text="#000000">
+ <space>
+ <ThemeSpaceGeneric back="#9098a0"
+ title="#c8c6c9"
+ text="#333333"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#888888"
+ header_text_hi="#ffffff"
+ button="#725864ff"
+ button_title="#f1c2d8"
+ button_text="#f0f0f0"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeInfo>
+ </info>
+ <user_preferences>
+ <ThemeUserPreferences>
+ <space>
+ <ThemeSpaceGeneric back="#484848"
+ title="#000000"
+ text="#ffffff"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#fdffff"
+ button="#484848a7"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeUserPreferences>
+ </user_preferences>
+ <console>
+ <ThemeConsole line_output="#6080ff"
+ line_input="#ffffff"
+ line_info="#00aa00"
+ line_error="#dc6060"
+ cursor="#dc6060"
+ select="#ffffff30">
+ <space>
+ <ThemeSpaceGeneric back="#000000"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#727272ff"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ </ThemeConsole>
+ </console>
+ <clip_editor>
+ <ThemeClipEditor gp_vertex="#000000"
+ gp_vertex_select="#000000"
+ gp_vertex_size="0"
+ marker_outline="#000000"
+ marker="#7f7f00"
+ active_marker="#ffffff"
+ selected_marker="#ffff00"
+ disabled_marker="#7f0000"
+ locked_marker="#7f7f7f"
+ path_before="#ff0000"
+ path_after="#0000ff"
+ frame_current="#60c040"
+ strips="#0c0a0a"
+ strips_selected="#ff8c00"
+ handle_free="#000000"
+ handle_auto="#909000"
+ handle_align="#803060"
+ handle_sel_free="#000000"
+ handle_sel_auto="#f0ff40"
+ handle_sel_align="#f090a0"
+ handle_auto_clamped="#000000"
+ handle_sel_auto_clamped="#000000"
+ handle_vertex="#000000"
+ handle_vertex_select="#ffff00"
+ handle_vertex_size="5">
+ <space>
+ <ThemeSpaceGeneric back="#40464e"
+ title="#000000"
+ text="#000000"
+ text_hi="#ffffff"
+ header="#484848"
+ header_text="#000000"
+ header_text_hi="#ffffff"
+ button="#48484880"
+ button_title="#000000"
+ button_text="#000000"
+ button_text_hi="#ffffff"
+ tab_active="#727272"
+ tab_inactive="#535353"
+ tab_back="#404040ff"
+ tab_outline="#3c3c3c">
+ <panelcolors>
+ <ThemePanelColors header="#ffffff79"
+ back="#72727280"
+ show_header="FALSE"
+ show_back="FALSE">
+ </ThemePanelColors>
+ </panelcolors>
+ </ThemeSpaceGeneric>
+ </space>
+ <space_list>
+ <ThemeSpaceListGeneric list="#666666"
+ list_title="#000000"
+ list_text="#000000"
+ list_text_hi="#ffffff">
+ </ThemeSpaceListGeneric>
+ </space_list>
+ </ThemeClipEditor>
+ </clip_editor>
+ <bone_color_sets>
+ <ThemeBoneColorSet normal="#9a0000"
+ select="#bd1111"
+ active="#f70a0a"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f74018"
+ select="#f66913"
+ active="#fa9900"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e9109"
+ select="#59b70b"
+ active="#83ef1d"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#0a3694"
+ select="#3667df"
+ active="#5ec1ef"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#a9294e"
+ select="#c1416a"
+ active="#f05d91"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#430c78"
+ select="#543aa3"
+ active="#8764d5"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#24785a"
+ select="#3c9579"
+ active="#6fb6ab"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#4b707c"
+ select="#6a8691"
+ active="#9bc2cd"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#f4c90c"
+ select="#eec236"
+ active="#f3ff00"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#1e2024"
+ select="#484c56"
+ active="#ffffff"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6f2f6a"
+ select="#9845be"
+ active="#d330d6"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#6c8e22"
+ select="#7fb022"
+ active="#bbef5b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#8d8d8d"
+ select="#b0b0b0"
+ active="#dedede"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#834326"
+ select="#8b5811"
+ active="#bd6a11"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#08310e"
+ select="#1c430b"
+ active="#34622b"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ <ThemeBoneColorSet normal="#000000"
+ select="#000000"
+ active="#000000"
+ show_colored_constraints="FALSE">
+ </ThemeBoneColorSet>
+ </bone_color_sets>
+ </Theme>
+ <ThemeStyle>
+ <panel_title>
+ <ThemeFontStyle points="12"
+ font_kerning_style="FITTED"
+ shadow="1"
+ shadow_offset_x="0"
+ shadow_offset_y="-1"
+ shadow_alpha="0.15"
+ shadow_value="1">
+ </ThemeFontStyle>
+ </panel_title>
+ <widget_label>
+ <ThemeFontStyle points="11"
+ font_kerning_style="FITTED"
+ shadow="3"
+ shadow_offset_x="0"
+ shadow_offset_y="-1"
+ shadow_alpha="0.15"
+ shadow_value="1">
+ </ThemeFontStyle>
+ </widget_label>
+ <widget>
+ <ThemeFontStyle points="11"
+ font_kerning_style="FITTED"
+ shadow="0"
+ shadow_offset_x="0"
+ shadow_offset_y="0"
+ shadow_alpha="0.25"
+ shadow_value="0">
+ </ThemeFontStyle>
+ </widget>
+ </ThemeStyle>
+</bpy>
diff --git a/release/scripts/presets/interface_theme/science_lab.xml b/release/scripts/presets/interface_theme/science_lab.xml
index f591c2f448e..98dddfb0014 100644
--- a/release/scripts/presets/interface_theme/science_lab.xml
+++ b/release/scripts/presets/interface_theme/science_lab.xml
@@ -5,6 +5,7 @@
menu_shadow_width="12"
icon_file=""
icon_alpha="1"
+ widget_emboss="#ffffff05"
axis_x="#dc4800"
axis_y="#73dc00"
axis_z="#00c2ff">
@@ -286,6 +287,7 @@
editmesh_active="#e4ffebab"
normal="#22dddd"
vertex_normal="#2361dd"
+ split_normal="#dd23dd"
bone_solid="#2890e8"
bone_pose="#50c8ff"
bone_pose_active="#8cffff"
@@ -746,6 +748,7 @@
<ThemeNodeEditor node_selected="#6ebdff"
node_active="#fefff3"
wire="#9effc5"
+ wire_inner="#737373"
wire_select="#99d9ff"
selected_text="#7f7070"
node_backdrop="#9b9b9bb9"
@@ -969,7 +972,6 @@
locked_marker="#7f7f7f"
path_before="#ff0000"
path_after="#0000ff"
- grid="#5e5e5e"
frame_current="#60c040"
strips="#0c0a0a"
strips_selected="#ff8c00"
@@ -1125,21 +1127,21 @@
<panel_title>
<ThemeFontStyle points="12"
font_kerning_style="FITTED"
- shadow="4"
+ shadow="1"
shadow_offset_x="0"
- shadow_offset_y="0"
- shadow_alpha="0.3"
- shadow_value="0">
+ shadow_offset_y="-1"
+ shadow_alpha="0.15"
+ shadow_value="1">
</ThemeFontStyle>
</panel_title>
<widget_label>
- <ThemeFontStyle points="12"
+ <ThemeFontStyle points="11"
font_kerning_style="FITTED"
- shadow="4"
+ shadow="3"
shadow_offset_x="0"
- shadow_offset_y="0"
- shadow_alpha="0.5"
- shadow_value="0">
+ shadow_offset_y="-1"
+ shadow_alpha="0.15"
+ shadow_value="1">
</ThemeFontStyle>
</widget_label>
<widget>
@@ -1147,7 +1149,7 @@
font_kerning_style="FITTED"
shadow="0"
shadow_offset_x="0"
- shadow_offset_y="-1"
+ shadow_offset_y="0"
shadow_alpha="0.25"
shadow_value="0">
</ThemeFontStyle>
diff --git a/release/scripts/presets/interface_theme/softimage.xml b/release/scripts/presets/interface_theme/softimage.xml
index b1cbed39150..d58e04619ed 100644
--- a/release/scripts/presets/interface_theme/softimage.xml
+++ b/release/scripts/presets/interface_theme/softimage.xml
@@ -5,6 +5,7 @@
menu_shadow_width="12"
icon_file=""
icon_alpha="1"
+ widget_emboss="#ffffff05"
axis_x="#ff5a5a"
axis_y="#58ff58"
axis_z="#6262ff">
@@ -747,6 +748,7 @@
<ThemeNodeEditor node_selected="#ffffff"
node_active="#ffffff"
wire="#222222"
+ wire_inner="#737373"
wire_select="#ffffff"
selected_text="#ffffff"
node_backdrop="#d4d4d4ff"
@@ -970,7 +972,6 @@
locked_marker="#7f7f7f"
path_before="#22d8d1"
path_after="#5a7575"
- grid="#5e5e5e"
frame_current="#f06868"
strips="#0c0a0a"
strips_selected="#ff8c00"
@@ -1127,9 +1128,9 @@
<ThemeFontStyle points="12"
font_kerning_style="FITTED"
shadow="1"
- shadow_offset_x="1"
+ shadow_offset_x="0"
shadow_offset_y="-1"
- shadow_alpha="0.278"
+ shadow_alpha="0.15"
shadow_value="1">
</ThemeFontStyle>
</panel_title>
diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
index e702e25bc86..b2743f36c02 100644
--- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
+++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
@@ -5,6 +5,7 @@
menu_shadow_width="12"
icon_file=""
icon_alpha="1"
+ widget_emboss="#ffffff05"
axis_x="#dc0000"
axis_y="#00dc00"
axis_z="#0000dc">
@@ -433,18 +434,18 @@
<nla_editor>
<ThemeNLAEditor grid="#5c5c52"
view_sliders="#969696"
- active_action="#00000000"
- active_action_unset="#00000000"
+ active_action="#cc701a66"
+ active_action_unset="#9987614d"
strips="#0c0a0a"
strips_selected="#6b395a"
- transition_strips="#000000"
- transition_strips_selected="#000000"
- meta_strips="#000000"
- meta_strips_selected="#000000"
- sound_strips="#000000"
- sound_strips_selected="#000000"
- tweak="#000000"
- tweak_duplicate="#000000"
+ transition_strips="#1c2630"
+ transition_strips_selected="#2e75db"
+ meta_strips="#332642"
+ meta_strips_selected="#692196"
+ sound_strips="#2b3d3d"
+ sound_strips_selected="#1f7a7a"
+ tweak="#4df31a"
+ tweak_duplicate="#d90000"
keyframe_border="#000000ff"
keyframe_border_selected="#000000ff"
frame_current="#f58032">
@@ -505,7 +506,7 @@
keyframe_jitter_selected="#61c042"
keyframe_border="#000000ff"
keyframe_border_selected="#000000ff"
- summary="#00000000">
+ summary="#cc701a66">
<space>
<ThemeSpaceGeneric back="#131311"
title="#9c9c9c"
@@ -747,6 +748,7 @@
<ThemeNodeEditor node_selected="#ffffff"
node_active="#ffffff"
wire="#f45b00"
+ wire_inner="#737373"
wire_select="#f4b696"
selected_text="#7f7070"
node_backdrop="#52524ed1"
@@ -970,7 +972,6 @@
locked_marker="#7f7f7f"
path_before="#ff5100"
path_after="#19b6ee"
- grid="#302e2c"
frame_current="#f47421"
strips="#0c0a0a"
strips_selected="#ff8c00"
diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py
index 29573e40d70..47a7a7c5f5d 100644
--- a/release/scripts/presets/keyconfig/maya.py
+++ b/release/scripts/presets/keyconfig/maya.py
@@ -142,9 +142,9 @@ kmi = km.keymap_items.new('screen.frame_offset', 'LEFT_ARROW', 'PRESS')
kmi.properties.delta = -1
kmi = km.keymap_items.new('screen.frame_offset', 'RIGHT_ARROW', 'PRESS')
kmi.properties.delta = 1
-kmi = km.keymap_items.new('screen.frame_offset', 'WHEELDOWNMOUSE', 'PRESS', alt=True)
+kmi = km.keymap_items.new('screen.frame_offset', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True, alt=True)
kmi.properties.delta = 1
-kmi = km.keymap_items.new('screen.frame_offset', 'WHEELUPMOUSE', 'PRESS', alt=True)
+kmi = km.keymap_items.new('screen.frame_offset', 'WHEELUPMOUSE', 'PRESS', ctrl=True, alt=True)
kmi.properties.delta = -1
kmi = km.keymap_items.new('screen.frame_jump', 'V', 'PRESS', shift=True, alt=True)
kmi.properties.end = False
@@ -957,6 +957,10 @@ kmi = km.keymap_items.new('view3d.zoom', 'WHEELINMOUSE', 'PRESS')
kmi.properties.delta = 1
kmi = km.keymap_items.new('view3d.zoom', 'WHEELOUTMOUSE', 'PRESS')
kmi.properties.delta = -1
+kmi = km.keymap_items.new('view3d.zoom', 'WHEELINMOUSE', 'PRESS', alt=True)
+kmi.properties.delta = 1
+kmi = km.keymap_items.new('view3d.zoom', 'WHEELOUTMOUSE', 'PRESS', alt=True)
+kmi.properties.delta = -1
kmi = km.keymap_items.new('view3d.view_all', 'A', 'PRESS')
kmi.properties.center = False
kmi = km.keymap_items.new('view3d.viewnumpad', 'ZERO', 'PRESS', ctrl=True)
diff --git a/release/scripts/presets/safe_areas/14_colon_9_in_16_colon_9.py b/release/scripts/presets/safe_areas/14_colon_9_in_16_colon_9.py
new file mode 100644
index 00000000000..e486b413de8
--- /dev/null
+++ b/release/scripts/presets/safe_areas/14_colon_9_in_16_colon_9.py
@@ -0,0 +1,7 @@
+import bpy
+safe_areas = bpy.context.scene.safe_areas
+
+safe_areas.title = (0.035, 0.035)
+safe_areas.action = (0.1, 0.05)
+safe_areas.title_center = (0.15, 0.05)
+safe_areas.action_center = (0.1, 0.05)
diff --git a/release/scripts/presets/safe_areas/16_colon_9.py b/release/scripts/presets/safe_areas/16_colon_9.py
new file mode 100644
index 00000000000..221b8db84bd
--- /dev/null
+++ b/release/scripts/presets/safe_areas/16_colon_9.py
@@ -0,0 +1,7 @@
+import bpy
+safe_areas = bpy.context.scene.safe_areas
+
+safe_areas.title = (0.035, 0.035)
+safe_areas.action = (0.1, 0.05)
+safe_areas.title_center = (0.0, 0.0)
+safe_areas.action_center = (0.0, 0.0)
diff --git a/release/scripts/presets/safe_areas/4_colon_3_in_16_colon_9.py b/release/scripts/presets/safe_areas/4_colon_3_in_16_colon_9.py
new file mode 100644
index 00000000000..c10bc6cf285
--- /dev/null
+++ b/release/scripts/presets/safe_areas/4_colon_3_in_16_colon_9.py
@@ -0,0 +1,7 @@
+import bpy
+safe_areas = bpy.context.scene.safe_areas
+
+safe_areas.title = (0.035, 0.035)
+safe_areas.action = (0.1, 0.05)
+safe_areas.title_center = (0.175, 0.05)
+safe_areas.action_center = (0.15, 0.05)
diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py
index e44fce63acd..65f7bde1809 100644
--- a/release/scripts/startup/bl_operators/__init__.py
+++ b/release/scripts/startup/bl_operators/__init__.py
@@ -19,9 +19,10 @@
# <pep8 compliant>
if "bpy" in locals():
- from imp import reload as _reload
+ from importlib import reload
for val in _modules_loaded.values():
- _reload(val)
+ reload(val)
+ del reload
_modules = [
"add_mesh_torus",
"anim",
diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py
index 449a4cef1ef..dfb734e9b5b 100644
--- a/release/scripts/startup/bl_operators/add_mesh_torus.py
+++ b/release/scripts/startup/bl_operators/add_mesh_torus.py
@@ -20,9 +20,10 @@
import bpy
from bpy.types import Operator
-from bpy.props import (FloatProperty,
- IntProperty,
- )
+from bpy.props import (
+ FloatProperty,
+ IntProperty,
+ )
from bpy.app.translations import pgettext_data as data_
from bpy_extras import object_utils
diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py
index 756b75b8d03..1b3e719b2bd 100644
--- a/release/scripts/startup/bl_operators/anim.py
+++ b/release/scripts/startup/bl_operators/anim.py
@@ -19,18 +19,20 @@
# <pep8-80 compliant>
if "bpy" in locals():
- import imp
+ from importlib import reload
if "anim_utils" in locals():
- imp.reload(anim_utils)
+ reload(anim_utils)
+ del reload
import bpy
from bpy.types import Operator
-from bpy.props import (IntProperty,
- BoolProperty,
- EnumProperty,
- StringProperty,
- )
+from bpy.props import (
+ IntProperty,
+ BoolProperty,
+ EnumProperty,
+ StringProperty,
+ )
class ANIM_OT_keying_set_export(Operator):
@@ -83,7 +85,9 @@ class ANIM_OT_keying_set_export(Operator):
f.write("ks.is_path_absolute = False\n")
f.write("\n")
- f.write("ks.bl_options = %r\n" % ks.bl_options)
+ f.write("ks.use_insertkey_needed = %s\n" % ks.use_insertkey_needed)
+ f.write("ks.use_insertkey_visual = %s\n" % ks.use_insertkey_visual)
+ f.write("ks.use_insertkey_xyz_to_rgb = %s\n" % ks.use_insertkey_xyz_to_rgb)
f.write("\n")
# --------------------------------------------------------
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py
index 4ce300ecce2..7e4e0ea9246 100644
--- a/release/scripts/startup/bl_operators/clip.py
+++ b/release/scripts/startup/bl_operators/clip.py
@@ -20,7 +20,7 @@
import bpy
import os
from bpy.types import Operator
-
+from bpy.props import FloatProperty
from mathutils import Vector, Matrix
@@ -124,6 +124,100 @@ def CLIP_default_settings_from_track(clip, track, framenr):
settings.default_weight = track.weight
+class CLIP_OT_filter_tracks(bpy.types.Operator):
+ """Filter tracks which has weirdly looking spikes in motion curves"""
+ bl_label = "Filter Tracks"
+ bl_idname = "clip.filter_tracks"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ track_threshold = FloatProperty(
+ name="Track Threshold",
+ description="Filter Threshold to select problematic tracks",
+ default=5.0,
+ )
+
+ @staticmethod
+ def _filter_values(context, threshold):
+
+ def get_marker_coordinates_in_pixels(clip_size, track, frame_number):
+ marker = track.markers.find_frame(frame_number)
+ return Vector((marker.co[0] * clip_size[0], marker.co[1] * clip_size[1]))
+
+ def marker_velocity(clip_size, track, frame):
+ marker_a = get_marker_coordinates_in_pixels(clip_size, track, frame)
+ marker_b = get_marker_coordinates_in_pixels(clip_size, track, frame - 1)
+ return marker_a - marker_b
+
+ scene = context.scene
+ frame_start = scene.frame_start
+ frame_end = scene.frame_end
+ clip = context.space_data.clip
+ clip_size = clip.size[:]
+
+ bpy.ops.clip.clean_tracks(frames=10, action='DELETE_TRACK')
+
+ tracks_to_clean = set()
+
+ for frame in range(frame_start, frame_end + 1):
+
+ # Find tracks with markers in both this frame and the previous one.
+ relevant_tracks = [
+ track for track in clip.tracking.tracks
+ if (track.markers.find_frame(frame) and
+ track.markers.find_frame(frame - 1))]
+
+ if not relevant_tracks:
+ continue
+
+ # Get average velocity and deselect track.
+ average_velocity = Vector((0.0, 0.0))
+ for track in relevant_tracks:
+ track.select = False
+ average_velocity += marker_velocity(clip_size, track, frame)
+ if len(relevant_tracks) >= 1:
+ average_velocity = average_velocity / len(relevant_tracks)
+
+ # Then find all markers that behave differently than the average.
+ for track in relevant_tracks:
+ track_velocity = marker_velocity(clip_size, track, frame)
+ distance = (average_velocity - track_velocity).length
+
+ if distance > threshold:
+ tracks_to_clean.add(track)
+
+ for track in tracks_to_clean:
+ track.select = True
+ return len(tracks_to_clean)
+
+ @classmethod
+ def poll(cls, context):
+ space = context.space_data
+ return (space.type == 'CLIP_EDITOR') and space.clip
+
+ def execute(self, context):
+ num_tracks = self._filter_values(context, self.track_threshold)
+ self.report({'INFO'}, "Identified %d problematic tracks" % num_tracks)
+ return {'FINISHED'}
+
+
+class CLIP_OT_set_active_clip(bpy.types.Operator):
+ bl_label = "Set Active Clip"
+ bl_idname = "clip.set_active_clip"
+
+ @classmethod
+ def poll(cls, context):
+ space = context.space_data
+ return space.type == 'CLIP_EDITOR'
+
+ def execute(self, context):
+ clip = context.space_data.clip
+ scene = context.scene
+ scene.active_clip = clip
+ scene.render.resolution_x = clip.size[0]
+ scene.render.resolution_y = clip.size[1]
+ return {'FINISHED'}
+
+
class CLIP_OT_track_to_empty(Operator):
"""Create an Empty object which will be copying movement of active track"""
@@ -920,3 +1014,58 @@ class CLIP_OT_track_settings_as_default(Operator):
CLIP_default_settings_from_track(clip, track, framenr)
return {'FINISHED'}
+
+
+class CLIP_OT_track_settings_to_track(bpy.types.Operator):
+ """Copy tracking settings from active track to selected tracks"""
+
+ bl_label = "Copy Track Settings"
+ bl_idname = "clip.track_settings_to_track"
+ bl_options = {'UNDO', 'REGISTER'}
+
+ _attrs_track = (
+ "correlation_min",
+ "frames_limit",
+ "pattern_match",
+ "margin",
+ "motion_model",
+ "use_brute",
+ "use_normalization",
+ "use_mask",
+ "use_red_channel",
+ "use_green_channel",
+ "use_blue_channel",
+ "weight"
+ )
+
+ _attrs_marker = (
+ "pattern_corners",
+ "search_min",
+ "search_max",
+ )
+
+ @classmethod
+ def poll(cls, context):
+ space = context.space_data
+ if space.type != 'CLIP_EDITOR':
+ return False
+ clip = space.clip
+ return clip and clip.tracking.tracks.active
+
+ def execute(self, context):
+ space = context.space_data
+ clip = space.clip
+ track = clip.tracking.tracks.active
+
+ framenr = context.scene.frame_current - clip.frame_start + 1
+ marker = track.markers.find_frame(framenr, False)
+
+ for t in clip.tracking.tracks:
+ if t.select and t != track:
+ marker_selected = t.markers.find_frame(framenr, False)
+ for attr in self._attrs_track:
+ setattr(t, attr, getattr(track, attr))
+ for attr in self._attrs_marker:
+ setattr(marker_selected, attr, getattr(marker, attr))
+
+ return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/console.py b/release/scripts/startup/bl_operators/console.py
index 4e99acd4f36..8cfc977294a 100644
--- a/release/scripts/startup/bl_operators/console.py
+++ b/release/scripts/startup/bl_operators/console.py
@@ -20,9 +20,10 @@
import bpy
from bpy.types import Operator
-from bpy.props import (BoolProperty,
- StringProperty,
- )
+from bpy.props import (
+ BoolProperty,
+ StringProperty,
+ )
def _lang_module_get(sc):
diff --git a/release/scripts/startup/bl_operators/freestyle.py b/release/scripts/startup/bl_operators/freestyle.py
index 453be519abf..edda92284d2 100644
--- a/release/scripts/startup/bl_operators/freestyle.py
+++ b/release/scripts/startup/bl_operators/freestyle.py
@@ -16,10 +16,13 @@
#
# ##### END GPL LICENSE BLOCK #####
-import sys
import bpy
-from bpy.props import (BoolProperty, EnumProperty, StringProperty)
+from bpy.props import (
+ BoolProperty,
+ EnumProperty,
+ StringProperty,
+ )
class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator):
@@ -29,11 +32,16 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator):
bl_label = "Fill Range by Selection"
bl_options = {'INTERNAL'}
- type = EnumProperty(name="Type", description="Type of the modifier to work on",
- items=(("COLOR", "Color", "Color modifier type"),
- ("ALPHA", "Alpha", "Alpha modifier type"),
- ("THICKNESS", "Thickness", "Thickness modifier type")))
- name = StringProperty(name="Name", description="Name of the modifier to work on")
+ type = EnumProperty(
+ name="Type", description="Type of the modifier to work on",
+ items=(("COLOR", "Color", "Color modifier type"),
+ ("ALPHA", "Alpha", "Alpha modifier type"),
+ ("THICKNESS", "Thickness", "Thickness modifier type")),
+ )
+ name = StringProperty(
+ name="Name",
+ description="Name of the modifier to work on",
+ )
@classmethod
def poll(cls, context):
@@ -41,6 +49,8 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator):
return rl and rl.freestyle_settings.linesets.active
def execute(self, context):
+ import sys
+
scene = context.scene
rl = scene.render.layers.active
lineset = rl.freestyle_settings.linesets.active
diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py
index 9bdd9289700..e8b1ed248a3 100644
--- a/release/scripts/startup/bl_operators/node.py
+++ b/release/scripts/startup/bl_operators/node.py
@@ -20,15 +20,17 @@
import bpy
import nodeitems_utils
-from bpy.types import (Operator,
- PropertyGroup,
- )
-from bpy.props import (BoolProperty,
- CollectionProperty,
- EnumProperty,
- IntProperty,
- StringProperty,
- )
+from bpy.types import (
+ Operator,
+ PropertyGroup,
+ )
+from bpy.props import (
+ BoolProperty,
+ CollectionProperty,
+ EnumProperty,
+ IntProperty,
+ StringProperty,
+ )
class NodeSetting(PropertyGroup):
@@ -40,7 +42,7 @@ class NodeSetting(PropertyGroup):
# Base class for node 'Add' operators
-class NodeAddOperator():
+class NodeAddOperator:
type = StringProperty(
name="Node Type",
@@ -122,7 +124,7 @@ class NodeAddOperator():
result = self.execute(context)
if self.use_transform and ('FINISHED' in result):
- # removes the node again if transform is cancelled
+ # removes the node again if transform is canceled
bpy.ops.transform.translate('INVOKE_DEFAULT', remove_on_cancel=True)
return result
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index c1f75c74bb4..e3ceeca8abe 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -20,11 +20,13 @@
import bpy
from bpy.types import Operator
-from bpy.props import (StringProperty,
- BoolProperty,
- EnumProperty,
- IntProperty,
- FloatProperty)
+from bpy.props import (
+ StringProperty,
+ BoolProperty,
+ EnumProperty,
+ IntProperty,
+ FloatProperty,
+ )
class SelectPattern(Operator):
@@ -250,7 +252,7 @@ class SubdivisionSet(Operator):
if not relative:
if level > mod.total_levels:
sub = level - mod.total_levels
- for i in range (0, sub):
+ for i in range(sub):
bpy.ops.object.multires_subdivide(modifier="Multires")
if obj.mode == 'SCULPT':
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index 06dc82d2b77..414855c7e35 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -21,12 +21,13 @@
from mathutils import Vector
import bpy
from bpy.types import Operator
-from bpy.props import (BoolProperty,
- EnumProperty,
- IntProperty,
- FloatProperty,
- FloatVectorProperty,
- )
+from bpy.props import (
+ BoolProperty,
+ EnumProperty,
+ IntProperty,
+ FloatProperty,
+ FloatVectorProperty,
+ )
def object_ensure_material(obj, mat_name):
@@ -74,7 +75,7 @@ class QuickFur(Operator):
def execute(self, context):
fake_context = context.copy()
mesh_objects = [obj for obj in context.selected_objects
- if obj.type == 'MESH']
+ if obj.type == 'MESH' and obj.mode == 'OBJECT']
if not mesh_objects:
self.report({'ERROR'}, "Select at least one mesh object")
@@ -387,7 +388,7 @@ class QuickSmoke(Operator):
links.new(node_add_shader_1.outputs["Shader"],
node_out.inputs["Volume"])
- if self.style in {'SMOKE', 'BOTH'}:
+ if self.style in {'SMOKE', 'FIRE', 'BOTH'}:
# Smoke
# Add shader 2
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index f89792bea6e..7195b7819d1 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -23,7 +23,7 @@ from bpy.types import Menu, Operator
from bpy.props import StringProperty, BoolProperty
-class AddPresetBase():
+class AddPresetBase:
"""Base preset class, only for subclassing
subclasses must define
- preset_values
@@ -277,6 +277,26 @@ class AddPresetCamera(AddPresetBase, Operator):
return preset_values
+class AddPresetSafeAreas(AddPresetBase, Operator):
+ """Add or remove a Safe Areas Preset"""
+ bl_idname = "safe_areas.preset_add"
+ bl_label = "Add Safe Area Preset"
+ preset_menu = "SAFE_AREAS_MT_presets"
+
+ preset_defines = [
+ "safe_areas = bpy.context.scene.safe_areas"
+ ]
+
+ preset_values = [
+ "safe_areas.title",
+ "safe_areas.action",
+ "safe_areas.title_center",
+ "safe_areas.action_center",
+ ]
+
+ preset_subdir = "safe_areas"
+
+
class AddPresetSSS(AddPresetBase, Operator):
"""Add or remove a Subsurface Scattering Preset"""
bl_idname = "material.sss_preset_add"
@@ -345,6 +365,36 @@ class AddPresetFluid(AddPresetBase, Operator):
preset_subdir = "fluid"
+class AddPresetHairDynamics(AddPresetBase, Operator):
+ """Add or remove a Hair Dynamics Preset"""
+ bl_idname = "particle.hair_dynamics_preset_add"
+ bl_label = "Add Hair Dynamics Preset"
+ preset_menu = "PARTICLE_MT_hair_dynamics_presets"
+
+ preset_defines = [
+ "psys = bpy.context.particle_system",
+ "cloth = bpy.context.particle_system.cloth",
+ "settings = bpy.context.particle_system.cloth.settings",
+ "collision = bpy.context.particle_system.cloth.collision_settings",
+ ]
+
+ preset_subdir = "hair_dynamics"
+
+ preset_values = [
+ "settings.quality",
+ "settings.mass",
+ "settings.bending_stiffness",
+ "psys.settings.bending_random",
+ "settings.bending_damping",
+ "settings.air_damping",
+ "settings.internal_friction",
+ "settings.density_target",
+ "settings.density_strength",
+ "settings.voxel_cell_size",
+ "settings.pin_stiffness",
+ ]
+
+
class AddPresetSunSky(AddPresetBase, Operator):
"""Add or remove a Sky & Atmosphere Preset"""
bl_idname = "lamp.sunsky_preset_add"
diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py
index 9a3aae53ceb..237c2d55672 100644
--- a/release/scripts/startup/bl_operators/rigidbody.py
+++ b/release/scripts/startup/bl_operators/rigidbody.py
@@ -64,17 +64,19 @@ class CopyRigidbodySettings(Operator):
for o in context.selected_objects:
if o.type != 'MESH':
o.select = False
+ elif o.rigid_body is None:
+ # Add rigidbody to object!
+ scene.objects.active = o
+ bpy.ops.rigidbody.object_add()
+ scene.objects.active = obj_act
objects = context.selected_objects
if objects:
- # add selected objects to active one groups and recalculate
- bpy.ops.group.objects_add_active()
- scene.frame_set(scene.frame_current)
rb_from = obj_act.rigid_body
# copy settings
for o in objects:
rb_to = o.rigid_body
- if (o == obj_act) or (rb_to is None):
+ if o == obj_act:
continue
for attr in self._attrs:
setattr(rb_to, attr, getattr(rb_from, attr))
diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
index 8f618e0632e..a120e2b2461 100644
--- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py
+++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
@@ -23,7 +23,7 @@ from bpy.types import Operator
import mathutils
-class prettyface(object):
+class prettyface:
__slots__ = (
"uv",
"width",
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index aa8a1742c1e..73e6bcd9b0c 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -670,7 +670,7 @@ def VectoQuat(vec):
return vec.to_track_quat('Z', 'X' if abs(vec.x) > 0.5 else 'Y').inverted()
-class thickface(object):
+class thickface:
__slost__= "v", "uv", "no", "area", "edge_keys"
def __init__(self, face, uv_layer, mesh_verts):
self.v = [mesh_verts[i] for i in face.vertices]
@@ -708,6 +708,7 @@ def main(context,
island_margin,
projection_limit,
user_area_weight,
+ use_aspect
):
global USER_FILL_HOLES
global USER_FILL_HOLES_QUALITY
@@ -720,7 +721,6 @@ def main(context,
global dict_matrix
dict_matrix = {}
-
# Constants:
# Takes a list of faces that make up a UV island and rotate
# until they optimally fit inside a square.
@@ -992,9 +992,31 @@ def main(context,
print("Smart Projection time: %.2f" % (time.time() - time1))
# Window.DrawProgressBar(0.9, "Smart Projections done, time: %.2f sec" % (time.time() - time1))
+ # aspect correction is only done in edit mode - and only smart unwrap supports currently
if is_editmode:
bpy.ops.object.mode_set(mode='EDIT')
+ if use_aspect:
+ import bmesh
+ aspect = context.scene.uvedit_aspect(context.active_object)
+ if aspect[0] > aspect[1]:
+ aspect[0] = aspect[1]/aspect[0];
+ aspect[1] = 1.0
+ else:
+ aspect[1] = aspect[0]/aspect[1];
+ aspect[0] = 1.0
+
+ bm = bmesh.from_edit_mesh(me)
+
+ uv_act = bm.loops.layers.uv.active
+
+ faces = [f for f in bm.faces if f.select]
+
+ for f in faces:
+ for l in f.loops:
+ l[uv_act].uv[0] *= aspect[0]
+ l[uv_act].uv[1] *= aspect[1]
+
dict_matrix.clear()
#XXX Window.DrawProgressBar(1.0, "")
@@ -1017,7 +1039,7 @@ def main(context,
]
"""
-from bpy.props import FloatProperty
+from bpy.props import FloatProperty, BoolProperty
class SmartProject(Operator):
@@ -1046,6 +1068,11 @@ class SmartProject(Operator):
min=0.0, max=1.0,
default=0.0,
)
+ use_aspect = BoolProperty(
+ name="Correct Aspect",
+ description="Map UVs taking image aspect ratio into account",
+ default=True
+ )
@classmethod
def poll(cls, context):
@@ -1056,6 +1083,7 @@ class SmartProject(Operator):
self.island_margin,
self.angle_limit,
self.user_area_weight,
+ self.use_aspect
)
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/vertexpaint_dirt.py b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
index ecb1ecf7f47..892e1822d68 100644
--- a/release/scripts/startup/bl_operators/vertexpaint_dirt.py
+++ b/release/scripts/startup/bl_operators/vertexpaint_dirt.py
@@ -27,11 +27,9 @@
def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, dirt_only):
from mathutils import Vector
from math import acos
+ import array
- vert_tone = [0.0] * len(me.vertices)
-
- min_tone = 180.0
- max_tone = 0.0
+ vert_tone = array.array("f", [0.0]) * len(me.vertices)
# create lookup table for each vertex's connected vertices (via edges)
con = []
@@ -74,7 +72,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
# blur tones
for i in range(blur_iterations):
# backup the original tones
- orig_vert_tone = list(vert_tone)
+ orig_vert_tone = vert_tone[:]
# use connected verts look up for blurring
for j, c in enumerate(con):
@@ -82,20 +80,18 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
vert_tone[j] += blur_strength * orig_vert_tone[v]
vert_tone[j] /= len(c) * blur_strength + 1
+ del orig_vert_tone
min_tone = min(vert_tone)
max_tone = max(vert_tone)
- # debug information
- # print(min_tone * 2 * math.pi)
- # print(max_tone * 2 * math.pi)
- # print(clamp_clean)
- # print(clamp_dirt)
-
tone_range = max_tone - min_tone
- if not tone_range:
- return {'CANCELLED'}
+ if tone_range < 0.0001:
+ # weak, don't cancel, see T43345
+ tone_range = 0.0
+ else:
+ tone_range = 1.0 / tone_range
active_col_layer = None
@@ -112,7 +108,6 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
return {'CANCELLED'}
use_paint_mask = me.use_paint_mask
-
for i, p in enumerate(me.polygons):
if not use_paint_mask or p.select:
for loop_index in p.loop_indices:
@@ -120,11 +115,10 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
v = loop.vertex_index
col = active_col_layer[loop_index].color
tone = vert_tone[v]
- tone = (tone - min_tone) / tone_range
+ tone = (tone - min_tone) * tone_range
if dirt_only:
- tone = min(tone, 0.5)
- tone *= 2.0
+ tone = min(tone, 0.5) * 2.0
col[0] = tone * col[0]
col[1] = tone * col[1]
@@ -182,15 +176,9 @@ class VertexPaintDirt(Operator):
return (obj and obj.type == 'MESH')
def execute(self, context):
- import time
-
obj = context.object
mesh = obj.data
- t = time.time()
-
ret = applyVertexDirt(mesh, self.blur_iterations, self.blur_strength, self.dirt_angle, self.clean_angle, self.dirt_only)
- print('Dirt calculated in %.6f' % (time.time() - t))
-
return ret
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 8d04cb132e6..a48415caa9b 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -20,12 +20,13 @@
import bpy
from bpy.types import Operator
-from bpy.props import (StringProperty,
- BoolProperty,
- IntProperty,
- FloatProperty,
- EnumProperty,
- )
+from bpy.props import (
+ StringProperty,
+ BoolProperty,
+ IntProperty,
+ FloatProperty,
+ EnumProperty,
+ )
from bpy.app.translations import pgettext_tip as tip_
@@ -1737,7 +1738,7 @@ class WM_OT_addon_enable(Operator):
err_str = traceback.format_exc()
print(err_str)
- mod = addon_utils.enable(self.module, handle_error=err_cb)
+ mod = addon_utils.enable(self.module, default_set=True, handle_error=err_cb)
if mod:
info = addon_utils.module_bl_info(mod)
@@ -1987,7 +1988,6 @@ class WM_OT_addon_install(Operator):
# if not compressed file just copy into the addon path
try:
shutil.copyfile(pyfile, path_dest)
-
except:
traceback.print_exc()
return {'CANCELLED'}
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index 6b72ef12dcc..51117f68558 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -21,9 +21,10 @@
# note, properties_animviz is a helper module only.
if "bpy" in locals():
- from imp import reload as _reload
+ from importlib import reload
for val in _modules_loaded.values():
- _reload(val)
+ reload(val)
+ del reload
_modules = [
"properties_animviz",
"properties_constraint",
@@ -99,10 +100,10 @@ def register():
def addon_filter_items(self, context):
import addon_utils
- items = [('All', "All", "All Addons"),
- ('User', "User", "All Addons Installed by User"),
- ('Enabled', "Enabled", "All Enabled Addons"),
- ('Disabled', "Disabled", "All Disabled Addons"),
+ items = [('All', "All", "All Add-ons"),
+ ('User', "User", "All Add-ons Installed by User"),
+ ('Enabled', "Enabled", "All Enabled Add-ons"),
+ ('Disabled', "Disabled", "All Disabled Add-ons"),
]
items_unique = set()
@@ -117,6 +118,7 @@ def register():
WindowManager.addon_search = StringProperty(
name="Search",
description="Search within the selected filter",
+ options={'TEXTEDIT_UPDATE'},
)
WindowManager.addon_filter = EnumProperty(
items=addon_filter_items,
diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py
index 8308c7fc425..11081232f12 100644
--- a/release/scripts/startup/bl_ui/properties_animviz.py
+++ b/release/scripts/startup/bl_ui/properties_animviz.py
@@ -25,7 +25,7 @@
# don't register these classes since they are only helpers.
-class MotionPathButtonsPanel():
+class MotionPathButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_label = "Motion Paths"
@@ -97,7 +97,7 @@ class MotionPathButtonsPanel():
# FIXME: this panel still needs to be ported so that it will work correctly with animviz
-class OnionSkinButtonsPanel():
+class OnionSkinButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_label = "Onion Skinning"
diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index e6b62cae6ef..9aa67223fc4 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -21,7 +21,7 @@ import bpy
from bpy.types import Panel
-class ConstraintButtonsPanel():
+class ConstraintButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "constraint"
@@ -768,9 +768,27 @@ class ConstraintButtonsPanel():
col = layout.column()
col.label(text="Chain Scaling:")
col.prop(con, "use_y_stretch")
- col.prop(con, "xz_scale_mode")
col.prop(con, "use_curve_radius")
+ layout.prop(con, "xz_scale_mode")
+
+ if con.xz_scale_mode == 'VOLUME_PRESERVE':
+ layout.prop(con, "bulge", text="Volume Variation")
+ split = layout.split()
+ col = split.column(align=True)
+ col.prop(con, "use_bulge_min", text="Volume Min")
+ sub = col.column()
+ sub.active = con.use_bulge_min
+ sub.prop(con, "bulge_min", text="")
+ col = split.column(align=True)
+ col.prop(con, "use_bulge_max", text="Volume Max")
+ sub = col.column()
+ sub.active = con.use_bulge_max
+ sub.prop(con, "bulge_max", text="")
+ col = layout.column()
+ col.active = con.use_bulge_min or con.use_bulge_max
+ col.prop(con, "bulge_smooth", text="Smooth")
+
def PIVOT(self, context, layout, con):
self.target_template(layout, con)
diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py
index 6a8f9c586ed..84e06d4c7fc 100644
--- a/release/scripts/startup/bl_ui/properties_data_armature.py
+++ b/release/scripts/startup/bl_ui/properties_data_armature.py
@@ -22,7 +22,7 @@ from bpy.types import Panel, Menu
from rna_prop_ui import PropertyPanel
-class ArmatureButtonsPanel():
+class ArmatureButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@@ -144,7 +144,7 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
if group.color_set:
col = split.column()
sub = col.row(align=True)
- sub.enabled = group.is_custom_color_set # only custom colors are editable
+ sub.enabled = group.is_custom_color_set # only custom colors are editable
sub.prop(group.colors, "normal", text="")
sub.prop(group.colors, "select", text="")
sub.prop(group.colors, "active", text="")
@@ -278,9 +278,10 @@ class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel):
row.prop(itasc, "damping_max", text="Damp", slider=True)
row.prop(itasc, "damping_epsilon", text="Eps", slider=True)
-from bl_ui.properties_animviz import (MotionPathButtonsPanel,
- OnionSkinButtonsPanel,
- )
+from bl_ui.properties_animviz import (
+ MotionPathButtonsPanel,
+ OnionSkinButtonsPanel,
+ )
class DATA_PT_motion_paths(MotionPathButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index c07e9d677e7..a14e34580c5 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -23,7 +23,7 @@ from bpy.types import Panel
from rna_prop_ui import PropertyPanel
-class BoneButtonsPanel():
+class BoneButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "bone"
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index 0600c87244b..106e31ea89a 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -22,7 +22,7 @@ from bpy.types import Panel, Menu
from rna_prop_ui import PropertyPanel
-class CameraButtonsPanel():
+class CameraButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@@ -41,6 +41,14 @@ class CAMERA_MT_presets(Menu):
draw = Menu.draw_preset
+class SAFE_AREAS_MT_presets(Menu):
+ bl_label = "Camera Presets"
+ preset_subdir = "safe_areas"
+ preset_operator = "script.execute_preset"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ draw = Menu.draw_preset
+
+
class DATA_PT_context_camera(CameraButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
@@ -98,6 +106,14 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
row = layout.row()
row.prop(ccam, "fisheye_lens", text="Lens")
row.prop(ccam, "fisheye_fov")
+ elif ccam.panorama_type == 'EQUIRECTANGULAR':
+ row = layout.row()
+ sub = row.column(align=True)
+ sub.prop(ccam, "latitude_min")
+ sub.prop(ccam, "latitude_max")
+ sub = row.column(align=True)
+ sub.prop(ccam, "longitude_min")
+ sub.prop(ccam, "longitude_max")
elif engine == 'BLENDER_RENDER':
row = col.row()
if cam.lens_unit == 'MILLIMETERS':
@@ -161,16 +177,19 @@ class DATA_PT_camera_dof(CameraButtonsPanel, Panel):
layout = self.layout
cam = context.camera
-
- layout.label(text="Focus:")
+ dof_options = cam.gpu_dof
split = layout.split()
- split.prop(cam, "dof_object", text="")
col = split.column()
+ col.label(text="Focus:")
+ col.prop(cam, "dof_object", text="")
- col.active = cam.dof_object is None
- col.prop(cam, "dof_distance", text="Distance")
+ col = split.column()
+ col.prop(dof_options, "fstop")
+ sub = col.column()
+ sub.active = cam.dof_object is None
+ sub.prop(cam, "dof_distance", text="Distance")
class DATA_PT_camera_display(CameraButtonsPanel, Panel):
@@ -187,7 +206,7 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel):
col = split.column()
col.prop(cam, "show_limits", text="Limits")
col.prop(cam, "show_mist", text="Mist")
- col.prop(cam, "show_title_safe", text="Safe Areas")
+
col.prop(cam, "show_sensor", text="Sensor")
col.prop(cam, "show_name", text="Name")
@@ -202,10 +221,56 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel):
sub.prop(cam, "passepartout_alpha", text="Alpha", slider=True)
+class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel):
+ bl_label = "Safe Areas"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+ def draw_header(self, context):
+ cam = context.camera
+
+ self.layout.prop(cam, "show_safe_areas", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ safe_data = context.scene.safe_areas
+ camera = context.camera
+
+ draw_display_safe_settings(layout, safe_data, camera)
+
+
class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
_context_path = "object.data"
_property_type = bpy.types.Camera
+
+def draw_display_safe_settings(layout, safe_data, settings):
+ show_safe_areas = settings.show_safe_areas
+ show_safe_center = settings.show_safe_center
+
+ split = layout.split()
+
+ col = split.column()
+ row = col.row(align=True)
+ row.menu("SAFE_AREAS_MT_presets", text=bpy.types.SAFE_AREAS_MT_presets.bl_label)
+ row.operator("safe_areas.preset_add", text="", icon='ZOOMIN')
+ row.operator("safe_areas.preset_add", text="", icon='ZOOMOUT').remove_active = True
+
+ col = split.column()
+ col.prop(settings, "show_safe_center", text="Center-Cut Safe Areas")
+
+ split = layout.split()
+ col = split.column()
+ col.active = show_safe_areas
+ col.prop(safe_data, "title", slider=True)
+ col.prop(safe_data, "action", slider=True)
+
+ col = split.column()
+ col.active = show_safe_areas and show_safe_center
+ col.prop(safe_data, "title_center", slider=True)
+ col.prop(safe_data, "action_center", slider=True)
+
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index 7cfdcccfb94..9277bbe20f9 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -24,7 +24,7 @@ from rna_prop_ui import PropertyPanel
from bpy.types import Curve, SurfaceCurve, TextCurve
-class CurveButtonsPanel():
+class CurveButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py
index c93bebf2673..a752d3517de 100644
--- a/release/scripts/startup/bl_ui/properties_data_empty.py
+++ b/release/scripts/startup/bl_ui/properties_data_empty.py
@@ -21,7 +21,7 @@ import bpy
from bpy.types import Panel
-class DataButtonsPanel():
+class DataButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py
index 3aa0b71ae04..6fef30fa3e6 100644
--- a/release/scripts/startup/bl_ui/properties_data_lamp.py
+++ b/release/scripts/startup/bl_ui/properties_data_lamp.py
@@ -30,7 +30,7 @@ class LAMP_MT_sunsky_presets(Menu):
draw = Menu.draw_preset
-class DataButtonsPanel():
+class DataButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
diff --git a/release/scripts/startup/bl_ui/properties_data_lattice.py b/release/scripts/startup/bl_ui/properties_data_lattice.py
index 14d6ea66894..cbfa6961e8c 100644
--- a/release/scripts/startup/bl_ui/properties_data_lattice.py
+++ b/release/scripts/startup/bl_ui/properties_data_lattice.py
@@ -22,7 +22,7 @@ from bpy.types import Panel
from rna_prop_ui import PropertyPanel
-class DataButtonsPanel():
+class DataButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 5a59a238d19..8efd14afb47 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -29,7 +29,7 @@ class MESH_MT_vertex_group_specials(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("object.vertex_group_sort", icon='SORTALPHA').sort_type = "NAME"
+ layout.operator("object.vertex_group_sort", icon='SORTALPHA', text="Sort by Name").sort_type = "NAME"
layout.operator("object.vertex_group_sort", icon='ARMATURE_DATA', text="Sort by Bone Hierarchy").sort_type = "BONE_HIERARCHY"
layout.operator("object.vertex_group_copy", icon='COPY_ID')
layout.operator("object.vertex_group_copy_to_linked", icon='LINK_AREA')
@@ -111,7 +111,7 @@ class MESH_UL_uvmaps_vcols(UIList):
layout.label(text="", icon_value=icon)
-class MeshButtonsPanel():
+class MeshButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@@ -154,7 +154,7 @@ class DATA_PT_normals(MeshButtonsPanel, Panel):
col = split.column()
col.prop(mesh, "use_auto_smooth")
sub = col.column()
- sub.active = mesh.use_auto_smooth
+ sub.active = mesh.use_auto_smooth and not mesh.has_custom_normals
sub.prop(mesh, "auto_smooth_angle", text="Angle")
split.prop(mesh, "show_double_sided")
@@ -317,7 +317,6 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
row = layout.column()
row.active = enable_edit_value
row.prop(key, "eval_time")
- row.prop(key, "slurph")
class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
@@ -373,6 +372,11 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
col.operator("mesh.customdata_clear_mask", icon='X')
col.operator("mesh.customdata_clear_skin", icon='X')
+ if me.has_custom_normals:
+ col.operator("mesh.customdata_custom_splitnormals_clear", icon='X')
+ else:
+ col.operator("mesh.customdata_custom_splitnormals_add", icon='ZOOMIN')
+
col = layout.column()
col.enabled = (obj.mode != 'EDIT')
diff --git a/release/scripts/startup/bl_ui/properties_data_metaball.py b/release/scripts/startup/bl_ui/properties_data_metaball.py
index cd894e60dbb..b42258c386a 100644
--- a/release/scripts/startup/bl_ui/properties_data_metaball.py
+++ b/release/scripts/startup/bl_ui/properties_data_metaball.py
@@ -22,7 +22,7 @@ from bpy.types import Panel
from rna_prop_ui import PropertyPanel
-class DataButtonsPanel():
+class DataButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index efc430db50f..ec60f1caec8 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -22,7 +22,7 @@ from bpy.types import Panel
from bpy.app.translations import pgettext_iface as iface_
-class ModifierButtonsPanel():
+class ModifierButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "modifier"
@@ -352,6 +352,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.label(text="Settings are inside the Physics tab")
def HOOK(self, layout, ob, md):
+ use_falloff = (md.falloff_type != 'NONE')
split = layout.split()
col = split.column()
@@ -366,19 +367,28 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.separator()
- split = layout.split()
+ row = layout.row(align=True)
+ if use_falloff:
+ row.prop(md, "falloff_radius")
+ row.prop(md, "strength", slider=True)
+ layout.prop(md, "falloff_type")
- col = split.column()
- col.prop(md, "falloff")
- col.prop(md, "force", slider=True)
+ col = layout.column()
+ if use_falloff:
+ if md.falloff_type == 'CURVE':
+ col.template_curve_mapping(md, "falloff_curve")
+
+ split = layout.split()
col = split.column()
- col.operator("object.hook_reset", text="Reset")
- col.operator("object.hook_recenter", text="Recenter")
+ col.prop(md, "use_falloff_uniform")
if ob.mode == 'EDIT':
- layout.separator()
- row = layout.row()
+ row = col.row(align=True)
+ row.operator("object.hook_reset", text="Reset")
+ row.operator("object.hook_recenter", text="Recenter")
+
+ row = layout.row(align=True)
row.operator("object.hook_select", text="Select")
row.operator("object.hook_assign", text="Assign")
@@ -448,7 +458,11 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
if md.mode == 'ARMATURE':
col.label(text="Armature:")
- col.prop(md, "armature", text="")
+ row = col.row(align=True)
+ row.prop(md, "armature", text="")
+ sub = row.row(align=True)
+ sub.active = (md.armature is not None)
+ sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
elif md.mode == 'VERTEX_GROUP':
col.label(text="Vertex Group:")
row = col.row(align=True)
@@ -962,7 +976,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.template_ID(md, "texture", new="texture.new")
layout.prop(md, "texture_coords")
- if md.texture_coords == 'MAP_UV' and ob.type == 'MESH':
+ if md.texture_coords == 'UV' and ob.type == 'MESH':
layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
elif md.texture_coords == 'OBJECT':
layout.prop(md, "texture_coords_object")
@@ -1225,6 +1239,153 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "material_offset", text="Material Offset")
+ def DATA_TRANSFER(self, layout, ob, md):
+ row = layout.row(align=True)
+ row.prop(md, "object")
+ sub = row.row(align=True)
+ sub.active = bool(md.object)
+ sub.prop(md, "use_object_transform", text="", icon='GROUP')
+
+ layout.separator()
+
+ split = layout.split(0.333)
+ split.prop(md, "use_vert_data")
+ use_vert = md.use_vert_data
+ row = split.row()
+ row.active = use_vert
+ row.prop(md, "vert_mapping", text="")
+ if use_vert:
+ col = layout.column(align=True)
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_verts_vgroup")
+ row = split.row(align=True)
+ row.prop(md, "layers_vgroup_select_src", text="")
+ row.label(icon='RIGHTARROW_THIN')
+ row.prop(md, "layers_vgroup_select_dst", text="")
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_verts")
+
+ layout.separator()
+
+ split = layout.split(0.333)
+ split.prop(md, "use_edge_data")
+ use_edge = md.use_edge_data
+ row = split.row()
+ row.active = use_edge
+ row.prop(md, "edge_mapping", text="")
+ if use_edge:
+ col = layout.column(align=True)
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_edges")
+
+ layout.separator()
+
+ split = layout.split(0.333)
+ split.prop(md, "use_loop_data")
+ use_loop = md.use_loop_data
+ row = split.row()
+ row.active = use_loop
+ row.prop(md, "loop_mapping", text="")
+ if use_loop:
+ col = layout.column(align=True)
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_loops")
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_loops_vcol")
+ row = split.row(align=True)
+ row.prop(md, "layers_vcol_select_src", text="")
+ row.label(icon='RIGHTARROW')
+ row.prop(md, "layers_vcol_select_dst", text="")
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_loops_uv")
+ row = split.row(align=True)
+ row.prop(md, "layers_uv_select_src", text="")
+ row.label(icon='RIGHTARROW')
+ row.prop(md, "layers_uv_select_dst", text="")
+ col.prop(md, "islands_precision")
+
+ layout.separator()
+
+ split = layout.split(0.333)
+ split.prop(md, "use_poly_data")
+ use_poly = md.use_poly_data
+ row = split.row()
+ row.active = use_poly
+ row.prop(md, "poly_mapping", text="")
+ if use_poly:
+ col = layout.column(align=True)
+ split = col.split(0.333, align=True)
+ sub = split.column(align=True)
+ sub.prop(md, "data_types_polys")
+
+ layout.separator()
+
+ split = layout.split()
+ col = split.column()
+ row = col.row(align=True)
+ sub = row.row(align=True)
+ sub.active = md.use_max_distance
+ sub.prop(md, "max_distance")
+ row.prop(md, "use_max_distance", text="", icon='STYLUS_PRESSURE')
+
+ col = split.column()
+ col.prop(md, "ray_radius")
+
+ layout.separator()
+
+ split = layout.split()
+ col = split.column()
+ col.prop(md, "mix_mode")
+ col.prop(md, "mix_factor")
+
+ col = split.column()
+ row = col.row()
+ row.active = bool(md.object)
+ row.operator("object.datalayout_transfer", text="Generate Data Layers")
+ row = col.row(align=True)
+ row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+ sub = row.row(align=True)
+ sub.active = bool(md.vertex_group)
+ sub.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
+
+ def NORMAL_EDIT(self, layout, ob, md):
+ has_vgroup = bool(md.vertex_group)
+ needs_object_offset = (((md.mode == 'RADIAL') and not md.target) or
+ ((md.mode == 'DIRECTIONAL') and md.use_direction_parallel))
+
+ row = layout.row()
+ row.prop(md, "mode", expand=True)
+
+ split = layout.split()
+
+ col = split.column()
+ col.prop(md, "target", text="")
+ sub = col.column(align=True)
+ sub.active = needs_object_offset
+ sub.prop(md, "offset")
+ row = col.row(align=True)
+
+ col = split.column()
+ row = col.row()
+ row.active = (md.mode == 'DIRECTIONAL')
+ row.prop(md, "use_direction_parallel")
+
+ subcol = col.column(align=True)
+ subcol.label("Mix Mode:")
+ subcol.prop(md, "mix_mode", text="")
+ subcol.prop(md, "mix_factor")
+ row = subcol.row(align=True)
+ row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+ sub = row.row(align=True)
+ sub.active = has_vgroup
+ sub.prop(md, "use_invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py
index ca922dfb544..5ed0f8c3265 100644
--- a/release/scripts/startup/bl_ui/properties_data_speaker.py
+++ b/release/scripts/startup/bl_ui/properties_data_speaker.py
@@ -22,7 +22,7 @@ from bpy.types import Panel
from rna_prop_ui import PropertyPanel
-class DataButtonsPanel():
+class DataButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py
index 606842db01d..2d91c998007 100644
--- a/release/scripts/startup/bl_ui/properties_freestyle.py
+++ b/release/scripts/startup/bl_ui/properties_freestyle.py
@@ -23,7 +23,7 @@ from bpy.types import Menu, Panel, UIList
# Render properties
-class RenderFreestyleButtonsPanel():
+class RenderFreestyleButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "render"
@@ -62,7 +62,7 @@ class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel):
# Render layer properties
-class RenderLayerFreestyleButtonsPanel():
+class RenderLayerFreestyleButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "render_layer"
@@ -701,7 +701,7 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
# Material properties
-class MaterialFreestyleButtonsPanel():
+class MaterialFreestyleButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "material"
diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py
index 503b3cd234c..32a8e734ab6 100644
--- a/release/scripts/startup/bl_ui/properties_game.py
+++ b/release/scripts/startup/bl_ui/properties_game.py
@@ -21,7 +21,7 @@ import bpy
from bpy.types import Panel, Menu
-class PhysicsButtonsPanel():
+class PhysicsButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"
@@ -100,6 +100,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
sub.prop(game, "damping", text="Translation", slider=True)
sub.prop(game, "rotation_damping", text="Rotation", slider=True)
+ if physics_type == 'RIGID_BODY':
layout.separator()
split = layout.split()
@@ -179,7 +180,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
col.prop(game, "use_actor", text="Detect Actors")
col.prop(ob, "hide_render", text="Invisible")
- elif physics_type in {'INVISIBLE', 'NO_COLLISION', 'OCCLUDE'}:
+ elif physics_type in {'INVISIBLE', 'NO_COLLISION', 'OCCLUDER'}:
layout.prop(ob, "hide_render", text="Invisible")
elif physics_type == 'NAVMESH':
@@ -191,15 +192,6 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
layout.operator("mesh.navmesh_reset")
layout.operator("mesh.navmesh_clear")
- if physics_type not in {'NO_COLLISION', 'OCCLUDE'}:
- layout.separator()
- split = layout.split()
-
- col = split.column()
- col.prop(game, "collision_group")
- col = split.column()
- col.prop(game, "collision_mask")
-
class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
bl_label = "Collision Bounds"
@@ -209,7 +201,8 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
def poll(cls, context):
game = context.object.game
rd = context.scene.render
- return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC', 'CHARACTER'}) and (rd.engine in cls.COMPAT_ENGINES)
+ return (rd.engine in cls.COMPAT_ENGINES) \
+ and (game.physics_type in {'SENSOR', 'STATIC', 'DYNAMIC', 'RIGID_BODY', 'CHARACTER', 'SOFT_BODY'})
def draw_header(self, context):
game = context.active_object.game
@@ -220,13 +213,23 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
layout = self.layout
game = context.active_object.game
-
layout.active = game.use_collision_bounds
+
layout.prop(game, "collision_bounds_type", text="Bounds")
row = layout.row()
row.prop(game, "collision_margin", text="Margin", slider=True)
- row.prop(game, "use_collision_compound", text="Compound")
+
+ sub = row.row()
+ sub.active = game.physics_type not in {'SOFT_BODY', 'CHARACTER'}
+ sub.prop(game, "use_collision_compound", text="Compound")
+
+ layout.separator()
+ split = layout.split()
+ col = split.column()
+ col.prop(game, "collision_group")
+ col = split.column()
+ col.prop(game, "collision_mask")
class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
@@ -237,7 +240,8 @@ class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
def poll(cls, context):
game = context.object.game
rd = context.scene.render
- return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC'}) and (rd.engine in cls.COMPAT_ENGINES)
+ return (rd.engine in cls.COMPAT_ENGINES) \
+ and (game.physics_type in {'SENSOR', 'STATIC', 'DYNAMIC', 'RIGID_BODY', 'SOFT_BODY'})
def draw_header(self, context):
game = context.active_object.game
@@ -256,7 +260,7 @@ class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
row.label()
-class RenderButtonsPanel():
+class RenderButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "render"
@@ -455,7 +459,7 @@ class RENDER_PT_game_display(RenderButtonsPanel, Panel):
col.prop(gs, "frame_color", text="")
-class SceneButtonsPanel():
+class SceneButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "scene"
@@ -519,23 +523,7 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
row.prop(rd, "sample_max_error")
-class RENDER_PT_game_sound(RenderButtonsPanel, Panel):
- bl_label = "Sound"
- COMPAT_ENGINES = {'BLENDER_GAME'}
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
-
- layout.prop(scene, "audio_distance_model")
-
- col = layout.column(align=True)
- col.prop(scene, "audio_doppler_speed", text="Speed")
- col.prop(scene, "audio_doppler_factor")
-
-
-class WorldButtonsPanel():
+class WorldButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "world"
@@ -691,7 +679,7 @@ class WORLD_PT_game_physics_obstacles(WorldButtonsPanel, Panel):
layout.prop(gs, "show_obstacle_simulation")
-class DataButtonsPanel():
+class DataButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "data"
@@ -749,7 +737,7 @@ class DATA_PT_shadow_game(DataButtonsPanel, Panel):
row.prop(lamp, "shadow_frustum_size", text="Frustum Size")
-class ObjectButtonsPanel():
+class ObjectButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 4789d119192..5b5a7648d83 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -19,11 +19,34 @@
# <pep8 compliant>
-class GreasePencilPanel():
+from bpy.types import Menu, UIList
+
+
+def gpencil_stroke_placement_settings(context, layout, gpd):
+ col = layout.column(align=True)
+
+ col.label(text="Stroke Placement:")
+
+ row = col.row(align=True)
+ row.prop_enum(gpd, "draw_mode", 'VIEW')
+ row.prop_enum(gpd, "draw_mode", 'CURSOR')
+
+ if context.space_data.type == 'VIEW_3D':
+ row = col.row(align=True)
+ row.prop_enum(gpd, "draw_mode", 'SURFACE')
+ row.prop_enum(gpd, "draw_mode", 'STROKE')
+
+ row = col.row(align=False)
+ row.active = gpd.draw_mode in {'SURFACE', 'STROKE'}
+ row.prop(gpd, "use_stroke_endpoints")
+
+
+class GreasePencilDrawingToolsPanel:
# subclass must set
# bl_space_type = 'IMAGE_EDITOR'
- # bl_region_type = 'TOOLS'
bl_label = "Grease Pencil"
+ bl_category = "Grease Pencil"
+ bl_region_type = 'TOOLS'
@staticmethod
def draw(self, context):
@@ -31,19 +54,440 @@ class GreasePencilPanel():
col = layout.column(align=True)
+ col.label(text="Draw:")
row = col.row(align=True)
row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
- row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
+ row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
row = col.row(align=True)
+ row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
- row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
row = col.row(align=True)
- row.prop(context.tool_settings, "use_grease_pencil_sessions")
+ row.prop(context.tool_settings, "use_grease_pencil_sessions", text="Continuous Drawing")
+
+ if context.space_data.type in {'VIEW_3D', 'CLIP_EDITOR'}:
+ col.separator()
+ col.label("Data Source:")
+ row = col.row(align=True)
+ if context.space_data.type == 'VIEW_3D':
+ row.prop(context.tool_settings, "grease_pencil_source", expand=True)
+ elif context.space_data.type == 'CLIP_EDITOR':
+ row.prop(context.space_data, "grease_pencil_source", expand=True)
+
+ gpd = context.gpencil_data
+ if gpd:
+ col.separator()
+ gpencil_stroke_placement_settings(context, col, gpd)
if context.space_data.type == 'VIEW_3D':
col.separator()
+ col.separator()
- col.label(text="Measure:")
+ col.label(text="Tools:")
+ col.operator("gpencil.convert", text="Convert...")
col.operator("view3d.ruler")
+
+
+class GreasePencilStrokeEditPanel:
+ # subclass must set
+ # bl_space_type = 'IMAGE_EDITOR'
+ bl_label = "Edit Strokes"
+ bl_category = "Grease Pencil"
+ bl_region_type = 'TOOLS'
+
+ @classmethod
+ def poll(cls, context):
+ return (context.gpencil_data is not None)
+
+ @staticmethod
+ def draw(self, context):
+ layout = self.layout
+
+ gpd = context.gpencil_data
+ edit_ok = bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
+
+ col = layout.column(align=True)
+ col.prop(gpd, "use_stroke_edit_mode", text="Enable Editing", icon='EDIT', toggle=True)
+
+ col.separator()
+
+ col.label(text="Select:")
+ subcol = col.column(align=True)
+ subcol.active = edit_ok
+ subcol.operator("gpencil.select_all", text="Select All")
+ subcol.operator("gpencil.select_border")
+ subcol.operator("gpencil.select_circle")
+
+ col.separator()
+
+ subcol = col.column(align=True)
+ subcol.active = edit_ok
+ subcol.operator("gpencil.select_linked")
+ subcol.operator("gpencil.select_more")
+ subcol.operator("gpencil.select_less")
+
+ col.separator()
+
+ col.label(text="Edit:")
+ row = col.row(align=True)
+ row.active = edit_ok
+ row.operator("gpencil.copy", text="Copy")
+ row.operator("gpencil.paste", text="Paste")
+
+ subcol = col.column(align=True)
+ subcol.active = edit_ok
+ subcol.operator("gpencil.delete", text="Delete")
+ subcol.operator("gpencil.duplicate_move", text="Duplicate")
+ subcol.operator("transform.mirror", text="Mirror").gpencil_strokes = True
+
+ col.separator()
+
+ subcol = col.column(align=True)
+ subcol.active = edit_ok
+ subcol.operator("transform.translate").gpencil_strokes = True # icon='MAN_TRANS'
+ subcol.operator("transform.rotate").gpencil_strokes = True # icon='MAN_ROT'
+ subcol.operator("transform.resize", text="Scale").gpencil_strokes = True # icon='MAN_SCALE'
+
+ col.separator()
+
+ subcol = col.column(align=True)
+ subcol.active = edit_ok
+ subcol.operator("transform.bend", text="Bend").gpencil_strokes = True
+ subcol.operator("transform.shear", text="Shear").gpencil_strokes = True
+ subcol.operator("transform.tosphere", text="To Sphere").gpencil_strokes = True
+
+
+###############################
+
+class GPENCIL_PIE_tool_palette(Menu):
+ """A pie menu for quick access to Grease Pencil tools"""
+ bl_label = "Grease Pencil Tools"
+
+ def draw(self, context):
+ layout = self.layout
+
+ pie = layout.menu_pie()
+ gpd = context.gpencil_data
+
+ # W - Drawing Types
+ col = pie.column()
+ col.operator("gpencil.draw", text="Draw", icon='GREASEPENCIL').mode = 'DRAW'
+ col.operator("gpencil.draw", text="Straight Lines", icon='LINE_DATA').mode = 'DRAW_STRAIGHT'
+ col.operator("gpencil.draw", text="Poly", icon='MESH_DATA').mode = 'DRAW_POLY'
+
+ # E - Eraser
+ # XXX: needs a dedicated icon...
+ col = pie.column()
+ col.operator("gpencil.draw", text="Eraser", icon='FORCE_CURVE').mode = 'ERASER'
+
+ # E - "Settings" Palette is included here too, since it needs to be in a stable position...
+ if gpd and gpd.layers.active:
+ col.separator()
+ col.operator("wm.call_menu_pie", text="Settings...", icon='SCRIPTWIN').name = "GPENCIL_PIE_settings_palette"
+
+ # Editing tools
+ if gpd:
+ if gpd.use_stroke_edit_mode and context.editable_gpencil_strokes:
+ # S - Exit Edit Mode
+ pie.prop(gpd, "use_stroke_edit_mode", text="Exit Edit Mode", icon='EDIT')
+
+ # N - Transforms
+ col = pie.column()
+ row = col.row(align=True)
+ row.operator("transform.translate", icon='MAN_TRANS').gpencil_strokes = True
+ row.operator("transform.rotate", icon='MAN_ROT').gpencil_strokes = True
+ row.operator("transform.resize", text="Scale", icon='MAN_SCALE').gpencil_strokes = True
+ row = col.row(align=True)
+ row.label("Proportional Edit:")
+ row.prop(context.tool_settings, "proportional_edit", text="", icon_only=True)
+ row.prop(context.tool_settings, "proportional_edit_falloff", text="", icon_only=True)
+
+ # NW - Select (Non-Modal)
+ col = pie.column()
+ col.operator("gpencil.select_all", text="Select All", icon='PARTICLE_POINT')
+ col.operator("gpencil.select_all", text="Select Inverse", icon='BLANK1')
+ col.operator("gpencil.select_linked", text="Select Linked", icon='LINKED')
+
+ # NE - Select (Modal)
+ col = pie.column()
+ col.operator("gpencil.select_border", text="Border Select", icon='BORDER_RECT')
+ col.operator("gpencil.select_circle", text="Circle Select", icon='META_EMPTY')
+ col.operator("gpencil.select_lasso", text="Lasso Select", icon='BORDER_LASSO')
+
+ # SW - Edit Tools
+ col = pie.column()
+ col.operator("gpencil.duplicate_move", icon='PARTICLE_PATH', text="Duplicate")
+ col.operator("gpencil.delete", icon='X', text="Delete...")
+
+ # SE - More Tools
+ pie.operator("wm.call_menu_pie", text="More...").name = "GPENCIL_PIE_tools_more"
+ else:
+ # Toggle Edit Mode
+ pie.prop(gpd, "use_stroke_edit_mode", text="Enable Stroke Editing", icon='EDIT')
+
+
+class GPENCIL_PIE_settings_palette(Menu):
+ """A pie menu for quick access to Grease Pencil settings"""
+ bl_label = "Grease Pencil Settings"
+
+ @classmethod
+ def poll(cls, context):
+ return bool(context.gpencil_data and context.active_gpencil_layer)
+
+ def draw(self, context):
+ layout = self.layout
+
+ pie = layout.menu_pie()
+ # gpd = context.gpencil_data
+ gpl = context.active_gpencil_layer
+
+ # W - Stroke draw settings
+ col = pie.column(align=True)
+ col.label(text="Stroke")
+ col.prop(gpl, "color", text="")
+ col.prop(gpl, "alpha", text="", slider=True)
+
+ # E - Fill draw settings
+ col = pie.column(align=True)
+ col.label(text="Fill")
+ col.prop(gpl, "fill_color", text="")
+ col.prop(gpl, "fill_alpha", text="", slider=True)
+
+ # S - Layer settings
+ col = pie.column()
+ col.prop(gpl, "line_width", slider=True)
+ # col.prop(gpl, "use_volumetric_strokes")
+ col.prop(gpl, "use_onion_skinning")
+
+ # N - Active Layer
+ # XXX: this should show an operator to change the active layer instead
+ col = pie.column()
+ col.label("Active Layer: ")
+ col.prop(gpl, "info", text="")
+ # col.prop(gpd, "layers")
+ row = col.row()
+ row.prop(gpl, "lock")
+ row.prop(gpl, "hide")
+
+
+class GPENCIL_PIE_tools_more(Menu):
+ """A pie menu for accessing more Grease Pencil tools"""
+ bl_label = "More Grease Pencil Tools"
+
+ @classmethod
+ def poll(cls, context):
+ gpd = context.gpencil_data
+ return bool(gpd and gpd.use_stroke_edit_mode and context.editable_gpencil_strokes)
+
+ def draw(self, context):
+ layout = self.layout
+
+ pie = layout.menu_pie()
+ # gpd = context.gpencil_data
+
+ col = pie.column(align=True)
+ col.operator("gpencil.copy", icon='COPYDOWN', text="Copy")
+ col.operator("gpencil.paste", icon='PASTEDOWN', text="Paste")
+
+ col = pie.column(align=True)
+ col.operator("gpencil.select_more", icon='ZOOMIN')
+ col.operator("gpencil.select_less", icon='ZOOMOUT')
+
+ pie.operator("transform.mirror", icon='MOD_MIRROR').gpencil_strokes = True
+ pie.operator("transform.bend", icon='MOD_SIMPLEDEFORM').gpencil_strokes = True
+ pie.operator("transform.shear", icon='MOD_TRIANGULATE').gpencil_strokes = True
+ pie.operator("transform.tosphere", icon='MOD_MULTIRES').gpencil_strokes = True
+
+ pie.operator("gpencil.convert", icon='OUTLINER_OB_CURVE', text="Convert...")
+ pie.operator("wm.call_menu_pie", text="Back to Main Palette...").name = "GPENCIL_PIE_tool_palette"
+
+
+class GPENCIL_UL_layer(UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ # assert(isinstance(item, bpy.types.GPencilLayer)
+ gpl = item
+
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ if gpl.lock:
+ layout.active = False
+
+ split = layout.split(percentage=0.25)
+ row = split.row(align=True)
+ row.prop(gpl, "color", text="", emboss=gpl.is_stroke_visible)
+ row.prop(gpl, "fill_color", text="", emboss=gpl.is_fill_visible)
+ split.prop(gpl, "info", text="", emboss=False)
+
+ row = layout.row(align=True)
+ row.prop(gpl, "lock", text="", emboss=False)
+ row.prop(gpl, "hide", text="", emboss=False)
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
+class GreasePencilDataPanel:
+ # subclass must set
+ # bl_space_type = 'IMAGE_EDITOR'
+ bl_label = "Grease Pencil"
+ bl_region_type = 'UI'
+
+ @staticmethod
+ def draw_header(self, context):
+ self.layout.prop(context.space_data, "show_grease_pencil", text="")
+
+ @staticmethod
+ def draw(self, context):
+ layout = self.layout
+
+ # owner of Grease Pencil data
+ gpd_owner = context.gpencil_data_owner
+ gpd = context.gpencil_data
+
+ # Owner Selector
+ if context.space_data.type == 'VIEW_3D':
+ layout.prop(context.tool_settings, "grease_pencil_source", expand=True)
+ elif context.space_data.type == 'CLIP_EDITOR':
+ layout.prop(context.space_data, "grease_pencil_source", expand=True)
+
+ # Grease Pencil data selector
+ layout.template_ID(gpd_owner, "grease_pencil", new="gpencil.data_add", unlink="gpencil.data_unlink")
+
+ # Grease Pencil data...
+ if gpd:
+ self.draw_layers(context, layout, gpd)
+
+ def draw_layers(self, context, layout, gpd):
+ row = layout.row()
+
+ col = row.column()
+ if len(gpd.layers) >= 2:
+ layer_rows = 5
+ else:
+ layer_rows = 2
+ col.template_list("GPENCIL_UL_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows)
+
+ col = row.column()
+
+ sub = col.column(align=True)
+ sub.operator("gpencil.layer_add", icon='ZOOMIN', text="")
+ sub.operator("gpencil.layer_remove", icon='ZOOMOUT', text="")
+
+ gpl = context.active_gpencil_layer
+ if gpl:
+ sub.operator("gpencil.layer_duplicate", icon='COPY_ID', text="") # XXX: needs a dedicated icon
+
+ if len(gpd.layers) > 1:
+ col.separator()
+
+ sub = col.column(align=True)
+ sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP'
+ sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN'
+
+ if gpl:
+ self.draw_layer(layout, gpl)
+
+ def draw_layer(self, layout, gpl):
+ # layer settings
+ split = layout.split(percentage=0.5)
+ split.active = not gpl.lock
+
+ # Column 1 - Stroke
+ col = split.column(align=True)
+ col.label(text="Stroke:")
+ col.prop(gpl, "color", text="")
+ col.prop(gpl, "alpha", slider=True)
+
+ # Column 2 - Fill
+ col = split.column(align=True)
+ col.label(text="Fill:")
+ col.prop(gpl, "fill_color", text="")
+ col.prop(gpl, "fill_alpha", text="Opacity", slider=True)
+
+ # Options
+ split = layout.split(percentage=0.5)
+ split.active = not gpl.lock
+
+ col = split.column(align=True)
+ col.prop(gpl, "line_width", slider=True)
+ col.prop(gpl, "use_volumetric_strokes")
+
+ col = split.column(align=True)
+ col.prop(gpl, "show_x_ray")
+
+ # if debug:
+ # layout.prop(gpl, "show_points")
+
+ layout.separator()
+
+ # Full-Row - Frame Locking (and Delete Frame)
+ row = layout.row(align=True)
+ row.active = not gpl.lock
+
+ if gpl.active_frame:
+ lock_status = "Locked" if gpl.lock_frame else "Unlocked"
+ lock_label = "Frame: %d (%s)" % (gpl.active_frame.frame_number, lock_status)
+ else:
+ lock_label = "Lock Frame"
+ row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED')
+ row.operator("gpencil.active_frame_delete", text="", icon='X')
+
+ layout.separator()
+
+ # Onion skinning
+ col = layout.column(align=True)
+ col.active = not gpl.lock
+
+ row = col.row()
+ row.prop(gpl, "use_onion_skinning")
+ row.prop(gpl, "use_ghost_custom_colors", text="", icon='COLOR')
+
+ split = col.split(percentage=0.5)
+ split.active = gpl.use_onion_skinning
+
+ # - Before Frames
+ sub = split.column(align=True)
+ row = sub.row(align=True)
+ row.active = gpl.use_ghost_custom_colors
+ row.prop(gpl, "before_color", text="")
+ sub.prop(gpl, "ghost_before_range", text="Before")
+
+ # - After Frames
+ sub = split.column(align=True)
+ row = sub.row(align=True)
+ row.active = gpl.use_ghost_custom_colors
+ row.prop(gpl, "after_color", text="")
+ sub.prop(gpl, "ghost_after_range", text="After")
+
+
+class GreasePencilToolsPanel:
+ # subclass must set
+ # bl_space_type = 'IMAGE_EDITOR'
+ # bl_options = {'DEFAULT_CLOSED'}
+ bl_label = "Grease Pencil Settings"
+ bl_region_type = 'UI'
+
+ @classmethod
+ def poll(cls, context):
+ return (context.gpencil_data is not None)
+
+ @staticmethod
+ def draw(self, context):
+ layout = self.layout
+
+ # gpd_owner = context.gpencil_data_owner
+ gpd = context.gpencil_data
+
+ layout.prop(gpd, "use_stroke_edit_mode", text="Enable Editing", icon='EDIT', toggle=True)
+
+ layout.separator()
+
+ layout.label("Proportional Edit:")
+ row = layout.row()
+ row.prop(context.tool_settings, "proportional_edit", text="")
+ row.prop(context.tool_settings, "proportional_edit_falloff", text="")
+
+ layout.separator()
+ layout.separator()
+
+ gpencil_stroke_placement_settings(context, layout, gpd)
diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py
index 9a2857cc7b8..cb4a0f5bb85 100644
--- a/release/scripts/startup/bl_ui/properties_mask_common.py
+++ b/release/scripts/startup/bl_ui/properties_mask_common.py
@@ -112,7 +112,7 @@ class MASK_PT_layers:
row.prop(active_layer, "use_fill_holes", text="Holes")
-class MASK_PT_spline():
+class MASK_PT_spline:
# subclasses must define...
#~ bl_space_type = 'CLIP_EDITOR'
#~ bl_region_type = 'UI'
@@ -146,7 +146,7 @@ class MASK_PT_spline():
col.prop(spline, "use_self_intersection_check")
-class MASK_PT_point():
+class MASK_PT_point:
# subclasses must define...
#~ bl_space_type = 'CLIP_EDITOR'
#~ bl_region_type = 'UI'
@@ -173,8 +173,8 @@ class MASK_PT_point():
parent = point.parent
col = layout.column()
- # Currently only parenting yo movie clip is allowed, so do not
- # ver-oplicate things for now and use single template_ID
+ # Currently only parenting the movie-clip is allowed,
+ # so do not over-complicate things for now by using single template_ID
#col.template_any_ID(parent, "id", "id_type", text="")
col.label("Parent:")
@@ -201,7 +201,7 @@ class MASK_PT_point():
tracks_list, icon='ANIM_DATA', text="Track:")
-class MASK_PT_display():
+class MASK_PT_display:
# subclasses must define...
#~ bl_space_type = 'CLIP_EDITOR'
#~ bl_region_type = 'UI'
@@ -227,7 +227,7 @@ class MASK_PT_display():
sub.prop(space_data, "mask_overlay_mode", text="")
-class MASK_PT_transforms():
+class MASK_PT_transforms:
# subclasses must define...
#~ bl_space_type = 'CLIP_EDITOR'
#~ bl_region_type = 'TOOLS'
@@ -251,7 +251,7 @@ class MASK_PT_transforms():
col.operator("transform.transform", text="Scale Feather").mode = 'MASK_SHRINKFATTEN'
-class MASK_PT_tools():
+class MASK_PT_tools:
# subclasses must define...
#~ bl_space_type = 'CLIP_EDITOR'
#~ bl_region_type = 'TOOLS'
@@ -289,7 +289,7 @@ class MASK_PT_tools():
col.operator("mask.shape_key_rekey", text="Re-Key Shape Points")
-class MASK_PT_add():
+class MASK_PT_add:
# subclasses must define...
#~ bl_space_type = 'CLIP_EDITOR'
#~ bl_region_type = 'TOOLS'
@@ -344,7 +344,7 @@ class MASK_MT_visibility(Menu):
layout = self.layout
layout.operator("mask.hide_view_clear", text="Show Hidden")
- layout.operator("mask.hide_view_set", text="Hide Selected")
+ layout.operator("mask.hide_view_set", text="Hide Selected").unselected = False
layout.operator("mask.hide_view_set", text="Hide Unselected").unselected = True
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index e3fcb0ef53e..20143b81d14 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -92,7 +92,7 @@ class MATERIAL_UL_matslots(UIList):
layout.label(text="", icon_value=icon)
-class MaterialButtonsPanel():
+class MaterialButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "material"
@@ -875,7 +875,7 @@ class MATERIAL_PT_transp_game(MaterialButtonsPanel, Panel):
layout.prop(mat, "alpha")
-class VolumeButtonsPanel():
+class VolumeButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "material"
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 25367a58a54..3ff7a248c60 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -22,7 +22,7 @@ from bpy.types import Panel, Menu
from rna_prop_ui import PropertyPanel
-class ObjectButtonsPanel():
+class ObjectButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
@@ -323,8 +323,10 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel):
layout.prop(ob, "use_extra_recalc_data")
-from bl_ui.properties_animviz import (MotionPathButtonsPanel,
- OnionSkinButtonsPanel)
+from bl_ui.properties_animviz import (
+ MotionPathButtonsPanel,
+ OnionSkinButtonsPanel,
+ )
class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index f1042856e4c..b0da65063d1 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -20,7 +20,7 @@
from bpy.types import Menu
-class UnifiedPaintPanel():
+class UnifiedPaintPanel:
# subclass must set
# bl_space_type = 'IMAGE_EDITOR'
# bl_region_type = 'UI'
@@ -243,24 +243,23 @@ def brush_texture_settings(layout, brush, sculpt):
layout.operator("brush.stencil_reset_transform")
# angle and texture_angle_source
- if brush.brush_capabilities.has_texture_angle:
+ if tex_slot.has_texture_angle:
col = layout.column()
col.label(text="Angle:")
- row = col.row(align=True)
- if brush.brush_capabilities.has_texture_angle_source:
- if brush.brush_capabilities.has_random_texture_angle:
+ col.prop(tex_slot, "angle", text="")
+ if tex_slot.has_texture_angle_source:
+ col.prop(tex_slot, "use_rake", text="Rake")
+
+ if brush.brush_capabilities.has_random_texture_angle and tex_slot.has_random_texture_angle:
if sculpt:
if brush.sculpt_capabilities.has_random_texture_angle:
- row.prop(brush, "texture_angle_source_random", text="")
- else:
- row.prop(brush, "texture_angle_source_no_random", text="")
-
+ col.prop(tex_slot, "use_random", text="Random")
+ if tex_slot.use_random:
+ col.prop(tex_slot, "random_angle", text="")
else:
- row.prop(brush, "texture_angle_source_random", text="")
- else:
- row.prop(brush, "texture_angle_source_no_random", text="")
-
- row.prop(tex_slot, "angle", text="")
+ col.prop(tex_slot, "use_random", text="Random")
+ if tex_slot.use_random:
+ col.prop(tex_slot, "random_angle", text="")
# scale and offset
split = layout.split()
@@ -290,9 +289,18 @@ def brush_mask_texture_settings(layout, brush):
col = layout.column()
col.prop(brush, "use_pressure_masking", text="")
- col.label(text="Angle:")
- col.active = brush.brush_capabilities.has_texture_angle
- col.prop(mask_tex_slot, "angle", text="")
+ # angle and texture_angle_source
+ if mask_tex_slot.has_texture_angle:
+ col = layout.column()
+ col.label(text="Angle:")
+ col.prop(mask_tex_slot, "angle", text="")
+ if mask_tex_slot.has_texture_angle_source:
+ col.prop(mask_tex_slot, "use_rake", text="Rake")
+
+ if brush.brush_capabilities.has_random_texture_angle and mask_tex_slot.has_random_texture_angle:
+ col.prop(mask_tex_slot, "use_random", text="Random")
+ if mask_tex_slot.use_random:
+ col.prop(mask_tex_slot, "random_angle", text="")
# scale and offset
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 30fc3a9e373..29be9ac2158 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -18,15 +18,16 @@
# <pep8 compliant>
import bpy
-from bpy.types import Panel
+from bpy.types import Panel, Menu
from rna_prop_ui import PropertyPanel
from bpy.app.translations import pgettext_iface as iface_
-from bl_ui.properties_physics_common import (point_cache_ui,
- effector_weights_ui,
- basic_force_field_settings_ui,
- basic_force_field_falloff_ui,
- )
+from bl_ui.properties_physics_common import (
+ point_cache_ui,
+ effector_weights_ui,
+ basic_force_field_settings_ui,
+ basic_force_field_falloff_ui,
+ )
def particle_panel_enabled(context, psys):
@@ -63,7 +64,31 @@ def particle_get_settings(context):
return None
-class ParticleButtonsPanel():
+class PARTICLE_MT_specials(Menu):
+ bl_label = "Particle Specials"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ props = layout.operator("particle.copy_particle_systems", text="Copy Active to Selected Objects")
+ props.use_active = True
+ props.remove_target_particles = False
+
+ props = layout.operator("particle.copy_particle_systems", text="Copy All to Selected Objects")
+ props.use_active = False
+ props.remove_target_particles = True
+
+
+class PARTICLE_MT_hair_dynamics_presets(Menu):
+ bl_label = "Hair Dynamics Presets"
+ preset_subdir = "hair_dynamics"
+ preset_operator = "script.execute_preset"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+ draw = Menu.draw_preset
+
+
+class ParticleButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "particle"
@@ -73,6 +98,31 @@ class ParticleButtonsPanel():
return particle_panel_poll(cls, context)
+def find_modifier(ob, psys):
+ for md in ob.modifiers:
+ if md.type == 'PARTICLE_SYSTEM':
+ if md.particle_system == psys:
+ return md
+
+
+class PARTICLE_UL_particle_systems(bpy.types.UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag):
+ ob = data
+ psys = item
+
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ md = find_modifier(ob, psys)
+
+ layout.prop(psys, "name", text="", emboss=False, icon_value=icon)
+ if md:
+ layout.prop(md, "show_render", emboss=False, icon_only=True, icon='RESTRICT_RENDER_OFF' if md.show_render else 'RESTRICT_RENDER_ON')
+ layout.prop(md, "show_viewport", emboss=False, icon_only=True, icon='RESTRICT_VIEW_OFF' if md.show_viewport else 'RESTRICT_VIEW_ON')
+
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.label(text="", icon_value=icon)
+
+
class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
@@ -97,12 +147,13 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
if ob:
row = layout.row()
- row.template_list("UI_UL_list", "particle_systems", ob, "particle_systems",
+ row.template_list("PARTICLE_UL_particle_systems", "particle_systems", ob, "particle_systems",
ob.particle_systems, "active_index", rows=1)
col = row.column(align=True)
col.operator("object.particle_system_add", icon='ZOOMIN', text="")
col.operator("object.particle_system_remove", icon='ZOOMOUT', text="")
+ col.menu("PARTICLE_MT_specials", icon='DOWNARROW_HLT', text="")
if psys is None:
part = particle_get_settings(context)
@@ -278,30 +329,75 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
if not psys.cloth:
return
- cloth = psys.cloth.settings
+ cloth_md = psys.cloth
+ cloth = cloth_md.settings
+ result = cloth_md.solver_result
layout.enabled = psys.use_hair_dynamics and psys.point_cache.is_baked is False
- split = layout.split()
+ row = layout.row(align=True)
+ row.menu("PARTICLE_MT_hair_dynamics_presets", text=bpy.types.PARTICLE_MT_hair_dynamics_presets.bl_label)
+ row.operator("particle.hair_dynamics_preset_add", text="", icon='ZOOMIN')
+ row.operator("particle.hair_dynamics_preset_add", text="", icon='ZOOMOUT').remove_active = True
+
+ split = layout.column()
col = split.column()
- col.label(text="Material:")
+ col.label(text="Structure")
+ col.prop(cloth, "mass")
sub = col.column(align=True)
- sub.prop(cloth, "pin_stiffness", text="Stiffness")
- sub.prop(cloth, "mass")
- sub.prop(cloth, "bending_stiffness", text="Bending")
- sub.prop(cloth, "internal_friction", slider=True)
- sub.prop(cloth, "collider_friction", slider=True)
+ subsub = sub.row(align=True)
+ subsub.prop(cloth, "bending_stiffness", text="Stiffness")
+ subsub.prop(psys.settings, "bending_random", text="Random")
+ sub.prop(cloth, "bending_damping", text="Damping")
+ # XXX has no noticeable effect with stiff hair structure springs
+ #col.prop(cloth, "spring_damping", text="Damping")
+
+ split.separator()
col = split.column()
- col.label(text="Damping:")
+ col.label(text="Volume")
+ col.prop(cloth, "air_damping", text="Air Drag")
+ col.prop(cloth, "internal_friction", slider=True)
sub = col.column(align=True)
- sub.prop(cloth, "spring_damping", text="Spring")
- sub.prop(cloth, "air_damping", text="Air")
+ sub.prop(cloth, "density_target", text="Density Target")
+ sub.prop(cloth, "density_strength", slider=True, text="Strength")
+ col.prop(cloth, "voxel_cell_size")
+
+ split.separator()
+
+ col = split.column()
+ col.label(text="Pinning")
+ col.prop(cloth, "pin_stiffness", text="Goal Strength")
+
+ split.separator()
+ col = split.column()
col.label(text="Quality:")
col.prop(cloth, "quality", text="Steps", slider=True)
+ row = col.row()
+ row.prop(psys.settings, "show_hair_grid", text="HairGrid")
+
+ if result:
+ box = layout.box()
+
+ if not result.status:
+ label = " "
+ icon = 'NONE'
+ elif result.status == {'SUCCESS'}:
+ label = "Success"
+ icon = 'NONE'
+ elif result.status - {'SUCCESS'} == {'NO_CONVERGENCE'}:
+ label = "No Convergence"
+ icon = 'ERROR'
+ else:
+ label = "ERROR"
+ icon = 'ERROR'
+ box.label(label, icon=icon)
+ box.label("Iterations: %d .. %d (avg. %d)" % (result.min_iterations, result.max_iterations, result.avg_iterations))
+ box.label("Error: %.5f .. %.5f (avg. %.5f)" % (result.min_error, result.max_error, result.avg_error))
+
class PARTICLE_PT_cache(ParticleButtonsPanel, Panel):
bl_label = "Cache"
@@ -999,6 +1095,7 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, Panel):
row = layout.row()
row.prop(part, "draw_method", expand=True)
+ row.prop(part, "show_guide_hairs")
if part.draw_method == 'NONE' or (part.render_type == 'NONE' and part.draw_method == 'RENDER'):
return
@@ -1083,8 +1180,17 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
col.label(text="Effects:")
sub = col.column(align=True)
- sub.prop(part, "clump_factor", slider=True)
- sub.prop(part, "clump_shape", slider=True)
+ sub.prop(part, "use_clump_curve")
+ if part.use_clump_curve:
+ sub.template_curve_mapping(part, "clump_curve")
+ else:
+ sub.prop(part, "clump_factor", slider=True)
+ sub.prop(part, "clump_shape", slider=True)
+ sub = col.column(align=True)
+ sub.prop(part, "use_clump_noise")
+ subsub = sub.column()
+ subsub.enabled = part.use_clump_noise
+ subsub.prop(part, "clump_noise_size")
sub = col.column(align=True)
sub.prop(part, "child_length", slider=True)
@@ -1108,20 +1214,28 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
sub.prop(part, "child_parting_max", text="Max")
col = split.column()
- col.label(text="Roughness:")
- sub = col.column(align=True)
- sub.prop(part, "roughness_1", text="Uniform")
- sub.prop(part, "roughness_1_size", text="Size")
+ col.prop(part, "use_roughness_curve")
+ if part.use_roughness_curve:
+ sub = col.column()
+ sub.template_curve_mapping(part, "roughness_curve")
+ sub.prop(part, "roughness_1", text="Roughness")
+ sub.prop(part, "roughness_1_size", text="Size")
+ else:
+ col.label(text="Roughness:")
- sub = col.column(align=True)
- sub.prop(part, "roughness_endpoint", "Endpoint")
- sub.prop(part, "roughness_end_shape")
+ sub = col.column(align=True)
+ sub.prop(part, "roughness_1", text="Uniform")
+ sub.prop(part, "roughness_1_size", text="Size")
- sub = col.column(align=True)
- sub.prop(part, "roughness_2", text="Random")
- sub.prop(part, "roughness_2_size", text="Size")
- sub.prop(part, "roughness_2_threshold", slider=True)
+ sub = col.column(align=True)
+ sub.prop(part, "roughness_endpoint", "Endpoint")
+ sub.prop(part, "roughness_end_shape")
+
+ sub = col.column(align=True)
+ sub.prop(part, "roughness_2", text="Random")
+ sub.prop(part, "roughness_2_size", text="Size")
+ sub.prop(part, "roughness_2_threshold", slider=True)
layout.row().label(text="Kink:")
layout.row().prop(part, "kink", expand=True)
@@ -1129,14 +1243,27 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
split = layout.split()
split.active = part.kink != 'NO'
- col = split.column()
- sub = col.column(align=True)
- sub.prop(part, "kink_amplitude")
- sub.prop(part, "kink_amplitude_clump", text="Clump", slider=True)
- col.prop(part, "kink_flat", slider=True)
- col = split.column(align=True)
- col.prop(part, "kink_frequency")
- col.prop(part, "kink_shape", slider=True)
+ if part.kink in {'SPIRAL'}:
+ col = split.column()
+ sub = col.column(align=True)
+ sub.prop(part, "kink_amplitude", text="Radius")
+ sub.prop(part, "kink_amplitude_random", text="Random", slider=True)
+ sub = col.column(align=True)
+ sub.prop(part, "kink_axis")
+ sub.prop(part, "kink_axis_random", text="Random", slider=True)
+ col = split.column(align=True)
+ col.prop(part, "kink_frequency", text="Frequency")
+ col.prop(part, "kink_shape", text="Shape", slider=True)
+ col.prop(part, "kink_extra_steps", text="Steps")
+ else:
+ col = split.column()
+ sub = col.column(align=True)
+ sub.prop(part, "kink_amplitude")
+ sub.prop(part, "kink_amplitude_clump", text="Clump", slider=True)
+ col.prop(part, "kink_flat", slider=True)
+ col = split.column(align=True)
+ col.prop(part, "kink_frequency")
+ col.prop(part, "kink_shape", slider=True)
class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index 327ee4035ef..a5cbffb2e2c 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -20,8 +20,10 @@
import bpy
from bpy.types import Menu, Panel
-from bl_ui.properties_physics_common import (point_cache_ui,
- effector_weights_ui)
+from bl_ui.properties_physics_common import (
+ point_cache_ui,
+ effector_weights_ui,
+ )
def cloth_panel_enabled(md):
@@ -35,7 +37,7 @@ class CLOTH_MT_presets(Menu):
draw = Menu.draw_preset
-class PhysicButtonsPanel():
+class PhysicButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"
@@ -90,9 +92,6 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
sub.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="")
sub.prop(cloth, "pin_stiffness", text="Stiffness")
- col.label(text="Pre roll:")
- col.prop(cloth, "pre_roll", text="Frames")
-
# Disabled for now
"""
if cloth.vertex_group_mass:
diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py
index 4df8eab7d10..bb0f0cfc796 100644
--- a/release/scripts/startup/bl_ui/properties_physics_common.py
+++ b/release/scripts/startup/bl_ui/properties_physics_common.py
@@ -23,7 +23,7 @@ from bpy.types import Panel
from bpy.app.translations import contexts as i18n_contexts
-class PhysicButtonsPanel():
+class PhysicButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"
diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
index 6a6d8dcff4a..01dcf837546 100644
--- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
+++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
@@ -20,9 +20,10 @@
import bpy
from bpy.types import Panel, UIList
-from bl_ui.properties_physics_common import (point_cache_ui,
- effector_weights_ui,
- )
+from bl_ui.properties_physics_common import (
+ point_cache_ui,
+ effector_weights_ui,
+ )
class PHYSICS_UL_dynapaint_surfaces(UIList):
@@ -46,7 +47,7 @@ class PHYSICS_UL_dynapaint_surfaces(UIList):
row.label(text="", icon_value=sticon)
-class PhysicButtonsPanel():
+class PhysicButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"
diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py
index 933a9aa12a3..348f66da145 100644
--- a/release/scripts/startup/bl_ui/properties_physics_field.py
+++ b/release/scripts/startup/bl_ui/properties_physics_field.py
@@ -20,12 +20,13 @@
import bpy
from bpy.types import Panel
-from bl_ui.properties_physics_common import (basic_force_field_settings_ui,
- basic_force_field_falloff_ui,
- )
+from bl_ui.properties_physics_common import (
+ basic_force_field_settings_ui,
+ basic_force_field_falloff_ui,
+ )
-class PhysicButtonsPanel():
+class PhysicButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"
diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py
index 7b96d784fed..d6fd8f3792c 100644
--- a/release/scripts/startup/bl_ui/properties_physics_fluid.py
+++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py
@@ -29,7 +29,7 @@ class FLUID_MT_presets(Menu):
draw = Menu.draw_preset
-class PhysicButtonsPanel():
+class PhysicButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"
diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
index 5f589c499d3..e7225d73e41 100644
--- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
@@ -21,7 +21,7 @@ import bpy
from bpy.types import Panel
-class PHYSICS_PT_rigidbody_panel():
+class PHYSICS_PT_rigidbody_panel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"
diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
index dcf63f25079..3f5e0f1fc9b 100644
--- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
@@ -21,7 +21,7 @@ import bpy
from bpy.types import Panel
-class PHYSICS_PT_rigidbody_constraint_panel():
+class PHYSICS_PT_rigidbody_constraint_panel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"
diff --git a/release/scripts/startup/bl_ui/properties_physics_smoke.py b/release/scripts/startup/bl_ui/properties_physics_smoke.py
index d2a93e4bd4c..c2a2b3be230 100644
--- a/release/scripts/startup/bl_ui/properties_physics_smoke.py
+++ b/release/scripts/startup/bl_ui/properties_physics_smoke.py
@@ -22,11 +22,13 @@ import os
from copy import deepcopy
from bpy.types import Panel
-from bl_ui.properties_physics_common import (point_cache_ui,
- effector_weights_ui)
+from bl_ui.properties_physics_common import (
+ point_cache_ui,
+ effector_weights_ui,
+ )
-class PhysicButtonsPanel():
+class PhysicButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"
diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py
index 17366f59016..e74cac3d06b 100644
--- a/release/scripts/startup/bl_ui/properties_physics_softbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py
@@ -20,15 +20,17 @@
import bpy
from bpy.types import Panel
-from bl_ui.properties_physics_common import (point_cache_ui,
- effector_weights_ui)
+from bl_ui.properties_physics_common import (
+ point_cache_ui,
+ effector_weights_ui,
+ )
def softbody_panel_enabled(md):
return (md.point_cache.is_baked is False)
-class PhysicButtonsPanel():
+class PhysicButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "physics"
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 9ffd244d78f..b596fe48b49 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -43,7 +43,7 @@ class RENDER_MT_framerate_presets(Menu):
draw = Menu.draw_preset
-class RenderButtonsPanel():
+class RenderButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "render"
diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py
index 2494e49d812..35032d38933 100644
--- a/release/scripts/startup/bl_ui/properties_render_layer.py
+++ b/release/scripts/startup/bl_ui/properties_render_layer.py
@@ -21,7 +21,7 @@ import bpy
from bpy.types import Panel, UIList
-class RenderLayerButtonsPanel():
+class RenderLayerButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "render_layer"
@@ -48,7 +48,7 @@ class RENDERLAYER_UL_renderlayers(UIList):
class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
bl_label = "Layer List"
bl_options = {'HIDE_HEADER'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
def draw(self, context):
layout = self.layout
@@ -56,6 +56,10 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
scene = context.scene
rd = scene.render
+ if rd.engine == 'BLENDER_GAME':
+ layout.label("Not available in the Game Engine")
+ return
+
row = layout.row()
col = row.column()
col.template_list("RENDERLAYER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2)
diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index 049161fdce8..facf54d358a 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -22,9 +22,9 @@ from bpy.types import Panel, UIList
from rna_prop_ui import PropertyPanel
from bl_ui.properties_physics_common import (
- point_cache_ui,
- effector_weights_ui,
- )
+ point_cache_ui,
+ effector_weights_ui,
+ )
class SCENE_UL_keying_set_paths(UIList):
@@ -40,7 +40,7 @@ class SCENE_UL_keying_set_paths(UIList):
layout.label(text="", icon_value=icon)
-class SceneButtonsPanel():
+class SceneButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "scene"
@@ -62,7 +62,8 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel):
layout.prop(scene, "camera")
layout.prop(scene, "background_set", text="Background")
- layout.prop(scene, "active_clip", text="Active Clip")
+ if context.scene.render.engine != 'BLENDER_GAME':
+ layout.prop(scene, "active_clip", text="Active Clip")
class SCENE_PT_unit(SceneButtonsPanel, Panel):
@@ -84,7 +85,53 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel):
row.prop(unit, "use_separate")
-class SCENE_PT_keying_sets(SceneButtonsPanel, Panel):
+class SceneKeyingSetsPanel:
+ def draw_keyframing_settings(self, context, layout, ks, ksp):
+ self.draw_keyframing_setting(context, layout, ks, ksp, "Needed",
+ "use_insertkey_override_needed", "use_insertkey_needed",
+ userpref_fallback="use_keyframe_insert_needed")
+
+ self.draw_keyframing_setting(context, layout, ks, ksp, "Visual",
+ "use_insertkey_override_visual", "use_insertkey_visual",
+ userpref_fallback="use_visual_keying")
+
+ self.draw_keyframing_setting(context, layout, ks, ksp, "XYZ to RGB",
+ "use_insertkey_override_xyz_to_rgb", "use_insertkey_xyz_to_rgb")
+
+ def draw_keyframing_setting(self, context, layout, ks, ksp, label, toggle_prop, prop, userpref_fallback=None):
+ if ksp:
+ item = ksp
+
+ if getattr(ks, toggle_prop):
+ owner = ks
+ propname = prop
+ else:
+ owner = context.user_preferences.edit
+ if userpref_fallback:
+ propname = userpref_fallback
+ else:
+ propname = prop
+ else:
+ item = ks
+
+ owner = context.user_preferences.edit
+ if userpref_fallback:
+ propname = userpref_fallback
+ else:
+ propname = prop
+
+ row = layout.row(align=True)
+ row.prop(item, toggle_prop, text="", icon='STYLUS_PRESSURE', toggle=True) # XXX: needs dedicated icon
+
+ subrow = row.row()
+ subrow.active = getattr(item, toggle_prop)
+ if subrow.active:
+ subrow.prop(item, prop, text=label)
+ else:
+ subrow.prop(owner, propname, text=label)
+
+
+class SCENE_PT_keying_sets(SceneButtonsPanel, SceneKeyingSetsPanel, Panel):
bl_label = "Keying Sets"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -114,10 +161,10 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, Panel):
col = row.column()
col.label(text="Keyframing Settings:")
- col.prop(ks, "bl_options")
+ self.draw_keyframing_settings(context, col, ks, None)
-class SCENE_PT_keying_set_paths(SceneButtonsPanel, Panel):
+class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel):
bl_label = "Active Keying Set"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@@ -170,7 +217,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, Panel):
col = row.column()
col.label(text="Keyframing Settings:")
- col.prop(ksp, "bl_options")
+ self.draw_keyframing_settings(context, col, ks, ksp)
class SCENE_PT_color_management(SceneButtonsPanel, Panel):
@@ -216,10 +263,11 @@ class SCENE_PT_audio(SceneButtonsPanel, Panel):
split = layout.split()
col = split.column()
- col.label("Listener:")
+ col.label("Distance Model:")
col.prop(scene, "audio_distance_model", text="")
- col.prop(scene, "audio_doppler_speed", text="Speed")
- col.prop(scene, "audio_doppler_factor", text="Doppler")
+ sub = col.column(align=True)
+ sub.prop(scene, "audio_doppler_speed", text="Speed")
+ sub.prop(scene, "audio_doppler_factor", text="Doppler")
col = split.column()
col.label("Format:")
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index e491d3a7761..a48e06249fb 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -20,14 +20,16 @@
import bpy
from bpy.types import Menu, Panel, UIList
-from bpy.types import (Brush,
- Lamp,
- Material,
- Object,
- ParticleSettings,
- FreestyleLineStyle,
- Texture,
- World)
+from bpy.types import (
+ Brush,
+ FreestyleLineStyle,
+ Lamp,
+ Material,
+ Object,
+ ParticleSettings,
+ Texture,
+ World,
+ )
from rna_prop_ui import PropertyPanel
@@ -114,7 +116,7 @@ def id_tex_datablock(bid):
return bid
-class TextureButtonsPanel():
+class TextureButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "texture"
@@ -133,8 +135,8 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel):
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
- #if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")):
- #return False
+ # if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")):
+ # return False
return ((context.material or
context.world or
context.lamp or
@@ -172,14 +174,13 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel):
if user or pin_id:
layout.separator()
- split = layout.split(percentage=0.65)
- col = split.column()
+ row = layout.row()
if pin_id:
- col.template_ID(space, "pin_id")
+ row.template_ID(space, "pin_id")
else:
propname = context.texture_user_property.identifier
- col.template_ID(user, propname, new="texture.new")
+ row.template_ID(user, propname, new="texture.new")
if tex:
split = layout.split(percentage=0.2)
@@ -771,6 +772,9 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel, Panel):
elif vd.file_format == 'SMOKE':
layout.prop(vd, "domain_object")
layout.prop(vd, "smoke_data_type")
+ elif vd.file_format == 'HAIR':
+ layout.prop(vd, "domain_object")
+ layout.prop(vd, "hair_data_type")
elif vd.file_format == 'IMAGE_SEQUENCE':
layout.template_ID(tex, "image", open="image.open")
layout.template_image(tex, "image", tex.image_user, compact=True)
@@ -1161,7 +1165,8 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel):
factor_but(col, "use_map_clump", "clump_factor", "Clump")
col = split.column()
- factor_but(col, "use_map_kink", "kink_factor", "Kink")
+ factor_but(col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude")
+ factor_but(col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency")
factor_but(col, "use_map_rough", "rough_factor", "Rough")
elif isinstance(idblock, FreestyleLineStyle):
diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py
index 39a8986a20c..2c8a6fac967 100644
--- a/release/scripts/startup/bl_ui/properties_world.py
+++ b/release/scripts/startup/bl_ui/properties_world.py
@@ -22,7 +22,7 @@ from bpy.types import Panel
from rna_prop_ui import PropertyPanel
-class WorldButtonsPanel():
+class WorldButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "world"
@@ -49,7 +49,6 @@ class WORLD_PT_context_world(WorldButtonsPanel, Panel):
scene = context.scene
world = context.world
space = context.space_data
- rd = context.scene.render
texture_count = world and len(world.texture_slots.keys())
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index d43792bc61d..a9fcdea35c7 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -21,7 +21,11 @@
import bpy
from bpy.types import Panel, Header, Menu, UIList
from bpy.app.translations import pgettext_iface as iface_
-from bl_ui.properties_grease_pencil_common import GreasePencilPanel
+from bl_ui.properties_grease_pencil_common import (
+ GreasePencilDrawingToolsPanel,
+ GreasePencilStrokeEditPanel,
+ GreasePencilDataPanel
+ )
class CLIP_UL_tracking_objects(UIList):
@@ -422,7 +426,9 @@ class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel):
col = layout.column()
row = col.row()
row.prop(settings, "use_tripod_solver", text="Tripod")
- row.prop(settings, "use_keyframe_selection", text="Keyframe")
+ sub = row.row()
+ sub.active = not settings.use_tripod_solver
+ sub.prop(settings, "use_keyframe_selection", text="Keyframe")
col = layout.column(align=True)
col.active = (not settings.use_tripod_solver and
@@ -461,6 +467,7 @@ class CLIP_PT_tools_cleanup(CLIP_PT_tracking_panel, Panel):
layout.prop(settings, "clean_frames", text="Frames")
layout.prop(settings, "clean_error", text="Error")
layout.prop(settings, "clean_action", text="")
+ layout.operator("clip.filter_tracks")
class CLIP_PT_tools_geometry(CLIP_PT_tracking_panel, Panel):
@@ -997,15 +1004,16 @@ class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel):
# -----------------------------------------------------------------------------
# Mask (similar code in space_image.py, keep in sync)
-
-from bl_ui.properties_mask_common import (MASK_PT_mask,
- MASK_PT_layers,
- MASK_PT_spline,
- MASK_PT_point,
- MASK_PT_display,
- MASK_PT_tools,
- MASK_PT_transforms,
- MASK_PT_add)
+from bl_ui.properties_mask_common import (
+ MASK_PT_mask,
+ MASK_PT_layers,
+ MASK_PT_spline,
+ MASK_PT_point,
+ MASK_PT_display,
+ MASK_PT_tools,
+ MASK_PT_transforms,
+ MASK_PT_add,
+ )
class CLIP_PT_mask_layers(MASK_PT_layers, Panel):
@@ -1050,12 +1058,6 @@ class CLIP_PT_tools_mask(MASK_PT_tools, Panel):
# --- end mask ---
-class CLIP_PT_tools_grease_pencil(GreasePencilPanel, Panel):
- bl_space_type = 'CLIP_EDITOR'
- bl_region_type = 'TOOLS'
- bl_category = "Grease Pencil"
-
-
class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel):
bl_space_type = 'CLIP_EDITOR'
bl_region_type = 'UI'
@@ -1110,6 +1112,26 @@ class CLIP_PT_tools_scenesetup(Panel):
layout.operator("clip.setup_tracking_scene")
+# Grease Pencil properties
+class CLIP_PT_grease_pencil(GreasePencilDataPanel, CLIP_PT_clip_view_panel, Panel):
+ bl_space_type = 'CLIP_EDITOR'
+ bl_region_type = 'UI'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ # NOTE: this is just a wrapper around the generic GP Panel
+ # But, this should only be visible in "clip" view
+
+
+# Grease Pencil drawing tools
+class CLIP_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
+ bl_space_type = 'CLIP_EDITOR'
+
+
+# Grease Pencil stroke editing tools
+class CLIP_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
+ bl_space_type = 'CLIP_EDITOR'
+
+
class CLIP_MT_view(Menu):
bl_label = "View"
@@ -1194,14 +1216,17 @@ class CLIP_MT_track(Menu):
layout.operator("clip.solve_camera")
layout.separator()
- layout.operator("clip.clear_track_path",
- text="Clear After").action = 'REMAINED'
+ props = layout.operator("clip.clear_track_path", text="Clear After")
+ props.clear_active = False
+ props.action = 'REMAINED'
- layout.operator("clip.clear_track_path",
- text="Clear Before").action = 'UPTO'
+ props = layout.operator("clip.clear_track_path", text="Clear Before")
+ props.clear_active = False
+ props.action = 'UPTO'
- layout.operator("clip.clear_track_path",
- text="Clear Track Path").action = 'ALL'
+ props = layout.operator("clip.clear_track_path", text="Clear Track Path")
+ props.clear_active = False
+ props.action = 'ALL'
layout.separator()
layout.operator("clip.join_tracks")
@@ -1214,16 +1239,21 @@ class CLIP_MT_track(Menu):
layout.operator("clip.paste_tracks")
layout.separator()
- layout.operator("clip.track_markers",
- text="Track Frame Backwards").backwards = True
+ props = layout.operator("clip.track_markers", text="Track Frame Backwards")
+ props.backwards = True
+ props.sequence = False
props = layout.operator("clip.track_markers", text="Track Backwards")
props.backwards = True
props.sequence = True
- layout.operator("clip.track_markers",
- text="Track Forwards").sequence = True
- layout.operator("clip.track_markers", text="Track Frame Forwards")
+ props = layout.operator("clip.track_markers", text="Track Forwards")
+ props.backwards = False
+ props.sequence = True
+
+ props = layout.operator("clip.track_markers", text="Track Frame Forwards")
+ props.backwards = False
+ props.sequence = False
layout.separator()
layout.operator("clip.delete_track")
@@ -1265,10 +1295,8 @@ class CLIP_MT_track_visibility(Menu):
layout = self.layout
layout.operator("clip.hide_tracks_clear", text="Show Hidden")
- layout.operator("clip.hide_tracks", text="Hide Selected")
-
- layout.operator("clip.hide_tracks",
- text="Hide Unselected").unselected = True
+ layout.operator("clip.hide_tracks", text="Hide Selected").unselected = False
+ layout.operator("clip.hide_tracks", text="Hide Unselected").unselected = True
class CLIP_MT_track_transform(Menu):
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index 79240bbf72a..5358670c2f2 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -91,6 +91,8 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False):
row.prop(dopesheet, "show_speakers", text="")
if bpy.data.linestyles:
row.prop(dopesheet, "show_linestyles", text="")
+ if bpy.data.grease_pencil:
+ row.prop(dopesheet, "show_gpencil", text="")
#######################################
@@ -122,6 +124,10 @@ class DOPESHEET_HT_header(Header):
if st.mode in {'ACTION', 'SHAPEKEY'}:
layout.template_ID(st, "action", new="action.new")
+ row = layout.row(align=True)
+ row.operator("action.push_down", text="Push Down", icon='NLA_PUSHDOWN')
+ row.operator("action.stash", text="Stash", icon='FREEZE')
+
# Grease Pencil mode doesn't need snapping, as it's frame-aligned only
if st.mode != 'GPENCIL':
layout.prop(st, "auto_snap", text="")
@@ -129,6 +135,7 @@ class DOPESHEET_HT_header(Header):
row = layout.row(align=True)
row.operator("action.copy", text="", icon='COPYDOWN')
row.operator("action.paste", text="", icon='PASTEDOWN')
+ row.operator("action.paste", text="", icon='PASTEFLIPDOWN').flipped = True
class DOPESHEET_MT_editor_menus(Menu):
@@ -212,8 +219,12 @@ class DOPESHEET_MT_select(Menu):
layout.operator("action.select_column", text="Between Selected Markers").mode = 'MARKERS_BETWEEN'
layout.separator()
- layout.operator("action.select_leftright", text="Before Current Frame").mode = 'LEFT'
- layout.operator("action.select_leftright", text="After Current Frame").mode = 'RIGHT'
+ props = layout.operator("action.select_leftright", text="Before Current Frame")
+ props.extend = False
+ props.mode = 'LEFT'
+ props = layout.operator("action.select_leftright", text="After Current Frame")
+ props.extend = False
+ props.mode = 'RIGHT'
# FIXME: grease pencil mode isn't supported for these yet, so skip for that mode only
if context.space_data.mode != 'GPENCIL':
@@ -365,14 +376,16 @@ class DOPESHEET_MT_gpencil_frame(Menu):
layout = self.layout
layout.menu("DOPESHEET_MT_key_transform", text="Transform")
-
- #layout.operator_menu_enum("action.snap", "type", text="Snap")
- #layout.operator_menu_enum("action.mirror", "type", text="Mirror")
+ layout.operator_menu_enum("action.snap", "type", text="Snap")
+ layout.operator_menu_enum("action.mirror", "type", text="Mirror")
layout.separator()
layout.operator("action.duplicate")
layout.operator("action.delete")
+ layout.separator()
+ layout.operator("action.keyframe_type")
+
#layout.separator()
#layout.operator("action.copy")
#layout.operator("action.paste")
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py
index b90eb7a89c3..841e169b080 100644
--- a/release/scripts/startup/bl_ui/space_filebrowser.py
+++ b/release/scripts/startup/bl_ui/space_filebrowser.py
@@ -18,7 +18,7 @@
# <pep8 compliant>
import bpy
-from bpy.types import Header
+from bpy.types import Header, Panel, Menu
class FILEBROWSER_HT_header(Header):
@@ -55,7 +55,7 @@ class FILEBROWSER_HT_header(Header):
layout.prop(params, "display_type", expand=True, text="")
layout.prop(params, "sort_method", expand=True, text="")
- layout.prop(params, "show_hidden")
+ layout.prop(params, "show_hidden", text="", icon='FILE_HIDDEN')
layout.prop(params, "use_filter", text="", icon='FILTER')
row = layout.row(align=True)
@@ -77,5 +77,137 @@ class FILEBROWSER_HT_header(Header):
row.prop(params, "use_filter_sound", text="")
row.prop(params, "use_filter_text", text="")
+ row.separator()
+ row.prop(params, "filter_search", text="", icon='VIEWZOOM')
+
+
+class FILEBROWSER_UL_dir(bpy.types.UIList):
+ def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
+ direntry = item
+ space = context.space_data
+ icon = 'NONE'
+ if active_propname == "system_folders_active":
+ icon = 'DISK_DRIVE'
+ if active_propname == "system_bookmarks_active":
+ icon = 'BOOKMARKS'
+ if active_propname == "bookmarks_active":
+ icon = 'BOOKMARKS'
+ if active_propname == "recent_folders_active":
+ icon = 'FILE_FOLDER'
+
+ if self.layout_type in {'DEFAULT', 'COMPACT'}:
+ row = layout.row(align=True)
+ row.enabled = direntry.is_valid
+ # Non-editable entries would show grayed-out, which is bad in this specific case, so switch to mere label.
+ if direntry.is_property_readonly('name'):
+ row.label(text=direntry.name, icon=icon)
+ else:
+ row.prop(direntry, "name", text="", emboss=False, icon=icon)
+
+ elif self.layout_type in {'GRID'}:
+ layout.alignment = 'CENTER'
+ layout.prop(direntry, "path", text="")
+
+
+class FILEBROWSER_PT_system_folders(Panel):
+ bl_space_type = 'FILE_BROWSER'
+ bl_region_type = 'TOOLS'
+ bl_category = "Bookmarks"
+ bl_label = "System"
+
+ def draw(self, context):
+ layout = self.layout
+ space = context.space_data
+
+ if space.system_folders:
+ row = layout.row()
+ row.template_list("FILEBROWSER_UL_dir", "system_folders", space, "system_folders",
+ space, "system_folders_active", item_dyntip_propname="path", rows=1, maxrows=10)
+
+class FILEBROWSER_PT_system_bookmarks(Panel):
+ bl_space_type = 'FILE_BROWSER'
+ bl_region_type = 'TOOLS'
+ bl_category = "Bookmarks"
+ bl_label = "System Bookmarks"
+
+ @classmethod
+ def poll(cls, context):
+ return not context.user_preferences.filepaths.hide_system_bookmarks
+
+ def draw(self, context):
+ layout = self.layout
+ space = context.space_data
+
+ if space.system_bookmarks:
+ row = layout.row()
+ row.template_list("FILEBROWSER_UL_dir", "system_bookmarks", space, "system_bookmarks",
+ space, "system_bookmarks_active", item_dyntip_propname="path", rows=1, maxrows=10)
+
+
+class FILEBROWSER_MT_bookmarks_specials(Menu):
+ bl_label = "Bookmarks Specials"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator("file.bookmark_cleanup", icon='X', text="Cleanup")
+
+ layout.separator()
+ layout.operator("file.bookmark_move", icon='TRIA_UP_BAR', text="Move To Top").direction = 'TOP'
+ layout.operator("file.bookmark_move", icon='TRIA_DOWN_BAR', text="Move To Bottom").direction = 'BOTTOM'
+
+
+class FILEBROWSER_PT_bookmarks(Panel):
+ bl_space_type = 'FILE_BROWSER'
+ bl_region_type = 'TOOLS'
+ bl_category = "Bookmarks"
+ bl_label = "Bookmarks"
+
+ def draw(self, context):
+ layout = self.layout
+ space = context.space_data
+
+ if space.bookmarks:
+ row = layout.row()
+ num_rows = len(space.bookmarks)
+ row.template_list("FILEBROWSER_UL_dir", "bookmarks", space, "bookmarks",
+ space, "bookmarks_active", item_dyntip_propname="path",
+ rows=(2 if num_rows < 2 else 4), maxrows=10)
+
+ col = row.column(align=True)
+ col.operator("file.bookmark_add", icon='ZOOMIN', text="")
+ col.operator("file.bookmark_delete", icon='ZOOMOUT', text="")
+ col.menu("FILEBROWSER_MT_bookmarks_specials", icon='DOWNARROW_HLT', text="")
+
+ if num_rows > 1:
+ col.separator()
+ col.operator("file.bookmark_move", icon='TRIA_UP', text="").direction = 'UP'
+ col.operator("file.bookmark_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
+ else:
+ layout.operator("file.bookmark_add", icon='ZOOMIN')
+
+
+class FILEBROWSER_PT_recent_folders(Panel):
+ bl_space_type = 'FILE_BROWSER'
+ bl_region_type = 'TOOLS'
+ bl_category = "Bookmarks"
+ bl_label = "Recent"
+
+ @classmethod
+ def poll(cls, context):
+ return not context.user_preferences.filepaths.hide_recent_locations
+
+ def draw(self, context):
+ layout = self.layout
+ space = context.space_data
+
+ if space.recent_folders:
+ row = layout.row()
+ row.template_list("FILEBROWSER_UL_dir", "recent_folders", space, "recent_folders",
+ space, "recent_folders_active", item_dyntip_propname="path", rows=1, maxrows=10)
+
+ col = row.column(align=True)
+ col.operator("file.reset_recent", icon='X', text="")
+
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index 6fc3d9e4f2b..d3e1a866e43 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -52,6 +52,7 @@ class GRAPH_HT_header(Header):
row = layout.row(align=True)
row.operator("graph.copy", text="", icon='COPYDOWN')
row.operator("graph.paste", text="", icon='PASTEDOWN')
+ row.operator("graph.paste", text="", icon='PASTEFLIPDOWN').flipped = True
row = layout.row(align=True)
if st.has_ghost_curves:
@@ -133,9 +134,15 @@ class GRAPH_MT_select(Menu):
layout.operator("graph.select_all_toggle", text="Invert Selection").invert = True
layout.separator()
- layout.operator("graph.select_border")
- layout.operator("graph.select_border", text="Border Axis Range").axis_range = True
- layout.operator("graph.select_border", text="Border (Include Handles)").include_handles = True
+ props = layout.operator("graph.select_border")
+ props.axis_range = False
+ props.include_handles = False
+ props = layout.operator("graph.select_border", text="Border Axis Range")
+ props.axis_range = True
+ props.include_handles = False
+ props = layout.operator("graph.select_border", text="Border (Include Handles)")
+ props.axis_range = False
+ props.include_handles = True
layout.separator()
layout.operator("graph.select_column", text="Columns on Selected Keys").mode = 'KEYS'
@@ -145,8 +152,12 @@ class GRAPH_MT_select(Menu):
layout.operator("graph.select_column", text="Between Selected Markers").mode = 'MARKERS_BETWEEN'
layout.separator()
- layout.operator("graph.select_leftright", text="Before Current Frame").mode = 'LEFT'
- layout.operator("graph.select_leftright", text="After Current Frame").mode = 'RIGHT'
+ props = layout.operator("graph.select_leftright", text="Before Current Frame")
+ props.extend = False
+ props.mode = 'LEFT'
+ props = layout.operator("graph.select_leftright", text="After Current Frame")
+ props.extend = False
+ props.mode = 'RIGHT'
layout.separator()
layout.operator("graph.select_more")
@@ -189,10 +200,14 @@ class GRAPH_MT_channel(Menu):
layout.separator()
layout.operator("anim.channels_editable_toggle")
- layout.operator("anim.channels_visibility_set")
layout.operator_menu_enum("graph.extrapolation_type", "type", text="Extrapolation Mode")
layout.separator()
+ layout.operator("graph.hide", text="Hide Selected Curves").unselected = False
+ layout.operator("graph.hide", text="Hide Unselected Curves").unselected = True
+ layout.operator("graph.reveal")
+
+ layout.separator()
layout.operator("anim.channels_expand")
layout.operator("anim.channels_collapse")
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index bdb0ca7aa15..a75e0916c09 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -25,7 +25,11 @@ from bl_ui.properties_paint_common import (
brush_texpaint_common,
brush_mask_texture_settings,
)
-from bl_ui.properties_grease_pencil_common import GreasePencilPanel
+from bl_ui.properties_grease_pencil_common import (
+ GreasePencilDrawingToolsPanel,
+ GreasePencilStrokeEditPanel,
+ GreasePencilDataPanel,
+ )
from bpy.app.translations import pgettext_iface as iface_
@@ -82,6 +86,7 @@ class IMAGE_MT_view(Menu):
layout.prop(uv, "show_other_objects")
if paint.brush and (context.image_paint_object or sima.mode == 'PAINT'):
layout.prop(uv, "show_texpaint")
+ layout.prop(toolsettings, "show_uv_local_view", text="Show same material")
layout.separator()
@@ -131,7 +136,7 @@ class IMAGE_MT_select(Menu):
layout.separator()
layout.operator("uv.select_pinned")
- layout.operator("uv.select_linked")
+ layout.operator("uv.select_linked").extend = False
layout.separator()
@@ -510,12 +515,14 @@ class MASK_MT_editor_menus(Menu):
# Mask (similar code in space_clip.py, keep in sync)
# note! - panel placement does _not_ fit well with image panels... need to fix
-from bl_ui.properties_mask_common import (MASK_PT_mask,
- MASK_PT_layers,
- MASK_PT_spline,
- MASK_PT_point,
- MASK_PT_display,
- MASK_PT_tools)
+from bl_ui.properties_mask_common import (
+ MASK_PT_mask,
+ MASK_PT_layers,
+ MASK_PT_spline,
+ MASK_PT_point,
+ MASK_PT_display,
+ MASK_PT_tools,
+ )
class IMAGE_PT_mask(MASK_PT_mask, Panel):
@@ -1037,17 +1044,27 @@ class IMAGE_PT_tools_mask(MASK_PT_tools, Panel):
# --- end mask ---
-class IMAGE_PT_view_histogram(Panel):
+class ImageScopesPanel:
+ @classmethod
+ def poll(cls, context):
+ sima = context.space_data
+ if not (sima and sima.image):
+ return False
+ # scopes are not updated in paint modes, hide
+ if sima.mode in {'PAINT'}:
+ return False
+ ob = context.active_object
+ if ob and ob.mode in {'TEXTURE_PAINT'}:
+ return False
+ return True
+
+
+class IMAGE_PT_view_histogram(ImageScopesPanel, Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'TOOLS'
bl_label = "Histogram"
bl_category = "Scopes"
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return (sima and sima.image)
-
def draw(self, context):
layout = self.layout
@@ -1060,17 +1077,12 @@ class IMAGE_PT_view_histogram(Panel):
row.prop(hist, "show_line", text="")
-class IMAGE_PT_view_waveform(Panel):
+class IMAGE_PT_view_waveform(ImageScopesPanel, Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'TOOLS'
bl_label = "Waveform"
bl_category = "Scopes"
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return (sima and sima.image)
-
def draw(self, context):
layout = self.layout
@@ -1082,17 +1094,12 @@ class IMAGE_PT_view_waveform(Panel):
row.prop(sima.scopes, "waveform_mode", text="")
-class IMAGE_PT_view_vectorscope(Panel):
+class IMAGE_PT_view_vectorscope(ImageScopesPanel, Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'TOOLS'
bl_label = "Vectorscope"
bl_category = "Scopes"
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return (sima and sima.image)
-
def draw(self, context):
layout = self.layout
@@ -1101,17 +1108,12 @@ class IMAGE_PT_view_vectorscope(Panel):
layout.prop(sima.scopes, "vectorscope_alpha")
-class IMAGE_PT_sample_line(Panel):
+class IMAGE_PT_sample_line(ImageScopesPanel, Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'TOOLS'
bl_label = "Sample Line"
bl_category = "Scopes"
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return (sima and sima.image)
-
def draw(self, context):
layout = self.layout
@@ -1125,17 +1127,12 @@ class IMAGE_PT_sample_line(Panel):
row.prop(hist, "show_line", text="")
-class IMAGE_PT_scope_sample(Panel):
+class IMAGE_PT_scope_sample(ImageScopesPanel, Panel):
bl_space_type = 'IMAGE_EDITOR'
bl_region_type = 'TOOLS'
bl_label = "Scope Samples"
bl_category = "Scopes"
- @classmethod
- def poll(cls, context):
- sima = context.space_data
- return sima
-
def draw(self, context):
layout = self.layout
@@ -1148,10 +1145,22 @@ class IMAGE_PT_scope_sample(Panel):
sub.prop(sima.scopes, "accuracy")
-class IMAGE_PT_tools_grease_pencil(GreasePencilPanel, Panel):
+# Grease Pencil properties
+class IMAGE_PT_grease_pencil(GreasePencilDataPanel, Panel):
+ bl_space_type = 'IMAGE_EDITOR'
+ bl_region_type = 'UI'
+
+ # NOTE: this is just a wrapper around the generic GP Panel
+
+
+# Grease Pencil drawing tools
+class IMAGE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
+ bl_space_type = 'IMAGE_EDITOR'
+
+
+# Grease Pencil stroke editing tools
+class IMAGE_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
bl_space_type = 'IMAGE_EDITOR'
- bl_region_type = 'TOOLS'
- bl_category = "Grease Pencil"
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 67b2bbe1905..927967c8bc6 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -57,12 +57,15 @@ class INFO_HT_header(Header):
row = layout.row(align=True)
if bpy.app.autoexec_fail is True and bpy.app.autoexec_fail_quiet is False:
- row.label("Auto-run disabled: %s" % bpy.app.autoexec_fail_message, icon='ERROR')
+ row.label("Auto-run disabled", icon='ERROR')
if bpy.data.is_saved:
props = row.operator("wm.revert_mainfile", icon='SCREEN_BACK', text="Reload Trusted")
props.use_scripts = True
row.operator("script.autoexec_warn_clear", text="Ignore")
+
+ # include last so text doesn't push buttons out of the header
+ row.label(bpy.app.autoexec_fail_message)
return
row.operator("wm.splash", text="", icon='BLENDER', emboss=False)
@@ -129,6 +132,7 @@ class INFO_MT_file(Menu):
layout.operator_context = 'INVOKE_AREA'
layout.operator("wm.link", text="Link", icon='LINK_BLEND')
layout.operator("wm.append", text="Append", icon='APPEND_BLEND')
+ layout.menu("INFO_MT_file_previews")
layout.separator()
@@ -192,6 +196,15 @@ class INFO_MT_file_external_data(Menu):
layout.operator("file.find_missing_files")
+class INFO_MT_file_previews(Menu):
+ bl_label = "Data Previews"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("wm.previews_ensure")
+
+
class INFO_MT_game(Menu):
bl_label = "Game"
@@ -262,8 +275,8 @@ class INFO_MT_window(Menu):
layout.separator()
- layout.operator("screen.screenshot").full = True
- layout.operator("screen.screencast").full = True
+ layout.operator("screen.screenshot")
+ layout.operator("screen.screencast")
if sys.platform[:3] == "win":
layout.separator()
@@ -276,7 +289,7 @@ class INFO_MT_help(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("wm.url_open", text="Manual", icon='HELP').url = "http://wiki.blender.org/index.php/Doc:2.6/Manual"
+ layout.operator("wm.url_open", text="Manual", icon='HELP').url = "http://www.blender.org/manual"
layout.operator("wm.url_open", text="Release Log", icon='URL').url = "http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/%d.%d" % bpy.app.version[:2]
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py
index b748e904f31..ae432c44bf6 100644
--- a/release/scripts/startup/bl_ui/space_nla.py
+++ b/release/scripts/startup/bl_ui/space_nla.py
@@ -108,8 +108,12 @@ class NLA_MT_select(Menu):
layout.operator("nla.select_border", text="Border Axis Range").axis_range = True
layout.separator()
- layout.operator("nla.select_leftright", text="Before Current Frame").mode = 'LEFT'
- layout.operator("nla.select_leftright", text="After Current Frame").mode = 'RIGHT'
+ props = layout.operator("nla.select_leftright", text="Before Current Frame")
+ props.extend = False
+ props.mode = 'LEFT'
+ props = layout.operator("nla.select_leftright", text="After Current Frame")
+ props.extend = False
+ props.mode = 'RIGHT'
class NLA_MT_marker(Menu):
@@ -135,7 +139,7 @@ class NLA_MT_edit(Menu):
layout.operator_menu_enum("nla.snap", "type", text="Snap")
layout.separator()
- layout.operator("nla.duplicate", text="Duplicate")
+ layout.operator("nla.duplicate", text="Duplicate").linked = False
layout.operator("nla.duplicate", text="Linked Duplicate").linked = True
layout.operator("nla.split")
layout.operator("nla.delete")
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 17eeeec2480..a5ab6898b13 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -19,6 +19,12 @@
# <pep8 compliant>
import bpy
from bpy.types import Header, Menu, Panel
+from bl_ui.properties_grease_pencil_common import (
+ GreasePencilDrawingToolsPanel,
+ GreasePencilStrokeEditPanel,
+ GreasePencilDataPanel,
+ GreasePencilToolsPanel,
+ )
class NODE_HT_header(Header):
@@ -190,7 +196,7 @@ class NODE_MT_select(Menu):
def draw(self, context):
layout = self.layout
- layout.operator("node.select_border")
+ layout.operator("node.select_border").tweak = False
layout.operator("node.select_circle")
layout.separator()
@@ -201,7 +207,7 @@ class NODE_MT_select(Menu):
layout.separator()
- layout.operator("node.select_grouped")
+ layout.operator("node.select_grouped").extend = False
layout.operator("node.select_same_type_step").prev = True
layout.operator("node.select_same_type_step").prev = False
@@ -233,14 +239,14 @@ class NODE_MT_node(Menu):
layout.separator()
- layout.operator("node.link_make")
+ layout.operator("node.link_make").replace = False
layout.operator("node.link_make", text="Make and Replace Links").replace = True
layout.operator("node.links_cut")
layout.operator("node.links_detach")
layout.separator()
- layout.operator("node.group_edit")
+ layout.operator("node.group_edit").exit = False
layout.operator("node.group_ungroup")
layout.operator("node.group_make")
layout.operator("node.group_insert")
@@ -439,6 +445,46 @@ class NODE_UL_interface_sockets(bpy.types.UIList):
layout.template_node_socket(color)
+# Grease Pencil properties
+class NODE_PT_grease_pencil(GreasePencilDataPanel, Panel):
+ bl_space_type = 'NODE_EDITOR'
+ bl_region_type = 'UI'
+
+ # NOTE: this is just a wrapper around the generic GP Panel
+
+ @classmethod
+ def poll(cls, context):
+ snode = context.space_data
+ return snode is not None and snode.node_tree is not None
+
+
+class NODE_PT_grease_pencil_tools(GreasePencilToolsPanel, Panel):
+ bl_space_type = 'NODE_EDITOR'
+ bl_region_type = 'UI'
+ bl_options = {'DEFAULT_CLOSED'}
+
+ # NOTE: this is just a wrapper around the generic GP tools panel
+ # It contains access to some essential tools usually found only in
+ # toolbar, but which may not necessarily be open
+
+
+# Tool Shelf ------------------
+
+
+# Grease Pencil drawing tools
+class NODE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
+ bl_space_type = 'NODE_EDITOR'
+ bl_region_type = 'TOOLS'
+
+
+# Grease Pencil stroke editing tools
+class NODE_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
+ bl_space_type = 'NODE_EDITOR'
+ bl_region_type = 'TOOLS'
+
+# -----------------------------
+
+
def node_draw_tree_view(layout, context):
pass
diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index 7b508c067e1..7b1dfb9579a 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -57,6 +57,8 @@ class OUTLINER_HT_header(Header):
else:
row = layout.row()
row.label(text="No Keying Set active")
+ elif space.display_mode == 'ORPHAN_DATA':
+ layout.operator("outliner.orphans_purge")
class OUTLINER_MT_editor_menus(Menu):
@@ -86,6 +88,7 @@ class OUTLINER_MT_view(Menu):
space = context.space_data
if space.display_mode not in {'DATABLOCKS', 'USER_PREFERENCES', 'KEYMAPS'}:
+ layout.prop(space, "use_sort_alpha")
layout.prop(space, "show_restrict_columns")
layout.separator()
layout.operator("outliner.show_active")
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 2f90dae2782..0be1bf0b90a 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -19,6 +19,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Header, Menu, Panel
+from bl_ui.properties_grease_pencil_common import GreasePencilDataPanel, GreasePencilToolsPanel
from bpy.app.translations import pgettext_iface as iface_
@@ -82,6 +83,7 @@ class SEQUENCER_HT_header(Header):
layout.separator()
layout.operator("sequencer.refresh_all")
+ layout.prop(st, "show_backdrop")
else:
if st.view_type == 'SEQUENCER_PREVIEW':
layout.separator()
@@ -101,6 +103,17 @@ class SEQUENCER_HT_header(Header):
row = layout.row()
row.prop(st, "overlay_type", text="")
+ if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
+ gpd = context.gpencil_data
+ toolsettings = context.tool_settings
+
+ # Proportional editing
+ if gpd and gpd.use_stroke_edit_mode:
+ row = layout.row(align=True)
+ row.prop(toolsettings, "proportional_edit", icon_only=True)
+ if toolsettings.proportional_edit != 'DISABLED':
+ row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
+
row = layout.row(align=True)
row.operator("render.opengl", text="", icon='RENDER_STILL').sequencer = True
props = row.operator("render.opengl", text="", icon='RENDER_ANIMATION')
@@ -149,8 +162,10 @@ class SEQUENCER_MT_view(Menu):
layout = self.layout
st = context.space_data
+ is_preview = st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}
+ is_sequencer_view = st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}
- if st.view_type in {'PREVIEW'}:
+ if st.view_type == 'PREVIEW':
# Specifying the REGION_PREVIEW context is needed in preview-only
# mode, else the lookup for the shortcut will fail in
# wm_keymap_item_find_props() (see #32595).
@@ -160,10 +175,10 @@ class SEQUENCER_MT_view(Menu):
layout.separator()
- if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
+ if is_sequencer_view:
layout.operator("sequencer.view_all", text="View all Sequences")
layout.operator("sequencer.view_selected")
- if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
+ if is_preview:
layout.operator_context = 'INVOKE_REGION_PREVIEW'
layout.operator("sequencer.view_all_preview", text="Fit preview in window")
@@ -181,19 +196,22 @@ class SEQUENCER_MT_view(Menu):
# # XXX, invokes in the header view
# layout.operator("sequencer.view_ghost_border", text="Overlay Border")
- if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
+ if is_sequencer_view:
layout.prop(st, "show_seconds")
layout.prop(st, "show_frame_indicator")
+ layout.prop(st, "show_strip_offset")
- if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
+ layout.prop_menu_enum(st, "waveform_draw_type")
+
+ if is_preview:
if st.display_mode == 'IMAGE':
- layout.prop(st, "show_safe_margin")
+ layout.prop(st, "show_safe_areas")
elif st.display_mode == 'WAVEFORM':
layout.prop(st, "show_separate_color")
layout.separator()
- if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
+ if is_sequencer_view:
layout.prop(st, "use_marker_sync")
layout.separator()
@@ -330,7 +348,7 @@ class SEQUENCER_MT_strip(Menu):
layout.operator("transform.transform", text="Grab/Move").mode = 'TRANSLATION'
layout.operator("transform.transform", text="Grab/Extend from frame").mode = 'TIME_EXTEND'
- layout.operator("sequencer.gap_remove")
+ layout.operator("sequencer.gap_remove").all = False
layout.operator("sequencer.gap_insert")
# uiItemO(layout, NULL, 0, "sequencer.strip_snap"); // TODO - add this operator
@@ -338,7 +356,7 @@ class SEQUENCER_MT_strip(Menu):
layout.operator("sequencer.cut", text="Cut (hard) at frame").type = 'HARD'
layout.operator("sequencer.cut", text="Cut (soft) at frame").type = 'SOFT'
- layout.operator("sequencer.trim", text="Trim Contents")
+ layout.operator("sequencer.slip", text="Slip Strip Contents")
layout.operator("sequencer.images_separate")
layout.operator("sequencer.offset_clear")
layout.operator("sequencer.deinterlace_selected_movies")
@@ -386,7 +404,7 @@ class SEQUENCER_MT_strip(Menu):
#}
layout.separator()
- layout.operator("sequencer.reload", text="Reload Strips").adjust_length = False
+ layout.operator("sequencer.reload", text="Reload Strips")
layout.operator("sequencer.reload", text="Reload Strips and Adjust Length").adjust_length = True
layout.operator("sequencer.reassign_inputs")
layout.operator("sequencer.swap_inputs")
@@ -395,7 +413,7 @@ class SEQUENCER_MT_strip(Menu):
layout.operator("sequencer.lock")
layout.operator("sequencer.unlock")
layout.operator("sequencer.mute").unselected = False
- layout.operator("sequencer.unmute")
+ layout.operator("sequencer.unmute").unselected = False
layout.operator("sequencer.mute", text="Mute Deselected Strips").unselected = True
@@ -409,7 +427,7 @@ class SEQUENCER_MT_strip(Menu):
layout.menu("SEQUENCER_MT_change")
-class SequencerButtonsPanel():
+class SequencerButtonsPanel:
bl_space_type = 'SEQUENCE_EDITOR'
bl_region_type = 'UI'
@@ -422,13 +440,14 @@ class SequencerButtonsPanel():
return cls.has_sequencer(context) and (act_strip(context) is not None)
-class SequencerButtonsPanel_Output():
+class SequencerButtonsPanel_Output:
bl_space_type = 'SEQUENCE_EDITOR'
bl_region_type = 'UI'
@staticmethod
def has_preview(context):
- return (context.space_data.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'})
+ st = context.space_data
+ return (st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}) or st.show_backdrop
@classmethod
def poll(cls, context):
@@ -716,6 +735,7 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ st = context.space_data
strip = act_strip(context)
sound = strip.sound
@@ -734,7 +754,9 @@ class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
row.prop(sound, "use_memory_cache")
- layout.prop(strip, "show_waveform")
+ if st.waveform_draw_type == 'DEFAULT_WAVEFORMS':
+ layout.prop(strip, "show_waveform")
+
layout.prop(strip, "volume")
layout.prop(strip, "pitch")
layout.prop(strip, "pan")
@@ -776,6 +798,8 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
layout.label(text="Camera Override")
layout.template_ID(strip, "scene_camera")
+ layout.prop(strip, "use_grease_pencil", text="Show Grease Pencil")
+
if scene:
layout.prop(scene, "audio_volume", text="Audio Volume")
@@ -900,11 +924,23 @@ class SEQUENCER_PT_proxy(SequencerButtonsPanel, Panel):
if strip.use_proxy_custom_file:
flow.prop(strip.proxy, "filepath")
+ layout.label("Enabled Proxies:")
+ enabled = ""
row = layout.row()
- row.prop(strip.proxy, "build_25")
- row.prop(strip.proxy, "build_50")
- row.prop(strip.proxy, "build_75")
- row.prop(strip.proxy, "build_100")
+ if (strip.proxy.build_25):
+ enabled += "25% "
+ if (strip.proxy.build_50):
+ enabled += "50% "
+ if (strip.proxy.build_75):
+ enabled += "75% "
+ if (strip.proxy.build_100):
+ enabled += "100% "
+
+ row.label(enabled)
+ if (strip.proxy.use_overwrite):
+ layout.label("Overwrite On")
+ else:
+ layout.label("Overwrite Off")
col = layout.column()
col.label(text="Build JPEG quality")
@@ -916,6 +952,10 @@ class SEQUENCER_PT_proxy(SequencerButtonsPanel, Panel):
col.prop(strip.proxy, "timecode")
+ col = layout.column()
+ col.operator("sequencer.enable_proxies")
+ col.operator("sequencer.rebuild_proxy")
+
class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel):
bl_label = "Scene Preview/Render"
@@ -949,12 +989,41 @@ class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel):
col = layout.column()
if st.display_mode == 'IMAGE':
col.prop(st, "draw_overexposed")
- col.prop(st, "show_safe_margin")
+ col.separator()
+
elif st.display_mode == 'WAVEFORM':
col.prop(st, "show_separate_color")
+
+ col = layout.column()
+ col.separator()
col.prop(st, "proxy_render_size")
+class SEQUENCER_PT_view_safe_areas(SequencerButtonsPanel_Output, Panel):
+ bl_label = "Safe Areas"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ st = context.space_data
+ is_preview = st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}
+ return is_preview and (st.display_mode == 'IMAGE')
+
+ def draw_header(self, context):
+ st = context.space_data
+
+ self.layout.prop(st, "show_safe_areas", text="")
+
+ def draw(self, context):
+ from bl_ui.properties_data_camera import draw_display_safe_settings
+
+ layout = self.layout
+ st = context.space_data
+ safe_data = context.scene.safe_areas
+
+ draw_display_safe_settings(layout, safe_data, st)
+
+
class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
bl_label = "Modifiers"
@@ -1012,5 +1081,22 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
col.prop(mod, "contrast")
+class SEQUENCER_PT_grease_pencil(GreasePencilDataPanel, SequencerButtonsPanel_Output, Panel):
+ bl_space_type = 'SEQUENCE_EDITOR'
+ bl_region_type = 'UI'
+
+ # NOTE: this is just a wrapper around the generic GP Panel
+ # But, it should only show up when there are images in the preview region
+
+
+class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsPanel_Output, Panel):
+ bl_space_type = 'SEQUENCE_EDITOR'
+ bl_region_type = 'UI'
+
+ # NOTE: this is just a wrapper around the generic GP tools panel
+ # It contains access to some essential tools usually found only in
+ # toolbar, which doesn't exist here...
+
+
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py
index d23ee84d9d2..27fcf94666a 100644
--- a/release/scripts/startup/bl_ui/space_time.py
+++ b/release/scripts/startup/bl_ui/space_time.py
@@ -207,6 +207,8 @@ class TIME_MT_playback(Menu):
layout.prop(screen, "use_play_clip_editors")
layout.separator()
+ layout.prop(screen, "use_follow")
+ layout.separator()
layout.prop(scene, "use_frame_drop", text="Frame Dropping")
layout.prop(scene, "use_audio_sync", text="AV-sync", icon='SPEAKER')
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index a7ddec040a5..3b17e40c294 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -120,6 +120,14 @@ class USERPREF_MT_splash(Menu):
row.menu("USERPREF_MT_appconfigs", text="Preset")
+# only for addons
+class USERPREF_MT_splash_footer(Menu):
+ bl_label = ""
+
+ def draw(self, context):
+ pass
+
+
class USERPREF_PT_interface(Panel):
bl_space_type = 'USER_PREFERENCES'
bl_label = "Interface"
@@ -162,6 +170,12 @@ class USERPREF_PT_interface(Panel):
sub.prop(view, "mini_axis_brightness", text="Brightness")
col.separator()
+
+ if sys.platform[:3] == "win":
+ col.label("Warnings")
+ col.prop(view, "use_quit_dialog")
+ col.prop(view, "use_gl_warn_support")
+
row.separator()
row.separator()
@@ -230,9 +244,6 @@ class USERPREF_PT_interface(Panel):
col.prop(view, "show_splash")
- if sys.platform[:3] == "win":
- col.prop(view, "use_quit_dialog")
-
class USERPREF_PT_edit(Panel):
bl_space_type = 'USER_PREFERENCES'
@@ -744,7 +755,7 @@ class USERPREF_PT_theme(Panel):
col.separator()
col.separator()
- col.label("Menu Shadow:")
+ col.label("Styles:")
row = col.row()
@@ -762,11 +773,6 @@ class USERPREF_PT_theme(Panel):
colsub = padding.column()
colsub.row().prop(ui, "menu_shadow_width")
- col.separator()
- col.separator()
-
- col.label("Icons:")
-
row = col.row()
subsplit = row.split(percentage=0.95)
@@ -774,16 +780,14 @@ class USERPREF_PT_theme(Panel):
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
- # Not working yet.
- #~ colsub.active = False
- #~ colsub.row().prop(ui, "icon_file")
+ colsub.row().prop(ui, "icon_alpha")
subsplit = row.split(percentage=0.85)
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
- colsub.row().prop(ui, "icon_alpha")
+ colsub.row().prop(ui, "widget_emboss")
col.separator()
col.separator()
@@ -1167,7 +1171,7 @@ class USERPREF_MT_addons_dev_guides(Menu):
class USERPREF_PT_addons(Panel):
bl_space_type = 'USER_PREFERENCES'
- bl_label = "Addons"
+ bl_label = "Add-ons"
bl_region_type = 'WINDOW'
bl_options = {'HIDE_HEADER'}
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 0ea552e51e7..c65cebfde10 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -19,6 +19,7 @@
# <pep8 compliant>
import bpy
from bpy.types import Header, Menu, Panel
+from bl_ui.properties_grease_pencil_common import GreasePencilDataPanel
from bl_ui.properties_paint_common import UnifiedPaintPanel
from bpy.app.translations import contexts as i18n_contexts
@@ -56,7 +57,12 @@ class VIEW3D_HT_header(Header):
row.prop(view, "use_occlude_geometry", text="")
# Proportional editing
- if mode in {'EDIT', 'PARTICLE_EDIT'}:
+ if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
+ row = layout.row(align=True)
+ row.prop(toolsettings, "proportional_edit", icon_only=True)
+ if toolsettings.proportional_edit != 'DISABLED':
+ row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
+ elif mode in {'EDIT', 'PARTICLE_EDIT'}:
row = layout.row(align=True)
row.prop(toolsettings, "proportional_edit", icon_only=True)
if toolsettings.proportional_edit != 'DISABLED':
@@ -66,6 +72,13 @@ class VIEW3D_HT_header(Header):
row.prop(toolsettings, "use_proportional_edit_objects", icon_only=True)
if toolsettings.use_proportional_edit_objects:
row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
+ else:
+ # Proportional editing
+ if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
+ row = layout.row(align=True)
+ row.prop(toolsettings, "proportional_edit", icon_only=True)
+ if toolsettings.proportional_edit != 'DISABLED':
+ row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
# Snap
if not obj or mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT'}:
@@ -100,8 +113,8 @@ class VIEW3D_HT_header(Header):
if obj and mode == 'POSE':
row = layout.row(align=True)
row.operator("pose.copy", text="", icon='COPYDOWN')
- row.operator("pose.paste", text="", icon='PASTEDOWN')
- row.operator("pose.paste", text="", icon='PASTEFLIPDOWN').flipped = 1
+ row.operator("pose.paste", text="", icon='PASTEDOWN').flipped = False
+ row.operator("pose.paste", text="", icon='PASTEFLIPDOWN').flipped = True
class VIEW3D_MT_editor_menus(Menu):
@@ -161,7 +174,7 @@ class VIEW3D_MT_editor_menus(Menu):
# ********** Utilities **********
-class ShowHideMenu():
+class ShowHideMenu:
bl_label = "Show/Hide"
_operator_name = ""
@@ -401,7 +414,7 @@ class VIEW3D_MT_view(Menu):
layout.operator("view3d.clip_border", text="Clipping Border...")
layout.operator("view3d.zoom_border", text="Zoom Border...")
- layout.operator("view3d.render_border", text="Render Border...")
+ layout.operator("view3d.render_border", text="Render Border...").camera_only = False
layout.separator()
@@ -410,8 +423,8 @@ class VIEW3D_MT_view(Menu):
layout.separator()
layout.operator("view3d.localview", text="View Global/Local")
- layout.operator("view3d.view_selected")
- layout.operator("view3d.view_all")
+ layout.operator("view3d.view_selected").use_all_regions = False
+ layout.operator("view3d.view_all").center = False
layout.separator()
@@ -433,6 +446,9 @@ class VIEW3D_MT_view_navigation(Menu):
layout = self.layout
layout.operator_enum("view3d.view_orbit", "type")
+ props = layout.operator("view3d.view_orbit", "Orbit Opposite")
+ props.type = 'ORBITRIGHT'
+ props.angle = pi
layout.separator()
@@ -565,8 +581,13 @@ class VIEW3D_MT_select_pose(Menu):
layout.separator()
- layout.operator("pose.select_hierarchy", text="Parent").direction = 'PARENT'
- layout.operator("pose.select_hierarchy", text="Child").direction = 'CHILD'
+ props = layout.operator("pose.select_hierarchy", text="Parent")
+ props.extend = False
+ props.direction = 'PARENT'
+
+ props = layout.operator("pose.select_hierarchy", text="Child")
+ props.extend = False
+ props.direction = 'CHILD'
layout.separator()
@@ -834,8 +855,13 @@ class VIEW3D_MT_select_edit_armature(Menu):
layout.separator()
- layout.operator("armature.select_hierarchy", text="Parent").direction = 'PARENT'
- layout.operator("armature.select_hierarchy", text="Child").direction = 'CHILD'
+ props = layout.operator("armature.select_hierarchy", text="Parent")
+ props.extend = False
+ props.direction = 'PARENT'
+
+ props = layout.operator("armature.select_hierarchy", text="Child")
+ props.extend = False
+ props.direction = 'CHILD'
layout.separator()
@@ -888,6 +914,41 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
layout.operator("paint.vert_select_ungrouped", text="Ungrouped Verts")
+
+class VIEW3D_MT_angle_control(Menu):
+ bl_label = "Angle Control"
+
+ @classmethod
+ def poll(cls, context):
+ settings = UnifiedPaintPanel.paint_settings(context)
+ if not settings:
+ return False
+
+ brush = settings.brush
+ tex_slot = brush.texture_slot
+
+ return tex_slot.has_texture_angle and tex_slot.has_texture_angle_source
+
+ def draw(self, context):
+ layout = self.layout
+
+ settings = UnifiedPaintPanel.paint_settings(context)
+ brush = settings.brush
+
+ sculpt = (context.sculpt_object != None)
+
+ tex_slot = brush.texture_slot
+
+ layout.prop(tex_slot, "use_rake", text="Rake")
+
+ if brush.brush_capabilities.has_random_texture_angle and tex_slot.has_random_texture_angle:
+ if sculpt:
+ if brush.sculpt_capabilities.has_random_texture_angle:
+ layout.prop(tex_slot, "use_random", text="Random")
+ else:
+ layout.prop(tex_slot, "use_random", text="Random")
+
+
# ********** Add menu **********
# XXX: INFO_MT_ names used to keep backwards compatibility (Addons etc that hook into the menu)
@@ -1057,7 +1118,7 @@ class VIEW3D_MT_object(Menu):
layout.operator("object.duplicate_move")
layout.operator("object.duplicate_move_linked")
- layout.operator("object.delete", text="Delete...")
+ layout.operator("object.delete", text="Delete...").use_global = False
layout.operator("object.proxy_make", text="Make Proxy...")
layout.menu("VIEW3D_MT_make_links", text="Make Links...")
layout.operator("object.make_dupli_face")
@@ -1082,6 +1143,8 @@ class VIEW3D_MT_object(Menu):
layout.separator()
layout.operator("object.join")
+ layout.operator("object.data_transfer")
+ layout.operator("object.datalayout_transfer")
layout.separator()
@@ -1154,12 +1217,16 @@ class VIEW3D_MT_object_specials(Menu):
props.header_text = "Camera Lens Scale: %.3f"
if not obj.data.dof_object:
- #layout.label(text="Test Has DOF obj");
- props = layout.operator("wm.context_modal_mouse", text="DOF Distance")
- props.data_path_iter = "selected_editable_objects"
- props.data_path_item = "data.dof_distance"
- props.input_scale = 0.02
- props.header_text = "DOF Distance: %.3f"
+ view = context.space_data
+ if view and view.camera == obj and view.region_3d.view_perspective == 'CAMERA':
+ props = layout.operator("ui.eyedropper_depth", text="DOF Distance (Pick)")
+ else:
+ props = layout.operator("wm.context_modal_mouse", text="DOF Distance")
+ props.data_path_iter = "selected_editable_objects"
+ props.data_path_item = "data.dof_distance"
+ props.input_scale = 0.02
+ props.header_text = "DOF Distance: %.3f"
+ del view
if obj.type in {'CURVE', 'FONT'}:
layout.operator_context = 'INVOKE_REGION_WIN'
@@ -1588,7 +1655,9 @@ class VIEW3D_MT_paint_weight(Menu):
layout.operator("object.vertex_group_quantize", text="Quantize")
layout.operator("object.vertex_group_levels", text="Levels")
layout.operator("object.vertex_group_blend", text="Blend")
- layout.operator("object.vertex_group_transfer_weight", text="Transfer Weights")
+ prop = layout.operator("object.data_transfer", text="Transfer Weights")
+ prop.use_reverse_transfer = True
+ prop.data_type = 'VGROUP_WEIGHTS'
layout.operator("object.vertex_group_limit_total", text="Limit Total")
layout.operator("object.vertex_group_fix", text="Fix Deforms")
@@ -1781,7 +1850,7 @@ class VIEW3D_MT_pose(Menu):
layout.separator()
layout.operator("pose.copy")
- layout.operator("pose.paste")
+ layout.operator("pose.paste").flipped = False
layout.operator("pose.paste", text="Paste X-Flipped Pose").flipped = True
layout.separator()
@@ -2187,7 +2256,8 @@ class VIEW3D_MT_edit_mesh_vertices(Menu):
layout.operator("mesh.rip_edge_move")
layout.operator("mesh.split")
layout.operator_menu_enum("mesh.separate", "type")
- layout.operator("mesh.vert_connect", text="Connect")
+ layout.operator("mesh.vert_connect_path", text="Connect Vertex Path")
+ layout.operator("mesh.vert_connect", text="Connect Vertices")
layout.operator("transform.vert_slide", text="Slide")
layout.separator()
@@ -2299,7 +2369,8 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
layout.separator()
layout.operator("mesh.poke")
- layout.operator("mesh.quads_convert_to_tris")
+ props = layout.operator("mesh.quads_convert_to_tris")
+ props.quad_method = props.ngon_method = 'BEAUTY'
layout.operator("mesh.tris_convert_to_quads")
layout.operator("mesh.face_split_by_edges")
@@ -2308,7 +2379,7 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
layout.operator("mesh.faces_shade_smooth")
layout.operator("mesh.faces_shade_flat")
- layout.operator("mesh.normals_make_consistent", text="Recalculate Normals")
+ layout.operator("mesh.normals_make_consistent", text="Recalculate Normals").inside = False
layout.separator()
@@ -2349,6 +2420,7 @@ class VIEW3D_MT_edit_mesh_clean(Menu):
layout.operator("mesh.dissolve_degenerate")
layout.operator("mesh.dissolve_limited")
layout.operator("mesh.vert_connect_nonplanar")
+ layout.operator("mesh.vert_connect_concave")
layout.operator("mesh.fill_holes")
@@ -2434,7 +2506,6 @@ class VIEW3D_MT_edit_curve_ctrlpoints(Menu):
if edit_object.type == 'CURVE':
layout.operator("transform.tilt")
layout.operator("curve.tilt_clear")
- layout.operator("curve.separate")
layout.separator()
@@ -2704,6 +2775,13 @@ class VIEW3D_MT_edit_armature_roll(Menu):
# ********** Panel **********
+class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+
+ # NOTE: this is just a wrapper around the generic GP Panel
+
+
class VIEW3D_PT_view3d_properties(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
@@ -2813,6 +2891,7 @@ class VIEW3D_PT_view3d_display(Panel):
col = layout.column()
col.prop(view, "show_only_render")
+ col.prop(view, "show_world")
col = layout.column()
display_all = not view.show_only_render
@@ -2889,8 +2968,26 @@ class VIEW3D_PT_view3d_shading(Panel):
col.prop(view, "show_textured_shadeless")
col.prop(view, "show_backface_culling")
- if obj and obj.mode == 'EDIT' and view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
- col.prop(view, "show_occlude_wire")
+
+ if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
+ if obj and obj.mode == 'EDIT':
+ col.prop(view, "show_occlude_wire")
+
+ fx_settings = view.fx_settings
+
+ sub = col.column()
+ sub.active = view.region_3d.view_perspective == 'CAMERA'
+ sub.prop(fx_settings, "use_dof")
+
+ col.prop(fx_settings, "use_ssao", text="Ambient Occlusion")
+ if fx_settings.use_ssao:
+ ssao_settings = fx_settings.ssao
+ subcol = col.column(align=True)
+ subcol.prop(ssao_settings, "factor")
+ subcol.prop(ssao_settings, "distance_max")
+ subcol.prop(ssao_settings, "attenuation")
+ subcol.prop(ssao_settings, "samples")
+ subcol.prop(ssao_settings, "color")
class VIEW3D_PT_view3d_motion_tracking(Panel):
@@ -3137,12 +3234,19 @@ class VIEW3D_PT_background_image(Panel):
if bg.view_axis in {'CAMERA', 'ALL'}:
col.row().prop(bg, "frame_method", expand=True)
- row = col.row(align=True)
+ box = col.box()
+ row = box.row()
row.prop(bg, "offset_x", text="X")
row.prop(bg, "offset_y", text="Y")
+ row = box.row()
+ row.prop(bg, "use_flip_x")
+ row.prop(bg, "use_flip_y")
+
+ row = box.row()
if bg.view_axis != 'CAMERA':
- col.prop(bg, "size")
+ row.prop(bg, "rotation")
+ row.prop(bg, "size")
class VIEW3D_PT_transform_orientations(Panel):
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index da64caa7a30..70874460d4d 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -19,7 +19,10 @@
# <pep8 compliant>
import bpy
from bpy.types import Menu, Panel, UIList
-from bl_ui.properties_grease_pencil_common import GreasePencilPanel
+from bl_ui.properties_grease_pencil_common import (
+ GreasePencilDrawingToolsPanel,
+ GreasePencilStrokeEditPanel
+ )
from bl_ui.properties_paint_common import (
UnifiedPaintPanel,
brush_texture_settings,
@@ -28,7 +31,7 @@ from bl_ui.properties_paint_common import (
)
-class View3DPanel():
+class View3DPanel:
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
@@ -97,6 +100,13 @@ class VIEW3D_PT_tools_object(View3DPanel, Panel):
row.operator("object.shade_smooth", text="Smooth")
row.operator("object.shade_flat", text="Flat")
+ if obj_type in {'MESH'}:
+ col = layout.column(align=True)
+ col.label(text="Data Transfer:")
+ row = col.row(align=True)
+ row.operator("object.data_transfer", text="Data")
+ row.operator("object.datalayout_transfer", text="Data Layout")
+
class VIEW3D_PT_tools_add_object(View3DPanel, Panel):
bl_category = "Create"
@@ -313,6 +323,8 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel):
col.menu("VIEW3D_MT_edit_mesh_extrude")
col.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Region")
col.operator("view3d.edit_mesh_extrude_individual_move", text="Extrude Individual")
+ col.operator("mesh.inset", text="Inset Faces")
+ col.operator("mesh.edge_face_add")
col.operator("mesh.subdivide")
col.operator("mesh.loopcut_slide")
col.operator("mesh.duplicate_move", text="Duplicate")
@@ -775,6 +787,7 @@ class View3DPaintPanel(UnifiedPaintPanel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
+
class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel):
bl_category = "Tools"
bl_label = "Missing Data"
@@ -793,16 +806,15 @@ class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel):
if toolsettings.missing_uvs:
col.separator()
col.label("Missing UVs", icon='INFO')
- col.label("Unwrap the mesh in edit mode or generate a simple UVs")
- col.operator("mesh.uv_texture_add", text="Add Simple UVs")
-
+ col.label("Unwrap the mesh in edit mode or generate a simple UV layer")
+ col.operator("paint.add_simple_uvs")
+
if toolsettings.mode == 'MATERIAL':
if toolsettings.missing_materials:
col.separator()
col.label("Missing Materials", icon='INFO')
col.label("Add a material and paint slot below")
col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
-
elif toolsettings.missing_texture:
ob = context.active_object
mat = ob.active_material
@@ -816,7 +828,6 @@ class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel):
col.label("Missing Materials", icon='INFO')
col.label("Add a material and paint slot below")
col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
-
elif toolsettings.mode == 'IMAGE':
if toolsettings.missing_texture:
@@ -835,6 +846,7 @@ class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel):
col.template_ID(toolsettings, "stencil_image")
col.operator("image.new", text="New").gen_context = 'PAINT_STENCIL'
+
class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
bl_category = "Tools"
bl_label = "Brush"
@@ -870,10 +882,8 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
col.prop(brush, "count")
col = layout.column()
col.prop(settings, "use_default_interpolate")
- sub = col.column(align=True)
- sub.active = settings.use_default_interpolate
- sub.prop(brush, "steps", slider=True)
- sub.prop(settings, "default_key_count", slider=True)
+ col.prop(brush, "steps", slider=True)
+ col.prop(settings, "default_key_count", slider=True)
elif tool == 'LENGTH':
layout.prop(brush, "length_mode", expand=True)
elif tool == 'PUFF':
@@ -1058,13 +1068,14 @@ class TEXTURE_UL_texpaintslots(UIList):
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(item, "name", text="", emboss=False, icon_value=icon)
- if (not mat.use_nodes) and (context.scene.render.engine == 'BLENDER_RENDER'):
+ if (not mat.use_nodes) and context.scene.render.engine in {'BLENDER_RENDER', 'BLENDER_GAME'}:
mtex_index = mat.texture_paint_slots[index].index
layout.prop(mat, "use_textures", text="", index=mtex_index)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label(text="")
+
class VIEW3D_MT_tools_projectpaint_uvlayer(Menu):
bl_label = "Clone Layer"
@@ -1115,18 +1126,23 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
mat, "texture_paint_images",
mat, "paint_active_slot", rows=2)
- if (not mat.use_nodes) and (context.scene.render.engine == 'BLENDER_RENDER'):
+ if mat.texture_paint_slots:
+ slot = mat.texture_paint_slots[mat.paint_active_slot]
+ else:
+ slot = None
+
+ if (not mat.use_nodes) and context.scene.render.engine in {'BLENDER_RENDER', 'BLENDER_GAME'}:
row = col.row(align=True)
row.operator_menu_enum("paint.add_texture_paint_slot", "type")
row.operator("paint.delete_texture_paint_slot", text="", icon='X')
- if mat.texture_paint_slots:
- slot = mat.texture_paint_slots[mat.paint_active_slot]
-
+ if slot:
col.prop(mat.texture_slots[slot.index], "blend_type")
col.separator()
- col.label("UV Map")
- col.prop_search(slot, "uv_layer", ob.data, "uv_textures", text="")
+
+ if slot and slot.index != -1:
+ col.label("UV Map")
+ col.prop_search(slot, "uv_layer", ob.data, "uv_textures", text="")
elif settings.mode == 'IMAGE':
mesh = ob.data
@@ -1175,7 +1191,6 @@ class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel):
col.template_ID(ipaint, "stencil_image")
col.operator("image.new", text="New").gen_context = 'PAINT_STENCIL'
-
col.label("Visualization")
row = col.row(align=True)
row.prop(ipaint, "stencil_color", text="")
@@ -1586,7 +1601,9 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
col = layout.column()
col.operator("paint.weight_gradient")
- col.operator("object.vertex_group_transfer_weight", text="Transfer Weights")
+ prop = col.operator("object.data_transfer", text="Transfer Weights")
+ prop.use_reverse_transfer = True
+ prop.data_type = 'VGROUP_WEIGHTS'
class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
@@ -1705,7 +1722,12 @@ class VIEW3D_PT_tools_projectpaint(View3DPaintPanel, Panel):
sub.active = (ipaint.use_normal_falloff)
sub.prop(ipaint, "normal_angle", text="")
+ layout.prop(ipaint, "use_cavity")
+ if ipaint.use_cavity:
+ layout.template_curve_mapping(ipaint, "cavity_curve", brush=True)
+
layout.prop(ipaint, "seam_bleed")
+ layout.prop(ipaint, "dither")
self.unified_paint_settings(layout, context)
@@ -1789,6 +1811,9 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
col.prop(pe, "use_auto_velocity", text="Velocity")
col.prop(ob.data, "use_mirror_x")
+ col.prop(pe, "shape_object")
+ col.operator("particle.shape_cut")
+
col = layout.column(align=True)
col.active = pe.is_editable
col.label(text="Draw:")
@@ -1804,11 +1829,14 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
sub.prop(pe, "fade_frames", slider=True)
-# Grease Pencil tools
-class VIEW3D_PT_tools_grease_pencil(GreasePencilPanel, Panel):
+# Grease Pencil drawing tools
+class VIEW3D_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
+ bl_space_type = 'VIEW_3D'
+
+
+# Grease Pencil stroke editing tools
+class VIEW3D_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
bl_space_type = 'VIEW_3D'
- bl_region_type = 'TOOLS'
- bl_category = "Grease Pencil"
# Note: moved here so that it's always in last position in 'Tools' panels!
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 8c2476bd430..1590bd49763 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -150,6 +150,7 @@ shader_node_categories = [
NodeItem("ShaderNodeRGBCurve"),
NodeItem("ShaderNodeInvert"),
NodeItem("ShaderNodeHueSaturation"),
+ NodeItem("ShaderNodeGamma"),
]),
ShaderOldNodeCategory("SH_OP_VECTOR", "Vector", items=[
NodeItem("ShaderNodeNormal"),
diff --git a/release/scripts/templates_py/custom_nodes.py b/release/scripts/templates_py/custom_nodes.py
index 992ef734859..32c61abace7 100644
--- a/release/scripts/templates_py/custom_nodes.py
+++ b/release/scripts/templates_py/custom_nodes.py
@@ -13,9 +13,6 @@ class MyCustomTree(NodeTree):
# Label for nice name display
bl_label = 'Custom Node Tree'
# Icon identifier
- # NOTE: If no icon is defined, the node tree will not show up in the editor header!
- # This can be used to make additional tree types for groups and similar nodes (see below)
- # Only one base tree class is needed in the editor for selecting the general category
bl_icon = 'NODETREE'
diff --git a/release/scripts/templates_py/operator_mesh_add.py b/release/scripts/templates_py/operator_mesh_add.py
index fa248cb9005..5fabaaf3f7f 100644
--- a/release/scripts/templates_py/operator_mesh_add.py
+++ b/release/scripts/templates_py/operator_mesh_add.py
@@ -89,6 +89,7 @@ class AddBox(bpy.types.Operator):
for v_co in verts_loc:
bm.verts.new(v_co)
+ bm.verts.ensure_lookup_table()
for f_idx in faces:
bm.faces.new([bm.verts[i] for i in f_idx])
diff --git a/release/scripts/templates_py/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py
index 1aa13c90ca3..b72b2f76750 100644
--- a/release/scripts/templates_py/operator_modal_view3d_raycast.py
+++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py
@@ -14,10 +14,6 @@ def main(context, event, ray_max=1000.0):
view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
- if rv3d.view_perspective == 'ORTHO':
- # move ortho origin back
- ray_origin = ray_origin - (view_vector * (ray_max / 2.0))
-
ray_target = ray_origin + (view_vector * ray_max)
def visible_objects_and_duplis():
diff --git a/release/text/readme.html b/release/text/readme.html
index 4d8b0bf24d2..8e08a8ba027 100644
--- a/release/text/readme.html
+++ b/release/text/readme.html
@@ -3,9 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
- <title></title>
- <meta name="Generator" content="Cocoa HTML Writer">
- <meta name="CocoaVersion" content="1265">
+ <title>Blender Readme</title>
<style type="text/css">
p.p1 {margin: 0.0px 156.0px 22.0px 156.0px; text-align: center; font: 22.0px Helvetica}
p.p2 {margin: 0.0px 0.0px 12.0px 0.0px; font: 12.0px Times; min-height: 14.0px}
@@ -20,18 +18,38 @@
</style>
</head>
<body>
-<p class="p1"><b>Blender 2.72</b></p>
+<p class="p1"><b>Blender BLENDER_VERSION</b></p>
<p class="p2"><br></p>
<p class="p3"><b>About</b></p>
-<p class="p4">Welcome to Blender, the free, open source 3D application for modeling, animation, rendering, compositing, video editing and game creation. Blender is available for Linux, Mac OS X and Windows and has a large world-wide community.</p>
-<p class="p4">Blender can be used freely for any purpose, including commercial use and distribution. It's free and open-source software, released under the GNU GPL licence. The entire source code is available on our website.</p>
-<p class="p4">For more information, visit <a href="http://www.blender.org/"><span class="s1">blender.org</span></a>.</p>
+<p class="p4">
+Welcome to Blender, the free, open source 3D application for modeling, animation, rendering,
+compositing, video editing and game creation.
+Blender is available for Linux, Mac OS X and Windows and has a large world-wide community.
+</p>
+<p class="p4">
+Blender can be used freely for any purpose, including commercial use and distribution.
+It's free and open-source software, released under the GNU GPL licence.
+The entire source code is available on our website.
+</p>
+<p class="p4">
+For more information, visit <a href="http://www.blender.org/"><span class="s1">blender.org</span></a>.
+</p>
<p class="p2"><br></p>
-<p class="p3"><b>2.72</b></p>
-<p class="p4">The Blender Foundation and online developer community is proud to present Blender 2.72. This release is the third official stable release of the Blender 2.7 series. <a href="http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72"><span class="s1">More information about this release</span></a>.</p>
+<p class="p3"><b>BLENDER_VERSION</b></p>
+<p class="p4">
+The Blender Foundation and online developer community is proud to present Blender BLENDER_VERSION.
+<a href="http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/BLENDER_VERSION">
+<span class="s1">More information about this release</span></a>.
+</p>
<p class="p2"><br></p>
<p class="p3"><b>Bugs</b></p>
-<p class="p4">Although Blender 2.72 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help <span class="s2">→</span> Report a Bug from inside Blender. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p>
+<p class="p4">
+Although this is considered a stable release, you may encounter a bug.
+If you do, please help us by posting it in the bug tracker or using Help
+<span class="s2">→</span> Report a Bug from inside Blender.
+If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error.
+Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.
+</p>
<p class="p2"><br></p>
<p class="p3"><b>Package Contents</b></p>
<p class="p4">The downloaded Blender package includes:</p>
@@ -40,31 +58,70 @@
<p class="p4">• Readme and copyright files.</p>
<p class="p2"><br></p>
<p class="p3"><b>Installation</b></p>
-<p class="p4"><b>Windows: </b>The download .zip contains a Blender folder. You may put this anywhere on your hard drive. To launch Blender, double-click on Blender.exe.</p>
-<p class="p4"><b>Linux: </b>Unpack the archive, then run the Blender executable.</p>
-<p class="p4"><b>Mac OS X: </b>The downloaded package includes blender.app. Optionally copy this to your Applications folder, and add it to the dock by dragging it from there to the dock.</p>
+<p class="p4">
+<b>Windows: </b>The download .zip contains a Blender folder. You may put this anywhere on your hard drive.
+To launch Blender, double-click on Blender.exe.
+</p>
+<p class="p4">
+<b>Linux: </b>Unpack the archive, then run the Blender executable.
+</p>
+<p class="p4">
+<b>Mac OS X: </b>The downloaded package includes blender.app.
+Optionally copy this to your Applications folder, and add it to the dock by dragging it from there to the dock.
+</p>
<p class="p2"><br></p>
-<p class="p4"><b>Installing Addons (all systems)</b> Addons can be installed from the user preferences addons section, download an addon as a .py or .zip file, then press the "Install Addon" button and select the file to install it.</p>
+<p class="p4">
+<b>Installing Addons (all systems)</b> Addons can be installed from the user preferences addons section,
+download an addon as a .py or .zip file, then press the "Install Addon" button and select the file to install it.
+</p>
<p class="p2"><br></p>
<p class="p3"><b>Getting Started</b></p>
-<p class="p4">When opening Blender, you’ll see large 3D view in the center, a Toolbar on the left, a Properties editor and an Outliner on the right and a Timeline at the bottom.</p>
-<p class="p4">Orbit around in the 3D view by holding the middle mouse button and dragging. Alternatively, hold the alt key and drag the left mouse button. Additionally, hold Shift to pan the view and Ctrl to zoom.</p>
-<p class="p4">Select objects using the right mouse button. With the object selected, perform actions by clicking any of the tool buttons on the left, or make changes to its properties by altering any of the setting on the right.</p>
-<p class="p4">For more information on how to use Blender, <a href="http://www.blender.org/support/"><span class="s1">check out the support page</span></a>.</p>
+<p class="p4">
+When opening Blender, you’ll see large 3D view in the center, a Toolbar on the left,
+a Properties editor and an Outliner on the right and a Timeline at the bottom.
+</p>
+<p class="p4">
+Orbit around in the 3D view by holding the middle mouse button and dragging.
+Alternatively, hold the alt key and drag the left mouse button.
+Additionally, hold Shift to pan the view and Ctrl to zoom.
+</p>
+<p class="p4">
+Select objects using the right mouse button.
+With the object selected, perform actions by clicking any of the tool buttons on the left,
+or make changes to its properties by altering any of the setting on the right.
+</p>
+<p class="p4">
+For more information on how to use Blender,
+<a href="http://www.blender.org/support/"><span class="s1">check out the support page</span></a>.
+</p>
<p class="p2"><br></p>
<p class="p3"><b>Links</b></p>
<p class="p4">Users:</p>
-<p class="p5"><span class="s3">General information <a href="http://www.blender.org/"><span class="s4">www.blender.org</span></a> <br>
-Full release log <a href="http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72"><span class="s4">wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72</span></a><br>
-Tutorials <a href="http://www.blender.org/support/tutorials/"><span class="s4">www.blender.org/support/tutorials/</span></a> <br>
-Manual <a href="http://wiki.blender.org/index.php/Doc:2.6/Manual"><span class="s4">wiki.blender.org/index.php/Doc:2.6/Manual</span></a><br>
-User Forum <a href="http://www.blenderartists.org/"><span class="s4">www.blenderartists.org</span></a><br>
-IRC <a href="irc://irc.freenode.net/#blenderchat"><span class="s4">#blenderchat</span></a> or <a href="irc://irc.freenode.net/#blender"><span class="s4">#blender</span></a> on irc.freenode.net</span></p>
+<p class="p5">
+<span class="s3">General information <a href="http://www.blender.org/">
+<span class="s4">www.blender.org</span></a> <br>
+Full release log <a href="http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/BLENDER_VERSION">
+<span class="s4">wiki.blender.org/index.php/Dev:Ref/Release_Notes/BLENDER_VERSION</span></a><br>
+Tutorials <a href="http://www.blender.org/support/tutorials/">
+<span class="s4">www.blender.org/support/tutorials/</span></a> <br>
+Manual <a href="http://www.blender.org/manual"><span class="s4">www.blender.org/manual</span></a><br>
+User Forum <a href="http://www.blenderartists.org/">
+<span class="s4">www.blenderartists.org</span></a><br>
+IRC <a href="irc://irc.freenode.net/#blenderchat">
+<span class="s4">#blenderchat</span></a> or <a href="irc://irc.freenode.net/#blender">
+<span class="s4">#blender</span></a> on irc.freenode.net</span>
+</p>
<p class="p4">Developers:</p>
-<p class="p5"><span class="s3">Development <a href="http://www.blender.org/get-involved/developers/"><span class="s4">www.blender.org/get-involved/developers/</span></a><br>
-GIT and Bug Tracker <a href="http://developer.blender.org/"><span class="s4">developer.blender.org/</span></a><br>
-Get Involved <a href="http://www.blender.org/get-involved/"><span class="s4">www.blender.org/get-involved/</span></a><br>
-IRC <a href="irc://irc.freenode.net/#blendercoders"><span class="s4">#blendercoders</span></a> on irc.freenode.net</span></p>
+<p class="p5">
+<span class="s3">Development <a href="http://www.blender.org/get-involved/developers/">
+<span class="s4">www.blender.org/get-involved/developers/</span></a><br>
+GIT and Bug Tracker <a href="http://developer.blender.org/">
+<span class="s4">developer.blender.org/</span></a><br>
+Get Involved <a href="http://www.blender.org/get-involved/">
+<span class="s4">www.blender.org/get-involved/</span></a><br>
+IRC <a href="irc://irc.freenode.net/#blendercoders">
+<span class="s4">#blendercoders</span></a> on irc.freenode.net</span>
+</p>
<p class="p2"><br></p>
<p class="p2"><br></p>
<p class="p6">Blender is open-source and free for all to use.</p>
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index 0d309523daf..d87d5dfc2cc 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -46,6 +46,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_freestyle_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_genfile.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_group_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_image_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_ipo_types.h
@@ -102,6 +103,7 @@ add_subdirectory(render)
add_subdirectory(blenfont)
add_subdirectory(blenloader)
add_subdirectory(ikplugin)
+add_subdirectory(physics)
add_subdirectory(gpu)
add_subdirectory(imbuf)
add_subdirectory(nodes)
diff --git a/source/blender/SConscript b/source/blender/SConscript
index de052f24c33..64eca6a62db 100644
--- a/source/blender/SConscript
+++ b/source/blender/SConscript
@@ -41,6 +41,7 @@ SConscript(['avi/SConscript',
'nodes/SConscript',
'modifiers/SConscript',
'ikplugin/SConscript',
+ 'physics/SConscript',
'windowmanager/SConscript',
'blenfont/SConscript'])
diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c
index a423c874adf..6ea94d3b2f3 100644
--- a/source/blender/avi/intern/avi.c
+++ b/source/blender/avi/intern/avi.c
@@ -676,7 +676,7 @@ AviError AVI_open_movie(const char *name, AviMovie *movie)
* instead of an offset from the movie beginning... this is...
* wacky, but we need to handle it. The wacky offset always
* starts at movi_offset it seems... so we'll check that.
- * Note the the offset needs an extra 4 bytes for some
+ * Note the offset needs an extra 4 bytes for some
* undetermined reason */
if (movie->entries[0].Offset == movie->movi_offset)
diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h
index c11996799ff..b42e6f80022 100644
--- a/source/blender/blenfont/BLF_translation.h
+++ b/source/blender/blenfont/BLF_translation.h
@@ -163,6 +163,8 @@ const char *BLF_translate_do_new_dataname(const char *msgctxt, const char *msgid
#define BLF_I18NCONTEXT_ID_MESH "Mesh"
#define BLF_I18NCONTEXT_ID_NODETREE "NodeTree"
#define BLF_I18NCONTEXT_ID_OBJECT "Object"
+#define BLF_I18NCONTEXT_ID_PAINTCURVE "PaintCurve"
+#define BLF_I18NCONTEXT_ID_PALETTE "Palette"
#define BLF_I18NCONTEXT_ID_PARTICLESETTINGS "ParticleSettings"
#define BLF_I18NCONTEXT_ID_SCENE "Scene"
#define BLF_I18NCONTEXT_ID_SCREEN "Screen"
@@ -207,11 +209,15 @@ typedef struct
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LAMP, "id_lamp"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LIBRARY, "id_library"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_LATTICE, "id_lattice"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MASK, "id_mask"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MATERIAL, "id_material"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_METABALL, "id_metaball"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MESH, "id_mesh"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MOVIECLIP, "id_movieclip"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_NODETREE, "id_nodetree"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_OBJECT, "id_object"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_PAINTCURVE, "id_paintcurve"), \
+ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_PALETTE, "id_palette"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_PARTICLESETTINGS, "id_particlesettings"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SCENE, "id_scene"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_SCREEN, "id_screen"), \
@@ -223,8 +229,6 @@ typedef struct
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_VFONT, "id_vfont"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_WORLD, "id_world"), \
BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_WINDOWMANAGER, "id_windowmanager"), \
- BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MOVIECLIP, "id_movieclip"), \
- BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_MASK, "id_mask"), \
{NULL, NULL, NULL} \
}
diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt
index 346d5bc64b8..392a9ede100 100644
--- a/source/blender/blenfont/CMakeLists.txt
+++ b/source/blender/blenfont/CMakeLists.txt
@@ -56,6 +56,12 @@ set(SRC
intern/blf_internal_types.h
)
+if(WIN32)
+ list(APPEND SRC
+ intern/blf_font_win32_compat.c
+ )
+endif()
+
if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index cdccbe044bb..127826f98c8 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -63,6 +63,9 @@
*/
#define BLF_MAX_FONT 16
+/* call BLF_default_set first! */
+#define ASSERT_DEFAULT_SET BLI_assert(global_font_default != -1)
+
/* Font array. */
static FontBLF *global_font[BLF_MAX_FONT] = {NULL};
@@ -134,7 +137,7 @@ static int blf_search(const char *name)
for (i = 0; i < BLF_MAX_FONT; i++) {
font = global_font[i];
- if (font && (!strcmp(font->name, name)))
+ if (font && (STREQ(font->name, name)))
return i;
}
@@ -160,21 +163,6 @@ void BLF_default_set(int fontid)
}
}
-static int blf_global_font_init(void)
-{
- if (global_font_default == -1) {
- global_font_default = blf_search("default");
- }
-
- if (global_font_default == -1) {
- printf("Warning: Can't find default font!\n");
- return 0;
- }
- else {
- return 1;
- }
-}
-
int BLF_load(const char *name)
{
FontBLF *font;
@@ -336,7 +324,7 @@ void BLF_unload(const char *name)
for (i = 0; i < BLF_MAX_FONT; i++) {
font = global_font[i];
- if (font && (!strcmp(font->name, name))) {
+ if (font && (STREQ(font->name, name))) {
blf_font_free(font);
global_font[i] = NULL;
}
@@ -477,8 +465,7 @@ void BLF_blur(int fontid, int size)
void BLF_draw_default(float x, float y, float z, const char *str, size_t len)
{
- if (!blf_global_font_init())
- return;
+ ASSERT_DEFAULT_SET;
BLF_size(global_font_default, global_font_points, global_font_dpi);
BLF_position(global_font_default, x, y, z);
@@ -488,8 +475,7 @@ void BLF_draw_default(float x, float y, float z, const char *str, size_t len)
/* same as above but call 'BLF_draw_ascii' */
void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len)
{
- if (!blf_global_font_init())
- return;
+ ASSERT_DEFAULT_SET;
BLF_size(global_font_default, global_font_points, global_font_dpi);
BLF_position(global_font_default, x, y, z);
@@ -670,10 +656,7 @@ void BLF_width_and_height(int fontid, const char *str, size_t len, float *r_widt
void BLF_width_and_height_default(const char *str, size_t len, float *r_width, float *r_height)
{
- if (!blf_global_font_init()) {
- *r_width = *r_height = 0.0f;
- return;
- }
+ ASSERT_DEFAULT_SET;
BLF_size(global_font_default, global_font_points, global_font_dpi);
BLF_width_and_height(global_font_default, str, len, r_width, r_height);
@@ -703,8 +686,7 @@ float BLF_fixed_width(int fontid)
float BLF_width_default(const char *str, size_t len)
{
- if (!blf_global_font_init())
- return 0.0f;
+ ASSERT_DEFAULT_SET;
BLF_size(global_font_default, global_font_points, global_font_dpi);
return BLF_width(global_font_default, str, len);
@@ -767,8 +749,7 @@ float BLF_ascender(int fontid)
float BLF_height_default(const char *str, size_t len)
{
- if (!blf_global_font_init())
- return 0.0f;
+ ASSERT_DEFAULT_SET;
BLF_size(global_font_default, global_font_points, global_font_dpi);
diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c
index 4a36ae03bed..f493aa9af74 100644
--- a/source/blender/blenfont/intern/blf_dir.c
+++ b/source/blender/blenfont/intern/blf_dir.c
@@ -103,7 +103,7 @@ char **BLF_dir_get(int *ndir)
char *path;
int i, count;
- count = BLI_countlist(&global_font_dir);
+ count = BLI_listbase_count(&global_font_dir);
if (!count)
return NULL;
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 4891c332c87..087c7c7345e 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -65,6 +65,10 @@
#include "BLI_strict_flags.h"
+#ifdef WIN32
+# define FT_New_Face FT_New_Face__win32_compat
+#endif
+
/* freetype2 handle ONLY for this file!. */
static FT_Library ft_lib;
static SpinLock ft_lib_mutex;
diff --git a/source/blender/blenfont/intern/blf_font_win32_compat.c b/source/blender/blenfont/intern/blf_font_win32_compat.c
new file mode 100644
index 00000000000..dd4a443e69f
--- /dev/null
+++ b/source/blender/blenfont/intern/blf_font_win32_compat.c
@@ -0,0 +1,145 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenfont/intern/blf_font_win32_compat.c
+ * \ingroup blf
+ *
+ * Workaround for win32 which needs to use BLI_fopen to access files.
+ *
+ * defines #FT_New_Face__win32_compat, a drop-in replacement for \a #FT_New_Face.
+ */
+
+#ifdef WIN32
+
+#include <stdio.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_fileops.h"
+
+#include "blf_internal.h"
+
+/* internal freetype defines */
+#define STREAM_FILE(stream) ((FILE *)stream->descriptor.pointer)
+#define FT_THROW(e) -1
+
+static void ft_ansi_stream_close(
+ FT_Stream stream)
+{
+ fclose(STREAM_FILE(stream));
+
+ stream->descriptor.pointer = NULL;
+ stream->size = 0;
+ stream->base = 0;
+
+ /* WARNING: this works but be careful!
+ * Checked freetype sources, there isn't any access after closing. */
+ MEM_freeN(stream);
+}
+
+static unsigned long ft_ansi_stream_io(
+ FT_Stream stream,
+ unsigned long offset,
+ unsigned char *buffer,
+ unsigned long count)
+{
+ FILE *file;
+ if (!count && offset > stream->size)
+ return 1;
+
+ file = STREAM_FILE(stream);
+
+ if (stream->pos != offset)
+ fseek(file, offset, SEEK_SET);
+
+ return fread(buffer, 1, count, file);
+}
+
+static FT_Error FT_Stream_Open__win32_compat(FT_Stream stream, const char *filepathname)
+{
+ FILE *file;
+ BLI_assert(stream);
+
+ stream->descriptor.pointer = NULL;
+ stream->pathname.pointer = (char *)filepathname;
+ stream->base = 0;
+ stream->pos = 0;
+ stream->read = NULL;
+ stream->close = NULL;
+
+ file = BLI_fopen(filepathname, "rb");
+ if (!file) {
+ fprintf(stderr,
+ "FT_Stream_Open: "
+ "could not open `%s'\n", filepathname);
+ return FT_THROW(Cannot_Open_Resource);
+ }
+
+ fseek(file, 0, SEEK_END);
+ stream->size = ftell(file);
+ if (!stream->size) {
+ fprintf(stderr,
+ "FT_Stream_Open: "
+ "opened `%s' but zero-sized\n", filepathname);
+ fclose(file);
+ return FT_THROW(Cannot_Open_Stream);
+ }
+
+ fseek(file, 0, SEEK_SET);
+
+ stream->descriptor.pointer = file;
+ stream->read = ft_ansi_stream_io;
+ stream->close = ft_ansi_stream_close;
+
+ return FT_Err_Ok;
+}
+
+FT_Error FT_New_Face__win32_compat(
+ FT_Library library,
+ const char *pathname,
+ FT_Long face_index,
+ FT_Face *aface)
+{
+ FT_Error err;
+ FT_Open_Args open;
+ FT_Stream stream = NULL;
+ stream = MEM_callocN(sizeof(*stream), __func__);
+
+ open.flags = FT_OPEN_STREAM;
+ open.stream = stream;
+ stream->pathname.pointer = (char *)pathname;
+
+ err = FT_Stream_Open__win32_compat(stream, pathname);
+ if (err) {
+ MEM_freeN(stream);
+ return err;
+ }
+
+ err = FT_Open_Face(library, &open, face_index, aface);
+ /* no need to free 'stream', its handled by FT_Open_Face if an error occurs */
+
+ return err;
+}
+
+#endif /* WIN32 */
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 7978d28a4ef..c65a0825a49 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -262,8 +262,8 @@ GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c)
g->xoff = -1;
g->yoff = -1;
bitmap = slot->bitmap;
- g->width = bitmap.width;
- g->height = bitmap.rows;
+ g->width = (int)bitmap.width;
+ g->height = (int)bitmap.rows;
if (g->width && g->height) {
if (sharp) {
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 8cb2d377449..39b3e3397be 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -75,4 +75,11 @@ struct GlyphBLF *blf_glyph_add(struct FontBLF *font, unsigned int index, unsigne
void blf_glyph_free(struct GlyphBLF *g);
void blf_glyph_render(struct FontBLF *font, struct GlyphBLF *g, float x, float y);
+#ifdef WIN32
+/* blf_font_win32_compat.c */
+# ifdef FT_FREETYPE_H
+extern FT_Error FT_New_Face__win32_compat(FT_Library library, const char *pathname, FT_Long face_index, FT_Face *aface);
+# endif
+#endif
+
#endif /* __BLF_INTERNAL_H__ */
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index 12d71827136..99e1aa5d3e3 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -33,6 +33,10 @@
#include <stdlib.h>
#include <string.h>
+#ifndef _WIN32
+# include <locale.h>
+#endif
+
#include "RNA_types.h"
#include "BLF_translation.h" /* own include */
@@ -42,6 +46,7 @@
#include "BLI_path_util.h"
#include "BLI_string.h"
+#include "BKE_appdir.h"
#include "DNA_userdef_types.h"
@@ -79,7 +84,7 @@ static void free_locales(void)
static void fill_locales(void)
{
- const char * const languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale");
+ const char * const languages_path = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale");
char languages[FILE_MAX];
LinkNode *lines = NULL, *line;
char *str;
@@ -187,8 +192,37 @@ EnumPropertyItem *BLF_RNA_lang_enum_properties(void)
void BLF_lang_init(void)
{
#ifdef WITH_INTERNATIONAL
- const char * const messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale");
+ const char * const messagepath = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale");
+#endif
+
+ /* Make sure LANG is correct and wouldn't cause std::rumtime_error. */
+#ifndef _WIN32
+ /* TODO(sergey): This code only ensures LANG is set properly, so later when
+ * Cycles will try to use file system API from boost there'll be no runtime
+ * exception generated by std::locale() which _requires_ having proper LANG
+ * set in the environment.
+ *
+ * Ideally we also need to ensure LC_ALL, LC_MESSAGES and others are also
+ * set to a proper value, but currently it's not a huge deal and doesn't
+ * cause any headache.
+ *
+ * Would also be good to find nicer way to check if LANG is correct.
+ */
+ const char *lang = getenv("LANG");
+ if (lang != NULL) {
+ char *old_locale = setlocale(LC_ALL, NULL);
+ /* Make a copy so subsequenct setlocale() doesn't interfere. */
+ old_locale = BLI_strdup(old_locale);
+ if (setlocale(LC_ALL, lang) == NULL) {
+ setenv("LANG", "C", 1);
+ printf("Warning: Falling back to the standard locale (\"C\")\n");
+ }
+ setlocale(LC_ALL, old_locale);
+ MEM_freeN(old_locale);
+ }
+#endif
+#ifdef WITH_INTERNATIONAL
if (messagepath) {
bl_locale_init(messagepath, TEXT_DOMAIN_NAME);
fill_locales();
diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c
index 150ff1b2107..2a4a152f0eb 100644
--- a/source/blender/blenfont/intern/blf_translation.c
+++ b/source/blender/blenfont/intern/blf_translation.c
@@ -42,6 +42,8 @@
#include "BLI_path_util.h"
#include "BLI_string.h"
+#include "BKE_appdir.h"
+
#include "DNA_userdef_types.h" /* For user settings. */
#include "BPY_extern.h"
@@ -62,7 +64,7 @@ unsigned char *BLF_get_unifont(int *r_unifont_size)
{
#ifdef WITH_INTERNATIONAL
if (unifont_ttf == NULL) {
- const char * const fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts");
+ const char * const fontpath = BKE_appdir_folder_id(BLENDER_DATAFILES, "fonts");
if (fontpath) {
char unifont_path[1024];
@@ -97,7 +99,7 @@ unsigned char *BLF_get_unifont_mono(int *r_unifont_size)
{
#ifdef WITH_INTERNATIONAL
if (unifont_mono_ttf == NULL) {
- const char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts");
+ const char *fontpath = BKE_appdir_folder_id(BLENDER_DATAFILES, "fonts");
if (fontpath) {
char unifont_path[1024];
@@ -131,7 +133,7 @@ void BLF_free_unifont_mono(void)
bool BLF_is_default_context(const char *msgctxt)
{
/* We use the "short" test, a more complete one could be:
- * return (!msgctxt || !msgctxt[0] || !strcmp(msgctxt == BLF_I18NCONTEXT_DEFAULT_BPYRNA))
+ * return (!msgctxt || !msgctxt[0] || STREQ(msgctxt, BLF_I18NCONTEXT_DEFAULT_BPYRNA))
*/
/* Note: trying without the void string check for now, it *should* not be necessary... */
return (!msgctxt || msgctxt[0] == BLF_I18NCONTEXT_DEFAULT_BPYRNA[0]);
diff --git a/source/blender/blenfont/intern/blf_util.c b/source/blender/blenfont/intern/blf_util.c
index 06309a944e9..cdd81e33b0a 100644
--- a/source/blender/blenfont/intern/blf_util.c
+++ b/source/blender/blenfont/intern/blf_util.c
@@ -38,7 +38,6 @@
#include "blf_internal.h"
#include "BLI_utildefines.h"
-#include "BLI_string_utf8.h"
unsigned int blf_next_p2(unsigned int x)
{
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 229d2fc17cd..236eae29967 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -88,6 +88,7 @@ struct MTFace;
struct Object;
struct Scene;
struct Mesh;
+struct MLoopNorSpaceArray;
struct BMEditMesh;
struct KeyBlock;
struct ModifierData;
@@ -147,6 +148,7 @@ typedef int (*DMSetMaterial)(int mat_nr, void *attribs);
typedef int (*DMCompareDrawOptions)(void *userData, int cur_index, int next_index);
typedef void (*DMSetDrawInterpOptions)(void *userData, int index, float t);
typedef DMDrawOption (*DMSetDrawOptions)(void *userData, int index);
+typedef DMDrawOption (*DMSetDrawOptionsMappedTex)(void *userData, int origindex, int mat_nr);
typedef DMDrawOption (*DMSetDrawOptionsTex)(struct MTFace *tface, const bool has_vcol, int matnr);
typedef enum DMDrawFlag {
@@ -196,7 +198,11 @@ struct DerivedMesh {
void (*calcNormals)(DerivedMesh *dm);
/** Calculate loop (split) normals */
- void (*calcLoopNormals)(DerivedMesh *dm, const float split_angle);
+ void (*calcLoopNormals)(DerivedMesh *dm, const bool use_split_normals, const float split_angle);
+
+ /** Calculate loop (split) normals, and returns split loop normal spacearr. */
+ void (*calcLoopNormalsSpaceArray)(DerivedMesh *dm, const bool use_split_normals, const float split_angle,
+ struct MLoopNorSpaceArray *r_lnors_spacearr);
/** Recalculates mesh tessellation */
void (*recalcTessellation)(DerivedMesh *dm);
@@ -423,7 +429,7 @@ struct DerivedMesh {
* - Drawing options too complicated to enumerate, look at code.
*/
void (*drawMappedFacesTex)(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
+ DMSetDrawOptionsMappedTex setDrawOptions,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag uvflag);
@@ -497,7 +503,7 @@ int DM_release(DerivedMesh *dm);
/** utility function to convert a DerivedMesh to a Mesh
*/
-void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob, CustomDataMask mask);
+void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob, CustomDataMask mask, bool take_ownership);
struct BMEditMesh *DM_to_editbmesh(struct DerivedMesh *dm,
struct BMEditMesh *existing, const bool do_tessellate);
@@ -745,6 +751,8 @@ typedef struct DMVertexAttribs {
void DM_vertex_attributes_from_gpu(DerivedMesh *dm,
struct GPUVertexAttribs *gattribs, DMVertexAttribs *attribs);
+void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert);
+
void DM_add_tangent_layer(DerivedMesh *dm);
void DM_calc_auto_bump_scale(DerivedMesh *dm);
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index e79822daa4d..0acfd40a110 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -73,6 +73,20 @@ bool BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const bool do_ac
/* Copy AnimData Actions */
void BKE_copy_animdata_id_action(struct ID *id);
+/* Merge copies of data from source AnimData block */
+typedef enum eAnimData_MergeCopy_Modes {
+ /* Keep destination action */
+ ADT_MERGECOPY_KEEP_DST = 0,
+
+ /* Use src action (make a new copy) */
+ ADT_MERGECOPY_SRC_COPY = 1,
+
+ /* Use src action (but just reference the existing version) */
+ ADT_MERGECOPY_SRC_REF = 2
+} eAnimData_MergeCopy_Modes;
+
+void BKE_animdata_merge_copy(struct ID *dst_id, struct ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers);
+
/* Make Local */
void BKE_animdata_make_local(struct AnimData *adt);
@@ -106,7 +120,11 @@ void BKE_keyingsets_free(struct ListBase *list);
/* ************************************* */
/* Path Fixing API */
-/* Fix all the paths for the the given ID + Action */
+/* Get a "fixed" version of the given path (oldPath) */
+char *BKE_animsys_fix_rna_path_rename(ID *owner_id, char *old_path, const char *prefix, const char *oldName,
+ const char *newName, int oldSubscript, int newSubscript, bool verify_paths);
+
+/* Fix all the paths for the given ID + Action */
void BKE_action_fix_paths_rename(struct ID *owner_id, struct bAction *act, const char *prefix, const char *oldName,
const char *newName, int oldSubscript, int newSubscript, bool verify_paths);
diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h
new file mode 100644
index 00000000000..5e42f17be03
--- /dev/null
+++ b/source/blender/blenkernel/BKE_appdir.h
@@ -0,0 +1,80 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_APPDIR_H__
+#define __BKE_APPDIR_H__
+
+/** \file BKE_appdir.h
+ * \ingroup bli
+ */
+
+/* note on naming: typical _get() suffix is omitted here,
+ * since its the main purpose of the API. */
+const char *BKE_appdir_folder_default(void);
+const char *BKE_appdir_folder_id(const int folder_id, const char *subfolder);
+const char *BKE_appdir_folder_id_create(const int folder_id, const char *subfolder);
+const char *BKE_appdir_folder_id_user_notest(const int folder_id, const char *subfolder);
+const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, const bool do_check);
+
+/* Initialize path to program executable */
+void BKE_appdir_program_path_init(const char *argv0);
+
+const char *BKE_appdir_program_path(void);
+const char *BKE_appdir_program_dir(void);
+
+/* Initialize path to temporary directory. */
+void BKE_tempdir_init(char *userdir);
+void BKE_tempdir_system_init(char *dir);
+
+const char *BKE_tempdir_base(void);
+const char *BKE_tempdir_session(void);
+void BKE_tempdir_session_purge(void);
+
+
+/* folder_id */
+enum {
+ /* general, will find based on user/local/system priority */
+ BLENDER_DATAFILES = 2,
+
+ /* user-specific */
+ BLENDER_USER_CONFIG = 31,
+ BLENDER_USER_DATAFILES = 32,
+ BLENDER_USER_SCRIPTS = 33,
+ BLENDER_USER_AUTOSAVE = 34,
+
+ /* system */
+ BLENDER_SYSTEM_DATAFILES = 52,
+ BLENDER_SYSTEM_SCRIPTS = 53,
+ BLENDER_SYSTEM_PYTHON = 54,
+};
+
+/* for BKE_appdir_folder_id_version only */
+enum {
+ BLENDER_RESOURCE_PATH_USER = 0,
+ BLENDER_RESOURCE_PATH_LOCAL = 1,
+ BLENDER_RESOURCE_PATH_SYSTEM = 2,
+};
+
+#define BLENDER_STARTUP_FILE "startup.blend"
+#define BLENDER_USERPREF_FILE "userpref.blend"
+#define BLENDER_QUIT_FILE "quit.blend"
+#define BLENDER_BOOKMARK_FILE "bookmarks.txt"
+#define BLENDER_HISTORY_FILE "recent-files.txt"
+
+#endif /* __BKE_APPDIR_H__ */
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index fdf0795fe02..66e204e51e0 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -87,6 +87,8 @@ int bone_autoside_name(char name[64], int strip_number, short axis, float head,
struct Bone *BKE_armature_find_bone_name(struct bArmature *arm, const char *name);
+bool BKE_armature_bone_flag_test_recursive(const struct Bone *bone, int flag);
+
float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3], float r1, float r2, float rdist);
void BKE_armature_where_is(struct bArmature *arm);
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 6c8f90c60ae..dad7f1916a1 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -41,9 +41,9 @@ extern "C" {
/* these lines are grep'd, watch out for our not-so-awesome regex
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
-#define BLENDER_VERSION 272
-#define BLENDER_SUBVERSION 1
-/* 262 was the last editmesh release but it has compatibility code for bmesh data */
+#define BLENDER_VERSION 274
+#define BLENDER_SUBVERSION 0
+/* Several breakages with 270, e.g. constraint deg vs rad */
#define BLENDER_MINVERSION 270
#define BLENDER_MINSUBVERSION 5
@@ -88,7 +88,7 @@ void BKE_userdef_free(void);
void BKE_userdef_state(void);
/* set this callback when a UI is running */
-void set_blender_test_break_cb(void (*func)(void) );
+void set_blender_test_break_cb(void (*func)(void));
int blender_test_break(void);
#define BKE_UNDO_STR_MAX 64
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index d48753590bb..49975fa0276 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -62,12 +62,11 @@ int BKE_brush_clone_image_delete(struct Brush *brush);
/* jitter */
void BKE_brush_jitter_pos(const struct Scene *scene, struct Brush *brush,
const float pos[2], float jitterpos[2]);
-void BKE_brush_randomize_texture_coordinates(struct UnifiedPaintSettings *ups, bool mask);
+void BKE_brush_randomize_texture_coords(struct UnifiedPaintSettings *ups, bool mask);
/* brush curve */
void BKE_brush_curve_preset(struct Brush *b, int preset);
-float BKE_brush_curve_strength_clamp(struct Brush *br, float p, const float len);
-float BKE_brush_curve_strength(struct Brush *br, float p, const float len); /* used for sculpt */
+float BKE_brush_curve_strength(struct Brush *br, float p, const float len);
/* sampling */
float BKE_brush_sample_tex_3D(const Scene *scene, struct Brush *br, const float point[3],
diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index 4bc8fc44bb4..a360511dcd3 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -31,6 +31,7 @@
* \ingroup bke
*/
+#include "BLI_bitmap.h"
#include "BLI_kdopbvh.h"
/*
@@ -56,8 +57,8 @@ typedef struct BVHTreeFromMesh {
struct MEdge *edge; /* only used for BVHTreeFromMeshEdges */
struct MFace *face;
bool vert_allocated;
- bool face_allocated;
bool edge_allocated;
+ bool face_allocated;
/* radius for raycast */
float sphere_radius;
@@ -69,36 +70,28 @@ typedef struct BVHTreeFromMesh {
} BVHTreeFromMesh;
/*
- * Builds a bvh tree where nodes are the vertexs of the given mesh.
+ * Builds a bvh tree where nodes are the relevant elements of the given mesh.
* Configures BVHTreeFromMesh.
*
* The tree is build in mesh space coordinates, this means special care must be made on queries
* so that the coordinates and rays are first translated on the mesh local coordinates.
- * Reason for this is that later bvh_from_mesh_* might use a cache system and so it becomes possible to reuse
- * a BVHTree.
+ * Reason for this is that bvh_from_mesh_* can use a cache in some cases and so it becomes possible to reuse a BVHTree.
*
* free_bvhtree_from_mesh should be called when the tree is no longer needed.
*/
BVHTree *bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
-
-/*
- * Builds a bvh tree where nodes are the faces of the given mesh.
- * Configures BVHTreeFromMesh.
- *
- * The tree is build in mesh space coordinates, this means special care must be made on queries
- * so that the coordinates and rays are first translated on the mesh local coordinates.
- * Reason for this is that later bvh_from_mesh_* might use a cache system and so it becomes possible to reuse
- * a BVHTree.
- *
- * The returned value is the same as in data->tree, its only returned to make it easier to test
- * the success
- *
- * free_bvhtree_from_mesh should be called when the tree is no longer needed.
- */
-BVHTree *bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
+BVHTree *bvhtree_from_mesh_verts_ex(struct BVHTreeFromMesh *data, struct MVert *vert, const int numVerts,
+ const bool vert_allocated, BLI_bitmap *mask, int numVerts_active,
+ float epsilon, int tree_type, int axis);
BVHTree *bvhtree_from_mesh_edges(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
+BVHTree *bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
+BVHTree *bvhtree_from_mesh_faces_ex(struct BVHTreeFromMesh *data, struct MVert *vert, const bool vert_allocated,
+ struct MFace *face, const int numFaces, const bool face_allocated,
+ BLI_bitmap *mask, int numFaces_active,
+ float epsilon, int tree_type, int axis);
+
/*
* Frees data allocated by a call to bvhtree_from_mesh_*.
*/
@@ -114,12 +107,13 @@ float nearest_point_in_tri_surface_squared(const float v0[3], const float v1[3],
* BVHCache
*/
-//Using local coordinates
-#define BVHTREE_FROM_FACES 0
-#define BVHTREE_FROM_VERTICES 1
-#define BVHTREE_FROM_EDGES 2
-
-#define BVHTREE_FROM_FACES_EDITMESH 3
+/* Using local coordinates */
+enum {
+ BVHTREE_FROM_VERTS = 0,
+ BVHTREE_FROM_EDGES = 1,
+ BVHTREE_FROM_FACES = 2,
+ BVHTREE_FROM_FACES_EDITMESH = 3,
+};
typedef struct LinkNode *BVHCache;
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 01b401c6bcc..77296920ee2 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -46,6 +46,7 @@ struct RenderData;
struct Scene;
struct rctf;
struct View3D;
+struct GPUFXSettings;
/* Camera Datablock */
@@ -118,7 +119,11 @@ void BKE_camera_view_frame_ex(struct Scene *scene, struct Camera *camera, float
void BKE_camera_view_frame(struct Scene *scene, struct Camera *camera, float r_vec[4][3]);
bool BKE_camera_view_frame_fit_to_scene(struct Scene *scene, struct View3D *v3d, struct Object *camera_ob,
- float r_co[3]);
+ float r_co[3], float *r_scale);
+bool BKE_camera_view_frame_fit_to_coords(struct Scene *scene, float (*cos)[3], int num_cos,
+ struct Object *camera_ob, float r_co[3], float *r_scale);
+
+void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_settings);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index b0ade7bacdf..59ec316a403 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -40,6 +40,7 @@
struct DerivedMesh;
struct BMEditMesh;
struct Mesh;
+struct MLoopNorSpaceArray;
struct Object;
/* creates a new CDDerivedMesh */
@@ -106,7 +107,9 @@ void CDDM_calc_normals_mapping(struct DerivedMesh *dm);
void CDDM_calc_normals(struct DerivedMesh *dm);
void CDDM_calc_normals_tessface(struct DerivedMesh *dm);
-void CDDM_calc_loop_normals(struct DerivedMesh *dm, const float split_angle);
+void CDDM_calc_loop_normals(struct DerivedMesh *dm, const bool use_split_normals, const float split_angle);
+void CDDM_calc_loop_normals_spacearr(struct DerivedMesh *dm, const bool use_split_normals, const float split_angle,
+ struct MLoopNorSpaceArray *r_lnors_spacearr);
/* calculates edges for a CDDerivedMesh (from face data)
* this completely replaces the current edge data in the DerivedMesh
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 757d63e6ec1..a7fad85ed42 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -41,7 +41,10 @@ struct Scene;
struct MFace;
struct DerivedMesh;
struct ClothModifierData;
+struct CollisionModifierData;
struct CollisionTree;
+struct VoxelData;
+struct PartDeflect;
#define DO_INLINE MALWAYS_INLINE
@@ -53,8 +56,26 @@ struct CollisionTree;
#define ALMOST_ZERO FLT_EPSILON
/* Bits to or into the ClothVertex.flags. */
-#define CLOTH_VERT_FLAG_PINNED 1
-#define CLOTH_VERT_FLAG_NOSELFCOLL 2 /* vertex NOT used for self collisions */
+typedef enum eClothVertexFlag {
+ CLOTH_VERT_FLAG_PINNED = 1,
+ CLOTH_VERT_FLAG_NOSELFCOLL = 2, /* vertex NOT used for self collisions */
+} eClothVertexFlag;
+
+typedef struct ClothHairData {
+ float loc[3];
+ float rot[3][3];
+ float rest_target[3]; /* rest target direction for each segment */
+ float radius;
+ float bending_stiffness;
+} ClothHairData;
+
+typedef struct ClothSolverResult {
+ int status;
+
+ int max_iterations, min_iterations;
+ float avg_iterations;
+ float max_error, min_error, avg_error;
+} ClothSolverResult;
/**
* This structure describes a cloth object against which the
@@ -79,7 +100,6 @@ typedef struct Cloth {
struct BVHTree *bvhselftree; /* collision tree for this cloth object */
struct MFace *mfaces;
struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */
- struct Implicit_Data *implicitEM; /* our implicit solver connects to this pointer */
struct EdgeSet *edgeset; /* used for selfcollisions */
int last_frame, pad4;
} Cloth;
@@ -116,8 +136,8 @@ ClothVertex;
typedef struct ClothSpring {
int ij; /* Pij from the paper, one end of the spring. */
int kl; /* Pkl from the paper, one end of the spring. */
+ int mn;
float restlen; /* The original length of the spring. */
- int matrix_index; /* needed for implicit solver (fast lookup) */
int type; /* types defined in BKE_cloth.h ("springType") */
int flags; /* defined in BKE_cloth.h, e.g. deactivated due to tearing */
float dfdx[3][3];
@@ -125,6 +145,9 @@ typedef struct ClothSpring {
float f[3];
float stiffness; /* stiffness factor from the vertex groups */
float editrestlen;
+
+ /* angular bending spring target and derivatives */
+ float target[3];
}
ClothSpring;
@@ -166,7 +189,8 @@ typedef enum {
CLOTH_SPRING_TYPE_SHEAR = (1 << 2),
CLOTH_SPRING_TYPE_BENDING = (1 << 3),
CLOTH_SPRING_TYPE_GOAL = (1 << 4),
- CLOTH_SPRING_TYPE_SEWING = (1 << 5)
+ CLOTH_SPRING_TYPE_SEWING = (1 << 5),
+ CLOTH_SPRING_TYPE_BENDING_ANG = (1 << 6),
} CLOTH_SPRING_TYPES;
/* SPRING FLAGS */
@@ -180,21 +204,25 @@ typedef enum {
// collision.c
////////////////////////////////////////////////
+struct CollPair;
+
+typedef struct ColliderContacts {
+ struct Object *ob;
+ struct CollisionModifierData *collmd;
+
+ struct CollPair *collisions;
+ int totcollisions;
+} ColliderContacts;
+
// needed for implicit.c
int cloth_bvh_objcollision (struct Object *ob, struct ClothModifierData *clmd, float step, float dt );
+int cloth_points_objcollision(struct Object *ob, struct ClothModifierData *clmd, float step, float dt);
-////////////////////////////////////////////////
-
+void cloth_find_point_contacts(struct Object *ob, struct ClothModifierData *clmd, float step, float dt,
+ ColliderContacts **r_collider_contacts, int *r_totcolliders);
+void cloth_free_contacts(ColliderContacts *collider_contacts, int totcolliders);
////////////////////////////////////////////////
-// implicit.c
-////////////////////////////////////////////////
-
-// needed for cloth.c
-int implicit_init (struct Object *ob, struct ClothModifierData *clmd );
-int implicit_free (struct ClothModifierData *clmd );
-int implicit_solver (struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors );
-void implicit_set_positions (struct ClothModifierData *clmd );
/////////////////////////////////////////////////
// cloth.c
@@ -218,27 +246,9 @@ void cloth_clear_cache (struct Object *ob, struct ClothModifierData *clmd, float
// needed for cloth.c
int cloth_add_spring (struct ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type);
-////////////////////////////////////////////////
-
-
-/* This enum provides the IDs for our solvers. */
-// only one available in the moment
-typedef enum {
- CM_IMPLICIT = 0,
-} CM_SOLVER_ID;
-
-
-/* This structure defines how to call the solver.
- */
-typedef struct {
- const char *name;
- CM_SOLVER_ID id;
- int ( *init ) (struct Object *ob, struct ClothModifierData *clmd );
- int ( *solver ) (struct Object *ob, float framenr, struct ClothModifierData *clmd, struct ListBase *effectors );
- int ( *free ) (struct ClothModifierData *clmd );
-}
-CM_SOLVER_DEF;
+void cloth_parallel_transport_hair_frame(float mat[3][3], const float dir_old[3], const float dir_new[3]);
+////////////////////////////////////////////////
#endif
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index ec257a2f394..b81b8f04817 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -81,6 +81,8 @@ typedef struct CollPair {
float pa[3], pb[3]; // collision point p1 on face1, p2 on face2
int flag;
float time; // collision time, from 0 up to 1
+
+ /* mesh-mesh collision */
#ifdef WITH_ELTOPO /*either ap* or bp* can be set, but not both*/
float bary[3];
int ap1, ap2, ap3, collp, bp1, bp2, bp3;
@@ -135,6 +137,8 @@ void bvhtree_update_from_mvert(BVHTree *bvhtree, struct MFace *faces, int numfac
// defined in collisions.c
void collision_move_object(struct CollisionModifierData *collmd, float step, float prevstep);
+void collision_get_collider_velocity(float vel_old[3], float vel_new[3], struct CollisionModifierData *collmd, struct CollPair *collpair);
+
/////////////////////////////////////////////////
// used in effect.c
/////////////////////////////////////////////////
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 87da74dc119..1346feec82c 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -118,10 +118,12 @@ bConstraintTypeInfo *BKE_constraint_typeinfo_from_type(int type);
void BKE_constraint_unique_name(struct bConstraint *con, struct ListBase *list);
void BKE_constraints_free(struct ListBase *list);
+void BKE_constraints_free_ex(struct ListBase *list, bool do_id_user);
void BKE_constraints_copy(struct ListBase *dst, const struct ListBase *src, bool do_extern);
void BKE_constraints_relink(struct ListBase *list);
void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, void *userdata);
void BKE_constraint_free_data(struct bConstraint *con);
+void BKE_constraint_free_data_ex(struct bConstraint *con, bool do_id_user);
/* Constraint API function prototypes */
struct bConstraint *BKE_constraints_active_get(struct ListBase *list);
@@ -131,6 +133,7 @@ struct bConstraint *BKE_constraints_find_name(struct ListBase *list, const char
struct bConstraint *BKE_constraint_add_for_object(struct Object *ob, const char *name, short type);
struct bConstraint *BKE_constraint_add_for_pose(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type);
+bool BKE_constraint_remove_ex(ListBase *list, struct Object *ob, struct bConstraint *con, bool clear_dep);
bool BKE_constraint_remove(ListBase *list, struct bConstraint *con);
/* Constraints + Proxies function prototypes */
@@ -141,7 +144,8 @@ bool BKE_constraints_proxylocked_owner(struct Object *ob, struct bPoseChannel *p
struct bConstraintOb *BKE_constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype);
void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
-void BKE_constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to);
+void BKE_constraint_mat_convertspace(
+ struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to, const bool keep_scale);
void BKE_constraint_target_matrix_get(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime);
void BKE_constraint_targets_for_solving_get(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 877e376b343..ae0ef9ce314 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -56,6 +56,9 @@ struct Text;
struct ImBuf;
struct EditBone;
struct bPoseChannel;
+struct bGPdata;
+struct bGPDlayer;
+struct bGPDframe;
struct wmWindow;
struct wmWindowManager;
struct SpaceText;
@@ -275,6 +278,14 @@ struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C);
int CTX_data_selected_pose_bones(const bContext *C, ListBase *list);
int CTX_data_visible_pose_bones(const bContext *C, ListBase *list);
+struct bGPdata *CTX_data_gpencil_data(const bContext *C);
+struct bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C);
+struct bGPDframe *CTX_data_active_gpencil_frame(const bContext *C);
+int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
+int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
+int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 253d9edc3b5..60cbf8b302e 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -85,8 +85,8 @@ void BKE_curve_texspace_get(struct Curve *cu, float r_loc[3], float r_rot[3], fl
bool BKE_curve_minmax(struct Curve *cu, bool use_radius, float min[3], float max[3]);
bool BKE_curve_center_median(struct Curve *cu, float cent[3]);
bool BKE_curve_center_bounds(struct Curve *cu, float cent[3]);
-void BKE_curve_transform_ex(struct Curve *cu, float mat[4][4], bool do_keys, const float unit_scale);
-void BKE_curve_transform(struct Curve *cu, float mat[4][4], bool do_keys);
+void BKE_curve_transform_ex(struct Curve *cu, float mat[4][4], const bool do_keys, const float unit_scale);
+void BKE_curve_transform(struct Curve *cu, float mat[4][4], const bool do_keys);
void BKE_curve_translate(struct Curve *cu, float offset[3], const bool do_keys);
void BKE_curve_material_index_remove(struct Curve *cu, int index);
void BKE_curve_material_index_clear(struct Curve *cu);
@@ -176,6 +176,7 @@ void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_p
void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next,
const bool is_fcurve);
void BKE_nurb_handle_calc_simple(struct Nurb *nu, struct BezTriple *bezt);
+void BKE_nurb_handle_calc_simple_auto(struct Nurb *nu, struct BezTriple *bezt);
void BKE_nurb_handles_calc(struct Nurb *nu);
void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 51c78948c70..6a0cfefb1c2 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -41,6 +41,8 @@ extern "C" {
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
+#include "DNA_customdata_types.h"
+
struct BMesh;
struct ID;
struct CustomData;
@@ -77,6 +79,9 @@ extern const CustomDataMask CD_MASK_EVERYTHING;
void customData_mask_layers__print(CustomDataMask mask);
+typedef void (*cd_interp)(const void **sources, const float *weights, const float *sub_weights, int count, void *dest);
+typedef void (*cd_copy)(const void *source, void *dest, int count);
+
/**
* Checks if the layer at physical offset \a layer_n (in data->layers) support math
* the below operations.
@@ -91,11 +96,19 @@ bool CustomData_has_math(const struct CustomData *data);
bool CustomData_has_interp(const struct CustomData *data);
bool CustomData_bmesh_has_free(const struct CustomData *data);
+/**
+ * Checks if any of the customdata layers is referenced.
+ */
+bool CustomData_has_referenced(const struct CustomData *data);
+
/* copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
* another, while not overwriting anything else (e.g. flags). probably only
* implemented for mloopuv/mloopcol, for now.*/
void CustomData_data_copy_value(int type, const void *source, void *dest);
+/* Same as above, but doing advanced mixing. Only available for a few types of data (like colors...). */
+void CustomData_data_mix_value(int type, const void *source, void *dest, const int mixmode, const float mixfactor);
+
/* compares if data1 is equal to data2. type is a valid CustomData type
* enum (e.g. CD_MLOOPUV). the layer type's equal function is used to compare
* the data, if it exists, otherwise memcmp is used.*/
@@ -122,8 +135,9 @@ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest,
/* bmesh version of CustomData_merge; merges the layouts of source and dest,
* then goes through the mesh and makes sure all the customdata blocks are
* consistent with the new layout.*/
-bool CustomData_bmesh_merge(struct CustomData *source, struct CustomData *dest,
- CustomDataMask mask, int alloctype, struct BMesh *bm, const char htype);
+bool CustomData_bmesh_merge(
+ const struct CustomData *source, struct CustomData *dest,
+ CustomDataMask mask, int alloctype, struct BMesh *bm, const char htype);
/** NULL's all members and resets the typemap. */
void CustomData_reset(struct CustomData *data);
@@ -133,6 +147,9 @@ void CustomData_reset(struct CustomData *data);
*/
void CustomData_free(struct CustomData *data, int totelem);
+/* same as above, but only frees layers which matches the given mask. */
+void CustomData_free_typemask(struct CustomData *data, int totelem, CustomDataMask mask);
+
/* frees all layers with CD_FLAG_TEMPORARY */
void CustomData_free_temporary(struct CustomData *data, int totelem);
@@ -173,6 +190,7 @@ int CustomData_number_of_layers_typemask(const struct CustomData *data, CustomDa
/* duplicate data of a layer with flag NOFREE, and remove that flag.
* returns the layer data */
void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem);
+void *CustomData_duplicate_referenced_layer_n(struct CustomData *data, const int type, const int n, const int totelem);
void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
const int type, const char *name, const int totelem);
bool CustomData_is_referenced_layer(struct CustomData *data, int type);
@@ -195,7 +213,7 @@ void CustomData_copy_data(const struct CustomData *source,
void CustomData_copy_data_named(const struct CustomData *source,
struct CustomData *dest, int source_index,
int dest_index, int count);
-void CustomData_copy_elements(int type, void *source, void *dest, int count);
+void CustomData_copy_elements(int type, void *src_data_ofs, void *dst_data_ofs, int count);
void CustomData_bmesh_copy_data(const struct CustomData *source,
struct CustomData *dest, void *src_block,
void **dest_block);
@@ -217,14 +235,17 @@ void CustomData_free_elem(struct CustomData *data, int index, int count);
* count gives the number of source elements to interpolate from
* dest_index gives the dest element to write the interpolated value to
*/
-void CustomData_interp(const struct CustomData *source, struct CustomData *dest,
- int *src_indices, float *weights, float *sub_weights,
- int count, int dest_index);
-void CustomData_bmesh_interp_n(struct CustomData *data, void **src_blocks, const float *weights,
- const float *sub_weights, int count, void *dest_block, int n);
-void CustomData_bmesh_interp(struct CustomData *data, void **src_blocks,
- const float *weights, const float *sub_weights, int count,
- void *dest_block);
+void CustomData_interp(
+ const struct CustomData *source, struct CustomData *dest,
+ int *src_indices, float *weights, float *sub_weights,
+ int count, int dest_index);
+void CustomData_bmesh_interp_n(
+ struct CustomData *data, const void **src_blocks, const float *weights,
+ const float *sub_weights, int count, void *dst_block_ofs, int n);
+void CustomData_bmesh_interp(
+ struct CustomData *data, const void **src_blocks,
+ const float *weights, const float *sub_weights, int count,
+ void *dst_block);
/* swaps the data in the element corners, to new corners with indices as
@@ -245,14 +266,14 @@ void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int typ
void *CustomData_bmesh_get_layer_n(const struct CustomData *data, void *block, int n);
bool CustomData_set_layer_name(const struct CustomData *data, int type, int n, const char *name);
+const char *CustomData_get_layer_name(const struct CustomData *data, int type, int n);
/* gets a pointer to the active or first layer of type
* returns NULL if there is no layer of type
*/
void *CustomData_get_layer(const struct CustomData *data, int type);
void *CustomData_get_layer_n(const struct CustomData *data, int type, int n);
-void *CustomData_get_layer_named(const struct CustomData *data, int type,
- const char *name);
+void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name);
int CustomData_get_offset(const struct CustomData *data, int type);
int CustomData_get_n_offset(const struct CustomData *data, int type, int n);
@@ -273,19 +294,23 @@ int CustomData_get_stencil_layer(const struct CustomData *data, int type);
* layer of type
* no effect if there is no layer of type
*/
-void CustomData_set(const struct CustomData *data, int index, int type,
- void *source);
+void CustomData_set(
+ const struct CustomData *data, int index, int type,
+ const void *source);
-void CustomData_bmesh_set(const struct CustomData *data, void *block, int type,
- void *source);
+void CustomData_bmesh_set(
+ const struct CustomData *data, void *block, int type,
+ const void *source);
-void CustomData_bmesh_set_n(struct CustomData *data, void *block, int type, int n,
- void *source);
+void CustomData_bmesh_set_n(
+ struct CustomData *data, void *block, int type, int n,
+ const void *source);
/* sets the data of the block at physical layer n. no real type checking
* is performed.
*/
-void CustomData_bmesh_set_layer_n(struct CustomData *data, void *block, int n,
- void *source);
+void CustomData_bmesh_set_layer_n(
+ struct CustomData *data, void *block, int n,
+ const void *source);
/* set the pointer of to the first layer of type. the old data is not freed.
* returns the value of ptr if the layer is found, NULL otherwise
@@ -361,6 +386,84 @@ void CustomData_external_read(struct CustomData *data,
void CustomData_external_reload(struct CustomData *data,
struct ID *id, CustomDataMask mask, int totelem);
+/* Mesh-to-mesh transfer data. */
+
+struct MeshPairRemap;
+struct CustomDataTransferLayerMap;
+
+typedef void (*cd_datatransfer_interp)(
+ const struct CustomDataTransferLayerMap *laymap, void *dest,
+ const void **sources, const float *weights, const int count, const float mix_factor);
+
+/**
+ * Fake CD_LAYERS (those are actually 'real' data stored directly into elements' structs, or otherwise not (directly)
+ * accessible to usual CDLayer system). */
+enum {
+ CD_FAKE = 1 << 8,
+
+ /* Vertices. */
+ CD_FAKE_MDEFORMVERT = CD_FAKE | CD_MDEFORMVERT, /* *sigh* due to how vgroups are stored :( . */
+ CD_FAKE_SHAPEKEY = CD_FAKE | CD_SHAPEKEY, /* Not available as real CD layer in non-bmesh context. */
+
+ /* Edges. */
+ CD_FAKE_SEAM = CD_FAKE | 100, /* UV seam flag for edges. */
+ CD_FAKE_CREASE = CD_FAKE | CD_CREASE, /* *sigh*. */
+
+ /* Multiple types of mesh elements... */
+ CD_FAKE_BWEIGHT = CD_FAKE | CD_BWEIGHT, /* *sigh*. */
+ CD_FAKE_UV = CD_FAKE | CD_MLOOPUV, /* UV flag, because we handle both loop's UVs and poly's textures. */
+
+ CD_FAKE_LNOR = CD_FAKE | CD_CUSTOMLOOPNORMAL, /* Because we play with clnor and temp lnor layers here. */
+
+ CD_FAKE_SHARP = CD_FAKE | 200, /* Sharp flag for edges, smooth flag for faces. */
+};
+
+enum {
+ ME_VERT = 1 << 0,
+ ME_EDGE = 1 << 1,
+ ME_POLY = 1 << 2,
+ ME_LOOP = 1 << 3,
+};
+
+/**
+ * How to filter out some elements (to leave untouched).
+ * Note those options are highly dependent on type of transferred data! */
+enum {
+ CDT_MIX_NOMIX = -1, /* Special case, only used because we abuse 'copy' CD callback. */
+ CDT_MIX_TRANSFER = 0,
+ CDT_MIX_REPLACE_ABOVE_THRESHOLD = 1,
+ CDT_MIX_REPLACE_BELOW_THRESHOLD = 2,
+ CDT_MIX_MIX = 16,
+ CDT_MIX_ADD = 17,
+ CDT_MIX_SUB = 18,
+ CDT_MIX_MUL = 19,
+ /* etc. etc. */
+};
+
+typedef struct CustomDataTransferLayerMap {
+ struct CustomDataTransferLayerMap *next, *prev;
+
+ int data_type;
+ int mix_mode;
+ float mix_factor;
+ const float *mix_weights; /* If non-NULL, array of weights, one for each dest item, replaces mix_factor. */
+
+ const void *data_src; /* Data source array (can be regular CD data, vertices/edges/etc., keyblocks...). */
+ void *data_dst; /* Data dest array (same type as dat_src). */
+ int data_src_n; /* Index to affect in data_src (used e.g. for vgroups). */
+ int data_dst_n; /* Index to affect in data_dst (used e.g. for vgroups). */
+ size_t elem_size; /* Size of one element of data_src/data_dst. */
+
+ size_t data_size; /* Size of actual data we transfer. */
+ size_t data_offset; /* Offset of actual data we transfer (in element contained in data_src/dst). */
+ uint64_t data_flag; /* For bitflag transfer, flag(s) to affect in transfered data. */
+
+ cd_datatransfer_interp interp;
+} CustomDataTransferLayerMap;
+
+/* Those functions assume src_n and dst_n layers of given type exist in resp. src and dst. */
+void CustomData_data_transfer(const struct MeshPairRemap *me_remap, const CustomDataTransferLayerMap *laymap);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_customdata_file.h b/source/blender/blenkernel/BKE_customdata_file.h
index 978db8a6c1a..242897f968f 100644
--- a/source/blender/blenkernel/BKE_customdata_file.h
+++ b/source/blender/blenkernel/BKE_customdata_file.h
@@ -40,14 +40,14 @@ void cdf_free(CDataFile *cdf);
/* File read/write/remove */
-int cdf_read_open(CDataFile *cdf, const char *filename);
-int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay);
-int cdf_read_data(CDataFile *cdf, unsigned int size, void *data);
+bool cdf_read_open(CDataFile *cdf, const char *filename);
+bool cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay);
+bool cdf_read_data(CDataFile *cdf, unsigned int size, void *data);
void cdf_read_close(CDataFile *cdf);
-int cdf_write_open(CDataFile *cdf, const char *filename);
-int cdf_write_layer(CDataFile *cdf, CDataFileLayer *blay);
-int cdf_write_data(CDataFile *cdf, unsigned int size, void *data);
+bool cdf_write_open(CDataFile *cdf, const char *filename);
+bool cdf_write_layer(CDataFile *cdf, CDataFileLayer *blay);
+bool cdf_write_data(CDataFile *cdf, unsigned int size, void *data);
void cdf_write_close(CDataFile *cdf);
void cdf_remove(const char *filename);
diff --git a/source/blender/blenkernel/BKE_data_transfer.h b/source/blender/blenkernel/BKE_data_transfer.h
new file mode 100644
index 00000000000..cea093adca4
--- /dev/null
+++ b/source/blender/blenkernel/BKE_data_transfer.h
@@ -0,0 +1,159 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Bastien Montagne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/BKE_data_transfer.h
+ * \ingroup bke
+ */
+
+#ifndef __BKE_DATA_TRANSFER_H__
+#define __BKE_DATA_TRANSFER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "BKE_customdata.h"
+
+struct Object;
+struct Scene;
+struct SpaceTransform;
+struct ReportList;
+
+/* Warning, those def are stored in files (TransferData modifier), *DO NOT* modify those values. */
+enum {
+ DT_TYPE_MDEFORMVERT = 1 << 0,
+ DT_TYPE_SHAPEKEY = 1 << 1,
+ DT_TYPE_SKIN = 1 << 2,
+ DT_TYPE_BWEIGHT_VERT = 1 << 3,
+
+ DT_TYPE_SHARP_EDGE = 1 << 8,
+ DT_TYPE_SEAM = 1 << 9,
+ DT_TYPE_CREASE = 1 << 10,
+ DT_TYPE_BWEIGHT_EDGE = 1 << 11,
+ DT_TYPE_FREESTYLE_EDGE = 1 << 12,
+
+ DT_TYPE_VCOL = 1 << 16,
+ DT_TYPE_LNOR = 1 << 17,
+
+ DT_TYPE_UV = 1 << 24,
+ DT_TYPE_SHARP_FACE = 1 << 25,
+ DT_TYPE_FREESTYLE_FACE = 1 << 26,
+#define \
+ DT_TYPE_MAX 27
+
+ DT_TYPE_VERT_ALL = DT_TYPE_MDEFORMVERT | DT_TYPE_SHAPEKEY | DT_TYPE_SKIN | DT_TYPE_BWEIGHT_VERT,
+ DT_TYPE_EDGE_ALL = DT_TYPE_SHARP_EDGE | DT_TYPE_SEAM | DT_TYPE_CREASE | DT_TYPE_BWEIGHT_EDGE |
+ DT_TYPE_FREESTYLE_EDGE,
+ DT_TYPE_LOOP_ALL = DT_TYPE_VCOL | DT_TYPE_LNOR | DT_TYPE_UV,
+ DT_TYPE_POLY_ALL = DT_TYPE_UV | DT_TYPE_SHARP_FACE | DT_TYPE_FREESTYLE_FACE,
+};
+
+
+CustomDataMask BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types);
+bool BKE_object_data_transfer_get_dttypes_capacity(
+ const int dtdata_types, bool *r_advanced_mixing, bool *r_threshold);
+int BKE_object_data_transfer_get_dttypes_item_types(const int dtdata_types);
+
+int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type);
+int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type);
+
+#define DT_DATATYPE_IS_VERT(_dt) \
+ ELEM(_dt, DT_TYPE_MDEFORMVERT, DT_TYPE_SHAPEKEY, DT_TYPE_SKIN, DT_TYPE_BWEIGHT_VERT)
+#define DT_DATATYPE_IS_EDGE(_dt) \
+ ELEM(_dt, DT_TYPE_CREASE, DT_TYPE_SHARP_EDGE, DT_TYPE_SEAM, DT_TYPE_BWEIGHT_EDGE, DT_TYPE_FREESTYLE_EDGE)
+#define DT_DATATYPE_IS_LOOP(_dt) \
+ ELEM(_dt, DT_TYPE_UV, DT_TYPE_VCOL, DT_TYPE_LNOR)
+#define DT_DATATYPE_IS_POLY(_dt) \
+ ELEM(_dt, DT_TYPE_UV, DT_TYPE_SHARP_FACE, DT_TYPE_FREESTYLE_FACE)
+
+#define DT_DATATYPE_IS_MULTILAYERS(_dt) \
+ ELEM(_dt, DT_TYPE_MDEFORMVERT, DT_TYPE_SHAPEKEY, DT_TYPE_VCOL, DT_TYPE_UV)
+
+
+enum {
+ DT_MULTILAYER_INDEX_INVALID = -1,
+ DT_MULTILAYER_INDEX_MDEFORMVERT = 0,
+ DT_MULTILAYER_INDEX_SHAPEKEY = 1,
+ DT_MULTILAYER_INDEX_VCOL = 2,
+ DT_MULTILAYER_INDEX_UV = 3,
+ DT_MULTILAYER_INDEX_MAX = 4,
+};
+
+/* Below we keep positive values for real layers idx (generated dynamically). */
+
+/* How to select data layers, for types supporting multi-layers.
+ * Here too, some options are highly dependent on type of transferred data! */
+enum {
+ DT_LAYERS_ACTIVE_SRC = -1,
+ DT_LAYERS_ALL_SRC = -2,
+ /* Datatype-specific. */
+ DT_LAYERS_VGROUP_SRC = 1 << 8,
+ DT_LAYERS_VGROUP_SRC_BONE_SELECT = -(DT_LAYERS_VGROUP_SRC | 1),
+ DT_LAYERS_VGROUP_SRC_BONE_DEFORM = -(DT_LAYERS_VGROUP_SRC | 2),
+ /* Other types-related modes... */
+};
+
+/* How to map a source layer to a destination layer, for types supporting multi-layers.
+ * Note: if no matching layer can be found, it will be created. */
+enum {
+ DT_LAYERS_ACTIVE_DST = -1, /* Only for DT_LAYERS_FROMSEL_ACTIVE. */
+ DT_LAYERS_NAME_DST = -2,
+ DT_LAYERS_INDEX_DST = -3,
+#if 0 /* TODO */
+ DT_LAYERS_CREATE_DST = -4, /* Never replace existing data in dst, always create new layers. */
+#endif
+};
+
+void BKE_object_data_transfer_layout(
+ struct Scene *scene, struct Object *ob_src, struct Object *ob_dst, const int data_types, const bool use_delete,
+ const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX]);
+
+bool BKE_object_data_transfer_mesh(
+ struct Scene *scene,
+ struct Object *ob_src, struct Object *ob_dst, const int data_types, bool use_create,
+ const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode,
+ struct SpaceTransform *space_transform, const float max_distance, const float ray_radius,
+ const float islands_handling_precision,
+ const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX],
+ const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup,
+ struct ReportList *reports);
+bool BKE_object_data_transfer_dm(
+ struct Scene *scene,
+ struct Object *ob_src, struct Object *ob_dst, struct DerivedMesh *dm_dst,
+ const int data_types, bool use_create,
+ const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode,
+ struct SpaceTransform *space_transform, const float max_distance, const float ray_radius,
+ const float islands_handling_precision,
+ const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX],
+ const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup,
+ struct ReportList *reports);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BKE_DATA_TRANSFER_H__ */
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index e203549fef5..08312035e40 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -39,6 +39,10 @@ struct Object;
struct ListBase;
struct bDeformGroup;
struct MDeformVert;
+struct MVert;
+struct MEdge;
+struct MLoop;
+struct MPoly;
struct bDeformGroup *BKE_defgroup_new(struct Object *ob, const char *name);
void defgroup_copy_list(struct ListBase *lb1, struct ListBase *lb2);
@@ -85,6 +89,19 @@ void defvert_normalize_lock_map(struct MDeformVert *dvert,
const bool *vgroup_subset, const int vgroup_tot,
const bool *lock_flags, const int defbase_tot);
+/* Utilities to 'extract' a given vgroup into a simple float array, for verts, but also edges/polys/loops. */
+void BKE_defvert_extract_vgroup_to_vertweights(
+ struct MDeformVert *dvert, const int defgroup, const int num_verts, float *r_weights, const bool invert_vgroup);
+void BKE_defvert_extract_vgroup_to_edgeweights(
+ struct MDeformVert *dvert, const int defgroup, const int num_verts, struct MEdge *edges, const int num_edges,
+ float *r_weights, const bool invert_vgroup);
+void BKE_defvert_extract_vgroup_to_loopweights(
+ struct MDeformVert *dvert, const int defgroup, const int num_verts, struct MLoop *loops, const int num_loops,
+ float *r_weights, const bool invert_vgroup);
+void BKE_defvert_extract_vgroup_to_polyweights(
+ struct MDeformVert *dvert, const int defgroup, const int num_verts, struct MLoop *loops, const int num_loops,
+ struct MPoly *polys, const int num_polys, float *r_weights, const bool invert_vgroup);
+
/* utility function, note that MAX_VGROUP_NAME chars is the maximum string length since its only
* used with defgroups currently */
diff --git a/source/blender/blenkernel/BKE_editmesh_bvh.h b/source/blender/blenkernel/BKE_editmesh_bvh.h
index 168f700d132..3ee7dcd94b8 100644
--- a/source/blender/blenkernel/BKE_editmesh_bvh.h
+++ b/source/blender/blenkernel/BKE_editmesh_bvh.h
@@ -43,6 +43,8 @@ struct Scene;
typedef struct BMBVHTree BMBVHTree;
+typedef bool (*BMBVHTree_FaceFilter)(struct BMFace *f, void *userdata);
+
BMBVHTree *BKE_bmbvh_new_from_editmesh(
struct BMEditMesh *em, int flag,
const float (*cos_cage)[3], const bool cos_cage_free);
@@ -55,8 +57,16 @@ BMBVHTree *BKE_bmbvh_new(
const float (*cos_cage)[3], const bool cos_cage_free);
void BKE_bmbvh_free(BMBVHTree *tree);
struct BVHTree *BKE_bmbvh_tree_get(BMBVHTree *tree);
-struct BMFace *BKE_bmbvh_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], const float radius,
- float *r_dist, float r_hitout[3], float r_cagehit[3]);
+
+struct BMFace *BKE_bmbvh_ray_cast(
+ BMBVHTree *tree, const float co[3], const float dir[3], const float radius,
+ float *r_dist, float r_hitout[3], float r_cagehit[3]);
+
+struct BMFace *BKE_bmbvh_ray_cast_filter(
+ BMBVHTree *tree, const float co[3], const float dir[3], const float radius,
+ float *r_dist, float r_hitout[3], float r_cagehit[3],
+ BMBVHTree_FaceFilter filter, void *filter_cb);
+
/* find a face intersecting a segment (but not apart of the segment) */
struct BMFace *BKE_bmbvh_find_face_segment(BMBVHTree *tree, const float co_a[3], const float co_b[3],
float *r_fac, float r_hitout[3], float r_cagehit[3]);
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index d5e54d849cd..c4c27e1060d 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -32,8 +32,11 @@
* \since March 2001
* \author nzc
*/
+
#include "DNA_modifier_types.h"
+#include "BLI_utildefines.h"
+
struct Object;
struct Scene;
struct Effect;
@@ -136,6 +139,88 @@ int get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struc
/* EffectorData->flag */
#define PE_VELOCITY_TO_IMPULSE 1
+/* ======== Simulation Debugging ======== */
+
+#define SIM_DEBUG_HASH_BASE 5381
+
+unsigned int BKE_sim_debug_data_hash(int i);
+unsigned int BKE_sim_debug_data_hash_combine(unsigned int kx, unsigned int ky);
+
+/* _VA_SIM_DEBUG_HASH#(i, ...): combined hash value of multiple integers */
+/* internal helpers*/
+#define _VA_SIM_DEBUG_HASH1(a) \
+ (BKE_sim_debug_data_hash(a))
+#define _VA_SIM_DEBUG_HASH2(a, b) \
+ (BKE_sim_debug_data_hash_combine(BKE_sim_debug_data_hash(a), _VA_SIM_DEBUG_HASH1(b)))
+#define _VA_SIM_DEBUG_HASH3(a, b, c) \
+ (BKE_sim_debug_data_hash_combine(BKE_sim_debug_data_hash(a), _VA_SIM_DEBUG_HASH2(b, c)))
+#define _VA_SIM_DEBUG_HASH4(a, b, c, d) \
+ (BKE_sim_debug_data_hash_combine(BKE_sim_debug_data_hash(a), _VA_SIM_DEBUG_HASH3(b, c, d)))
+#define _VA_SIM_DEBUG_HASH5(a, b, c, d, e) \
+ (BKE_sim_debug_data_hash_combine(BKE_sim_debug_data_hash(a), _VA_SIM_DEBUG_HASH4(b, c, d, e)))
+#define _VA_SIM_DEBUG_HASH6(a, b, c, d, e, f) \
+ (BKE_sim_debug_data_hash_combine(BKE_sim_debug_data_hash(a), _VA_SIM_DEBUG_HASH5(b, c, d, e, f)))
+#define _VA_SIM_DEBUG_HASH7(a, b, c, d, e, f, g) \
+ (BKE_sim_debug_data_hash_combine(BKE_sim_debug_data_hash(a), _VA_SIM_DEBUG_HASH6(b, c, d, e, f, g)))
+#define _VA_SIM_DEBUG_HASH8(a, b, c, d, e, f, g, h) \
+ (BKE_sim_debug_data_hash_combine(BKE_sim_debug_data_hash(a), _VA_SIM_DEBUG_HASH7(b, c, d, e, f, g, h)))
+
+#define SIM_DEBUG_HASH(...) VA_NARGS_CALL_OVERLOAD(_VA_SIM_DEBUG_HASH, __VA_ARGS__)
+
+typedef struct SimDebugElement {
+ unsigned int category_hash;
+ unsigned int hash;
+
+ int type;
+ float color[3];
+
+ float v1[3], v2[3];
+} SimDebugElement;
+
+typedef enum eSimDebugElement_Type {
+ SIM_DEBUG_ELEM_DOT,
+ SIM_DEBUG_ELEM_CIRCLE,
+ SIM_DEBUG_ELEM_LINE,
+ SIM_DEBUG_ELEM_VECTOR,
+} eSimDebugElement_Type;
+
+typedef struct SimDebugData {
+ struct GHash *gh;
+} SimDebugData;
+
+extern SimDebugData *_sim_debug_data;
+
+void BKE_sim_debug_data_set_enabled(bool enable);
+bool BKE_sim_debug_data_get_enabled(void);
+void BKE_sim_debug_data_free(void);
+
+void BKE_sim_debug_data_add_element(int type, const float v1[3], const float v2[3],
+ float r, float g, float b, const char *category, unsigned int hash);
+void BKE_sim_debug_data_remove_element(unsigned int hash);
+
+#define BKE_sim_debug_data_add_dot(p, r, g, b, category, ...) { \
+ const float v2[3] = { 0.0f, 0.0f, 0.0f }; \
+ BKE_sim_debug_data_add_element(SIM_DEBUG_ELEM_DOT, p, v2, r, g, b, category, SIM_DEBUG_HASH(__VA_ARGS__)); \
+}
+
+#define BKE_sim_debug_data_add_circle(p, radius, r, g, b, category, ...) { \
+ const float v2[3] = { radius, 0.0f, 0.0f }; \
+ BKE_sim_debug_data_add_element(SIM_DEBUG_ELEM_CIRCLE, p, v2, r, g, b, category, SIM_DEBUG_HASH(__VA_ARGS__)); \
+}
+
+#define BKE_sim_debug_data_add_line(p1, p2, r, g, b, category, ...) { \
+ BKE_sim_debug_data_add_element(SIM_DEBUG_ELEM_LINE, p1, p2, r, g, b, category, SIM_DEBUG_HASH(__VA_ARGS__)); \
+}
+
+#define BKE_sim_debug_data_add_vector(p, d, r, g, b, category, ...) { \
+ BKE_sim_debug_data_add_element(SIM_DEBUG_ELEM_VECTOR, p, d, r, g, b, category, SIM_DEBUG_HASH(__VA_ARGS__)); \
+}
+
+#define BKE_sim_debug_data_remove(...) \
+ BKE_sim_debug_data_remove_element(SIM_DEBUG_HASH(__VA_ARGS__))
+
+void BKE_sim_debug_data_clear(void);
+void BKE_sim_debug_data_clear_category(const char *category);
#endif
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index c377769b271..83783946d4f 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -44,6 +44,7 @@ struct DriverTarget;
struct FCM_EnvelopeData;
struct bContext;
+struct AnimData;
struct bAction;
struct BezTriple;
struct StructRNA;
@@ -224,10 +225,10 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
/* find an f-curve based on an rna property. */
struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex,
- struct bAction **action, bool *r_driven);
+ struct AnimData **adt, struct bAction **action, bool *r_driven);
/* Same as above, but takes a context data, temp hack needed for complex paths like texture ones. */
struct FCurve *rna_get_fcurve_context_ui(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
- int rnaindex, struct bAction **action, bool *r_driven);
+ int rnaindex, struct AnimData **adt, struct bAction **action, bool *r_driven);
/* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
* Returns the index to insert at (data already at that index will be offset if replace is 0)
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index a7aa4c6969a..57003ffc3aa 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -70,7 +70,6 @@ typedef struct Global {
bool factory_startup;
short moving;
- short winpos, displaymode; /* used to be in Render */
/* to indicate render is busy, prevent renderwindow events etc */
bool is_rendering;
@@ -90,9 +89,6 @@ typedef struct Global {
/* this variable is written to / read from FileGlobal->fileflags */
int fileflags;
- /* save the allowed windowstate of blender when using -W or -w (GHOST_TWindowState) */
- int windowstate;
-
/* message to use when autoexec fails */
char autoexec_fail[200];
} Global;
@@ -130,6 +126,7 @@ enum {
G_DEBUG_JOBS = (1 << 6), /* jobs time profiling */
G_DEBUG_FREESTYLE = (1 << 7), /* freestyle messages */
G_DEBUG_DEPSGRAPH = (1 << 8), /* depsgraph messages */
+ G_DEBUG_SIMDATA = (1 << 9), /* sim debug data display */
};
#define G_DEBUG_ALL (G_DEBUG | G_DEBUG_FFMPEG | G_DEBUG_PYTHON | G_DEBUG_EVENTS | G_DEBUG_WM | G_DEBUG_JOBS | \
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 86c111653d1..084c5527f21 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -35,6 +35,7 @@ struct ListBase;
struct bGPdata;
struct bGPDlayer;
struct bGPDframe;
+struct bGPDstroke;
/* ------------ Grease-Pencil API ------------------ */
@@ -43,17 +44,15 @@ void free_gpencil_frames(struct bGPDlayer *gpl);
void free_gpencil_layers(struct ListBase *list);
void BKE_gpencil_free(struct bGPdata *gpd);
+void gpencil_stroke_sync_selection(struct bGPDstroke *gps);
+
struct bGPDframe *gpencil_frame_addnew(struct bGPDlayer *gpl, int cframe);
struct bGPDlayer *gpencil_layer_addnew(struct bGPdata *gpd, const char *name, int setactive);
struct bGPdata *gpencil_data_addnew(const char name[]);
struct bGPDframe *gpencil_frame_duplicate(struct bGPDframe *src);
struct bGPDlayer *gpencil_layer_duplicate(struct bGPDlayer *src);
-struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd);
-
-//struct bGPdata *gpencil_data_getactive(struct ScrArea *sa);
-//short gpencil_data_setactive(struct ScrArea *sa, struct bGPdata *gpd);
-//struct ScrArea *gpencil_data_findowner(struct bGPdata *gpd);
+struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd, bool internal_copy);
void gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe *gpf);
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index f528fe8c7f9..820e1ea1494 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -50,6 +50,7 @@ bool BKE_group_object_add(struct Group *group, struct Object *ob, struc
bool BKE_group_object_unlink(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
struct Group *BKE_group_object_find(struct Group *group, struct Object *ob);
bool BKE_group_object_exists(struct Group *group, struct Object *ob);
+bool BKE_group_object_cyclic_check(struct Main *bmain, struct Object *object, struct Group *group);
bool BKE_group_is_animated(struct Group *group, struct Object *parent);
void BKE_group_tag_recalc(struct Group *group);
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 2ab3d84dea5..5b10d7ebc06 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -40,18 +40,18 @@ typedef union IDPropertyTemplate {
float f;
double d;
struct {
- char *str;
- short len;
+ const char *str;
+ int len;
char subtype;
} string;
struct ID *id;
struct {
- short type;
- short len;
+ int len;
+ char type;
} array;
struct {
int matvec_size;
- float *example;
+ const float *example;
} matrix_or_vector;
} IDPropertyTemplate;
@@ -91,6 +91,7 @@ void IDP_SyncGroupValues(struct IDProperty *dest, const struct IDProperty *src)
void IDP_SyncGroupTypes(struct IDProperty *dest, const struct IDProperty *src, const bool do_arraylen) ATTR_NONNULL();
void IDP_ReplaceGroupInGroup(struct IDProperty *dest, const struct IDProperty *src) ATTR_NONNULL();
void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL();
+void IDP_ReplaceInGroup_ex(struct IDProperty *group, struct IDProperty *prop, struct IDProperty *prop_exist);
void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite) ATTR_NONNULL();
bool IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL();
bool IDP_InsertToGroup(struct IDProperty *group, struct IDProperty *previous,
@@ -100,9 +101,6 @@ void IDP_FreeFromGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_N
IDProperty *IDP_GetPropertyFromGroup(struct IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
IDProperty *IDP_GetPropertyTypeFromGroup(struct IDProperty *prop, const char *name, const char type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void *IDP_GetGroupIterator(struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT;
-IDProperty *IDP_GroupIterNext(void *vself) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void IDP_FreeIterBeforeEnd(void *vself) ATTR_NONNULL();
/*-------- Main Functions --------*/
struct IDProperty *IDP_GetProperties(struct ID *id, const bool create_if_needed) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -112,7 +110,7 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
bool IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2) ATTR_WARN_UNUSED_RESULT;
-struct IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+struct IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void IDP_FreeProperty(struct IDProperty *prop);
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index dc3d9f38b21..2c9ecef4c2d 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -57,19 +57,25 @@ void BKE_image_free_buffers(struct Image *image);
void BKE_image_free(struct Image *image);
void BKE_imbuf_stamp_info(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf);
-void BKE_stamp_buf(struct Scene *scene, struct Object *camera, unsigned char *rect, float *rectf, int width, int height, int channels);
+void BKE_image_stamp_buf(
+ struct Scene *scene, struct Object *camera,
+ unsigned char *rect, float *rectf, int width, int height, int channels);
bool BKE_imbuf_alpha_test(struct ImBuf *ibuf);
int BKE_imbuf_write_stamp(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
int BKE_imbuf_write(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
int BKE_imbuf_write_as(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf, const bool is_copy);
-void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame,
- const struct ImageFormatData *im_format, const bool use_ext, const bool use_frames);
-void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame,
- const char imtype, const bool use_ext, const bool use_frames);
-int BKE_add_image_extension(char *string, const struct ImageFormatData *im_format);
-int BKE_add_image_extension_from_type(char *string, const char imtype);
-char BKE_ftype_to_imtype(const int ftype);
-int BKE_imtype_to_ftype(const char imtype);
+
+void BKE_image_path_from_imformat(
+ char *string, const char *base, const char *relbase, int frame,
+ const struct ImageFormatData *im_format, const bool use_ext, const bool use_frames);
+void BKE_image_path_from_imtype(
+ char *string, const char *base, const char *relbase, int frame,
+ const char imtype, const bool use_ext, const bool use_frames);
+
+bool BKE_image_path_ensure_ext_from_imformat(char *string, const struct ImageFormatData *im_format);
+bool BKE_image_path_ensure_ext_from_imtype(char *string, const char imtype);
+char BKE_image_ftype_to_imtype(const int ftype);
+int BKE_image_imtype_to_ftype(const char imtype);
bool BKE_imtype_is_movie(const char imtype);
int BKE_imtype_supports_zbuf(const char imtype);
@@ -85,13 +91,13 @@ void BKE_imformat_defaults(struct ImageFormatData *im_format);
void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const struct ImBuf *imbuf);
struct anim *openanim(const char *name, int flags, int streamindex, char colorspace[IMA_MAX_SPACE]);
+struct anim *openanim_noload(const char *name, int flags, int streamindex, char colorspace[IMA_MAX_SPACE]);
void BKE_image_de_interlace(struct Image *ima, int odd);
void BKE_image_make_local(struct Image *ima);
void BKE_image_tag_time(struct Image *ima);
-void free_old_images(void);
/* ********************************** NEW IMAGE API *********************** */
@@ -162,6 +168,7 @@ void BKE_image_alpha_mode_from_extension(struct Image *image);
/* returns a new image or NULL if it can't load */
struct Image *BKE_image_load(struct Main *bmain, const char *filepath);
/* returns existing Image when filename/type is same (frame optional) */
+struct Image *BKE_image_load_exists_ex(const char *filepath, bool *r_exists);
struct Image *BKE_image_load_exists(const char *filepath);
/* adds image, adds ibuf, generates color or pattern */
@@ -179,9 +186,6 @@ void BKE_image_walk_all_users(const struct Main *mainp, void *customdata,
/* ensures an Image exists for viewing nodes or render */
struct Image *BKE_image_verify_viewer(int type, const char *name);
-/* force an ImBuf to become part of Image */
-void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf);
-
/* called on frame change or before render */
void BKE_image_user_frame_calc(struct ImageUser *iuser, int cfra, int fieldnr);
void BKE_image_user_check_frame_calc(struct ImageUser *iuser, int cfra, int fieldnr);
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 892c42b4588..9535b921736 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -60,9 +60,11 @@ void key_curve_position_weights(float t, float data[4], int type);
void key_curve_tangent_weights(float t, float data[4], int type);
void key_curve_normal_weights(float t, float data[4], int type);
-float *BKE_key_evaluate_object_ex(struct Scene *scene, struct Object *ob, int *r_totelem,
- float *arr, size_t arr_size);
-float *BKE_key_evaluate_object(struct Scene *scene, struct Object *ob, int *r_totelem);
+float *BKE_key_evaluate_object_ex(
+ struct Object *ob, int *r_totelem,
+ float *arr, size_t arr_size);
+float *BKE_key_evaluate_object(
+ struct Object *ob, int *r_totelem);
struct Key *BKE_key_from_object(struct Object *ob);
struct KeyBlock *BKE_keyblock_from_object(struct Object *ob);
@@ -87,22 +89,29 @@ void BKE_key_evaluate_relative(const int start, int end, const int tot, char *ba
float **per_keyblock_weights, const int mode);
/* conversion functions */
-void BKE_key_convert_to_mesh(struct KeyBlock *kb, struct Mesh *me);
-void BKE_key_convert_from_mesh(struct Mesh *me, struct KeyBlock *kb);
-void BKE_key_convert_to_lattice(struct KeyBlock *kb, struct Lattice *lt);
-void BKE_key_convert_from_lattice(struct Lattice *lt, struct KeyBlock *kb);
-void BKE_key_convert_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb);
-void BKE_key_convert_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
-float (*BKE_key_convert_to_vertcos(struct Object *ob, struct KeyBlock *kb))[3];
-void BKE_key_convert_from_vertcos(struct Object *ob, struct KeyBlock *kb, float (*vertCos)[3]);
-void BKE_key_convert_from_offset(struct Object *ob, struct KeyBlock *kb, float (*ofs)[3]);
+/* Note: 'update_from' versions do not (re)allocate mem in kb, while 'convert_from' do. */
+void BKE_keyblock_update_from_lattice(struct Lattice *lt, struct KeyBlock *kb);
+void BKE_keyblock_convert_from_lattice(struct Lattice *lt, struct KeyBlock *kb);
+void BKE_keyblock_convert_to_lattice(struct KeyBlock *kb, struct Lattice *lt);
+
+void BKE_keyblock_update_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
+void BKE_keyblock_convert_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
+void BKE_keyblock_convert_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb);
+
+void BKE_keyblock_update_from_mesh(struct Mesh *me, struct KeyBlock *kb);
+void BKE_keyblock_convert_from_mesh(struct Mesh *me, struct KeyBlock *kb);
+void BKE_keyblock_convert_to_mesh(struct KeyBlock *kb, struct Mesh *me);
+
+void BKE_keyblock_update_from_vertcos(struct Object *ob, struct KeyBlock *kb, float (*vertCos)[3]);
+void BKE_keyblock_convert_from_vertcos(struct Object *ob, struct KeyBlock *kb, float (*vertCos)[3]);
+float (*BKE_keyblock_convert_to_vertcos(struct Object *ob, struct KeyBlock *kb))[3];
+
+void BKE_keyblock_update_from_offset(struct Object *ob, struct KeyBlock *kb, float (*ofs)[3]);
/* other management */
bool BKE_keyblock_move(struct Object *ob, int org_index, int new_index);
-
-/* key.c */
-extern int slurph_opt;
+bool BKE_keyblock_is_basis(struct Key *key, const int index);
#ifdef __cplusplus
};
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 500c2813a75..e88a4e88209 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -107,8 +107,8 @@ void BKE_library_make_local(struct Main *bmain, struct Library *lib, bool untagg
struct ID *BKE_libblock_find_name_ex(struct Main *bmain, const short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowManager *) );
-void set_free_notifier_reference_cb(void (*func)(const void *) );
+void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowManager *));
+void set_free_notifier_reference_cb(void (*func)(const void *));
/* use when "" is given to new_id() */
#define ID_FALLBACK_NAME N_("Untitled")
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index b2b9e37f500..224be0f3685 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -36,6 +36,9 @@ struct BoundBox;
struct DispList;
struct EdgeHash;
struct ListBase;
+struct LinkNode;
+struct BLI_Stack;
+struct MemArena;
struct BMEditMesh;
struct BMesh;
struct Main;
@@ -174,10 +177,6 @@ void BKE_mesh_calc_normals_tessface(
struct MVert *mverts, int numVerts,
struct MFace *mfaces, int numFaces,
float (*r_faceNors)[3]);
-void BKE_mesh_normals_loop_split(
- struct MVert *mverts, const int numVerts, struct MEdge *medges, const int numEdges,
- struct MLoop *mloops, float (*r_loopnors)[3], const int numLoops,
- struct MPoly *mpolys, float (*polynors)[3], const int numPolys, float split_angle);
void BKE_mesh_loop_tangents_ex(
struct MVert *mverts, const int numVerts, struct MLoop *mloops, float (*r_looptangent)[4], float (*loopnors)[3],
struct MLoopUV *loopuv, const int numLoops, struct MPoly *mpolys, const int numPolys,
@@ -185,6 +184,56 @@ void BKE_mesh_loop_tangents_ex(
void BKE_mesh_loop_tangents(
struct Mesh *mesh, const char *uvmap, float (*r_looptangents)[4], struct ReportList *reports);
+/**
+ * References a contiguous loop-fan with normal offset vars.
+ */
+typedef struct MLoopNorSpace {
+ float vec_lnor[3]; /* Automatically computed loop normal. */
+ float vec_ref[3]; /* Reference vector, orthogonal to vec_lnor. */
+ float vec_ortho[3]; /* Third vector, orthogonal to vec_lnor and vec_ref. */
+ float ref_alpha; /* Reference angle, around vec_ortho, in ]0, pi] range (0.0 marks that space as invalid). */
+ float ref_beta; /* Reference angle, around vec_lnor, in ]0, 2pi] range (0.0 marks that space as invalid). */
+ struct LinkNode *loops; /* All indices (uint_in_ptr) of loops using this lnor space (i.e. smooth fan of loops). */
+} MLoopNorSpace;
+/**
+ * Collection of #MLoopNorSpace basic storage & pre-allocation.
+ */
+typedef struct MLoopNorSpaceArray {
+ MLoopNorSpace **lspacearr; /* MLoop aligned array */
+ struct LinkNode *loops_pool; /* Allocated once, avoids to call BLI_linklist_prepend_arena() for each loop! */
+ struct MemArena *mem;
+} MLoopNorSpaceArray;
+void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoops);
+void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr);
+void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr);
+MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr);
+void BKE_lnor_space_define(
+ MLoopNorSpace *lnor_space, const float lnor[3], float vec_ref[3], float vec_other[3],
+ struct BLI_Stack *edge_vectors);
+void BKE_lnor_space_add_loop(
+ MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, const int ml_index, const bool add_to_list);
+void BKE_lnor_space_custom_data_to_normal(MLoopNorSpace *lnor_space, const short clnor_data[2], float r_custom_lnor[3]);
+void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2]);
+
+bool BKE_mesh_has_custom_loop_normals(struct Mesh *me);
+
+void BKE_mesh_normals_loop_split(struct MVert *mverts, const int numVerts, struct MEdge *medges, const int numEdges,
+ struct MLoop *mloops, float (*r_loopnors)[3], const int numLoops,
+ struct MPoly *mpolys, const float (*polynors)[3], const int numPolys,
+ const bool use_split_normals, float split_angle,
+ MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], int *r_loop_to_poly);
+
+void BKE_mesh_normals_loop_custom_set(
+ struct MVert *mverts, const int numVerts, struct MEdge *medges, const int numEdges,
+ struct MLoop *mloops, float (*custom_loopnors)[3], const int numLoops,
+ struct MPoly *mpolys, const float (*polynors)[3], const int numPolys,
+ short (*r_clnors_data)[2]);
+void BKE_mesh_normals_loop_custom_from_vertices_set(
+ struct MVert *mverts, float (*custom_vertnors)[3], const int numVerts,
+ struct MEdge *medges, const int numEdges, struct MLoop *mloops, const int numLoops,
+ struct MPoly *mpolys, const float (*polynors)[3], const int numPolys,
+ short (*r_clnors_data)[2]);
+
void BKE_mesh_calc_poly_normal(
struct MPoly *mpoly, struct MLoop *loopstart,
struct MVert *mvarray, float no[3]);
@@ -286,7 +335,7 @@ void BKE_mesh_calc_relative_deform(
/* *** mesh_validate.c *** */
-int BKE_mesh_validate(struct Mesh *me, const int do_verbose);
+int BKE_mesh_validate(struct Mesh *me, const int do_verbose, const int cddata_check_mask);
void BKE_mesh_cd_validate(struct Mesh *me);
int BKE_mesh_validate_material_indices(struct Mesh *me);
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index ed7e506941c..da44c989146 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -31,8 +31,9 @@
* \ingroup bke
*/
-struct MPoly;
+struct MVert;
struct MEdge;
+struct MPoly;
struct MLoop;
struct MLoopUV;
@@ -109,6 +110,10 @@ void BKE_mesh_vert_poly_map_create(
MeshElemMap **r_map, int **r_mem,
const struct MPoly *mface, const struct MLoop *mloop,
int totvert, int totface, int totloop);
+void BKE_mesh_vert_loop_map_create(
+ MeshElemMap **r_map, int **r_mem,
+ const struct MPoly *mface, const struct MLoop *mloop,
+ int totvert, int totface, int totloop);
void BKE_mesh_vert_edge_map_create(
MeshElemMap **r_map, int **r_mem,
const struct MEdge *medge, int totvert, int totedge);
@@ -122,7 +127,61 @@ void BKE_mesh_origindex_map_create(
const int totorig,
const int *final_origindex, const int totfinal);
-/* smoothgroups */
+
+/* islands */
+
+/* Loop islands data helpers. */
+enum {
+ MISLAND_TYPE_NONE = 0,
+ MISLAND_TYPE_VERT = 1,
+ MISLAND_TYPE_EDGE = 2,
+ MISLAND_TYPE_POLY = 3,
+ MISLAND_TYPE_LOOP = 4,
+};
+
+typedef struct MeshIslandStore {
+ short item_type; /* MISLAND_TYPE_... */
+ short island_type; /* MISLAND_TYPE_... */
+ short innercut_type; /* MISLAND_TYPE_... */
+
+ int items_to_islands_num;
+ int *items_to_islands; /* map the item to the island index */
+
+ int islands_num;
+ size_t islands_num_alloc;
+ struct MeshElemMap **islands; /* Array of pointers, one item per island. */
+ struct MeshElemMap **innercuts; /* Array of pointers, one item per island. */
+
+ struct MemArena *mem; /* Memory arena, internal use only. */
+} MeshIslandStore;
+
+void BKE_mesh_loop_islands_init(
+ MeshIslandStore *island_store,
+ const short item_type, const int item_num, const short island_type, const short innercut_type);
+void BKE_mesh_loop_islands_clear(MeshIslandStore *island_store);
+void BKE_mesh_loop_islands_free(MeshIslandStore *island_store);
+void BKE_mesh_loop_islands_add(
+ MeshIslandStore *islands, const int item_num, int *item_indices,
+ const int num_island_items, int *island_item_indices,
+ const int num_innercut_items, int *innercut_item_indices);
+
+typedef bool (*MeshRemapIslandsCalc)(
+ struct MVert *verts, const int totvert,
+ struct MEdge *edges, const int totedge,
+ struct MPoly *polys, const int totpoly,
+ struct MLoop *loops, const int totloop,
+ struct MeshIslandStore *r_island_store);
+
+/* Above vert/UV mapping stuff does not do what we need here, but does things we do not need here.
+ * So better keep them separated for now, I think.
+ */
+bool BKE_mesh_calc_islands_loop_poly_uv(
+ struct MVert *verts, const int totvert,
+ struct MEdge *edges, const int totedge,
+ struct MPoly *polys, const int totpoly,
+ struct MLoop *loops, const int totloop,
+ MeshIslandStore *r_island_store);
+
int *BKE_mesh_calc_smoothgroups(
const struct MEdge *medge, const int totedge,
const struct MPoly *mpoly, const int totpoly,
diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h
new file mode 100644
index 00000000000..752270a8120
--- /dev/null
+++ b/source/blender/blenkernel/BKE_mesh_remap.h
@@ -0,0 +1,171 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_MESH_REMAP_H__
+#define __BKE_MESH_REMAP_H__
+
+/** \file BKE_mesh_remap.h
+ * \ingroup bke
+ */
+
+struct CustomData;
+struct DerivedMesh;
+struct MVert;
+struct MeshElemMap;
+struct MemArena;
+
+/* Generic ways to map some geometry elements from a source mesh to a dest one. */
+
+typedef struct MeshPairRemapItem {
+ int sources_num;
+ int *indices_src; /* NULL if no source found. */
+ float *weights_src; /* NULL if no source found, else, always normalized! */
+ /* UNUSED (at the moment)*/
+ // float hit_dist; /* FLT_MAX if irrelevant or no source found. */
+ int island; /* For loops only. */
+} MeshPairRemapItem;
+
+/* All mapping computing func return this. */
+typedef struct MeshPairRemap {
+ int items_num;
+ MeshPairRemapItem *items; /* array, one item per dest element. */
+
+ struct MemArena *mem; /* memory arena, internal use only. */
+} MeshPairRemap;
+
+/* Helpers! */
+void BKE_mesh_remap_init(MeshPairRemap *map, const int items_num);
+void BKE_mesh_remap_free(MeshPairRemap *map);
+
+void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, const int index);
+
+/* TODO:
+ * Add other 'from/to' mapping sources, like e.g. using an UVMap, etc.
+ * http://blenderartists.org/forum/showthread.php?346458-Move-Vertices-to-the-location-of-the-Reference-Mesh-based-on-the-UV-Position
+ * We could also use similar topology mappings inside a same mesh
+ * (cf. Campbell's 'select face islands from similar topology' wip work).
+ * Also, users will have to check, whether we can get rid of some modes here, not sure all will be useful!
+ */
+enum {
+ MREMAP_USE_VERT = 1 << 4,
+ MREMAP_USE_EDGE = 1 << 5,
+ MREMAP_USE_LOOP = 1 << 6,
+ MREMAP_USE_POLY = 1 << 7,
+
+ MREMAP_USE_NEAREST = 1 << 8,
+ MREMAP_USE_NORPROJ = 1 << 9,
+ MREMAP_USE_INTERP = 1 << 10,
+ MREMAP_USE_NORMAL = 1 << 11,
+
+ /* ***** Target's vertices ***** */
+ MREMAP_MODE_VERT = 1 << 24,
+ /* Nearest source vert. */
+ MREMAP_MODE_VERT_NEAREST = MREMAP_MODE_VERT | MREMAP_USE_VERT | MREMAP_USE_NEAREST,
+
+ /* Nearest vertex of nearest edge. */
+ MREMAP_MODE_VERT_EDGE_NEAREST = MREMAP_MODE_VERT | MREMAP_USE_EDGE | MREMAP_USE_NEAREST,
+ /* This one uses two verts of selected edge (weighted interpolation). */
+ /* Nearest point on nearest edge. */
+ MREMAP_MODE_VERT_EDGEINTERP_NEAREST = MREMAP_MODE_VERT | MREMAP_USE_EDGE | MREMAP_USE_NEAREST | MREMAP_USE_INTERP,
+
+ /* Nearest vertex of nearest poly. */
+ MREMAP_MODE_VERT_POLY_NEAREST = MREMAP_MODE_VERT | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
+ /* Those two use all verts of selected poly (weighted interpolation). */
+ /* Nearest point on nearest poly. */
+ MREMAP_MODE_VERT_POLYINTERP_NEAREST = MREMAP_MODE_VERT | MREMAP_USE_POLY | MREMAP_USE_NEAREST | MREMAP_USE_INTERP,
+ /* Point on nearest face hit by ray from target vertex's normal. */
+ MREMAP_MODE_VERT_POLYINTERP_VNORPROJ = MREMAP_MODE_VERT | MREMAP_USE_POLY | MREMAP_USE_NORPROJ | MREMAP_USE_INTERP,
+
+ /* ***** Target's edges ***** */
+ MREMAP_MODE_EDGE = 1 << 25,
+
+ /* Source edge which both vertices are nearest of dest ones. */
+ MREMAP_MODE_EDGE_VERT_NEAREST = MREMAP_MODE_EDGE | MREMAP_USE_VERT | MREMAP_USE_NEAREST,
+
+ /* Nearest source edge (using mid-point). */
+ MREMAP_MODE_EDGE_NEAREST = MREMAP_MODE_EDGE | MREMAP_USE_EDGE | MREMAP_USE_NEAREST,
+
+ /* Nearest edge of nearest poly (using mid-point). */
+ MREMAP_MODE_EDGE_POLY_NEAREST = MREMAP_MODE_EDGE | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
+
+ /* Cast a set of rays from along dest edge, interpolating its vertices' normals, and use hit source edges. */
+ MREMAP_MODE_EDGE_EDGEINTERP_VNORPROJ = MREMAP_MODE_EDGE | MREMAP_USE_VERT | MREMAP_USE_NORPROJ | MREMAP_USE_INTERP,
+
+ /* ***** Target's loops ***** */
+ /* Note: when islands are given to loop mapping func, all loops from the same destination face will always be mapped
+ * to loops of source faces within a same island, regardless of mapping mode. */
+ MREMAP_MODE_LOOP = 1 << 26,
+
+ /* Best normal-matching loop from nearest vert. */
+ MREMAP_MODE_LOOP_NEAREST_LOOPNOR = MREMAP_MODE_LOOP | MREMAP_USE_LOOP | MREMAP_USE_VERT | MREMAP_USE_NEAREST | MREMAP_USE_NORMAL,
+ /* Loop from best normal-matching poly from nearest vert. */
+ MREMAP_MODE_LOOP_NEAREST_POLYNOR = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_VERT | MREMAP_USE_NEAREST | MREMAP_USE_NORMAL,
+
+ /* Loop from nearest vertex of nearest poly. */
+ MREMAP_MODE_LOOP_POLY_NEAREST = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
+ /* Those two use all verts of selected poly (weighted interpolation). */
+ /* Nearest point on nearest poly. */
+ MREMAP_MODE_LOOP_POLYINTERP_NEAREST = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_NEAREST | MREMAP_USE_INTERP,
+ /* Point on nearest face hit by ray from target loop's normal. */
+ MREMAP_MODE_LOOP_POLYINTERP_LNORPROJ = MREMAP_MODE_LOOP | MREMAP_USE_POLY | MREMAP_USE_NORPROJ | MREMAP_USE_INTERP,
+
+ /* ***** Target's polygons ***** */
+ MREMAP_MODE_POLY = 1 << 27,
+
+ /* Nearest source poly. */
+ MREMAP_MODE_POLY_NEAREST = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
+ /* Source poly from best normal-matching dest poly. */
+ MREMAP_MODE_POLY_NOR = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NORMAL,
+
+ /* Project dest poly onto source mesh using its normal, and use interpolation of all intersecting source polys. */
+ MREMAP_MODE_POLY_POLYINTERP_PNORPROJ = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NORPROJ | MREMAP_USE_INTERP,
+
+ /* ***** Same topology, applies to all four elements types. ***** */
+ MREMAP_MODE_TOPOLOGY = MREMAP_MODE_VERT | MREMAP_MODE_EDGE | MREMAP_MODE_LOOP | MREMAP_MODE_POLY,
+};
+
+/* TODO add mesh2mesh versions (we'll need mesh versions of bvhtree funcs too, though!). */
+
+void BKE_mesh_remap_calc_verts_from_dm(
+ const int mode, const struct SpaceTransform *space_transform, const float max_dist, const float ray_radius,
+ const struct MVert *verts_dst, const int numverts_dst, const bool dirty_nors_dst,
+ struct DerivedMesh *dm_src, MeshPairRemap *r_map);
+
+void BKE_mesh_remap_calc_edges_from_dm(
+ const int mode, const struct SpaceTransform *space_transform, const float max_dist, const float ray_radius,
+ const struct MVert *verts_dst, const int numverts_dst, const struct MEdge *edges_dst, const int numedges_dst,
+ const bool dirty_nors_dst, struct DerivedMesh *dm_src, MeshPairRemap *r_map);
+
+void BKE_mesh_remap_calc_loops_from_dm(
+ const int mode, const struct SpaceTransform *space_transform, const float max_dist, const float ray_radius,
+ struct MVert *verts_dst, const int numverts_dst, struct MEdge *edges_dst, const int numedges_dst,
+ struct MLoop *loops_dst, const int numloops_dst, struct MPoly *polys_dst, const int numpolys_dst,
+ struct CustomData *ldata_dst, struct CustomData *pdata_dst,
+ const bool use_split_nors_dst, const float split_angle_dst, const bool dirty_nors_dst,
+ struct DerivedMesh *dm_src, const bool use_split_nors_src, const float split_angle_src,
+ MeshRemapIslandsCalc gen_islands_src, const float islands_precision_src, struct MeshPairRemap *r_map);
+
+void BKE_mesh_remap_calc_polys_from_dm(
+ const int mode, const struct SpaceTransform *space_transform, const float max_dist, const float ray_radius,
+ struct MVert *verts_dst, const int numverts_dst, struct MLoop *loops_dst, const int numloops_dst,
+ struct MPoly *polys_dst, const int numpolys_dst, struct CustomData *pdata_dst, const bool dirty_nors_dst,
+ struct DerivedMesh *dm_src, struct MeshPairRemap *r_map);
+
+#endif /* __BKE_MESH_REMAP_H__ */
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 75616b9df78..1ec4e23abca 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -41,6 +41,7 @@ struct Scene;
struct ListBase;
struct LinkNode;
struct bArmature;
+struct Main;
struct ModifierData;
struct BMEditMesh;
@@ -256,7 +257,8 @@ typedef struct ModifierTypeInfo {
*
* This function is optional.
*/
- void (*updateDepgraph)(struct ModifierData *md, struct DagForest *forest, struct Scene *scene,
+ void (*updateDepgraph)(struct ModifierData *md, struct DagForest *forest,
+ struct Main *bmain, struct Scene *scene,
struct Object *ob, struct DagNode *obNode);
/* Should return true if the modifier needs to be recalculated on time
@@ -319,7 +321,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type);
struct ModifierData *modifier_new(int type);
void modifier_free(struct ModifierData *md);
-void modifier_unique_name(struct ListBase *modifiers, struct ModifierData *md);
+bool modifier_unique_name(struct ListBase *modifiers, struct ModifierData *md);
void modifier_copyData_generic(const struct ModifierData *md, struct ModifierData *target);
void modifier_copyData(struct ModifierData *md, struct ModifierData *target);
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 341105cfdf7..a4aa58e22f1 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -46,6 +46,7 @@ void BKE_movieclip_unlink(struct Main *bmain, struct MovieClip *clip);
struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *name);
void BKE_movieclip_reload(struct MovieClip *clip);
void BKE_movieclip_clear_cache(struct MovieClip *clip);
+void BKE_movieclip_clear_proxy_cache(struct MovieClip *clip);
struct ImBuf *BKE_movieclip_get_ibuf(struct MovieClip *clip, struct MovieClipUser *user);
struct ImBuf *BKE_movieclip_get_postprocessed_ibuf(struct MovieClip *clip, struct MovieClipUser *user, int postprocess_flag);
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 0c29179aa1c..c3fc29e811f 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -105,6 +105,11 @@ void BKE_nla_validate_state(struct AnimData *adt);
/* ............ */
+bool BKE_nla_action_is_stashed(struct AnimData *adt, struct bAction *act);
+bool BKE_nla_action_stash(struct AnimData *adt);
+
+/* ............ */
+
void BKE_nla_action_pushdown(struct AnimData *adt);
bool BKE_nla_tweakmode_enter(struct AnimData *adt);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index cb96538ad81..44ac3b7bb38 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -84,8 +84,9 @@ struct ColorManagedViewSettings;
struct ColorManagedDisplaySettings;
struct bNodeInstanceHash;
-
-/* ************** NODE TYPE DEFINITIONS ***** */
+/* -------------------------------------------------------------------- */
+/** \name Node Type Definitions
+ * \{ */
/** Compact definition of a node socket.
* Can be used to quickly define a list of static sockets for a node,
@@ -314,8 +315,11 @@ typedef struct bNodeTreeType {
ExtensionRNA ext;
} bNodeTreeType;
+/** \} */
-/* ************** GENERIC API, TREES *************** */
+/* -------------------------------------------------------------------- */
+/** \name Generic API, Trees
+ * \{ */
struct bNodeTreeType *ntreeTypeFind(const char *idname);
void ntreeTypeAdd(struct bNodeTreeType *nt);
@@ -377,8 +381,12 @@ struct bNodeTree *ntreeLocalize(struct bNodeTree *ntree);
void ntreeLocalSync(struct bNodeTree *localtree, struct bNodeTree *ntree);
void ntreeLocalMerge(struct bNodeTree *localtree, struct bNodeTree *ntree);
-/* ************** NODE TREE INTERFACE *************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Node Tree Interface
+ * \{ */
struct bNodeSocket *ntreeFindSocketInterface(struct bNodeTree *ntree, int in_out, const char *identifier);
struct bNodeSocket *ntreeAddSocketInterface(struct bNodeTree *ntree, int in_out, const char *idname, const char *name);
struct bNodeSocket *ntreeInsertSocketInterface(struct bNodeTree *ntree, int in_out, const char *idname,
@@ -392,7 +400,12 @@ struct StructRNA *ntreeInterfaceTypeGet(struct bNodeTree *ntree, int create);
void ntreeInterfaceTypeFree(struct bNodeTree *ntree);
void ntreeInterfaceTypeUpdate(struct bNodeTree *ntree);
-/* ************** GENERIC API, NODES *************** */
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+/** \name Generic API, Nodes
+ * \{ */
struct bNodeType *nodeTypeFind(const char *idname);
void nodeRegisterType(struct bNodeType *ntype);
@@ -455,7 +468,7 @@ struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node);
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);
-int nodeLinkIsHidden(struct bNodeLink *link);
+bool nodeLinkIsHidden(struct bNodeLink *link);
void nodeInternalRelink(struct bNodeTree *ntree, struct bNode *node);
void nodeToView(struct bNode *node, float x, float y, float *rx, float *ry);
@@ -485,6 +498,7 @@ void nodeUpdateInternalLinks(struct bNodeTree *ntree, struct bNode *n
void nodeSynchronizeID(struct bNode *node, bool copy_to_id);
int nodeSocketIsHidden(struct bNodeSocket *sock);
+void ntreeTagUsedSockets(struct bNodeTree *ntree);
/* Node Clipboard */
void BKE_node_clipboard_init(struct bNodeTree *ntree);
@@ -557,8 +571,12 @@ void BKE_node_preview_merge_tree(struct bNodeTree *to_ntree, struct b
void BKE_node_preview_set_pixel(struct bNodePreview *preview, const float col[4], int x, int y, bool do_manage);
+/** \} */
+
-/* ************** NODE TYPE ACCESS *************** */
+/* -------------------------------------------------------------------- */
+/** \name Node Type Access
+ * \{ */
void nodeLabel(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen);
@@ -585,7 +603,11 @@ void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpufu
void node_type_internal_links(struct bNodeType *ntype, void (*update_internal_links)(struct bNodeTree *, struct bNode *));
void node_type_compatibility(struct bNodeType *ntype, short compatibility);
-/* ************** GENERIC NODE FUNCTIONS *************** */
+
+/* -------------------------------------------------------------------- */
+/** \name Node Generic Functions
+ * \{ */
+
bool BKE_node_is_connected_to_output(struct bNodeTree *ntree, struct bNode *node);
/* ************** COMMON NODES *************** */
@@ -602,7 +624,12 @@ bool BKE_node_is_connected_to_output(struct bNodeTree *ntree, struct bNode *node
void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree);
-/* Utility macro for visiting every node tree in the library data, including local bNodeTree blocks in other IDs.
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Node Tree Iterator
+ *
+ * Utility macro for visiting every node tree in the library data, including local bNodeTree blocks in other IDs.
* This avoids the need for callback functions and allows executing code in a single inner code block.
*
* Variables:
@@ -615,6 +642,7 @@ void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree);
*
* Examples:
*
+ * \code{.c}
* FOREACH_NODETREE(bmain, nodetree) {
* if (id == nodetree)
* printf("This is a linkable node tree");
@@ -626,6 +654,9 @@ void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree);
* if (GS(id) == ID_MA)
* printf(" and it's owned by a material");
* } FOREACH_NODETREE_END
+ * \endcode
+ *
+ * \{
*/
/* should be an opaque type, only for internal use by BKE_node_tree_iter_*** */
@@ -657,9 +688,11 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
} \
} \
}
+/** \} */
-/* ************** SHADER NODES *************** */
-
+/* -------------------------------------------------------------------- */
+/** \name Shader Nodes
+ */
struct ShadeInput;
struct ShadeResult;
@@ -782,8 +815,11 @@ void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInp
void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat, short compatibility);
+/** \} */
-/* ************** COMPOSITE NODES *************** */
+/* -------------------------------------------------------------------- */
+/** \name Composite Nodes
+ */
/* output socket defines */
#define RRES_OUT_IMAGE 0
@@ -963,7 +999,11 @@ void ntreeCompositOutputFileUniqueLayer(struct ListBase *list, struct bNodeSocke
void ntreeCompositColorBalanceSyncFromLGG(bNodeTree *ntree, bNode *node);
void ntreeCompositColorBalanceSyncFromCDL(bNodeTree *ntree, bNode *node);
-/* ************** TEXTURE NODES *************** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Texture Nodes
+ */
struct TexResult;
@@ -1004,11 +1044,9 @@ void ntreeTexEndExecTree(struct bNodeTreeExec *exec);
int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target,
float coord[3], float dxt[3], float dyt[3], int osatex, const short thread,
struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex);
-
-
-/*************************************************/
+/** \} */
void init_nodesystem(void);
void free_nodesystem(void);
-#endif
+#endif /* __BKE_NODE_H__ */
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 1bfd26d4f8c..1c6f7221bec 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -57,6 +57,7 @@ void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struc
void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src);
struct SoftBody *copy_softbody(struct SoftBody *sb, bool copy_caches);
struct BulletSoftBody *copy_bulletsoftbody(struct BulletSoftBody *sb);
+struct ParticleSystem *BKE_object_copy_particlesystem(struct ParticleSystem *psys);
void BKE_object_copy_particlesystems(struct Object *obn, struct Object *ob);
void BKE_object_copy_softbody(struct Object *obn, struct Object *ob);
void BKE_object_free_particlesystems(struct Object *ob);
@@ -68,6 +69,7 @@ void BKE_object_update_base_layer(struct Scene *scene, struct Object *ob);
void BKE_object_free(struct Object *ob);
void BKE_object_free_ex(struct Object *ob, bool do_id_user);
void BKE_object_free_derived_caches(struct Object *ob);
+void BKE_object_free_caches(struct Object *object);
void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData *hmd);
@@ -181,7 +183,9 @@ int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float *
int BKE_object_insert_ptcache(struct Object *ob);
void BKE_object_delete_ptcache(struct Object *ob, int index);
-struct KeyBlock *BKE_object_insert_shape_key(struct Scene *scene, struct Object *ob, const char *name, const bool from_mix);
+struct KeyBlock *BKE_object_insert_shape_key(struct Object *ob, const char *name, const bool from_mix);
+
+bool BKE_object_flag_test_recursive(const struct Object *ob, short flag);
bool BKE_object_is_child_recursive(struct Object *ob_parent, struct Object *ob_child);
bool BKE_object_is_animated(struct Scene *scene, struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_object_deform.h b/source/blender/blenkernel/BKE_object_deform.h
index 6de7ff9bc1c..e956815d6f7 100644
--- a/source/blender/blenkernel/BKE_object_deform.h
+++ b/source/blender/blenkernel/BKE_object_deform.h
@@ -29,10 +29,54 @@
* used by painting and tools.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct Object;
+struct ID;
+struct MDeformVert;
+struct bDeformGroup;
+
+/* General vgroup operations */
+void BKE_object_defgroup_remap_update_users(struct Object *ob, int *map);
+
+bool BKE_object_defgroup_array_get(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
+
+struct bDeformGroup *BKE_object_defgroup_add(struct Object *ob);
+struct bDeformGroup *BKE_object_defgroup_add_name(struct Object *ob, const char *name);
+struct MDeformVert *BKE_object_defgroup_data_create(struct ID *id);
+
+bool BKE_object_defgroup_clear(struct Object *ob, struct bDeformGroup *dg, const bool use_selection);
+bool BKE_object_defgroup_clear_all(struct Object *ob, const bool use_selection);
+
+void BKE_object_defgroup_remove(struct Object *ob, struct bDeformGroup *defgroup);
+void BKE_object_defgroup_remove_all(struct Object *ob);
+
+
+/* Select helpers */
+enum eVGroupSelect;
+bool *BKE_object_defgroup_subset_from_select_type(
+ struct Object *ob, enum eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count);
+void BKE_object_defgroup_subset_to_index_array(
+ const bool *defgroup_validmap, const int defgroup_tot, int *r_defgroup_subset_map);
+
+
+/* ********** */
+
+bool *BKE_object_defgroup_lock_flags_get(struct Object *ob, const int defbase_tot);
+bool *BKE_object_defgroup_validmap_get(struct Object *ob, const int defbase_tot);
+bool *BKE_object_defgroup_selected_get(struct Object *ob, int defbase_tot, int *r_dg_flags_sel_tot);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Select helpers */
+bool *BKE_objdef_vgroup_subset_from_select_type(
+ struct Object *ob, enum eVGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count);
+void BKE_objdef_vgroup_subset_to_index_array(
+ const bool *vgroup_validmap, const int vgroup_tot, int *r_vgroup_subset_map);
-bool *BKE_objdef_lock_flags_get(struct Object *ob, const int defbase_tot);
-bool *BKE_objdef_validmap_get(struct Object *ob, const int defbase_tot);
-bool *BKE_objdef_selected_get(struct Object *ob, int defbase_tot, int *r_dg_flags_sel_tot);
#endif /* __BKE_OBJECT_DEFORM_H__ */
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index b080ca37e67..3e4e6ab4146 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -109,10 +109,12 @@ void BKE_palette_cleanup(struct Palette *palette);
struct PaintCurve *BKE_paint_curve_add(struct Main *bmain, const char *name);
void BKE_paint_curve_free(struct PaintCurve *pc);
-void BKE_paint_init(struct Paint *p, const char col[3]);
+void BKE_paint_init(struct UnifiedPaintSettings *ups, struct Paint *p, const char col[3]);
void BKE_paint_free(struct Paint *p);
void BKE_paint_copy(struct Paint *src, struct Paint *tar);
+void BKE_paint_cavity_curve_preset(struct Paint *p, int preset);
+
struct Paint *BKE_paint_get_active(struct Scene *sce);
struct Paint *BKE_paint_get_active_from_context(const struct bContext *C);
PaintMode BKE_paintmode_get_active_from_context(const struct bContext *C);
@@ -143,7 +145,9 @@ float paint_grid_paint_mask(const struct GridPaintMask *gpm, unsigned level,
unsigned x, unsigned y);
/* stroke related */
-void paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, const float mouse_pos[2]);
+void paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, struct Brush *brush, const float mouse_pos[2]);
+
+void BKE_paint_stroke_get_average(struct Scene *scene, struct Object *ob, float stroke[3]);
/* Session data (mode-specific) */
@@ -191,13 +195,6 @@ typedef struct SculptSession {
struct SculptStroke *stroke;
struct StrokeCache *cache;
-
- /* last paint/sculpt stroke location */
- bool last_stroke_valid;
- float last_stroke[3];
-
- float average_stroke_accum[3];
- int average_stroke_counter;
} SculptSession;
void BKE_free_sculptsession(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index f84a6378fb3..0f1389bfeec 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -39,6 +39,8 @@
#include "DNA_particle_types.h"
#include "DNA_object_types.h"
+#include "BKE_customdata.h"
+
struct ParticleSystemModifierData;
struct ParticleSystem;
struct ParticleKey;
@@ -110,7 +112,7 @@ typedef struct ParticleTexture {
float ivel; /* used in reset */
float time, life, exist, size; /* used in init */
float damp, gravity, field; /* used in physics */
- float length, clump, kink, effector; /* used in path caching */
+ float length, clump, kink_freq, kink_amp, effector; /* used in path caching */
float rough1, rough2, roughe; /* used in path caching */
} ParticleTexture;
@@ -126,7 +128,7 @@ typedef struct ParticleCacheKey {
float rot[4];
float col[3];
float time;
- int steps;
+ int segments;
} ParticleCacheKey;
typedef struct ParticleThreadContext {
@@ -145,12 +147,12 @@ typedef struct ParticleThreadContext {
float maxweight;
int *index, *skip, jitlevel;
- int from, cfrom, distr;
+ int cfrom, distr;
struct ParticleData *tpars;
/* path caching */
- int editupdate, between, steps;
+ int editupdate, between, segments, extra_segments;
int totchild, totparent, parent_pass;
float cfra;
@@ -160,11 +162,11 @@ typedef struct ParticleThreadContext {
float *vg_effector;
} ParticleThreadContext;
-typedef struct ParticleThread {
+typedef struct ParticleTask {
ParticleThreadContext *ctx;
struct RNG *rng, *rng_path;
- int num, tot;
-} ParticleThread;
+ int begin, end;
+} ParticleTask;
typedef struct ParticleBillboardData {
struct Object *ob;
@@ -279,6 +281,9 @@ BLI_INLINE void psys_frand_vec(ParticleSystem *psys, unsigned int seed, float ve
int count_particles(struct ParticleSystem *psys);
int count_particles_mod(struct ParticleSystem *psys, int totgr, int cur);
+int psys_get_child_number(struct Scene *scene, struct ParticleSystem *psys);
+int psys_get_tot_child(struct Scene *scene, struct ParticleSystem *psys);
+
struct ParticleSystem *psys_get_current(struct Object *ob);
/* for rna */
short psys_get_current_num(struct Object *ob);
@@ -288,9 +293,9 @@ void psys_set_current_num(Object *ob, int index);
struct LatticeDeformData *psys_create_lattice_deform_data(struct ParticleSimulationData *sim);
-int psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys);
-int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
-int psys_check_edited(struct ParticleSystem *psys);
+bool psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys);
+bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
+bool psys_check_edited(struct ParticleSystem *psys);
void psys_check_group_weights(struct ParticleSettings *part);
int psys_uses_gravity(struct ParticleSimulationData *sim);
@@ -302,7 +307,6 @@ void psys_free(struct Object *ob, struct ParticleSystem *psys);
void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset);
void psys_render_restore(struct Object *ob, struct ParticleSystem *psys);
-int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot);
bool psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
void psys_interpolate_uvs(const struct MTFace *tface, int quad, const float w[4], float uvco[2]);
@@ -310,6 +314,7 @@ void psys_interpolate_mcol(const struct MCol *mcol, int quad, const float w[4],
void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time);
+CustomDataMask psys_emitter_customdata_mask(struct ParticleSystem *psys);
void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache,
float fuv[4], float foffset, float vec[3], float nor[3],
float utan[3], float vtan[3], float orco[3], float ornor[3]);
@@ -328,7 +333,7 @@ void psys_find_parents(struct ParticleSimulationData *sim);
void psys_cache_paths(struct ParticleSimulationData *sim, float cfra);
void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra);
void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, int editupdate);
-int do_guides(struct ListBase *effectors, ParticleKey *state, int pa_num, float time);
+int do_guides(struct ParticleSettings *part, struct ListBase *effectors, ParticleKey *state, int pa_num, float time);
void precalc_guides(struct ParticleSimulationData *sim, struct ListBase *effectors);
float psys_get_timestep(struct ParticleSimulationData *sim);
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime);
@@ -336,6 +341,13 @@ float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa
void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, const bool vel);
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always);
+/* child paths */
+void BKE_particlesettings_clump_curve_init(struct ParticleSettings *part);
+void BKE_particlesettings_rough_curve_init(struct ParticleSettings *part);
+void psys_apply_child_modifiers(struct ParticleThreadContext *ctx, struct ListBase *modifiers,
+ struct ChildParticle *cpa, struct ParticleTexture *ptex, const float orco[3], const float ornor[3], float hairmat[4][4],
+ struct ParticleCacheKey *keys, struct ParticleCacheKey *parent_keys, const float parent_orco[3]);
+
void psys_sph_init(struct ParticleSimulationData *sim, struct SPHData *sphdata);
void psys_sph_finalise(struct SPHData *sphdata);
void psys_sph_density(struct BVHTree *tree, struct SPHData *data, float co[3], float vars[2]);
@@ -347,8 +359,10 @@ void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings
void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa,
struct ParticleCacheKey *cache, float mat[4][4], float *scale);
-ParticleThread *psys_threads_create(struct ParticleSimulationData *sim);
-void psys_threads_free(ParticleThread *threads);
+void psys_thread_context_init(struct ParticleThreadContext *ctx, struct ParticleSimulationData *sim);
+void psys_thread_context_free(struct ParticleThreadContext *ctx);
+void psys_tasks_create(struct ParticleThreadContext *ctx, int totpart, struct ParticleTask **r_tasks, int *r_numtasks);
+void psys_tasks_free(struct ParticleTask *tasks, int numtasks);
void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
void psys_apply_hair_lattice(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
@@ -364,7 +378,7 @@ void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, in
void psys_check_boid_data(struct ParticleSystem *psys);
-void psys_get_birth_coordinates(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, float dtime, float cfra);
+void psys_get_birth_coords(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, float dtime, float cfra);
void particle_system_update(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
@@ -378,7 +392,7 @@ void free_keyed_keys(struct ParticleSystem *psys);
void psys_free_particles(struct ParticleSystem *psys);
void psys_free_children(struct ParticleSystem *psys);
-void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, int velocity);
+void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, bool velocity);
void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float vec[3]);
void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
@@ -403,6 +417,7 @@ void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_
float orco[3], float ornor[3]);
/* particle_system.c */
+void distribute_particles(struct ParticleSimulationData *sim, int from);
void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, const float fw[4], struct LinkNode *node);
@@ -411,6 +426,33 @@ void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa,
float psys_get_current_display_percentage(struct ParticleSystem *psys);
+typedef struct ParticleRenderElem {
+ int curchild, totchild, reduce;
+ float lambda, t, scalemin, scalemax;
+} ParticleRenderElem;
+
+typedef struct ParticleRenderData {
+ ChildParticle *child;
+ ParticleCacheKey **pathcache;
+ ParticleCacheKey **childcache;
+ ListBase pathcachebufs, childcachebufs;
+ int totchild, totcached, totchildcache;
+ struct DerivedMesh *dm;
+ int totdmvert, totdmedge, totdmface;
+
+ float mat[4][4];
+ float viewmat[4][4], winmat[4][4];
+ int winx, winy;
+
+ int do_simplify;
+ int timeoffset;
+ ParticleRenderElem *elems;
+
+ /* ORIGINDEX */
+ const int *index_mf_to_mpoly;
+ const int *index_mp_to_orig;
+} ParticleRenderData;
+
/* psys_reset */
#define PSYS_RESET_ALL 1
#define PSYS_RESET_DEPSGRAPH 2
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 99579086e25..e18e9d46a25 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -241,7 +241,6 @@ typedef struct PTCacheEdit {
/* particles stuff */
struct ParticleSystem *psys;
- struct ParticleData *particles;
struct KDTree *emitter_field;
float *emitter_cosnos; /* localspace face centers and normals (average of its verts), from the derived mesh */
int *mirror_cache;
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 1bfe0eeea0b..149472db8fa 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -39,6 +39,7 @@ extern "C" {
struct AviCodecData;
struct Base;
+struct DisplaySafeAreas;
struct EvaluationContext;
struct bglMats;
struct Main;
@@ -110,7 +111,7 @@ char *BKE_scene_find_marker_name(struct Scene *scene, int frame);
char *BKE_scene_find_last_marker_name(struct Scene *scene, int frame);
/* checks for cycle, returns 1 if it's all OK */
-int BKE_scene_validate_setscene(struct Main *bmain, struct Scene *sce);
+bool BKE_scene_validate_setscene(struct Main *bmain, struct Scene *sce);
float BKE_scene_frame_get(struct Scene *scene);
float BKE_scene_frame_get_from_ctime(struct Scene *scene, const float frame);
@@ -131,7 +132,9 @@ int get_render_shadow_samples(struct RenderData *r, int samples);
float get_render_aosss_error(struct RenderData *r, float error);
bool BKE_scene_use_new_shading_nodes(struct Scene *scene);
+
bool BKE_scene_uses_blender_internal(struct Scene *scene);
+bool BKE_scene_uses_blender_game(struct Scene *scene);
void BKE_scene_disable_color_management(struct Scene *scene);
bool BKE_scene_check_color_management_enabled(const struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 188b8e22815..29590c52b23 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -52,6 +52,7 @@ struct wmKeyConfig;
struct wmNotifier;
struct wmWindow;
struct wmWindowManager;
+struct GPUFXSettings;
#include "BLI_compiler_attrs.h"
@@ -265,7 +266,7 @@ struct SpaceType *BKE_spacetype_from_id(int spaceid);
struct ARegionType *BKE_regiontype_from_id(struct SpaceType *st, int regionid);
const struct ListBase *BKE_spacetypes_list(void);
void BKE_spacetype_register(struct SpaceType *st);
-int BKE_spacetype_exists(int spaceid);
+bool BKE_spacetype_exists(int spaceid);
void BKE_spacetypes_free(void); /* only for quitting blender */
/* spacedata */
@@ -280,7 +281,9 @@ void BKE_screen_area_free(struct ScrArea *sa);
struct ARegion *BKE_area_find_region_type(struct ScrArea *sa, int type);
struct ARegion *BKE_area_find_region_active_win(struct ScrArea *sa);
+struct ScrArea *BKE_screen_find_area_from_space(struct bScreen *sc, struct SpaceLink *sl) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2);
struct ScrArea *BKE_screen_find_big_area(struct bScreen *sc, const int spacetype, const short min);
+struct ScrArea *BKE_screen_find_area_xy(struct bScreen *sc, const int spacetype, int x, int y);
unsigned int BKE_screen_view3d_layer_active_ex(
const struct View3D *v3d, const struct Scene *scene, bool use_localvd) ATTR_NONNULL(2);
@@ -292,6 +295,7 @@ void BKE_screen_view3d_scene_sync(struct bScreen *sc);
void BKE_screen_view3d_main_sync(ListBase *screen_lb, struct Scene *scene);
void BKE_screen_view3d_twmode_remove(struct View3D *v3d, const int i);
void BKE_screen_view3d_main_twmode_remove(ListBase *screen_lb, struct Scene *scene, const int i);
+void BKE_screen_gpu_fx_validate(struct GPUFXSettings *fx_settings);
/* zoom factor conversion */
float BKE_screen_view3d_zoom_to_fac(float camzoom);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index bbc4fd05256..c936ce5284d 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -34,6 +34,7 @@ struct bContext;
struct EvaluationContext;
struct StripColorBalance;
struct Editing;
+struct GSet;
struct ImBuf;
struct Main;
struct Mask;
@@ -102,8 +103,10 @@ typedef struct SeqRenderData {
bool is_proxy_render;
} SeqRenderData;
-SeqRenderData BKE_sequencer_new_render_data(struct EvaluationContext *eval_ctx, struct Main *bmain,
- struct Scene *scene, int rectx, int recty, int preview_render_size);
+void BKE_sequencer_new_render_data(
+ struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *scene,
+ int rectx, int recty, int preview_render_size,
+ SeqRenderData *r_context);
/* Wipe effect */
enum {
@@ -234,10 +237,11 @@ struct StripElem *BKE_sequencer_give_stripelem(struct Sequence *seq, int cfra);
void BKE_sequencer_update_changed_seq_and_deps(struct Scene *scene, struct Sequence *changed_seq, int len_change, int ibuf_change);
bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, struct Sequence *seq, float cfra);
-struct SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(struct Main *bmain, struct Scene *scene, struct Sequence *seq);
+struct SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(struct Main *bmain, struct Scene *scene, struct Sequence *seq, struct GSet *file_list);
void BKE_sequencer_proxy_rebuild(struct SeqIndexBuildContext *context, short *stop, short *do_update, float *progress);
void BKE_sequencer_proxy_rebuild_finish(struct SeqIndexBuildContext *context, bool stop);
+void BKE_sequencer_proxy_set(struct Sequence *seq, bool value);
/* **********************************************************************
* seqcache.c
*
@@ -249,25 +253,25 @@ typedef enum {
SEQ_STRIPELEM_IBUF_COMP,
SEQ_STRIPELEM_IBUF_STARTSTILL,
SEQ_STRIPELEM_IBUF_ENDSTILL
-} seq_stripelem_ibuf_t;
+} eSeqStripElemIBuf;
void BKE_sequencer_cache_destruct(void);
void BKE_sequencer_cache_cleanup(void);
/* returned ImBuf is properly refed and has to be freed */
-struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type);
+struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context, struct Sequence *seq, float cfra, eSeqStripElemIBuf type);
/* passed ImBuf is properly refed, so ownership is *not*
* transferred to the cache.
* you can pass the same ImBuf multiple times to the cache without problems.
*/
-void BKE_sequencer_cache_put(const SeqRenderData *context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type, struct ImBuf *nval);
+void BKE_sequencer_cache_put(const SeqRenderData *context, struct Sequence *seq, float cfra, eSeqStripElemIBuf type, struct ImBuf *nval);
void BKE_sequencer_cache_cleanup_sequence(struct Sequence *seq);
-struct ImBuf *BKE_sequencer_preprocessed_cache_get(const SeqRenderData *context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type);
-void BKE_sequencer_preprocessed_cache_put(const SeqRenderData *context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type, struct ImBuf *ibuf);
+struct ImBuf *BKE_sequencer_preprocessed_cache_get(const SeqRenderData *context, struct Sequence *seq, float cfra, eSeqStripElemIBuf type);
+void BKE_sequencer_preprocessed_cache_put(const SeqRenderData *context, struct Sequence *seq, float cfra, eSeqStripElemIBuf type, struct ImBuf *ibuf);
void BKE_sequencer_preprocessed_cache_cleanup(void);
void BKE_sequencer_preprocessed_cache_cleanup_sequence(struct Sequence *seq);
@@ -310,9 +314,13 @@ struct Sequence *BKE_sequence_metastrip(ListBase *seqbase /* = ed->seqbase */, s
void BKE_sequencer_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs);
void BKE_sequencer_dupe_animdata(struct Scene *scene, const char *name_src, const char *name_dst);
-bool BKE_sequence_base_shuffle(struct ListBase *seqbasep, struct Sequence *test, struct Scene *evil_scene);
+bool BKE_sequence_base_shuffle_ex(
+ struct ListBase *seqbasep, struct Sequence *test, struct Scene *evil_scene,
+ int channel_delta);
+bool BKE_sequence_base_shuffle(
+ struct ListBase *seqbasep, struct Sequence *test, struct Scene *evil_scene);
bool BKE_sequence_base_shuffle_time(ListBase *seqbasep, struct Scene *evil_scene);
-bool BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase, bool one_only);
+bool BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase);
void BKE_sequencer_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, bool for_render);
struct Sequence *BKE_sequence_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence *seq, int dupe_flag);
int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
@@ -377,12 +385,23 @@ struct Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine);
void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq);
void BKE_sequence_init_colorspace(struct Sequence *seq);
+/* RNA enums, just to be more readable */
+enum {
+ SEQ_SIDE_NONE = 0,
+ SEQ_SIDE_LEFT,
+ SEQ_SIDE_RIGHT,
+ SEQ_SIDE_BOTH
+};
+int BKE_sequencer_find_next_prev_edit(
+ struct Scene *scene, int cfra, const short side,
+ const bool do_skip_mute, const bool do_center, const bool do_unselected);
+
struct Sequence *BKE_sequencer_add_image_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
struct Sequence *BKE_sequencer_add_sound_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
/* view3d draw callback, run when not in background view */
-typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, bool, bool, int, char[256]);
+typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, bool, bool, bool, int, char[256]);
extern SequencerDrawView sequencer_view3d_cb;
/* copy/paste */
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 50ca5fcdf7b..a4182b8405f 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -71,8 +71,6 @@ void sound_delete(struct Main *bmain, struct bSound *sound);
void sound_cache(struct bSound *sound);
-void sound_cache_notifying(struct Main *main, struct bSound *sound);
-
void sound_delete_cache(struct bSound *sound);
void sound_load(struct Main *main, struct bSound *sound);
@@ -132,7 +130,7 @@ int sound_scene_playing(struct Scene *scene);
void sound_free_waveform(struct bSound *sound);
-void sound_read_waveform(struct bSound *sound);
+void sound_read_waveform(struct bSound *sound, short *stop);
void sound_update_scene(struct Main *bmain, struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index 1e79eaa8431..96e88f80464 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -51,7 +51,7 @@ int BKE_text_reload (struct Text *text);
struct Text *BKE_text_load_ex(struct Main *bmain, const char *file, const char *relpath,
const bool is_internal);
struct Text *BKE_text_load (struct Main *bmain, const char *file, const char *relpath);
-struct Text *BKE_text_copy (struct Text *ta);
+struct Text *BKE_text_copy (struct Main *bmain, struct Text *ta);
void BKE_text_unlink (struct Main *bmain, struct Text *text);
void BKE_text_clear (struct Text *text);
void BKE_text_write (struct Text *text, const char *str);
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 4ad84dceb53..ebf85ff51d1 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -132,6 +132,7 @@ struct OceanTex *BKE_add_oceantex(void);
struct OceanTex *BKE_copy_oceantex(struct OceanTex *ot);
bool BKE_texture_dependsOnTime(const struct Tex *texture);
+bool BKE_texture_is_image_user(const struct Tex *tex);
void BKE_texture_get_value(struct Scene *scene, struct Tex *texture, float *tex_co, struct TexResult *texres, bool use_color_management);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 8bc619c1b27..e5fb60cf1b5 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -145,6 +145,9 @@ void BKE_tracking_plane_marker_delete(struct MovieTrackingPlaneTrack *plane_trac
struct MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get(struct MovieTrackingPlaneTrack *plane_track, int framenr);
struct MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get_exact(struct MovieTrackingPlaneTrack *plane_track, int framenr);
struct MovieTrackingPlaneMarker *BKE_tracking_plane_marker_ensure(struct MovieTrackingPlaneTrack *plane_track, int framenr);
+void BKE_tracking_plane_marker_get_subframe_corners(struct MovieTrackingPlaneTrack *plane_track,
+ float framenr,
+ float corners[4][2]);
/* **** Object **** */
struct MovieTrackingObject *BKE_tracking_object_add(struct MovieTracking *tracking, const char *name);
@@ -210,16 +213,18 @@ void BKE_tracking_disable_channels(struct ImBuf *ibuf, bool disable_red, bool di
bool disable_blue, bool grayscale);
/* **** 2D tracking **** */
-struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user,
- const bool backwards, const bool sequence);
-void BKE_tracking_context_free(struct MovieTrackingContext *context);
-void BKE_tracking_context_sync(struct MovieTrackingContext *context);
-void BKE_tracking_context_sync_user(const struct MovieTrackingContext *context, struct MovieClipUser *user);
-bool BKE_tracking_context_step(struct MovieTrackingContext *context);
-void BKE_tracking_context_finish(struct MovieTrackingContext *context);
-
void BKE_tracking_refine_marker(struct MovieClip *clip, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, bool backwards);
+/* *** 2D auto track *** */
+
+struct AutoTrackContext *BKE_autotrack_context_new(struct MovieClip *clip, struct MovieClipUser *user,
+ const bool backwards, const bool sequence);
+bool BKE_autotrack_context_step(struct AutoTrackContext *context);
+void BKE_autotrack_context_sync(struct AutoTrackContext *context);
+void BKE_autotrack_context_sync_user(struct AutoTrackContext *context, struct MovieClipUser *user);
+void BKE_autotrack_context_finish(struct AutoTrackContext *context);
+void BKE_autotrack_context_free(struct AutoTrackContext *context);
+
/* **** Plane tracking **** */
void BKE_tracking_track_plane_from_existing_motion(struct MovieTrackingPlaneTrack *plane_track, int start_frame);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 2a857a33d2c..162089c6e1d 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -36,7 +36,9 @@ set(INC
../bmesh
../modifiers
../nodes
+ ../physics
../render/extern/include
+ ../../../intern/ghost
../../../intern/guardedalloc
../../../intern/glew-mx
../../../intern/iksolver/extern
@@ -44,8 +46,8 @@ set(INC
../../../intern/mikktspace
../../../intern/raskter
../../../intern/smoke/extern
- ../../../extern/libmv
../../../intern/atomic
+ ../../../extern/libmv
# XXX - BAD LEVEL CALL WM_api.h
../windowmanager
@@ -64,6 +66,7 @@ set(SRC
intern/addon.c
intern/anim.c
intern/anim_sys.c
+ intern/appdir.c
intern/armature.c
intern/autoexec.c
intern/blender.c
@@ -84,6 +87,7 @@ set(SRC
intern/curve.c
intern/customdata.c
intern/customdata_file.c
+ intern/data_transfer.c
intern/deform.c
intern/depsgraph.c
intern/displist.c
@@ -104,7 +108,6 @@ set(SRC
intern/idprop.c
intern/image.c
intern/image_gen.c
- intern/implicit.c
intern/ipo.c
intern/key.c
intern/lamp.c
@@ -120,6 +123,7 @@ set(SRC
intern/mesh.c
intern/mesh_evaluate.c
intern/mesh_mapping.c
+ intern/mesh_remap.c
intern/mesh_validate.c
intern/modifier.c
intern/modifiers_bmesh.c
@@ -134,6 +138,8 @@ set(SRC
intern/packedFile.c
intern/paint.c
intern/particle.c
+ intern/particle_child.c
+ intern/particle_distribute.c
intern/particle_system.c
intern/pbvh.c
intern/pbvh_bmesh.c
@@ -159,6 +165,7 @@ set(SRC
intern/text.c
intern/texture.c
intern/tracking.c
+ intern/tracking_auto.c
intern/tracking_detect.c
intern/tracking_plane_tracker.c
intern/tracking_region_tracker.c
@@ -176,6 +183,7 @@ set(SRC
BKE_addon.h
BKE_anim.h
BKE_animsys.h
+ BKE_appdir.h
BKE_armature.h
BKE_autoexec.h
BKE_blender.h
@@ -198,6 +206,7 @@ set(SRC
BKE_curve.h
BKE_customdata.h
BKE_customdata_file.h
+ BKE_data_transfer.h
BKE_deform.h
BKE_depsgraph.h
BKE_displist.h
@@ -227,6 +236,7 @@ set(SRC
BKE_mball.h
BKE_mesh.h
BKE_mesh_mapping.h
+ BKE_mesh_remap.h
BKE_modifier.h
BKE_movieclip.h
BKE_multires.h
@@ -272,10 +282,24 @@ set(SRC
tracking_private.h
intern/CCGSubSurf.h
intern/pbvh_intern.h
+ intern/data_transfer_intern.h
)
+if(WITH_BINRELOC)
+ list(APPEND INC_SYS
+ ${BINRELOC_INCLUDE_DIRS}
+ )
+ add_definitions(-DWITH_BINRELOC)
+endif()
+
add_definitions(${GL_DEFINITIONS})
+if(WIN32)
+ list(APPEND INC
+ ../../../intern/utfconv
+ )
+endif()
+
if(WITH_AUDASPACE)
list(APPEND INC
../../../intern/audaspace/intern
@@ -403,9 +427,16 @@ if(WITH_JACK)
endif()
if(WITH_LZO)
- list(APPEND INC_SYS
- ../../../extern/lzo/minilzo
- )
+ if(WITH_SYSTEM_LZO)
+ list(APPEND INC_SYS
+ ${LZO_INCLUDE_DIR}
+ )
+ add_definitions(-DWITH_SYSTEM_LZO)
+ else()
+ list(APPEND INC_SYS
+ ../../../extern/lzo/minilzo
+ )
+ endif()
add_definitions(-DWITH_LZO)
endif()
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 1389cd0241c..4897949ae44 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -46,6 +46,7 @@ incs = [
'#/intern/rigidbody',
'#/extern/bullet2/src',
env['BF_GLEW_INC'],
+ '#/intern/ghost',
'#/intern/glew-mx',
'#/intern/audaspace/intern',
'#/intern/elbeem/extern',
@@ -65,6 +66,7 @@ incs = [
'../makesrna',
'../modifiers',
'../nodes',
+ '../physics',
'../render/extern/include',
'../windowmanager',
env['BF_ZLIB_INC'],
@@ -171,7 +173,11 @@ if env['WITH_BF_FREESTYLE']:
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
+ incs += ' ../../../intern/utfconv'
+if env['WITH_BF_BINRELOC']:
+ incs += ' #extern/binreloc/include'
+ defs.append('WITH_BINRELOC')
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [166,25]) #, cc_compileflags = env['CCFLAGS'].append('/WX') )
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 623fb50b62c..cadca6b2623 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -172,29 +172,19 @@ static void *_ehash_lookup(EHash *eh, void *key)
/**/
-typedef struct _EHashIterator {
- EHash *eh;
- int curBucket;
- EHEntry *curEntry;
-} EHashIterator;
-
-static EHashIterator *_ehashIterator_new(EHash *eh)
+static void _ehashIterator_init(EHash *eh, EHashIterator *ehi)
{
- EHashIterator *ehi = EHASH_alloc(eh, sizeof(*ehi));
+ /* fill all members */
ehi->eh = eh;
- ehi->curEntry = NULL;
ehi->curBucket = -1;
+ ehi->curEntry = NULL;
+
while (!ehi->curEntry) {
ehi->curBucket++;
if (ehi->curBucket == ehi->eh->curSize)
break;
ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
}
- return ehi;
-}
-static void _ehashIterator_free(EHashIterator *ehi)
-{
- EHASH_free(ehi->eh, ehi);
}
static void *_ehashIterator_getCurrent(EHashIterator *ehi)
@@ -223,15 +213,15 @@ static int _ehashIterator_isStopped(EHashIterator *ehi)
static void *_stdAllocator_alloc(CCGAllocatorHDL UNUSED(a), int numBytes)
{
- return malloc(numBytes);
+ return MEM_mallocN(numBytes, "CCG standard alloc");
}
static void *_stdAllocator_realloc(CCGAllocatorHDL UNUSED(a), void *ptr, int newSize, int UNUSED(oldSize))
{
- return realloc(ptr, newSize);
+ return MEM_reallocN(ptr, newSize);
}
static void _stdAllocator_free(CCGAllocatorHDL UNUSED(a), void *ptr)
{
- free(ptr);
+ MEM_freeN(ptr);
}
static CCGAllocatorIFC *_getStandardAllocatorIFC(void)
@@ -589,8 +579,14 @@ static float *_vert_getNo(CCGVert *v, int lvl, int dataSize, int normalDataOffse
static void _vert_free(CCGVert *v, CCGSubSurf *ss)
{
- CCGSUBSURF_free(ss, v->edges);
- CCGSUBSURF_free(ss, v->faces);
+ if (v->edges) {
+ CCGSUBSURF_free(ss, v->edges);
+ }
+
+ if (v->faces) {
+ CCGSUBSURF_free(ss, v->faces);
+ }
+
CCGSUBSURF_free(ss, v);
}
@@ -679,7 +675,10 @@ static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSiz
static void _edge_free(CCGEdge *e, CCGSubSurf *ss)
{
- CCGSUBSURF_free(ss, e->faces);
+ if (e->faces) {
+ CCGSUBSURF_free(ss, e->faces);
+ }
+
CCGSUBSURF_free(ss, e);
}
static void _edge_unlinkMarkAndFree(CCGEdge *e, CCGSubSurf *ss)
@@ -3051,17 +3050,17 @@ void *ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int
/*** External API iterator functions ***/
-CCGVertIterator *ccgSubSurf_getVertIterator(CCGSubSurf *ss)
+void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter)
{
- return (CCGVertIterator *) _ehashIterator_new(ss->vMap);
+ _ehashIterator_init(ss->vMap, viter);
}
-CCGEdgeIterator *ccgSubSurf_getEdgeIterator(CCGSubSurf *ss)
+void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter)
{
- return (CCGEdgeIterator *) _ehashIterator_new(ss->eMap);
+ _ehashIterator_init(ss->eMap, eiter);
}
-CCGFaceIterator *ccgSubSurf_getFaceIterator(CCGSubSurf *ss)
+void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter)
{
- return (CCGFaceIterator *) _ehashIterator_new(ss->fMap);
+ _ehashIterator_init(ss->fMap, fiter);
}
CCGVert *ccgVertIterator_getCurrent(CCGVertIterator *vi)
@@ -3076,10 +3075,6 @@ void ccgVertIterator_next(CCGVertIterator *vi)
{
_ehashIterator_next((EHashIterator *) vi);
}
-void ccgVertIterator_free(CCGVertIterator *vi)
-{
- _ehashIterator_free((EHashIterator *) vi);
-}
CCGEdge *ccgEdgeIterator_getCurrent(CCGEdgeIterator *vi)
{
@@ -3093,10 +3088,6 @@ void ccgEdgeIterator_next(CCGEdgeIterator *vi)
{
_ehashIterator_next((EHashIterator *) vi);
}
-void ccgEdgeIterator_free(CCGEdgeIterator *vi)
-{
- _ehashIterator_free((EHashIterator *) vi);
-}
CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *vi)
{
@@ -3110,10 +3101,6 @@ void ccgFaceIterator_next(CCGFaceIterator *vi)
{
_ehashIterator_next((EHashIterator *) vi);
}
-void ccgFaceIterator_free(CCGFaceIterator *vi)
-{
- _ehashIterator_free((EHashIterator *) vi);
-}
/*** Extern API final vert/edge/face interface ***/
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index fdf6d2df99f..2b86a2a66b2 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -53,6 +53,13 @@ typedef struct CCGAllocatorIFC {
void (*release) (CCGAllocatorHDL a);
} CCGAllocatorIFC;
+/* private, so we can allocate on the stack */
+typedef struct _EHashIterator {
+ struct _EHash *eh;
+ int curBucket;
+ struct _EHEntry *curEntry;
+} EHashIterator;
+
/***/
typedef enum {
@@ -163,27 +170,24 @@ int ccgSubSurf_getNumFinalFaces (const CCGSubSurf *ss);
/***/
-typedef struct CCGVertIterator CCGVertIterator;
-typedef struct CCGEdgeIterator CCGEdgeIterator;
-typedef struct CCGFaceIterator CCGFaceIterator;
+typedef struct _EHashIterator CCGVertIterator;
+typedef struct _EHashIterator CCGEdgeIterator;
+typedef struct _EHashIterator CCGFaceIterator;
-CCGVertIterator* ccgSubSurf_getVertIterator (CCGSubSurf *ss);
-CCGEdgeIterator* ccgSubSurf_getEdgeIterator (CCGSubSurf *ss);
-CCGFaceIterator* ccgSubSurf_getFaceIterator (CCGSubSurf *ss);
+void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter);
+void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter);
+void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter);
CCGVert* ccgVertIterator_getCurrent (CCGVertIterator *vi);
int ccgVertIterator_isStopped (CCGVertIterator *vi);
void ccgVertIterator_next (CCGVertIterator *vi);
-void ccgVertIterator_free (CCGVertIterator *vi);
CCGEdge* ccgEdgeIterator_getCurrent (CCGEdgeIterator *ei);
int ccgEdgeIterator_isStopped (CCGEdgeIterator *ei);
void ccgEdgeIterator_next (CCGEdgeIterator *ei);
-void ccgEdgeIterator_free (CCGEdgeIterator *ei);
CCGFace* ccgFaceIterator_getCurrent (CCGFaceIterator *fi);
int ccgFaceIterator_isStopped (CCGFaceIterator *fi);
void ccgFaceIterator_next (CCGFaceIterator *fi);
-void ccgFaceIterator_free (CCGFaceIterator *fi);
#endif /* __CCGSUBSURF_H__ */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 81c03d8081b..0bfa3628967 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -73,13 +73,11 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
#include "BLI_sys_types.h" /* for intptr_t support */
#include "GPU_buffers.h"
-#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
-#include "GPU_material.h"
/* very slow! enable for testing only! */
-// #define USE_MODIFIER_VALIDATE
+//#define USE_MODIFIER_VALIDATE
#ifdef USE_MODIFIER_VALIDATE
# define ASSERT_IS_VALID_DM(dm) (BLI_assert((dm == NULL) || (DM_is_valid(dm) == true)))
@@ -394,9 +392,9 @@ void DM_ensure_normals(DerivedMesh *dm)
BLI_assert((dm->dirty & DM_DIRTY_NORMALS) == 0);
}
-static void DM_calc_loop_normals(DerivedMesh *dm, float split_angle)
+static void DM_calc_loop_normals(DerivedMesh *dm, const bool use_split_normals, float split_angle)
{
- dm->calcLoopNormals(dm, split_angle);
+ dm->calcLoopNormals(dm, use_split_normals, split_angle);
dm->dirty |= DM_DIRTY_TESS_CDLAYERS;
}
@@ -533,13 +531,26 @@ MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr)
return tf_base;
}
-void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
+void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask, bool take_ownership)
{
/* dm might depend on me, so we need to do everything with a local copy */
Mesh tmp = *me;
int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly;
int did_shapekeys = 0;
-
+ int alloctype = CD_DUPLICATE;
+
+ if (take_ownership && dm->type == DM_TYPE_CDDM && dm->needsFree) {
+ bool has_any_referenced_layers =
+ CustomData_has_referenced(&dm->vertData) ||
+ CustomData_has_referenced(&dm->edgeData) ||
+ CustomData_has_referenced(&dm->loopData) ||
+ CustomData_has_referenced(&dm->faceData) ||
+ CustomData_has_referenced(&dm->polyData);
+ if (!has_any_referenced_layers) {
+ alloctype = CD_ASSIGN;
+ }
+ }
+
CustomData_reset(&tmp.vdata);
CustomData_reset(&tmp.edata);
CustomData_reset(&tmp.fdata);
@@ -554,10 +565,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
totpoly = tmp.totpoly = dm->getNumPolys(dm);
tmp.totface = 0;
- CustomData_copy(&dm->vertData, &tmp.vdata, mask, CD_DUPLICATE, totvert);
- CustomData_copy(&dm->edgeData, &tmp.edata, mask, CD_DUPLICATE, totedge);
- CustomData_copy(&dm->loopData, &tmp.ldata, mask, CD_DUPLICATE, totloop);
- CustomData_copy(&dm->polyData, &tmp.pdata, mask, CD_DUPLICATE, totpoly);
+ CustomData_copy(&dm->vertData, &tmp.vdata, mask, alloctype, totvert);
+ CustomData_copy(&dm->edgeData, &tmp.edata, mask, alloctype, totedge);
+ CustomData_copy(&dm->loopData, &tmp.ldata, mask, alloctype, totloop);
+ CustomData_copy(&dm->polyData, &tmp.pdata, mask, alloctype, totpoly);
tmp.cd_flag = dm->cd_flag;
if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) {
@@ -592,13 +603,19 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
/* not all DerivedMeshes store their verts/edges/faces in CustomData, so
* we set them here in case they are missing */
- if (!CustomData_has_layer(&tmp.vdata, CD_MVERT))
- CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, dm->dupVertArray(dm), totvert);
- if (!CustomData_has_layer(&tmp.edata, CD_MEDGE))
- CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge);
+ if (!CustomData_has_layer(&tmp.vdata, CD_MVERT)) {
+ CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN,
+ (alloctype == CD_ASSIGN) ? dm->getVertArray(dm) : dm->dupVertArray(dm),
+ totvert);
+ }
+ if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) {
+ CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN,
+ (alloctype == CD_ASSIGN) ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm),
+ totedge);
+ }
if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
- tmp.mloop = dm->dupLoopArray(dm);
- tmp.mpoly = dm->dupPolyArray(dm);
+ tmp.mloop = (alloctype == CD_ASSIGN) ? dm->getLoopArray(dm) : dm->dupLoopArray(dm);
+ tmp.mpoly = (alloctype == CD_ASSIGN) ? dm->getPolyArray(dm) : dm->dupPolyArray(dm);
CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, tmp.mloop, tmp.totloop);
CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly);
@@ -609,7 +626,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
if (CustomData_has_layer(&me->ldata, CD_MDISPS)) {
if (totloop == me->totloop) {
MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
- CustomData_add_layer(&tmp.ldata, CD_MDISPS, CD_DUPLICATE, mdisps, totloop);
+ CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop);
}
}
@@ -643,6 +660,16 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
/* skip the listbase */
MEMCPY_STRUCT_OFS(me, &tmp, id.prev);
+
+ if (take_ownership) {
+ if (alloctype == CD_ASSIGN) {
+ CustomData_free_typemask(&dm->vertData, dm->numVertData, ~mask);
+ CustomData_free_typemask(&dm->edgeData, dm->numEdgeData, ~mask);
+ CustomData_free_typemask(&dm->loopData, dm->numLoopData, ~mask);
+ CustomData_free_typemask(&dm->polyData, dm->numPolyData, ~mask);
+ }
+ dm->release(dm);
+ }
}
void DM_to_meshkey(DerivedMesh *dm, Mesh *me, KeyBlock *kb)
@@ -914,7 +941,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob,
if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL;
if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob->shapenr - 1))) {
- BKE_key_convert_to_mesh(kb, me);
+ BKE_keyblock_convert_to_mesh(kb, me);
}
if (mti->type == eModifierTypeType_OnlyDeform) {
@@ -1221,14 +1248,14 @@ static void calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const d
unsigned int i;
/* variables for multipaint */
- const int defbase_tot = BLI_countlist(&ob->defbase);
+ const int defbase_tot = BLI_listbase_count(&ob->defbase);
const int defbase_act = ob->actdef - 1;
int defbase_sel_tot = 0;
bool *defbase_sel = NULL;
if (draw_flag & CALC_WP_MULTIPAINT) {
- defbase_sel = BKE_objdef_selected_get(ob, defbase_tot, &defbase_sel_tot);
+ defbase_sel = BKE_object_defgroup_selected_get(ob, defbase_tot, &defbase_sel_tot);
}
for (i = numVerts; i != 0; i--, wc++, dv++) {
@@ -1451,8 +1478,10 @@ static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *UNUSED(ob))
*/
static void dm_ensure_display_normals(DerivedMesh *dm)
{
- /* this is for final output only, up until now this layer should be missing */
- BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
+ /* Note: dm *may* have a poly CD_NORMAL layer (generated by a modifier needing poly normals e.g.).
+ * We do not use it here, though. And it should be tagged as temp!
+ */
+ /* BLI_assert((CustomData_has_layer(&dm->polyData, CD_NORMAL) == false)); */
if ((dm->type == DM_TYPE_CDDM) &&
((dm->dirty & DM_DIRTY_NORMALS) || CustomData_has_layer(&dm->faceData, CD_NORMAL) == false))
@@ -1486,8 +1515,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
const bool has_multires = (mmd && mmd->sculptlvl != 0);
bool multires_applied = false;
- const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt;
- const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm);
+ const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams;
+ const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !useRenderParams;
const int draw_flag = dm_drawflag_calc(scene->toolsettings);
/* Generic preview only in object mode! */
@@ -1500,7 +1529,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
/* XXX Same as above... For now, only weights preview in WPaint mode. */
const bool do_mod_wmcol = do_init_wmcol;
- const bool do_loop_normals = (me->flag & ME_AUTOSMOOTH);
+ const bool do_loop_normals = (me->flag & ME_AUTOSMOOTH) != 0;
const float loop_normals_split_angle = me->smoothresh;
VirtualModifierData virtualModifierData;
@@ -1906,7 +1935,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
if (do_loop_normals) {
/* Compute loop normals (note: will compute poly and vert normals as well, if needed!) */
- DM_calc_loop_normals(finaldm, loop_normals_split_angle);
+ DM_calc_loop_normals(finaldm, do_loop_normals, loop_normals_split_angle);
}
{
@@ -1977,10 +2006,10 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *
if (!modifier_isEnabled(scene, md, required_mode)) return 0;
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
modifier_setError(md, "Modifier requires original data, bad stack position");
- return 0;
+ return false;
}
- return 1;
+ return true;
}
static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh **cage_r,
@@ -2006,7 +2035,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
const bool do_mod_wmcol = do_init_wmcol;
VirtualModifierData virtualModifierData;
- const bool do_loop_normals = (((Mesh *)(ob->data))->flag & ME_AUTOSMOOTH);
+ const bool do_loop_normals = (((Mesh *)(ob->data))->flag & ME_AUTOSMOOTH) != 0;
const float loop_normals_split_angle = ((Mesh *)(ob->data))->smoothresh;
modifiers_clearErrors(ob);
@@ -2222,9 +2251,9 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
if (do_loop_normals) {
/* Compute loop normals */
- DM_calc_loop_normals(*final_r, loop_normals_split_angle);
+ DM_calc_loop_normals(*final_r, do_loop_normals, loop_normals_split_angle);
if (cage_r && *cage_r && (*cage_r != *final_r)) {
- DM_calc_loop_normals(*cage_r, loop_normals_split_angle);
+ DM_calc_loop_normals(*cage_r, do_loop_normals, loop_normals_split_angle);
}
}
@@ -2511,7 +2540,9 @@ DerivedMesh *object_get_derived_final(Object *ob, const bool for_render)
return ob->derivedFinal;
}
- if (em) {
+ /* only return the editmesh if its from this object because
+ * we don't a mesh from another object's modifier stack: T43122 */
+ if (em && (em->ob == ob)) {
DerivedMesh *dm = em->derivedFinal;
return dm;
}
@@ -2960,7 +2991,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
a = attribs->tottface++;
if (layer != -1) {
- attribs->tface[a].array = tfdata->layers[layer].data;
+ attribs->tface[a].array = NULL;
attribs->tface[a].em_offset = ldata->layers[layer].offset;
}
else {
@@ -3007,7 +3038,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
a = attribs->totmcol++;
if (layer != -1) {
- attribs->mcol[a].array = tfdata->layers[layer].data;
+ attribs->mcol[a].array = NULL;
/* odd, store the offset for a different layer type here, but editmode draw code expects it */
attribs->mcol[a].em_offset = ldata->layers[layer].offset;
}
@@ -3078,6 +3109,69 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
}
}
+/* Set vertex shader attribute inputs for a particular tessface vert
+ *
+ * a: tessface index
+ * index: vertex index
+ * vert: corner index (0, 1, 2, 3)
+ */
+void DM_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert)
+{
+ const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ int b;
+
+ /* orco texture coordinates */
+ if (attribs->totorco) {
+ /*const*/ float (*array)[3] = attribs->orco.array;
+ const float *orco = (array) ? array[index] : zero;
+
+ if (attribs->orco.gl_texco)
+ glTexCoord3fv(orco);
+ else
+ glVertexAttrib3fvARB(attribs->orco.gl_index, orco);
+ }
+
+ /* uv texture coordinates */
+ for (b = 0; b < attribs->tottface; b++) {
+ const float *uv;
+
+ if (attribs->tface[b].array) {
+ MTFace *tf = &attribs->tface[b].array[a];
+ uv = tf->uv[vert];
+ }
+ else {
+ uv = zero;
+ }
+
+ if (attribs->tface[b].gl_texco)
+ glTexCoord2fv(uv);
+ else
+ glVertexAttrib2fvARB(attribs->tface[b].gl_index, uv);
+ }
+
+ /* vertex colors */
+ for (b = 0; b < attribs->totmcol; b++) {
+ GLubyte col[4];
+
+ if (attribs->mcol[b].array) {
+ MCol *cp = &attribs->mcol[b].array[a * 4 + vert];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ }
+ else {
+ col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
+ }
+
+ glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col);
+ }
+
+ /* tangent for normal mapping */
+ if (attribs->tottang) {
+ /*const*/ float (*array)[4] = attribs->tang.array;
+ const float *tang = (array) ? array[a * 4 + vert] : zero;
+ glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
+ }
+}
+
/* Set object's bounding box based on DerivedMesh min/max data */
void DM_set_object_boundbox(Object *ob, DerivedMesh *dm)
{
@@ -3141,7 +3235,8 @@ static void navmesh_drawColored(DerivedMesh *dm)
#endif
glDisable(GL_LIGHTING);
- /* if (GPU_buffer_legacy(dm) ) */ { /* TODO - VBO draw code, not high priority - campbell */
+ /* if (GPU_buffer_legacy(dm) ) */ /* TODO - VBO draw code, not high priority - campbell */
+ {
DEBUG_VBO("Using legacy code. drawNavMeshColored\n");
//glShadeModel(GL_SMOOTH);
glBegin(glmode = GL_QUADS);
@@ -3325,7 +3420,7 @@ static void dm_debug_info_layers(DynStr *dynstr, DerivedMesh *dm, CustomData *cd
CustomData_file_write_info(type, &structname, &structnum);
BLI_dynstr_appendf(dynstr,
" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
- name, structname, type, (void *)pt, size, pt_size);
+ name, structname, type, (const void *)pt, size, pt_size);
}
}
}
@@ -3389,7 +3484,7 @@ void DM_debug_print(DerivedMesh *dm)
void DM_debug_print_cdlayers(CustomData *data)
{
int i;
- CustomDataLayer *layer;
+ const CustomDataLayer *layer;
printf("{\n");
@@ -3401,7 +3496,7 @@ void DM_debug_print_cdlayers(CustomData *data)
int structnum;
CustomData_file_write_info(layer->type, &structname, &structnum);
printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
- name, structname, layer->type, (void *)layer->data, size, (int)(MEM_allocN_len(layer->data) / size));
+ name, structname, layer->type, (const void *)layer->data, size, (int)(MEM_allocN_len(layer->data) / size));
}
printf("}\n");
@@ -3420,7 +3515,7 @@ bool DM_is_valid(DerivedMesh *dm)
dm->getEdgeDataLayout(dm),
dm->getLoopDataLayout(dm),
dm->getPolyDataLayout(dm),
- 0, /* setting mask here isn't useful, gives false positives */
+ false, /* setting mask here isn't useful, gives false positives */
do_verbose, do_fixes, &changed);
is_valid &= BKE_mesh_validate_arrays(
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index c6dcca576fb..f9556bf39ab 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -215,6 +215,10 @@ bAction *BKE_action_copy(bAction *src)
}
}
+ if (src->id.lib) {
+ BKE_id_lib_local_paths(G.main, src->id.lib, &dst->id);
+ }
+
return dst;
}
@@ -450,9 +454,9 @@ bPoseChannel *BKE_pose_channel_find_name(const bPose *pose, const char *name)
return NULL;
if (pose->chanhash)
- return BLI_ghash_lookup(pose->chanhash, (void *)name);
+ return BLI_ghash_lookup(pose->chanhash, (const void *)name);
- return BLI_findstring(&((bPose *)pose)->chanbase, name, offsetof(bPoseChannel, name));
+ return BLI_findstring(&((const bPose *)pose)->chanbase, name, offsetof(bPoseChannel, name));
}
/**
@@ -729,7 +733,7 @@ void BKE_pose_channel_free_ex(bPoseChannel *pchan, bool do_id_user)
pchan->mpath = NULL;
}
- BKE_constraints_free(&pchan->constraints);
+ BKE_constraints_free_ex(&pchan->constraints, do_id_user);
if (pchan->prop) {
IDP_FreeProperty(pchan->prop);
@@ -966,7 +970,7 @@ bActionGroup *BKE_pose_add_group(bPose *pose, const char *name)
BLI_addtail(&pose->agroups, grp);
BLI_uniquename(&pose->agroups, grp, name, '.', offsetof(bActionGroup, name), sizeof(grp->name));
- pose->active_group = BLI_countlist(&pose->agroups);
+ pose->active_group = BLI_listbase_count(&pose->agroups);
return grp;
}
@@ -998,8 +1002,12 @@ void BKE_pose_remove_group(bPose *pose, bActionGroup *grp, const int index)
/* now, remove it from the pose */
BLI_freelinkN(&pose->agroups, grp);
if (pose->active_group >= idx) {
+ const bool has_groups = !BLI_listbase_is_empty(&pose->agroups);
pose->active_group--;
- if (pose->active_group < 0 || BLI_listbase_is_empty(&pose->agroups)) {
+ if (pose->active_group == 0 && has_groups) {
+ pose->active_group = 1;
+ }
+ else if (pose->active_group < 0 || !has_groups) {
pose->active_group = 0;
}
}
@@ -1028,12 +1036,12 @@ bool action_has_motion(const bAction *act)
if (act) {
for (fcu = act->curves.first; fcu; fcu = fcu->next) {
if (fcu->totvert)
- return 1;
+ return true;
}
}
/* nothing found */
- return 0;
+ return false;
}
/* Calculate the extents of given action */
diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c
index 119fa266908..28667d458b8 100644
--- a/source/blender/blenkernel/intern/addon.c
+++ b/source/blender/blenkernel/intern/addon.c
@@ -29,15 +29,9 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
-#include "BLI_string.h"
#include "BKE_addon.h" /* own include */
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "BLF_translation.h"
-
#include "MEM_guardedalloc.h"
static GHash *global_addonpreftype_hash = NULL;
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index aff99d3e1bf..b878dbe1f39 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -627,6 +627,9 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua
if (!bl->nr) return 0;
if (bl->poly > -1) cycl = 1;
+ /* values below zero for non-cyclic curves give strange results */
+ BLI_assert(cycl || ctime >= 0.0f);
+
ctime *= (path->len - 1);
s1 = (int)floor(ctime);
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 2fb832dc72d..effe32a8079 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -83,7 +83,7 @@ bool id_type_can_have_animdata(ID *id)
{
/* sanity check */
if (id == NULL)
- return 0;
+ return false;
/* Only some ID-blocks have this info for now */
/* TODO: finish adding this for the other blocktypes */
@@ -100,13 +100,14 @@ bool id_type_can_have_animdata(ID *id)
case ID_SCE:
case ID_MC:
case ID_MSK:
+ case ID_GD:
{
- return 1;
+ return true;
}
/* no AnimData */
default:
- return 0;
+ return false;
}
}
@@ -193,20 +194,20 @@ bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
/* can set */
adt->action = act;
id_us_plus((ID *)adt->action);
- ok = 1;
+ ok = true;
}
else {
/* cannot set */
BKE_reportf(reports, RPT_ERROR,
"Could not set action '%s' onto ID '%s', as it does not have suitably rooted paths "
"for this purpose", act->id.name + 2, id->name);
- /* ok = 0; */
+ /* ok = false; */
}
}
else {
/* just clearing the action... */
adt->action = NULL;
- ok = 1;
+ ok = true;
}
return ok;
@@ -289,7 +290,7 @@ bool BKE_copy_animdata_id(ID *id_to, ID *id_from, const bool do_action)
AnimData *adt;
if ((id_to && id_from) && (GS(id_to->name) != GS(id_from->name)))
- return 0;
+ return false;
BKE_free_animdata(id_to);
@@ -299,7 +300,7 @@ bool BKE_copy_animdata_id(ID *id_to, ID *id_from, const bool do_action)
iat->adt = BKE_copy_animdata(adt, do_action);
}
- return 1;
+ return true;
}
void BKE_copy_animdata_id_action(ID *id)
@@ -317,6 +318,77 @@ void BKE_copy_animdata_id_action(ID *id)
}
}
+/* Merge copies of the data from the src AnimData into the destination AnimData */
+void BKE_animdata_merge_copy(ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
+{
+ AnimData *src = BKE_animdata_from_id(src_id);
+ AnimData *dst = BKE_animdata_from_id(dst_id);
+
+ /* sanity checks */
+ if (ELEM(NULL, dst, src))
+ return;
+
+ // TODO: we must unset all "tweakmode" flags
+ if ((src->flag & ADT_NLA_EDIT_ON) || (dst->flag & ADT_NLA_EDIT_ON)) {
+ printf("ERROR: Merging AnimData blocks while editing NLA is dangerous as it may cause data corruption\n");
+ return;
+ }
+
+ /* handle actions... */
+ if (action_mode == ADT_MERGECOPY_SRC_COPY) {
+ /* make a copy of the actions */
+ dst->action = BKE_action_copy(src->action);
+ dst->tmpact = BKE_action_copy(src->tmpact);
+ }
+ else if (action_mode == ADT_MERGECOPY_SRC_REF) {
+ /* make a reference to it */
+ dst->action = src->action;
+ id_us_plus((ID *)dst->action);
+
+ dst->tmpact = src->tmpact;
+ id_us_plus((ID *)dst->tmpact);
+ }
+
+ /* duplicate NLA data */
+ if (src->nla_tracks.first) {
+ ListBase tracks = {NULL, NULL};
+
+ copy_nladata(&tracks, &src->nla_tracks);
+ BLI_movelisttolist(&dst->nla_tracks, &tracks);
+ }
+
+ /* duplicate drivers (F-Curves) */
+ if (src->drivers.first) {
+ ListBase drivers = {NULL, NULL};
+
+ copy_fcurves(&drivers, &src->drivers);
+
+ /* Fix up all driver targets using the old target id
+ * - This assumes that the src ID is being merged into the dst ID
+ */
+ if (fix_drivers) {
+ FCurve *fcu;
+
+ for (fcu = drivers.first; fcu; fcu = fcu->next) {
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ if (dtar->id == src_id) {
+ dtar->id = dst_id;
+ }
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
+ }
+ }
+
+ BLI_movelisttolist(&dst->drivers, &drivers);
+ }
+}
+
/* Make Local -------------------------------------------- */
static void make_local_strips(ListBase *strips)
@@ -719,7 +791,7 @@ static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char
if (fcu->rna_path != old_path) {
bActionGroup *agrp = fcu->grp;
- if ((agrp) && strcmp(oldName, agrp->name) == 0) {
+ if ((agrp) && STREQ(oldName, agrp->name)) {
BLI_strncpy(agrp->name, newName, sizeof(agrp->name));
}
}
@@ -756,7 +828,7 @@ static void drivers_path_rename_fix(ID *owner_id, ID *ref_id, const char *prefix
/* also fix the bone-name (if applicable) */
if (strstr(prefix, "bones")) {
if ( ((dtar->id) && (GS(dtar->id->name) == ID_OB) && (!ref_id || ((Object *)(dtar->id))->data == ref_id)) &&
- (dtar->pchan_name[0]) && (strcmp(oldName, dtar->pchan_name) == 0) )
+ (dtar->pchan_name[0]) && STREQ(oldName, dtar->pchan_name) )
{
BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name));
}
@@ -786,6 +858,60 @@ static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const ch
}
}
+/* ----------------------- */
+
+
+/* Fix up the given RNA-Path
+ *
+ * This is just an external wrapper for the RNA-Path fixing function,
+ * with input validity checks on top of the basic method.
+ *
+ * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
+ * i.e. pose.bones["Bone"]
+ */
+char *BKE_animsys_fix_rna_path_rename(ID *owner_id, char *old_path, const char *prefix, const char *oldName,
+ const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
+{
+ char *oldN, *newN;
+ char *result;
+
+ /* if no action, no need to proceed */
+ if (ELEM(NULL, owner_id, old_path)) {
+ printf("early abort\n");
+ return old_path;
+ }
+
+ /* Name sanitation logic - copied from BKE_animdata_fix_paths_rename() */
+ if ((oldName != NULL) && (newName != NULL)) {
+ /* pad the names with [" "] so that only exact matches are made */
+ const size_t name_old_len = strlen(oldName);
+ const size_t name_new_len = strlen(newName);
+ char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
+ char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
+
+ BLI_strescape(name_old_esc, oldName, (name_old_len * 2) + 1);
+ BLI_strescape(name_new_esc, newName, (name_new_len * 2) + 1);
+ oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
+ newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
+ }
+ else {
+ oldN = BLI_sprintfN("[%d]", oldSubscript);
+ newN = BLI_sprintfN("[%d]", newSubscript);
+ }
+
+ /* fix given path */
+ printf("%s | %s | oldpath = %p ", oldN, newN, old_path);
+ result = rna_path_rename_fix(owner_id, prefix, oldN, newN, old_path, verify_paths);
+ printf("result = %p\n", result);
+
+ /* free the temp names */
+ MEM_freeN(oldN);
+ MEM_freeN(newN);
+
+ /* return the resulting path - may be the same path again if nothing changed */
+ return result;
+}
+
/* Fix all RNA_Paths in the given Action, relative to the given ID block
*
* This is just an external wrapper for the F-Curve fixing function,
@@ -1031,6 +1157,9 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u
/* line styles */
ANIMDATA_IDS_CB(mainptr->linestyle.first);
+
+ /* grease pencil */
+ ANIMDATA_IDS_CB(mainptr->gpencil.first);
}
/* Fix all RNA-Paths throughout the database (directly access the Global.main version)
@@ -1119,6 +1248,9 @@ void BKE_all_animdata_fix_paths_rename(ID *ref_id, const char *prefix, const cha
/* linestyles */
RENAMEFIX_ANIM_IDS(mainptr->linestyle.first);
+ /* grease pencil */
+ RENAMEFIX_ANIM_IDS(mainptr->gpencil.first);
+
/* scenes */
RENAMEFIX_ANIM_NODETREE_IDS(mainptr->scene.first, Scene);
}
@@ -1149,7 +1281,7 @@ KS_Path *BKE_keyingset_find_path(KeyingSet *ks, ID *id, const char group_name[],
eq_id = 0;
/* path */
- if ((ksp->rna_path == NULL) || strcmp(rna_path, ksp->rna_path))
+ if ((ksp->rna_path == NULL) || !STREQ(rna_path, ksp->rna_path))
eq_path = 0;
/* index - need to compare whole-array setting too... */
@@ -1185,6 +1317,7 @@ KeyingSet *BKE_keyingset_add(ListBase *list, const char idname[], const char nam
ks->flag = flag;
ks->keyingflag = keyingflag;
+ ks->keyingoverride = keyingflag; /* NOTE: assume that if one is set one way, the other should be too, so that it'll work */
/* add KeyingSet to list */
BLI_addtail(list, ks);
@@ -1346,11 +1479,11 @@ static bool animsys_remap_path(AnimMapper *UNUSED(remap), char *path, char **dst
/* nothing suitable found, so just set dst to look at path (i.e. no alloc/free needed) */
*dst = path;
- return 0;
+ return false;
}
-/* less then 1.0 evaluates to false, use epsilon to avoid float error */
+/* less than 1.0 evaluates to false, use epsilon to avoid float error */
#define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON)))
/* Write the given value to a setting using RNA, and return success */
@@ -1375,7 +1508,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind
path, array_index, array_len - 1);
}
- return 0;
+ return false;
}
switch (RNA_property_type(prop)) {
@@ -1429,7 +1562,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind
break;
default:
/* nothing can be done here... so it is unsuccessful? */
- return 0;
+ return false;
}
/* RNA property update disabled for now - [#28525] [#28690] [#28774] [#28777] */
@@ -1468,7 +1601,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind
}
/* successful */
- return 1;
+ return true;
}
else {
/* failed to get path */
@@ -1479,7 +1612,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind
(ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
path, array_index);
}
- return 0;
+ return false;
}
}
@@ -2332,13 +2465,19 @@ static void animsys_evaluate_nla(ListBase *echannels, PointerRNA *ptr, AnimData
if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED))
break;
- /* skip if we're only considering a track tagged 'solo' */
- if ((adt->flag & ADT_NLA_SOLO_TRACK) && (nlt->flag & NLATRACK_SOLO) == 0)
- continue;
- /* skip if track is muted */
- if (nlt->flag & NLATRACK_MUTED)
- continue;
-
+ /* solo and muting are mutually exclusive... */
+ if (adt->flag & ADT_NLA_SOLO_TRACK) {
+ /* skip if there is a solo track, but this isn't it */
+ if ((nlt->flag & NLATRACK_SOLO) == 0)
+ continue;
+ /* else - mute doesn't matter */
+ }
+ else {
+ /* no solo tracks - skip track if muted */
+ if (nlt->flag & NLATRACK_MUTED)
+ continue;
+ }
+
/* if this track has strips (but maybe they won't be suitable), set has_strips
* - used for mainly for still allowing normal action evaluation...
*/
@@ -2680,6 +2819,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime)
/* linestyles */
EVAL_ANIM_IDS(main->linestyle.first, ADT_RECALC_ANIM);
+ /* grease pencil */
+ EVAL_ANIM_IDS(main->gpencil.first, ADT_RECALC_ANIM);
+
/* objects */
/* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
* this tagged by Depsgraph on framechange. This optimization means that objects
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
new file mode 100644
index 00000000000..60e81003c40
--- /dev/null
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -0,0 +1,808 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/** \file blender/blenkernel/intern/appdir.c
+ * \ingroup bke
+ *
+ * Access to application level directories.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+#include "BLI_fileops.h"
+#include "BLI_path_util.h"
+
+#include "BKE_appdir.h" /* own include */
+
+#include "GHOST_Path-api.h"
+
+#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */
+
+#include "MEM_guardedalloc.h"
+
+#ifdef WIN32
+# include "utf_winfunc.h"
+# include "utfconv.h"
+# include <io.h>
+# ifdef _WIN32_IE
+# undef _WIN32_IE
+# endif
+# define _WIN32_IE 0x0501
+# include <windows.h>
+# include <shlobj.h>
+# include "BLI_winstuff.h"
+#else /* non windows */
+# ifdef WITH_BINRELOC
+# include "binreloc.h"
+# endif
+# include <unistd.h> /* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */
+#endif /* WIN32 */
+
+/* local */
+static char bprogname[FILE_MAX]; /* full path to program executable */
+static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */
+static char btempdir_base[FILE_MAX]; /* persistent temporary directory */
+static char btempdir_session[FILE_MAX] = ""; /* volatile temporary directory */
+
+/* This is now only used to really get the user's default document folder */
+/* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used
+ * as default location to save documents */
+const char *BKE_appdir_folder_default(void)
+{
+#ifndef WIN32
+ const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR");
+
+ if (xdg_documents_dir)
+ return xdg_documents_dir;
+
+ return getenv("HOME");
+#else /* Windows */
+ static char documentfolder[MAXPATHLEN];
+ HRESULT hResult;
+
+ /* Check for %HOME% env var */
+ if (uput_getenv("HOME", documentfolder, MAXPATHLEN)) {
+ if (BLI_is_dir(documentfolder)) return documentfolder;
+ }
+
+ /* add user profile support for WIN 2K / NT.
+ * This is %APPDATA%, which translates to either
+ * %USERPROFILE%\Application Data or since Vista
+ * to %USERPROFILE%\AppData\Roaming
+ */
+ hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder);
+
+ if (hResult == S_OK) {
+ if (BLI_is_dir(documentfolder)) return documentfolder;
+ }
+
+ return NULL;
+#endif /* WIN32 */
+}
+
+
+// #define PATH_DEBUG
+
+/* returns a formatted representation of the specified version number. Non-reentrant! */
+static char *blender_version_decimal(const int ver)
+{
+ static char version_str[5];
+ sprintf(version_str, "%d.%02d", ver / 100, ver % 100);
+ return version_str;
+}
+
+/**
+ * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath,
+ * returning true if result points to a directory.
+ */
+static bool test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name)
+{
+ char tmppath[FILE_MAX];
+
+ if (path_sep) BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep);
+ else BLI_strncpy(tmppath, path_base, sizeof(tmppath));
+
+ /* rare cases folder_name is omitted (when looking for ~/.blender/2.xx dir only) */
+ if (folder_name)
+ BLI_make_file_string("/", targetpath, tmppath, folder_name);
+ else
+ BLI_strncpy(targetpath, tmppath, sizeof(tmppath));
+ /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile)
+ * if folder_name is specified but not otherwise? */
+
+ if (BLI_is_dir(targetpath)) {
+#ifdef PATH_DEBUG
+ printf("\t%s found: %s\n", __func__, targetpath);
+#endif
+ return true;
+ }
+ else {
+#ifdef PATH_DEBUG
+ printf("\t%s missing: %s\n", __func__, targetpath);
+#endif
+ //targetpath[0] = '\0';
+ return false;
+ }
+}
+
+/**
+ * Puts the value of the specified environment variable into *path if it exists
+ * and points at a directory. Returns true if this was done.
+ */
+static bool test_env_path(char *path, const char *envvar)
+{
+ const char *env = envvar ? getenv(envvar) : NULL;
+ if (!env) return false;
+
+ if (BLI_is_dir(env)) {
+ BLI_strncpy(path, env, FILE_MAX);
+#ifdef PATH_DEBUG
+ printf("\t%s env %s found: %s\n", __func__, envvar, env);
+#endif
+ return true;
+ }
+ else {
+ path[0] = '\0';
+#ifdef PATH_DEBUG
+ printf("\t%s env %s missing: %s\n", __func__, envvar, env);
+#endif
+ return false;
+ }
+}
+
+/**
+ * Constructs in \a targetpath the name of a directory relative to a version-specific
+ * subdirectory in the parent directory of the Blender executable.
+ *
+ * \param targetpath String to return path
+ * \param folder_name Optional folder name within version-specific directory
+ * \param subfolder_name Optional subfolder name within folder_name
+ * \param ver To construct name of version-specific directory within bprogdir
+ * \return true if such a directory exists.
+ */
+static bool get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver)
+{
+ char relfolder[FILE_MAX];
+
+#ifdef PATH_DEBUG
+ printf("%s...\n", __func__);
+#endif
+
+ if (folder_name) {
+ if (subfolder_name) {
+ BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name);
+ }
+ else {
+ BLI_strncpy(relfolder, folder_name, sizeof(relfolder));
+ }
+ }
+ else {
+ relfolder[0] = '\0';
+ }
+
+ /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */
+#ifdef __APPLE__
+ static char osx_resourses[FILE_MAX]; /* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */
+ sprintf(osx_resourses, "%s../Resources", bprogdir);
+ return test_path(targetpath, osx_resourses, blender_version_decimal(ver), relfolder);
+#else
+ return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder);
+#endif
+}
+
+/**
+ * Is this an install with user files kept together with the Blender executable and its
+ * installation files.
+ */
+static bool is_portable_install(void)
+{
+ /* detect portable install by the existence of config folder */
+ const int ver = BLENDER_VERSION;
+ char path[FILE_MAX];
+
+ return get_path_local(path, "config", NULL, ver);
+}
+
+/**
+ * Returns the path of a folder within the user-files area.
+ *
+ *
+ * \param targetpath String to return path
+ * \param folder_name default name of folder within user area
+ * \param subfolder_name optional name of subfolder within folder
+ * \param envvar name of environment variable which, if defined, overrides folder_name
+ * \param ver Blender version, used to construct a subdirectory name
+ * \return true if it was able to construct such a path.
+ */
+static bool get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
+{
+ char user_path[FILE_MAX];
+ const char *user_base_path;
+
+ /* for portable install, user path is always local */
+ if (is_portable_install())
+ return get_path_local(targetpath, folder_name, subfolder_name, ver);
+
+ user_path[0] = '\0';
+
+ if (test_env_path(user_path, envvar)) {
+ if (subfolder_name) {
+ return test_path(targetpath, user_path, NULL, subfolder_name);
+ }
+ else {
+ BLI_strncpy(targetpath, user_path, FILE_MAX);
+ return true;
+ }
+ }
+
+ user_base_path = (const char *)GHOST_getUserDir(ver, blender_version_decimal(ver));
+ if (user_base_path)
+ BLI_strncpy(user_path, user_base_path, FILE_MAX);
+
+ if (!user_path[0])
+ return false;
+
+#ifdef PATH_DEBUG
+ printf("%s: %s\n", __func__, user_path);
+#endif
+
+ if (subfolder_name) {
+ return test_path(targetpath, user_path, folder_name, subfolder_name);
+ }
+ else {
+ return test_path(targetpath, user_path, NULL, folder_name);
+ }
+}
+
+/**
+ * Returns the path of a folder within the Blender installation directory.
+ *
+ * \param targetpath String to return path
+ * \param folder_name default name of folder within installation area
+ * \param subfolder_name optional name of subfolder within folder
+ * \param envvar name of environment variable which, if defined, overrides folder_name
+ * \param ver Blender version, used to construct a subdirectory name
+ * \return true if it was able to construct such a path.
+ */
+static bool get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
+{
+ char system_path[FILE_MAX];
+ const char *system_base_path;
+ char cwd[FILE_MAX];
+ char relfolder[FILE_MAX];
+
+ if (folder_name) {
+ if (subfolder_name) {
+ BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name);
+ }
+ else {
+ BLI_strncpy(relfolder, folder_name, sizeof(relfolder));
+ }
+ }
+ else {
+ relfolder[0] = '\0';
+ }
+
+ /* first allow developer only overrides to the system path
+ * these are only used when running blender from source */
+
+ /* try CWD/release/folder_name */
+ if (BLI_current_working_dir(cwd, sizeof(cwd))) {
+ if (test_path(targetpath, cwd, "release", relfolder)) {
+ return true;
+ }
+ }
+
+ /* try EXECUTABLE_DIR/release/folder_name */
+ if (test_path(targetpath, bprogdir, "release", relfolder))
+ return true;
+
+ /* end developer overrides */
+
+
+
+ system_path[0] = '\0';
+
+ if (test_env_path(system_path, envvar)) {
+ if (subfolder_name) {
+ return test_path(targetpath, system_path, NULL, subfolder_name);
+ }
+ else {
+ BLI_strncpy(targetpath, system_path, FILE_MAX);
+ return true;
+ }
+ }
+
+ system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver));
+ if (system_base_path)
+ BLI_strncpy(system_path, system_base_path, FILE_MAX);
+
+ if (!system_path[0])
+ return false;
+
+#ifdef PATH_DEBUG
+ printf("%s: %s\n", __func__, system_path);
+#endif
+
+ if (subfolder_name) {
+ /* try $BLENDERPATH/folder_name/subfolder_name */
+ return test_path(targetpath, system_path, folder_name, subfolder_name);
+ }
+ else {
+ /* try $BLENDERPATH/folder_name */
+ return test_path(targetpath, system_path, NULL, folder_name);
+ }
+}
+
+/* get a folder out of the 'folder_id' presets for paths */
+/* returns the path if found, NULL string if not */
+const char *BKE_appdir_folder_id(const int folder_id, const char *subfolder)
+{
+ const int ver = BLENDER_VERSION;
+ static char path[FILE_MAX] = "";
+
+ switch (folder_id) {
+ case BLENDER_DATAFILES: /* general case */
+ if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
+ if (get_path_local(path, "datafiles", subfolder, ver)) break;
+ if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break;
+ return NULL;
+
+ case BLENDER_USER_DATAFILES:
+ if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
+ return NULL;
+
+ case BLENDER_SYSTEM_DATAFILES:
+ if (get_path_local(path, "datafiles", subfolder, ver)) break;
+ if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break;
+ return NULL;
+
+ case BLENDER_USER_AUTOSAVE:
+ if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
+ return NULL;
+
+ case BLENDER_USER_CONFIG:
+ if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver)) break;
+ return NULL;
+
+ case BLENDER_USER_SCRIPTS:
+ if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver)) break;
+ return NULL;
+
+ case BLENDER_SYSTEM_SCRIPTS:
+ if (get_path_local(path, "scripts", subfolder, ver)) break;
+ if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS", ver)) break;
+ return NULL;
+
+ case BLENDER_SYSTEM_PYTHON:
+ if (get_path_local(path, "python", subfolder, ver)) break;
+ if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break;
+ return NULL;
+
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ return path;
+}
+
+/**
+ * Returns the path to a folder in the user area without checking that it actually exists first.
+ */
+const char *BKE_appdir_folder_id_user_notest(const int folder_id, const char *subfolder)
+{
+ const int ver = BLENDER_VERSION;
+ static char path[FILE_MAX] = "";
+
+ switch (folder_id) {
+ case BLENDER_USER_DATAFILES:
+ get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver);
+ break;
+ case BLENDER_USER_CONFIG:
+ get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver);
+ break;
+ case BLENDER_USER_AUTOSAVE:
+ get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE", ver);
+ break;
+ case BLENDER_USER_SCRIPTS:
+ get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ if ('\0' == path[0]) {
+ return NULL;
+ }
+ return path;
+}
+
+/**
+ * Returns the path to a folder in the user area, creating it if it doesn't exist.
+ */
+const char *BKE_appdir_folder_id_create(const int folder_id, const char *subfolder)
+{
+ const char *path;
+
+ /* only for user folders */
+ if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE))
+ return NULL;
+
+ path = BKE_appdir_folder_id(folder_id, subfolder);
+
+ if (!path) {
+ path = BKE_appdir_folder_id_user_notest(folder_id, subfolder);
+ if (path) BLI_dir_create_recursive(path);
+ }
+
+ return path;
+}
+
+/**
+ * Returns the path of the top-level version-specific local, user or system directory.
+ * If do_check, then the result will be NULL if the directory doesn't exist.
+ */
+const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, const bool do_check)
+{
+ static char path[FILE_MAX] = "";
+ bool ok;
+ switch (folder_id) {
+ case BLENDER_RESOURCE_PATH_USER:
+ ok = get_path_user(path, NULL, NULL, NULL, ver);
+ break;
+ case BLENDER_RESOURCE_PATH_LOCAL:
+ ok = get_path_local(path, NULL, NULL, ver);
+ break;
+ case BLENDER_RESOURCE_PATH_SYSTEM:
+ ok = get_path_system(path, NULL, NULL, NULL, ver);
+ break;
+ default:
+ path[0] = '\0'; /* in case do_check is false */
+ ok = false;
+ BLI_assert(!"incorrect ID");
+ break;
+ }
+
+ if (!ok && do_check) {
+ return NULL;
+ }
+
+ return path;
+}
+
+#ifdef PATH_DEBUG
+# undef PATH_DEBUG
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/* Preset paths */
+
+/**
+ * Tries appending each of the semicolon-separated extensions in the PATHEXT
+ * environment variable (Windows-only) onto *name in turn until such a file is found.
+ * Returns success/failure.
+ */
+static int add_win32_extension(char *name)
+{
+ int retval = 0;
+ int type;
+
+ type = BLI_exists(name);
+ if ((type == 0) || S_ISDIR(type)) {
+#ifdef _WIN32
+ char filename[FILE_MAX];
+ char ext[FILE_MAX];
+ const char *extensions = getenv("PATHEXT");
+ if (extensions) {
+ char *temp;
+ do {
+ strcpy(filename, name);
+ temp = strstr(extensions, ";");
+ if (temp) {
+ strncpy(ext, extensions, temp - extensions);
+ ext[temp - extensions] = 0;
+ extensions = temp + 1;
+ strcat(filename, ext);
+ }
+ else {
+ strcat(filename, extensions);
+ }
+
+ type = BLI_exists(filename);
+ if (type && (!S_ISDIR(type))) {
+ retval = 1;
+ strcpy(name, filename);
+ break;
+ }
+ } while (temp);
+ }
+#endif
+ }
+ else {
+ retval = 1;
+ }
+
+ return (retval);
+}
+
+/**
+ * Checks if name is a fully qualified filename to an executable.
+ * If not it searches $PATH for the file. On Windows it also
+ * adds the correct extension (.com .exe etc) from
+ * $PATHEXT if necessary. Also on Windows it translates
+ * the name to its 8.3 version to prevent problems with
+ * spaces and stuff. Final result is returned in fullname.
+ *
+ * \param fullname The full path and full name of the executable
+ * (must be FILE_MAX minimum)
+ * \param name The name of the executable (usually argv[0]) to be checked
+ */
+static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name)
+{
+ char filename[FILE_MAX];
+ const char *path = NULL, *temp;
+
+#ifdef _WIN32
+ const char *separator = ";";
+#else
+ const char *separator = ":";
+#endif
+
+
+#ifdef WITH_BINRELOC
+ /* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */
+ path = br_find_exe(NULL);
+ if (path) {
+ BLI_strncpy(fullname, path, maxlen);
+ free((void *)path);
+ return;
+ }
+#endif
+
+#ifdef _WIN32
+ wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath");
+ if (GetModuleFileNameW(0, fullname_16, maxlen)) {
+ conv_utf_16_to_8(fullname_16, fullname, maxlen);
+ if (!BLI_exists(fullname)) {
+ printf("path can't be found: \"%.*s\"\n", (int)maxlen, fullname);
+ MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK);
+ }
+ MEM_freeN(fullname_16);
+ return;
+ }
+
+ MEM_freeN(fullname_16);
+#endif
+
+ /* unix and non linux */
+ if (name && name[0]) {
+
+ BLI_strncpy(fullname, name, maxlen);
+ if (name[0] == '.') {
+ char wdir[FILE_MAX] = "";
+ BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */
+
+ // not needed but avoids annoying /./ in name
+ if (name[1] == SEP)
+ BLI_join_dirfile(fullname, maxlen, wdir, name + 2);
+ else
+ BLI_join_dirfile(fullname, maxlen, wdir, name);
+
+ add_win32_extension(fullname); /* XXX, doesnt respect length */
+ }
+ else if (BLI_last_slash(name)) {
+ // full path
+ BLI_strncpy(fullname, name, maxlen);
+ add_win32_extension(fullname);
+ }
+ else {
+ // search for binary in $PATH
+ path = getenv("PATH");
+ if (path) {
+ do {
+ temp = strstr(path, separator);
+ if (temp) {
+ strncpy(filename, path, temp - path);
+ filename[temp - path] = 0;
+ path = temp + 1;
+ }
+ else {
+ strncpy(filename, path, sizeof(filename));
+ }
+ BLI_path_append(fullname, maxlen, name);
+ if (add_win32_extension(filename)) {
+ BLI_strncpy(fullname, filename, maxlen);
+ break;
+ }
+ } while (temp);
+ }
+ }
+#if defined(DEBUG)
+ if (!STREQ(name, fullname)) {
+ printf("guessing '%s' == '%s'\n", name, fullname);
+ }
+#endif
+ }
+}
+
+void BKE_appdir_program_path_init(const char *argv0)
+{
+ bli_where_am_i(bprogname, sizeof(bprogname), argv0);
+ BLI_split_dir_part(bprogname, bprogdir, sizeof(bprogdir));
+}
+
+/**
+ * Path to executable
+ */
+const char *BKE_appdir_program_path(void)
+{
+ return bprogname;
+}
+
+/**
+ * Path to directory of executable
+ */
+const char *BKE_appdir_program_dir(void)
+{
+ return bprogdir;
+}
+
+/**
+ * Gets the temp directory when blender first runs.
+ * If the default path is not found, use try $TEMP
+ *
+ * Also make sure the temp dir has a trailing slash
+ *
+ * \param fullname The full path to the temporary temp directory
+ * \param basename The full path to the persistent temp directory (may be NULL)
+ * \param maxlen The size of the fullname buffer
+ * \param userdir Directory specified in user preferences
+ */
+static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir)
+{
+ /* Clear existing temp dir, if needed. */
+ BKE_tempdir_session_purge();
+
+ fullname[0] = '\0';
+ if (basename) {
+ basename[0] = '\0';
+ }
+
+ if (userdir && BLI_is_dir(userdir)) {
+ BLI_strncpy(fullname, userdir, maxlen);
+ }
+
+
+#ifdef WIN32
+ if (fullname[0] == '\0') {
+ const char *tmp = getenv("TEMP"); /* Windows */
+ if (tmp && BLI_is_dir(tmp)) {
+ BLI_strncpy(fullname, tmp, maxlen);
+ }
+ }
+#else
+ /* Other OS's - Try TMP and TMPDIR */
+ if (fullname[0] == '\0') {
+ const char *tmp = getenv("TMP");
+ if (tmp && BLI_is_dir(tmp)) {
+ BLI_strncpy(fullname, tmp, maxlen);
+ }
+ }
+
+ if (fullname[0] == '\0') {
+ const char *tmp = getenv("TMPDIR");
+ if (tmp && BLI_is_dir(tmp)) {
+ BLI_strncpy(fullname, tmp, maxlen);
+ }
+ }
+#endif
+
+ if (fullname[0] == '\0') {
+ BLI_strncpy(fullname, "/tmp/", maxlen);
+ }
+ else {
+ /* add a trailing slash if needed */
+ BLI_add_slash(fullname);
+#ifdef WIN32
+ if (userdir && userdir != fullname) {
+ BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */
+ }
+#endif
+ }
+
+ /* Now that we have a valid temp dir, add system-generated unique sub-dir. */
+ if (basename) {
+ /* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */
+ char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX");
+ const size_t ln = strlen(tmp_name) + 1;
+ if (ln <= maxlen) {
+#ifdef WIN32
+ if (_mktemp_s(tmp_name, ln) == 0) {
+ BLI_dir_create_recursive(tmp_name);
+ }
+#else
+ mkdtemp(tmp_name);
+#endif
+ }
+ if (BLI_is_dir(tmp_name)) {
+ BLI_strncpy(basename, fullname, maxlen);
+ BLI_strncpy(fullname, tmp_name, maxlen);
+ BLI_add_slash(fullname);
+ }
+ else {
+ printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname);
+ }
+
+ MEM_freeN(tmp_name);
+ }
+}
+
+/**
+ * Sets btempdir_base to userdir if specified and is a valid directory, otherwise
+ * chooses a suitable OS-specific temporary directory.
+ * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base.
+ *
+ * \note On Window userdir will be set to the temporary directory!
+ */
+void BKE_tempdir_init(char *userdir)
+{
+ BLI_where_is_temp(btempdir_session, btempdir_base, FILE_MAX, userdir);
+;
+}
+
+/**
+ * Path to temporary directory (with trailing slash)
+ */
+const char *BKE_tempdir_session(void)
+{
+ return btempdir_session[0] ? btempdir_session : BKE_tempdir_base();
+}
+
+/**
+ * Path to persistent temporary directory (with trailing slash)
+ */
+const char *BKE_tempdir_base(void)
+{
+ return btempdir_base;
+}
+
+/**
+ * Path to the system temporary directory (with trailing slash)
+ */
+void BKE_tempdir_system_init(char *dir)
+{
+ BLI_where_is_temp(dir, NULL, FILE_MAX, NULL);
+}
+
+/**
+ * Delete content of this instance's temp dir.
+ */
+void BKE_tempdir_session_purge(void)
+{
+ if (btempdir_session[0] && BLI_is_dir(btempdir_session)) {
+ BLI_delete(btempdir_session, true, true);
+ }
+}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index bb05b5de8a6..6b67a4e5763 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -222,6 +222,10 @@ bArmature *BKE_armature_copy(bArmature *arm)
newArm->act_edbone = NULL;
newArm->sketch = NULL;
+ if (arm->id.lib) {
+ BKE_id_lib_local_paths(G.main, arm->id.lib, &newArm->id);
+ }
+
return newArm;
}
@@ -229,7 +233,7 @@ static Bone *get_named_bone_bonechildren(Bone *bone, const char *name)
{
Bone *curBone, *rbone;
- if (!strcmp(bone->name, name))
+ if (STREQ(bone->name, name))
return bone;
for (curBone = bone->childbase.first; curBone; curBone = curBone->next) {
@@ -259,6 +263,19 @@ Bone *BKE_armature_find_bone_name(bArmature *arm, const char *name)
return bone;
}
+bool BKE_armature_bone_flag_test_recursive(const Bone *bone, int flag)
+{
+ if (bone->flag & flag) {
+ return true;
+ }
+ else if (bone->parent) {
+ return BKE_armature_bone_flag_test_recursive(bone->parent, flag);
+ }
+ else {
+ return false;
+ }
+}
+
/* Finds the best possible extension to the name on a particular axis. (For renaming, check for
* unique names afterwards) strip_number: removes number extensions (TODO: not used)
* axis: the axis to name on
@@ -840,7 +857,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
/* bone defmats are already in the channels, chan_mat */
/* initialize B_bone matrices and dual quaternions */
- totchan = BLI_countlist(&armOb->pose->chanbase);
+ totchan = BLI_listbase_count(&armOb->pose->chanbase);
if (use_quaternion) {
dualquats = MEM_callocN(sizeof(DualQuat) * totchan, "dualquats");
@@ -866,7 +883,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
armature_def_nr = defgroup_name_index(target, defgrp_name);
if (ELEM(target->type, OB_MESH, OB_LATTICE)) {
- defbase_tot = BLI_countlist(&target->defbase);
+ defbase_tot = BLI_listbase_count(&target->defbase);
if (target->type == OB_MESH) {
Mesh *me = target->data;
@@ -1654,6 +1671,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
pchanw.next = pchan->next;
pchanw.parent = pchan->parent;
pchanw.child = pchan->child;
+ pchanw.custom_tx = pchan->custom_tx;
pchanw.mpath = pchan->mpath;
pchan->mpath = NULL;
@@ -1662,7 +1680,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
if (pchanw.prop) {
pchanw.prop = IDP_CopyProperty(pchanw.prop);
- /* use the values from the the existing props */
+ /* use the values from the existing props */
if (pchan->prop) {
IDP_SyncGroupValues(pchanw.prop, pchan->prop);
}
@@ -1916,7 +1934,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos
if (ikData->points)
MEM_freeN(ikData->points);
ikData->numpoints = ikData->chainlen + 1;
- ikData->points = MEM_callocN(sizeof(float) * ikData->numpoints, "Spline IK Binding");
+ ikData->points = MEM_mallocN(sizeof(float) * ikData->numpoints, "Spline IK Binding");
/* bind 'tip' of chain (i.e. first joint = tip of bone with the Spline IK Constraint) */
ikData->points[0] = 1.0f;
@@ -1944,6 +1962,9 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos
ikData->flag |= CONSTRAINT_SPLINEIK_BOUND;
}
+ /* disallow negative values (happens with float precision) */
+ CLAMP_MIN(ikData->points[segcount], 0.0f);
+
/* apply corrections for sensitivity to scaling on a copy of the bind points,
* since it's easier to determine the positions of all the joints beforehand this way
*/
@@ -1989,7 +2010,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos
tree->chainlen = segcount;
/* copy over the array of links to bones in the chain (from tip to root) */
- tree->chain = MEM_callocN(sizeof(bPoseChannel *) * segcount, "SplineIK Chain");
+ tree->chain = MEM_mallocN(sizeof(bPoseChannel *) * segcount, "SplineIK Chain");
memcpy(tree->chain, pchanChain, sizeof(bPoseChannel *) * segcount);
/* store reference to joint position array */
@@ -2158,9 +2179,9 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
mul_v3_fl(poseMat[2], scale);
break;
}
- case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC:
+ case CONSTRAINT_SPLINEIK_XZS_INVERSE:
{
- /* 'volume preservation' */
+ /* old 'volume preservation' method using the inverse scale */
float scale;
/* calculate volume preservation factor which is
@@ -2181,6 +2202,54 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
mul_v3_fl(poseMat[2], scale);
break;
}
+ case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC:
+ {
+ /* improved volume preservation based on the Stretch To constraint */
+ float final_scale;
+
+ /* as the basis for volume preservation, we use the inverse scale factor... */
+ if (fabsf(scaleFac) != 0.0f) {
+ /* NOTE: The method here is taken wholesale from the Stretch To constraint */
+ float bulge = powf(1.0f / fabsf(scaleFac), ikData->bulge);
+
+ if (bulge > 1.0f) {
+ if (ikData->flag & CONSTRAINT_SPLINEIK_USE_BULGE_MAX) {
+ float bulge_max = max_ff(ikData->bulge_max, 1.0f);
+ float hard = min_ff(bulge, bulge_max);
+
+ float range = bulge_max - 1.0f;
+ float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
+ float soft = 1.0f + range * atanf((bulge - 1.0f) * scale) / (float)M_PI_2;
+
+ bulge = interpf(soft, hard, ikData->bulge_smooth);
+ }
+ }
+ if (bulge < 1.0f) {
+ if (ikData->flag & CONSTRAINT_SPLINEIK_USE_BULGE_MIN) {
+ float bulge_min = CLAMPIS(ikData->bulge_min, 0.0f, 1.0f);
+ float hard = max_ff(bulge, bulge_min);
+
+ float range = 1.0f - bulge_min;
+ float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
+ float soft = 1.0f - range * atanf((1.0f - bulge) * scale) / (float)M_PI_2;
+
+ bulge = interpf(soft, hard, ikData->bulge_smooth);
+ }
+ }
+
+ /* compute scale factor for xz axes from this value */
+ final_scale = sqrt(bulge);
+ }
+ else {
+ /* no scaling, so scale factor is simple */
+ final_scale = 1.0f;
+ }
+
+ /* apply the scaling (assuming normalised scale) */
+ mul_v3_fl(poseMat[0], final_scale);
+ mul_v3_fl(poseMat[2], final_scale);
+ break;
+ }
}
/* finally, multiply the x and z scaling by the radius of the curve too,
@@ -2361,7 +2430,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
/* validate first */
if (amod->ob && amod->ob->type == OB_CURVE && amod->channel[0]) {
- if (strcmp(pchan->name, amod->channel) == 0) {
+ if (STREQ(pchan->name, amod->channel)) {
float mat4[4][4], mat3[3][3];
curve_deform_vector(scene, amod->ob, armob, bone->arm_mat[3], pchan->pose_mat[3], mat3, amod->no_rot_axis);
@@ -2374,7 +2443,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
break;
case ACTSTRIP_MOD_NOISE:
{
- if (strcmp(pchan->name, amod->channel) == 0) {
+ if (STREQ(pchan->name, amod->channel)) {
float nor[3], loc[3], ofs;
float eul[3], size[3], eulo[3], sizeo[3];
diff --git a/source/blender/blenkernel/intern/autoexec.c b/source/blender/blenkernel/intern/autoexec.c
index 872780bd50a..d9462cd0262 100644
--- a/source/blender/blenkernel/intern/autoexec.c
+++ b/source/blender/blenkernel/intern/autoexec.c
@@ -34,9 +34,12 @@
#include "BLI_utildefines.h"
#include "BLI_fnmatch.h"
-#include "BLI_string.h"
#include "BLI_path_util.h"
+#ifdef WIN32
+# include "BLI_string.h"
+#endif
+
#include "BKE_autoexec.h" /* own include */
/**
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index adfe43cb2a3..b6ea780576e 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -61,6 +61,7 @@
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
+#include "BKE_appdir.h"
#include "BKE_blender.h"
#include "BKE_bpath.h"
#include "BKE_brush.h"
@@ -145,10 +146,6 @@ void initglobals(void)
else
BLI_snprintf(versionstr, sizeof(versionstr), "v%d.%02d", BLENDER_VERSION / 100, BLENDER_VERSION % 100);
-#ifdef _WIN32
- G.windowstate = 0;
-#endif
-
#ifndef WITH_PYTHON_SECURITY /* default */
G.f |= G_SCRIPT_AUTOEXEC;
#else
@@ -188,6 +185,17 @@ static void clean_paths(Main *main)
}
}
+static bool wm_scene_is_visible(wmWindowManager *wm, Scene *scene)
+{
+ wmWindow *win;
+ for (win = wm->windows.first; win; win = win->next) {
+ if (win->screen->scene == scene) {
+ return true;
+ }
+ }
+ return false;
+}
+
/* context matching */
/* handle no-ui case */
@@ -231,6 +239,20 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
/* no load screens? */
if (mode != LOAD_UI) {
+ /* Logic for 'track_undo_scene' is to keep using the scene which the active screen has,
+ * as long as the scene associated with the undo operation is visible in one of the open windows.
+ *
+ * - 'curscreen->scene' - scene the user is currently looking at.
+ * - 'bfd->curscene' - scene undo-step was created in.
+ *
+ * This means users can have 2+ windows open and undo in both without screens switching.
+ * But if they close one of the screens,
+ * undo will ensure that the scene being operated on will be activated
+ * (otherwise we'd be undoing on an off-screen scene which isn't acceptable).
+ * see: T43424
+ */
+ bool track_undo_scene;
+
/* comes from readfile.c */
SWAP(ListBase, G.main->wm, bfd->main->wm);
SWAP(ListBase, G.main->screen, bfd->main->screen);
@@ -240,15 +262,36 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
curscreen = CTX_wm_screen(C);
/* but use new Scene pointer */
curscene = bfd->curscene;
+
+ track_undo_scene = (mode == LOAD_UNDO && curscreen && bfd->main->wm.first);
+
if (curscene == NULL) curscene = bfd->main->scene.first;
/* empty file, we add a scene to make Blender work */
if (curscene == NULL) curscene = BKE_scene_add(bfd->main, "Empty");
-
- /* and we enforce curscene to be in current screen */
- if (curscreen) curscreen->scene = curscene; /* can run in bgmode */
+
+ if (track_undo_scene) {
+ /* keep the old (free'd) scene, let 'blo_lib_link_screen_restore'
+ * replace it with 'curscene' if its needed */
+ }
+ else {
+ /* and we enforce curscene to be in current screen */
+ if (curscreen) {
+ /* can run in bgmode */
+ curscreen->scene = curscene;
+ }
+ }
/* clear_global will free G.main, here we can still restore pointers */
blo_lib_link_screen_restore(bfd->main, curscreen, curscene);
+ curscene = curscreen->scene;
+
+ if (track_undo_scene) {
+ wmWindowManager *wm = bfd->main->wm.first;
+ if (wm_scene_is_visible(wm, bfd->curscene) == false) {
+ curscene = bfd->curscene;
+ curscreen->scene = curscene;
+ }
+ }
}
/* free G.main Main database */
@@ -270,6 +313,17 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
BKE_userdef_free();
U = *bfd->user;
+
+ /* Security issue: any blend file could include a USER block.
+ *
+ * Currently we load prefs from BLENDER_STARTUP_FILE and later on load BLENDER_USERPREF_FILE,
+ * to load the preferences defined in the users home dir.
+ *
+ * This means we will never accidentally (or maliciously)
+ * enable scripts auto-execution by loading a '.blend' file.
+ */
+ U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE;
+
MEM_freeN(bfd->user);
}
@@ -279,8 +333,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
CTX_data_scene_set(C, curscene);
}
else {
- G.winpos = bfd->winpos;
- G.displaymode = bfd->displaymode;
G.fileflags = bfd->fileflags;
CTX_wm_manager_set(C, G.main->wm.first);
CTX_wm_screen_set(C, bfd->curscreen);
@@ -493,10 +545,11 @@ bool BKE_read_file_from_memory(
BLO_update_defaults_startup_blend(bfd->main);
setup_app_data(C, bfd, "<memory2>");
}
- else
+ else {
BKE_reports_prepend(reports, "Loading failed: ");
+ }
- return (bfd ? 1 : 0);
+ return (bfd != NULL);
}
/* memfile is the undo buffer */
@@ -516,10 +569,11 @@ bool BKE_read_file_from_memfile(
setup_app_data(C, bfd, "<memory1>");
}
- else
+ else {
BKE_reports_prepend(reports, "Loading failed: ");
+ }
- return (bfd ? 1 : 0);
+ return (bfd != NULL);
}
/* only read the userdef from a .blend */
@@ -565,7 +619,7 @@ int BKE_write_file_userdef(const char *filepath, ReportList *reports)
static void (*blender_test_break_cb)(void) = NULL;
-void set_blender_test_break_cb(void (*func)(void) )
+void set_blender_test_break_cb(void (*func)(void))
{
blender_test_break_cb = func;
}
@@ -687,7 +741,7 @@ void BKE_write_undo(bContext *C, const char *name)
counter = counter % U.undosteps;
BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter);
- BLI_make_file_string("/", filepath, BLI_temp_dir_session(), numstr);
+ BLI_make_file_string("/", filepath, BKE_tempdir_session(), numstr);
/* success = */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
@@ -834,13 +888,13 @@ bool BKE_undo_save_file(const char *filename)
int file, oflags;
if ((U.uiflag & USER_GLOBALUNDO) == 0) {
- return 0;
+ return false;
}
uel = curundo;
if (uel == NULL) {
fprintf(stderr, "No undo buffer to save recovery file\n");
- return 0;
+ return false;
}
/* note: This is currently used for autosave and 'quit.blend', where _not_ following symlinks is OK,
@@ -862,7 +916,7 @@ bool BKE_undo_save_file(const char *filename)
if (file == -1) {
fprintf(stderr, "Unable to save '%s': %s\n",
filename, errno ? strerror(errno) : "Unknown error opening file");
- return 0;
+ return false;
}
for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) {
@@ -876,9 +930,9 @@ bool BKE_undo_save_file(const char *filename)
if (chunk) {
fprintf(stderr, "Unable to save '%s': %s\n",
filename, errno ? strerror(errno) : "Unknown error writing file");
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/* sets curscene */
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 5731455fc01..11879c7973c 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -994,8 +994,8 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
}
case eBoidRulesetType_Random:
{
- /* use random rule for each particle (allways same for same particle though) */
- rule = BLI_findlink(&state->rules, rand % BLI_countlist(&state->rules));
+ /* use random rule for each particle (always same for same particle though) */
+ rule = BLI_findlink(&state->rules, rand % BLI_listbase_count(&state->rules));
apply_boid_rule(bbd, rule, &val, pa, -1.0);
break;
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 3cd26dacebd..3488cff7315 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -228,12 +228,12 @@ static int findFileRecursive(char *filename_new,
while ((de = readdir(dir)) != NULL) {
- if (STREQ(".", de->d_name) || STREQ("..", de->d_name))
+ if (FILENAME_IS_CURRPAR(de->d_name))
continue;
BLI_join_dirfile(path, sizeof(path), dirname, de->d_name);
- if (BLI_stat(path, &status) != 0)
+ if (BLI_stat(path, &status) == -1)
continue; /* cant stat, don't bother with this file, could print debug info here */
if (S_ISREG(status.st_mode)) { /* is file */
@@ -284,7 +284,7 @@ static bool findMissingFiles_visit_cb(void *userdata, char *path_dst, const char
filename_new[0] = '\0';
found = findFileRecursive(filename_new,
- data->searchdir, BLI_path_basename((char *)path_src),
+ data->searchdir, BLI_path_basename(path_src),
&filesize, &recur_depth);
if (filesize == -1) { /* could not open dir */
@@ -296,7 +296,7 @@ static bool findMissingFiles_visit_cb(void *userdata, char *path_dst, const char
else if (found == false) {
BKE_reportf(data->reports, RPT_WARNING,
"Could not find '%s' in '%s'",
- BLI_path_basename((char *)path_src), data->searchdir);
+ BLI_path_basename(path_src), data->searchdir);
return false;
}
else {
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index ae6ae6087af..10d77921515 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -33,7 +33,6 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_rand.h"
-#include "BLI_rect.h"
#include "BKE_brush.h"
#include "BKE_colortools.h"
@@ -49,7 +48,6 @@
#include "IMB_imbuf_types.h"
#include "RE_render_ext.h" /* externtex */
-#include "RE_shader_ext.h"
static RNG *brush_rng;
@@ -180,6 +178,10 @@ Brush *BKE_brush_copy(Brush *brush)
brushn->id.us++;
}
+ if (brush->id.lib) {
+ BKE_id_lib_local_paths(G.main, brush->id.lib, &brushn->id);
+ }
+
return brushn;
}
@@ -300,7 +302,6 @@ void BKE_brush_debug_print_state(Brush *br)
BR_TEST_FLAG(BRUSH_SIZE_PRESSURE);
BR_TEST_FLAG(BRUSH_JITTER_PRESSURE);
BR_TEST_FLAG(BRUSH_SPACING_PRESSURE);
- BR_TEST_FLAG(BRUSH_RAKE);
BR_TEST_FLAG(BRUSH_ANCHORED);
BR_TEST_FLAG(BRUSH_DIR_IN);
BR_TEST_FLAG(BRUSH_SPACE);
@@ -316,7 +317,6 @@ void BKE_brush_debug_print_state(Brush *br)
BR_TEST_FLAG(BRUSH_EDGE_TO_EDGE);
BR_TEST_FLAG(BRUSH_DRAG_DOT);
BR_TEST_FLAG(BRUSH_INVERSE_SMOOTH_PRESSURE);
- BR_TEST_FLAG(BRUSH_RANDOM_ROTATION);
BR_TEST_FLAG(BRUSH_PLANE_TRIM);
BR_TEST_FLAG(BRUSH_FRONTFACE);
BR_TEST_FLAG(BRUSH_CUSTOM_ICON);
@@ -542,7 +542,7 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
/* Get strength by feeding the vertex
* location directly into a texture */
hasrgb = externtex(mtex, point, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false);
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
float rotation = -mtex->rot;
@@ -573,7 +573,7 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
co[2] = 0.0f;
hasrgb = externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false);
}
else {
float rotation = -mtex->rot;
@@ -630,7 +630,7 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
co[2] = 0.0f;
hasrgb = externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false);
}
intensity += br->texture_sample_bias;
@@ -690,7 +690,7 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
co[2] = 0.0f;
externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false);
}
else {
float rotation = -mtex->rot;
@@ -702,7 +702,7 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
/* keep coordinates relative to mouse */
- rotation += ups->brush_rotation;
+ rotation += ups->brush_rotation_sec;
x = point_2d[0] - ups->mask_tex_mouse[0];
y = point_2d[1] - ups->mask_tex_mouse[1];
@@ -720,7 +720,7 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
y = point_2d[1];
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
- rotation += ups->brush_rotation;
+ rotation += ups->brush_rotation_sec;
/* these contain a random coordinate */
x = point_2d[0] - ups->mask_tex_mouse[0];
y = point_2d[1] - ups->mask_tex_mouse[1];
@@ -747,7 +747,7 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
co[2] = 0.0f;
externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false);
}
CLAMP(intensity, 0.0f, 1.0f);
@@ -810,6 +810,9 @@ void BKE_brush_size_set(Scene *scene, Brush *brush, int size)
size = (int)((float)size / U.pixelsize);
+ /* make sure range is sane */
+ CLAMP(size, 1, MAX_BRUSH_PIXEL_RADIUS);
+
if (ups->flag & UNIFIED_PAINT_SIZE)
ups->size = size;
else
@@ -953,7 +956,7 @@ void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2],
jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * spread;
}
-void BKE_brush_randomize_texture_coordinates(UnifiedPaintSettings *ups, bool mask)
+void BKE_brush_randomize_texture_coords(UnifiedPaintSettings *ups, bool mask)
{
/* we multiply with brush radius as an optimization for the brush
* texture sampling functions */
@@ -968,7 +971,7 @@ void BKE_brush_randomize_texture_coordinates(UnifiedPaintSettings *ups, bool mas
}
/* Uses the brush curve control to find a strength value between 0 and 1 */
-float BKE_brush_curve_strength_clamp(Brush *br, float p, const float len)
+float BKE_brush_curve_strength(Brush *br, float p, const float len)
{
float strength;
@@ -981,17 +984,6 @@ float BKE_brush_curve_strength_clamp(Brush *br, float p, const float len)
return strength;
}
-/* same as above but can return negative values if the curve enables
- * used for sculpt only */
-float BKE_brush_curve_strength(Brush *br, float p, const float len)
-{
- if (p >= len)
- p = 1.0f;
- else
- p = p / len;
-
- return curvemapping_evaluateF(br->curve, 0, p);
-}
/* TODO: should probably be unified with BrushPainter stuff? */
unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side, bool use_secondary)
@@ -1018,7 +1010,7 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side, bool use_sec
/* This is copied from displace modifier code */
/* TODO(sergey): brush are always cacheing with CM enabled for now. */
externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL);
+ rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL, false);
((char *)texcache)[(iy * side + ix) * 4] =
((char *)texcache)[(iy * side + ix) * 4 + 1] =
@@ -1048,8 +1040,8 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary)
for (i = 0; i < side; ++i) {
for (j = 0; j < side; ++j) {
- float magn = sqrtf(powf(i - half, 2) + powf(j - half, 2));
- im->rect_float[i * side + j] = BKE_brush_curve_strength_clamp(br, magn, half);
+ float magn = sqrtf(pow2f(i - half) + pow2f(j - half));
+ im->rect_float[i * side + j] = BKE_brush_curve_strength(br, magn, half);
}
}
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 4ad577a7bda..1a4a4bd6bce 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -65,9 +65,7 @@ static float sphereray_tri_intersection(const BVHTreeRay *ray, float radius, con
float idist;
float p1[3];
- float plane_normal[3], hit_point[3];
-
- normal_tri_v3(plane_normal, v0, v1, v2);
+ float hit_point[3];
madd_v3_v3v3fl(p1, ray->origin, ray->direction, m_dist);
if (isect_sweeping_sphere_tri_v3(ray->origin, p1, radius, v0, v1, v2, &idist, hit_point)) {
@@ -81,7 +79,7 @@ static float sphereray_tri_intersection(const BVHTreeRay *ray, float radius, con
* BVH from meshes callbacks
*/
-/* Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_faces.
+/* Callback to bvh tree nearest point. The tree must have been built using bvhtree_from_mesh_faces.
* userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */
static void mesh_faces_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
{
@@ -145,7 +143,7 @@ static void editmesh_faces_nearest_point(void *userdata, int index, const float
}
}
-/* Callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_faces.
+/* Callback to bvh tree raycast. The tree must have been built using bvhtree_from_mesh_faces.
* userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */
static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
@@ -214,7 +212,7 @@ static void editmesh_faces_spherecast(void *userdata, int index, const BVHTreeRa
}
}
-/* Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_edges.
+/* Callback to bvh tree nearest point. The tree must have been built using bvhtree_from_mesh_edges.
* userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */
static void mesh_edges_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
{
@@ -239,68 +237,140 @@ static void mesh_edges_nearest_point(void *userdata, int index, const float co[3
}
}
-/*
- * BVH builders
- */
-/* Builds a bvh tree.. where nodes are the vertexs of the given mesh */
-BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *dm, float epsilon, int tree_type, int axis)
+/* Helper, does all the point-spherecast work actually. */
+static void mesh_verts_spherecast_do(
+ const BVHTreeFromMesh *UNUSED(data), int index, const float v[3], const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
- BVHTree *tree;
- MVert *vert;
- bool vert_allocated;
+ float dist;
+ const float *r1;
+ float r2[3], i1[3];
+ r1 = ray->origin;
+ add_v3_v3v3(r2, r1, ray->direction);
+
+ closest_to_line_segment_v3(i1, v, r1, r2);
+
+ /* No hit if closest point is 'behind' the origin of the ray, or too far away from it. */
+ if ((dot_v3v3v3(r1, i1, r2) >= 0.0f) && ((dist = len_v3v3(r1, i1)) < hit->dist)) {
+ hit->index = index;
+ hit->dist = dist;
+ copy_v3_v3(hit->co, i1);
+ }
+}
- BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
- tree = bvhcache_find(&dm->bvhCache, BVHTREE_FROM_VERTICES);
- BLI_rw_mutex_unlock(&cache_rwlock);
+/* Callback to bvh tree raycast. The tree must have been built using bvhtree_from_mesh_verts.
+ * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */
+static void mesh_verts_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{
+ const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
+ float *v = data->vert[index].co;
- vert = DM_get_vert_array(dm, &vert_allocated);
+ mesh_verts_spherecast_do(data, index, v, ray, hit);
+}
- /* Not in cache */
- if (tree == NULL) {
- BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
- tree = bvhcache_find(&dm->bvhCache, BVHTREE_FROM_VERTICES);
- if (tree == NULL) {
- int i;
- int numVerts = dm->getNumVerts(dm);
+/* Callback to bvh tree raycast. The tree must have been built using bvhtree_from_mesh_edges.
+ * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. */
+static void mesh_edges_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{
+ const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
+ MVert *vert = data->vert;
+ MEdge *edge = &data->edge[index];
- if (vert != NULL) {
- tree = BLI_bvhtree_new(numVerts, epsilon, tree_type, axis);
+ const float radius_sq = SQUARE(data->sphere_radius);
+ float dist;
+ const float *v1, *v2, *r1;
+ float r2[3], i1[3], i2[3];
+ v1 = vert[edge->v1].co;
+ v2 = vert[edge->v2].co;
+
+ /* In case we get a zero-length edge, handle it as a point! */
+ if (equals_v3v3(v1, v2)) {
+ mesh_verts_spherecast_do(data, index, v1, ray, hit);
+ return;
+ }
- if (tree != NULL) {
- for (i = 0; i < numVerts; i++) {
- BLI_bvhtree_insert(tree, i, vert[i].co, 1);
- }
+ r1 = ray->origin;
+ add_v3_v3v3(r2, r1, ray->direction);
- BLI_bvhtree_balance(tree);
+ if (isect_line_line_v3(v1, v2, r1, r2, i1, i2)) {
+ /* No hit if intersection point is 'behind' the origin of the ray, or too far away from it. */
+ if ((dot_v3v3v3(r1, i2, r2) >= 0.0f) && ((dist = len_v3v3(r1, i2)) < hit->dist)) {
+ const float e_fac = line_point_factor_v3(i1, v1, v2);
+ if (e_fac < 0.0f) {
+ copy_v3_v3(i1, v1);
+ }
+ else if (e_fac > 1.0f) {
+ copy_v3_v3(i1, v2);
+ }
+ /* Ensure ray is really close enough from edge! */
+ if (len_squared_v3v3(i1, i2) <= radius_sq) {
+ hit->index = index;
+ hit->dist = dist;
+ copy_v3_v3(hit->co, i2);
+ }
+ }
+ }
+}
- /* Save on cache for later use */
-// printf("BVHTree built and saved on cache\n");
- bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_VERTICES);
+/*
+ * BVH builders
+ */
+
+/* ***** Vertex ***** */
+
+static BVHTree *bvhtree_from_mesh_verts_create_tree(float epsilon, int tree_type, int axis,
+ MVert *vert, const int numVerts,
+ BLI_bitmap *mask, int numVerts_active)
+{
+ BVHTree *tree = NULL;
+ int i;
+
+ if (vert) {
+ if (mask && numVerts_active < 0) {
+ numVerts_active = 0;
+ for (i = 0; i < numVerts; i++) {
+ if (BLI_BITMAP_TEST_BOOL(mask, i)) {
+ numVerts_active++;
}
}
}
- BLI_rw_mutex_unlock(&cache_rwlock);
- }
- else {
-// printf("BVHTree is already build, using cached tree\n");
+ else if (!mask) {
+ numVerts_active = numVerts;
+ }
+
+ tree = BLI_bvhtree_new(numVerts_active, epsilon, tree_type, axis);
+
+ if (tree) {
+ for (i = 0; i < numVerts; i++) {
+ if (mask && !BLI_BITMAP_TEST_BOOL(mask, i)) {
+ continue;
+ }
+ BLI_bvhtree_insert(tree, i, vert[i].co, 1);
+ }
+
+ BLI_bvhtree_balance(tree);
+ }
}
+ return tree;
+}
- /* Setup BVHTreeFromMesh */
+static void bvhtree_from_mesh_verts_setup_data(BVHTreeFromMesh *data, BVHTree *tree, const bool is_cached, float epsilon,
+ MVert *vert, const bool vert_allocated)
+{
memset(data, 0, sizeof(*data));
- data->tree = tree;
- if (data->tree) {
- data->cached = true;
+ if (tree) {
+ data->tree = tree;
+ data->cached = is_cached;
/* a NULL nearest callback works fine
* remember the min distance to point is the same as the min distance to BV of point */
data->nearest_callback = NULL;
- data->raycast_callback = NULL;
+ data->raycast_callback = mesh_verts_spherecast;
data->vert = vert;
data->vert_allocated = vert_allocated;
- data->face = DM_get_tessface_array(dm, &data->face_allocated);
+ //data->face = DM_get_tessface_array(dm, &data->face_allocated); /* XXX WHY???? */
data->sphere_radius = epsilon;
}
@@ -309,184 +379,66 @@ BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *dm, float e
MEM_freeN(vert);
}
}
-
- return data->tree;
}
-/* Builds a bvh tree.. where nodes are the faces of the given dm. */
-BVHTree *bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *dm, float epsilon, int tree_type, int axis)
+/* Builds a bvh tree where nodes are the vertices of the given dm */
+BVHTree *bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *dm, float epsilon, int tree_type, int axis)
{
- BMEditMesh *em = data->em_evil;
- const int bvhcache_type = em ? BVHTREE_FROM_FACES_EDITMESH : BVHTREE_FROM_FACES;
BVHTree *tree;
MVert *vert;
- MFace *face;
- bool vert_allocated = false, face_allocated = false;
+ bool vert_allocated;
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
- tree = bvhcache_find(&dm->bvhCache, bvhcache_type);
+ tree = bvhcache_find(&dm->bvhCache, BVHTREE_FROM_VERTS);
BLI_rw_mutex_unlock(&cache_rwlock);
- if (em == NULL) {
- vert = DM_get_vert_array(dm, &vert_allocated);
- face = DM_get_tessface_array(dm, &face_allocated);
- }
+ vert = DM_get_vert_array(dm, &vert_allocated);
/* Not in cache */
if (tree == NULL) {
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
- tree = bvhcache_find(&dm->bvhCache, bvhcache_type);
+ tree = bvhcache_find(&dm->bvhCache, BVHTREE_FROM_VERTS);
if (tree == NULL) {
- int i;
- int numFaces;
-
- /* BMESH specific check that we have tessfaces,
- * we _could_ tessellate here but rather not - campbell
- *
- * this assert checks we have tessfaces,
- * if not caller should use DM_ensure_tessface() */
- if (em) {
- numFaces = em->tottri;
- }
- else {
- numFaces = dm->getNumTessFaces(dm);
- BLI_assert(!(numFaces == 0 && dm->getNumPolys(dm) != 0));
- }
-
- if (numFaces != 0) {
- /* Create a bvh-tree of the given target */
- // printf("%s: building BVH, total=%d\n", __func__, numFaces);
- tree = BLI_bvhtree_new(numFaces, epsilon, tree_type, axis);
- if (tree != NULL) {
- if (em) {
- const struct BMLoop *(*looptris)[3] = (void *)em->looptris;
-
- /* avoid double-up on face searches for quads-ngons */
- bool insert_prev = false;
- BMFace *f_prev = NULL;
-
- /* data->em_evil is only set for snapping, and only for the mesh of the object
- * which is currently open in edit mode. When set, the bvhtree should not contain
- * faces that will interfere with snapping (e.g. faces that are hidden/selected
- * or faces that have selected verts).*/
-
- /* Insert BMesh-tessellation triangles into the bvh tree, unless they are hidden
- * and/or selected. Even if the faces themselves are not selected for the snapped
- * transform, having a vertex selected means the face (and thus it's tessellated
- * triangles) will be moving and will not be a good snap targets.*/
- for (i = 0; i < em->tottri; i++) {
- const BMLoop **ltri = looptris[i];
- BMFace *f = ltri[0]->f;
- bool insert;
-
- /* Start with the assumption the triangle should be included for snapping. */
- if (f == f_prev) {
- insert = insert_prev;
- }
- else {
- if (BM_elem_flag_test(f, BM_ELEM_SELECT) || BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- /* Don't insert triangles tessellated from faces that are hidden
- * or selected*/
- insert = false;
- }
- else {
- BMLoop *l_iter, *l_first;
- insert = true;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
- /* Don't insert triangles tessellated from faces that have
- * any selected verts.*/
- insert = false;
- break;
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
-
- /* skip if face doesn't change */
- f_prev = f;
- insert_prev = insert;
- }
-
- if (insert) {
- /* No reason found to block hit-testing the triangle for snap,
- * so insert it now.*/
- float co[3][3];
- copy_v3_v3(co[0], ltri[0]->v->co);
- copy_v3_v3(co[1], ltri[1]->v->co);
- copy_v3_v3(co[2], ltri[2]->v->co);
-
- BLI_bvhtree_insert(tree, i, co[0], 3);
- }
- }
- }
- else {
- if (vert != NULL && face != NULL) {
- for (i = 0; i < numFaces; i++) {
- float co[4][3];
- copy_v3_v3(co[0], vert[face[i].v1].co);
- copy_v3_v3(co[1], vert[face[i].v2].co);
- copy_v3_v3(co[2], vert[face[i].v3].co);
- if (face[i].v4)
- copy_v3_v3(co[3], vert[face[i].v4].co);
-
- BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
- }
- }
- }
- BLI_bvhtree_balance(tree);
-
- /* Save on cache for later use */
-// printf("BVHTree built and saved on cache\n");
- bvhcache_insert(&dm->bvhCache, tree, bvhcache_type);
- }
+ tree = bvhtree_from_mesh_verts_create_tree(epsilon, tree_type, axis, vert, dm->getNumVerts(dm), NULL, -1);
+ if (tree) {
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_VERTS);
}
}
BLI_rw_mutex_unlock(&cache_rwlock);
}
else {
-// printf("BVHTree is already build, using cached tree\n");
+ /* printf("BVHTree is already build, using cached tree\n"); */
}
-
/* Setup BVHTreeFromMesh */
- memset(data, 0, sizeof(*data));
- data->tree = tree;
- data->em_evil = em;
+ bvhtree_from_mesh_verts_setup_data(data, tree, true, epsilon, vert, vert_allocated);
- if (data->tree) {
- data->cached = true;
-
- if (em) {
- data->nearest_callback = editmesh_faces_nearest_point;
- data->raycast_callback = editmesh_faces_spherecast;
- }
- else {
- data->nearest_callback = mesh_faces_nearest_point;
- data->raycast_callback = mesh_faces_spherecast;
+ return data->tree;
+}
- data->vert = vert;
- data->vert_allocated = vert_allocated;
- data->face = face;
- data->face_allocated = face_allocated;
- }
+/**
+ * Builds a bvh tree where nodes are the given vertices (note: does not copy given mverts!).
+ * \param vert_allocated if true, vert freeing will be done when freeing data.
+ * \param mask if not null, true elements give which vert to add to BVH tree.
+ * \param numVerts_active if >= 0, number of active verts to add to BVH tree (else will be computed from mask).
+ */
+BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data, MVert *vert, const int numVerts, const bool vert_allocated,
+ BLI_bitmap *mask, int numVerts_active,
+ float epsilon, int tree_type, int axis)
+{
+ BVHTree *tree = bvhtree_from_mesh_verts_create_tree(epsilon, tree_type, axis, vert, numVerts, mask, numVerts_active);
- data->sphere_radius = epsilon;
- }
- else {
- if (vert_allocated) {
- MEM_freeN(vert);
- }
- if (face_allocated) {
- MEM_freeN(face);
- }
- }
+ /* Setup BVHTreeFromMesh */
+ bvhtree_from_mesh_verts_setup_data(data, tree, false, epsilon, vert, vert_allocated);
return data->tree;
-
}
-/* Builds a bvh tree.. where nodes are the faces of the given dm. */
+/* ***** Edge ***** */
+
+/* Builds a bvh tree where nodes are the edges of the given dm */
BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *dm, float epsilon, int tree_type, int axis)
{
BVHTree *tree;
@@ -523,7 +475,7 @@ BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *dm, float e
BLI_bvhtree_balance(tree);
/* Save on cache for later use */
-// printf("BVHTree built and saved on cache\n");
+ /* printf("BVHTree built and saved on cache\n"); */
bvhcache_insert(&dm->bvhCache, tree, BVHTREE_FROM_EDGES);
}
}
@@ -531,7 +483,7 @@ BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *dm, float e
BLI_rw_mutex_unlock(&cache_rwlock);
}
else {
-// printf("BVHTree is already build, using cached tree\n");
+ /* printf("BVHTree is already build, using cached tree\n"); */
}
@@ -543,7 +495,7 @@ BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *dm, float e
data->cached = true;
data->nearest_callback = mesh_edges_nearest_point;
- data->raycast_callback = NULL;
+ data->raycast_callback = mesh_edges_spherecast;
data->vert = vert;
data->vert_allocated = vert_allocated;
@@ -561,15 +513,240 @@ BVHTree *bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *dm, float e
}
}
return data->tree;
+}
+
+/* ***** Tessellated face ***** */
+
+static BVHTree *bvhtree_from_mesh_faces_create_tree(float epsilon, int tree_type, int axis,
+ BMEditMesh *em, MVert *vert, MFace *face, const int numFaces,
+ BLI_bitmap *mask, int numFaces_active)
+{
+ BVHTree *tree = NULL;
+ int i;
+
+ if (numFaces) {
+ if (mask && numFaces_active < 0) {
+ numFaces_active = 0;
+ for (i = 0; i < numFaces; i++) {
+ if (BLI_BITMAP_TEST_BOOL(mask, i)) {
+ numFaces_active++;
+ }
+ }
+ }
+ else if (!mask) {
+ numFaces_active = numFaces;
+ }
+
+ /* Create a bvh-tree of the given target */
+ /* printf("%s: building BVH, total=%d\n", __func__, numFaces); */
+ tree = BLI_bvhtree_new(numFaces_active, epsilon, tree_type, axis);
+ if (tree) {
+ if (em) {
+ const struct BMLoop *(*looptris)[3] = (void *)em->looptris;
+
+ /* avoid double-up on face searches for quads-ngons */
+ bool insert_prev = false;
+ BMFace *f_prev = NULL;
+
+ /* data->em_evil is only set for snapping, and only for the mesh of the object
+ * which is currently open in edit mode. When set, the bvhtree should not contain
+ * faces that will interfere with snapping (e.g. faces that are hidden/selected
+ * or faces that have selected verts). */
+
+ /* Insert BMesh-tessellation triangles into the bvh tree, unless they are hidden
+ * and/or selected. Even if the faces themselves are not selected for the snapped
+ * transform, having a vertex selected means the face (and thus it's tessellated
+ * triangles) will be moving and will not be a good snap targets. */
+ for (i = 0; i < numFaces; i++) {
+ const BMLoop **ltri = looptris[i];
+ BMFace *f = ltri[0]->f;
+ bool insert = mask ? BLI_BITMAP_TEST_BOOL(mask, i) : true;
+
+ /* Start with the assumption the triangle should be included for snapping. */
+ if (f == f_prev) {
+ insert = insert_prev;
+ }
+ else if (insert) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT) || BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ /* Don't insert triangles tessellated from faces that are hidden or selected */
+ insert = false;
+ }
+ else {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+ /* Don't insert triangles tessellated from faces that have any selected verts */
+ insert = false;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ /* skip if face doesn't change */
+ f_prev = f;
+ insert_prev = insert;
+ }
+
+ if (insert) {
+ /* No reason found to block hit-testing the triangle for snap, so insert it now.*/
+ float co[3][3];
+ copy_v3_v3(co[0], ltri[0]->v->co);
+ copy_v3_v3(co[1], ltri[1]->v->co);
+ copy_v3_v3(co[2], ltri[2]->v->co);
+
+ BLI_bvhtree_insert(tree, i, co[0], 3);
+ }
+ }
+ }
+ else {
+ if (vert && face) {
+ for (i = 0; i < numFaces; i++) {
+ float co[4][3];
+ if (mask && !BLI_BITMAP_TEST_BOOL(mask, i)) {
+ continue;
+ }
+ copy_v3_v3(co[0], vert[face[i].v1].co);
+ copy_v3_v3(co[1], vert[face[i].v2].co);
+ copy_v3_v3(co[2], vert[face[i].v3].co);
+ if (face[i].v4)
+ copy_v3_v3(co[3], vert[face[i].v4].co);
+
+ BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
+ }
+ }
+ }
+ BLI_bvhtree_balance(tree);
+ }
+ }
+
+ return tree;
+}
+
+static void bvhtree_from_mesh_faces_setup_data(BVHTreeFromMesh *data, BVHTree *tree, const bool is_cached,
+ float epsilon, BMEditMesh *em,
+ MVert *vert, const bool vert_allocated,
+ MFace *face, const bool face_allocated)
+{
+ memset(data, 0, sizeof(*data));
+ data->em_evil = em;
+
+ if (tree) {
+ data->tree = tree;
+ data->cached = is_cached;
+
+ if (em) {
+ data->nearest_callback = editmesh_faces_nearest_point;
+ data->raycast_callback = editmesh_faces_spherecast;
+ }
+ else {
+ data->nearest_callback = mesh_faces_nearest_point;
+ data->raycast_callback = mesh_faces_spherecast;
+
+ data->vert = vert;
+ data->vert_allocated = vert_allocated;
+ data->face = face;
+ data->face_allocated = face_allocated;
+ }
+
+ data->sphere_radius = epsilon;
+ }
+ else {
+ if (vert_allocated) {
+ MEM_freeN(vert);
+ }
+ if (face_allocated) {
+ MEM_freeN(face);
+ }
+ }
+}
+
+/* Builds a bvh tree where nodes are the tesselated faces of the given dm */
+BVHTree *bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *dm, float epsilon, int tree_type, int axis)
+{
+ BMEditMesh *em = data->em_evil;
+ const int bvhcache_type = em ? BVHTREE_FROM_FACES_EDITMESH : BVHTREE_FROM_FACES;
+ BVHTree *tree;
+ MVert *vert = NULL;
+ MFace *face = NULL;
+ bool vert_allocated = false, face_allocated = false;
+
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
+ tree = bvhcache_find(&dm->bvhCache, bvhcache_type);
+ BLI_rw_mutex_unlock(&cache_rwlock);
+
+ if (em == NULL) {
+ vert = DM_get_vert_array(dm, &vert_allocated);
+ face = DM_get_tessface_array(dm, &face_allocated);
+ }
+
+ /* Not in cache */
+ if (tree == NULL) {
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ tree = bvhcache_find(&dm->bvhCache, bvhcache_type);
+ if (tree == NULL) {
+ int numFaces;
+
+ /* BMESH specific check that we have tessfaces,
+ * we _could_ tessellate here but rather not - campbell
+ *
+ * this assert checks we have tessfaces,
+ * if not caller should use DM_ensure_tessface() */
+ if (em) {
+ numFaces = em->tottri;
+ }
+ else {
+ numFaces = dm->getNumTessFaces(dm);
+ BLI_assert(!(numFaces == 0 && dm->getNumPolys(dm) != 0));
+ }
+
+ tree = bvhtree_from_mesh_faces_create_tree(epsilon, tree_type, axis, em, vert, face, numFaces, NULL, -1);
+ if (tree) {
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(&dm->bvhCache, tree, bvhcache_type);
+ }
+ }
+ BLI_rw_mutex_unlock(&cache_rwlock);
+ }
+ else {
+ /* printf("BVHTree is already build, using cached tree\n"); */
+ }
+
+ /* Setup BVHTreeFromMesh */
+ bvhtree_from_mesh_faces_setup_data(data, tree, true, epsilon, em, vert, vert_allocated, face, face_allocated);
+
+ return data->tree;
+}
+
+/**
+ * Builds a bvh tree where nodes are the given tessellated faces (note: does not copy given mfaces!).
+ * \param vert_allocated if true, vert freeing will be done when freeing data.
+ * \param face_allocated if true, face freeing will be done when freeing data.
+ * \param mask if not null, true elements give which faces to add to BVH tree.
+ * \param numFaces_active if >= 0, number of active faces to add to BVH tree (else will be computed from mask).
+ */
+BVHTree *bvhtree_from_mesh_faces_ex(BVHTreeFromMesh *data, MVert *vert, const bool vert_allocated,
+ MFace *face, const int numFaces, const bool face_allocated,
+ BLI_bitmap *mask, int numFaces_active, float epsilon, int tree_type, int axis)
+{
+ BVHTree *tree = bvhtree_from_mesh_faces_create_tree(epsilon, tree_type, axis, NULL, vert, face, numFaces,
+ mask, numFaces_active);
+
+ /* Setup BVHTreeFromMesh */
+ bvhtree_from_mesh_faces_setup_data(data, tree, false, epsilon, NULL, vert, vert_allocated, face, face_allocated);
+
+ return data->tree;
}
/* Frees data allocated by a call to bvhtree_from_mesh_*. */
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
{
if (data->tree) {
- if (!data->cached)
+ if (!data->cached) {
BLI_bvhtree_free(data->tree);
+ }
if (data->vert_allocated) {
MEM_freeN(data->vert);
@@ -586,7 +763,10 @@ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
}
-/* BVHCache */
+/*
+ * BVHCache
+ */
+
typedef struct BVHCacheItem {
int type;
BVHTree *tree;
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 1402f62291f..451656a9bca 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -39,6 +39,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_rect.h"
#include "BKE_animsys.h"
#include "BKE_camera.h"
@@ -48,6 +49,8 @@
#include "BKE_main.h"
#include "BKE_screen.h"
+#include "GPU_compositing.h"
+
/****************************** Camera Datablock *****************************/
void *BKE_camera_add(Main *bmain, const char *name)
@@ -65,7 +68,9 @@ void *BKE_camera_add(Main *bmain, const char *name)
cam->ortho_scale = 6.0;
cam->flag |= CAM_SHOWPASSEPARTOUT;
cam->passepartalpha = 0.5f;
-
+
+ GPU_fx_compositor_init_dof_settings(&cam->gpu_dof);
+
return cam;
}
@@ -77,6 +82,10 @@ Camera *BKE_camera_copy(Camera *cam)
id_lib_extern((ID *)camn->dof_ob);
+ if (cam->id.lib) {
+ BKE_id_lib_local_paths(G.main, cam->id.lib, &camn->id);
+ }
+
return camn;
}
@@ -257,7 +266,7 @@ void BKE_camera_params_from_view3d(CameraParams *params, View3D *v3d, RegionView
/* camera view */
BKE_camera_params_from_object(params, v3d->camera);
- params->zoom = BKE_screen_view3d_zoom_to_fac((float)rv3d->camzoom);
+ params->zoom = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
params->offsetx = 2.0f * rv3d->camdx * params->zoom;
params->offsety = 2.0f * rv3d->camdy * params->zoom;
@@ -454,17 +463,25 @@ void BKE_camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3])
float dummy_drawsize;
const float dummy_scale[3] = {1.0f, 1.0f, 1.0f};
- BKE_camera_view_frame_ex(scene, camera, false, 1.0, dummy_scale,
+ BKE_camera_view_frame_ex(scene, camera, 0.0, true, dummy_scale,
dummy_asp, dummy_shift, &dummy_drawsize, r_vec);
}
+#define CAMERA_VIEWFRAME_NUM_PLANES 4
typedef struct CameraViewFrameData {
- float plane_tx[4][4]; /* 4 planes (not 4x4 matrix)*/
- float frame_tx[4][3];
- float normal_tx[4][3];
- float dist_vals_sq[4]; /* distance squared (signed) */
+ float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][4]; /* 4 planes */
+ float normal_tx[CAMERA_VIEWFRAME_NUM_PLANES][3];
+ float dist_vals_sq[CAMERA_VIEWFRAME_NUM_PLANES]; /* distance squared (signed) */
unsigned int tot;
+
+ /* Ortho camera only. */
+ bool is_ortho;
+ float camera_no[3];
+ float dist_to_cam;
+
+ /* Not used by callbacks... */
+ float camera_rotmat[3][3];
} CameraViewFrameData;
static void camera_to_frame_view_cb(const float co[3], void *user_data)
@@ -472,67 +489,106 @@ static void camera_to_frame_view_cb(const float co[3], void *user_data)
CameraViewFrameData *data = (CameraViewFrameData *)user_data;
unsigned int i;
- for (i = 0; i < 4; i++) {
- float nd = dist_signed_squared_to_plane_v3(co, data->plane_tx[i]);
- if (nd < data->dist_vals_sq[i]) {
- data->dist_vals_sq[i] = nd;
- }
+ for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
+ const float nd = dist_signed_squared_to_plane_v3(co, data->plane_tx[i]);
+ CLAMP_MAX(data->dist_vals_sq[i], nd);
+ }
+
+ if (data->is_ortho) {
+ const float d = dot_v3v3(data->camera_no, co);
+ CLAMP_MAX(data->dist_to_cam, d);
}
data->tot++;
}
-/* don't move the camera, just yield the fit location */
-/* only valid for perspective cameras */
-bool BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3])
+static void camera_frame_fit_data_init(Scene *scene, Object *ob, CameraParams *params, CameraViewFrameData *data)
{
- float shift[2];
- float plane_tx[4][3];
- float rot_obmat[3][3];
- const float zero[3] = {0, 0, 0};
- CameraViewFrameData data_cb;
-
+ float camera_rotmat_transposed_inversed[4][4];
unsigned int i;
- BKE_camera_view_frame(scene, camera_ob->data, data_cb.frame_tx);
+ /* setup parameters */
+ BKE_camera_params_init(params);
+ BKE_camera_params_from_object(params, ob);
- copy_m3_m4(rot_obmat, camera_ob->obmat);
- normalize_m3(rot_obmat);
-
- for (i = 0; i < 4; i++) {
- /* normalize so Z is always 1.0f*/
- mul_v3_fl(data_cb.frame_tx[i], 1.0f / data_cb.frame_tx[i][2]);
+ /* compute matrix, viewplane, .. */
+ if (scene) {
+ BKE_camera_params_compute_viewplane(params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
}
+ else {
+ BKE_camera_params_compute_viewplane(params, 1, 1, 1.0f, 1.0f);
+ }
+ BKE_camera_params_compute_matrix(params);
- /* get the shift back out of the frame */
- shift[0] = (data_cb.frame_tx[0][0] +
- data_cb.frame_tx[1][0] +
- data_cb.frame_tx[2][0] +
- data_cb.frame_tx[3][0]) / 4.0f;
- shift[1] = (data_cb.frame_tx[0][1] +
- data_cb.frame_tx[1][1] +
- data_cb.frame_tx[2][1] +
- data_cb.frame_tx[3][1]) / 4.0f;
-
- for (i = 0; i < 4; i++) {
- mul_m3_v3(rot_obmat, data_cb.frame_tx[i]);
+ /* initialize callback data */
+ copy_m3_m4(data->camera_rotmat, ob->obmat);
+ normalize_m3(data->camera_rotmat);
+ /* To transform a plane which is in its homogeneous representation (4d vector),
+ * we need the inverse of the transpose of the transform matrix... */
+ copy_m4_m3(camera_rotmat_transposed_inversed, data->camera_rotmat);
+ transpose_m4(camera_rotmat_transposed_inversed);
+ invert_m4(camera_rotmat_transposed_inversed);
+
+ /* Extract frustum planes from projection matrix. */
+ planes_from_projmat(params->winmat,
+ /* left right top bottom near far */
+ data->plane_tx[2], data->plane_tx[0], data->plane_tx[3], data->plane_tx[1], NULL, NULL);
+
+ /* Rotate planes and get normals from them */
+ for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
+ mul_m4_v4(camera_rotmat_transposed_inversed, data->plane_tx[i]);
+ normalize_v3_v3(data->normal_tx[i], data->plane_tx[i]);
}
- for (i = 0; i < 4; i++) {
- normal_tri_v3(data_cb.normal_tx[i], zero, data_cb.frame_tx[i], data_cb.frame_tx[(i + 1) % 4]);
- plane_from_point_normal_v3(data_cb.plane_tx[i], data_cb.frame_tx[i], data_cb.normal_tx[i]);
+ copy_v4_fl(data->dist_vals_sq, FLT_MAX);
+ data->tot = 0;
+ data->is_ortho = params->is_ortho;
+ if (params->is_ortho) {
+ /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */
+ negate_v3_v3(data->camera_no, data->camera_rotmat[2]);
+ data->dist_to_cam = FLT_MAX;
}
+}
- /* initialize callback data */
- copy_v4_fl(data_cb.dist_vals_sq, FLT_MAX);
- data_cb.tot = 0;
- /* run callback on all visible points */
- BKE_scene_foreach_display_point(scene, v3d, BA_SELECT,
- camera_to_frame_view_cb, &data_cb);
+static bool camera_frame_fit_calc_from_data(
+ CameraParams *params, CameraViewFrameData *data, float r_co[3], float *r_scale)
+{
+ float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][3];
+ unsigned int i;
- if (data_cb.tot <= 1) {
+ if (data->tot <= 1) {
return false;
}
+
+ if (params->is_ortho) {
+ const float *cam_axis_x = data->camera_rotmat[0];
+ const float *cam_axis_y = data->camera_rotmat[1];
+ const float *cam_axis_z = data->camera_rotmat[2];
+ float dists[CAMERA_VIEWFRAME_NUM_PLANES];
+ float scale_diff;
+
+ /* apply the dist-from-plane's to the transformed plane points */
+ for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
+ dists[i] = sqrtf_signed(data->dist_vals_sq[i]);
+ }
+
+ if ((dists[0] + dists[2]) > (dists[1] + dists[3])) {
+ scale_diff = (dists[1] + dists[3]) *
+ (BLI_rctf_size_x(&params->viewplane) / BLI_rctf_size_y(&params->viewplane));
+ }
+ else {
+ scale_diff = (dists[0] + dists[2]) *
+ (BLI_rctf_size_y(&params->viewplane) / BLI_rctf_size_x(&params->viewplane));
+ }
+ *r_scale = params->ortho_scale - scale_diff;
+
+ zero_v3(r_co);
+ madd_v3_v3fl(r_co, cam_axis_x, (dists[2] - dists[0]) * 0.5f + params->shiftx * scale_diff);
+ madd_v3_v3fl(r_co, cam_axis_y, (dists[1] - dists[3]) * 0.5f + params->shifty * scale_diff);
+ madd_v3_v3fl(r_co, cam_axis_z, -(data->dist_to_cam - 1.0f - params->clipsta));
+
+ return true;
+ }
else {
float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];
@@ -540,16 +596,16 @@ bool BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object
float plane_isect_pt_1[3], plane_isect_pt_2[3];
/* apply the dist-from-plane's to the transformed plane points */
- for (i = 0; i < 4; i++) {
- mul_v3_v3fl(plane_tx[i], data_cb.normal_tx[i], sqrtf_signed(data_cb.dist_vals_sq[i]));
+ for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
+ mul_v3_v3fl(plane_tx[i], data->normal_tx[i], sqrtf_signed(data->dist_vals_sq[i]));
}
if ((!isect_plane_plane_v3(plane_isect_1, plane_isect_1_no,
- plane_tx[0], data_cb.normal_tx[0],
- plane_tx[2], data_cb.normal_tx[2])) ||
+ plane_tx[0], data->normal_tx[0],
+ plane_tx[2], data->normal_tx[2])) ||
(!isect_plane_plane_v3(plane_isect_2, plane_isect_2_no,
- plane_tx[1], data_cb.normal_tx[1],
- plane_tx[3], data_cb.normal_tx[3])))
+ plane_tx[1], data->normal_tx[1],
+ plane_tx[3], data->normal_tx[3])))
{
return false;
}
@@ -559,16 +615,17 @@ bool BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object
if (isect_line_line_v3(plane_isect_1, plane_isect_1_other,
plane_isect_2, plane_isect_2_other,
- plane_isect_pt_1, plane_isect_pt_2) == 0)
+ plane_isect_pt_1, plane_isect_pt_2) != 0)
{
- return false;
- }
- else {
- float cam_plane_no[3] = {0.0f, 0.0f, -1.0f};
+ float cam_plane_no[3];
float plane_isect_delta[3];
float plane_isect_delta_len;
- mul_m3_v3(rot_obmat, cam_plane_no);
+ float shift_fac = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y) /
+ params->lens;
+
+ /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */
+ negate_v3_v3(cam_plane_no, data->camera_rotmat[2]);
sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1);
plane_isect_delta_len = len_v3(plane_isect_delta);
@@ -578,18 +635,73 @@ bool BKE_camera_view_frame_fit_to_scene(Scene *scene, struct View3D *v3d, Object
/* offset shift */
normalize_v3(plane_isect_1_no);
- madd_v3_v3fl(r_co, plane_isect_1_no, shift[1] * -plane_isect_delta_len);
+ madd_v3_v3fl(r_co, plane_isect_1_no, params->shifty * plane_isect_delta_len * shift_fac);
}
else {
copy_v3_v3(r_co, plane_isect_pt_2);
/* offset shift */
normalize_v3(plane_isect_2_no);
- madd_v3_v3fl(r_co, plane_isect_2_no, shift[0] * -plane_isect_delta_len);
+ madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac);
}
-
return true;
}
}
+
+ return false;
+}
+
+/* don't move the camera, just yield the fit location */
+/* r_scale only valid/useful for ortho cameras */
+bool BKE_camera_view_frame_fit_to_scene(
+ Scene *scene, struct View3D *v3d, Object *camera_ob, float r_co[3], float *r_scale)
+{
+ CameraParams params;
+ CameraViewFrameData data_cb;
+
+ /* just in case */
+ *r_scale = 1.0f;
+
+ camera_frame_fit_data_init(scene, camera_ob, &params, &data_cb);
+
+ /* run callback on all visible points */
+ BKE_scene_foreach_display_point(scene, v3d, BA_SELECT, camera_to_frame_view_cb, &data_cb);
+
+ return camera_frame_fit_calc_from_data(&params, &data_cb, r_co, r_scale);
+}
+
+bool BKE_camera_view_frame_fit_to_coords(
+ Scene *scene, float (*cos)[3], int num_cos, Object *camera_ob, float r_co[3], float *r_scale)
+{
+ CameraParams params;
+ CameraViewFrameData data_cb;
+
+ /* just in case */
+ *r_scale = 1.0f;
+
+ camera_frame_fit_data_init(scene, camera_ob, &params, &data_cb);
+
+ /* run callback on all given coordinates */
+ while (num_cos--) {
+ camera_to_frame_view_cb(cos[num_cos], &data_cb);
+ }
+
+ return camera_frame_fit_calc_from_data(&params, &data_cb, r_co, r_scale);
+}
+
+void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_settings)
+{
+ if (camera->type == OB_CAMERA) {
+ Camera *cam = camera->data;
+ r_fx_settings->dof = &cam->gpu_dof;
+ r_fx_settings->dof->focal_length = cam->lens;
+ r_fx_settings->dof->sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
+ if (cam->dof_ob) {
+ r_fx_settings->dof->focus_distance = len_v3v3(cam->dof_ob->obmat[3], camera->obmat[3]);
+ }
+ else {
+ r_fx_settings->dof->focus_distance = cam->YF_dofdist;
+ }
+ }
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index bfc70c91181..6b7855b7759 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -35,7 +35,6 @@
*/
#include "BLI_math.h"
-#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_utildefines.h"
#include "BLI_stackdefines.h"
@@ -49,7 +48,6 @@
#include "BKE_editmesh.h"
#include "BKE_curve.h"
-#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -61,7 +59,6 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
-#include "GPU_material.h"
#include <string.h>
#include <limits.h>
@@ -343,106 +340,64 @@ static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
static void cdDM_drawVerts(DerivedMesh *dm)
{
- CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- MVert *mv = cddm->mvert;
- int i;
-
- if (GPU_buffer_legacy(dm)) {
- glBegin(GL_POINTS);
- for (i = 0; i < dm->numVertData; i++, mv++)
- glVertex3fv(mv->co);
- glEnd();
- }
- else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- GPU_vertex_setup(dm);
- if (!GPU_buffer_legacy(dm)) {
- if (dm->drawObject->tot_triangle_point)
- glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point);
- else
- glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point);
- }
- GPU_buffer_unbind();
- }
+ GPU_vertex_setup(dm);
+ if (dm->drawObject->tot_triangle_point)
+ glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point);
+ else
+ glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point);
+ GPU_buffer_unbind();
}
static void cdDM_drawUVEdges(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
MFace *mf = cddm->mface;
- MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
int i;
if (mf) {
- if (GPU_buffer_legacy(dm)) {
- glBegin(GL_LINES);
- for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) {
- if (!(mf->flag & ME_HIDE)) {
- glVertex2fv(tf->uv[0]);
- glVertex2fv(tf->uv[1]);
-
- glVertex2fv(tf->uv[1]);
- glVertex2fv(tf->uv[2]);
-
- if (!mf->v4) {
- glVertex2fv(tf->uv[2]);
- glVertex2fv(tf->uv[0]);
- }
- else {
- glVertex2fv(tf->uv[2]);
- glVertex2fv(tf->uv[3]);
-
- glVertex2fv(tf->uv[3]);
- glVertex2fv(tf->uv[0]);
- }
- }
+ int prevstart = 0;
+ int prevdraw = 1;
+ int draw = 1;
+ int curpos = 0;
+
+ GPU_uvedge_setup(dm);
+ for (i = 0; i < dm->numTessFaceData; i++, mf++) {
+ if (!(mf->flag & ME_HIDE)) {
+ draw = 1;
}
- glEnd();
- }
- else {
- int prevstart = 0;
- int prevdraw = 1;
- int draw = 1;
- int curpos = 0;
-
- GPU_uvedge_setup(dm);
- if (!GPU_buffer_legacy(dm)) {
- for (i = 0; i < dm->numTessFaceData; i++, mf++) {
- if (!(mf->flag & ME_HIDE)) {
- draw = 1;
- }
- else {
- draw = 0;
- }
- if (prevdraw != draw) {
- if (prevdraw > 0 && (curpos - prevstart) > 0) {
- glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
- }
- prevstart = curpos;
- }
- if (mf->v4) {
- curpos += 8;
- }
- else {
- curpos += 6;
- }
- prevdraw = draw;
- }
+ else {
+ draw = 0;
+ }
+ if (prevdraw != draw) {
if (prevdraw > 0 && (curpos - prevstart) > 0) {
glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
}
+ prevstart = curpos;
+ }
+ if (mf->v4) {
+ curpos += 8;
}
- GPU_buffer_unbind();
+ else {
+ curpos += 6;
+ }
+ prevdraw = draw;
+ }
+ if (prevdraw > 0 && (curpos - prevstart) > 0) {
+ glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
}
+ GPU_buffer_unbind();
}
}
static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- MVert *mvert = cddm->mvert;
MEdge *medge = cddm->medge;
int i;
-
+ int prevstart = 0;
+ int prevdraw = 1;
+ bool draw = true;
+
if (cddm->pbvh && cddm->pbvh_draw &&
BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH)
{
@@ -451,97 +406,60 @@ static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdg
return;
}
- if (GPU_buffer_legacy(dm)) {
- DEBUG_VBO("Using legacy code. cdDM_drawEdges\n");
- glBegin(GL_LINES);
- for (i = 0; i < dm->numEdgeData; i++, medge++) {
- if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
- (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
- {
- glVertex3fv(mvert[medge->v1].co);
- glVertex3fv(mvert[medge->v2].co);
- }
+ GPU_edge_setup(dm);
+ for (i = 0; i < dm->numEdgeData; i++, medge++) {
+ if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
+ (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
+ {
+ draw = true;
}
- glEnd();
- }
- else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- int prevstart = 0;
- int prevdraw = 1;
- bool draw = true;
-
- GPU_edge_setup(dm);
- if (!GPU_buffer_legacy(dm)) {
- for (i = 0; i < dm->numEdgeData; i++, medge++) {
- if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
- (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
- {
- draw = true;
- }
- else {
- draw = false;
- }
- if (prevdraw != draw) {
- if (prevdraw > 0 && (i - prevstart) > 0) {
- GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
- }
- prevstart = i;
- }
- prevdraw = draw;
- }
+ else {
+ draw = false;
+ }
+ if (prevdraw != draw) {
if (prevdraw > 0 && (i - prevstart) > 0) {
GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
}
+ prevstart = i;
}
- GPU_buffer_unbind();
+ prevdraw = draw;
+ }
+ if (prevdraw > 0 && (i - prevstart) > 0) {
+ GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
}
+ GPU_buffer_unbind();
}
static void cdDM_drawLooseEdges(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- MVert *mvert = cddm->mvert;
MEdge *medge = cddm->medge;
int i;
-
- if (GPU_buffer_legacy(dm)) {
- DEBUG_VBO("Using legacy code. cdDM_drawLooseEdges\n");
- glBegin(GL_LINES);
- for (i = 0; i < dm->numEdgeData; i++, medge++) {
- if (medge->flag & ME_LOOSEEDGE) {
- glVertex3fv(mvert[medge->v1].co);
- glVertex3fv(mvert[medge->v2].co);
- }
+
+ int prevstart = 0;
+ int prevdraw = 1;
+ int draw = 1;
+
+ GPU_edge_setup(dm);
+ for (i = 0; i < dm->numEdgeData; i++, medge++) {
+ if (medge->flag & ME_LOOSEEDGE) {
+ draw = 1;
}
- glEnd();
- }
- else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- int prevstart = 0;
- int prevdraw = 1;
- int draw = 1;
-
- GPU_edge_setup(dm);
- if (!GPU_buffer_legacy(dm)) {
- for (i = 0; i < dm->numEdgeData; i++, medge++) {
- if (medge->flag & ME_LOOSEEDGE) {
- draw = 1;
- }
- else {
- draw = 0;
- }
- if (prevdraw != draw) {
- if (prevdraw > 0 && (i - prevstart) > 0) {
- GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
- }
- prevstart = i;
- }
- prevdraw = draw;
- }
+ else {
+ draw = 0;
+ }
+ if (prevdraw != draw) {
if (prevdraw > 0 && (i - prevstart) > 0) {
GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
}
+ prevstart = i;
}
- GPU_buffer_unbind();
+ prevdraw = draw;
+ }
+ if (prevdraw > 0 && (i - prevstart) > 0) {
+ GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
}
+ GPU_buffer_unbind();
}
static void cdDM_drawFacesSolid(DerivedMesh *dm,
@@ -549,11 +467,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
bool UNUSED(fast), DMSetMaterial setMaterial)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- MVert *mvert = cddm->mvert;
- MFace *mface = cddm->mface;
- const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
- const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
- int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
+ int a;
if (cddm->pbvh && cddm->pbvh_draw) {
if (dm->numTessFaceData) {
@@ -566,121 +480,37 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
return;
}
-
- if (GPU_buffer_legacy(dm)) {
- DEBUG_VBO("Using legacy code. cdDM_drawFacesSolid\n");
- glBegin(glmode = GL_QUADS);
- for (a = 0; a < dm->numTessFaceData; a++, mface++) {
- int new_glmode, new_matnr, new_shademodel;
-
- new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES;
- new_matnr = mface->mat_nr + 1;
- new_shademodel = (lnors || (mface->flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
-
-
- if ((new_glmode != glmode) || (new_shademodel != shademodel) ||
- (setMaterial && (new_matnr != matnr)))
- {
- glEnd();
-
- if (setMaterial) {
- drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
- }
-
- glShadeModel(shademodel = new_shademodel);
- glBegin(glmode = new_glmode);
- }
-
- if (drawCurrentMat) {
- if (lnors) {
- glNormal3sv((const GLshort *)lnors[0][0]);
- glVertex3fv(mvert[mface->v1].co);
- glNormal3sv((const GLshort *)lnors[0][1]);
- glVertex3fv(mvert[mface->v2].co);
- glNormal3sv((const GLshort *)lnors[0][2]);
- glVertex3fv(mvert[mface->v3].co);
- if (mface->v4) {
- glNormal3sv((const GLshort *)lnors[0][3]);
- glVertex3fv(mvert[mface->v4].co);
- }
- }
- else if (shademodel == GL_FLAT) {
- if (nors) {
- glNormal3fv(nors);
- }
- else {
- /* TODO make this better (cache facenormals as layer?) */
- float nor[3];
- if (mface->v4) {
- normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
- }
- else {
- normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
- }
- glNormal3fv(nor);
- }
- glVertex3fv(mvert[mface->v1].co);
- glVertex3fv(mvert[mface->v2].co);
- glVertex3fv(mvert[mface->v3].co);
- if (mface->v4) {
- glVertex3fv(mvert[mface->v4].co);
- }
- }
- else { /* shademodel == GL_SMOOTH */
- glNormal3sv(mvert[mface->v1].no);
- glVertex3fv(mvert[mface->v1].co);
- glNormal3sv(mvert[mface->v2].no);
- glVertex3fv(mvert[mface->v2].co);
- glNormal3sv(mvert[mface->v3].no);
- glVertex3fv(mvert[mface->v3].co);
- if (mface->v4) {
- glNormal3sv(mvert[mface->v4].no);
- glVertex3fv(mvert[mface->v4].co);
- }
- }
- }
-
- if (nors)
- nors += 3;
- if (lnors)
- lnors++;
- }
- glEnd();
- }
- else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- GPU_vertex_setup(dm);
- GPU_normal_setup(dm);
- if (!GPU_buffer_legacy(dm)) {
- glShadeModel(GL_SMOOTH);
- for (a = 0; a < dm->drawObject->totmaterial; a++) {
- if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
- glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
- dm->drawObject->materials[a].totpoint);
- }
- }
+
+ GPU_vertex_setup(dm);
+ GPU_normal_setup(dm);
+ glShadeModel(GL_SMOOTH);
+ for (a = 0; a < dm->drawObject->totmaterial; a++) {
+ if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
+ glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
+ dm->drawObject->materials[a].totpoint);
}
- GPU_buffer_unbind();
}
+ GPU_buffer_unbind();
glShadeModel(GL_FLAT);
}
static void cdDM_drawFacesTex_common(DerivedMesh *dm,
DMSetDrawOptionsTex drawParams,
- DMSetDrawOptions drawParamsMapped,
+ DMSetDrawOptionsMappedTex drawParamsMapped,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag uvflag)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- MVert *mv = cddm->mvert;
const MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
- const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
- const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
MCol *mcol;
int i, orig;
int colType, startFace = 0;
bool use_tface = (uvflag & DM_DRAW_USE_ACTIVE_UV) != 0;
+ int tottri;
+ int next_actualFace;
+
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
@@ -717,208 +547,81 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
cdDM_update_normals_from_pbvh(dm);
-
- if (GPU_buffer_legacy(dm)) {
- int mat_nr_cache = -1;
- MTFace *tf_base = DM_get_tessface_data_layer(dm, CD_MTFACE);
- MTFace *tf_stencil_base = NULL;
- MTFace *tf_stencil = NULL;
-
- if (uvflag & DM_DRAW_USE_TEXPAINT_UV) {
- int stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE);
- tf_stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil);
+
+ GPU_vertex_setup(dm);
+ GPU_normal_setup(dm);
+ if (uvflag & DM_DRAW_USE_TEXPAINT_UV)
+ GPU_texpaint_uv_setup(dm);
+ else
+ GPU_uv_setup(dm);
+ if (mcol) {
+ GPU_color_setup(dm, colType);
+ }
+
+ tottri = dm->drawObject->tot_triangle_point / 3;
+ next_actualFace = dm->drawObject->triangle_to_mface[0];
+
+ glShadeModel(GL_SMOOTH);
+ /* lastFlag = 0; */ /* UNUSED */
+ for (i = 0; i < tottri; i++) {
+ int actualFace = next_actualFace;
+ DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
+ int flush = 0;
+
+ if (i != tottri - 1)
+ next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
+
+ if (drawParams) {
+ draw_option = drawParams(use_tface && tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr);
}
-
- DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n");
- for (i = 0; i < dm->numTessFaceData; i++, mf++) {
- MVert *mvert;
- DMDrawOption draw_option;
- unsigned char *cp = NULL;
-
- if (uvflag & DM_DRAW_USE_TEXPAINT_UV) {
- if (mf->mat_nr != mat_nr_cache) {
- tf_base = DM_paint_uvlayer_active_get(dm, mf->mat_nr);
-
- mat_nr_cache = mf->mat_nr;
- }
- }
-
- tf = tf_base ? tf_base + i : NULL;
- tf_stencil = tf_stencil_base ? tf_stencil_base + i : NULL;
-
- if (drawParams) {
- draw_option = drawParams(use_tface ? tf : NULL, (mcol != NULL), mf->mat_nr);
- }
- else {
- if (index_mf_to_mpoly) {
- orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i);
- if (orig == ORIGINDEX_NONE) {
- /* XXX, this is not really correct
- * it will draw the previous faces context for this one when we don't know its settings.
- * but better then skipping it altogether. - campbell */
- draw_option = DM_DRAW_OPTION_NORMAL;
- }
- else if (drawParamsMapped) {
- draw_option = drawParamsMapped(userData, orig);
- }
- else {
- if (nors) {
- nors += 3;
- }
- continue;
- }
+ else {
+ if (index_mf_to_mpoly) {
+ orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace);
+ if (orig == ORIGINDEX_NONE) {
+ /* XXX, this is not really correct
+ * it will draw the previous faces context for this one when we don't know its settings.
+ * but better then skipping it altogether. - campbell */
+ draw_option = DM_DRAW_OPTION_NORMAL;
}
else if (drawParamsMapped) {
- draw_option = drawParamsMapped(userData, i);
- }
- else {
- if (nors) {
- nors += 3;
- }
- continue;
+ draw_option = drawParamsMapped(userData, orig, mf[actualFace].mat_nr);
}
}
-
- if (draw_option != DM_DRAW_OPTION_SKIP) {
- if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol)
- cp = (unsigned char *) &mcol[i * 4];
-
- if (!(lnors || (mf->flag & ME_SMOOTH))) {
- if (nors) {
- glNormal3fv(nors);
- }
- else {
- float nor[3];
- if (mf->v4) {
- normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
- }
- else {
- normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
- }
- glNormal3fv(nor);
- }
- }
-
- glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
- if (tf) glTexCoord2fv(tf->uv[0]);
- if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[0]);
- if (cp) glColor3ub(cp[3], cp[2], cp[1]);
- mvert = &mv[mf->v1];
- if (lnors) glNormal3sv((const GLshort *)lnors[0][0]);
- else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
- glVertex3fv(mvert->co);
-
- if (tf) glTexCoord2fv(tf->uv[1]);
- if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[1]);
- if (cp) glColor3ub(cp[7], cp[6], cp[5]);
- mvert = &mv[mf->v2];
- if (lnors) glNormal3sv((const GLshort *)lnors[0][1]);
- else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
- glVertex3fv(mvert->co);
-
- if (tf) glTexCoord2fv(tf->uv[2]);
- if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[2]);
- if (cp) glColor3ub(cp[11], cp[10], cp[9]);
- mvert = &mv[mf->v3];
- if (lnors) glNormal3sv((const GLshort *)lnors[0][2]);
- else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
- glVertex3fv(mvert->co);
-
- if (mf->v4) {
- if (tf) glTexCoord2fv(tf->uv[3]);
- if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[3]);
- if (cp) glColor3ub(cp[15], cp[14], cp[13]);
- mvert = &mv[mf->v4];
- if (lnors) glNormal3sv((const GLshort *)lnors[0][3]);
- else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
- glVertex3fv(mvert->co);
- }
- glEnd();
+ else if (drawParamsMapped) {
+ draw_option = drawParamsMapped(userData, actualFace, mf[actualFace].mat_nr);
}
-
- if (nors)
- nors += 3;
- if (lnors)
- lnors++;
}
- }
- else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- GPU_vertex_setup(dm);
- GPU_normal_setup(dm);
- if (uvflag & DM_DRAW_USE_TEXPAINT_UV)
- GPU_texpaint_uv_setup(dm);
- else
- GPU_uv_setup(dm);
- if (mcol) {
- GPU_color_setup(dm, colType);
- }
-
- if (!GPU_buffer_legacy(dm)) {
- int tottri = dm->drawObject->tot_triangle_point / 3;
- int next_actualFace = dm->drawObject->triangle_to_mface[0];
-
- glShadeModel(GL_SMOOTH);
- /* lastFlag = 0; */ /* UNUSED */
- for (i = 0; i < tottri; i++) {
- int actualFace = next_actualFace;
- DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
- int flush = 0;
-
- if (i != tottri - 1)
- next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
-
- if (drawParams) {
- draw_option = drawParams(use_tface && tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr);
- }
- else {
- if (index_mf_to_mpoly) {
- orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace);
- if (orig == ORIGINDEX_NONE) {
- /* XXX, this is not really correct
- * it will draw the previous faces context for this one when we don't know its settings.
- * but better then skipping it altogether. - campbell */
- draw_option = DM_DRAW_OPTION_NORMAL;
- }
- else if (drawParamsMapped) {
- draw_option = drawParamsMapped(userData, orig);
- }
- }
- else if (drawParamsMapped) {
- draw_option = drawParamsMapped(userData, actualFace);
- }
- }
-
- /* flush buffer if current triangle isn't drawable or it's last triangle */
- flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
-
- if (!flush && compareDrawOptions) {
- /* also compare draw options and flush buffer if they're different
+
+ /* flush buffer if current triangle isn't drawable or it's last triangle */
+ flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
+
+ if (!flush && compareDrawOptions) {
+ /* also compare draw options and flush buffer if they're different
* need for face selection highlight in edit mode */
- flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
- }
-
- if (flush) {
- int first = startFace * 3;
- /* Add one to the length if we're drawing at the end of the array */
- int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
-
- if (count) {
- if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
- GPU_color_switch(1);
- else
- GPU_color_switch(0);
-
- glDrawArrays(GL_TRIANGLES, first, count);
- }
-
- startFace = i + 1;
- }
+ flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
+ }
+
+ if (flush) {
+ int first = startFace * 3;
+ /* Add one to the length if we're drawing at the end of the array */
+ int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
+
+ if (count) {
+ if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
+ GPU_color_switch(1);
+ else
+ GPU_color_switch(0);
+
+ glDrawArrays(GL_TRIANGLES, first, count);
}
+
+ startFace = i + 1;
}
-
- GPU_buffer_unbind();
- glShadeModel(GL_FLAT);
}
+
+ GPU_buffer_unbind();
+ glShadeModel(GL_FLAT);
+
}
static void cdDM_drawFacesTex(DerivedMesh *dm,
@@ -968,7 +671,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
/* back-buffer always uses legacy since VBO's would need the
* color array temporarily overwritten for drawing, then reset. */
- if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
+ if (G.f & G_BACKBUFSEL) {
DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n");
for (i = 0; i < dm->numTessFaceData; i++, mf++) {
int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mf->flag & ME_SMOOTH);
@@ -1070,79 +773,85 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
}
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
int prevstart = 0;
+ int tottri;
+
GPU_vertex_setup(dm);
GPU_normal_setup(dm);
if (useColors && mcol) {
GPU_color_setup(dm, colType);
}
- if (!GPU_buffer_legacy(dm)) {
- int tottri = dm->drawObject->tot_triangle_point / 3;
- glShadeModel(GL_SMOOTH);
+ tottri = dm->drawObject->tot_triangle_point / 3;
+ glShadeModel(GL_SMOOTH);
+
+ if (tottri == 0) {
+ /* avoid buffer problems in following code */
+ }
+ if (setDrawOptions == NULL) {
+ /* just draw the entire face array */
+ glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
+ }
+ else {
+ /* we need to check if the next material changes */
+ int next_actualFace = dm->drawObject->triangle_to_mface[0];
+ int prev_mat_nr = -1;
- if (tottri == 0) {
- /* avoid buffer problems in following code */
- }
- if (setDrawOptions == NULL) {
- /* just draw the entire face array */
- glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
- }
- else {
- /* we need to check if the next material changes */
- int next_actualFace = dm->drawObject->triangle_to_mface[0];
+ for (i = 0; i < tottri; i++) {
+ //int actualFace = dm->drawObject->triangle_to_mface[i];
+ int actualFace = next_actualFace;
+ MFace *mface = mf + actualFace;
+ /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */
+ DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
+ int flush = 0;
- for (i = 0; i < tottri; i++) {
- //int actualFace = dm->drawObject->triangle_to_mface[i];
- int actualFace = next_actualFace;
- MFace *mface = mf + actualFace;
- /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */
- DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
- int flush = 0;
-
- if (i != tottri - 1)
- next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
-
- orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace;
-
- if (orig == ORIGINDEX_NONE)
+ if (i != tottri - 1)
+ next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
+
+ orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace;
+
+ if (mface->mat_nr != prev_mat_nr) {
+ if (setMaterial)
draw_option = setMaterial(mface->mat_nr + 1, NULL);
- else if (setDrawOptions != NULL)
- draw_option = setDrawOptions(userData, orig);
-
- if (draw_option == DM_DRAW_OPTION_STIPPLE) {
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
-
- /* Goal is to draw as long of a contiguous triangle
+
+ prev_mat_nr = mface->mat_nr;
+ }
+
+ if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE))
+ draw_option = setDrawOptions(userData, orig);
+
+ if (draw_option == DM_DRAW_OPTION_STIPPLE) {
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(stipple_quarttone);
+ }
+
+ /* Goal is to draw as long of a contiguous triangle
* array as possible, so draw when we hit either an
* invisible triangle or at the end of the array */
-
- /* flush buffer if current triangle isn't drawable or it's last triangle... */
- flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1);
-
- /* ... or when material setting is dissferent */
- flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
-
- if (!flush && compareDrawOptions) {
- flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
- }
-
- if (flush) {
- int first = prevstart * 3;
- /* Add one to the length if we're drawing at the end of the array */
- int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
-
- if (count)
- glDrawArrays(GL_TRIANGLES, first, count);
-
- prevstart = i + 1;
-
- if (draw_option == DM_DRAW_OPTION_STIPPLE)
- glDisable(GL_POLYGON_STIPPLE);
- }
+
+ /* flush buffer if current triangle isn't drawable or it's last triangle... */
+ flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1);
+
+ /* ... or when material setting is dissferent */
+ flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
+
+ if (!flush && compareDrawOptions) {
+ flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
+ }
+
+ if (flush) {
+ int first = prevstart * 3;
+ /* Add one to the length if we're drawing at the end of the array */
+ int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
+
+ if (count)
+ glDrawArrays(GL_TRIANGLES, first, count);
+
+ prevstart = i + 1;
+
+ if (draw_option == DM_DRAW_OPTION_STIPPLE)
+ glDisable(GL_POLYGON_STIPPLE);
}
}
-
+
glShadeModel(GL_FLAT);
}
GPU_buffer_unbind();
@@ -1150,7 +859,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
}
static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
+ DMSetDrawOptionsMappedTex setDrawOptions,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag flag)
{
@@ -1160,59 +869,7 @@ static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, const MVert *mvert, int a, int index, int vert,
const short (*lnor)[3], const bool smoothnormal)
{
- const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- int b;
-
- /* orco texture coordinates */
- if (attribs->totorco) {
- /*const*/ float (*array)[3] = attribs->orco.array;
- const float *orco = (array) ? array[index] : zero;
-
- if (attribs->orco.gl_texco)
- glTexCoord3fv(orco);
- else
- glVertexAttrib3fvARB(attribs->orco.gl_index, orco);
- }
-
- /* uv texture coordinates */
- for (b = 0; b < attribs->tottface; b++) {
- const float *uv;
-
- if (attribs->tface[b].array) {
- MTFace *tf = &attribs->tface[b].array[a];
- uv = tf->uv[vert];
- }
- else {
- uv = zero;
- }
-
- if (attribs->tface[b].gl_texco)
- glTexCoord2fv(uv);
- else
- glVertexAttrib2fvARB(attribs->tface[b].gl_index, uv);
- }
-
- /* vertex colors */
- for (b = 0; b < attribs->totmcol; b++) {
- GLubyte col[4];
-
- if (attribs->mcol[b].array) {
- MCol *cp = &attribs->mcol[b].array[a * 4 + vert];
- col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
- }
- else {
- col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
- }
-
- glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col);
- }
-
- /* tangent for normal mapping */
- if (attribs->tottang) {
- /*const*/ float (*array)[4] = attribs->tang.array;
- const float *tang = (array) ? array[a * 4 + vert] : zero;
- glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
- }
+ DM_draw_attrib_vertex(attribs, a, index, vert);
/* vertex normal */
if (lnor) {
@@ -1270,7 +927,10 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
glShadeModel(GL_SMOOTH);
- if (GPU_buffer_legacy(dm) || setDrawOptions != NULL) {
+ /* workaround for NVIDIA GPUs on Mac not supporting vertex arrays + interleaved formats, see T43342 */
+ if ((GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_MAC, GPU_DRIVER_ANY) && (U.gameflags & USER_DISABLE_VBO)) ||
+ setDrawOptions != NULL)
+ {
DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n");
memset(&attribs, 0, sizeof(attribs));
@@ -1329,11 +989,11 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
ln3 = &lnors[a][2];
ln4 = &lnors[a][3];
}
-
+
cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, ln1, smoothnormal);
cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, ln2, smoothnormal);
cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal);
-
+
if (mface->v4)
cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, ln4, smoothnormal);
else
@@ -1343,218 +1003,215 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
}
else {
GPUBuffer *buffer = NULL;
- const char *varray = NULL;
+ char *varray = NULL;
int numdata = 0, elementsize = 0, offset;
int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
int i;
-
+
const MFace *mf = mface;
GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
memset(&attribs, 0, sizeof(attribs));
-
+
GPU_vertex_setup(dm);
GPU_normal_setup(dm);
-
- if (!GPU_buffer_legacy(dm)) {
- for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) {
-
- a = dm->drawObject->triangle_to_mface[i];
-
- mface = mf + a;
- new_matnr = mface->mat_nr + 1;
-
- if (new_matnr != matnr) {
- numfaces = curface - start;
- if (numfaces > 0) {
-
- if (do_draw) {
-
- if (numdata != 0) {
-
- GPU_buffer_unlock(buffer);
-
- GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
- }
-
- glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3);
-
- if (numdata != 0) {
-
- GPU_buffer_free(buffer);
-
- buffer = NULL;
- }
-
+
+ for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) {
+
+ a = dm->drawObject->triangle_to_mface[i];
+
+ mface = mf + a;
+ new_matnr = mface->mat_nr + 1;
+
+ if (new_matnr != matnr) {
+ numfaces = curface - start;
+ if (numfaces > 0) {
+
+ if (do_draw) {
+
+ if (numdata != 0) {
+
+ GPU_buffer_unlock(buffer);
+
+ GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
}
+
+ glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3);
+
+ if (numdata != 0) {
+
+ GPU_buffer_free(buffer);
+
+ buffer = NULL;
+ }
+
}
- numdata = 0;
- start = curface;
- /* prevdraw = do_draw; */ /* UNUSED */
- do_draw = setMaterial(matnr = new_matnr, &gattribs);
- if (do_draw) {
- DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
-
- if (attribs.totorco && attribs.orco.array) {
- datatypes[numdata].index = attribs.orco.gl_index;
- datatypes[numdata].size = 3;
+ }
+ numdata = 0;
+ start = curface;
+ /* prevdraw = do_draw; */ /* UNUSED */
+ do_draw = setMaterial(matnr = new_matnr, &gattribs);
+ if (do_draw) {
+ DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
+
+ if (attribs.totorco && attribs.orco.array) {
+ datatypes[numdata].index = attribs.orco.gl_index;
+ datatypes[numdata].size = 3;
+ datatypes[numdata].type = GL_FLOAT;
+ numdata++;
+ }
+ for (b = 0; b < attribs.tottface; b++) {
+ if (attribs.tface[b].array) {
+ datatypes[numdata].index = attribs.tface[b].gl_index;
+ datatypes[numdata].size = 2;
datatypes[numdata].type = GL_FLOAT;
numdata++;
}
- for (b = 0; b < attribs.tottface; b++) {
- if (attribs.tface[b].array) {
- datatypes[numdata].index = attribs.tface[b].gl_index;
- datatypes[numdata].size = 2;
- datatypes[numdata].type = GL_FLOAT;
- numdata++;
- }
- }
- for (b = 0; b < attribs.totmcol; b++) {
- if (attribs.mcol[b].array) {
- datatypes[numdata].index = attribs.mcol[b].gl_index;
- datatypes[numdata].size = 4;
- datatypes[numdata].type = GL_UNSIGNED_BYTE;
- numdata++;
- }
- }
- if (attribs.tottang && attribs.tang.array) {
- datatypes[numdata].index = attribs.tang.gl_index;
+ }
+ for (b = 0; b < attribs.totmcol; b++) {
+ if (attribs.mcol[b].array) {
+ datatypes[numdata].index = attribs.mcol[b].gl_index;
datatypes[numdata].size = 4;
- datatypes[numdata].type = GL_FLOAT;
+ datatypes[numdata].type = GL_UNSIGNED_BYTE;
numdata++;
}
- if (numdata != 0) {
- elementsize = GPU_attrib_element_size(datatypes, numdata);
- buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point);
- if (buffer == NULL) {
- GPU_buffer_unbind();
- dm->drawObject->legacy = 1;
- return;
- }
- varray = GPU_buffer_lock_stream(buffer);
- if (varray == NULL) {
- GPU_buffer_unbind();
- GPU_buffer_free(buffer);
- dm->drawObject->legacy = 1;
- return;
- }
+ }
+ if (attribs.tottang && attribs.tang.array) {
+ datatypes[numdata].index = attribs.tang.gl_index;
+ datatypes[numdata].size = 4;
+ datatypes[numdata].type = GL_FLOAT;
+ numdata++;
+ }
+ if (numdata != 0) {
+ elementsize = GPU_attrib_element_size(datatypes, numdata);
+ buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point, false);
+ if (buffer == NULL) {
+ buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point, true);
}
- else {
- /* if the buffer was set, don't use it again.
- * prevdraw was assumed true but didnt run so set to false - [#21036] */
- /* prevdraw = 0; */ /* UNUSED */
- buffer = NULL;
+ varray = GPU_buffer_lock_stream(buffer);
+ if (varray == NULL) {
+ GPU_buffer_unbind();
+ GPU_buffer_free(buffer);
+ fprintf(stderr, "Out of memory, can't draw object\n");
+ return;
}
}
+ else {
+ /* if the buffer was set, don't use it again.
+ * prevdraw was assumed true but didnt run so set to false - [#21036] */
+ /* prevdraw = 0; */ /* UNUSED */
+ buffer = NULL;
+ }
}
-
+ }
+
+ if (do_draw && numdata != 0) {
+ offset = 0;
+ if (attribs.totorco && attribs.orco.array) {
+ copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]);
+ offset += sizeof(float) * 3;
+ }
+ for (b = 0; b < attribs.tottface; b++) {
+ if (attribs.tface[b].array) {
+ MTFace *tf = &attribs.tface[b].array[a];
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]);
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]);
+
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]);
+ offset += sizeof(float) * 2;
+ }
+ }
+ for (b = 0; b < attribs.totmcol; b++) {
+ if (attribs.mcol[b].array) {
+ MCol *cp = &attribs.mcol[b].array[a * 4 + 0];
+ GLubyte col[4];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
+ cp = &attribs.mcol[b].array[a * 4 + 1];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
+ cp = &attribs.mcol[b].array[a * 4 + 2];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
+ offset += sizeof(unsigned char) * 4;
+ }
+ }
+ if (attribs.tottang && attribs.tang.array) {
+ const float *tang = attribs.tang.array[a * 4 + 0];
+ copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
+ tang = attribs.tang.array[a * 4 + 1];
+ copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
+ tang = attribs.tang.array[a * 4 + 2];
+ copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
+ offset += sizeof(float) * 4;
+ }
+ (void)offset;
+ }
+ curface++;
+ if (mface->v4) {
if (do_draw && numdata != 0) {
offset = 0;
if (attribs.totorco && attribs.orco.array) {
- copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]);
- copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]);
- copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]);
offset += sizeof(float) * 3;
}
for (b = 0; b < attribs.tottface; b++) {
if (attribs.tface[b].array) {
MTFace *tf = &attribs.tface[b].array[a];
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]);
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]);
-
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]);
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]);
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]);
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]);
offset += sizeof(float) * 2;
}
}
for (b = 0; b < attribs.totmcol; b++) {
if (attribs.mcol[b].array) {
- MCol *cp = &attribs.mcol[b].array[a * 4 + 0];
+ MCol *cp = &attribs.mcol[b].array[a * 4 + 2];
GLubyte col[4];
col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
- cp = &attribs.mcol[b].array[a * 4 + 1];
+ cp = &attribs.mcol[b].array[a * 4 + 3];
col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
- cp = &attribs.mcol[b].array[a * 4 + 2];
+ cp = &attribs.mcol[b].array[a * 4 + 0];
col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
offset += sizeof(unsigned char) * 4;
}
}
if (attribs.tottang && attribs.tang.array) {
- const float *tang = attribs.tang.array[a * 4 + 0];
+ const float *tang = attribs.tang.array[a * 4 + 2];
copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
- tang = attribs.tang.array[a * 4 + 1];
+ tang = attribs.tang.array[a * 4 + 3];
copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
- tang = attribs.tang.array[a * 4 + 2];
+ tang = attribs.tang.array[a * 4 + 0];
copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
offset += sizeof(float) * 4;
}
(void)offset;
}
curface++;
- if (mface->v4) {
- if (do_draw && numdata != 0) {
- offset = 0;
- if (attribs.totorco && attribs.orco.array) {
- copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]);
- copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]);
- copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]);
- offset += sizeof(float) * 3;
- }
- for (b = 0; b < attribs.tottface; b++) {
- if (attribs.tface[b].array) {
- MTFace *tf = &attribs.tface[b].array[a];
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]);
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]);
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]);
- offset += sizeof(float) * 2;
- }
- }
- for (b = 0; b < attribs.totmcol; b++) {
- if (attribs.mcol[b].array) {
- MCol *cp = &attribs.mcol[b].array[a * 4 + 2];
- GLubyte col[4];
- col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
- copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
- cp = &attribs.mcol[b].array[a * 4 + 3];
- col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
- copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
- cp = &attribs.mcol[b].array[a * 4 + 0];
- col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
- copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
- offset += sizeof(unsigned char) * 4;
- }
- }
- if (attribs.tottang && attribs.tang.array) {
- const float *tang = attribs.tang.array[a * 4 + 2];
- copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
- tang = attribs.tang.array[a * 4 + 3];
- copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
- tang = attribs.tang.array[a * 4 + 0];
- copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
- offset += sizeof(float) * 4;
- }
- (void)offset;
- }
- curface++;
- i++;
- }
+ i++;
}
- numfaces = curface - start;
- if (numfaces > 0) {
- if (do_draw) {
- if (numdata != 0) {
- GPU_buffer_unlock(buffer);
- GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
- }
- glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3);
+ }
+ numfaces = curface - start;
+ if (numfaces > 0) {
+ if (do_draw) {
+ if (numdata != 0) {
+ GPU_buffer_unlock(buffer);
+ GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
}
+ glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3);
}
- GPU_buffer_unbind();
}
+ GPU_buffer_unbind();
+
GPU_buffer_free(buffer);
}
-
+
glShadeModel(GL_FLAT);
}
@@ -1884,6 +1541,7 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->calcNormals = CDDM_calc_normals;
dm->calcLoopNormals = CDDM_calc_loop_normals;
+ dm->calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr;
dm->recalcTessellation = CDDM_recalc_tessellation;
dm->getVertCos = cdDM_getVertCos;
@@ -2500,7 +2158,15 @@ void CDDM_calc_normals(DerivedMesh *dm)
#endif
-void CDDM_calc_loop_normals(DerivedMesh *dm, const float split_angle)
+void CDDM_calc_loop_normals(DerivedMesh *dm, const bool use_split_normals, const float split_angle)
+{
+ CDDM_calc_loop_normals_spacearr(dm, use_split_normals, split_angle, NULL);
+}
+
+/* #define DEBUG_CLNORS */
+
+void CDDM_calc_loop_normals_spacearr(
+ DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr)
{
MVert *mverts = dm->getVertArray(dm);
MEdge *medges = dm->getEdgeArray(dm);
@@ -2510,6 +2176,7 @@ void CDDM_calc_loop_normals(DerivedMesh *dm, const float split_angle)
CustomData *ldata, *pdata;
float (*lnors)[3];
+ short (*clnor_data)[2];
float (*pnors)[3];
const int numVerts = dm->getNumVerts(dm);
@@ -2537,8 +2204,37 @@ void CDDM_calc_loop_normals(DerivedMesh *dm, const float split_angle)
dm->dirty &= ~DM_DIRTY_NORMALS;
+ clnor_data = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL);
+
BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops, lnors, numLoops,
- mpolys, pnors, numPolys, split_angle);
+ mpolys, (const float (*)[3])pnors, numPolys,
+ use_split_normals, split_angle,
+ r_lnors_spacearr, clnor_data, NULL);
+#ifdef DEBUG_CLNORS
+ if (r_lnors_spacearr) {
+ int i;
+ for (i = 0; i < numLoops; i++) {
+ if (r_lnors_spacearr->lspacearr[i]->ref_alpha != 0.0f) {
+ LinkNode *loops = r_lnors_spacearr->lspacearr[i]->loops;
+ printf("Loop %d uses lnor space %p:\n", i, r_lnors_spacearr->lspacearr[i]);
+ print_v3("\tfinal lnor", lnors[i]);
+ print_v3("\tauto lnor", r_lnors_spacearr->lspacearr[i]->vec_lnor);
+ print_v3("\tref_vec", r_lnors_spacearr->lspacearr[i]->vec_ref);
+ printf("\talpha: %f\n\tbeta: %f\n\tloops: %p\n", r_lnors_spacearr->lspacearr[i]->ref_alpha,
+ r_lnors_spacearr->lspacearr[i]->ref_beta, r_lnors_spacearr->lspacearr[i]->loops);
+ printf("\t\t(shared with loops");
+ while (loops) {
+ printf(" %d", GET_INT_FROM_POINTER(loops->link));
+ loops = loops->next;
+ }
+ printf(")\n");
+ }
+ else {
+ printf("Loop %d has no lnor space\n", i);
+ }
+ }
+ }
+#endif
}
@@ -2725,10 +2421,10 @@ static bool poly_gset_compare_fn(const void *k1, const void *k2)
(pk1->totloops == pk2->totloops))
{
/* Equality - note that this does not mean equality of polys */
- return 0;
+ return false;
}
else {
- return 1;
+ return true;
}
}
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index aacf02555d4..3b3fe323f2b 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -47,16 +47,9 @@
#include "BKE_modifier.h"
#include "BKE_pointcache.h"
-// #include "PIL_time.h" /* timing for debug prints */
+#include "BPH_mass_spring.h"
-/* Our available solvers. */
-// 255 is the magic reserved number, so NEVER try to put 255 solvers in here!
-// 254 = MAX!
-static CM_SOLVER_DEF solvers [] =
-{
- { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
- // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free },
-};
+// #include "PIL_time.h" /* timing for debug prints */
/* ********** cloth engine ******* */
/* Prototypes for internal functions.
@@ -68,7 +61,6 @@ static void cloth_update_springs( ClothModifierData *clmd );
static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm );
-
/******************************************************************************
*
* External interface called by modifier.c clothModifier functions.
@@ -89,13 +81,13 @@ void cloth_init(ClothModifierData *clmd )
clmd->sim_parms->structural = 15.0;
clmd->sim_parms->shear = 15.0;
clmd->sim_parms->bending = 0.5;
+ clmd->sim_parms->bending_damping = 0.5;
clmd->sim_parms->Cdis = 5.0;
clmd->sim_parms->Cvi = 1.0;
clmd->sim_parms->mass = 0.3f;
clmd->sim_parms->stepsPerFrame = 5;
clmd->sim_parms->flags = 0;
clmd->sim_parms->solver_type = 0;
- clmd->sim_parms->preroll = 0;
clmd->sim_parms->maxspringlen = 10;
clmd->sim_parms->vgroup_mass = 0;
clmd->sim_parms->vgroup_shrink = 0;
@@ -130,6 +122,8 @@ void cloth_init(ClothModifierData *clmd )
clmd->sim_parms->goalfrict = 0.0f;
clmd->sim_parms->velocity_smooth = 0.0f;
+ clmd->sim_parms->voxel_cell_size = 0.1f;
+
if (!clmd->sim_parms->effector_weights)
clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
@@ -343,7 +337,7 @@ static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
return 0;
}
- implicit_set_positions(clmd);
+ BKE_cloth_solver_set_positions(clmd);
clmd->clothObject->last_frame= MINFRAME-1;
}
@@ -385,8 +379,7 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
// TIMEIT_START(cloth_step)
/* call the solver. */
- if (solvers [clmd->sim_parms->solver_type].solver)
- ret = solvers[clmd->sim_parms->solver_type].solver(ob, framenr, clmd, effectors);
+ ret = BPH_cloth_solve(ob, framenr, clmd, effectors);
// TIMEIT_END(cloth_step)
@@ -469,10 +462,7 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);
clmd->sim_parms->timescale= timescale;
- if (clmd->sim_parms->reset ||
- (framenr == (startframe - clmd->sim_parms->preroll) && clmd->sim_parms->preroll != 0) ||
- (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->numverts))
- {
+ if (clmd->sim_parms->reset || (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->numverts)) {
clmd->sim_parms->reset = 0;
cache->flag |= PTCACHE_OUTDATED;
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
@@ -484,22 +474,6 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
// unused in the moment, calculated separately in implicit.c
clmd->sim_parms->dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
- /* handle continuous simulation with the play button */
- if ((clmd->sim_parms->preroll > 0) && (framenr > startframe - clmd->sim_parms->preroll) && (framenr < startframe)) {
- BKE_ptcache_invalidate(cache);
-
- /* do simulation */
- if (!do_init_cloth(ob, clmd, dm, framenr))
- return;
-
- do_step_cloth(ob, clmd, dm, framenr);
- cloth_to_object(ob, clmd, vertexCos);
-
- clmd->clothObject->last_frame= framenr;
-
- return;
- }
-
/* simulation is only active during a specific period */
if (framenr < startframe) {
BKE_ptcache_invalidate(cache);
@@ -513,7 +487,7 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
if (!do_init_cloth(ob, clmd, dm, framenr))
return;
- if ((framenr == startframe) && (clmd->sim_parms->preroll == 0)) {
+ if (framenr == startframe) {
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
do_init_cloth(ob, clmd, dm, framenr);
BKE_ptcache_validate(cache, framenr);
@@ -526,7 +500,7 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe);
if (cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
- implicit_set_positions(clmd);
+ BKE_cloth_solver_set_positions(clmd);
cloth_to_object (ob, clmd, vertexCos);
BKE_ptcache_validate(cache, framenr);
@@ -539,7 +513,7 @@ void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, Derived
return;
}
else if (cache_result==PTCACHE_READ_OLD) {
- implicit_set_positions(clmd);
+ BKE_cloth_solver_set_positions(clmd);
}
else if ( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
/* if baked and nothing in cache, do nothing */
@@ -581,10 +555,7 @@ void cloth_free_modifier(ClothModifierData *clmd )
if ( cloth ) {
- // If our solver provides a free function, call it
- if ( solvers [clmd->sim_parms->solver_type].free ) {
- solvers [clmd->sim_parms->solver_type].free ( clmd );
- }
+ BPH_cloth_solver_free(clmd);
// Free the verts.
if ( cloth->verts != NULL )
@@ -650,10 +621,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd )
if (G.debug_value > 0)
printf("cloth_free_modifier_extern in\n");
- // If our solver provides a free function, call it
- if ( solvers [clmd->sim_parms->solver_type].free ) {
- solvers [clmd->sim_parms->solver_type].free ( clmd );
- }
+ BPH_cloth_solver_free(clmd);
// Free the verts.
if ( cloth->verts != NULL )
@@ -789,7 +757,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
// Kicking goal factor to simplify things...who uses that anyway?
// ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal );
- verts->goal = powf(verts->goal, 4.0f);
+ verts->goal = pow4f(verts->goal);
if ( verts->goal >= SOFTGOALSNAP )
verts->flags |= CLOTH_VERT_FLAG_PINNED;
}
@@ -812,17 +780,15 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
}
}
- if (clmd->sim_parms->vgroup_shrink > 0 )
- {
- if ( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_shrink-1))
- {
- verts->shrink_factor = clmd->sim_parms->shrink_min*(1.0f-dvert->dw[j].weight)+clmd->sim_parms->shrink_max*dvert->dw [j].weight; // linear interpolation between min and max shrink factor based on weight
+ if (clmd->sim_parms->vgroup_shrink > 0) {
+ if (dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_shrink - 1)) {
+ /* linear interpolation between min and max shrink factor based on weight */
+ verts->shrink_factor = clmd->sim_parms->shrink_min * (1.0f - dvert->dw[j].weight) + clmd->sim_parms->shrink_max * dvert->dw [j].weight;
+ }
+ }
+ else {
+ verts->shrink_factor = clmd->sim_parms->shrink_min;
}
- }
- else {
- verts->shrink_factor = clmd->sim_parms->shrink_min;
- }
-
}
}
}
@@ -931,12 +897,10 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
}
// init our solver
- if ( solvers [clmd->sim_parms->solver_type].init ) {
- solvers [clmd->sim_parms->solver_type].init ( ob, clmd );
- }
+ BPH_cloth_solver_init(ob, clmd);
if (!first)
- implicit_set_positions(clmd);
+ BKE_cloth_solver_set_positions(clmd);
clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel) );
@@ -1068,6 +1032,135 @@ static void cloth_free_errorsprings(Cloth *cloth, LinkNode **edgelist)
}
}
+static void cloth_hair_update_bending_targets(ClothModifierData *clmd)
+{
+ Cloth *cloth = clmd->clothObject;
+ LinkNode *search = NULL;
+ float hair_frame[3][3], dir_old[3], dir_new[3];
+ int prev_mn; /* to find hair chains */
+
+ if (!clmd->hairdata)
+ return;
+
+ /* XXX Note: we need to propagate frames from the root up,
+ * but structural hair springs are stored in reverse order.
+ * The bending springs however are then inserted in the same
+ * order as vertices again ...
+ * This messy situation can be resolved when solver data is
+ * generated directly from a dedicated hair system.
+ */
+
+ prev_mn = -1;
+ for (search = cloth->springs; search; search = search->next) {
+ ClothSpring *spring = search->link;
+ ClothHairData *hair_ij, *hair_kl;
+ bool is_root = spring->kl != prev_mn;
+
+ if (spring->type != CLOTH_SPRING_TYPE_BENDING_ANG) {
+ continue;
+ }
+
+ hair_ij = &clmd->hairdata[spring->ij];
+ hair_kl = &clmd->hairdata[spring->kl];
+ if (is_root) {
+ /* initial hair frame from root orientation */
+ copy_m3_m3(hair_frame, hair_ij->rot);
+ /* surface normal is the initial direction,
+ * parallel transport then keeps it aligned to the hair direction
+ */
+ copy_v3_v3(dir_new, hair_frame[2]);
+ }
+
+ copy_v3_v3(dir_old, dir_new);
+ sub_v3_v3v3(dir_new, cloth->verts[spring->mn].x, cloth->verts[spring->kl].x);
+ normalize_v3(dir_new);
+
+#if 0
+ if (clmd->debug_data && (spring->ij == 0 || spring->ij == 1)) {
+ float a[3], b[3];
+
+ copy_v3_v3(a, cloth->verts[spring->kl].x);
+// BKE_sim_debug_data_add_dot(clmd->debug_data, cloth_vert ? cloth_vert->x : key->co, 1, 1, 0, "frames", 8246, p, k);
+
+ mul_v3_v3fl(b, hair_frame[0], clmd->sim_parms->avg_spring_len);
+ BKE_sim_debug_data_add_vector(clmd->debug_data, a, b, 1, 0, 0, "frames", 8247, spring->kl, spring->mn);
+
+ mul_v3_v3fl(b, hair_frame[1], clmd->sim_parms->avg_spring_len);
+ BKE_sim_debug_data_add_vector(clmd->debug_data, a, b, 0, 1, 0, "frames", 8248, spring->kl, spring->mn);
+
+ mul_v3_v3fl(b, hair_frame[2], clmd->sim_parms->avg_spring_len);
+ BKE_sim_debug_data_add_vector(clmd->debug_data, a, b, 0, 0, 1, "frames", 8249, spring->kl, spring->mn);
+ }
+#endif
+
+ /* get local targets for kl/mn vertices by putting rest targets into the current frame,
+ * then multiply with the rest length to get the actual goals
+ */
+
+ mul_v3_m3v3(spring->target, hair_frame, hair_kl->rest_target);
+ mul_v3_fl(spring->target, spring->restlen);
+
+ /* move frame to next hair segment */
+ cloth_parallel_transport_hair_frame(hair_frame, dir_old, dir_new);
+
+ prev_mn = spring->mn;
+ }
+}
+
+static void cloth_hair_update_bending_rest_targets(ClothModifierData *clmd)
+{
+ Cloth *cloth = clmd->clothObject;
+ LinkNode *search = NULL;
+ float hair_frame[3][3], dir_old[3], dir_new[3];
+ int prev_mn; /* to find hair roots */
+
+ if (!clmd->hairdata)
+ return;
+
+ /* XXX Note: we need to propagate frames from the root up,
+ * but structural hair springs are stored in reverse order.
+ * The bending springs however are then inserted in the same
+ * order as vertices again ...
+ * This messy situation can be resolved when solver data is
+ * generated directly from a dedicated hair system.
+ */
+
+ prev_mn = -1;
+ for (search = cloth->springs; search; search = search->next) {
+ ClothSpring *spring = search->link;
+ ClothHairData *hair_ij, *hair_kl;
+ bool is_root = spring->kl != prev_mn;
+
+ if (spring->type != CLOTH_SPRING_TYPE_BENDING_ANG) {
+ continue;
+ }
+
+ hair_ij = &clmd->hairdata[spring->ij];
+ hair_kl = &clmd->hairdata[spring->kl];
+ if (is_root) {
+ /* initial hair frame from root orientation */
+ copy_m3_m3(hair_frame, hair_ij->rot);
+ /* surface normal is the initial direction,
+ * parallel transport then keeps it aligned to the hair direction
+ */
+ copy_v3_v3(dir_new, hair_frame[2]);
+ }
+
+ copy_v3_v3(dir_old, dir_new);
+ sub_v3_v3v3(dir_new, cloth->verts[spring->mn].xrest, cloth->verts[spring->kl].xrest);
+ normalize_v3(dir_new);
+
+ /* dir expressed in the hair frame defines the rest target direction */
+ copy_v3_v3(hair_kl->rest_target, dir_new);
+ mul_transposed_m3_v3(hair_frame, hair_kl->rest_target);
+
+ /* move frame to next hair segment */
+ cloth_parallel_transport_hair_frame(hair_frame, dir_old, dir_new);
+
+ prev_mn = spring->mn;
+ }
+}
+
/* update stiffness if vertex group values are changing from frame to frame */
static void cloth_update_springs( ClothModifierData *clmd )
{
@@ -1089,6 +1182,16 @@ static void cloth_update_springs( ClothModifierData *clmd )
else if (spring->type == CLOTH_SPRING_TYPE_BENDING) {
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f;
}
+ else if (spring->type == CLOTH_SPRING_TYPE_BENDING_ANG) {
+ ClothVertex *v1 = &cloth->verts[spring->ij];
+ ClothVertex *v2 = &cloth->verts[spring->kl];
+ if (clmd->hairdata) {
+ /* copy extra hair data to generic cloth vertices */
+ v1->bend_stiff = clmd->hairdata[spring->ij].bending_stiffness;
+ v2->bend_stiff = clmd->hairdata[spring->kl].bending_stiffness;
+ }
+ spring->stiffness = (v1->bend_stiff + v2->bend_stiff) / 2.0f;
+ }
else if (spring->type == CLOTH_SPRING_TYPE_GOAL) {
/* Warning: Appending NEW goal springs does not work because implicit solver would need reset! */
@@ -1105,8 +1208,43 @@ static void cloth_update_springs( ClothModifierData *clmd )
search = search->next;
}
+
+ cloth_hair_update_bending_targets(clmd);
+}
+BLI_INLINE void cross_identity_v3(float r[3][3], const float v[3])
+{
+ zero_m3(r);
+ r[0][1] = v[2];
+ r[0][2] = -v[1];
+ r[1][0] = -v[2];
+ r[1][2] = v[0];
+ r[2][0] = v[1];
+ r[2][1] = -v[0];
+}
+
+BLI_INLINE void madd_m3_m3fl(float r[3][3], float m[3][3], float f)
+{
+ r[0][0] += m[0][0] * f;
+ r[0][1] += m[0][1] * f;
+ r[0][2] += m[0][2] * f;
+ r[1][0] += m[1][0] * f;
+ r[1][1] += m[1][1] * f;
+ r[1][2] += m[1][2] * f;
+ r[2][0] += m[2][0] * f;
+ r[2][1] += m[2][1] * f;
+ r[2][2] += m[2][2] * f;
+}
+void cloth_parallel_transport_hair_frame(float mat[3][3], const float dir_old[3], const float dir_new[3])
+{
+ float rot[3][3];
+
+ /* rotation between segments */
+ rotation_between_vecs_to_mat3(rot, dir_old, dir_new);
+
+ /* rotate the frame */
+ mul_m3_m3m3(mat, rot, mat);
}
static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
@@ -1283,40 +1421,74 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
}
}
else if (struct_springs > 2) {
- /* bending springs for hair strands */
- /* The current algorightm only goes through the edges in order of the mesh edges list */
- /* and makes springs between the outer vert of edges sharing a vertice. This works just */
- /* fine for hair, but not for user generated string meshes. This could/should be later */
- /* extended to work with non-ordered edges so that it can be used for general "rope */
- /* dynamics" without the need for the vertices or edges to be ordered through the length*/
- /* of the strands. -jahka */
- search = cloth->springs;
- search2 = search->next;
- while (search && search2) {
- tspring = search->link;
- tspring2 = search2->link;
-
- if (tspring->ij == tspring2->kl) {
- spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+ if (G.debug_value != 1112) {
+ search = cloth->springs;
+ search2 = search->next;
+ while (search && search2) {
+ tspring = search->link;
+ tspring2 = search2->link;
+
+ if (tspring->ij == tspring2->kl) {
+ spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+
+ if (!spring) {
+ cloth_free_errorsprings(cloth, edgelist);
+ return 0;
+ }
+
+ spring->ij = tspring2->ij;
+ spring->kl = tspring->ij;
+ spring->mn = tspring->kl;
+ spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest);
+ spring->type = CLOTH_SPRING_TYPE_BENDING_ANG;
+ spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f;
+ bend_springs++;
+
+ BLI_linklist_prepend ( &cloth->springs, spring );
+ }
+
+ search = search->next;
+ search2 = search2->next;
+ }
+ }
+ else {
+ /* bending springs for hair strands */
+ /* The current algorightm only goes through the edges in order of the mesh edges list */
+ /* and makes springs between the outer vert of edges sharing a vertice. This works just */
+ /* fine for hair, but not for user generated string meshes. This could/should be later */
+ /* extended to work with non-ordered edges so that it can be used for general "rope */
+ /* dynamics" without the need for the vertices or edges to be ordered through the length*/
+ /* of the strands. -jahka */
+ search = cloth->springs;
+ search2 = search->next;
+ while (search && search2) {
+ tspring = search->link;
+ tspring2 = search2->link;
- if (!spring) {
- cloth_free_errorsprings(cloth, edgelist);
- return 0;
+ if (tspring->ij == tspring2->kl) {
+ spring = (ClothSpring *)MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+
+ if (!spring) {
+ cloth_free_errorsprings(cloth, edgelist);
+ return 0;
+ }
+
+ spring->ij = tspring2->ij;
+ spring->kl = tspring->kl;
+ spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest);
+ spring->type = CLOTH_SPRING_TYPE_BENDING;
+ spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f;
+ bend_springs++;
+
+ BLI_linklist_prepend ( &cloth->springs, spring );
}
-
- spring->ij = tspring2->ij;
- spring->kl = tspring->kl;
- spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest);
- spring->type = CLOTH_SPRING_TYPE_BENDING;
- spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0f;
- bend_springs++;
-
- BLI_linklist_prepend ( &cloth->springs, spring );
+
+ search = search->next;
+ search2 = search2->next;
}
-
- search = search->next;
- search2 = search2->next;
}
+
+ cloth_hair_update_bending_rest_targets(clmd);
}
/* note: the edges may already exist so run reinsert */
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 2f600935b1e..6b8eac44dfa 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -33,6 +33,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_cloth_types.h"
+#include "DNA_effect_types.h"
#include "DNA_group_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
@@ -45,6 +46,7 @@
#include "BLI_edgehash.h"
#include "BKE_cloth.h"
+#include "BKE_effect.h"
#include "BKE_modifier.h"
#include "BKE_scene.h"
@@ -648,12 +650,12 @@ static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, Collis
{
int i;
- *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 64, "collision array" ); // * 4 since cloth_collision_static can return more than 1 collision
+ *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 4, "collision array" ); // * 4 since cloth_collision_static can return more than 1 collision
*collisions_index = *collisions;
for ( i = 0; i < numresult; i++ ) {
- *collisions_index = cloth_collision ( (ModifierData *)clmd, (ModifierData *)collmd,
- overlap+i, *collisions_index, dt );
+ *collisions_index = cloth_collision((ModifierData *)clmd, (ModifierData *)collmd,
+ overlap+i, *collisions_index, dt);
}
}
@@ -913,3 +915,558 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, floa
return 1|MIN2 ( ret, 1 );
}
+
+BLI_INLINE void max_v3_v3v3(float r[3], const float a[3], const float b[3])
+{
+ r[0] = max_ff(a[0], b[0]);
+ r[1] = max_ff(a[1], b[1]);
+ r[2] = max_ff(a[2], b[2]);
+}
+
+void collision_get_collider_velocity(float vel_old[3], float vel_new[3], CollisionModifierData *collmd, CollPair *collpair)
+{
+ float u1, u2, u3;
+
+ /* compute barycentric coordinates */
+ collision_compute_barycentric(collpair->pb,
+ collmd->current_x[collpair->bp1].co,
+ collmd->current_x[collpair->bp2].co,
+ collmd->current_x[collpair->bp3].co,
+ &u1, &u2, &u3);
+
+ collision_interpolateOnTriangle(vel_new, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3);
+ /* XXX assume constant velocity of the collider for now */
+ copy_v3_v3(vel_old, vel_new);
+}
+
+static bool cloth_points_collision_response_static(ClothModifierData *clmd, CollisionModifierData *collmd, PartDeflect *pd,
+ CollPair *collpair, CollPair *collision_end, float dt)
+{
+ bool result = false;
+ float restitution = (1.0f - clmd->coll_parms->damping) * (1.0f - pd->pdef_sbdamp);
+ float inv_dt = 1.0f / dt;
+ Cloth *cloth1 = clmd->clothObject;
+
+ // float w1, w2;
+ float u1, u2, u3;
+ float v1[3], v2_old[3], v2_new[3], v_rel_old[3], v_rel_new[3];
+ float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
+
+ for ( ; collpair != collision_end; collpair++ ) {
+ float margin_distance = collpair->distance - epsilon2;
+ float impulse[3];
+ float mag_v_rel;
+
+ if (margin_distance > 0.0f)
+ continue;
+
+ zero_v3(impulse);
+
+ /* only handle static collisions here */
+ if ( collpair->flag & COLLISION_IN_FUTURE )
+ continue;
+
+ /* compute barycentric coordinates for both collision points */
+ // w1 = 1.0f - collpair->time;
+ // w2 = collpair->time;
+
+ /* was: txold */
+ collision_compute_barycentric ( collpair->pb,
+ collmd->current_x[collpair->bp1].co,
+ collmd->current_x[collpair->bp2].co,
+ collmd->current_x[collpair->bp3].co,
+ &u1, &u2, &u3 );
+
+ /* Calculate relative velocity */
+ copy_v3_v3(v1, cloth1->verts[collpair->ap1].tv);
+
+ collision_interpolateOnTriangle ( v2_new, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3 );
+ /* XXX assume constant velocity of the collider for now */
+ copy_v3_v3(v2_old, v2_new);
+
+ sub_v3_v3v3(v_rel_old, v1, v2_old);
+ sub_v3_v3v3(v_rel_new, v1, v2_new);
+
+ /* normal component of the relative velocity */
+ mag_v_rel = dot_v3v3(v_rel_old, collpair->normal);
+
+ /**** DEBUG ****/
+ BKE_sim_debug_data_add_dot(collpair->pa, 0.9, 0.2, 0.2, "collision", 833, collpair->face1, collpair->face2);
+ BKE_sim_debug_data_add_dot(collpair->pb, 0.2, 0.9, 0.2, "collision", 834, collpair->face1, collpair->face2);
+ BKE_sim_debug_data_add_line(collpair->pa, collpair->pb, 0.8, 0.8, 0.8, "collision", 835, collpair->face1, collpair->face2);
+ /********/
+
+ if (mag_v_rel < -ALMOST_ZERO) {
+ float v_nor_old, v_nor_new;
+ float v_tan_old[3], v_tan_new[3];
+ float bounce, repulse;
+
+ /* Collision response based on
+ * "Simulating Complex Hair with Robust Collision Handling" (Choe, Choi, Ko, ACM SIGGRAPH 2005)
+ * http://graphics.snu.ac.kr/publications/2005-choe-HairSim/Choe_2005_SCA.pdf
+ */
+
+ v_nor_old = mag_v_rel;
+ v_nor_new = dot_v3v3(v_rel_new, collpair->normal);
+
+ madd_v3_v3v3fl(v_tan_old, v_rel_old, collpair->normal, -v_nor_old);
+ madd_v3_v3v3fl(v_tan_new, v_rel_new, collpair->normal, -v_nor_new);
+
+ repulse = -margin_distance * inv_dt + dot_v3v3(v1, collpair->normal);
+
+ if (margin_distance < -epsilon2) {
+ bounce = -v_nor_new + v_nor_old * restitution;
+ mul_v3_v3fl(impulse, collpair->normal, max_ff(repulse, bounce));
+ }
+ else {
+ bounce = 0.0f;
+ mul_v3_v3fl(impulse, collpair->normal, repulse);
+ }
+ cloth1->verts[collpair->ap1].impulse_count++;
+
+ result = true;
+ }
+
+ if (result) {
+ int i = 0;
+
+ for (i = 0; i < 3; i++) {
+ if (cloth1->verts[collpair->ap1].impulse_count > 0 && fabsf(cloth1->verts[collpair->ap1].impulse[i]) < fabsf(impulse[i]))
+ cloth1->verts[collpair->ap1].impulse[i] = impulse[i];
+ }
+ }
+ }
+ return result;
+}
+
+BLI_INLINE bool cloth_point_face_collision_params(const float p1[3], const float p2[3], const float v0[3], const float v1[3], const float v2[3],
+ float r_nor[3], float *r_lambda, float r_w[4])
+{
+ float edge1[3], edge2[3], p2face[3], p1p2[3], v0p2[3];
+ float nor_v0p2, nor_p1p2;
+
+ sub_v3_v3v3(edge1, v1, v0);
+ sub_v3_v3v3(edge2, v2, v0);
+ cross_v3_v3v3(r_nor, edge1, edge2);
+ normalize_v3(r_nor);
+
+ nor_v0p2 = dot_v3v3(v0p2, r_nor);
+ madd_v3_v3v3fl(p2face, p2, r_nor, -nor_v0p2);
+ interp_weights_face_v3(r_w, v0, v1, v2, NULL, p2face);
+
+ sub_v3_v3v3(p1p2, p2, p1);
+ sub_v3_v3v3(v0p2, p2, v0);
+ nor_p1p2 = dot_v3v3(p1p2, r_nor);
+ *r_lambda = (nor_p1p2 != 0.0f ? nor_v0p2 / nor_p1p2 : 0.0f);
+
+ return r_w[1] >= 0.0f && r_w[2] >= 0.0f && r_w[1] + r_w[2] <= 1.0f;
+
+#if 0 /* XXX this method uses the intersection point, but is broken and doesn't work well in general */
+ float p[3], vec1[3], line[3], edge1[3], edge2[3], q[3];
+ float a, f, u, v;
+
+ sub_v3_v3v3(edge1, v1, v0);
+ sub_v3_v3v3(edge2, v2, v0);
+ sub_v3_v3v3(line, p2, p1);
+
+ cross_v3_v3v3(p, line, edge2);
+ a = dot_v3v3(edge1, p);
+ if (a == 0.0f) return 0;
+ f = 1.0f / a;
+
+ sub_v3_v3v3(vec1, p1, v0);
+
+ u = f * dot_v3v3(vec1, p);
+ if ((u < 0.0f) || (u > 1.0f))
+ return false;
+
+ cross_v3_v3v3(q, vec1, edge1);
+
+ v = f * dot_v3v3(line, q);
+ if ((v < 0.0f) || ((u + v) > 1.0f))
+ return false;
+
+ *r_lambda = f * dot_v3v3(edge2, q);
+ /* don't care about 0..1 lambda range here */
+ /*if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f))
+ * return 0;
+ */
+
+ r_w[0] = 1.0f - u - v;
+ r_w[1] = u;
+ r_w[2] = v;
+ r_w[3] = 0.0f;
+
+ cross_v3_v3v3(r_nor, edge1, edge2);
+ normalize_v3(r_nor);
+
+ return true;
+#endif
+}
+
+static CollPair *cloth_point_collpair(float p1[3], float p2[3], MVert *mverts, int bp1, int bp2, int bp3,
+ int index_cloth, int index_coll, float epsilon, CollPair *collpair)
+{
+ float *co1 = mverts[bp1].co, *co2 = mverts[bp2].co, *co3 = mverts[bp3].co;
+ float lambda /*, distance1 */, distance2;
+ float facenor[3], v1p1[3], v1p2[3];
+ float w[4];
+
+ if (!cloth_point_face_collision_params(p1, p2, co1, co2, co3, facenor, &lambda, w))
+ return collpair;
+
+ sub_v3_v3v3(v1p1, p1, co1);
+// distance1 = dot_v3v3(v1p1, facenor);
+ sub_v3_v3v3(v1p2, p2, co1);
+ distance2 = dot_v3v3(v1p2, facenor);
+// if (distance2 > epsilon || (distance1 < 0.0f && distance2 < 0.0f))
+ if (distance2 > epsilon)
+ return collpair;
+
+ collpair->face1 = index_cloth; /* XXX actually not a face, but equivalent index for point */
+ collpair->face2 = index_coll;
+ collpair->ap1 = index_cloth;
+ collpair->ap2 = collpair->ap3 = -1; /* unused */
+ collpair->bp1 = bp1;
+ collpair->bp2 = bp2;
+ collpair->bp3 = bp3;
+
+ /* note: using the second point here, which is
+ * the current updated position that needs to be corrected
+ */
+ copy_v3_v3(collpair->pa, p2);
+ collpair->distance = distance2;
+ mul_v3_v3fl(collpair->vector, facenor, -distance2);
+
+ interp_v3_v3v3v3(collpair->pb, co1, co2, co3, w);
+
+ copy_v3_v3(collpair->normal, facenor);
+ collpair->time = lambda;
+ collpair->flag = 0;
+
+ collpair++;
+ return collpair;
+}
+
+//Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned
+static CollPair* cloth_point_collision(ModifierData *md1, ModifierData *md2,
+ BVHTreeOverlap *overlap, float epsilon, CollPair *collpair, float UNUSED(dt))
+{
+ ClothModifierData *clmd = (ClothModifierData *)md1;
+ CollisionModifierData *collmd = (CollisionModifierData *) md2;
+ /* Cloth *cloth = clmd->clothObject; */ /* UNUSED */
+ ClothVertex *vert = NULL;
+ MFace *face = NULL;
+ MVert *mverts = collmd->current_x;
+
+ vert = &clmd->clothObject->verts[overlap->indexA];
+ face = &collmd->mfaces[overlap->indexB];
+
+ collpair = cloth_point_collpair(vert->tx, vert->x, mverts, face->v1, face->v2, face->v3, overlap->indexA, overlap->indexB, epsilon, collpair);
+ if (face->v4)
+ collpair = cloth_point_collpair(vert->tx, vert->x, mverts, face->v3, face->v4, face->v1, overlap->indexA, overlap->indexB, epsilon, collpair);
+
+ return collpair;
+}
+
+static void cloth_points_objcollisions_nearcheck(ClothModifierData * clmd, CollisionModifierData *collmd,
+ CollPair **collisions, CollPair **collisions_index,
+ int numresult, BVHTreeOverlap *overlap, float epsilon, double dt)
+{
+ int i;
+
+ /* can return 2 collisions in total */
+ *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 2, "collision array" );
+ *collisions_index = *collisions;
+
+ for ( i = 0; i < numresult; i++ ) {
+ *collisions_index = cloth_point_collision((ModifierData *)clmd, (ModifierData *)collmd,
+ overlap+i, epsilon, *collisions_index, dt);
+ }
+}
+
+static int cloth_points_objcollisions_resolve(ClothModifierData * clmd, CollisionModifierData *collmd, PartDeflect *pd,
+ CollPair *collisions, CollPair *collisions_index, float dt)
+{
+ Cloth *cloth = clmd->clothObject;
+ int i=0, numverts = clmd->clothObject->numverts;
+ ClothVertex *verts = cloth->verts;
+ int ret = 0;
+
+ // process all collisions
+ if ( collmd->bvhtree ) {
+ bool result = cloth_points_collision_response_static(clmd, collmd, pd, collisions, collisions_index, dt);
+
+ // apply impulses in parallel
+ if (result) {
+ for (i = 0; i < numverts; i++) {
+ // calculate "velocities" (just xnew = xold + v; no dt in v)
+ if (verts[i].impulse_count) {
+ // VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
+ VECADD ( verts[i].tv, verts[i].tv, verts[i].impulse);
+ zero_v3(verts[i].impulse);
+ verts[i].impulse_count = 0;
+
+ ret++;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+// cloth - object collisions
+int cloth_points_objcollision(Object *ob, ClothModifierData *clmd, float step, float dt)
+{
+ Cloth *cloth= clmd->clothObject;
+ BVHTree *cloth_bvh;
+ int rounds = 0; // result counts applied collisions; ic is for debug output;
+ float round_dt = dt / (float)clmd->coll_parms->loop_count;
+ unsigned int i=0, numverts = 0;
+ ClothVertex *verts = NULL;
+ int ret = 0, ret2 = 0;
+ Object **collobjs = NULL;
+ unsigned int numcollobj = 0;
+
+ verts = cloth->verts;
+ numverts = cloth->numverts;
+
+ ////////////////////////////////////////////////////////////
+ // static collisions
+ ////////////////////////////////////////////////////////////
+
+ // create temporary cloth points bvh
+ cloth_bvh = BLI_bvhtree_new(numverts, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel), 4, 6);
+ /* fill tree */
+ for (i = 0; i < numverts; i++) {
+ float co[6];
+
+ copy_v3_v3(&co[0*3], verts[i].x);
+ copy_v3_v3(&co[1*3], verts[i].tx);
+
+ BLI_bvhtree_insert(cloth_bvh, i, co, 2);
+ }
+ /* balance tree */
+ BLI_bvhtree_balance(cloth_bvh);
+
+ collobjs = get_collisionobjects(clmd->scene, ob, clmd->coll_parms->group, &numcollobj, eModifierType_Collision);
+ if (!collobjs)
+ return 0;
+
+ /* move object to position (step) in time */
+ for (i = 0; i < numcollobj; i++) {
+ Object *collob= collobjs[i];
+ CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
+ if (!collmd->bvhtree)
+ continue;
+
+ /* move object to position (step) in time */
+ collision_move_object ( collmd, step + dt, step );
+ }
+
+ do {
+ CollPair **collisions, **collisions_index;
+
+ ret2 = 0;
+
+ collisions = MEM_callocN(sizeof(CollPair *) *numcollobj, "CollPair");
+ collisions_index = MEM_callocN(sizeof(CollPair *) *numcollobj, "CollPair");
+
+ // check all collision objects
+ for (i = 0; i < numcollobj; i++) {
+ Object *collob= collobjs[i];
+ CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
+ BVHTreeOverlap *overlap = NULL;
+ unsigned int result = 0;
+ float epsilon;
+
+ if (!collmd->bvhtree)
+ continue;
+
+ /* search for overlapping collision pairs */
+ overlap = BLI_bvhtree_overlap ( cloth_bvh, collmd->bvhtree, &result );
+ epsilon = BLI_bvhtree_getepsilon(collmd->bvhtree);
+
+ // go to next object if no overlap is there
+ if (result && overlap) {
+ /* check if collisions really happen (costly near check) */
+ cloth_points_objcollisions_nearcheck(clmd, collmd, &collisions[i], &collisions_index[i],
+ result, overlap, epsilon, round_dt);
+
+ // resolve nearby collisions
+ ret += cloth_points_objcollisions_resolve(clmd, collmd, collob->pd, collisions[i], collisions_index[i], round_dt);
+ ret2 += ret;
+ }
+
+ if (overlap)
+ MEM_freeN ( overlap );
+ }
+ rounds++;
+
+ for (i = 0; i < numcollobj; i++) {
+ if (collisions[i])
+ MEM_freeN(collisions[i]);
+ }
+
+ MEM_freeN(collisions);
+ MEM_freeN(collisions_index);
+
+ ////////////////////////////////////////////////////////////
+ // update positions
+ // this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
+ ////////////////////////////////////////////////////////////
+
+ // verts come from clmd
+ for ( i = 0; i < numverts; i++ ) {
+ if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) {
+ if ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) {
+ continue;
+ }
+ }
+
+ VECADD ( verts[i].tx, verts[i].txold, verts[i].tv );
+ }
+ ////////////////////////////////////////////////////////////
+ }
+ while ( ret2 && ( clmd->coll_parms->loop_count>rounds ) );
+
+ if (collobjs)
+ MEM_freeN(collobjs);
+
+ BLI_bvhtree_free(cloth_bvh);
+
+ return 1|MIN2 ( ret, 1 );
+}
+
+void cloth_find_point_contacts(Object *ob, ClothModifierData *clmd, float step, float dt,
+ ColliderContacts **r_collider_contacts, int *r_totcolliders)
+{
+ Cloth *cloth= clmd->clothObject;
+ BVHTree *cloth_bvh;
+ unsigned int i=0, numverts = 0;
+ ClothVertex *verts = NULL;
+
+ ColliderContacts *collider_contacts;
+
+ Object **collobjs = NULL;
+ unsigned int numcollobj = 0;
+
+ verts = cloth->verts;
+ numverts = cloth->numverts;
+
+ ////////////////////////////////////////////////////////////
+ // static collisions
+ ////////////////////////////////////////////////////////////
+
+ // create temporary cloth points bvh
+ cloth_bvh = BLI_bvhtree_new(numverts, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel), 4, 6);
+ /* fill tree */
+ for (i = 0; i < numverts; i++) {
+ float co[6];
+
+ copy_v3_v3(&co[0*3], verts[i].x);
+ copy_v3_v3(&co[1*3], verts[i].tx);
+
+ BLI_bvhtree_insert(cloth_bvh, i, co, 2);
+ }
+ /* balance tree */
+ BLI_bvhtree_balance(cloth_bvh);
+
+ collobjs = get_collisionobjects(clmd->scene, ob, clmd->coll_parms->group, &numcollobj, eModifierType_Collision);
+ if (!collobjs) {
+ *r_collider_contacts = NULL;
+ *r_totcolliders = 0;
+ return;
+ }
+
+ /* move object to position (step) in time */
+ for (i = 0; i < numcollobj; i++) {
+ Object *collob= collobjs[i];
+ CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
+ if (!collmd->bvhtree)
+ continue;
+
+ /* move object to position (step) in time */
+ collision_move_object ( collmd, step + dt, step );
+ }
+
+ collider_contacts = MEM_callocN(sizeof(ColliderContacts) * numcollobj, "CollPair");
+
+ // check all collision objects
+ for (i = 0; i < numcollobj; i++) {
+ ColliderContacts *ct = collider_contacts + i;
+ Object *collob= collobjs[i];
+ CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
+ BVHTreeOverlap *overlap;
+ unsigned int result = 0;
+ float epsilon;
+
+ ct->ob = collob;
+ ct->collmd = collmd;
+ ct->collisions = NULL;
+ ct->totcollisions = 0;
+
+ if (!collmd->bvhtree)
+ continue;
+
+ /* search for overlapping collision pairs */
+ overlap = BLI_bvhtree_overlap(cloth_bvh, collmd->bvhtree, &result);
+ epsilon = BLI_bvhtree_getepsilon(collmd->bvhtree);
+
+ // go to next object if no overlap is there
+ if (result && overlap) {
+ CollPair *collisions_index;
+
+ /* check if collisions really happen (costly near check) */
+ cloth_points_objcollisions_nearcheck(clmd, collmd, &ct->collisions, &collisions_index,
+ result, overlap, epsilon, dt);
+ ct->totcollisions = (int)(collisions_index - ct->collisions);
+
+ // resolve nearby collisions
+// ret += cloth_points_objcollisions_resolve(clmd, collmd, collob->pd, collisions[i], collisions_index[i], dt);
+ }
+
+ if (overlap)
+ MEM_freeN(overlap);
+ }
+
+ if (collobjs)
+ MEM_freeN(collobjs);
+
+ BLI_bvhtree_free(cloth_bvh);
+
+ ////////////////////////////////////////////////////////////
+ // update positions
+ // this is needed for bvh_calc_DOP_hull_moving() [kdop.c]
+ ////////////////////////////////////////////////////////////
+
+ // verts come from clmd
+ for (i = 0; i < numverts; i++) {
+ if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) {
+ if (verts [i].flags & CLOTH_VERT_FLAG_PINNED) {
+ continue;
+ }
+ }
+
+ VECADD(verts[i].tx, verts[i].txold, verts[i].tv);
+ }
+ ////////////////////////////////////////////////////////////
+
+ *r_collider_contacts = collider_contacts;
+ *r_totcolliders = numcollobj;
+}
+
+void cloth_free_contacts(ColliderContacts *collider_contacts, int totcolliders)
+{
+ if (collider_contacts) {
+ int i;
+ for (i = 0; i < totcolliders; ++i) {
+ ColliderContacts *ct = collider_contacts + i;
+ if (ct->collisions) {
+ MEM_freeN(ct->collisions);
+ }
+ }
+ MEM_freeN(collider_contacts);
+ }
+}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index a63e06c7cb8..89c3e4b0cfc 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -50,7 +50,6 @@
#include "IMB_colormanagement.h"
-#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
/* ********************************* color curve ********************* */
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 8a5d313e3fb..c38a1239f12 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -79,6 +79,8 @@
#include "BKE_tracking.h"
#include "BKE_movieclip.h"
+#include "BIK_api.h"
+
#ifdef WITH_PYTHON
# include "BPY_extern.h"
#endif
@@ -229,7 +231,8 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
* of a matrix from one space to another for constraint evaluation.
* For now, this is only implemented for Objects and PoseChannels.
*/
-void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to)
+void BKE_constraint_mat_convertspace(
+ Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to, const bool keep_scale)
{
float diff_mat[4][4];
float imat[4][4];
@@ -252,7 +255,7 @@ void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[
/* use pose-space as stepping stone for other spaces... */
if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
/* call self with slightly different values */
- BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
}
break;
}
@@ -288,7 +291,7 @@ void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[
/* use pose-space as stepping stone for other spaces */
if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
/* call self with slightly different values */
- BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
}
break;
}
@@ -303,7 +306,7 @@ void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[
/* use pose-space as stepping stone for other spaces */
if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
/* call self with slightly different values */
- BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
}
break;
}
@@ -323,8 +326,17 @@ void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[
/* Local space in this case will have to be defined as local to the owner's
* transform-property-rotated axes. So subtract this rotation component.
*/
+ /* XXX This is actually an ugly hack, local space of a parent-less object *is* the same as
+ * global space!
+ * Think what we want actually here is some kind of 'Final Space', i.e. once transformations
+ * are applied - users are often confused about this too, this is not consistent with bones
+ * local space either... Meh :|
+ * --mont29
+ */
BKE_object_to_mat4(ob, diff_mat);
- normalize_m4(diff_mat);
+ if (!keep_scale) {
+ normalize_m4(diff_mat);
+ }
zero_v3(diff_mat[3]);
invert_m4_m4_safe(imat, diff_mat);
@@ -342,8 +354,11 @@ void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[
/* Local space in this case will have to be defined as local to the owner's
* transform-property-rotated axes. So add back this rotation component.
*/
+ /* XXX See comment above for world->local case... */
BKE_object_to_mat4(ob, diff_mat);
- normalize_m4(diff_mat);
+ if (!keep_scale) {
+ normalize_m4(diff_mat);
+ }
zero_v3(diff_mat[3]);
mul_m4_m4m4(mat, diff_mat, mat);
@@ -511,7 +526,7 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m
/* Case OBJECT */
if (!strlen(substring)) {
copy_m4_m4(mat, ob->obmat);
- BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
}
/* Case VERTEXGROUP */
/* Current method just takes the average location of all the points in the
@@ -524,11 +539,11 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m
*/
else if (ob->type == OB_MESH) {
contarget_get_mesh_mat(ob, substring, mat);
- BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
}
else if (ob->type == OB_LATTICE) {
contarget_get_lattice_mat(ob, substring, mat);
- BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
}
/* Case BONE */
else {
@@ -561,7 +576,7 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m
copy_m4_m4(mat, ob->obmat);
/* convert matrix space as required */
- BKE_constraint_mat_convertspace(ob, pchan, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, from, to, false);
}
}
@@ -1971,7 +1986,7 @@ static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTa
static void pycon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
{
#ifndef WITH_PYTHON
- (void)con; (void)cob; (void)targets; /* unused */
+ UNUSED_VARS(con, cob, targets);
return;
#else
bPythonConstraint *data = con->data;
@@ -2702,19 +2717,19 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
float range = bulge_max - 1.0f;
float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
- float soft = 1.0f + range * atanf((bulge - 1.0f) * scale) / (0.5f * M_PI);
+ float soft = 1.0f + range * atanf((bulge - 1.0f) * scale) / (float)M_PI_2;
bulge = interpf(soft, hard, data->bulge_smooth);
}
}
if (bulge < 1.0f) {
if (data->flag & STRETCHTOCON_USE_BULGE_MIN) {
- float bulge_min = CLAMPIS(data->bulge_max, 0.0f, 1.0f);
+ float bulge_min = CLAMPIS(data->bulge_min, 0.0f, 1.0f);
float hard = max_ff(bulge, bulge_min);
float range = 1.0f - bulge_min;
float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
- float soft = 1.0f - range * atanf((1.0f - bulge) * scale) / (0.5f * M_PI);
+ float soft = 1.0f - range * atanf((1.0f - bulge) * scale) / (float)M_PI_2;
bulge = interpf(soft, hard, data->bulge_smooth);
}
@@ -3461,8 +3476,11 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
}
/* transform normal into requested space */
+ /* Note that in this specific case, we need to keep scaling in non-parented 'local2world' object
+ * case, because SpaceTransform also takes it into account when handling normals. See T42447. */
unit_m4(mat);
- BKE_constraint_mat_convertspace(cob->ob, cob->pchan, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace);
+ BKE_constraint_mat_convertspace(cob->ob, cob->pchan, mat,
+ CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace, true);
invert_m4(mat);
mul_mat3_m4_v3(mat, no);
@@ -3682,6 +3700,9 @@ static void splineik_new_data(void *cdata)
bSplineIKConstraint *data = (bSplineIKConstraint *)cdata;
data->chainlen = 1;
+ data->bulge = 1.0;
+ data->bulge_max = 1.0f;
+ data->bulge_min = 1.0f;
}
static void splineik_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
@@ -4349,7 +4370,7 @@ static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, bool is_re
* be sure to run BIK_clear_data() when freeing an IK constraint,
* unless DAG_relations_tag_update is called.
*/
-void BKE_constraint_free_data(bConstraint *con)
+void BKE_constraint_free_data_ex(bConstraint *con, bool do_id_user)
{
if (con->data) {
bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
@@ -4360,7 +4381,7 @@ void BKE_constraint_free_data(bConstraint *con)
cti->free_data(con);
/* unlink the referenced resources it uses */
- if (cti->id_looper)
+ if (do_id_user && cti->id_looper)
cti->id_looper(con, con_unlink_refs_cb, NULL);
}
@@ -4369,19 +4390,28 @@ void BKE_constraint_free_data(bConstraint *con)
}
}
+void BKE_constraint_free_data(bConstraint *con)
+{
+ BKE_constraint_free_data_ex(con, true);
+}
+
/* Free all constraints from a constraint-stack */
-void BKE_constraints_free(ListBase *list)
+void BKE_constraints_free_ex(ListBase *list, bool do_id_user)
{
bConstraint *con;
/* Free constraint data and also any extra data */
for (con = list->first; con; con = con->next)
- BKE_constraint_free_data(con);
+ BKE_constraint_free_data_ex(con, do_id_user);
/* Free the whole list */
BLI_freelistN(list);
}
+void BKE_constraints_free(ListBase *list)
+{
+ BKE_constraints_free_ex(list, true);
+}
/* Remove the specified constraint from the given constraint stack */
bool BKE_constraint_remove(ListBase *list, bConstraint *con)
@@ -4389,10 +4419,26 @@ bool BKE_constraint_remove(ListBase *list, bConstraint *con)
if (con) {
BKE_constraint_free_data(con);
BLI_freelinkN(list, con);
- return 1;
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+bool BKE_constraint_remove_ex(ListBase *list, Object *ob, bConstraint *con, bool clear_dep)
+{
+ const short type = con->type;
+ if (BKE_constraint_remove(list, con)) {
+ /* ITASC needs to be rebuilt once a constraint is removed [#26920] */
+ if (clear_dep && ELEM(type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK)) {
+ BIK_clear_data(ob->pose);
+ }
+ return true;
+ }
+ else {
+ return false;
}
- else
- return 0;
}
/* ......... */
@@ -4656,15 +4702,15 @@ bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan)
/* On bone-level, check if bone is on proxy-protected layer */
if ((pchan->bone) && (pchan->bone->layer & arm->layer_protected))
- return 1;
+ return true;
}
else {
/* FIXME: constraints on object-level are not handled well yet */
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
/* -------- Target-Matrix Stuff ------- */
@@ -4810,7 +4856,7 @@ void BKE_constraints_solve(ListBase *conlist, bConstraintOb *cob, float ctime)
copy_m4_m4(oldmat, cob->matrix);
/* move owner matrix into right space */
- BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
+ BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace, false);
/* prepare targets for constraint solving */
BKE_constraint_targets_for_solving_get(con, cob, &targets, ctime);
@@ -4828,7 +4874,7 @@ void BKE_constraints_solve(ListBase *conlist, bConstraintOb *cob, float ctime)
/* move owner back into worldspace for next constraint/other business */
if ((con->flag & CONSTRAINT_SPACEONCE) == 0)
- BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
+ BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD, false);
/* Interpolate the enforcement, to blend result of constraint into final owner transform
* - all this happens in worldspace to prevent any weirdness creeping in ([#26014] and [#25725]),
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index de285f87444..7142c092583 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -37,6 +37,7 @@
#include "DNA_windowmanager_types.h"
#include "DNA_object_types.h"
#include "DNA_linestyle_types.h"
+#include "DNA_gpencil_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@@ -257,7 +258,7 @@ static void *ctx_wm_python_context_get(
}
}
#else
- (void)C, (void)member, (void)member_type;
+ UNUSED_VARS(C, member, member_type);
#endif
/* don't allow UI context access from non-main threads */
@@ -453,7 +454,7 @@ static void data_dir_add(ListBase *lb, const char *member, const bool use_all)
{
LinkData *link;
- if ((use_all == false) && strcmp(member, "scene") == 0) /* exception */
+ if ((use_all == false) && STREQ(member, "scene")) /* exception */
return;
if (BLI_findstring(lb, member, offsetof(LinkData, data)))
@@ -545,7 +546,7 @@ ListBase CTX_data_dir_get(const bContext *C)
bool CTX_data_equals(const char *member, const char *str)
{
- return (strcmp(member, str) == 0);
+ return (STREQ(member, str));
}
bool CTX_data_dir(const char *member)
@@ -588,7 +589,7 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas
ListBase list;
if (func(C, &list)) {
- int tot = BLI_countlist(&list);
+ int tot = BLI_listbase_count(&list);
BLI_freelistN(&list);
return tot;
}
@@ -1090,3 +1091,34 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "visible_pose_bones", list);
}
+
+bGPdata *CTX_data_gpencil_data(const bContext *C)
+{
+ return ctx_data_pointer_get(C, "gpencil_data");
+}
+
+bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C)
+{
+ return ctx_data_pointer_get(C, "active_gpencil_layer");
+}
+
+bGPDframe *CTX_data_active_gpencil_frame(const bContext *C)
+{
+ return ctx_data_pointer_get(C, "active_gpencil_frame");
+}
+
+int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list)
+{
+ return ctx_data_collection_get(C, "visible_gpencil_layers", list);
+}
+
+int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list)
+{
+ return ctx_data_collection_get(C, "editable_gpencil_layers", list);
+}
+
+int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list)
+{
+ return ctx_data_collection_get(C, "editable_gpencil_strokes", list);
+}
+
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index ca58035d638..b6a167da53d 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -237,6 +237,10 @@ Curve *BKE_curve_copy(Curve *cu)
id_us_plus((ID *)cun->vfonti);
id_us_plus((ID *)cun->vfontbi);
+ if (cu->id.lib) {
+ BKE_id_lib_local_paths(G.main, cu->id.lib, &cun->id);
+ }
+
return cun;
}
@@ -589,6 +593,10 @@ Nurb *BKE_nurb_copy(Nurb *src, int pntsu, int pntsv)
newnu->pntsu = pntsu;
newnu->pntsv = pntsv;
+ /* caller can manually handle these arrays */
+ newnu->knotsu = NULL;
+ newnu->knotsv = NULL;
+
if (src->bezt) {
newnu->bezt = (BezTriple *)MEM_mallocN(pntsu * pntsv * sizeof(BezTriple), "copyNurb2");
}
@@ -1239,6 +1247,7 @@ void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu,
void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array,
int resolu, int stride)
{
+ const float eps = 1e-6f;
BPoint *bp;
float u, ustart, uend, ustep, sumdiv;
float *basisu, *sum, *fp;
@@ -1297,7 +1306,7 @@ void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float *
*fp = basisu[i] * bp->vec[3];
sumdiv += *fp;
}
- if ((sumdiv != 0.0f) && (sumdiv < 0.999f || sumdiv > 1.001f)) {
+ if ((sumdiv != 0.0f) && (sumdiv < 1.0f - eps || sumdiv > 1.0f + eps)) {
/* is normalizing needed? */
fp = sum;
for (i = istart; i <= iend; i++, fp++) {
@@ -1734,7 +1743,7 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp,
/* half a circle */
fp = dl->verts;
- dangle = (0.5 * M_PI / (dnr - 1));
+ dangle = ((float)M_PI_2 / (dnr - 1));
angle = -(nr - 1) * dangle;
for (a = 0; a < nr; a++) {
@@ -1793,7 +1802,7 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp,
/* half a circle */
fp = dl->verts;
angle = 0.0;
- dangle = (0.5 * M_PI / (dnr - 1));
+ dangle = ((float)M_PI_2 / (dnr - 1));
for (a = 0; a < nr; a++) {
fp[0] = 0.0;
@@ -1935,7 +1944,7 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2,
t02 = x1 * x2 + y1 * y2;
if (fabsf(t02) >= 1.0f)
- t02 = 0.5 * M_PI;
+ t02 = M_PI_2;
else
t02 = (saacos(t02)) / 2.0f;
@@ -2468,7 +2477,7 @@ static void make_bevel_list_2D(BevList *bl)
/* first */
bevp = bl->bevpoints;
- angle = atan2f(bevp->dir[0], bevp->dir[1]) - (float)(M_PI / 2.0f);
+ angle = atan2f(bevp->dir[0], bevp->dir[1]) - (float)M_PI_2;
bevp->sina = sinf(angle);
bevp->cosa = cosf(angle);
vec_to_quat(bevp->quat, bevp->dir, 5, 1);
@@ -2476,7 +2485,7 @@ static void make_bevel_list_2D(BevList *bl)
/* last */
bevp = bl->bevpoints;
bevp += (bl->nr - 1);
- angle = atan2f(bevp->dir[0], bevp->dir[1]) - (float)(M_PI / 2.0f);
+ angle = atan2f(bevp->dir[0], bevp->dir[1]) - (float)M_PI_2;
bevp->sina = sinf(angle);
bevp->cosa = cosf(angle);
vec_to_quat(bevp->quat, bevp->dir, 5, 1);
@@ -3343,6 +3352,21 @@ void BKE_nurb_handle_calc_simple(Nurb *nu, BezTriple *bezt)
}
}
+void BKE_nurb_handle_calc_simple_auto(Nurb *nu, BezTriple *bezt)
+{
+ if (nu->pntsu > 1) {
+ const char h1_back = bezt->h1, h2_back = bezt->h2;
+
+ bezt->h1 = bezt->h2 = HD_AUTO;
+
+ /* Override handle types to HD_AUTO and recalculate */
+ BKE_nurb_handle_calc_simple(nu, bezt);
+
+ bezt->h1 = h1_back;
+ bezt->h2 = h2_back;
+ }
+}
+
/**
* Use when something has changed handle positions.
*
@@ -3600,24 +3624,12 @@ void BKE_nurbList_handles_recalculate(ListBase *editnurb, const bool calc_length
if (h1_select || h2_select) {
- /* Override handle types to HD_AUTO and recalculate */
-
- char h1_back, h2_back;
float co1_back[3], co2_back[3];
- h1_back = bezt->h1;
- h2_back = bezt->h2;
-
- bezt->h1 = HD_AUTO;
- bezt->h2 = HD_AUTO;
-
copy_v3_v3(co1_back, bezt->vec[0]);
copy_v3_v3(co2_back, bezt->vec[2]);
- BKE_nurb_handle_calc_simple(nu, bezt);
-
- bezt->h1 = h1_back;
- bezt->h2 = h2_back;
+ BKE_nurb_handle_calc_simple_auto(nu, bezt);
if (h1_select) {
if (!calc_length) {
@@ -4312,7 +4324,7 @@ bool BKE_curve_center_bounds(Curve *cu, float cent[3])
}
-void BKE_curve_transform_ex(Curve *cu, float mat[4][4], bool do_keys, float unit_scale)
+void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, const float unit_scale)
{
Nurb *nu;
BPoint *bp;
@@ -4348,13 +4360,13 @@ void BKE_curve_transform_ex(Curve *cu, float mat[4][4], bool do_keys, float unit
}
}
-void BKE_curve_transform(Curve *cu, float mat[4][4], bool do_keys)
+void BKE_curve_transform(Curve *cu, float mat[4][4], const bool do_keys)
{
float unit_scale = mat4_to_scale(mat);
BKE_curve_transform_ex(cu, mat, do_keys, unit_scale);
}
-void BKE_curve_translate(Curve *cu, float offset[3], bool do_keys)
+void BKE_curve_translate(Curve *cu, float offset[3], const bool do_keys)
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
Nurb *nu;
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 7684c5a3a42..999f411cece 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -48,6 +48,7 @@
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_math.h"
+#include "BLI_math_color_blend.h"
#include "BLI_mempool.h"
#include "BLF_translation.h"
@@ -56,6 +57,8 @@
#include "BKE_customdata_file.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_remap.h"
#include "BKE_multires.h"
#include "bmesh.h"
@@ -92,7 +95,7 @@ typedef struct LayerTypeInfo {
* (deep copy if appropriate)
* if NULL, memcpy is used
*/
- void (*copy)(const void *source, void *dest, int count);
+ cd_copy copy;
/**
* a function to free any dynamically allocated components of this
@@ -117,8 +120,7 @@ typedef struct LayerTypeInfo {
* applying changes while reading from sources.
* See bug [#32395] - Campbell.
*/
- void (*interp)(void **sources, const float *weights, const float *sub_weights,
- int count, void *dest);
+ cd_interp interp;
/** a function to swap the data in corners of the element */
void (*swap)(void *data, const int *corner_indices);
@@ -134,7 +136,7 @@ typedef struct LayerTypeInfo {
void (*initminmax)(void *min, void *max);
void (*add)(void *data1, const void *data2);
void (*dominmax)(const void *data1, void *min, void *max);
- void (*copyvalue)(const void *source, void *dest);
+ void (*copyvalue)(const void *source, void *dest, const int mixmode, const float mixfactor);
/** a function to read data from a cdf file */
int (*read)(CDataFile *cdf, void *data, int count);
@@ -157,7 +159,7 @@ static void layerCopy_mdeformvert(const void *source, void *dest,
memcpy(dest, source, count * size);
for (i = 0; i < count; ++i) {
- MDeformVert *dvert = (MDeformVert *)((char *)dest + i * size);
+ MDeformVert *dvert = POINTER_OFFSET(dest, i * size);
if (dvert->totweight) {
MDeformWeight *dw = MEM_mallocN(dvert->totweight * sizeof(*dw),
@@ -176,7 +178,7 @@ static void layerFree_mdeformvert(void *data, int count, int size)
int i;
for (i = 0; i < count; ++i) {
- MDeformVert *dvert = (MDeformVert *)((char *)data + i * size);
+ MDeformVert *dvert = POINTER_OFFSET(data, i * size);
if (dvert->dw) {
MEM_freeN(dvert->dw);
@@ -193,7 +195,7 @@ static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest,
int i, size = sizeof(void *);
for (i = 0; i < count; ++i) {
- void **ptr = (void **)((char *)dest + i * size);
+ void **ptr = POINTER_OFFSET(dest, i * size);
*ptr = NULL;
}
}
@@ -210,15 +212,16 @@ static void layerFree_bmesh_elem_py_ptr(void *data, int count, int size)
int i;
for (i = 0; i < count; ++i) {
- void **ptr = (void *)((char *)data + i * size);
+ void **ptr = POINTER_OFFSET(data, i * size);
if (*ptr) {
bpy_bm_generic_invalidate(*ptr);
}
}
}
-static void layerInterp_mdeformvert(void **sources, const float *weights,
- const float *UNUSED(sub_weights), int count, void *dest)
+static void layerInterp_mdeformvert(
+ const void **sources, const float *weights,
+ const float *UNUSED(sub_weights), int count, void *dest)
{
/* a single linked list of MDeformWeight's
* use this to avoid double allocs (which LinkNode would do) */
@@ -237,7 +240,7 @@ static void layerInterp_mdeformvert(void **sources, const float *weights,
/* build a list of unique def_nrs for dest */
totweight = 0;
for (i = 0; i < count; ++i) {
- MDeformVert *source = sources[i];
+ const MDeformVert *source = sources[i];
float interp_weight = weights ? weights[i] : 1.0f;
for (j = 0; j < source->totweight; ++j) {
@@ -298,6 +301,50 @@ static void layerInterp_mdeformvert(void **sources, const float *weights,
}
}
+static void layerInterp_normal(
+ const void **sources, const float *weights,
+ const float *UNUSED(sub_weights), int count, void *dest)
+{
+ float no[3] = {0.0f};
+
+ while (count--) {
+ madd_v3_v3fl(no, (const float *)sources[count], weights[count]);
+ }
+
+ copy_v3_v3((float *)dest, no);
+}
+
+static void layerCopyValue_normal(const void *source, void *dest, const int mixmode, const float mixfactor)
+{
+ const float *no_src = source;
+ float *no_dst = dest;
+ float no_tmp[3];
+
+ if (ELEM(mixmode, CDT_MIX_NOMIX, CDT_MIX_REPLACE_ABOVE_THRESHOLD, CDT_MIX_REPLACE_BELOW_THRESHOLD)) {
+ /* Above/below threshold modes are not supported here, fallback to nomix (just in case). */
+ copy_v3_v3(no_dst, no_src);
+ }
+ else { /* Modes that support 'real' mix factor. */
+ /* Since we normalize in the end, MIX and ADD are the same op here. */
+ if (ELEM(mixmode, CDT_MIX_MIX, CDT_MIX_ADD)) {
+ add_v3_v3v3(no_tmp, no_dst, no_src);
+ normalize_v3(no_tmp);
+ }
+ else if (mixmode == CDT_MIX_SUB) {
+ sub_v3_v3v3(no_tmp, no_dst, no_src);
+ normalize_v3(no_tmp);
+ }
+ else if (mixmode == CDT_MIX_MUL) {
+ mul_v3_v3v3(no_tmp, no_dst, no_src);
+ normalize_v3(no_tmp);
+ }
+ else {
+ copy_v3_v3(no_tmp, no_src);
+ }
+ interp_v3_v3v3_slerp_safe(no_dst, no_dst, no_tmp, mixfactor);
+ }
+}
+
static void layerCopy_tface(const void *source, void *dest, int count)
{
const MTFace *source_tf = (const MTFace *)source;
@@ -308,8 +355,9 @@ static void layerCopy_tface(const void *source, void *dest, int count)
dest_tf[i] = source_tf[i];
}
-static void layerInterp_tface(void **sources, const float *weights,
- const float *sub_weights, int count, void *dest)
+static void layerInterp_tface(
+ const void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
MTFace *tf = dest;
int i, j, k;
@@ -321,7 +369,7 @@ static void layerInterp_tface(void **sources, const float *weights,
sub_weight = sub_weights;
for (i = 0; i < count; ++i) {
float weight = weights ? weights[i] : 1;
- MTFace *src = sources[i];
+ const MTFace *src = sources[i];
for (j = 0; j < 4; ++j) {
if (sub_weights) {
@@ -415,8 +463,9 @@ static void layerCopy_origspace_face(const void *source, void *dest, int count)
dest_tf[i] = source_tf[i];
}
-static void layerInterp_origspace_face(void **sources, const float *weights,
- const float *sub_weights, int count, void *dest)
+static void layerInterp_origspace_face(
+ const void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
OrigSpaceFace *osf = dest;
int i, j, k;
@@ -428,7 +477,7 @@ static void layerInterp_origspace_face(void **sources, const float *weights,
sub_weight = sub_weights;
for (i = 0; i < count; ++i) {
float weight = weights ? weights[i] : 1;
- OrigSpaceFace *src = sources[i];
+ const OrigSpaceFace *src = sources[i];
for (j = 0; j < 4; ++j) {
if (sub_weights) {
@@ -620,14 +669,53 @@ static void layerFree_grid_paint_mask(void *data, int count, int UNUSED(size))
}
/* --------- */
-static void layerCopyValue_mloopcol(const void *source, void *dest)
+static void layerCopyValue_mloopcol(const void *source, void *dest, const int mixmode, const float mixfactor)
{
const MLoopCol *m1 = source;
MLoopCol *m2 = dest;
-
- m2->r = m1->r;
- m2->g = m1->g;
- m2->b = m1->b;
+ unsigned char tmp_col[4];
+
+ if (ELEM(mixmode, CDT_MIX_NOMIX, CDT_MIX_REPLACE_ABOVE_THRESHOLD, CDT_MIX_REPLACE_BELOW_THRESHOLD)) {
+ /* Modes that do a full copy or nothing. */
+ if (ELEM(mixmode, CDT_MIX_REPLACE_ABOVE_THRESHOLD, CDT_MIX_REPLACE_BELOW_THRESHOLD)) {
+ /* TODO: Check for a real valid way to get 'factor' value of our dest color? */
+ const float f = ((float)m2->r + (float)m2->g + (float)m2->b) / 3.0f;
+ if (mixmode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && f < mixfactor) {
+ return; /* Do Nothing! */
+ }
+ else if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) {
+ return; /* Do Nothing! */
+ }
+ }
+ m2->r = m1->r;
+ m2->g = m1->g;
+ m2->b = m1->b;
+ }
+ else { /* Modes that support 'real' mix factor. */
+ unsigned char src[4] = {m1->r, m1->g, m1->b, m1->a};
+ unsigned char dst[4] = {m2->r, m2->g, m2->b, m2->a};
+
+ if (mixmode == CDT_MIX_MIX) {
+ blend_color_mix_byte(tmp_col, dst, src);
+ }
+ else if (mixmode == CDT_MIX_ADD) {
+ blend_color_add_byte(tmp_col, dst, src);
+ }
+ else if (mixmode == CDT_MIX_SUB) {
+ blend_color_sub_byte(tmp_col, dst, src);
+ }
+ else if (mixmode == CDT_MIX_MUL) {
+ blend_color_mul_byte(tmp_col, dst, src);
+ }
+ else {
+ memcpy(tmp_col, src, sizeof(tmp_col));
+ }
+ blend_color_interpolate_byte(dst, dst, tmp_col, mixfactor);
+
+ m2->r = (char)dst[0];
+ m2->g = (char)dst[1];
+ m2->b = (char)dst[2];
+ }
m2->a = m1->a;
}
@@ -706,8 +794,9 @@ static void layerDefault_mloopcol(void *data, int count)
}
-static void layerInterp_mloopcol(void **sources, const float *weights,
- const float *sub_weights, int count, void *dest)
+static void layerInterp_mloopcol(
+ const void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
MLoopCol *mc = dest;
int i;
@@ -723,7 +812,7 @@ static void layerInterp_mloopcol(void **sources, const float *weights,
sub_weight = sub_weights;
for (i = 0; i < count; ++i) {
float weight = weights ? weights[i] : 1;
- MLoopCol *src = sources[i];
+ const MLoopCol *src = sources[i];
if (sub_weights) {
col.r += src->r * (*sub_weight) * weight;
col.g += src->g * (*sub_weight) * weight;
@@ -758,12 +847,19 @@ static int layerMaxNum_mloopcol(void)
return MAX_MCOL;
}
-static void layerCopyValue_mloopuv(const void *source, void *dest)
+static void layerCopyValue_mloopuv(const void *source, void *dest, const int mixmode, const float mixfactor)
{
const MLoopUV *luv1 = source;
MLoopUV *luv2 = dest;
- copy_v2_v2(luv2->uv, luv1->uv);
+ /* We only support a limited subset of advanced mixing here - namely the mixfactor interpolation. */
+
+ if (mixmode == CDT_MIX_NOMIX) {
+ copy_v2_v2(luv2->uv, luv1->uv);
+ }
+ else {
+ interp_v2_v2v2(luv2->uv, luv2->uv, luv1->uv, mixfactor);
+ }
}
static bool layerEqual_mloopuv(const void *data1, const void *data2)
@@ -803,8 +899,9 @@ static void layerAdd_mloopuv(void *data1, const void *data2)
add_v2_v2(l1->uv, l2->uv);
}
-static void layerInterp_mloopuv(void **sources, const float *weights,
- const float *sub_weights, int count, void *dest)
+static void layerInterp_mloopuv(
+ const void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
float uv[2];
int i;
@@ -815,7 +912,7 @@ static void layerInterp_mloopuv(void **sources, const float *weights,
const float *sub_weight = sub_weights;
for (i = 0; i < count; i++) {
float weight = weights ? weights[i] : 1.0f;
- MLoopUV *src = sources[i];
+ const MLoopUV *src = sources[i];
madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight);
sub_weight++;
}
@@ -823,7 +920,7 @@ static void layerInterp_mloopuv(void **sources, const float *weights,
else {
for (i = 0; i < count; i++) {
float weight = weights ? weights[i] : 1;
- MLoopUV *src = sources[i];
+ const MLoopUV *src = sources[i];
madd_v2_v2fl(uv, src->uv, weight);
}
}
@@ -833,7 +930,8 @@ static void layerInterp_mloopuv(void **sources, const float *weights,
}
/* origspace is almost exact copy of mloopuv's, keep in sync */
-static void layerCopyValue_mloop_origspace(const void *source, void *dest)
+static void layerCopyValue_mloop_origspace(const void *source, void *dest,
+ const int UNUSED(mixmode), const float UNUSED(mixfactor))
{
const OrigSpaceLoop *luv1 = source;
OrigSpaceLoop *luv2 = dest;
@@ -878,8 +976,9 @@ static void layerAdd_mloop_origspace(void *data1, const void *data2)
add_v2_v2(l1->uv, l2->uv);
}
-static void layerInterp_mloop_origspace(void **sources, const float *weights,
- const float *sub_weights, int count, void *dest)
+static void layerInterp_mloop_origspace(
+ const void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
float uv[2];
int i;
@@ -890,7 +989,7 @@ static void layerInterp_mloop_origspace(void **sources, const float *weights,
const float *sub_weight = sub_weights;
for (i = 0; i < count; i++) {
float weight = weights ? weights[i] : 1.0f;
- OrigSpaceLoop *src = sources[i];
+ const OrigSpaceLoop *src = sources[i];
madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight);
sub_weight++;
}
@@ -898,7 +997,7 @@ static void layerInterp_mloop_origspace(void **sources, const float *weights,
else {
for (i = 0; i < count; i++) {
float weight = weights ? weights[i] : 1.0f;
- OrigSpaceLoop *src = sources[i];
+ const OrigSpaceLoop *src = sources[i];
madd_v2_v2fl(uv, src->uv, weight);
}
}
@@ -908,8 +1007,9 @@ static void layerInterp_mloop_origspace(void **sources, const float *weights,
}
/* --- end copy */
-static void layerInterp_mcol(void **sources, const float *weights,
- const float *sub_weights, int count, void *dest)
+static void layerInterp_mcol(
+ const void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
MCol *mc = dest;
int i, j, k;
@@ -930,7 +1030,7 @@ static void layerInterp_mcol(void **sources, const float *weights,
for (j = 0; j < 4; ++j) {
if (sub_weights) {
- MCol *src = sources[i];
+ const MCol *src = sources[i];
for (k = 0; k < 4; ++k, ++sub_weight, ++src) {
const float w = (*sub_weight) * weight;
col[j].a += src->a * w;
@@ -940,7 +1040,7 @@ static void layerInterp_mcol(void **sources, const float *weights,
}
}
else {
- MCol *src = sources[i];
+ const MCol *src = sources[i];
col[j].a += src[j].a * weight;
col[j].r += src[j].r * weight;
col[j].g += src[j].g * weight;
@@ -994,8 +1094,9 @@ static void layerDefault_origindex(void *data, int count)
fill_vn_i((int *)data, count, ORIGINDEX_NONE);
}
-static void layerInterp_bweight(void **sources, const float *weights,
- const float *UNUSED(sub_weights), int count, void *dest)
+static void layerInterp_bweight(
+ const void **sources, const float *weights,
+ const float *UNUSED(sub_weights), int count, void *dest)
{
float f;
float **in = (float **)sources;
@@ -1020,8 +1121,9 @@ static void layerInterp_bweight(void **sources, const float *weights,
*((float *)dest) = f;
}
-static void layerInterp_shapekey(void **sources, const float *weights,
- const float *UNUSED(sub_weights), int count, void *dest)
+static void layerInterp_shapekey(
+ const void **sources, const float *weights,
+ const float *UNUSED(sub_weights), int count, void *dest)
{
float co[3];
float **in = (float **)sources;
@@ -1057,26 +1159,27 @@ static void layerDefault_mvert_skin(void *data, int count)
}
}
-static void layerInterp_mvert_skin(void **sources, const float *weights,
- const float *UNUSED(sub_weights),
- int count, void *dest)
+static void layerInterp_mvert_skin(
+ const void **sources, const float *weights,
+ const float *UNUSED(sub_weights),
+ int count, void *dest)
{
+ MVertSkin *vs_dst = dest;
float radius[3], w;
- MVertSkin *vs;
int i;
zero_v3(radius);
for (i = 0; i < count; i++) {
+ const MVertSkin *vs_src = sources[i];
w = weights ? weights[i] : 1.0f;
- vs = sources[i];
- madd_v3_v3fl(radius, vs->radius, w);
+ madd_v3_v3fl(radius, vs_src->radius, w);
}
/* delay writing to the destination incase dest is in sources */
- vs = dest;
- copy_v3_v3(vs->radius, radius);
- vs->flag &= ~MVERT_SKIN_ROOT;
+ vs_dst = dest;
+ copy_v3_v3(vs_dst->radius, radius);
+ vs_dst->flag &= ~MVERT_SKIN_ROOT;
}
static void layerSwap_flnor(void *data, const int *corner_indices)
@@ -1116,7 +1219,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, layerDefault_origindex},
/* 8: CD_NORMAL */
/* 3 floats per normal vector */
- {sizeof(float) * 3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(float) * 3, "vec3f", 1, NULL, NULL, NULL, layerInterp_normal, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, layerCopyValue_normal},
/* 9: CD_POLYINDEX (deprecated) */
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
/* 10: CD_PROP_FLT */
@@ -1206,6 +1310,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(float[4]), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
/* 40: CD_TESSLOOPNORMAL */
{sizeof(short[4][3]), "", 0, NULL, NULL, NULL, NULL, layerSwap_flnor, NULL},
+ /* 41: CD_CUSTOMLOOPNORMAL */
+ {sizeof(short[2]), "vec2s", 1, NULL, NULL, NULL, NULL, NULL, NULL},
};
/* note, numbers are from trunk and need updating for bmesh */
@@ -1221,7 +1327,8 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
/* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
/* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "CDBMElemPyPtr", "CDPaintMask",
/* 35-36 */ "CDGridPaintMask", "CDMVertSkin",
- /* 37-40 */ "CDFreestyleEdge", "CDFreestyleFace", "CDMLoopTangent", "CDTessLoopNormal",
+ /* 37-38 */ "CDFreestyleEdge", "CDFreestyleFace",
+ /* 39-41 */ "CDMLoopTangent", "CDTessLoopNormal", "CDCustomLoopNormal",
};
@@ -1233,26 +1340,29 @@ const CustomDataMask CD_MASK_MESH =
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
CD_MASK_MTEXPOLY | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
- CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
+ CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE |
+ CD_MASK_CUSTOMLOOPNORMAL;
const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX |
CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR |
CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
- CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN;
+ CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_CUSTOMLOOPNORMAL;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_PREVIEW_MLOOPCOL |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORCO | CD_MASK_TANGENT |
CD_MASK_PREVIEW_MCOL | CD_MASK_SHAPEKEY | CD_MASK_RECAST |
- CD_MASK_ORIGINDEX | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
+ CD_MASK_ORIGINDEX | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE |
+ CD_MASK_CUSTOMLOOPNORMAL;
const CustomDataMask CD_MASK_BMESH =
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS |
CD_MASK_CREASE | CD_MASK_BWEIGHT | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
- CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
+ CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE |
+ CD_MASK_CUSTOMLOOPNORMAL;
const CustomDataMask CD_MASK_FACECORNERS = /* XXX Not used anywhere! */
CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
CD_MASK_MLOOPCOL | CD_MASK_NORMAL | CD_MASK_MLOOPTANGENT;
@@ -1267,7 +1377,7 @@ const CustomDataMask CD_MASK_EVERYTHING =
/* BMESH ONLY END */
CD_MASK_PAINT_MASK | CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN |
CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE |
- CD_MASK_MLOOPTANGENT | CD_MASK_TESSLOOPNORMAL;
+ CD_MASK_MLOOPTANGENT | CD_MASK_TESSLOOPNORMAL | CD_MASK_CUSTOMLOOPNORMAL;
static const LayerTypeInfo *layerType_getInfo(int type)
{
@@ -1449,6 +1559,25 @@ void CustomData_free(CustomData *data, int totelem)
CustomData_reset(data);
}
+void CustomData_free_typemask(struct CustomData *data, int totelem, CustomDataMask mask)
+{
+ int i;
+
+ for (i = 0; i < data->totlayer; ++i) {
+ CustomDataLayer *layer = &data->layers[i];
+ if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
+ continue;
+ }
+ customData_free_layer__internal(layer, totelem);
+ }
+
+ if (data->layers)
+ MEM_freeN(data->layers);
+
+ CustomData_external_free(data);
+ CustomData_reset(data);
+}
+
static void customData_update_offsets(CustomData *data)
{
const LayerTypeInfo *typeInfo;
@@ -1504,7 +1633,7 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha
for (i = 0; i < data->totlayer; ++i)
if (data->layers[i].type == type)
- if (strcmp(data->layers[i].name, name) == 0)
+ if (STREQ(data->layers[i].name, name))
return i;
return -1;
@@ -1680,7 +1809,8 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, int typ
int totelem, const char *name)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
- int size = typeInfo->size * totelem, flag = 0, index = data->totlayer;
+ const int size = totelem * typeInfo->size;
+ int flag = 0, index = data->totlayer;
void *newlayerdata = NULL;
/* Passing a layerdata to copy from with an alloctype that won't copy is
@@ -1699,7 +1829,13 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, int typ
newlayerdata = layerdata;
}
else if (size > 0) {
- newlayerdata = MEM_callocN(size, layerType_getName(type));
+ if (alloctype == CD_DUPLICATE && layerdata) {
+ newlayerdata = MEM_mallocN(size, layerType_getName(type));
+ }
+ else {
+ newlayerdata = MEM_callocN(size, layerType_getName(type));
+ }
+
if (!newlayerdata)
return NULL;
}
@@ -1712,7 +1848,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, int typ
}
else if (alloctype == CD_DEFAULT) {
if (typeInfo->set_default)
- typeInfo->set_default((char *)newlayerdata, totelem);
+ typeInfo->set_default(newlayerdata, totelem);
}
else if (alloctype == CD_REFERENCE)
flag |= CD_FLAG_NOFREE;
@@ -1798,7 +1934,8 @@ bool CustomData_free_layer(CustomData *data, int type, int totelem, int index)
const int n = index - CustomData_get_layer_index(data, type);
int i;
- if (index < 0) return 0;
+ if (index < 0)
+ return false;
customData_free_layer__internal(&data->layers[index], totelem);
@@ -1828,14 +1965,15 @@ bool CustomData_free_layer(CustomData *data, int type, int totelem, int index)
customData_update_offsets(data);
- return 1;
+ return true;
}
bool CustomData_free_layer_active(CustomData *data, int type, int totelem)
{
int index = 0;
index = CustomData_get_active_layer_index(data, type);
- if (index == -1) return 0;
+ if (index == -1)
+ return false;
return CustomData_free_layer(data, type, totelem, index);
}
@@ -1873,14 +2011,13 @@ int CustomData_number_of_layers_typemask(const CustomData *data, CustomDataMask
return number;
}
-void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem)
+static void *customData_duplicate_referenced_layer_index(CustomData *data, const int layer_index, const int totelem)
{
CustomDataLayer *layer;
- int layer_index;
- /* get the layer index of the first layer of type */
- layer_index = CustomData_get_active_layer_index(data, type);
- if (layer_index == -1) return NULL;
+ if (layer_index == -1) {
+ return NULL;
+ }
layer = &data->layers[layer_index];
@@ -1892,12 +2029,13 @@ void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int t
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if (typeInfo->copy) {
- char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer");
- typeInfo->copy(layer->data, dest_data, totelem);
- layer->data = dest_data;
+ void *dst_data = MEM_mallocN(totelem * typeInfo->size, "CD duplicate ref layer");
+ typeInfo->copy(layer->data, dst_data, totelem);
+ layer->data = dst_data;
}
- else
+ else {
layer->data = MEM_dupallocN(layer->data);
+ }
layer->flag &= ~CD_FLAG_NOFREE;
}
@@ -1905,37 +2043,34 @@ void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int t
return layer->data;
}
-void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
- const int type, const char *name, const int totelem)
+void *CustomData_duplicate_referenced_layer(CustomData *data, const int type, const int totelem)
{
- CustomDataLayer *layer;
int layer_index;
- /* get the layer index of the desired layer */
- layer_index = CustomData_get_named_layer_index(data, type, name);
- if (layer_index == -1) return NULL;
+ /* get the layer index of the first layer of type */
+ layer_index = CustomData_get_active_layer_index(data, type);
- layer = &data->layers[layer_index];
+ return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
+}
- if (layer->flag & CD_FLAG_NOFREE) {
- /* MEM_dupallocN won't work in case of complex layers, like e.g.
- * CD_MDEFORMVERT, which has pointers to allocated data...
- * So in case a custom copy function is defined, use it!
- */
- const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+void *CustomData_duplicate_referenced_layer_n(CustomData *data, const int type, const int n, const int totelem)
+{
+ int layer_index;
- if (typeInfo->copy) {
- char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer");
- typeInfo->copy(layer->data, dest_data, totelem);
- layer->data = dest_data;
- }
- else
- layer->data = MEM_dupallocN(layer->data);
+ /* get the layer index of the desired layer */
+ layer_index = CustomData_get_layer_index_n(data, type, n);
- layer->flag &= ~CD_FLAG_NOFREE;
- }
+ return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
+}
- return layer->data;
+void *CustomData_duplicate_referenced_layer_named(CustomData *data, const int type, const char *name, const int totelem)
+{
+ int layer_index;
+
+ /* get the layer index of the desired layer */
+ layer_index = CustomData_get_named_layer_index(data, type, name);
+
+ return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
}
bool CustomData_is_referenced_layer(struct CustomData *data, int type)
@@ -1945,7 +2080,8 @@ bool CustomData_is_referenced_layer(struct CustomData *data, int type)
/* get the layer index of the first layer of type */
layer_index = CustomData_get_active_layer_index(data, type);
- if (layer_index == -1) return 0;
+ if (layer_index == -1)
+ return false;
layer = &data->layers[layer_index];
@@ -1994,47 +2130,48 @@ void CustomData_set_only_copy(const struct CustomData *data,
data->layers[i].flag |= CD_FLAG_NOCOPY;
}
-void CustomData_copy_elements(int type, void *source, void *dest, int count)
+void CustomData_copy_elements(int type, void *src_data_ofs, void *dst_data_ofs, int count)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if (typeInfo->copy)
- typeInfo->copy(source, dest, count);
+ typeInfo->copy(src_data_ofs, dst_data_ofs, count);
else
- memcpy(dest, source, typeInfo->size * count);
+ memcpy(dst_data_ofs, src_data_ofs, count * typeInfo->size);
}
-static void CustomData_copy_data_layer(const CustomData *source, CustomData *dest,
- int src_i, int dest_i,
- int source_index, int dest_index, int count) {
+static void CustomData_copy_data_layer(
+ const CustomData *source, CustomData *dest,
+ int src_i, int dst_i,
+ int src_index, int dst_index, int count) {
const LayerTypeInfo *typeInfo;
int src_offset;
- int dest_offset;
+ int dst_offset;
- const char *src_data = source->layers[src_i].data;
- char *dest_data = dest->layers[dest_i].data;
+ const void *src_data = source->layers[src_i].data;
+ void *dst_data = dest->layers[dst_i].data;
typeInfo = layerType_getInfo(source->layers[src_i].type);
- src_offset = source_index * typeInfo->size;
- dest_offset = dest_index * typeInfo->size;
+ src_offset = src_index * typeInfo->size;
+ dst_offset = dst_index * typeInfo->size;
- if (!src_data || !dest_data) {
- if (!(src_data == NULL && dest_data == NULL)) {
+ if (!src_data || !dst_data) {
+ if (!(src_data == NULL && dst_data == NULL)) {
printf("%s: warning null data for %s type (%p --> %p), skipping\n",
__func__, layerType_getName(source->layers[src_i].type),
- (void *)src_data, (void *)dest_data);
+ (void *)src_data, (void *)dst_data);
}
return;
}
if (typeInfo->copy)
- typeInfo->copy(src_data + src_offset,
- dest_data + dest_offset,
+ typeInfo->copy(POINTER_OFFSET(src_data, src_offset),
+ POINTER_OFFSET(dst_data, dst_offset),
count);
else
- memcpy(dest_data + dest_offset,
- src_data + src_offset,
+ memcpy(POINTER_OFFSET(dst_data, dst_offset),
+ POINTER_OFFSET(src_data, src_offset),
count * typeInfo->size);
}
@@ -2097,10 +2234,9 @@ void CustomData_free_elem(CustomData *data, int index, int count)
typeInfo = layerType_getInfo(data->layers[i].type);
if (typeInfo->free) {
- int offset = typeInfo->size * index;
+ int offset = index * typeInfo->size;
- typeInfo->free((char *)data->layers[i].data + offset,
- count, typeInfo->size);
+ typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size);
}
}
}
@@ -2113,17 +2249,15 @@ void CustomData_interp(const CustomData *source, CustomData *dest,
int count, int dest_index)
{
int src_i, dest_i;
- int dest_offset;
int j;
- void *source_buf[SOURCE_BUF_SIZE];
- void **sources = source_buf;
+ const void *source_buf[SOURCE_BUF_SIZE];
+ const void **sources = source_buf;
/* slow fallback in case we're interpolating a ridiculous number of
* elements
*/
if (count > SOURCE_BUF_SIZE)
- sources = MEM_callocN(sizeof(*sources) * count,
- "CustomData_interp sources");
+ sources = MEM_mallocN(sizeof(*sources) * count, __func__);
/* interpolates a layer at a time */
dest_i = 0;
@@ -2146,13 +2280,11 @@ void CustomData_interp(const CustomData *source, CustomData *dest,
void *src_data = source->layers[src_i].data;
for (j = 0; j < count; ++j) {
- sources[j] = (char *)src_data + typeInfo->size * src_indices[j];
+ sources[j] = POINTER_OFFSET(src_data, src_indices[j] * typeInfo->size);
}
- dest_offset = dest_index * typeInfo->size;
-
typeInfo->interp(sources, weights, sub_weights, count,
- (char *)dest->layers[dest_i].data + dest_offset);
+ POINTER_OFFSET(dest->layers[dest_i].data, dest_index * typeInfo->size));
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
@@ -2174,9 +2306,9 @@ void CustomData_swap(struct CustomData *data, int index, const int *corner_indic
typeInfo = layerType_getInfo(data->layers[i].type);
if (typeInfo->swap) {
- int offset = typeInfo->size * index;
+ const int offset = index * typeInfo->size;
- typeInfo->swap((char *)data->layers[i].data + offset, corner_indices);
+ typeInfo->swap(POINTER_OFFSET(data->layers[i].data, offset), corner_indices);
}
}
}
@@ -2195,7 +2327,7 @@ void *CustomData_get(const CustomData *data, int index, int type)
/* get the offset of the desired element */
offset = layerType_getInfo(type)->size * index;
- return (char *)data->layers[layer_index].data + offset;
+ return POINTER_OFFSET(data->layers[layer_index].data, offset);
}
void *CustomData_get_n(const CustomData *data, int type, int index, int n)
@@ -2210,7 +2342,7 @@ void *CustomData_get_n(const CustomData *data, int type, int index, int n)
if (layer_index == -1) return NULL;
offset = layerType_getInfo(type)->size * index;
- return (char *)data->layers[layer_index + n].data + offset;
+ return POINTER_OFFSET(data->layers[layer_index + n].data, offset);
}
void *CustomData_get_layer(const CustomData *data, int type)
@@ -2261,16 +2393,23 @@ int CustomData_get_n_offset(const CustomData *data, int type, int n)
bool CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
{
/* get the layer index of the first layer of type */
- int layer_index = CustomData_get_layer_index_n(data, type, n);
+ const int layer_index = CustomData_get_layer_index_n(data, type, n);
- if (layer_index == -1) return false;
- if (!name) return false;
+ if ((layer_index == -1) || !name)
+ return false;
BLI_strncpy(data->layers[layer_index].name, name, sizeof(data->layers[layer_index].name));
return true;
}
+const char *CustomData_get_layer_name(const CustomData *data, int type, int n)
+{
+ const int layer_index = CustomData_get_layer_index_n(data, type, n);
+
+ return (layer_index == -1) ? NULL : data->layers[layer_index].name;
+}
+
void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
{
/* get the layer index of the first layer of type */
@@ -2294,7 +2433,7 @@ void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, voi
return ptr;
}
-void CustomData_set(const CustomData *data, int index, int type, void *source)
+void CustomData_set(const CustomData *data, int index, int type, const void *source)
{
void *dest = CustomData_get(data, index, type);
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -2459,8 +2598,9 @@ void CustomData_bmesh_init_pool(CustomData *data, int totelem, const char htype)
}
}
-bool CustomData_bmesh_merge(CustomData *source, CustomData *dest,
- CustomDataMask mask, int alloctype, BMesh *bm, const char htype)
+bool CustomData_bmesh_merge(
+ const CustomData *source, CustomData *dest,
+ CustomDataMask mask, int alloctype, BMesh *bm, const char htype)
{
BMHeader *h;
BMIter iter;
@@ -2557,7 +2697,7 @@ void CustomData_bmesh_free_block(CustomData *data, void **block)
if (typeInfo->free) {
int offset = data->layers[i].offset;
- typeInfo->free((char *)*block + offset, 1, typeInfo->size);
+ typeInfo->free(POINTER_OFFSET(*block, offset), 1, typeInfo->size);
}
}
}
@@ -2585,7 +2725,7 @@ void CustomData_bmesh_free_block_data(CustomData *data, void *block)
if (typeInfo->free) {
int offset = data->layers[i].offset;
- typeInfo->free((char *)block + offset, 1, typeInfo->size);
+ typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
}
}
}
@@ -2634,10 +2774,10 @@ void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest,
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type &&
- strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0)
+ STREQ(dest->layers[dest_i].name, source->layers[src_i].name))
{
- const char *src_data = (char *)src_block + source->layers[src_i].offset;
- char *dest_data = (char *)*dest_block + dest->layers[dest_i].offset;
+ const void *src_data = POINTER_OFFSET(src_block, source->layers[src_i].offset);
+ void *dest_data = POINTER_OFFSET(*dest_block, dest->layers[dest_i].offset);
typeInfo = layerType_getInfo(source->layers[src_i].type);
@@ -2664,7 +2804,7 @@ void *CustomData_bmesh_get(const CustomData *data, void *block, int type)
layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index == -1) return NULL;
- return (char *)block + data->layers[layer_index].offset;
+ return POINTER_OFFSET(block, data->layers[layer_index].offset);
}
void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n)
@@ -2675,7 +2815,7 @@ void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int
layer_index = CustomData_get_layer_index(data, type);
if (layer_index == -1) return NULL;
- return (char *)block + data->layers[layer_index + n].offset;
+ return POINTER_OFFSET(block, data->layers[layer_index + n].offset);
}
/*gets from the layer at physical index n, note: doesn't check type.*/
@@ -2683,7 +2823,7 @@ void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
{
if (n < 0 || n >= data->totlayer) return NULL;
- return (char *)block + data->layers[n].offset;
+ return POINTER_OFFSET(block, data->layers[n].offset);
}
bool CustomData_layer_has_math(const struct CustomData *data, int layer_n)
@@ -2755,6 +2895,17 @@ bool CustomData_has_interp(const struct CustomData *data)
return false;
}
+bool CustomData_has_referenced(const struct CustomData *data)
+{
+ int i;
+ for (i = 0; i < data->totlayer; ++i) {
+ if (data->layers[i].flag & CD_FLAG_NOFREE) {
+ return true;
+ }
+ }
+ return false;
+}
+
/* copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
* another, while not overwriting anything else (e.g. flags)*/
void CustomData_data_copy_value(int type, const void *source, void *dest)
@@ -2764,11 +2915,28 @@ void CustomData_data_copy_value(int type, const void *source, void *dest)
if (!dest) return;
if (typeInfo->copyvalue)
- typeInfo->copyvalue(source, dest);
+ typeInfo->copyvalue(source, dest, CDT_MIX_NOMIX, 0.0f);
else
memcpy(dest, source, typeInfo->size);
}
+/* Mixes the "value" (e.g. mloopuv uv or mloopcol colors) from one block into
+ * another, while not overwriting anything else (e.g. flags)*/
+void CustomData_data_mix_value(int type, const void *source, void *dest, const int mixmode, const float mixfactor)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if (!dest) return;
+
+ if (typeInfo->copyvalue) {
+ typeInfo->copyvalue(source, dest, mixmode, mixfactor);
+ }
+ else {
+ /* Mere copy if no advanced interpolation is supported. */
+ memcpy(dest, source, typeInfo->size);
+ }
+}
+
bool CustomData_data_equals(int type, const void *data1, const void *data2)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -2813,7 +2981,7 @@ void CustomData_data_add(int type, void *data1, const void *data2)
typeInfo->add(data1, data2);
}
-void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
+void CustomData_bmesh_set(const CustomData *data, void *block, int type, const void *source)
{
void *dest = CustomData_bmesh_get(data, block, type);
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -2826,7 +2994,7 @@ void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *s
memcpy(dest, source, typeInfo->size);
}
-void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void *source)
+void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, const void *source)
{
void *dest = CustomData_bmesh_get_n(data, block, type, n);
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@@ -2839,7 +3007,7 @@ void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void
memcpy(dest, source, typeInfo->size);
}
-void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *source)
+void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, const void *source)
{
void *dest = CustomData_bmesh_get_layer_n(data, block, n);
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
@@ -2853,31 +3021,34 @@ void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *so
}
/**
- * \param src_blocks must be pointers to the data, offset by layer->offset already.
+ * \note src_blocks_ofs & dst_block_ofs
+ * must be pointers to the data, offset by layer->offset already.
*/
-void CustomData_bmesh_interp_n(CustomData *data, void **src_blocks, const float *weights,
- const float *sub_weights, int count, void *dest_block, int n)
+void CustomData_bmesh_interp_n(
+ CustomData *data, const void **src_blocks_ofs,
+ const float *weights, const float *sub_weights,
+ int count, void *dst_block_ofs, int n)
{
CustomDataLayer *layer = &data->layers[n];
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
- typeInfo->interp(src_blocks, weights, sub_weights, count,
- (char *)dest_block + layer->offset);
+ typeInfo->interp(src_blocks_ofs, weights, sub_weights, count, dst_block_ofs);
}
-void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *weights,
- const float *sub_weights, int count, void *dest_block)
+void CustomData_bmesh_interp(
+ CustomData *data, const void **src_blocks,
+ const float *weights, const float *sub_weights,
+ int count, void *dst_block)
{
int i, j;
void *source_buf[SOURCE_BUF_SIZE];
- void **sources = source_buf;
+ const void **sources = (const void **)source_buf;
/* slow fallback in case we're interpolating a ridiculous number of
* elements
*/
if (count > SOURCE_BUF_SIZE)
- sources = MEM_callocN(sizeof(*sources) * count,
- "CustomData_interp sources");
+ sources = MEM_mallocN(sizeof(*sources) * count, __func__);
/* interpolates a layer at a time */
for (i = 0; i < data->totlayer; ++i) {
@@ -2885,13 +3056,16 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, const float *w
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if (typeInfo->interp) {
for (j = 0; j < count; ++j) {
- sources[j] = (char *)src_blocks[j] + layer->offset;
+ sources[j] = POINTER_OFFSET(src_blocks[j], layer->offset);
}
- CustomData_bmesh_interp_n(data, sources, weights, sub_weights, count, dest_block, i);
+ CustomData_bmesh_interp_n(
+ data, sources,
+ weights, sub_weights, count,
+ POINTER_OFFSET(dst_block, layer->offset), i);
}
}
- if (count > SOURCE_BUF_SIZE) MEM_freeN(sources);
+ if (count > SOURCE_BUF_SIZE) MEM_freeN((void *)sources);
}
static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n)
@@ -2902,10 +3076,10 @@ static void CustomData_bmesh_set_default_n(CustomData *data, void **block, int n
typeInfo = layerType_getInfo(data->layers[n].type);
if (typeInfo->set_default) {
- typeInfo->set_default((char *)*block + offset, 1);
+ typeInfo->set_default(POINTER_OFFSET(*block, offset), 1);
}
else {
- memset((char *)*block + offset, 0, typeInfo->size);
+ memset(POINTER_OFFSET(*block, offset), 0, typeInfo->size);
}
}
@@ -2955,16 +3129,16 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
int offset = dest->layers[dest_i].offset;
- const char *src_data = source->layers[src_i].data;
- char *dest_data = (char *)*dest_block + offset;
+ const void *src_data = source->layers[src_i].data;
+ void *dest_data = POINTER_OFFSET(*dest_block, offset);
typeInfo = layerType_getInfo(dest->layers[dest_i].type);
src_offset = src_index * typeInfo->size;
if (typeInfo->copy)
- typeInfo->copy(src_data + src_offset, dest_data, 1);
+ typeInfo->copy(POINTER_OFFSET(src_data, src_offset), dest_data, 1);
else
- memcpy(dest_data, src_data + src_offset, typeInfo->size);
+ memcpy(dest_data, POINTER_OFFSET(src_data, src_offset), typeInfo->size);
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
@@ -2983,10 +3157,9 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
}
void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
- void *src_block, int dest_index)
+ void *src_block, int dst_index)
{
- const LayerTypeInfo *typeInfo;
- int dest_i, src_i, dest_offset;
+ int dest_i, src_i;
/* copies a layer at a time */
dest_i = 0;
@@ -3004,17 +3177,15 @@ void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
+ const LayerTypeInfo *typeInfo = layerType_getInfo(dest->layers[dest_i].type);
int offset = source->layers[src_i].offset;
- const char *src_data = (char *)src_block + offset;
- char *dest_data = dest->layers[dest_i].data;
-
- typeInfo = layerType_getInfo(dest->layers[dest_i].type);
- dest_offset = dest_index * typeInfo->size;
+ const void *src_data = POINTER_OFFSET(src_block, offset);
+ void *dst_data = POINTER_OFFSET(dest->layers[dest_i].data, dst_index * typeInfo->size);
if (typeInfo->copy)
- typeInfo->copy(src_data, dest_data + dest_offset, 1);
+ typeInfo->copy(src_data, dst_data, 1);
else
- memcpy(dest_data + dest_offset, src_data, typeInfo->size);
+ memcpy(dst_data, src_data, typeInfo->size);
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
@@ -3090,12 +3261,12 @@ static bool cd_layer_find_dupe(CustomData *data, const char *name, int type, int
CustomDataLayer *layer = &data->layers[i];
if (CustomData_is_property_layer(type)) {
- if (CustomData_is_property_layer(layer->type) && strcmp(layer->name, name) == 0) {
+ if (CustomData_is_property_layer(layer->type) && STREQ(layer->name, name)) {
return true;
}
}
else {
- if (i != index && layer->type == type && strcmp(layer->name, name) == 0) {
+ if (i != index && layer->type == type && STREQ(layer->name, name)) {
return true;
}
}
@@ -3464,3 +3635,234 @@ void CustomData_external_remove_object(CustomData *data, ID *id)
}
#endif
+/* ********** Mesh-to-mesh data transfer ********** */
+static void copy_bit_flag(void *dst, const void *src, const size_t data_size, const uint64_t flag)
+{
+#define COPY_BIT_FLAG(_type, _dst, _src, _f) \
+{ \
+ const _type _val = *((_type *)(_src)) & ((_type)(_f)); \
+ *((_type *)(_dst)) &= ~((_type)(_f)); \
+ *((_type *)(_dst)) |= _val; \
+} (void) 0
+
+ switch (data_size) {
+ case 1:
+ COPY_BIT_FLAG(uint8_t, dst, src, flag);
+ break;
+ case 2:
+ COPY_BIT_FLAG(uint16_t, dst, src, flag);
+ break;
+ case 4:
+ COPY_BIT_FLAG(uint32_t, dst, src, flag);
+ break;
+ case 8:
+ COPY_BIT_FLAG(uint64_t, dst, src, flag);
+ break;
+ default:
+ //printf("ERROR %s: Unknown flags-container size (%zu)\n", __func__, datasize);
+ break;
+ }
+
+#undef COPY_BIT_FLAG
+}
+
+static bool check_bit_flag(const void *data, const size_t data_size, const uint64_t flag)
+{
+ switch (data_size) {
+ case 1:
+ return ((*((uint8_t *)data) & ((uint8_t)flag)) != 0);
+ case 2:
+ return ((*((uint16_t *)data) & ((uint16_t)flag)) != 0);
+ case 4:
+ return ((*((uint32_t *)data) & ((uint32_t)flag)) != 0);
+ case 8:
+ return ((*((uint64_t *)data) & ((uint64_t)flag)) != 0);
+ default:
+ //printf("ERROR %s: Unknown flags-container size (%zu)\n", __func__, datasize);
+ return false;
+ }
+}
+
+static void customdata_data_transfer_interp_generic(
+ const CustomDataTransferLayerMap *laymap, void *data_dst,
+ const void **sources, const float *weights, const int count,
+ const float mix_factor)
+{
+ /* Fake interpolation, we actually copy highest weighted source to dest.
+ * Note we also handle bitflags here, in which case we rather choose to transfer value of elements totaling
+ * more than 0.5 of weight. */
+
+ int best_src_idx = 0;
+
+ const int data_type = laymap->data_type;
+ const int mix_mode = laymap->mix_mode;
+
+ size_t data_size;
+ const uint64_t data_flag = laymap->data_flag;
+
+ cd_interp interp_cd = NULL;
+ cd_copy copy_cd = NULL;
+
+ void *tmp_dst;
+
+ if (!sources) {
+ /* Not supported here, abort. */
+ return;
+ }
+
+ if (data_type & CD_FAKE) {
+ data_size = laymap->data_size;
+ }
+ else {
+ const LayerTypeInfo *type_info = layerType_getInfo(data_type);
+
+ data_size = (size_t)type_info->size;
+ interp_cd = type_info->interp;
+ copy_cd = type_info->copy;
+ }
+
+ tmp_dst = MEM_mallocN(data_size, __func__);
+
+ if (count > 1 && !interp_cd) {
+ int i;
+
+ if (data_flag) {
+ /* Boolean case, we can 'interpolate' in two groups, and choose value from highest weighted group. */
+ float tot_weight_true = 0.0f;
+ int item_true_idx = -1, item_false_idx = -1;
+
+ for (i = 0; i < count; i++) {
+ if (check_bit_flag(sources[i], data_size, data_flag)) {
+ tot_weight_true += weights[i];
+ item_true_idx = i;
+ }
+ else {
+ item_false_idx = i;
+ }
+ }
+ best_src_idx = (tot_weight_true >= 0.5f) ? item_true_idx : item_false_idx;
+ }
+ else {
+ /* We just choose highest weighted source. */
+ float max_weight = 0.0f;
+
+ for (i = 0; i < count; i++) {
+ if (weights[i] > max_weight) {
+ max_weight = weights[i];
+ best_src_idx = i;
+ }
+ }
+ }
+ }
+
+ BLI_assert(best_src_idx >= 0);
+
+ if (interp_cd) {
+ interp_cd(sources, weights, NULL, count, tmp_dst);
+ }
+ else if (data_flag) {
+ copy_bit_flag(tmp_dst, sources[best_src_idx], data_size, data_flag);
+ }
+ /* No interpolation, just copy highest weight source element's data. */
+ else if (copy_cd) {
+ copy_cd(sources[best_src_idx], tmp_dst, 1);
+ }
+ else {
+ memcpy(tmp_dst, sources[best_src_idx], data_size);
+ }
+
+ if (data_flag) {
+ /* Bool flags, only copy if dest data is set (resp. unset) - only 'advanced' modes we can support here! */
+ if (mix_factor >= 0.5f &&
+ ((mix_mode == CDT_MIX_TRANSFER) ||
+ (mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && check_bit_flag(data_dst, data_size, data_flag)) ||
+ (mix_mode == CDT_MIX_REPLACE_BELOW_THRESHOLD && !check_bit_flag(data_dst, data_size, data_flag))))
+ {
+ copy_bit_flag(data_dst, tmp_dst, data_size, data_flag);
+ }
+ }
+ else if (!(data_type & CD_FAKE)) {
+ CustomData_data_mix_value(data_type, tmp_dst, data_dst, mix_mode, mix_factor);
+ }
+ /* Else we can do nothing by default, needs custom interp func!
+ * Note this is here only for sake of consistency, not expected to be used much actually? */
+ else {
+ if (mix_factor >= 0.5f) {
+ memcpy(data_dst, tmp_dst, data_size);
+ }
+ }
+
+ MEM_freeN(tmp_dst);
+}
+
+void CustomData_data_transfer(const MeshPairRemap *me_remap, const CustomDataTransferLayerMap *laymap)
+{
+ MeshPairRemapItem *mapit = me_remap->items;
+ const int totelem = me_remap->items_num;
+ int i;
+
+ const int data_type = laymap->data_type;
+ const void *data_src = laymap->data_src;
+ void *data_dst = laymap->data_dst;
+
+ size_t data_step;
+ size_t data_size;
+ size_t data_offset;
+
+ cd_datatransfer_interp interp = NULL;
+
+ size_t tmp_buff_size = 32;
+ const void **tmp_data_src = NULL;
+
+ /* Note: NULL data_src may happen and be valid (see vgroups...). */
+ if (!data_dst) {
+ return;
+ }
+
+ if (data_src) {
+ tmp_data_src = MEM_mallocN(sizeof(*tmp_data_src) * tmp_buff_size, __func__);
+ }
+
+ if (data_type & CD_FAKE) {
+ data_step = laymap->elem_size;
+ data_size = laymap->data_size;
+ data_offset = laymap->data_offset;
+ }
+ else {
+ const LayerTypeInfo *type_info = layerType_getInfo(data_type);
+
+ /* Note: we can use 'fake' CDLayers, like e.g. for crease, bweight, etc. :/ */
+ data_size = (size_t)type_info->size;
+ data_step = laymap->elem_size ? laymap->elem_size : data_size;
+ data_offset = laymap->data_offset;
+ }
+
+ interp = laymap->interp ? laymap->interp : customdata_data_transfer_interp_generic;
+
+ for (i = 0; i < totelem; i++, data_dst = POINTER_OFFSET(data_dst, data_step), mapit++) {
+ const int sources_num = mapit->sources_num;
+ const float mix_factor = laymap->mix_weights ? laymap->mix_weights[i] : laymap->mix_factor;
+ int j;
+
+ if (!sources_num) {
+ /* No sources for this element, skip it. */
+ continue;
+ }
+
+ if (tmp_data_src) {
+ if (UNLIKELY(sources_num > tmp_buff_size)) {
+ tmp_buff_size = (size_t)sources_num;
+ tmp_data_src = MEM_reallocN(tmp_data_src, sizeof(*tmp_data_src) * tmp_buff_size);
+ }
+
+ for (j = 0; j < sources_num; j++) {
+ const size_t src_idx = (size_t)mapit->indices_src[j];
+ tmp_data_src[j] = POINTER_OFFSET(data_src, (data_step * src_idx) + data_offset);
+ }
+ }
+
+ interp(laymap, POINTER_OFFSET(data_dst, data_offset), tmp_data_src, mapit->weights_src, sources_num, mix_factor);
+ }
+
+ MEM_SAFE_FREE(tmp_data_src);
+}
diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c
index c72eea50e40..41579aaa568 100644
--- a/source/blender/blenkernel/intern/customdata_file.c
+++ b/source/blender/blenkernel/intern/customdata_file.c
@@ -276,7 +276,7 @@ static int cdf_write_header(CDataFile *cdf)
return 1;
}
-int cdf_read_open(CDataFile *cdf, const char *filename)
+bool cdf_read_open(CDataFile *cdf, const char *filename)
{
FILE *f;
@@ -299,7 +299,7 @@ int cdf_read_open(CDataFile *cdf, const char *filename)
return 1;
}
-int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay)
+bool cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay)
{
size_t offset;
int a;
@@ -316,7 +316,7 @@ int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay)
return (fseek(cdf->readf, offset, SEEK_SET) == 0);
}
-int cdf_read_data(CDataFile *cdf, unsigned int size, void *data)
+bool cdf_read_data(CDataFile *cdf, unsigned int size, void *data)
{
/* read data */
if (!fread(data, size, 1, cdf->readf))
@@ -338,7 +338,7 @@ void cdf_read_close(CDataFile *cdf)
}
}
-int cdf_write_open(CDataFile *cdf, const char *filename)
+bool cdf_write_open(CDataFile *cdf, const char *filename)
{
CDataFileHeader *header;
CDataFileImageHeader *image;
@@ -380,12 +380,12 @@ int cdf_write_open(CDataFile *cdf, const char *filename)
return 1;
}
-int cdf_write_layer(CDataFile *UNUSED(cdf), CDataFileLayer *UNUSED(blay))
+bool cdf_write_layer(CDataFile *UNUSED(cdf), CDataFileLayer *UNUSED(blay))
{
return 1;
}
-int cdf_write_data(CDataFile *cdf, unsigned int size, void *data)
+bool cdf_write_data(CDataFile *cdf, unsigned int size, void *data)
{
/* write data */
if (!fwrite(data, size, 1, cdf->writef))
@@ -417,7 +417,7 @@ CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, const char *name)
for (a = 0; a < cdf->totlayer; a++) {
layer = &cdf->layer[a];
- if (layer->type == type && strcmp(layer->name, name) == 0)
+ if (layer->type == type && STREQ(layer->name, name))
return layer;
}
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
new file mode 100644
index 00000000000..8f6d4385b55
--- /dev/null
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -0,0 +1,1370 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 by Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Bastien Montagne.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/data_transfer.c
+ * \ingroup bke
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_customdata_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BLI_array.h"
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_data_transfer.h"
+#include "BKE_deform.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_remap.h"
+#include "BKE_object.h"
+#include "BKE_object_deform.h"
+#include "BKE_report.h"
+
+#include "data_transfer_intern.h"
+
+
+CustomDataMask BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types)
+{
+ CustomDataMask cddata_mask = 0;
+ int i;
+
+ for (i = 0; i < DT_TYPE_MAX; i++) {
+ const int dtdata_type = 1 << i;
+ int cddata_type;
+
+ if (!(dtdata_types & dtdata_type)) {
+ continue;
+ }
+
+ cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
+ if (!(cddata_type & CD_FAKE)) {
+ cddata_mask |= 1LL << cddata_type;
+ }
+ else if (cddata_type == CD_FAKE_MDEFORMVERT) {
+ cddata_mask |= CD_MASK_MDEFORMVERT; /* Exception for vgroups :/ */
+ }
+ else if (cddata_type == CD_FAKE_UV) {
+ cddata_mask |= CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV;
+ }
+ else if (cddata_type == CD_FAKE_LNOR) {
+ cddata_mask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL;
+ }
+ }
+
+ return cddata_mask;
+}
+
+/* Check what can do each layer type (if it is actually handled by transferdata, if it supports advanced mixing... */
+bool BKE_object_data_transfer_get_dttypes_capacity(
+ const int dtdata_types, bool *r_advanced_mixing, bool *r_threshold)
+{
+ int i;
+ bool ret = false;
+
+ *r_advanced_mixing = false;
+ *r_threshold = false;
+
+ for (i = 0; (i < DT_TYPE_MAX) && !(ret && *r_advanced_mixing && *r_threshold); i++) {
+ const int dtdata_type = 1 << i;
+
+ if (!(dtdata_types & dtdata_type)) {
+ continue;
+ }
+
+ switch (dtdata_type) {
+ /* Vertex data */
+ case DT_TYPE_MDEFORMVERT:
+ *r_advanced_mixing = true;
+ *r_threshold = true;
+ ret = true;
+ break;
+ case DT_TYPE_SKIN:
+ *r_threshold = true;
+ ret = true;
+ break;
+ case DT_TYPE_BWEIGHT_VERT:
+ ret = true;
+ break;
+ /* Edge data */
+ case DT_TYPE_SHARP_EDGE:
+ *r_threshold = true;
+ ret = true;
+ break;
+ case DT_TYPE_SEAM:
+ *r_threshold = true;
+ ret = true;
+ break;
+ case DT_TYPE_CREASE:
+ ret = true;
+ break;
+ case DT_TYPE_BWEIGHT_EDGE:
+ ret = true;
+ break;
+ case DT_TYPE_FREESTYLE_EDGE:
+ *r_threshold = true;
+ ret = true;
+ break;
+ /* Loop/Poly data */
+ case DT_TYPE_UV:
+ ret = true;
+ break;
+ case DT_TYPE_VCOL:
+ *r_advanced_mixing = true;
+ *r_threshold = true;
+ ret = true;
+ break;
+ case DT_TYPE_LNOR:
+ *r_advanced_mixing = true;
+ ret = true;
+ break;
+ case DT_TYPE_SHARP_FACE:
+ *r_threshold = true;
+ ret = true;
+ break;
+ case DT_TYPE_FREESTYLE_FACE:
+ *r_threshold = true;
+ ret = true;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+int BKE_object_data_transfer_get_dttypes_item_types(const int dtdata_types)
+{
+ int i, ret = 0;
+
+ for (i = 0; (i < DT_TYPE_MAX) && (ret ^ (ME_VERT | ME_EDGE | ME_LOOP | ME_POLY)); i++) {
+ const int dtdata_type = 1 << i;
+
+ if (!(dtdata_types & dtdata_type)) {
+ continue;
+ }
+
+ if (DT_DATATYPE_IS_VERT(dtdata_type)) {
+ ret |= ME_VERT;
+ }
+ if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
+ ret |= ME_EDGE;
+ }
+ if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
+ ret |= ME_LOOP;
+ }
+ if (DT_DATATYPE_IS_POLY(dtdata_type)) {
+ ret |= ME_POLY;
+ }
+ }
+
+ return ret;
+}
+
+int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type)
+{
+ switch (dtdata_type) {
+ case DT_TYPE_MDEFORMVERT:
+ return CD_FAKE_MDEFORMVERT;
+ case DT_TYPE_SHAPEKEY:
+ return CD_FAKE_SHAPEKEY;
+ case DT_TYPE_SKIN:
+ return CD_MVERT_SKIN;
+ case DT_TYPE_BWEIGHT_VERT:
+ return CD_FAKE_BWEIGHT;
+
+ case DT_TYPE_SHARP_EDGE:
+ return CD_FAKE_SHARP;
+ case DT_TYPE_SEAM:
+ return CD_FAKE_SEAM;
+ case DT_TYPE_CREASE:
+ return CD_FAKE_CREASE;
+ case DT_TYPE_BWEIGHT_EDGE:
+ return CD_FAKE_BWEIGHT;
+ case DT_TYPE_FREESTYLE_EDGE:
+ return CD_FREESTYLE_EDGE;
+
+ case DT_TYPE_UV:
+ return CD_FAKE_UV;
+ case DT_TYPE_SHARP_FACE:
+ return CD_FAKE_SHARP;
+ case DT_TYPE_FREESTYLE_FACE:
+ return CD_FREESTYLE_FACE;
+
+ case DT_TYPE_VCOL:
+ return CD_MLOOPCOL;
+ case DT_TYPE_LNOR:
+ return CD_FAKE_LNOR;
+
+ default:
+ BLI_assert(0);
+ }
+ return 0; /* Should never be reached! */
+}
+
+int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type)
+{
+ switch (dtdata_type) {
+ case DT_TYPE_MDEFORMVERT:
+ return DT_MULTILAYER_INDEX_MDEFORMVERT;
+ case DT_TYPE_SHAPEKEY:
+ return DT_MULTILAYER_INDEX_SHAPEKEY;
+ case DT_TYPE_UV:
+ return DT_MULTILAYER_INDEX_UV;
+ case DT_TYPE_VCOL:
+ return DT_MULTILAYER_INDEX_VCOL;
+ default:
+ return DT_MULTILAYER_INDEX_INVALID;
+ }
+}
+
+/* ********** */
+
+/* Generic pre/post processing, only used by custom loop normals currently. */
+
+static void data_transfer_dtdata_type_preprocess(
+ Object *UNUSED(ob_src), Object *UNUSED(ob_dst), DerivedMesh *dm_src, DerivedMesh *dm_dst, Mesh *me_dst,
+ const int dtdata_type, const bool dirty_nors_dst, const bool use_split_nors_src, const float split_angle_src)
+{
+ if (dtdata_type == DT_TYPE_LNOR) {
+ /* Compute custom normals into regular loop normals, which will be used for the transfer. */
+ MVert *verts_dst = dm_dst ? dm_dst->getVertArray(dm_dst) : me_dst->mvert;
+ const int num_verts_dst = dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert;
+ MEdge *edges_dst = dm_dst ? dm_dst->getEdgeArray(dm_dst) : me_dst->medge;
+ const int num_edges_dst = dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge;
+ MPoly *polys_dst = dm_dst ? dm_dst->getPolyArray(dm_dst) : me_dst->mpoly;
+ const int num_polys_dst = dm_dst ? dm_dst->getNumPolys(dm_dst) : me_dst->totpoly;
+ MLoop *loops_dst = dm_dst ? dm_dst->getLoopArray(dm_dst) : me_dst->mloop;
+ const int num_loops_dst = dm_dst ? dm_dst->getNumLoops(dm_dst) : me_dst->totloop;
+ CustomData *pdata_dst = dm_dst ? dm_dst->getPolyDataLayout(dm_dst) : &me_dst->pdata;
+ CustomData *ldata_dst = dm_dst ? dm_dst->getLoopDataLayout(dm_dst) : &me_dst->ldata;
+
+ const bool use_split_nors_dst = (me_dst->flag & ME_AUTOSMOOTH) != 0;
+ const float split_angle_dst = me_dst->smoothresh;
+
+ dm_src->calcLoopNormals(dm_src, use_split_nors_src, split_angle_src);
+
+ if (dm_dst) {
+ dm_dst->calcLoopNormals(dm_dst, use_split_nors_dst, split_angle_dst);
+ }
+ else {
+ float (*poly_nors_dst)[3];
+ float (*loop_nors_dst)[3];
+ short (*custom_nors_dst)[2] = CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL);
+
+ /* Cache poly nors into a temp CDLayer. */
+ poly_nors_dst = CustomData_get_layer(pdata_dst, CD_NORMAL);
+ if (dirty_nors_dst || !poly_nors_dst) {
+ if (!poly_nors_dst) {
+ poly_nors_dst = CustomData_add_layer(pdata_dst, CD_NORMAL, CD_CALLOC, NULL, num_polys_dst);
+ CustomData_set_layer_flag(pdata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
+ BKE_mesh_calc_normals_poly(verts_dst, num_verts_dst, loops_dst, polys_dst,
+ num_loops_dst, num_polys_dst, poly_nors_dst, true);
+ }
+ /* Cache loop nors into a temp CDLayer. */
+ loop_nors_dst = CustomData_get_layer(ldata_dst, CD_NORMAL);
+ if (dirty_nors_dst || loop_nors_dst) {
+ if (!loop_nors_dst) {
+ loop_nors_dst = CustomData_add_layer(ldata_dst, CD_NORMAL, CD_CALLOC, NULL, num_loops_dst);
+ CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
+ BKE_mesh_normals_loop_split(verts_dst, num_verts_dst, edges_dst, num_edges_dst,
+ loops_dst, loop_nors_dst, num_loops_dst,
+ polys_dst, (const float (*)[3])poly_nors_dst, num_polys_dst,
+ use_split_nors_dst, split_angle_dst, NULL, custom_nors_dst, NULL);
+ }
+ }
+ }
+}
+
+static void data_transfer_dtdata_type_postprocess(
+ Object *UNUSED(ob_src), Object *UNUSED(ob_dst), DerivedMesh *UNUSED(dm_src), DerivedMesh *dm_dst, Mesh *me_dst,
+ const int dtdata_type, const bool changed)
+{
+ if (dtdata_type == DT_TYPE_LNOR) {
+ /* Bake edited destination loop normals into custom normals again. */
+ MVert *verts_dst = dm_dst ? dm_dst->getVertArray(dm_dst) : me_dst->mvert;
+ const int num_verts_dst = dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert;
+ MEdge *edges_dst = dm_dst ? dm_dst->getEdgeArray(dm_dst) : me_dst->medge;
+ const int num_edges_dst = dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge;
+ MPoly *polys_dst = dm_dst ? dm_dst->getPolyArray(dm_dst) : me_dst->mpoly;
+ const int num_polys_dst = dm_dst ? dm_dst->getNumPolys(dm_dst) : me_dst->totpoly;
+ MLoop *loops_dst = dm_dst ? dm_dst->getLoopArray(dm_dst) : me_dst->mloop;
+ const int num_loops_dst = dm_dst ? dm_dst->getNumLoops(dm_dst) : me_dst->totloop;
+ CustomData *pdata_dst = dm_dst ? dm_dst->getPolyDataLayout(dm_dst) : &me_dst->pdata;
+ CustomData *ldata_dst = dm_dst ? dm_dst->getLoopDataLayout(dm_dst) : &me_dst->ldata;
+
+ const float (*poly_nors_dst)[3] = CustomData_get_layer(pdata_dst, CD_NORMAL);
+ float (*loop_nors_dst)[3] = CustomData_get_layer(ldata_dst, CD_NORMAL);
+ short (*custom_nors_dst)[2] = CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL);
+
+ BLI_assert(poly_nors_dst);
+
+ if (!changed) {
+ return;
+ }
+
+ if (!custom_nors_dst) {
+ custom_nors_dst = CustomData_add_layer(ldata_dst, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, num_loops_dst);
+ }
+
+ /* Note loop_nors_dst contains our custom normals as transferred from source... */
+ BKE_mesh_normals_loop_custom_set(verts_dst, num_verts_dst, edges_dst, num_edges_dst,
+ loops_dst, loop_nors_dst, num_loops_dst,
+ polys_dst, poly_nors_dst, num_polys_dst,
+ custom_nors_dst);
+ }
+}
+
+/* ********** */
+
+static MeshRemapIslandsCalc data_transfer_get_loop_islands_generator(const int cddata_type)
+{
+ switch (cddata_type) {
+ case CD_FAKE_UV:
+ return BKE_mesh_calc_islands_loop_poly_uv;
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+float data_transfer_interp_float_do(
+ const int mix_mode, const float val_dst, const float val_src, const float mix_factor)
+{
+ float val_ret;
+
+ if (((mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && (val_dst < mix_factor)) ||
+ (mix_mode == CDT_MIX_REPLACE_BELOW_THRESHOLD && (val_dst > mix_factor))))
+ {
+ return val_dst; /* Do not affect destination. */
+ }
+
+ switch (mix_mode) {
+ case CDT_MIX_REPLACE_ABOVE_THRESHOLD:
+ case CDT_MIX_REPLACE_BELOW_THRESHOLD:
+ return val_src;
+ case CDT_MIX_MIX:
+ val_ret = (val_dst + val_src) * 0.5f;
+ break;
+ case CDT_MIX_ADD:
+ val_ret = val_dst + val_src;
+ break;
+ case CDT_MIX_SUB:
+ val_ret = val_dst - val_src;
+ break;
+ case CDT_MIX_MUL:
+ val_ret = val_dst * val_src;
+ break;
+ case CDT_MIX_TRANSFER:
+ default:
+ val_ret = val_src;
+ break;
+ }
+ return interpf(val_ret, val_dst, mix_factor);
+}
+
+static void data_transfer_interp_char(
+ const CustomDataTransferLayerMap *laymap, void *dest,
+ const void **sources, const float *weights, const int count, const float mix_factor)
+{
+ const char **data_src = (const char **)sources;
+ char *data_dst = (char *)dest;
+
+ const int mix_mode = laymap->mix_mode;
+ float val_src = 0.0f;
+ const float val_dst = (float)(*data_dst) / 255.0f;
+
+ int i;
+
+ for (i = count; i--;) {
+ val_src += ((float)(*data_src[i]) / 255.0f) * weights[i];
+ }
+
+ val_src = data_transfer_interp_float_do(mix_mode, val_dst, val_src, mix_factor);
+
+ CLAMP(val_src, 0.0f, 1.0f);
+
+ *data_dst = (char)(val_src * 255.0f);
+}
+
+/* Helpers to match sources and destinations data layers (also handles 'conversions' in CD_FAKE cases). */
+
+void data_transfer_layersmapping_add_item(
+ ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights,
+ const void *data_src, void *data_dst, const int data_src_n, const int data_dst_n,
+ const size_t elem_size, const size_t data_size, const size_t data_offset, const uint64_t data_flag,
+ cd_datatransfer_interp interp)
+{
+ CustomDataTransferLayerMap *item = MEM_mallocN(sizeof(*item), __func__);
+
+ BLI_assert(data_dst != NULL);
+
+ item->data_type = cddata_type;
+ item->mix_mode = mix_mode;
+ item->mix_factor = mix_factor;
+ item->mix_weights = mix_weights;
+
+ item->data_src = data_src;
+ item->data_dst = data_dst;
+ item->data_src_n = data_src_n;
+ item->data_dst_n = data_dst_n;
+ item->elem_size = elem_size;
+
+ item->data_size = data_size;
+ item->data_offset = data_offset;
+ item->data_flag = data_flag;
+
+ item->interp = interp;
+
+ BLI_addtail(r_map, item);
+}
+
+static void data_transfer_layersmapping_add_item_cd(
+ ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights,
+ void *data_src, void *data_dst)
+{
+ data_transfer_layersmapping_add_item(
+ r_map, cddata_type, mix_mode, mix_factor, mix_weights, data_src, data_dst,
+ 0, 0, 0, 0, 0, 0, NULL);
+}
+
+/* Note: All those layer mapping handlers return false *only* if they were given invalid parameters.
+ * This means that even if they do nothing, they will return true if all given parameters were OK.
+ * Also, r_map may be NULL, in which case they will 'only' create/delete destination layers according
+ * to given parameters.
+ */
+
+static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(
+ ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights,
+ const int num_elem_dst, const bool use_create, const bool use_delete,
+ CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst,
+ const int tolayers, bool *use_layers_src, const int num_layers_src)
+{
+ void *data_src, *data_dst = NULL;
+ int idx_src = num_layers_src;
+ int idx_dst, tot_dst = CustomData_number_of_layers(cd_dst, cddata_type);
+ bool *data_dst_to_delete = NULL;
+
+ if (!use_layers_src) {
+ /* No source at all, we can only delete all dest if requested... */
+ if (use_delete) {
+ idx_dst = tot_dst;
+ while (idx_dst--) {
+ CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, idx_dst);
+ }
+ }
+ return true;
+ }
+
+ switch (tolayers) {
+ case DT_LAYERS_INDEX_DST:
+ idx_dst = tot_dst;
+
+ /* Find last source actually used! */
+ while (idx_src-- && !use_layers_src[idx_src]);
+ idx_src++;
+
+ if (idx_dst < idx_src) {
+ if (!use_create) {
+ return true;
+ }
+ /* Create as much data layers as necessary! */
+ for (; idx_dst < idx_src; idx_dst++) {
+ CustomData_add_layer(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst);
+ }
+ }
+ else if (use_delete && idx_dst > idx_src) {
+ while (idx_dst-- > idx_src) {
+ CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, idx_dst);
+ }
+ }
+ if (r_map) {
+ while (idx_src--) {
+ if (!use_layers_src[idx_src]) {
+ continue;
+ }
+ data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src);
+ /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */
+ if (use_dupref_dst) {
+ data_dst = CustomData_duplicate_referenced_layer_n(cd_dst, cddata_type, idx_src, num_elem_dst);
+ }
+ else {
+ data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_src);
+ }
+ data_transfer_layersmapping_add_item_cd(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ data_src, data_dst);
+ }
+ }
+ break;
+ case DT_LAYERS_NAME_DST:
+ if (use_delete) {
+ if (tot_dst) {
+ data_dst_to_delete = MEM_mallocN(sizeof(*data_dst_to_delete) * (size_t)tot_dst, __func__);
+ memset(data_dst_to_delete, true, sizeof(*data_dst_to_delete) * (size_t)tot_dst);
+ }
+ }
+
+ while (idx_src--) {
+ const char *name;
+
+ if (!use_layers_src[idx_src]) {
+ continue;
+ }
+
+ name = CustomData_get_layer_name(cd_src, cddata_type, idx_src);
+ data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src);
+
+ if ((idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name)) == -1) {
+ if (!use_create) {
+ if (r_map) {
+ BLI_freelistN(r_map);
+ }
+ return true;
+ }
+ CustomData_add_layer_named(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst, name);
+ idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name);
+ }
+ else if (data_dst_to_delete) {
+ data_dst_to_delete[idx_dst] = false;
+ }
+ if (r_map) {
+ /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */
+ if (use_dupref_dst) {
+ data_dst = CustomData_duplicate_referenced_layer_n(cd_dst, cddata_type, idx_dst, num_elem_dst);
+ }
+ else {
+ data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
+ }
+ data_transfer_layersmapping_add_item_cd(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ data_src, data_dst);
+ }
+ }
+
+ if (data_dst_to_delete) {
+ /* Note: This won't affect newly created layers, if any, since tot_dst has not been updated!
+ * Also, looping backward ensures us we do not suffer from index shifting when deleting a layer.
+ */
+ for (idx_dst = tot_dst; idx_dst--;) {
+ if (data_dst_to_delete[idx_dst]) {
+ CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, idx_dst);
+ }
+ }
+
+ MEM_freeN(data_dst_to_delete);
+ }
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+static bool data_transfer_layersmapping_cdlayers(
+ ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights,
+ const int num_elem_dst, const bool use_create, const bool use_delete,
+ CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst,
+ const int fromlayers, const int tolayers)
+{
+ int idx_src, idx_dst;
+ void *data_src, *data_dst = NULL;
+
+ if (CustomData_layertype_is_singleton(cddata_type)) {
+ if (!(data_src = CustomData_get_layer(cd_src, cddata_type))) {
+ if (use_delete) {
+ CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, 0);
+ }
+ return true;
+ }
+
+ data_dst = CustomData_get_layer(cd_dst, cddata_type);
+ if (!data_dst) {
+ if (!use_create) {
+ return true;
+ }
+ data_dst = CustomData_add_layer(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst);
+ }
+ else if (use_dupref_dst && r_map) {
+ /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */
+ data_dst = CustomData_duplicate_referenced_layer(cd_dst, cddata_type, num_elem_dst);
+ }
+
+ if (r_map) {
+ data_transfer_layersmapping_add_item_cd(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ data_src, data_dst);
+ }
+ }
+ else if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) {
+ /* Note: use_delete has not much meaning in this case, ignored. */
+
+ if (fromlayers >= 0) { /* Real-layer index */
+ idx_src = fromlayers;
+ }
+ else {
+ if ((idx_src = CustomData_get_active_layer(cd_src, cddata_type)) == -1) {
+ return true;
+ }
+ }
+ data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src);
+ if (!data_src) {
+ return true;
+ }
+
+ if (tolayers >= 0) { /* Real-layer index */
+ idx_dst = tolayers;
+ /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */
+ if (use_dupref_dst && r_map) {
+ data_dst = CustomData_duplicate_referenced_layer_n(cd_dst, cddata_type, idx_dst, num_elem_dst);
+ }
+ else {
+ data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
+ }
+ }
+ else if (tolayers == DT_LAYERS_ACTIVE_DST) {
+ if ((idx_dst = CustomData_get_active_layer(cd_dst, cddata_type)) == -1) {
+ if (!use_create) {
+ return true;
+ }
+ data_dst = CustomData_add_layer(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst);
+ }
+ else {
+ /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */
+ if (use_dupref_dst && r_map) {
+ data_dst = CustomData_duplicate_referenced_layer_n(cd_dst, cddata_type, idx_dst, num_elem_dst);
+ }
+ else {
+ data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
+ }
+ }
+ }
+ else if (tolayers == DT_LAYERS_INDEX_DST) {
+ int num = CustomData_number_of_layers(cd_dst, cddata_type);
+ idx_dst = idx_src;
+ if (num <= idx_dst) {
+ if (!use_create) {
+ return true;
+ }
+ /* Create as much data layers as necessary! */
+ for (; num <= idx_dst; num++) {
+ CustomData_add_layer(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst);
+ }
+ }
+ /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */
+ if (use_dupref_dst && r_map) {
+ data_dst = CustomData_duplicate_referenced_layer_n(cd_dst, cddata_type, idx_dst, num_elem_dst);
+ }
+ else {
+ data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
+ }
+ }
+ else if (tolayers == DT_LAYERS_NAME_DST) {
+ const char *name = CustomData_get_layer_name(cd_src, cddata_type, idx_src);
+ if ((idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name)) == -1) {
+ if (!use_create) {
+ return true;
+ }
+ CustomData_add_layer_named(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst, name);
+ idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name);
+ }
+ /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */
+ if (use_dupref_dst && r_map) {
+ data_dst = CustomData_duplicate_referenced_layer_n(cd_dst, cddata_type, idx_dst, num_elem_dst);
+ }
+ else {
+ data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
+ }
+ }
+ else {
+ return false;
+ }
+
+ if (!data_dst) {
+ return false;
+ }
+
+ if (r_map) {
+ data_transfer_layersmapping_add_item_cd(
+ r_map, cddata_type, mix_mode, mix_factor, mix_weights, data_src, data_dst);
+ }
+ }
+ else if (fromlayers == DT_LAYERS_ALL_SRC) {
+ int num_src = CustomData_number_of_layers(cd_src, cddata_type);
+ bool *use_layers_src = num_src ? MEM_mallocN(sizeof(*use_layers_src) * (size_t)num_src, __func__) : NULL;
+ bool ret;
+
+ if (use_layers_src) {
+ memset(use_layers_src, true, sizeof(*use_layers_src) * num_src);
+ }
+
+ ret = data_transfer_layersmapping_cdlayers_multisrc_to_dst(
+ r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ num_elem_dst, use_create, use_delete, cd_src, cd_dst, use_dupref_dst,
+ tolayers, use_layers_src, num_src);
+
+ if (use_layers_src) {
+ MEM_freeN(use_layers_src);
+ }
+ return ret;
+ }
+ else {
+ return false;
+ }
+
+ return true;
+}
+
+static bool data_transfer_layersmapping_generate(
+ ListBase *r_map, Object *ob_src, Object *ob_dst, DerivedMesh *dm_src, DerivedMesh *dm_dst, Mesh *me_dst,
+ const int elem_type, int cddata_type, int mix_mode, float mix_factor, const float *mix_weights,
+ const int num_elem_dst, const bool use_create, const bool use_delete, const int fromlayers, const int tolayers)
+{
+ CustomData *cd_src, *cd_dst;
+
+ if (elem_type == ME_VERT) {
+ if (!(cddata_type & CD_FAKE)) {
+ cd_src = dm_src->getVertDataLayout(dm_src);
+ cd_dst = dm_dst ? dm_dst->getVertDataLayout(dm_dst) : &me_dst->vdata;
+
+ if (!data_transfer_layersmapping_cdlayers(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ num_elem_dst, use_create, use_delete,
+ cd_src, cd_dst, dm_dst != NULL,
+ fromlayers, tolayers))
+ {
+ /* We handle specific source selection cases here. */
+ return false;
+ }
+ return true;
+ }
+ else if (cddata_type == CD_FAKE_BWEIGHT) {
+ const size_t elem_size = sizeof(*((MVert *)NULL));
+ const size_t data_size = sizeof(((MVert *)NULL)->bweight);
+ const size_t data_offset = offsetof(MVert, bweight);
+ const uint64_t data_flag = 0;
+
+ if (!(dm_src->cd_flag & ME_CDFLAG_VERT_BWEIGHT)) {
+ if (use_delete && !dm_dst) {
+ me_dst->cd_flag &= ~ME_CDFLAG_VERT_BWEIGHT;
+ }
+ return true;
+ }
+ if (dm_dst) {
+ dm_dst->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ }
+ else {
+ me_dst->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ }
+ if (r_map) {
+ data_transfer_layersmapping_add_item(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ dm_src->getVertArray(dm_src),
+ dm_dst ? dm_dst->getVertArray(dm_dst) : me_dst->mvert,
+ dm_src->getNumVerts(dm_src),
+ dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert,
+ elem_size, data_size, data_offset, data_flag,
+ data_transfer_interp_char);
+ }
+ return true;
+ }
+ else if (cddata_type == CD_FAKE_MDEFORMVERT) {
+ bool ret;
+
+ cd_src = dm_src->getVertDataLayout(dm_src);
+ cd_dst = dm_dst ? dm_dst->getVertDataLayout(dm_dst) : &me_dst->vdata;
+
+ ret = data_transfer_layersmapping_vgroups(r_map, mix_mode, mix_factor, mix_weights,
+ num_elem_dst, use_create, use_delete,
+ ob_src, ob_dst, cd_src, cd_dst, dm_dst != NULL,
+ fromlayers, tolayers);
+
+ /* Mesh stores its dvert in a specific pointer too. :( */
+ me_dst->dvert = CustomData_get_layer(&me_dst->vdata, CD_MDEFORMVERT);
+ return ret;
+ }
+ else if (cddata_type == CD_FAKE_SHAPEKEY) {
+ /* TODO: leaving shapekeys asside for now, quite specific case, since we can't access them from MVert :/ */
+ return false;
+ }
+ }
+ else if (elem_type == ME_EDGE) {
+ if (!(cddata_type & CD_FAKE)) { /* Unused for edges, currently... */
+ cd_src = dm_src->getEdgeDataLayout(dm_src);
+ cd_dst = dm_dst ? dm_dst->getEdgeDataLayout(dm_dst) : &me_dst->edata;
+
+ if (!data_transfer_layersmapping_cdlayers(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ num_elem_dst, use_create, use_delete,
+ cd_src, cd_dst, dm_dst != NULL,
+ fromlayers, tolayers))
+ {
+ /* We handle specific source selection cases here. */
+ return false;
+ }
+ return true;
+ }
+ else if (cddata_type == CD_FAKE_CREASE) {
+ const size_t elem_size = sizeof(*((MEdge *)NULL));
+ const size_t data_size = sizeof(((MEdge *)NULL)->crease);
+ const size_t data_offset = offsetof(MEdge, crease);
+ const uint64_t data_flag = 0;
+
+ if (!(dm_src->cd_flag & ME_CDFLAG_EDGE_CREASE)) {
+ if (use_delete && !dm_dst) {
+ me_dst->cd_flag &= ~ME_CDFLAG_EDGE_CREASE;
+ }
+ return true;
+ }
+ if (dm_dst) {
+ dm_dst->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ }
+ else {
+ me_dst->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ }
+ if (r_map) {
+ data_transfer_layersmapping_add_item(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ dm_src->getEdgeArray(dm_src),
+ dm_dst ? dm_dst->getEdgeArray(dm_dst) : me_dst->medge,
+ dm_src->getNumEdges(dm_src),
+ dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge,
+ elem_size, data_size, data_offset, data_flag,
+ data_transfer_interp_char);
+ }
+ return true;
+ }
+ else if (cddata_type == CD_FAKE_BWEIGHT) {
+ const size_t elem_size = sizeof(*((MEdge *)NULL));
+ const size_t data_size = sizeof(((MEdge *)NULL)->bweight);
+ const size_t data_offset = offsetof(MEdge, bweight);
+ const uint64_t data_flag = 0;
+
+ if (!(dm_src->cd_flag & ME_CDFLAG_EDGE_BWEIGHT)) {
+ if (use_delete && !dm_dst) {
+ me_dst->cd_flag &= ~ME_CDFLAG_EDGE_BWEIGHT;
+ }
+ return true;
+ }
+ if (dm_dst) {
+ dm_dst->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ }
+ else {
+ me_dst->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ }
+ if (r_map) {
+ data_transfer_layersmapping_add_item(r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ dm_src->getEdgeArray(dm_src),
+ dm_dst ? dm_dst->getEdgeArray(dm_dst) : me_dst->medge,
+ dm_src->getNumEdges(dm_src),
+ dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge,
+ elem_size, data_size, data_offset, data_flag,
+ data_transfer_interp_char);
+ }
+ return true;
+ }
+ else if (r_map && ELEM(cddata_type, CD_FAKE_SHARP, CD_FAKE_SEAM)) {
+ const size_t elem_size = sizeof(*((MEdge *)NULL));
+ const size_t data_size = sizeof(((MEdge *)NULL)->flag);
+ const size_t data_offset = offsetof(MEdge, flag);
+ const uint64_t data_flag = (cddata_type == CD_FAKE_SHARP) ? ME_SHARP : ME_SEAM;
+
+ data_transfer_layersmapping_add_item(
+ r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ dm_src->getEdgeArray(dm_src),
+ dm_dst ? dm_dst->getEdgeArray(dm_dst) : me_dst->medge,
+ dm_src->getNumEdges(dm_src),
+ dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge,
+ elem_size, data_size, data_offset, data_flag, NULL);
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else if (elem_type == ME_LOOP) {
+ if (cddata_type == CD_FAKE_UV) {
+ cddata_type = CD_MLOOPUV;
+ }
+ else if (cddata_type == CD_FAKE_LNOR) {
+ /* Preprocess should have generated it, Postprocess will convert it back to CD_CUSTOMLOOPNORMAL. */
+ cddata_type = CD_NORMAL;
+ }
+
+ if (!(cddata_type & CD_FAKE)) {
+ cd_src = dm_src->getLoopDataLayout(dm_src);
+ cd_dst = dm_dst ? dm_dst->getLoopDataLayout(dm_dst) : &me_dst->ldata;
+
+ if (!data_transfer_layersmapping_cdlayers(
+ r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ num_elem_dst, use_create, use_delete, cd_src, cd_dst, dm_dst != NULL,
+ fromlayers, tolayers))
+ {
+ /* We handle specific source selection cases here. */
+ return false;
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ else if (elem_type == ME_POLY) {
+ if (cddata_type == CD_FAKE_UV) {
+ cddata_type = CD_MTEXPOLY;
+ }
+
+ if (!(cddata_type & CD_FAKE)) {
+ cd_src = dm_src->getPolyDataLayout(dm_src);
+ cd_dst = dm_dst ? dm_dst->getPolyDataLayout(dm_dst) : &me_dst->pdata;
+
+ if (!data_transfer_layersmapping_cdlayers(
+ r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ num_elem_dst, use_create, use_delete, cd_src, cd_dst, dm_dst != NULL,
+ fromlayers, tolayers))
+ {
+ /* We handle specific source selection cases here. */
+ return false;
+ }
+ return true;
+ }
+ else if (r_map && cddata_type == CD_FAKE_SHARP) {
+ const size_t elem_size = sizeof(*((MPoly *)NULL));
+ const size_t data_size = sizeof(((MPoly *)NULL)->flag);
+ const size_t data_offset = offsetof(MPoly, flag);
+ const uint64_t data_flag = ME_SMOOTH;
+
+ data_transfer_layersmapping_add_item(
+ r_map, cddata_type, mix_mode, mix_factor, mix_weights,
+ dm_src->getPolyArray(dm_src),
+ dm_dst ? dm_dst->getPolyArray(dm_dst) : me_dst->mpoly,
+ dm_src->getNumPolys(dm_src),
+ dm_dst ? dm_dst->getNumPolys(dm_dst) : me_dst->totpoly,
+ elem_size, data_size, data_offset, data_flag, NULL);
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Transfer data *layout* of selected types from source to destination object.
+ * By default, it only creates new data layers if needed on \a ob_dst.
+ * If \a use_delete is true, it will also delete data layers on \a ob_dst that do not match those from \a ob_src,
+ * to get (as much as possible) exact copy of source data layout.
+ */
+void BKE_object_data_transfer_layout(
+ Scene *scene, Object *ob_src, Object *ob_dst, const int data_types, const bool use_delete,
+ const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX])
+{
+ DerivedMesh *dm_src;
+ Mesh *me_dst;
+ int i;
+
+ const bool use_create = true; /* We always create needed layers here. */
+
+ CustomDataMask dm_src_mask = CD_MASK_BAREMESH;
+
+ BLI_assert((ob_src != ob_dst) && (ob_src->type == OB_MESH) && (ob_dst->type == OB_MESH));
+
+ me_dst = ob_dst->data;
+
+ /* Get source DM.*/
+ dm_src_mask |= BKE_object_data_transfer_dttypes_to_cdmask(data_types);
+ dm_src = mesh_get_derived_final(scene, ob_src, dm_src_mask);
+ if (!dm_src) {
+ return;
+ }
+
+ /* Check all possible data types. */
+ for (i = 0; i < DT_TYPE_MAX; i++) {
+ const int dtdata_type = 1 << i;
+ int cddata_type;
+ int fromlayers, tolayers, fromto_idx;
+
+ if (!(data_types & dtdata_type)) {
+ continue;
+ }
+
+ cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
+
+ fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(dtdata_type);
+ if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
+ fromlayers = fromlayers_select[fromto_idx];
+ tolayers = tolayers_select[fromto_idx];
+ }
+ else {
+ fromlayers = tolayers = 0;
+ }
+
+ if (DT_DATATYPE_IS_VERT(dtdata_type)) {
+ const int num_elem_dst = me_dst->totvert;
+
+ data_transfer_layersmapping_generate(
+ NULL, ob_src, ob_dst, dm_src, NULL, me_dst, ME_VERT, cddata_type, 0, 0.0f, NULL,
+ num_elem_dst, use_create, use_delete, fromlayers, tolayers);
+ }
+ if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
+ const int num_elem_dst = me_dst->totedge;
+
+ data_transfer_layersmapping_generate(
+ NULL, ob_src, ob_dst, dm_src, NULL, me_dst, ME_EDGE, cddata_type, 0, 0.0f, NULL,
+ num_elem_dst, use_create, use_delete, fromlayers, tolayers);
+ }
+ if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
+ const int num_elem_dst = me_dst->totloop;
+
+ data_transfer_layersmapping_generate(
+ NULL, ob_src, ob_dst, dm_src, NULL, me_dst, ME_LOOP, cddata_type, 0, 0.0f, NULL,
+ num_elem_dst, use_create, use_delete, fromlayers, tolayers);
+ }
+ if (DT_DATATYPE_IS_POLY(dtdata_type)) {
+ const int num_elem_dst = me_dst->totpoly;
+
+ data_transfer_layersmapping_generate(
+ NULL, ob_src, ob_dst, dm_src, NULL, me_dst, ME_POLY, cddata_type, 0, 0.0f, NULL,
+ num_elem_dst, use_create, use_delete, fromlayers, tolayers);
+ }
+ }
+}
+
+bool BKE_object_data_transfer_dm(
+ Scene *scene, Object *ob_src, Object *ob_dst, DerivedMesh *dm_dst, const int data_types, bool use_create,
+ const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode,
+ SpaceTransform *space_transform, const float max_distance, const float ray_radius,
+ const float islands_handling_precision,
+ const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX],
+ const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup,
+ ReportList *reports)
+{
+#define VDATA 0
+#define EDATA 1
+#define LDATA 2
+#define PDATA 3
+#define DATAMAX 4
+
+ DerivedMesh *dm_src;
+ Mesh *me_dst, *me_src;
+ bool dirty_nors_dst = true; /* Assumed always true if not using a dm as destination. */
+ int i;
+
+ MDeformVert *mdef = NULL;
+ int vg_idx = -1;
+ float *weights[DATAMAX] = {NULL};
+
+ MeshPairRemap geom_map[DATAMAX] = {{0}};
+ bool geom_map_init[DATAMAX] = {0};
+ ListBase lay_map = {NULL};
+ bool changed = false;
+
+ const bool use_delete = false; /* We never delete data layers from destination here. */
+
+ CustomDataMask dm_src_mask = CD_MASK_BAREMESH;
+
+ BLI_assert((ob_src != ob_dst) && (ob_src->type == OB_MESH) && (ob_dst->type == OB_MESH));
+
+ me_dst = ob_dst->data;
+ me_src = ob_src->data;
+ if (dm_dst) {
+ dirty_nors_dst = (dm_dst->dirty & DM_DIRTY_NORMALS) != 0;
+ use_create = false; /* Never create needed custom layers on DM (modifier case). */
+ }
+
+ if (vgroup_name) {
+ if (dm_dst) {
+ mdef = dm_dst->getVertDataArray(dm_dst, CD_MDEFORMVERT);
+ }
+ else {
+ mdef = CustomData_get_layer(&me_dst->vdata, CD_MDEFORMVERT);
+ }
+ if (mdef) {
+ vg_idx = defgroup_name_index(ob_dst, vgroup_name);
+ }
+ }
+
+ /* Get source DM.*/
+ dm_src_mask |= BKE_object_data_transfer_dttypes_to_cdmask(data_types);
+ /* XXX Hack! In case this is being evaluated from dm stack, we cannot compute final dm,
+ * can lead to infinite recursion in case of dependency cycles of DataTransfer modifiers...
+ * Issue is, this means we cannot be sure to have requested cd layers in source.
+ */
+ dm_src = dm_dst ? ob_src->derivedFinal : mesh_get_derived_final(scene, ob_src, dm_src_mask);
+ if (!dm_src) {
+ return changed;
+ }
+
+ /* Check all possible data types.
+ * Note item mappings and dest mix weights are cached. */
+ for (i = 0; i < DT_TYPE_MAX; i++) {
+ const int dtdata_type = 1 << i;
+ int cddata_type;
+ int fromlayers, tolayers, fromto_idx;
+
+ if (!(data_types & dtdata_type)) {
+ continue;
+ }
+
+ data_transfer_dtdata_type_preprocess(ob_src, ob_dst, dm_src, dm_dst, me_dst,
+ dtdata_type, dirty_nors_dst,
+ (me_src->flag & ME_AUTOSMOOTH) != 0, me_src->smoothresh);
+
+ cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
+
+ fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(dtdata_type);
+ if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
+ fromlayers = fromlayers_select[fromto_idx];
+ tolayers = tolayers_select[fromto_idx];
+ }
+ else {
+ fromlayers = tolayers = 0;
+ }
+
+ if (DT_DATATYPE_IS_VERT(dtdata_type)) {
+ MVert *verts_dst = dm_dst ? dm_dst->getVertArray(dm_dst) : me_dst->mvert;
+ const int num_verts_dst = dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert;
+
+ if (!geom_map_init[VDATA]) {
+ if ((map_vert_mode == MREMAP_MODE_TOPOLOGY) && (num_verts_dst != dm_src->getNumVerts(dm_src))) {
+ BKE_report(reports, RPT_ERROR,
+ "Source and destination meshes do not have the same amount of vertices, "
+ "'Topology' mapping cannot be used in this case");
+ return changed;
+ }
+ BKE_mesh_remap_calc_verts_from_dm(
+ map_vert_mode, space_transform, max_distance, ray_radius,
+ verts_dst, num_verts_dst, dirty_nors_dst, dm_src, &geom_map[VDATA]);
+ geom_map_init[VDATA] = true;
+ }
+
+ if (mdef && vg_idx != -1 && !weights[VDATA]) {
+ weights[VDATA] = MEM_mallocN(sizeof(*(weights[VDATA])) * (size_t)num_verts_dst, __func__);
+ BKE_defvert_extract_vgroup_to_vertweights(mdef, vg_idx, num_verts_dst, weights[VDATA], invert_vgroup);
+ }
+
+ if (data_transfer_layersmapping_generate(
+ &lay_map, ob_src, ob_dst, dm_src, dm_dst, me_dst, ME_VERT,
+ cddata_type, mix_mode, mix_factor, weights[VDATA],
+ num_verts_dst, use_create, use_delete, fromlayers, tolayers))
+ {
+ CustomDataTransferLayerMap *lay_mapit;
+
+ changed = (lay_map.first != NULL);
+
+ for (lay_mapit = lay_map.first; lay_mapit; lay_mapit = lay_mapit->next) {
+ CustomData_data_transfer(&geom_map[VDATA], lay_mapit);
+ }
+
+ BLI_freelistN(&lay_map);
+ }
+ }
+ if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
+ MVert *verts_dst = dm_dst ? dm_dst->getVertArray(dm_dst) : me_dst->mvert;
+ const int num_verts_dst = dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert;
+ MEdge *edges_dst = dm_dst ? dm_dst->getEdgeArray(dm_dst) : me_dst->medge;
+ const int num_edges_dst = dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge;
+
+ if (!geom_map_init[EDATA]) {
+ if ((map_edge_mode == MREMAP_MODE_TOPOLOGY) && (num_edges_dst != dm_src->getNumEdges(dm_src))) {
+ BKE_report(reports, RPT_ERROR,
+ "Source and destination meshes do not have the same amount of edges, "
+ "'Topology' mapping cannot be used in this case");
+ return changed;
+ }
+ BKE_mesh_remap_calc_edges_from_dm(
+ map_edge_mode, space_transform, max_distance, ray_radius,
+ verts_dst, num_verts_dst, edges_dst, num_edges_dst, dirty_nors_dst,
+ dm_src, &geom_map[EDATA]);
+ geom_map_init[EDATA] = true;
+ }
+
+ if (mdef && vg_idx != -1 && !weights[EDATA]) {
+ weights[EDATA] = MEM_mallocN(sizeof(*weights[EDATA]) * (size_t)num_edges_dst, __func__);
+ BKE_defvert_extract_vgroup_to_edgeweights(
+ mdef, vg_idx, num_verts_dst, edges_dst, num_edges_dst,
+ weights[EDATA], invert_vgroup);
+ }
+
+ if (data_transfer_layersmapping_generate(
+ &lay_map, ob_src, ob_dst, dm_src, dm_dst, me_dst, ME_EDGE,
+ cddata_type, mix_mode, mix_factor, weights[EDATA],
+ num_edges_dst, use_create, use_delete, fromlayers, tolayers))
+ {
+ CustomDataTransferLayerMap *lay_mapit;
+
+ changed = (lay_map.first != NULL);
+
+ for (lay_mapit = lay_map.first; lay_mapit; lay_mapit = lay_mapit->next) {
+ CustomData_data_transfer(&geom_map[EDATA], lay_mapit);
+ }
+
+ BLI_freelistN(&lay_map);
+ }
+ }
+ if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
+ MVert *verts_dst = dm_dst ? dm_dst->getVertArray(dm_dst) : me_dst->mvert;
+ const int num_verts_dst = dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert;
+ MEdge *edges_dst = dm_dst ? dm_dst->getEdgeArray(dm_dst) : me_dst->medge;
+ const int num_edges_dst = dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge;
+ MPoly *polys_dst = dm_dst ? dm_dst->getPolyArray(dm_dst) : me_dst->mpoly;
+ const int num_polys_dst = dm_dst ? dm_dst->getNumPolys(dm_dst) : me_dst->totpoly;
+ MLoop *loops_dst = dm_dst ? dm_dst->getLoopArray(dm_dst) : me_dst->mloop;
+ const int num_loops_dst = dm_dst ? dm_dst->getNumLoops(dm_dst) : me_dst->totloop;
+ CustomData *pdata_dst = dm_dst ? dm_dst->getPolyDataLayout(dm_dst) : &me_dst->pdata;
+ CustomData *ldata_dst = dm_dst ? dm_dst->getLoopDataLayout(dm_dst) : &me_dst->ldata;
+
+ MeshRemapIslandsCalc island_callback = data_transfer_get_loop_islands_generator(cddata_type);
+
+ if (!geom_map_init[LDATA]) {
+ if ((map_loop_mode == MREMAP_MODE_TOPOLOGY) && (num_loops_dst != dm_src->getNumLoops(dm_src))) {
+ BKE_report(reports, RPT_ERROR,
+ "Source and destination meshes do not have the same amount of face corners, "
+ "'Topology' mapping cannot be used in this case");
+ return changed;
+ }
+ BKE_mesh_remap_calc_loops_from_dm(
+ map_loop_mode, space_transform, max_distance, ray_radius,
+ verts_dst, num_verts_dst, edges_dst, num_edges_dst,
+ loops_dst, num_loops_dst, polys_dst, num_polys_dst,
+ ldata_dst, pdata_dst,
+ (me_dst->flag & ME_AUTOSMOOTH) != 0, me_dst->smoothresh, dirty_nors_dst,
+ dm_src, (me_src->flag & ME_AUTOSMOOTH) != 0, me_src->smoothresh,
+ island_callback, islands_handling_precision, &geom_map[LDATA]);
+ geom_map_init[LDATA] = true;
+ }
+
+ if (mdef && vg_idx != -1 && !weights[LDATA]) {
+ weights[LDATA] = MEM_mallocN(sizeof(*weights[LDATA]) * (size_t)num_loops_dst, __func__);
+ BKE_defvert_extract_vgroup_to_loopweights(
+ mdef, vg_idx, num_verts_dst, loops_dst, num_loops_dst,
+ weights[LDATA], invert_vgroup);
+ }
+
+ if (data_transfer_layersmapping_generate(
+ &lay_map, ob_src, ob_dst, dm_src, dm_dst, me_dst, ME_LOOP,
+ cddata_type, mix_mode, mix_factor, weights[LDATA],
+ num_loops_dst, use_create, use_delete, fromlayers, tolayers))
+ {
+ CustomDataTransferLayerMap *lay_mapit;
+
+ changed = (lay_map.first != NULL);
+
+ for (lay_mapit = lay_map.first; lay_mapit; lay_mapit = lay_mapit->next) {
+ CustomData_data_transfer(&geom_map[LDATA], lay_mapit);
+ }
+
+ BLI_freelistN(&lay_map);
+ }
+ }
+ if (DT_DATATYPE_IS_POLY(dtdata_type)) {
+ MVert *verts_dst = dm_dst ? dm_dst->getVertArray(dm_dst) : me_dst->mvert;
+ const int num_verts_dst = dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert;
+ MPoly *polys_dst = dm_dst ? dm_dst->getPolyArray(dm_dst) : me_dst->mpoly;
+ const int num_polys_dst = dm_dst ? dm_dst->getNumPolys(dm_dst) : me_dst->totpoly;
+ MLoop *loops_dst = dm_dst ? dm_dst->getLoopArray(dm_dst) : me_dst->mloop;
+ const int num_loops_dst = dm_dst ? dm_dst->getNumLoops(dm_dst) : me_dst->totloop;
+ CustomData *pdata_dst = dm_dst ? dm_dst->getPolyDataLayout(dm_dst) : &me_dst->pdata;
+
+ if (!geom_map_init[PDATA]) {
+ if ((map_poly_mode == MREMAP_MODE_TOPOLOGY) && (num_polys_dst != dm_src->getNumPolys(dm_src))) {
+ BKE_report(reports, RPT_ERROR,
+ "Source and destination meshes do not have the same amount of faces, "
+ "'Topology' mapping cannot be used in this case");
+ return changed;
+ }
+ BKE_mesh_remap_calc_polys_from_dm(
+ map_poly_mode, space_transform, max_distance, ray_radius,
+ verts_dst, num_verts_dst, loops_dst, num_loops_dst,
+ polys_dst, num_polys_dst, pdata_dst, dirty_nors_dst,
+ dm_src, &geom_map[PDATA]);
+ geom_map_init[PDATA] = true;
+ }
+
+ if (mdef && vg_idx != -1 && !weights[PDATA]) {
+ weights[PDATA] = MEM_mallocN(sizeof(*weights[PDATA]) * (size_t)num_polys_dst, __func__);
+ BKE_defvert_extract_vgroup_to_polyweights(
+ mdef, vg_idx, num_verts_dst, loops_dst, num_loops_dst,
+ polys_dst, num_polys_dst, weights[PDATA], invert_vgroup);
+ }
+
+ if (data_transfer_layersmapping_generate(
+ &lay_map, ob_src, ob_dst, dm_src, dm_dst, me_dst, ME_POLY,
+ cddata_type, mix_mode, mix_factor, weights[PDATA],
+ num_polys_dst, use_create, use_delete, fromlayers, tolayers))
+ {
+ CustomDataTransferLayerMap *lay_mapit;
+
+ changed = (lay_map.first != NULL);
+
+ for (lay_mapit = lay_map.first; lay_mapit; lay_mapit = lay_mapit->next) {
+ CustomData_data_transfer(&geom_map[PDATA], lay_mapit);
+ }
+
+ BLI_freelistN(&lay_map);
+ }
+ }
+
+ data_transfer_dtdata_type_postprocess(ob_src, ob_dst, dm_src, dm_dst, me_dst, dtdata_type, changed);
+ }
+
+ for (i = 0; i < DATAMAX; i++) {
+ BKE_mesh_remap_free(&geom_map[i]);
+ MEM_SAFE_FREE(weights[i]);
+ }
+
+ return changed;
+
+#undef VDATA
+#undef EDATA
+#undef LDATA
+#undef PDATA
+#undef DATAMAX
+}
+
+bool BKE_object_data_transfer_mesh(
+ Scene *scene, Object *ob_src, Object *ob_dst, const int data_types, const bool use_create,
+ const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode,
+ SpaceTransform *space_transform, const float max_distance, const float ray_radius,
+ const float islands_handling_precision,
+ const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX],
+ const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup,
+ ReportList *reports)
+{
+ return BKE_object_data_transfer_dm(
+ scene, ob_src, ob_dst, NULL, data_types, use_create,
+ map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode, space_transform,
+ max_distance, ray_radius, islands_handling_precision, fromlayers_select, tolayers_select,
+ mix_mode, mix_factor, vgroup_name, invert_vgroup, reports);
+}
diff --git a/source/blender/blenkernel/intern/data_transfer_intern.h b/source/blender/blenkernel/intern/data_transfer_intern.h
new file mode 100644
index 00000000000..dec27d2a056
--- /dev/null
+++ b/source/blender/blenkernel/intern/data_transfer_intern.h
@@ -0,0 +1,61 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Bastien Montagne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/data_transfer_intern.h
+ * \ingroup bke
+ */
+
+#ifndef __DATA_TRANSFER_INTERN_H__
+#define __DATA_TRANSFER_INTERN_H__
+
+struct CustomDataTransferLayerMap;
+struct CustomData;
+struct ListBase;
+
+float data_transfer_interp_float_do(
+ const int mix_mode, const float val_dst, const float val_src, const float mix_factor);
+
+/* Copied from BKE_customdata.h :( */
+typedef void (*cd_datatransfer_interp)(
+ const struct CustomDataTransferLayerMap *laymap, void *dest,
+ const void **sources, const float *weights, const int count, const float mix_factor);
+
+void data_transfer_layersmapping_add_item(
+ struct ListBase *r_map, const int data_type, const int mix_mode,
+ const float mix_factor, const float *mix_weights,
+ const void *data_src, void *data_dst, const int data_src_n, const int data_dst_n,
+ const size_t elem_size, const size_t data_size, const size_t data_offset, const uint64_t data_flag,
+ cd_datatransfer_interp interp);
+
+/* Type-specific. */
+
+bool data_transfer_layersmapping_vgroups(
+ struct ListBase *r_map, const int mix_mode, const float mix_factor, const float *mix_weights,
+ const int num_elem_dst, const bool use_create, const bool use_delete,
+ struct Object *ob_src, struct Object *ob_dst, struct CustomData *cd_src, struct CustomData *cd_dst,
+ const bool use_dupref_dst, const int fromlayers, const int tolayers);
+
+#endif /* __DATA_TRANSFER_INTERN_H__ */
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 528ff2d7b19..0adea59c245 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -39,7 +39,9 @@
#include "MEM_guardedalloc.h"
#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
@@ -49,7 +51,14 @@
#include "BLF_translation.h"
+#include "BKE_customdata.h"
+#include "BKE_data_transfer.h"
#include "BKE_deform.h" /* own include */
+#include "BKE_mesh_mapping.h"
+#include "BKE_object_deform.h"
+
+#include "data_transfer_intern.h"
+
bDeformGroup *BKE_defgroup_new(Object *ob, const char *name)
{
@@ -441,7 +450,7 @@ int defgroup_name_index(Object *ob, const char *name)
/* note, must be freed */
int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default)
{
- int defbase_tot = *flip_map_len = BLI_countlist(&ob->defbase);
+ int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
if (defbase_tot == 0) {
return NULL;
@@ -480,7 +489,7 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default)
/* note, must be freed */
int *defgroup_flip_map_single(Object *ob, int *flip_map_len, const bool use_default, int defgroup)
{
- int defbase_tot = *flip_map_len = BLI_countlist(&ob->defbase);
+ int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
if (defbase_tot == 0) {
return NULL;
@@ -533,7 +542,7 @@ static bool defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *
for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
if (dg != curdef) {
- if (!strcmp(curdef->name, name)) {
+ if (STREQ(curdef->name, name)) {
return true;
}
}
@@ -960,3 +969,386 @@ void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
MEM_freeN(dvert);
}
+
+void BKE_defvert_extract_vgroup_to_vertweights(
+ MDeformVert *dvert, const int defgroup, const int num_verts, float *r_weights, const bool invert_vgroup)
+{
+ if (dvert && defgroup != -1) {
+ int i = num_verts;
+
+ while (i--) {
+ const float w = defvert_find_weight(&dvert[i], defgroup);
+ r_weights[i] = invert_vgroup ? (1.0f - w) : w;
+ }
+ }
+ else {
+ fill_vn_fl(r_weights, invert_vgroup ? 1.0f : 0.0f, num_verts);
+ }
+}
+
+/* The following three make basic interpolation, using temp vert_weights array to avoid looking up same weight
+ * several times. */
+
+void BKE_defvert_extract_vgroup_to_edgeweights(
+ MDeformVert *dvert, const int defgroup, const int num_verts, MEdge *edges, const int num_edges,
+ float *r_weights, const bool invert_vgroup)
+{
+ if (dvert && defgroup != -1) {
+ int i = num_edges;
+ float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
+
+ BKE_defvert_extract_vgroup_to_vertweights(dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
+
+ while (i--) {
+ MEdge *me = &edges[i];
+
+ r_weights[i] = (tmp_weights[me->v1] + tmp_weights[me->v2]) * 0.5f;
+ }
+
+ MEM_freeN(tmp_weights);
+ }
+ else {
+ fill_vn_fl(r_weights, 0.0f, num_edges);
+ }
+}
+
+void BKE_defvert_extract_vgroup_to_loopweights(
+ MDeformVert *dvert, const int defgroup, const int num_verts, MLoop *loops, const int num_loops,
+ float *r_weights, const bool invert_vgroup)
+{
+ if (dvert && defgroup != -1) {
+ int i = num_loops;
+ float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
+
+ BKE_defvert_extract_vgroup_to_vertweights(dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
+
+ while (i--) {
+ MLoop *ml = &loops[i];
+
+ r_weights[i] = tmp_weights[ml->v];
+ }
+
+ MEM_freeN(tmp_weights);
+ }
+ else {
+ fill_vn_fl(r_weights, 0.0f, num_loops);
+ }
+}
+
+void BKE_defvert_extract_vgroup_to_polyweights(
+ MDeformVert *dvert, const int defgroup, const int num_verts, MLoop *loops, const int UNUSED(num_loops),
+ MPoly *polys, const int num_polys, float *r_weights, const bool invert_vgroup)
+{
+ if (dvert && defgroup != -1) {
+ int i = num_polys;
+ float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
+
+ BKE_defvert_extract_vgroup_to_vertweights(dvert, defgroup, num_verts, tmp_weights, invert_vgroup);
+
+ while (i--) {
+ MPoly *mp = &polys[i];
+ MLoop *ml = &loops[mp->loopstart];
+ int j = mp->totloop;
+ float w = 0.0f;
+
+ for (; j--; ml++) {
+ w += tmp_weights[ml->v];
+ }
+ r_weights[i] = w / (float)mp->totloop;
+ }
+
+ MEM_freeN(tmp_weights);
+ }
+ else {
+ fill_vn_fl(r_weights, 0.0f, num_polys);
+ }
+}
+
+/*********** Data Transfer **********/
+
+static void vgroups_datatransfer_interp(
+ const CustomDataTransferLayerMap *laymap, void *dest,
+ const void **sources, const float *weights, const int count, const float mix_factor)
+{
+ MDeformVert **data_src = (MDeformVert **)sources;
+ MDeformVert *data_dst = (MDeformVert *)dest;
+ const int idx_src = laymap->data_src_n;
+ const int idx_dst = laymap->data_dst_n;
+
+ const int mix_mode = laymap->mix_mode;
+
+ int i, j;
+
+ MDeformWeight *dw_src;
+ MDeformWeight *dw_dst = defvert_find_index(data_dst, idx_dst);
+ float weight_src = 0.0f, weight_dst = 0.0f;
+
+ if (sources) {
+ for (i = count; i--;) {
+ for (j = data_src[i]->totweight; j--;) {
+ if ((dw_src = &data_src[i]->dw[j])->def_nr == idx_src) {
+ weight_src += dw_src->weight * weights[i];
+ break;
+ }
+ }
+ }
+ }
+
+ if (dw_dst) {
+ weight_dst = dw_dst->weight;
+ }
+ else if (mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD) {
+ return; /* Do not affect destination. */
+ }
+
+ weight_src = data_transfer_interp_float_do(mix_mode, weight_dst, weight_src, mix_factor);
+
+ CLAMP(weight_src, 0.0f, 1.0f);
+
+ if (!dw_dst) {
+ defvert_add_index_notest(data_dst, idx_dst, weight_src);
+ }
+ else {
+ dw_dst->weight = weight_src;
+ }
+}
+
+static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(
+ ListBase *r_map, const int mix_mode, const float mix_factor, const float *mix_weights,
+ const int num_elem_dst, const bool use_create, const bool use_delete,
+ Object *ob_src, Object *ob_dst, MDeformVert *data_src, MDeformVert *data_dst,
+ CustomData *UNUSED(cd_src), CustomData *cd_dst, const bool UNUSED(use_dupref_dst),
+ const int tolayers, bool *use_layers_src, const int num_layers_src)
+{
+ int idx_src;
+ int idx_dst;
+ int tot_dst = BLI_listbase_count(&ob_dst->defbase);
+
+ const size_t elem_size = sizeof(*((MDeformVert *)NULL));
+
+ switch (tolayers) {
+ case DT_LAYERS_INDEX_DST:
+ idx_dst = tot_dst;
+
+ /* Find last source actually used! */
+ idx_src = num_layers_src;
+ while (idx_src-- && !use_layers_src[idx_src]);
+ idx_src++;
+
+ if (idx_dst < idx_src) {
+ if (!use_create) {
+ return false;
+ }
+ /* Create as much vgroups as necessary! */
+ for (; idx_dst < idx_src; idx_dst++) {
+ BKE_object_defgroup_add(ob_dst);
+ }
+ }
+ else if (use_delete && idx_dst > idx_src) {
+ while (idx_dst-- > idx_src) {
+ BKE_object_defgroup_remove(ob_dst, ob_dst->defbase.last);
+ }
+ }
+ if (r_map) {
+ /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest!
+ * Again, use_create is not relevant in this case */
+ if (!data_dst) {
+ data_dst = CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_CALLOC, NULL, num_elem_dst);
+ }
+
+ while (idx_src--) {
+ if (!use_layers_src[idx_src]) {
+ continue;
+ }
+ data_transfer_layersmapping_add_item(r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights,
+ data_src, data_dst, idx_src, idx_src,
+ elem_size, 0, 0, 0, vgroups_datatransfer_interp);
+ }
+ }
+ break;
+ case DT_LAYERS_NAME_DST:
+ {
+ bDeformGroup *dg_src, *dg_dst;
+
+ if (use_delete) {
+ /* Remove all unused dst vgroups first, simpler in this case. */
+ for (dg_dst = ob_dst->defbase.first; dg_dst;) {
+ bDeformGroup *dg_dst_next = dg_dst->next;
+
+ if (defgroup_name_index(ob_src, dg_dst->name) == -1) {
+ BKE_object_defgroup_remove(ob_dst, dg_dst);
+ }
+ dg_dst = dg_dst_next;
+ }
+ }
+
+ for (idx_src = 0, dg_src = ob_src->defbase.first;
+ idx_src < num_layers_src;
+ idx_src++, dg_src = dg_src->next)
+ {
+ if (!use_layers_src[idx_src]) {
+ continue;
+ }
+
+ if ((idx_dst = defgroup_name_index(ob_dst, dg_src->name)) == -1) {
+ if (!use_create) {
+ if (r_map) {
+ BLI_freelistN(r_map);
+ }
+ return false;
+ }
+ BKE_object_defgroup_add_name(ob_dst, dg_src->name);
+ idx_dst = ob_dst->actdef - 1;
+ }
+ if (r_map) {
+ /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest!
+ * use_create is not relevant in this case */
+ if (!data_dst) {
+ data_dst = CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_CALLOC, NULL, num_elem_dst);
+ }
+
+ data_transfer_layersmapping_add_item(
+ r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights,
+ data_src, data_dst, idx_src, idx_dst,
+ elem_size, 0, 0, 0, vgroups_datatransfer_interp);
+ }
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool data_transfer_layersmapping_vgroups(
+ ListBase *r_map, const int mix_mode, const float mix_factor, const float *mix_weights,
+ const int num_elem_dst, const bool use_create, const bool use_delete, Object *ob_src, Object *ob_dst,
+ CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst, const int fromlayers, const int tolayers)
+{
+ int idx_src, idx_dst;
+ MDeformVert *data_src, *data_dst = NULL;
+
+ const size_t elem_size = sizeof(*((MDeformVert *)NULL));
+
+ /* Note: VGroups are a bit hairy, since their layout is defined on object level (ob->defbase), while their actual
+ * data is a (mesh) CD layer.
+ * This implies we may have to handle data layout itself while having NULL data itself,
+ * and even have to support NULL data_src in transfer data code (we always create a data_dst, though).
+ */
+
+ if (BLI_listbase_is_empty(&ob_src->defbase)) {
+ if (use_delete) {
+ BKE_object_defgroup_remove_all(ob_dst);
+ }
+ return true;
+ }
+
+ data_src = CustomData_get_layer(cd_src, CD_MDEFORMVERT);
+
+ data_dst = CustomData_get_layer(cd_dst, CD_MDEFORMVERT);
+ if (data_dst && use_dupref_dst && r_map) {
+ /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */
+ data_dst = CustomData_duplicate_referenced_layer(cd_dst, CD_MDEFORMVERT, num_elem_dst);
+ }
+
+ if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) {
+ /* Note: use_delete has not much meaning in this case, ignored. */
+
+ if (fromlayers >= 0) {
+ idx_src = fromlayers;
+ BLI_assert(idx_src < BLI_listbase_count(&ob_src->defbase));
+ }
+ else if ((idx_src = ob_src->actdef - 1) == -1) {
+ return false;
+ }
+
+ if (tolayers >= 0) {
+ /* Note: in this case we assume layer exists! */
+ idx_dst = tolayers;
+ BLI_assert(idx_dst < BLI_listbase_count(&ob_dst->defbase));
+ }
+ else if (tolayers == DT_LAYERS_ACTIVE_DST) {
+ if ((idx_dst = ob_dst->actdef - 1) == -1) {
+ bDeformGroup *dg_src;
+ if (!use_create) {
+ return true;
+ }
+ dg_src = BLI_findlink(&ob_src->defbase, idx_src);
+ BKE_object_defgroup_add_name(ob_dst, dg_src->name);
+ idx_dst = ob_dst->actdef - 1;
+ }
+ }
+ else if (tolayers == DT_LAYERS_INDEX_DST) {
+ int num = BLI_listbase_count(&ob_src->defbase);
+ idx_dst = idx_src;
+ if (num <= idx_dst) {
+ if (!use_create) {
+ return true;
+ }
+ /* Create as much vgroups as necessary! */
+ for (; num <= idx_dst; num++) {
+ BKE_object_defgroup_add(ob_dst);
+ }
+ }
+ }
+ else if (tolayers == DT_LAYERS_NAME_DST) {
+ bDeformGroup *dg_src = BLI_findlink(&ob_src->defbase, idx_src);
+ if ((idx_dst = defgroup_name_index(ob_dst, dg_src->name)) == -1) {
+ if (!use_create) {
+ return true;
+ }
+ BKE_object_defgroup_add_name(ob_dst, dg_src->name);
+ idx_dst = ob_dst->actdef - 1;
+ }
+ }
+ else {
+ return false;
+ }
+
+ if (r_map) {
+ /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest!
+ * use_create is not relevant in this case */
+ if (!data_dst) {
+ data_dst = CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_CALLOC, NULL, num_elem_dst);
+ }
+
+ data_transfer_layersmapping_add_item(r_map, CD_FAKE_MDEFORMVERT, mix_mode, mix_factor, mix_weights,
+ data_src, data_dst, idx_src, idx_dst,
+ elem_size, 0, 0, 0, vgroups_datatransfer_interp);
+ }
+ }
+ else {
+ int num_src, num_sel_unused;
+ bool *use_layers_src = NULL;
+ bool ret = false;
+
+ switch (fromlayers) {
+ case DT_LAYERS_ALL_SRC:
+ use_layers_src = BKE_object_defgroup_subset_from_select_type(ob_src, WT_VGROUP_ALL,
+ &num_src, &num_sel_unused);
+ break;
+ case DT_LAYERS_VGROUP_SRC_BONE_SELECT:
+ use_layers_src = BKE_object_defgroup_subset_from_select_type(ob_src, WT_VGROUP_BONE_SELECT,
+ &num_src, &num_sel_unused);
+ break;
+ case DT_LAYERS_VGROUP_SRC_BONE_DEFORM:
+ use_layers_src = BKE_object_defgroup_subset_from_select_type(ob_src, WT_VGROUP_BONE_DEFORM,
+ &num_src, &num_sel_unused);
+ break;
+ }
+
+ if (use_layers_src) {
+ ret = data_transfer_layersmapping_vgroups_multisrc_to_dst(
+ r_map, mix_mode, mix_factor, mix_weights, num_elem_dst, use_create, use_delete,
+ ob_src, ob_dst, data_src, data_dst, cd_src, cd_dst, use_dupref_dst,
+ tolayers, use_layers_src, num_src);
+ }
+
+ MEM_SAFE_FREE(use_layers_src);
+ return ret;
+ }
+
+ return true;
+}
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 44a0b93fc01..0451c2239ac 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -484,7 +484,7 @@ static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Objec
}
}
-static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, Object *ob, int mask)
+static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Scene *scene, Object *ob, int mask)
{
bConstraint *con;
DagNode *node;
@@ -576,7 +576,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
for (md = ob->modifiers.first; md; md = md->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- if (mti->updateDepgraph) mti->updateDepgraph(md, dag, scene, ob, node);
+ if (mti->updateDepgraph) mti->updateDepgraph(md, dag, bmain, scene, ob, node);
}
}
if (ob->parent) {
@@ -891,7 +891,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
dag_add_relation(dag, scenenode, node, DAG_RL_SCENE, "Scene Relation");
}
-static void build_dag_group(DagForest *dag, DagNode *scenenode, Scene *scene, Group *group, short mask)
+static void build_dag_group(DagForest *dag, DagNode *scenenode, Main *bmain, Scene *scene, Group *group, short mask)
{
GroupObject *go;
@@ -901,9 +901,9 @@ static void build_dag_group(DagForest *dag, DagNode *scenenode, Scene *scene, Gr
group->id.flag |= LIB_DOIT;
for (go = group->gobject.first; go; go = go->next) {
- build_dag_object(dag, scenenode, scene, go->ob, mask);
+ build_dag_object(dag, scenenode, bmain, scene, go->ob, mask);
if (go->ob->dup_group)
- build_dag_group(dag, scenenode, scene, go->ob->dup_group, mask);
+ build_dag_group(dag, scenenode, bmain, scene, go->ob->dup_group, mask);
}
}
@@ -936,11 +936,11 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask)
for (base = sce->base.first; base; base = base->next) {
ob = base->object;
- build_dag_object(dag, scenenode, sce, ob, mask);
+ build_dag_object(dag, scenenode, bmain, sce, ob, mask);
if (ob->proxy)
- build_dag_object(dag, scenenode, sce, ob->proxy, mask);
+ build_dag_object(dag, scenenode, bmain, sce, ob->proxy, mask);
if (ob->dup_group)
- build_dag_group(dag, scenenode, sce, ob->dup_group, mask);
+ build_dag_group(dag, scenenode, bmain, sce, ob->dup_group, mask);
}
BKE_main_id_tag_idcode(bmain, ID_GR, false);
@@ -2357,6 +2357,15 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
ob->recalc |= OB_RECALC_DATA;
lib_id_recalc_tag(bmain, &ob->id);
}
+ /* This should not be needed here, but in some cases, like after a redo, we can end up with
+ * a wrong final matrix (see T42472).
+ * Quoting Sergey, this comes from BKE_object_handle_update_ex, which is calling
+ * BKE_object_where_is_calc_ex when it shouldn't, but that issue is not easily fixable.
+ */
+ else {
+ ob->recalc |= OB_RECALC_OB;
+ lib_id_recalc_tag(bmain, &ob->id);
+ }
if (ob->proxy && (ob->proxy_group == NULL)) {
ob->proxy->recalc |= OB_RECALC_DATA;
lib_id_recalc_tag(bmain, &ob->id);
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 893c69741cd..dd92a82bed2 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_curve_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_vfont_types.h"
@@ -352,7 +351,8 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase,
data = dl->verts;
- if (nu->flagu & CU_NURB_CYCLIC) {
+ /* check that (len != 2) so we don't immediately loop back on ourselves */
+ if (nu->flagu & CU_NURB_CYCLIC && (dl->nr != 2)) {
dl->type = DL_POLY;
a = nu->pntsu;
}
@@ -422,8 +422,12 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase,
dl->charidx = nu->charidx;
data = dl->verts;
- if (nu->flagu & CU_NURB_CYCLIC) dl->type = DL_POLY;
- else dl->type = DL_SEGM;
+ if ((nu->flagu & CU_NURB_CYCLIC) && (dl->nr != 2)) {
+ dl->type = DL_POLY;
+ }
+ else {
+ dl->type = DL_SEGM;
+ }
a = len;
bp = nu->bp;
@@ -814,7 +818,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, ListBase *nurb,
required_mode |= eModifierMode_Editmode;
if (cu->editnurb == NULL) {
- keyVerts = BKE_key_evaluate_object(scene, ob, &numVerts);
+ keyVerts = BKE_key_evaluate_object(ob, &numVerts);
if (keyVerts) {
/* split coords from key data, the latter also includes
@@ -1622,8 +1626,12 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
dl->type = DL_SURF;
dl->flag = dlb->flag & (DL_FRONT_CURVE | DL_BACK_CURVE);
- if (dlb->type == DL_POLY) dl->flag |= DL_CYCL_U;
- if (bl->poly >= 0) dl->flag |= DL_CYCL_V;
+ if (dlb->type == DL_POLY) {
+ dl->flag |= DL_CYCL_U;
+ }
+ if ((bl->poly >= 0) && (steps != 2)) {
+ dl->flag |= DL_CYCL_V;
+ }
dl->parts = steps;
dl->nr = dlb->nr;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 4719013e2f8..762b24dfdf8 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -71,10 +71,6 @@
#include "BKE_scene.h"
#include "BKE_texture.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
/* for image output */
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -257,20 +253,20 @@ static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface)
bool dynamicPaint_surfaceHasColorPreview(DynamicPaintSurface *surface)
{
if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
- return 0;
+ return false;
}
else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
surface->type == MOD_DPAINT_SURFACE_T_WAVE)
{
- return 0;
+ return false;
}
else {
- return 1;
+ return true;
}
}
else {
- return 1;
+ return true;
}
}
@@ -325,7 +321,7 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object
else if (output == 1)
name = surface->output_name2;
else
- return 0;
+ return false;
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
@@ -336,7 +332,7 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object
return (defgroup_name_index(ob, surface->output_name) != -1);
}
- return 0;
+ return false;
}
static bool surface_duplicateOutputExists(void *arg, const char *name)
@@ -372,7 +368,7 @@ static bool surface_duplicateNameExists(void *arg, const char *name)
DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
for (; surface; surface = surface->next) {
- if (surface != t_surface && !strcmp(name, surface->name)) return true;
+ if (surface != t_surface && STREQ(name, surface->name)) return true;
}
return false;
}
@@ -1106,13 +1102,13 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
canvas = pmd->canvas = MEM_callocN(sizeof(DynamicPaintCanvasSettings), "DynamicPaint Canvas");
if (!canvas)
- return 0;
+ return false;
canvas->pmd = pmd;
canvas->dm = NULL;
/* Create one surface */
if (!dynamicPaint_createNewSurface(canvas, scene))
- return 0;
+ return false;
}
else if (type == MOD_DYNAMICPAINT_TYPE_BRUSH) {
@@ -1122,7 +1118,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
brush = pmd->brush = MEM_callocN(sizeof(DynamicPaintBrushSettings), "DynamicPaint Paint");
if (!brush)
- return 0;
+ return false;
brush->pmd = pmd;
brush->psys = NULL;
@@ -1157,7 +1153,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
brush->paint_ramp = add_colorband(false);
if (!brush->paint_ramp)
- return 0;
+ return false;
ramp = brush->paint_ramp->data;
/* Add default smooth-falloff ramp. */
ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = 1.0f;
@@ -1173,7 +1169,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
brush->vel_ramp = add_colorband(false);
if (!brush->vel_ramp)
- return 0;
+ return false;
ramp = brush->vel_ramp->data;
ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = ramp[0].pos = 0.0f;
ramp[1].r = ramp[1].g = ramp[1].b = ramp[1].a = ramp[1].pos = 1.0f;
@@ -1181,10 +1177,11 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
}
}
}
- else
- return 0;
+ else {
+ return false;
+ }
- return 1;
+ return true;
}
void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tpmd)
@@ -1505,7 +1502,7 @@ static void dynamicPaint_setInitialColor(Scene *scene, DynamicPaintSurface *surf
uv[0] = tface[i].uv[j][0] * 2.0f - 1.0f;
uv[1] = tface[i].uv[j][1] * 2.0f - 1.0f;
- multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage);
+ multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage, false);
if (texres.tin > pPoint[*vert].alpha) {
copy_v3_v3(pPoint[*vert].color, &texres.tr);
@@ -1539,7 +1536,7 @@ static void dynamicPaint_setInitialColor(Scene *scene, DynamicPaintSurface *surf
uv_final[0] = uv_final[0] * 2.0f - 1.0f;
uv_final[1] = uv_final[1] * 2.0f - 1.0f;
- multitex_ext_safe(tex, uv_final, &texres, NULL, scene_color_manage);
+ multitex_ext_safe(tex, uv_final, &texres, NULL, scene_color_manage, false);
/* apply color */
copy_v3_v3(pPoint[i].color, &texres.tr);
@@ -1630,12 +1627,12 @@ bool dynamicPaint_resetSurface(Scene *scene, DynamicPaintSurface *surface)
if (surface->data) dynamicPaint_freeSurfaceData(surface);
/* don't reallocate for image sequence types. they get handled only on bake */
- if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 1;
- if (numOfPoints < 1) return 0;
+ if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return true;
+ if (numOfPoints < 1) return false;
/* allocate memory */
surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData");
- if (!surface->data) return 0;
+ if (!surface->data) return false;
/* allocate data depending on surface type and format */
surface->data->total_points = numOfPoints;
@@ -1646,7 +1643,7 @@ bool dynamicPaint_resetSurface(Scene *scene, DynamicPaintSurface *surface)
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT)
dynamicPaint_setInitialColor(scene, surface);
- return 1;
+ return true;
}
/* make sure allocated surface size matches current requirements */
@@ -1655,7 +1652,7 @@ static bool dynamicPaint_checkSurfaceData(Scene *scene, DynamicPaintSurface *sur
if (!surface->data || ((dynamicPaint_surfaceNumOfPoints(surface) != surface->data->total_points))) {
return dynamicPaint_resetSurface(scene, surface);
}
- return 1;
+ return true;
}
@@ -2708,7 +2705,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam
if (format == R_IMF_IMTYPE_OPENEXR) format = R_IMF_IMTYPE_PNG;
#endif
BLI_strncpy(output_file, filename, sizeof(output_file));
- BKE_add_image_extension_from_type(output_file, format);
+ BKE_image_path_ensure_ext_from_imtype(output_file, format);
/* Validate output file path */
BLI_path_abs(output_file, G.main->name);
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index ce7804d9878..082edb01efd 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -169,12 +169,25 @@ static void emDM_calcNormals(DerivedMesh *dm)
dm->dirty &= ~DM_DIRTY_NORMALS;
}
-static void emDM_calcLoopNormals(DerivedMesh *dm, const float split_angle)
+static void emDM_calcLoopNormalsSpaceArray(
+ DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr);
+
+static void emDM_calcLoopNormals(DerivedMesh *dm, const bool use_split_normals, const float split_angle)
+{
+ emDM_calcLoopNormalsSpaceArray(dm, use_split_normals, split_angle, NULL);
+}
+
+/* #define DEBUG_CLNORS */
+
+static void emDM_calcLoopNormalsSpaceArray(
+ DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr)
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = bmdm->em->bm;
const float (*vertexCos)[3], (*vertexNos)[3], (*polyNos)[3];
float (*loopNos)[3];
+ short (*clnors_data)[2];
+ int cd_loop_clnors_offset;
/* calculate loop normals from poly and vertex normals */
emDM_ensureVertNormals(bmdm);
@@ -191,7 +204,37 @@ static void emDM_calcLoopNormals(DerivedMesh *dm, const float split_angle)
loopNos = dm->getLoopDataArray(dm, CD_NORMAL);
}
- BM_loops_calc_normal_vcos(bm, vertexCos, vertexNos, polyNos, split_angle, loopNos);
+ /* We can have both, give priority to dm's data, and fallback to bm's ones. */
+ clnors_data = dm->getLoopDataArray(dm, CD_CUSTOMLOOPNORMAL);
+ cd_loop_clnors_offset = clnors_data ? -1 : CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+
+ BM_loops_calc_normal_vcos(bm, vertexCos, vertexNos, polyNos, use_split_normals, split_angle, loopNos,
+ r_lnors_spacearr, clnors_data, cd_loop_clnors_offset);
+#ifdef DEBUG_CLNORS
+ if (r_lnors_spacearr) {
+ int i;
+ for (i = 0; i < numLoops; i++) {
+ if (r_lnors_spacearr->lspacearr[i]->ref_alpha != 0.0f) {
+ LinkNode *loops = r_lnors_spacearr->lspacearr[i]->loops;
+ printf("Loop %d uses lnor space %p:\n", i, r_lnors_spacearr->lspacearr[i]);
+ print_v3("\tfinal lnor:", loopNos[i]);
+ print_v3("\tauto lnor:", r_lnors_spacearr->lspacearr[i]->vec_lnor);
+ print_v3("\tref_vec:", r_lnors_spacearr->lspacearr[i]->vec_ref);
+ printf("\talpha: %f\n\tbeta: %f\n\tloops: %p\n", r_lnors_spacearr->lspacearr[i]->ref_alpha,
+ r_lnors_spacearr->lspacearr[i]->ref_beta, r_lnors_spacearr->lspacearr[i]->loops);
+ printf("\t\t(shared with loops");
+ while (loops) {
+ printf(" %d", GET_INT_FROM_POINTER(loops->link));
+ loops = loops->next;
+ }
+ printf(")\n");
+ }
+ else {
+ printf("Loop %d has no lnor space\n", i);
+ }
+ }
+ }
+#endif
}
static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
@@ -526,6 +569,8 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
setDrawOptions(userData, BM_elem_index_get(efa)));
if (draw_option != DM_DRAW_OPTION_SKIP) {
const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
+ if (setMaterial)
+ setMaterial(efa->mat_nr + 1, NULL);
if (draw_option == DM_DRAW_OPTION_STIPPLE) { /* enabled with stipple */
if (poly_prev != GL_ZERO) glEnd();
@@ -608,12 +653,17 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
efa = ltri[0]->f;
drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
+
+ draw_option = (setDrawOptions ?
+ setDrawOptions(userData, BM_elem_index_get(efa)) :
+ DM_DRAW_OPTION_NORMAL);
- draw_option = (!setDrawOptions ?
- DM_DRAW_OPTION_NORMAL :
- setDrawOptions(userData, BM_elem_index_get(efa)));
if (draw_option != DM_DRAW_OPTION_SKIP) {
const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
+
+ if (setMaterial)
+ setMaterial(efa->mat_nr + 1, NULL);
+
if (draw_option == DM_DRAW_OPTION_STIPPLE) { /* enabled with stipple */
if (poly_prev != GL_ZERO) glEnd();
@@ -717,7 +767,7 @@ static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned c
static void emDM_drawFacesTex_common(DerivedMesh *dm,
DMSetDrawOptionsTex drawParams,
- DMSetDrawOptions drawParamsMapped,
+ DMSetDrawOptionsMappedTex drawParamsMapped,
DMCompareDrawOptions compareDrawOptions,
void *userData)
{
@@ -785,7 +835,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
if (drawParams)
draw_option = drawParams(&mtf, has_vcol, efa->mat_nr);
else if (drawParamsMapped)
- draw_option = drawParamsMapped(userData, BM_elem_index_get(efa));
+ draw_option = drawParamsMapped(userData, BM_elem_index_get(efa), efa->mat_nr);
else
draw_option = DM_DRAW_OPTION_NORMAL;
@@ -854,7 +904,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
if (drawParams)
draw_option = drawParams(&mtf, has_vcol, efa->mat_nr);
else if (drawParamsMapped)
- draw_option = drawParamsMapped(userData, BM_elem_index_get(efa));
+ draw_option = drawParamsMapped(userData, BM_elem_index_get(efa), efa->mat_nr);
else
draw_option = DM_DRAW_OPTION_NORMAL;
@@ -916,7 +966,7 @@ static void emDM_drawFacesTex(DerivedMesh *dm,
}
static void emDM_drawMappedFacesTex(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
+ DMSetDrawOptionsMappedTex setDrawOptions,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag UNUSED(flag))
{
@@ -970,7 +1020,7 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B
GLubyte col[4];
if (attribs->mcol[i].em_offset != -1) {
const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
- col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)col, &cp->r);
}
else {
col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
@@ -1555,7 +1605,8 @@ static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
if (type == CD_MTFACE || type == CD_MCOL) {
const int type_from = (type == CD_MTFACE) ? CD_MTEXPOLY : CD_MLOOPCOL;
int index;
- const char *data, *bmdata;
+ const char *bmdata;
+ char *data;
index = CustomData_get_layer_index(&bm->pdata, type_from);
if (index != -1) {
@@ -1580,11 +1631,11 @@ static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
// bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
bmdata = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
- ME_MTEXFACE_CPY(((MTFace *)data), ((MTexPoly *)bmdata));
+ ME_MTEXFACE_CPY(((MTFace *)data), ((const MTexPoly *)bmdata));
for (j = 0; j < 3; j++) {
// bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPUV);
bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_uv_offset);
- copy_v2_v2(((MTFace *)data)->uv[j], ((MLoopUV *)bmdata)->uv);
+ copy_v2_v2(((MTFace *)data)->uv[j], ((const MLoopUV *)bmdata)->uv);
}
}
}
@@ -1594,7 +1645,7 @@ static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
for (j = 0; j < 3; j++) {
// bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPCOL);
bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_color_offset);
- MESH_MLOOPCOL_TO_MCOL(((MLoopCol *)bmdata), (((MCol *)data) + j));
+ MESH_MLOOPCOL_TO_MCOL(((const MLoopCol *)bmdata), (((MCol *)data) + j));
}
}
}
@@ -1756,6 +1807,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
bmdm->dm.calcNormals = emDM_calcNormals;
bmdm->dm.calcLoopNormals = emDM_calcLoopNormals;
+ bmdm->dm.calcLoopNormalsSpaceArray = emDM_calcLoopNormalsSpaceArray;
bmdm->dm.recalcTessellation = emDM_recalcTessellation;
bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c
index 442ab26ffc8..5f2660b5365 100644
--- a/source/blender/blenkernel/intern/editmesh_bvh.c
+++ b/source/blender/blenkernel/intern/editmesh_bvh.c
@@ -239,6 +239,32 @@ struct RayCastUserData {
float uv[2];
};
+
+static BMFace *bmbvh_ray_cast_handle_hit(
+ BMBVHTree *bmtree, struct RayCastUserData *bmcb_data, const BVHTreeRayHit *hit,
+ float *r_dist, float r_hitout[3], float r_cagehit[3])
+{
+ if (r_hitout) {
+ if (bmtree->flag & BMBVH_RETURN_ORIG) {
+ BMLoop **ltri = bmtree->looptris[hit->index];
+ interp_v3_v3v3v3_uv(r_hitout, ltri[0]->v->co, ltri[1]->v->co, ltri[2]->v->co, bmcb_data->uv);
+ }
+ else {
+ copy_v3_v3(r_hitout, hit->co);
+ }
+
+ if (r_cagehit) {
+ copy_v3_v3(r_cagehit, hit->co);
+ }
+ }
+
+ if (r_dist) {
+ *r_dist = hit->dist;
+ }
+
+ return bmtree->looptris[hit->index][0]->f;
+}
+
static void bmbvh_ray_cast_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
struct RayCastUserData *bmcb_data = userdata;
@@ -284,32 +310,68 @@ BMFace *BKE_bmbvh_ray_cast(BMBVHTree *bmtree, const float co[3], const float dir
bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage;
BLI_bvhtree_ray_cast(bmtree->tree, co, dir, radius, &hit, bmbvh_ray_cast_cb, &bmcb_data);
+
if (hit.index != -1 && hit.dist != dist) {
- if (r_hitout) {
- if (bmtree->flag & BMBVH_RETURN_ORIG) {
- BMLoop **ltri = bmtree->looptris[hit.index];
- interp_v3_v3v3v3_uv(r_hitout, ltri[0]->v->co, ltri[1]->v->co, ltri[2]->v->co, bmcb_data.uv);
- }
- else {
- copy_v3_v3(r_hitout, hit.co);
- }
+ return bmbvh_ray_cast_handle_hit(bmtree, &bmcb_data, &hit, r_dist, r_hitout, r_cagehit);
+ }
- if (r_cagehit) {
- copy_v3_v3(r_cagehit, hit.co);
- }
- }
+ return NULL;
+}
- if (r_dist) {
- *r_dist = hit.dist;
- }
+/* -------------------------------------------------------------------- */
+/* bmbvh_ray_cast_cb_filter */
- return bmtree->looptris[hit.index][0]->f;
+/* Same as BKE_bmbvh_ray_cast but takes a callback to filter out faces.
+ */
+
+struct RayCastUserData_Filter {
+ struct RayCastUserData bmcb_data;
+
+ BMBVHTree_FaceFilter filter_cb;
+ void *filter_userdata;
+};
+
+static void bmbvh_ray_cast_cb_filter(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{
+ struct RayCastUserData_Filter *bmcb_data_filter = userdata;
+ struct RayCastUserData *bmcb_data = &bmcb_data_filter->bmcb_data;
+ const BMLoop **ltri = bmcb_data->looptris[index];
+ if (bmcb_data_filter->filter_cb(ltri[0]->f, bmcb_data_filter->filter_userdata)) {
+ bmbvh_ray_cast_cb(bmcb_data, index, ray, hit);
+ }
+}
+
+BMFace *BKE_bmbvh_ray_cast_filter(
+ BMBVHTree *bmtree, const float co[3], const float dir[3], const float radius,
+ float *r_dist, float r_hitout[3], float r_cagehit[3],
+ BMBVHTree_FaceFilter filter_cb, void *filter_userdata)
+{
+ BVHTreeRayHit hit;
+ struct RayCastUserData_Filter bmcb_data_filter;
+ struct RayCastUserData *bmcb_data = &bmcb_data_filter.bmcb_data;
+
+ const float dist = r_dist ? *r_dist : FLT_MAX;
+
+ bmcb_data_filter.filter_cb = filter_cb;
+ bmcb_data_filter.filter_userdata = filter_userdata;
+
+ if (bmtree->cos_cage) BLI_assert(!(bmtree->bm->elem_index_dirty & BM_VERT));
+
+ hit.dist = dist;
+ hit.index = -1;
+
+ /* ok to leave 'uv' uninitialized */
+ bmcb_data->looptris = (const BMLoop *(*)[3])bmtree->looptris;
+ bmcb_data->cos_cage = (const float (*)[3])bmtree->cos_cage;
+
+ BLI_bvhtree_ray_cast(bmtree->tree, co, dir, radius, &hit, bmbvh_ray_cast_cb_filter, &bmcb_data_filter);
+ if (hit.index != -1 && hit.dist != dist) {
+ return bmbvh_ray_cast_handle_hit(bmtree, bmcb_data, &hit, r_dist, r_hitout, r_cagehit);
}
return NULL;
}
-
/* -------------------------------------------------------------------- */
/* BKE_bmbvh_find_face_segment */
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index ced9da8d0b1..296a56ada5d 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -30,6 +30,7 @@
*/
#include <stddef.h>
+#include <stdarg.h>
#include <math.h>
#include <stdlib.h>
@@ -51,6 +52,7 @@
#include "BLI_noise.h"
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
#include "PIL_time.h"
@@ -61,6 +63,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_effect.h"
+#include "BKE_global.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -228,7 +231,7 @@ ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src
for (base = scene->base.first; base; base= base->next) {
if ( (base->lay & layer) ) {
if ( base->object->pd && base->object->pd->forcefield )
- add_object_to_effectors(&effectors, scene, weights, base->object, ob_src);
+ add_object_to_effectors(&effectors, scene, weights, base->object, ob_src);
if ( base->object->particlesystem.first ) {
ParticleSystem *psys= base->object->particlesystem.first;
@@ -754,7 +757,7 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP
scene_color_manage = BKE_scene_check_color_management_enabled(eff->scene);
- hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result, NULL, scene_color_manage);
+ hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result, NULL, scene_color_manage, false);
if (hasrgb && mode==PFIELD_TEX_RGB) {
force[0] = (0.5f - result->tr) * strength;
@@ -765,15 +768,15 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP
strength/=nabla;
tex_co[0] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1, NULL, scene_color_manage);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1, NULL, scene_color_manage, false);
tex_co[0] -= nabla;
tex_co[1] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2, NULL, scene_color_manage);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2, NULL, scene_color_manage, false);
tex_co[1] -= nabla;
tex_co[2] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3, NULL, scene_color_manage);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3, NULL, scene_color_manage, false);
if (mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we don't have rgb fall back to grad */
/* generate intensity if texture only has rgb value */
@@ -1024,3 +1027,160 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we
}
}
}
+
+/* ======== Simulation Debugging ======== */
+
+SimDebugData *_sim_debug_data = NULL;
+
+unsigned int BKE_sim_debug_data_hash(int i)
+{
+ return BLI_ghashutil_uinthash((unsigned int)i);
+}
+
+unsigned int BKE_sim_debug_data_hash_combine(unsigned int kx, unsigned int ky)
+{
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+ unsigned int a, b, c;
+
+ a = b = c = 0xdeadbeef + (2 << 2) + 13;
+ a += kx;
+ b += ky;
+
+ c ^= b; c -= rot(b,14);
+ a ^= c; a -= rot(c,11);
+ b ^= a; b -= rot(a,25);
+ c ^= b; c -= rot(b,16);
+ a ^= c; a -= rot(c,4);
+ b ^= a; b -= rot(a,14);
+ c ^= b; c -= rot(b,24);
+
+ return c;
+
+#undef rot
+}
+
+static unsigned int debug_element_hash(const void *key)
+{
+ const SimDebugElement *elem = key;
+ return elem->hash;
+}
+
+static bool debug_element_compare(const void *a, const void *b)
+{
+ const SimDebugElement *elem1 = a;
+ const SimDebugElement *elem2 = b;
+
+ if (elem1->hash == elem2->hash) {
+ return 0;
+ }
+ return 1;
+}
+
+static void debug_element_free(void *val)
+{
+ SimDebugElement *elem = val;
+ MEM_freeN(elem);
+}
+
+void BKE_sim_debug_data_set_enabled(bool enable)
+{
+ if (enable) {
+ if (!_sim_debug_data) {
+ _sim_debug_data = MEM_callocN(sizeof(SimDebugData), "sim debug data");
+ _sim_debug_data->gh = BLI_ghash_new(debug_element_hash, debug_element_compare, "sim debug element hash");
+ }
+ }
+ else {
+ BKE_sim_debug_data_free();
+ }
+}
+
+bool BKE_sim_debug_data_get_enabled(void)
+{
+ return _sim_debug_data != NULL;
+}
+
+void BKE_sim_debug_data_free(void)
+{
+ if (_sim_debug_data) {
+ if (_sim_debug_data->gh)
+ BLI_ghash_free(_sim_debug_data->gh, NULL, debug_element_free);
+ MEM_freeN(_sim_debug_data);
+ }
+}
+
+static void debug_data_insert(SimDebugData *debug_data, SimDebugElement *elem)
+{
+ SimDebugElement *old_elem = BLI_ghash_lookup(debug_data->gh, elem);
+ if (old_elem) {
+ *old_elem = *elem;
+ MEM_freeN(elem);
+ }
+ else
+ BLI_ghash_insert(debug_data->gh, elem, elem);
+}
+
+void BKE_sim_debug_data_add_element(int type, const float v1[3], const float v2[3], float r, float g, float b, const char *category, unsigned int hash)
+{
+ unsigned int category_hash = BLI_ghashutil_strhash_p(category);
+ SimDebugElement *elem;
+
+ if (!_sim_debug_data) {
+ if (G.debug & G_DEBUG_SIMDATA)
+ BKE_sim_debug_data_set_enabled(true);
+ else
+ return;
+ }
+
+ elem = MEM_callocN(sizeof(SimDebugElement), "sim debug data element");
+ elem->type = type;
+ elem->category_hash = category_hash;
+ elem->hash = hash;
+ elem->color[0] = r;
+ elem->color[1] = g;
+ elem->color[2] = b;
+ copy_v3_v3(elem->v1, v1);
+ copy_v3_v3(elem->v2, v2);
+
+ debug_data_insert(_sim_debug_data, elem);
+}
+
+void BKE_sim_debug_data_remove_element(unsigned int hash)
+{
+ SimDebugElement dummy;
+ if (!_sim_debug_data)
+ return;
+
+ dummy.hash = hash;
+ BLI_ghash_remove(_sim_debug_data->gh, &dummy, NULL, debug_element_free);
+}
+
+void BKE_sim_debug_data_clear(void)
+{
+ if (!_sim_debug_data)
+ return;
+
+ if (_sim_debug_data->gh)
+ BLI_ghash_clear(_sim_debug_data->gh, NULL, debug_element_free);
+}
+
+void BKE_sim_debug_data_clear_category(const char *category)
+{
+ int category_hash = (int)BLI_ghashutil_strhash_p(category);
+
+ if (!_sim_debug_data)
+ return;
+
+ if (_sim_debug_data->gh) {
+ GHashIterator iter;
+ BLI_ghashIterator_init(&iter, _sim_debug_data->gh);
+ while (!BLI_ghashIterator_done(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ BLI_ghashIterator_step(&iter); /* removing invalidates the current iterator, so step before removing */
+
+ if (elem->category_hash == category_hash)
+ BLI_ghash_remove(_sim_debug_data->gh, elem, NULL, debug_element_free);
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index e90a0891436..81321b9dbc2 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -230,7 +230,7 @@ FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_
/* check paths of curves, then array indices... */
for (fcu = list->first; fcu; fcu = fcu->next) {
/* simple string-compare (this assumes that they have the same root...) */
- if (fcu->rna_path && !strcmp(fcu->rna_path, rna_path)) {
+ if (fcu->rna_path && STREQ(fcu->rna_path, rna_path)) {
/* now check indices */
if (fcu->array_index == array_index)
return fcu;
@@ -253,7 +253,7 @@ FCurve *iter_step_fcurve(FCurve *fcu_iter, const char rna_path[])
/* check paths of curves, then array indices... */
for (fcu = fcu_iter; fcu; fcu = fcu->next) {
/* simple string-compare (this assumes that they have the same root...) */
- if (fcu->rna_path && !strcmp(fcu->rna_path, rna_path)) {
+ if (fcu->rna_path && STREQ(fcu->rna_path, rna_path)) {
return fcu;
}
}
@@ -290,7 +290,7 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
if (quotedName) {
/* check if the quoted name matches the required name */
- if (strcmp(quotedName, dataName) == 0) {
+ if (STREQ(quotedName, dataName)) {
LinkData *ld = MEM_callocN(sizeof(LinkData), __func__);
ld->data = fcu;
@@ -309,17 +309,18 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
return matches;
}
-FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven)
+FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, AnimData **adt, bAction **action, bool *r_driven)
{
- return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, action, r_driven);
+ return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, adt, action, r_driven);
}
FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex,
- bAction **action, bool *r_driven)
+ AnimData **animdata, bAction **action, bool *r_driven)
{
FCurve *fcu = NULL;
PointerRNA tptr = *ptr;
+ if (animdata) *animdata = NULL;
*r_driven = false;
/* there must be some RNA-pointer + property combon */
@@ -350,11 +351,14 @@ FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *pro
if (!fcu && (adt->drivers.first)) {
fcu = list_find_fcurve(&adt->drivers, path, rnaindex);
- if (fcu)
+ if (fcu) {
+ if (animdata) *animdata = adt;
*r_driven = true;
+ }
}
if (fcu && action) {
+ if (animdata) *animdata = adt;
*action = adt->action;
break;
}
@@ -683,11 +687,11 @@ bool fcurve_are_keyframes_usable(FCurve *fcu)
{
/* F-Curve must exist */
if (fcu == NULL)
- return 0;
+ return false;
/* F-Curve must not have samples - samples are mutually exclusive of keyframes */
if (fcu->fpt)
- return 0;
+ return false;
/* if it has modifiers, none of these should "drastically" alter the curve */
if (fcu->modifiers.first) {
@@ -714,7 +718,7 @@ bool fcurve_are_keyframes_usable(FCurve *fcu)
FMod_Generator *data = (FMod_Generator *)fcm->data;
if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
- return 0;
+ return false;
break;
}
case FMODIFIER_TYPE_FN_GENERATOR:
@@ -722,18 +726,18 @@ bool fcurve_are_keyframes_usable(FCurve *fcu)
FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)fcm->data;
if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
- return 0;
+ return false;
break;
}
/* always harmful - cannot allow */
default:
- return 0;
+ return false;
}
}
}
/* keyframes are usable */
- return 1;
+ return true;
}
bool BKE_fcurve_is_protected(FCurve *fcu)
@@ -816,7 +820,7 @@ void fcurve_store_samples(FCurve *fcu, void *data, int start, int end, FcuSample
printf("Error: No F-Curve with F-Curve Modifiers to Bake\n");
return;
}
- if (start >= end) {
+ if (start > end) {
printf("Error: Frame range for Sampled F-Curve creation is inappropriate\n");
return;
}
@@ -1279,7 +1283,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
/* extract transform just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
- BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
/* ... and from that, we get our transform */
copy_v3_v3(tmp_loc, mat[3]);
@@ -1304,7 +1308,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
/* extract transform just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
- BKE_constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
/* ... and from that, we get our transform */
copy_v3_v3(tmp_loc, mat[3]);
@@ -1381,7 +1385,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
/* just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
- BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
}
else {
/* specially calculate local matrix, since chan_mat is not valid
@@ -1408,7 +1412,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
/* just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
- BKE_constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
}
else {
/* transforms to matrix */
@@ -2098,7 +2102,7 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
* This lower bound was established in b888a32eee8147b028464336ad2404d8155c64dd
*/
a = binarysearch_bezt_index_ex(bezts, evaltime, fcu->totvert, 0.0001, &exact);
- if (G.debug & G_DEBUG) printf("eval fcurve '%s' - %f => %d/%d, %d\n", fcu->rna_path, evaltime, a, fcu->totvert, exact);
+ if (G.debug & G_DEBUG) printf("eval fcurve '%s' - %f => %u/%u, %d\n", fcu->rna_path, evaltime, a, fcu->totvert, exact);
if (exact) {
/* index returned must be interpreted differently when it sits on top of an existing keyframe
@@ -2153,18 +2157,29 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
v4[0] = bezt->vec[1][0];
v4[1] = bezt->vec[1][1];
- /* adjust handles so that they don't overlap (forming a loop) */
- correct_bezpart(v1, v2, v3, v4);
-
- /* try to get a value for this position - if failure, try another set of points */
- b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
- if (b) {
- berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
- cvalue = opl[0];
- /* break; */
+ if (fabsf(v1[1] - v4[1]) < FLT_EPSILON &&
+ fabsf(v2[1] - v3[1]) < FLT_EPSILON &&
+ fabsf(v3[1] - v4[1]) < FLT_EPSILON)
+ {
+ /* Optimisation: If all the handles are flat/at the same values,
+ * the value is simply the shared value (see T40372 -> F91346)
+ */
+ cvalue = v1[1];
}
else {
- if (G.debug & G_DEBUG) printf(" ERROR: findzero() failed at %f with %f %f %f %f\n", evaltime, v1[0], v2[0], v3[0], v4[0]);
+ /* adjust handles so that they don't overlap (forming a loop) */
+ correct_bezpart(v1, v2, v3, v4);
+
+ /* try to get a value for this position - if failure, try another set of points */
+ b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
+ if (b) {
+ berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
+ cvalue = opl[0];
+ /* break; */
+ }
+ else {
+ if (G.debug & G_DEBUG) printf(" ERROR: findzero() failed at %f with %f %f %f %f\n", evaltime, v1[0], v2[0], v3[0], v4[0]);
+ }
}
break;
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 56b087e7eb6..af0db5e1c47 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -27,8 +27,6 @@
* \ingroup bke
*/
-
-
#include <math.h>
#include <stdio.h>
#include <stddef.h>
@@ -1173,7 +1171,7 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm)
/* sanity check */
if (fcm == NULL)
- return 0;
+ return false;
/* free modifier's special data (stored inside fcm->data) */
if (fcm->data) {
@@ -1187,13 +1185,13 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm)
/* remove modifier from stack */
if (modifiers) {
BLI_freelinkN(modifiers, fcm);
- return 1;
+ return true;
}
else {
/* XXX this case can probably be removed some day, as it shouldn't happen... */
printf("remove_fmodifier() - no modifier stack given\n");
MEM_freeN(fcm);
- return 0;
+ return false;
}
}
@@ -1264,7 +1262,7 @@ bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype)
/* sanity checks */
if (ELEM(NULL, modifiers, modifiers->first))
- return 0;
+ return false;
/* find the first mdifier fitting these criteria */
for (fcm = modifiers->first; fcm; fcm = fcm->next) {
@@ -1279,11 +1277,11 @@ bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype)
/* if both are ok, we've found a hit */
if (mOk && aOk)
- return 1;
+ return true;
}
/* no matches */
- return 0;
+ return false;
}
/* Evaluation API --------------------------- */
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 8d4bb7ec058..2adf8ebc615 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -245,7 +245,7 @@ VFont *BKE_vfont_load(Main *bmain, const char *name)
}
/* Do not add FO_BUILTIN_NAME to temporary listbase */
- if (strcmp(filename, FO_BUILTIN_NAME)) {
+ if (!STREQ(filename, FO_BUILTIN_NAME)) {
vfont->temp_pf = temp_pf;
}
}
diff --git a/source/blender/blenkernel/intern/freestyle.c b/source/blender/blenkernel/intern/freestyle.c
index 4aa1b49ea13..cc9ad63d451 100644
--- a/source/blender/blenkernel/intern/freestyle.c
+++ b/source/blender/blenkernel/intern/freestyle.c
@@ -181,7 +181,7 @@ static FreestyleLineSet *alloc_lineset(void)
FreestyleLineSet *BKE_freestyle_lineset_add(FreestyleConfig *config, const char *name)
{
- int lineset_index = BLI_countlist(&config->linesets);
+ int lineset_index = BLI_listbase_count(&config->linesets);
FreestyleLineSet *lineset = alloc_lineset();
BLI_addtail(&config->linesets, (void *)lineset);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index e226e9d9797..dd2155505fb 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -45,6 +45,7 @@
#include "DNA_gpencil_types.h"
#include "DNA_userdef_types.h"
+#include "BKE_animsys.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_library.h"
@@ -115,6 +116,12 @@ void BKE_gpencil_free(bGPdata *gpd)
{
/* free layers */
free_gpencil_layers(&gpd->layers);
+
+ /* free animation data */
+ if (gpd->adt) {
+ BKE_free_animdata(&gpd->id);
+ gpd->adt = NULL;
+ }
}
/* -------- Container Creation ---------- */
@@ -276,7 +283,7 @@ bGPDlayer *gpencil_layer_duplicate(bGPDlayer *src)
}
/* make a copy of a given gpencil datablock */
-bGPdata *gpencil_data_duplicate(bGPdata *src)
+bGPdata *gpencil_data_duplicate(bGPdata *src, bool internal_copy)
{
bGPDlayer *gpl, *gpld;
bGPdata *dst;
@@ -286,7 +293,14 @@ bGPdata *gpencil_data_duplicate(bGPdata *src)
return NULL;
/* make a copy of the base-data */
- dst = MEM_dupallocN(src);
+ if (internal_copy) {
+ /* make a straight copy for undo buffers used during stroke drawing */
+ dst = MEM_dupallocN(src);
+ }
+ else {
+ /* make a copy when others use this */
+ dst = BKE_libblock_copy(&src->id);
+ }
/* copy layers */
BLI_listbase_clear(&dst->layers);
@@ -300,6 +314,31 @@ bGPdata *gpencil_data_duplicate(bGPdata *src)
return dst;
}
+/* -------- GP-Stroke API --------- */
+
+/* ensure selection status of stroke is in sync with its points */
+void gpencil_stroke_sync_selection(bGPDstroke *gps)
+{
+ bGPDspoint *pt;
+ int i;
+
+ /* error checking */
+ if (gps == NULL)
+ return;
+
+ /* we'll stop when we find the first selected point,
+ * so initially, we must deselect
+ */
+ gps->flag &= ~GP_STROKE_SELECT;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ gps->flag |= GP_STROKE_SELECT;
+ break;
+ }
+ }
+}
+
/* -------- GP-Frame API ---------- */
/* delete the last stroke of the given frame */
@@ -359,7 +398,7 @@ bGPDframe *gpencil_layer_getframe(bGPDlayer *gpl, int cframe, short addnew)
/* 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))
+ if (gpl->flag & 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)
@@ -468,16 +507,23 @@ bGPDframe *gpencil_layer_getframe(bGPDlayer *gpl, int cframe, short addnew)
bool gpencil_layer_delframe(bGPDlayer *gpl, bGPDframe *gpf)
{
bool changed = false;
-
+
/* error checking */
if (ELEM(NULL, gpl, gpf))
return false;
-
+
+ /* if this frame was active, make the previous frame active instead
+ * since it's tricky to set active frame otherwise
+ */
+ if (gpl->actframe == gpf)
+ gpl->actframe = gpf->prev;
+ else
+ gpl->actframe = NULL;
+
/* free the frame and its data */
changed = free_gpencil_strokes(gpf);
BLI_freelinkN(&gpl->frames, gpf);
- gpl->actframe = NULL;
-
+
return changed;
}
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 6ea6bafaa14..ae3ab833a87 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -149,6 +149,10 @@ Group *BKE_group_copy(Group *group)
groupn = BKE_libblock_copy(&group->id);
BLI_duplicatelist(&groupn->gobject, &group->gobject);
+ if (group->id.lib) {
+ BKE_id_lib_local_paths(G.main, group->id.lib, &groupn->id);
+ }
+
return groupn;
}
@@ -215,6 +219,43 @@ static int group_object_unlink_internal(Group *group, Object *ob)
return removed;
}
+static bool group_object_cyclic_check_internal(Object *object, Group *group)
+{
+ if (object->dup_group) {
+ Group *dup_group = object->dup_group;
+ if ((dup_group->id.flag & LIB_DOIT) == 0) {
+ /* Cycle already exists in groups, let's prevent further crappyness */
+ return true;
+ }
+ /* flag the object to identify cyclic dependencies in further dupli groups */
+ dup_group->id.flag &= ~LIB_DOIT;
+
+ if (dup_group == group)
+ return true;
+ else {
+ GroupObject *gob;
+ for (gob = dup_group->gobject.first; gob; gob = gob->next) {
+ if (group_object_cyclic_check_internal(gob->ob, group)) {
+ return true;
+ }
+ }
+ }
+
+ /* un-flag the object, it's allowed to have the same group multiple times in parallel */
+ dup_group->id.flag |= LIB_DOIT;
+ }
+
+ return false;
+}
+
+bool BKE_group_object_cyclic_check(Main *bmain, Object *object, Group *group)
+{
+ /* first flag all groups */
+ BKE_main_id_tag_listbase(&bmain->group, true);
+
+ return group_object_cyclic_check_internal(object, group);
+}
+
bool BKE_group_object_unlink(Group *group, Object *object, Scene *scene, Base *base)
{
if (group_object_unlink_internal(group, object)) {
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 4dbd15a3774..4d83f8cf916 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -42,10 +42,18 @@
#include "MEM_guardedalloc.h"
+#include "BLI_strict_flags.h"
+
/* IDPropertyTemplate is a union in DNA_ID.h */
+/**
+ * if the new is 'IDP_ARRAY_REALLOC_LIMIT' items less,
+ * than #IDProperty.totallen, reallocate anyway.
+ */
+#define IDP_ARRAY_REALLOC_LIMIT 200
+
/*local size table.*/
-static char idp_size_table[] = {
+static size_t idp_size_table[] = {
1, /*strings*/
sizeof(int),
sizeof(float),
@@ -158,9 +166,8 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen)
BLI_assert(prop->type == IDP_IDPARRAY);
/* first check if the array buffer size has room */
- /* if newlen is 200 items less then totallen, reallocate anyway */
if (newlen <= prop->totallen) {
- if (newlen < prop->len && prop->totallen - newlen < 200) {
+ if (newlen < prop->len && prop->totallen - newlen < IDP_ARRAY_REALLOC_LIMIT) {
int i;
for (i = newlen; i < prop->len; i++)
@@ -194,7 +201,7 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen)
*/
newsize = newlen;
newsize = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
- prop->data.pointer = MEM_recallocN(prop->data.pointer, sizeof(IDProperty) * newsize);
+ prop->data.pointer = MEM_recallocN(prop->data.pointer, sizeof(IDProperty) * (size_t)newsize);
prop->len = newlen;
prop->totallen = newsize;
}
@@ -235,8 +242,7 @@ void IDP_ResizeArray(IDProperty *prop, int newlen)
const bool is_grow = newlen >= prop->len;
/* first check if the array buffer size has room */
- /* if newlen is 200 chars less then totallen, reallocate anyway */
- if (newlen <= prop->totallen && prop->totallen - newlen < 200) {
+ if (newlen <= prop->totallen && prop->totallen - newlen < IDP_ARRAY_REALLOC_LIMIT) {
idp_resize_group_array(prop, newlen, prop->data.pointer);
prop->len = newlen;
return;
@@ -256,7 +262,8 @@ void IDP_ResizeArray(IDProperty *prop, int newlen)
if (is_grow == false)
idp_resize_group_array(prop, newlen, prop->data.pointer);
- prop->data.pointer = MEM_recallocN(prop->data.pointer, idp_size_table[(int)prop->subtype] * newsize);
+ prop->data.pointer = MEM_recallocN(
+ prop->data.pointer, idp_size_table[(int)prop->subtype] * (size_t)newsize);
if (is_grow == true)
idp_resize_group_array(prop, newlen, prop->data.pointer);
@@ -321,8 +328,8 @@ static IDProperty *IDP_CopyArray(const IDProperty *prop)
*
* \param st The string to assign.
* \param name The property name.
- * \param maxlen The size of the new string (including the \0 terminator)
- * \return
+ * \param maxlen The size of the new string (including the \0 terminator).
+ * \return The new string property.
*/
IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
{
@@ -336,14 +343,14 @@ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
}
else {
/* include null terminator '\0' */
- int stlen = strlen(st) + 1;
+ int stlen = (int)strlen(st) + 1;
if (maxlen > 0 && maxlen < stlen)
stlen = maxlen;
- prop->data.pointer = MEM_mallocN(stlen, "id property string 2");
+ prop->data.pointer = MEM_mallocN((size_t)stlen, "id property string 2");
prop->len = prop->totallen = stlen;
- BLI_strncpy(prop->data.pointer, st, stlen);
+ BLI_strncpy(prop->data.pointer, st, (size_t)stlen);
}
prop->type = IDP_STRING;
@@ -374,18 +381,18 @@ void IDP_AssignString(IDProperty *prop, const char *st, int maxlen)
int stlen;
BLI_assert(prop->type == IDP_STRING);
- stlen = strlen(st);
+ stlen = (int)strlen(st);
if (maxlen > 0 && maxlen < stlen)
stlen = maxlen;
if (prop->subtype == IDP_STRING_SUB_BYTE) {
IDP_ResizeArray(prop, stlen);
- memcpy(prop->data.pointer, st, stlen);
+ memcpy(prop->data.pointer, st, (size_t)stlen);
}
else {
stlen++;
IDP_ResizeArray(prop, stlen);
- BLI_strncpy(prop->data.pointer, st, stlen);
+ BLI_strncpy(prop->data.pointer, st, (size_t)stlen);
}
}
@@ -395,7 +402,7 @@ void IDP_ConcatStringC(IDProperty *prop, const char *st)
BLI_assert(prop->type == IDP_STRING);
- newlen = prop->len + strlen(st);
+ newlen = prop->len + (int)strlen(st);
/* we have to remember that prop->len includes the null byte for strings.
* so there's no need to add +1 to the resize function.*/
IDP_ResizeArray(prop, newlen);
@@ -571,18 +578,18 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, const 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(IDProperty *group, IDProperty *prop)
+void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop_exist)
{
- IDProperty *loop;
-
BLI_assert(group->type == IDP_GROUP);
- if ((loop = IDP_GetPropertyFromGroup(group, prop->name))) {
- BLI_insertlinkafter(&group->data.group, loop, prop);
+ BLI_assert(prop_exist == IDP_GetPropertyFromGroup(group, prop->name));
+
+ if ((prop_exist = IDP_GetPropertyFromGroup(group, prop->name))) {
+ BLI_insertlinkafter(&group->data.group, prop_exist, prop);
- BLI_remlink(&group->data.group, loop);
- IDP_FreeProperty(loop);
- MEM_freeN(loop);
+ BLI_remlink(&group->data.group, prop_exist);
+ IDP_FreeProperty(prop_exist);
+ MEM_freeN(prop_exist);
}
else {
group->len++;
@@ -590,6 +597,13 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
}
}
+void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
+{
+ IDProperty *prop_exist = IDP_GetPropertyFromGroup(group, prop->name);
+
+ IDP_ReplaceInGroup_ex(group, prop, prop_exist);
+}
+
/**
* If a property is missing in \a dest, add it.
*/
@@ -623,8 +637,8 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw
*
* The sanity check just means the property is not added to the group if another property
* exists with the same name; the client code using ID properties then needs to detect this
- * (the function that adds new properties to groups, IDP_AddToGroup,returns 0 if a property can't
- * be added to the group, and 1 if it can) and free the property.
+ * (the function that adds new properties to groups, IDP_AddToGroup, returns false if a property can't
+ * be added to the group, and true if it can) and free the property.
*
* Currently the code to free ID properties is designed to leave the actual struct
* you pass it un-freed, this is needed for how the system works. This means
@@ -639,10 +653,10 @@ bool IDP_AddToGroup(IDProperty *group, IDProperty *prop)
if (IDP_GetPropertyFromGroup(group, prop->name) == NULL) {
group->len++;
BLI_addtail(&group->data.group, prop);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/**
@@ -656,10 +670,10 @@ bool IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew
if (IDP_GetPropertyFromGroup(group, pnew->name) == NULL) {
group->len++;
BLI_insertlinkafter(&group->data.group, previous, pnew);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/**
@@ -700,56 +714,6 @@ IDProperty *IDP_GetPropertyTypeFromGroup(IDProperty *prop, const char *name, con
return (idprop && idprop->type == type) ? idprop : NULL;
}
-typedef struct IDPIter {
- void *next;
- IDProperty *parent;
-} IDPIter;
-
-/**
- * Get an iterator to iterate over the members of an id property group.
- * Note that this will automatically free the iterator once iteration is complete;
- * if you stop the iteration before hitting the end, make sure to call
- * IDP_FreeIterBeforeEnd().
- */
-void *IDP_GetGroupIterator(IDProperty *prop)
-{
- IDPIter *iter;
-
- BLI_assert(prop->type == IDP_GROUP);
- iter = MEM_mallocN(sizeof(IDPIter), "IDPIter");
- iter->next = prop->data.group.first;
- iter->parent = prop;
- return (void *) iter;
-}
-
-/**
- * Returns the next item in the iteration. To use, simple for a loop like the following:
- * while (IDP_GroupIterNext(iter) != NULL) {
- * ...
- * }
- */
-IDProperty *IDP_GroupIterNext(void *vself)
-{
- IDPIter *self = (IDPIter *) vself;
- Link *next = (Link *) self->next;
- if (self->next == NULL) {
- MEM_freeN(self);
- return NULL;
- }
-
- self->next = next->next;
- return (void *) next;
-}
-
-/**
- * Frees the iterator pointed to at vself, only use this if iteration is stopped early;
- * when the iterator hits the end of the list it'll automatically free itself.\
- */
-void IDP_FreeIterBeforeEnd(void *vself)
-{
- MEM_freeN(vself);
-}
-
/* Ok, the way things work, Groups free the ID Property structs of their children.
* This is because all ID Property freeing functions free only direct data (not the ID Property
* struct itself), but for Groups the child properties *are* considered
@@ -811,11 +775,11 @@ IDProperty *IDP_GetProperties(ID *id, const bool create_if_needed)
bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is_strict)
{
if (prop1 == NULL && prop2 == NULL)
- return 1;
+ return true;
else if (prop1 == NULL || prop2 == NULL)
- return is_strict ? 0 : 1;
+ return is_strict ? false : true;
else if (prop1->type != prop2->type)
- return 0;
+ return false;
switch (prop1->type) {
case IDP_INT:
@@ -838,27 +802,32 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
case IDP_DOUBLE:
return (IDP_Double(prop1) == IDP_Double(prop2));
case IDP_STRING:
- return ((prop1->len == prop2->len) && strncmp(IDP_String(prop1), IDP_String(prop2), prop1->len) == 0);
+ {
+ return (((prop1->len == prop2->len) &&
+ STREQLEN(IDP_String(prop1), IDP_String(prop2), (size_t)prop1->len)));
+ }
case IDP_ARRAY:
if (prop1->len == prop2->len && prop1->subtype == prop2->subtype) {
- return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype] * prop1->len);
+ return (memcmp(IDP_Array(prop1),
+ IDP_Array(prop2),
+ idp_size_table[(int)prop1->subtype] * (size_t)prop1->len) == 0);
}
- return 0;
+ return false;
case IDP_GROUP:
{
IDProperty *link1, *link2;
if (is_strict && prop1->len != prop2->len)
- return 0;
+ return false;
for (link1 = prop1->data.group.first; link1; link1 = link1->next) {
link2 = IDP_GetPropertyFromGroup(prop2, link1->name);
if (!IDP_EqualsProperties_ex(link1, link2, is_strict))
- return 0;
+ return false;
}
- return 1;
+ return true;
}
case IDP_IDPARRAY:
{
@@ -867,12 +836,12 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
int i;
if (prop1->len != prop2->len)
- return 0;
+ return false;
for (i = 0; i < prop1->len; i++)
if (!IDP_EqualsProperties(&array1[i], &array2[i]))
- return 0;
- return 1;
+ return false;
+ return true;
}
default:
/* should never get here */
@@ -880,7 +849,7 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
break;
}
- return 1;
+ return true;
}
bool IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
@@ -913,7 +882,7 @@ bool IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
* IDP_AddToGroup or MEM_freeN the property, doing anything else might result in
* a memory leak.
*/
-IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name)
+IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name)
{
IDProperty *prop = NULL;
@@ -940,8 +909,10 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n
{
prop = MEM_callocN(sizeof(IDProperty), "IDProperty array");
prop->subtype = val->array.type;
- if (val->array.len)
- prop->data.pointer = MEM_callocN(idp_size_table[val->array.type] * val->array.len, "id property array");
+ if (val->array.len) {
+ prop->data.pointer = MEM_callocN(
+ idp_size_table[val->array.type] * (size_t)val->array.len, "id property array");
+ }
prop->len = prop->totallen = val->array.len;
break;
}
@@ -961,9 +932,9 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n
prop->len = 0;
}
else {
- prop->data.pointer = MEM_mallocN(val->string.len, "id property string 2");
+ prop->data.pointer = MEM_mallocN((size_t)val->string.len, "id property string 2");
prop->len = prop->totallen = val->string.len;
- memcpy(prop->data.pointer, st, val->string.len);
+ memcpy(prop->data.pointer, st, (size_t)val->string.len);
}
prop->subtype = IDP_STRING_SUB_BYTE;
}
@@ -975,10 +946,10 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n
prop->len = 1; /*NULL string, has len of 1 to account for null byte.*/
}
else {
- int stlen = strlen(st) + 1;
- prop->data.pointer = MEM_mallocN(stlen, "id property string 3");
+ int stlen = (int)strlen(st) + 1;
+ prop->data.pointer = MEM_mallocN((size_t)stlen, "id property string 3");
prop->len = prop->totallen = stlen;
- memcpy(prop->data.pointer, st, stlen);
+ memcpy(prop->data.pointer, st, (size_t)stlen);
}
prop->subtype = IDP_STRING_SUB_UTF8;
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 54f5cb7a68e..9b00a0150ad 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -117,21 +117,21 @@ typedef struct ImageCacheKey {
static unsigned int imagecache_hashhash(const void *key_v)
{
- const ImageCacheKey *key = (ImageCacheKey *) key_v;
+ const ImageCacheKey *key = key_v;
return key->index;
}
static bool imagecache_hashcmp(const void *a_v, const void *b_v)
{
- const ImageCacheKey *a = (ImageCacheKey *) a_v;
- const ImageCacheKey *b = (ImageCacheKey *) b_v;
+ const ImageCacheKey *a = a_v;
+ const ImageCacheKey *b = b_v;
return (a->index != b->index);
}
static void imagecache_keydata(void *userkey, int *framenr, int *proxy, int *render_flags)
{
- ImageCacheKey *key = (ImageCacheKey *)userkey;
+ ImageCacheKey *key = userkey;
*framenr = IMA_INDEX_FRAME(key->index);
*proxy = IMB_PROXY_NONE;
@@ -273,7 +273,13 @@ void BKE_image_free_buffers(Image *ima)
ima->rr = NULL;
}
- GPU_free_image(ima);
+ if (!G.background) {
+ /* Background mode doesn't use opnegl,
+ * so we can avoid freeing GPU images and save some
+ * time by skipping mutex lock.
+ */
+ GPU_free_image(ima);
+ }
ima->ok = IMA_OK;
}
@@ -378,6 +384,10 @@ Image *BKE_image_copy(Main *bmain, Image *ima)
if (ima->packedfile)
nima->packedfile = dupPackedFile(ima->packedfile);
+ if (ima->id.lib) {
+ BKE_id_lib_local_paths(bmain, ima->id.lib, &nima->id);
+ }
+
return nima;
}
@@ -661,7 +671,7 @@ Image *BKE_image_load(Main *bmain, const char *filepath)
/* otherwise creates new. */
/* does not load ibuf itself */
/* pass on optional frame for #name images */
-Image *BKE_image_load_exists(const char *filepath)
+Image *BKE_image_load_exists_ex(const char *filepath, bool *r_exists)
{
Image *ima;
char str[FILE_MAX], strtest[FILE_MAX];
@@ -677,20 +687,27 @@ Image *BKE_image_load_exists(const char *filepath)
if (BLI_path_cmp(strtest, str) == 0) {
if (ima->anim == NULL || ima->id.us == 0) {
- BLI_strncpy(ima->name, filepath, sizeof(ima->name)); /* for stringcode */
- ima->id.us++; /* officially should not, it doesn't link here! */
+ ima->id.us++; /* officially should not, it doesn't link here! */
if (ima->ok == 0)
ima->ok = IMA_OK;
- /* RETURN! */
+ if (r_exists)
+ *r_exists = true;
return ima;
}
}
}
}
+ if (r_exists)
+ *r_exists = false;
return BKE_image_load(G.main, filepath);
}
+Image *BKE_image_load_exists(const char *filepath)
+{
+ return BKE_image_load_exists_ex(filepath, NULL);
+}
+
static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type,
const float color[4], ColorManagedColorspaceSettings *colorspace_settings)
{
@@ -785,7 +802,9 @@ Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int hei
return ima;
}
-/* creates an image image owns the imbuf passed */
+/* Create an image image from ibuf. The refcount of ibuf is increased,
+ * caller should take care to drop its reference by calling
+ * IMB_freeImBuf if needed. */
Image *BKE_image_add_from_imbuf(ImBuf *ibuf)
{
/* on save, type is changed to FILE in editsima.c */
@@ -842,14 +861,14 @@ void BKE_image_memorypack(Image *ima)
void BKE_image_tag_time(Image *ima)
{
- ima->lastused = (int)PIL_check_seconds_timer();
+ ima->lastused = PIL_check_seconds_timer_i();
}
#if 0
static void tag_all_images_time()
{
Image *ima;
- int ctime = (int)PIL_check_seconds_timer();
+ int ctime = PIL_check_seconds_timer_i();
ima = G.main->image.first;
while (ima) {
@@ -993,7 +1012,7 @@ void BKE_image_all_free_anim_ibufs(int cfra)
/* *********** READ AND WRITE ************** */
-int BKE_imtype_to_ftype(const char imtype)
+int BKE_image_imtype_to_ftype(const char imtype)
{
if (imtype == R_IMF_IMTYPE_TARGA)
return TGA;
@@ -1033,7 +1052,7 @@ int BKE_imtype_to_ftype(const char imtype)
return JPG | 90;
}
-char BKE_ftype_to_imtype(const int ftype)
+char BKE_image_ftype_to_imtype(const int ftype)
{
if (ftype == 0)
return R_IMF_IMTYPE_TARGA;
@@ -1205,42 +1224,42 @@ char BKE_imtype_valid_depths(const char imtype)
* creator.c help info */
char BKE_imtype_from_arg(const char *imtype_arg)
{
- if (!strcmp(imtype_arg, "TGA")) return R_IMF_IMTYPE_TARGA;
- else if (!strcmp(imtype_arg, "IRIS")) return R_IMF_IMTYPE_IRIS;
+ if (STREQ(imtype_arg, "TGA")) return R_IMF_IMTYPE_TARGA;
+ else if (STREQ(imtype_arg, "IRIS")) return R_IMF_IMTYPE_IRIS;
#ifdef WITH_DDS
- else if (!strcmp(imtype_arg, "DDS")) return R_IMF_IMTYPE_DDS;
+ else if (STREQ(imtype_arg, "DDS")) return R_IMF_IMTYPE_DDS;
#endif
- else if (!strcmp(imtype_arg, "JPEG")) return R_IMF_IMTYPE_JPEG90;
- else if (!strcmp(imtype_arg, "IRIZ")) return R_IMF_IMTYPE_IRIZ;
- else if (!strcmp(imtype_arg, "RAWTGA")) return R_IMF_IMTYPE_RAWTGA;
- else if (!strcmp(imtype_arg, "AVIRAW")) return R_IMF_IMTYPE_AVIRAW;
- else if (!strcmp(imtype_arg, "AVIJPEG")) return R_IMF_IMTYPE_AVIJPEG;
- else if (!strcmp(imtype_arg, "PNG")) return R_IMF_IMTYPE_PNG;
- else if (!strcmp(imtype_arg, "QUICKTIME")) return R_IMF_IMTYPE_QUICKTIME;
- else if (!strcmp(imtype_arg, "BMP")) return R_IMF_IMTYPE_BMP;
+ else if (STREQ(imtype_arg, "JPEG")) return R_IMF_IMTYPE_JPEG90;
+ else if (STREQ(imtype_arg, "IRIZ")) return R_IMF_IMTYPE_IRIZ;
+ else if (STREQ(imtype_arg, "RAWTGA")) return R_IMF_IMTYPE_RAWTGA;
+ else if (STREQ(imtype_arg, "AVIRAW")) return R_IMF_IMTYPE_AVIRAW;
+ else if (STREQ(imtype_arg, "AVIJPEG")) return R_IMF_IMTYPE_AVIJPEG;
+ else if (STREQ(imtype_arg, "PNG")) return R_IMF_IMTYPE_PNG;
+ else if (STREQ(imtype_arg, "QUICKTIME")) return R_IMF_IMTYPE_QUICKTIME;
+ else if (STREQ(imtype_arg, "BMP")) return R_IMF_IMTYPE_BMP;
#ifdef WITH_HDR
- else if (!strcmp(imtype_arg, "HDR")) return R_IMF_IMTYPE_RADHDR;
+ else if (STREQ(imtype_arg, "HDR")) return R_IMF_IMTYPE_RADHDR;
#endif
#ifdef WITH_TIFF
- else if (!strcmp(imtype_arg, "TIFF")) return R_IMF_IMTYPE_TIFF;
+ else if (STREQ(imtype_arg, "TIFF")) return R_IMF_IMTYPE_TIFF;
#endif
#ifdef WITH_OPENEXR
- else if (!strcmp(imtype_arg, "EXR")) return R_IMF_IMTYPE_OPENEXR;
- else if (!strcmp(imtype_arg, "MULTILAYER")) return R_IMF_IMTYPE_MULTILAYER;
+ else if (STREQ(imtype_arg, "EXR")) return R_IMF_IMTYPE_OPENEXR;
+ else if (STREQ(imtype_arg, "MULTILAYER")) return R_IMF_IMTYPE_MULTILAYER;
#endif
- else if (!strcmp(imtype_arg, "MPEG")) return R_IMF_IMTYPE_FFMPEG;
- else if (!strcmp(imtype_arg, "FRAMESERVER")) return R_IMF_IMTYPE_FRAMESERVER;
+ else if (STREQ(imtype_arg, "MPEG")) return R_IMF_IMTYPE_FFMPEG;
+ else if (STREQ(imtype_arg, "FRAMESERVER")) return R_IMF_IMTYPE_FRAMESERVER;
#ifdef WITH_CINEON
- else if (!strcmp(imtype_arg, "CINEON")) return R_IMF_IMTYPE_CINEON;
- else if (!strcmp(imtype_arg, "DPX")) return R_IMF_IMTYPE_DPX;
+ else if (STREQ(imtype_arg, "CINEON")) return R_IMF_IMTYPE_CINEON;
+ else if (STREQ(imtype_arg, "DPX")) return R_IMF_IMTYPE_DPX;
#endif
#ifdef WITH_OPENJPEG
- else if (!strcmp(imtype_arg, "JP2")) return R_IMF_IMTYPE_JP2;
+ else if (STREQ(imtype_arg, "JP2")) return R_IMF_IMTYPE_JP2;
#endif
else return R_IMF_IMTYPE_INVALID;
}
-static bool do_add_image_extension(char *string, const char imtype, const ImageFormatData *im_format)
+static bool image_path_ensure_ext(char *string, const char imtype, const ImageFormatData *im_format)
{
const char *extension = NULL;
const char *extension_test;
@@ -1350,14 +1369,14 @@ static bool do_add_image_extension(char *string, const char imtype, const ImageF
}
}
-int BKE_add_image_extension(char *string, const ImageFormatData *im_format)
+bool BKE_image_path_ensure_ext_from_imformat(char *string, const ImageFormatData *im_format)
{
- return do_add_image_extension(string, im_format->imtype, im_format);
+ return image_path_ensure_ext(string, im_format->imtype, im_format);
}
-int BKE_add_image_extension_from_type(char *string, const char imtype)
+bool BKE_image_path_ensure_ext_from_imtype(char *string, const char imtype)
{
- return do_add_image_extension(string, imtype, NULL);
+ return image_path_ensure_ext(string, imtype, NULL);
}
void BKE_imformat_defaults(ImageFormatData *im_format)
@@ -1633,7 +1652,9 @@ static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int d
}
}
-void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rectf, int width, int height, int channels)
+void BKE_image_stamp_buf(
+ Scene *scene, Object *camera,
+ unsigned char *rect, float *rectf, int width, int height, int channels)
{
struct StampData stamp_data;
float w, h, pad;
@@ -2058,8 +2079,9 @@ int BKE_imbuf_write_stamp(Scene *scene, struct Object *camera, ImBuf *ibuf, cons
}
-static void do_makepicstring(char *string, const char *base, const char *relbase, int frame, const char imtype,
- const ImageFormatData *im_format, const short use_ext, const short use_frames)
+static void image_path_makepicstring(
+ char *string, const char *base, const char *relbase, int frame, const char imtype,
+ const ImageFormatData *im_format, const short use_ext, const short use_frames)
{
if (string == NULL) return;
BLI_strncpy(string, base, FILE_MAX - 10); /* weak assumption */
@@ -2069,19 +2091,29 @@ static void do_makepicstring(char *string, const char *base, const char *relbase
BLI_path_frame(string, frame, 4);
if (use_ext)
- do_add_image_extension(string, imtype, im_format);
+ image_path_ensure_ext(string, imtype, im_format);
+}
+
+void BKE_image_path_from_imformat(
+ char *string, const char *base, const char *relbase, int frame,
+ const ImageFormatData *im_format, const bool use_ext, const bool use_frames)
+{
+ image_path_makepicstring(string, base, relbase, frame, im_format->imtype, im_format, use_ext, use_frames);
}
-void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame,
- const ImageFormatData *im_format, const bool use_ext, const bool use_frames)
+void BKE_image_path_from_imtype(
+ char *string, const char *base, const char *relbase, int frame,
+ const char imtype, const bool use_ext, const bool use_frames)
{
- do_makepicstring(string, base, relbase, frame, im_format->imtype, im_format, use_ext, use_frames);
+ image_path_makepicstring(string, base, relbase, frame, imtype, NULL, use_ext, use_frames);
}
-void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame,
- const char imtype, const bool use_ext, const bool use_frames)
+struct anim *openanim_noload(const char *name, int flags, int streamindex, char colorspace[IMA_MAX_SPACE])
{
- do_makepicstring(string, base, relbase, frame, imtype, NULL, use_ext, use_frames);
+ struct anim *anim;
+
+ anim = IMB_open_anim(name, flags, streamindex, colorspace);
+ return anim;
}
/* used by sequencer too */
@@ -2149,11 +2181,6 @@ Image *BKE_image_verify_viewer(int type, const char *name)
return ima;
}
-void BKE_image_assign_ibuf(Image *ima, ImBuf *ibuf)
-{
- image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
-}
-
void BKE_image_walk_all_users(const Main *mainp, void *customdata,
void callback(Image *ima, ImageUser *iuser, void *customdata))
{
@@ -2577,11 +2604,15 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
if (ima->anim == NULL) {
char str[FILE_MAX];
+ int flags = IB_rect;
+ if (ima->flag & IMA_DEINTERLACE) {
+ flags |= IB_animdeinterlace;
+ }
BKE_image_user_file_path(iuser, ima, str);
/* FIXME: make several stream accessible in image editor, too*/
- ima->anim = openanim(str, IB_rect, 0, ima->colorspace_settings.name);
+ ima->anim = openanim(str, flags, 0, ima->colorspace_settings.name);
/* let's initialize this user */
if (ima->anim && iuser && iuser->frames == 0)
@@ -2946,6 +2977,16 @@ static ImBuf *image_get_cached_ibuf(Image *ima, ImageUser *iuser, int *r_frame,
ima->tpageflag |= IMA_TPAGE_REFRESH;
}
ima->lastframe = frame;
+
+ /* counter the fact that image is set as invalid when loading a frame
+ * that is not in the cache (through image_acquire_ibuf for instance),
+ * yet we have valid frames in the cache loaded */
+ if (ibuf) {
+ ima->ok = IMA_OK_LOADED;
+
+ if (iuser)
+ iuser->ok = ima->ok;
+ }
}
else if (ima->type == IMA_TYPE_MULTILAYER) {
frame = iuser ? iuser->framenr : ima->lastframe;
@@ -3393,9 +3434,9 @@ bool BKE_image_has_alpha(struct Image *image)
BKE_image_release_ibuf(image, ibuf, lock);
if (planes == 32)
- return 1;
+ return true;
else
- return 0;
+ return false;
}
void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height)
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
deleted file mode 100644
index 4cf9d52989f..00000000000
--- a/source/blender/blenkernel/intern/implicit.c
+++ /dev/null
@@ -1,1964 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) Blender Foundation
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/blenkernel/intern/implicit.c
- * \ingroup bke
- */
-
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_scene_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_meshdata_types.h"
-
-#include "BLI_math.h"
-#include "BLI_linklist.h"
-#include "BLI_utildefines.h"
-
-#include "BKE_cloth.h"
-#include "BKE_collision.h"
-#include "BKE_effect.h"
-#include "BKE_global.h"
-
-
-#ifdef __GNUC__
-# pragma GCC diagnostic ignored "-Wtype-limits"
-#endif
-
-#ifdef _OPENMP
-# define CLOTH_OPENMP_LIMIT 512
-#endif
-
-#if 0 /* debug timing */
-#ifdef _WIN32
-#include <windows.h>
-static LARGE_INTEGER _itstart, _itend;
-static LARGE_INTEGER ifreq;
-static void itstart(void)
-{
- static int first = 1;
- if (first) {
- QueryPerformanceFrequency(&ifreq);
- first = 0;
- }
- QueryPerformanceCounter(&_itstart);
-}
-static void itend(void)
-{
- QueryPerformanceCounter(&_itend);
-}
-double itval(void)
-{
- return ((double)_itend.QuadPart -
- (double)_itstart.QuadPart)/((double)ifreq.QuadPart);
-}
-#else
-#include <sys/time.h>
-// intrinsics need better compile flag checking
-// #include <xmmintrin.h>
-// #include <pmmintrin.h>
-// #include <pthread.h>
-
-static struct timeval _itstart, _itend;
-static struct timezone itz;
-static void itstart(void)
-{
- gettimeofday(&_itstart, &itz);
-}
-static void itend(void)
-{
- gettimeofday(&_itend, &itz);
-}
-static double itval(void)
-{
- double t1, t2;
- t1 = (double)_itstart.tv_sec + (double)_itstart.tv_usec/(1000*1000);
- t2 = (double)_itend.tv_sec + (double)_itend.tv_usec/(1000*1000);
- return t2-t1;
-}
-#endif
-#endif /* debug timing */
-
-static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
-static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
-
-/*
-#define C99
-#ifdef C99
-#defineDO_INLINE inline
-#else
-#defineDO_INLINE static
-#endif
-*/
-struct Cloth;
-
-//////////////////////////////////////////
-/* fast vector / matrix library, enhancements are welcome :) -dg */
-/////////////////////////////////////////
-
-/* DEFINITIONS */
-typedef float lfVector[3];
-typedef struct fmatrix3x3 {
- float m[3][3]; /* 3x3 matrix */
- unsigned int c, r; /* column and row number */
- /* int pinned; // is this vertex allowed to move? */
- float n1, n2, n3; /* three normal vectors for collision constrains */
- unsigned int vcount; /* vertex count */
- unsigned int scount; /* spring count */
-} fmatrix3x3;
-
-///////////////////////////
-// float[3] vector
-///////////////////////////
-/* simple vector code */
-/* STATUS: verified */
-DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar)
-{
- to[0] = from[0] * scalar;
- to[1] = from[1] * scalar;
- to[2] = from[2] * scalar;
-}
-/* simple cross product */
-/* STATUS: verified */
-DO_INLINE void cross_fvector(float to[3], float vectorA[3], float vectorB[3])
-{
- to[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1];
- to[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2];
- to[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0];
-}
-/* simple v^T * v product ("outer product") */
-/* STATUS: HAS TO BE verified (*should* work) */
-DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3])
-{
- mul_fvector_S(to[0], vectorB, vectorA[0]);
- mul_fvector_S(to[1], vectorB, vectorA[1]);
- mul_fvector_S(to[2], vectorB, vectorA[2]);
-}
-/* simple v^T * v product with scalar ("outer product") */
-/* STATUS: HAS TO BE verified (*should* work) */
-DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS)
-{
- mul_fvectorT_fvector(to, vectorA, vectorB);
-
- mul_fvector_S(to[0], to[0], aS);
- mul_fvector_S(to[1], to[1], aS);
- mul_fvector_S(to[2], to[2], aS);
-}
-
-#if 0
-/* printf vector[3] on console: for debug output */
-static void print_fvector(float m3[3])
-{
- printf("%f\n%f\n%f\n\n", m3[0], m3[1], m3[2]);
-}
-
-///////////////////////////
-// long float vector float (*)[3]
-///////////////////////////
-/* print long vector on console: for debug output */
-DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts)
-{
- unsigned int i = 0;
- for (i = 0; i < verts; i++) {
- print_fvector(fLongVector[i]);
- }
-}
-#endif
-
-/* create long vector */
-DO_INLINE lfVector *create_lfvector(unsigned int verts)
-{
- /* TODO: check if memory allocation was successful */
- return (lfVector *)MEM_callocN(verts * sizeof(lfVector), "cloth_implicit_alloc_vector");
- // return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector));
-}
-/* delete long vector */
-DO_INLINE void del_lfvector(float (*fLongVector)[3])
-{
- if (fLongVector != NULL) {
- MEM_freeN(fLongVector);
- // cloth_aligned_free(&MEMORY_BASE, fLongVector);
- }
-}
-/* copy long vector */
-DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts)
-{
- memcpy(to, from, verts * sizeof(lfVector));
-}
-/* init long vector with float[3] */
-DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts)
-{
- unsigned int i = 0;
- for (i = 0; i < verts; i++) {
- copy_v3_v3(fLongVector[i], vector);
- }
-}
-/* zero long vector with float[3] */
-DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts)
-{
- memset(to, 0.0f, verts * sizeof(lfVector));
-}
-/* multiply long vector with scalar*/
-DO_INLINE void mul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts)
-{
- unsigned int i = 0;
-
- for (i = 0; i < verts; i++) {
- mul_fvector_S(to[i], fLongVector[i], scalar);
- }
-}
-/* multiply long vector with scalar*/
-/* A -= B * float */
-DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts)
-{
- unsigned int i = 0;
- for (i = 0; i < verts; i++) {
- VECSUBMUL(to[i], fLongVector[i], scalar);
- }
-}
-/* dot product for big vector */
-DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
-{
- long i = 0;
- float temp = 0.0;
-// XXX brecht, disabled this for now (first schedule line was already disabled),
-// due to non-commutative nature of floating point ops this makes the sim give
-// different results each time you run it!
-// schedule(guided, 2)
-//#pragma omp parallel for reduction(+: temp) if (verts > CLOTH_OPENMP_LIMIT)
- for (i = 0; i < (long)verts; i++) {
- temp += dot_v3v3(fLongVectorA[i], fLongVectorB[i]);
- }
- return temp;
-}
-/* A = B + C --> for big vector */
-DO_INLINE void add_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
-{
- unsigned int i = 0;
-
- for (i = 0; i < verts; i++) {
- VECADD(to[i], fLongVectorA[i], fLongVectorB[i]);
- }
-
-}
-/* A = B + C * float --> for big vector */
-DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts)
-{
- unsigned int i = 0;
-
- for (i = 0; i < verts; i++) {
- VECADDS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
-
- }
-}
-/* A = B * float + C * float --> for big vector */
-DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float aS, float (*fLongVectorB)[3], float bS, unsigned int verts)
-{
- unsigned int i = 0;
-
- for (i = 0; i < verts; i++) {
- VECADDSS(to[i], fLongVectorA[i], aS, fLongVectorB[i], bS);
- }
-}
-/* A = B - C * float --> for big vector */
-DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts)
-{
- unsigned int i = 0;
- for (i = 0; i < verts; i++) {
- VECSUBS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
- }
-
-}
-/* A = B - C --> for big vector */
-DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
-{
- unsigned int i = 0;
-
- for (i = 0; i < verts; i++) {
- sub_v3_v3v3(to[i], fLongVectorA[i], fLongVectorB[i]);
- }
-
-}
-///////////////////////////
-// 3x3 matrix
-///////////////////////////
-#if 0
-/* printf 3x3 matrix on console: for debug output */
-static void print_fmatrix(float m3[3][3])
-{
- printf("%f\t%f\t%f\n", m3[0][0], m3[0][1], m3[0][2]);
- printf("%f\t%f\t%f\n", m3[1][0], m3[1][1], m3[1][2]);
- printf("%f\t%f\t%f\n\n", m3[2][0], m3[2][1], m3[2][2]);
-}
-#endif
-
-/* copy 3x3 matrix */
-DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3])
-{
- // memcpy(to, from, sizeof (float) * 9);
- copy_v3_v3(to[0], from[0]);
- copy_v3_v3(to[1], from[1]);
- copy_v3_v3(to[2], from[2]);
-}
-
-/* copy 3x3 matrix */
-DO_INLINE void initdiag_fmatrixS(float to[3][3], float aS)
-{
- cp_fmatrix(to, ZERO);
-
- to[0][0] = aS;
- to[1][1] = aS;
- to[2][2] = aS;
-}
-
-/* calculate determinant of 3x3 matrix */
-DO_INLINE float det_fmatrix(float m[3][3])
-{
- return m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0]
- -m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2];
-}
-
-DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
-{
- unsigned int i, j;
- float d;
-
- if ((d=det_fmatrix(from)) == 0) {
- printf("can't build inverse");
- exit(0);
- }
- for (i=0;i<3;i++) {
- for (j=0;j<3;j++) {
- int i1=(i+1)%3;
- int i2=(i+2)%3;
- int j1=(j+1)%3;
- int j2=(j+2)%3;
- // reverse indexs i&j to take transpose
- to[j][i] = (from[i1][j1]*from[i2][j2]-from[i1][j2]*from[i2][j1])/d;
- /*
- if (i==j)
- to[i][j] = 1.0f / from[i][j];
- else
- to[i][j] = 0;
- */
- }
- }
-
-}
-
-/* 3x3 matrix multiplied by a scalar */
-/* STATUS: verified */
-DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar)
-{
- mul_fvector_S(matrix[0], matrix[0], scalar);
- mul_fvector_S(matrix[1], matrix[1], scalar);
- mul_fvector_S(matrix[2], matrix[2], scalar);
-}
-
-/* a vector multiplied by a 3x3 matrix */
-/* STATUS: verified */
-DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][3])
-{
- to[0] = matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
- to[1] = matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
- to[2] = matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
-}
-
-/* 3x3 matrix multiplied by a vector */
-/* STATUS: verified */
-DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float from[3])
-{
- to[0] = dot_v3v3(matrix[0], from);
- to[1] = dot_v3v3(matrix[1], from);
- to[2] = dot_v3v3(matrix[2], from);
-}
-/* 3x3 matrix multiplied by a 3x3 matrix */
-/* STATUS: verified */
-DO_INLINE void mul_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- mul_fvector_fmatrix(to[0], matrixA[0], matrixB);
- mul_fvector_fmatrix(to[1], matrixA[1], matrixB);
- mul_fvector_fmatrix(to[2], matrixA[2], matrixB);
-}
-/* 3x3 matrix addition with 3x3 matrix */
-DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- VECADD(to[0], matrixA[0], matrixB[0]);
- VECADD(to[1], matrixA[1], matrixB[1]);
- VECADD(to[2], matrixA[2], matrixB[2]);
-}
-/* 3x3 matrix add-addition with 3x3 matrix */
-DO_INLINE void addadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- VECADDADD(to[0], matrixA[0], matrixB[0]);
- VECADDADD(to[1], matrixA[1], matrixB[1]);
- VECADDADD(to[2], matrixA[2], matrixB[2]);
-}
-/* 3x3 matrix sub-addition with 3x3 matrix */
-DO_INLINE void addsub_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS)
-{
- VECADDSUBSS(to[0], matrixA[0], aS, matrixB[0], bS);
- VECADDSUBSS(to[1], matrixA[1], aS, matrixB[1], bS);
- VECADDSUBSS(to[2], matrixA[2], aS, matrixB[2], bS);
-}
-/* A -= B + C (3x3 matrix sub-addition with 3x3 matrix) */
-DO_INLINE void subadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- VECSUBADD(to[0], matrixA[0], matrixB[0]);
- VECSUBADD(to[1], matrixA[1], matrixB[1]);
- VECSUBADD(to[2], matrixA[2], matrixB[2]);
-}
-/* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */
-DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS)
-{
- VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS);
- VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS);
- VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS);
-}
-/* A = B - C (3x3 matrix subtraction with 3x3 matrix) */
-DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- sub_v3_v3v3(to[0], matrixA[0], matrixB[0]);
- sub_v3_v3v3(to[1], matrixA[1], matrixB[1]);
- sub_v3_v3v3(to[2], matrixA[2], matrixB[2]);
-}
-/* A += B - C (3x3 matrix add-subtraction with 3x3 matrix) */
-DO_INLINE void addsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- VECADDSUB(to[0], matrixA[0], matrixB[0]);
- VECADDSUB(to[1], matrixA[1], matrixB[1]);
- VECADDSUB(to[2], matrixA[2], matrixB[2]);
-}
-/////////////////////////////////////////////////////////////////
-// special functions
-/////////////////////////////////////////////////////////////////
-/* a vector multiplied and added to/by a 3x3 matrix */
-DO_INLINE void muladd_fvector_fmatrix(float to[3], float from[3], float matrix[3][3])
-{
- to[0] += matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
- to[1] += matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
- to[2] += matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
-}
-/* 3x3 matrix multiplied and added to/by a 3x3 matrix and added to another 3x3 matrix */
-DO_INLINE void muladd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- muladd_fvector_fmatrix(to[0], matrixA[0], matrixB);
- muladd_fvector_fmatrix(to[1], matrixA[1], matrixB);
- muladd_fvector_fmatrix(to[2], matrixA[2], matrixB);
-}
-/* a vector multiplied and sub'd to/by a 3x3 matrix */
-DO_INLINE void mulsub_fvector_fmatrix(float to[3], float from[3], float matrix[3][3])
-{
- to[0] -= matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
- to[1] -= matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
- to[2] -= matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
-}
-/* 3x3 matrix multiplied and sub'd to/by a 3x3 matrix and added to another 3x3 matrix */
-DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- mulsub_fvector_fmatrix(to[0], matrixA[0], matrixB);
- mulsub_fvector_fmatrix(to[1], matrixA[1], matrixB);
- mulsub_fvector_fmatrix(to[2], matrixA[2], matrixB);
-}
-/* 3x3 matrix multiplied+added by a vector */
-/* STATUS: verified */
-DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3])
-{
- to[0] += dot_v3v3(matrix[0], from);
- to[1] += dot_v3v3(matrix[1], from);
- to[2] += dot_v3v3(matrix[2], from);
-}
-/* 3x3 matrix multiplied+sub'ed by a vector */
-DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float from[3])
-{
- to[0] -= dot_v3v3(matrix[0], from);
- to[1] -= dot_v3v3(matrix[1], from);
- to[2] -= dot_v3v3(matrix[2], from);
-}
-/////////////////////////////////////////////////////////////////
-
-///////////////////////////
-// SPARSE SYMMETRIC big matrix with 3x3 matrix entries
-///////////////////////////
-/* printf a big matrix on console: for debug output */
-#if 0
-static void print_bfmatrix(fmatrix3x3 *m3)
-{
- unsigned int i = 0;
-
- for (i = 0; i < m3[0].vcount + m3[0].scount; i++)
- {
- print_fmatrix(m3[i].m);
- }
-}
-#endif
-
-/* create big matrix */
-DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
-{
- // TODO: check if memory allocation was successful */
- fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN(sizeof(fmatrix3x3) * (verts + springs), "cloth_implicit_alloc_matrix");
- temp[0].vcount = verts;
- temp[0].scount = springs;
- return temp;
-}
-/* delete big matrix */
-DO_INLINE void del_bfmatrix(fmatrix3x3 *matrix)
-{
- if (matrix != NULL) {
- MEM_freeN(matrix);
- }
-}
-
-/* copy big matrix */
-DO_INLINE void cp_bfmatrix(fmatrix3x3 *to, fmatrix3x3 *from)
-{
- // TODO bounds checking
- memcpy(to, from, sizeof(fmatrix3x3) * (from[0].vcount+from[0].scount));
-}
-
-/* init big matrix */
-// slow in parallel
-DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
-{
- unsigned int i;
-
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- cp_fmatrix(matrix[i].m, m3);
- }
-}
-
-/* init the diagonal of big matrix */
-// slow in parallel
-DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
-{
- unsigned int i, j;
- float tmatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
-
- for (i = 0; i < matrix[0].vcount; i++) {
- cp_fmatrix(matrix[i].m, m3);
- }
- for (j = matrix[0].vcount; j < matrix[0].vcount+matrix[0].scount; j++) {
- cp_fmatrix(matrix[j].m, tmatrix);
- }
-}
-
-/* multiply big matrix with scalar*/
-DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar)
-{
- unsigned int i = 0;
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- mul_fmatrix_S(matrix[i].m, scalar);
- }
-}
-
-/* SPARSE SYMMETRIC multiply big matrix with long vector*/
-/* STATUS: verified */
-DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
-{
- unsigned int i = 0;
- unsigned int vcount = from[0].vcount;
- lfVector *temp = create_lfvector(vcount);
-
- zero_lfvector(to, vcount);
-
-#pragma omp parallel sections private(i) if (vcount > CLOTH_OPENMP_LIMIT)
- {
-#pragma omp section
- {
- for (i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) {
- muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
- }
- }
-#pragma omp section
- {
- for (i = 0; i < from[0].vcount+from[0].scount; i++) {
- muladd_fmatrix_fvector(temp[from[i].r], from[i].m, fLongVector[from[i].c]);
- }
- }
- }
- add_lfvector_lfvector(to, to, temp, from[0].vcount);
-
- del_lfvector(temp);
-
-
-}
-
-/* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */
-/* STATUS: verified */
-DO_INLINE void mul_prevfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
-{
- unsigned int i = 0;
-
- for (i = 0; i < from[0].vcount; i++) {
- mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]);
- }
-}
-
-/* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/
-DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- add_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
- }
-
-}
-/* SPARSE SYMMETRIC add big matrix with big matrix: A += B + C */
-DO_INLINE void addadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- addadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
- }
-
-}
-/* SPARSE SYMMETRIC subadd big matrix with big matrix: A -= B + C */
-DO_INLINE void subadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- subadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
- }
-
-}
-/* A = B - C (SPARSE SYMMETRIC sub big matrix with big matrix) */
-DO_INLINE void sub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- sub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
- }
-
-}
-/* SPARSE SYMMETRIC sub big matrix with big matrix S (special constraint matrix with limited entries) */
-DO_INLINE void sub_bfmatrix_Smatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount; i++) {
- sub_fmatrix_fmatrix(to[matrix[i].c].m, from[matrix[i].c].m, matrix[i].m);
- }
-
-}
-/* A += B - C (SPARSE SYMMETRIC addsub big matrix with big matrix) */
-DO_INLINE void addsub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- addsub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
- }
-
-}
-/* SPARSE SYMMETRIC sub big matrix with big matrix*/
-/* A -= B * float + C * float --> for big matrix */
-/* VERIFIED */
-DO_INLINE void subadd_bfmatrixS_bfmatrixS( fmatrix3x3 *to, fmatrix3x3 *from, float aS, fmatrix3x3 *matrix, float bS)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- subadd_fmatrixS_fmatrixS(to[i].m, from[i].m, aS, matrix[i].m, bS);
- }
-
-}
-
-///////////////////////////////////////////////////////////////////
-// simulator start
-///////////////////////////////////////////////////////////////////
-typedef struct Implicit_Data {
- lfVector *X, *V, *Xnew, *Vnew, *olddV, *F, *B, *dV, *z;
- fmatrix3x3 *A, *dFdV, *dFdX, *S, *P, *Pinv, *bigI, *M;
-} Implicit_Data;
-
-/* Init constraint matrix */
-static void update_matrixS(ClothVertex *verts, int numverts, fmatrix3x3 *S)
-{
- unsigned int pinned = 0;
- int i = 0;
-
- /* Clear matrix from old vertex constraints */
- for (i = 0; i < S[0].vcount; i++)
- S[i].c = S[i].r = 0;
-
- /* Set new vertex constraints */
- for (i = 0; i < numverts; i++) {
- if (verts [i].flags & CLOTH_VERT_FLAG_PINNED) {
- S[pinned].c = S[pinned].r = i;
- pinned++;
- }
- }
-
- // S is special and needs specific vcount and scount
- S[0].vcount = pinned;
- S[0].scount = 0;
-}
-
-int implicit_init(Object *UNUSED(ob), ClothModifierData *clmd)
-{
- unsigned int i = 0;
- Cloth *cloth = NULL;
- ClothVertex *verts = NULL;
- ClothSpring *spring = NULL;
- Implicit_Data *id = NULL;
- LinkNode *search = NULL;
-
- if (G.debug_value > 0)
- printf("implicit_init\n");
-
- // init memory guard
- // BLI_listbase_clear(&MEMORY_BASE);
-
- cloth = (Cloth *)clmd->clothObject;
- verts = cloth->verts;
-
- // create implicit base
- id = (Implicit_Data *)MEM_callocN(sizeof(Implicit_Data), "implicit vecmat");
- cloth->implicit = id;
-
- /* process diagonal elements */
- id->A = create_bfmatrix(cloth->numverts, cloth->numsprings);
- id->dFdV = create_bfmatrix(cloth->numverts, cloth->numsprings);
- id->dFdX = create_bfmatrix(cloth->numverts, cloth->numsprings);
- id->S = create_bfmatrix(cloth->numverts, 0);
- id->Pinv = create_bfmatrix(cloth->numverts, cloth->numsprings);
- id->P = create_bfmatrix(cloth->numverts, cloth->numsprings);
- id->bigI = create_bfmatrix(cloth->numverts, cloth->numsprings); // TODO 0 springs
- id->M = create_bfmatrix(cloth->numverts, cloth->numsprings);
- id->X = create_lfvector(cloth->numverts);
- id->Xnew = create_lfvector(cloth->numverts);
- id->V = create_lfvector(cloth->numverts);
- id->Vnew = create_lfvector(cloth->numverts);
- id->olddV = create_lfvector(cloth->numverts);
- zero_lfvector(id->olddV, cloth->numverts);
- id->F = create_lfvector(cloth->numverts);
- id->B = create_lfvector(cloth->numverts);
- id->dV = create_lfvector(cloth->numverts);
- id->z = create_lfvector(cloth->numverts);
-
- id->S[0].vcount = 0;
- update_matrixS(verts, cloth->numverts, id->S);
-
- for (i = 0; i < cloth->numverts; i++) {
- id->A[i].r = id->A[i].c = id->dFdV[i].r = id->dFdV[i].c = id->dFdX[i].r = id->dFdX[i].c = id->P[i].c = id->P[i].r = id->Pinv[i].c = id->Pinv[i].r = id->bigI[i].c = id->bigI[i].r = id->M[i].r = id->M[i].c = i;
-
- initdiag_fmatrixS(id->M[i].m, verts[i].mass);
- }
-
- // init springs
- search = cloth->springs;
- for (i = 0; i < cloth->numsprings; i++) {
- spring = search->link;
-
- // dFdV_start[i].r = big_I[i].r = big_zero[i].r =
- id->A[i+cloth->numverts].r = id->dFdV[i+cloth->numverts].r = id->dFdX[i+cloth->numverts].r =
- id->P[i+cloth->numverts].r = id->Pinv[i+cloth->numverts].r = id->bigI[i+cloth->numverts].r = id->M[i+cloth->numverts].r = spring->ij;
-
- // dFdV_start[i].c = big_I[i].c = big_zero[i].c =
- id->A[i+cloth->numverts].c = id->dFdV[i+cloth->numverts].c = id->dFdX[i+cloth->numverts].c =
- id->P[i+cloth->numverts].c = id->Pinv[i+cloth->numverts].c = id->bigI[i+cloth->numverts].c = id->M[i+cloth->numverts].c = spring->kl;
-
- spring->matrix_index = i + cloth->numverts;
-
- search = search->next;
- }
-
- initdiag_bfmatrix(id->bigI, I);
-
- for (i = 0; i < cloth->numverts; i++) {
- copy_v3_v3(id->X[i], verts[i].x);
- }
-
- return 1;
-}
-
-int implicit_free(ClothModifierData *clmd)
-{
- Implicit_Data *id;
- Cloth *cloth;
- cloth = (Cloth *)clmd->clothObject;
-
- if (cloth) {
- id = cloth->implicit;
-
- if (id) {
- del_bfmatrix(id->A);
- del_bfmatrix(id->dFdV);
- del_bfmatrix(id->dFdX);
- del_bfmatrix(id->S);
- del_bfmatrix(id->P);
- del_bfmatrix(id->Pinv);
- del_bfmatrix(id->bigI);
- del_bfmatrix(id->M);
-
- del_lfvector(id->X);
- del_lfvector(id->Xnew);
- del_lfvector(id->V);
- del_lfvector(id->Vnew);
- del_lfvector(id->olddV);
- del_lfvector(id->F);
- del_lfvector(id->B);
- del_lfvector(id->dV);
- del_lfvector(id->z);
-
- MEM_freeN(id);
- }
- }
-
- return 1;
-}
-
-DO_INLINE float fb(float length, float L)
-{
- float x = length / L;
- return (-11.541f * powf(x, 4) + 34.193f * powf(x, 3) - 39.083f * powf(x, 2) + 23.116f * x - 9.713f);
-}
-
-DO_INLINE float fbderiv(float length, float L)
-{
- float x = length/L;
-
- return (-46.164f * powf(x, 3) + 102.579f * powf(x, 2) - 78.166f * x + 23.116f);
-}
-
-DO_INLINE float fbstar(float length, float L, float kb, float cb)
-{
- float tempfb_fl = kb * fb(length, L);
- float fbstar_fl = cb * (length - L);
-
- if (tempfb_fl < fbstar_fl)
- return fbstar_fl;
- else
- return tempfb_fl;
-}
-
-// function to calculae bending spring force (taken from Choi & Co)
-DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
-{
- float tempfb_fl = kb * fb(length, L);
- float fbstar_fl = cb * (length - L);
-
- if (tempfb_fl < fbstar_fl) {
- return cb;
- }
- else {
- return kb * fbderiv(length, L);
- }
-}
-
-DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
-{
- unsigned int i=0;
-
- for (i = 0; i < S[0].vcount; i++) {
- mul_fvector_fmatrix(V[S[i].r], V[S[i].r], S[i].m);
- }
-}
-
-static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
-{
- // Solves for unknown X in equation AX=B
- unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100;
- float conjgrad_epsilon=0.0001f /* , conjgrad_lasterror=0 */ /* UNUSED */;
- lfVector *q, *d, *tmp, *r;
- float s, starget, a, s_prev;
- unsigned int numverts = lA[0].vcount;
- q = create_lfvector(numverts);
- d = create_lfvector(numverts);
- tmp = create_lfvector(numverts);
- r = create_lfvector(numverts);
-
- // zero_lfvector(ldV, CLOTHPARTICLES);
- filter(ldV, S);
-
- add_lfvector_lfvector(ldV, ldV, z, numverts);
-
- // r = B - Mul(tmp, A, X); // just use B if X known to be zero
- cp_lfvector(r, lB, numverts);
- mul_bfmatrix_lfvector(tmp, lA, ldV);
- sub_lfvector_lfvector(r, r, tmp, numverts);
-
- filter(r, S);
-
- cp_lfvector(d, r, numverts);
-
- s = dot_lfvector(r, r, numverts);
- starget = s * sqrtf(conjgrad_epsilon);
-
- while (s>starget && conjgrad_loopcount < conjgrad_looplimit) {
- // Mul(q, A, d); // q = A*d;
- mul_bfmatrix_lfvector(q, lA, d);
-
- filter(q, S);
-
- a = s/dot_lfvector(d, q, numverts);
-
- // X = X + d*a;
- add_lfvector_lfvectorS(ldV, ldV, d, a, numverts);
-
- // r = r - q*a;
- sub_lfvector_lfvectorS(r, r, q, a, numverts);
-
- s_prev = s;
- s = dot_lfvector(r, r, numverts);
-
- //d = r+d*(s/s_prev);
- add_lfvector_lfvectorS(d, r, d, (s/s_prev), numverts);
-
- filter(d, S);
-
- conjgrad_loopcount++;
- }
- /* conjgrad_lasterror = s; */ /* UNUSED */
-
- del_lfvector(q);
- del_lfvector(d);
- del_lfvector(tmp);
- del_lfvector(r);
- // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount);
-
- return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
-}
-
-// block diagonalizer
-DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
-{
- unsigned int i = 0;
-
- // Take only the diagonal blocks of A
-// #pragma omp parallel for private(i) if (lA[0].vcount > CLOTH_OPENMP_LIMIT)
- for (i = 0; i<lA[0].vcount; i++) {
- // block diagonalizer
- cp_fmatrix(P[i].m, lA[i].m);
- inverse_fmatrix(Pinv[i].m, P[i].m);
-
- }
-}
-#if 0
-/*
-// version 1.3
-static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv)
-{
- unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100;
- float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0;
- float conjgrad_epsilon=0.0001; // 0.2 is dt for steps=5
- lfVector *r = create_lfvector(numverts);
- lfVector *p = create_lfvector(numverts);
- lfVector *s = create_lfvector(numverts);
- lfVector *h = create_lfvector(numverts);
-
- BuildPPinv(lA, P, Pinv);
-
- filter(dv, S);
- add_lfvector_lfvector(dv, dv, z, numverts);
-
- mul_bfmatrix_lfvector(r, lA, dv);
- sub_lfvector_lfvector(r, lB, r, numverts);
- filter(r, S);
-
- mul_prevfmatrix_lfvector(p, Pinv, r);
- filter(p, S);
-
- deltaNew = dot_lfvector(r, p, numverts);
-
- delta0 = deltaNew * sqrt(conjgrad_epsilon);
-
- // itstart();
-
- while ((deltaNew > delta0) && (iterations < conjgrad_looplimit))
- {
- iterations++;
-
- mul_bfmatrix_lfvector(s, lA, p);
- filter(s, S);
-
- alpha = deltaNew / dot_lfvector(p, s, numverts);
-
- add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
-
- add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
-
- mul_prevfmatrix_lfvector(h, Pinv, r);
- filter(h, S);
-
- deltaOld = deltaNew;
-
- deltaNew = dot_lfvector(r, h, numverts);
-
- add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
-
- filter(p, S);
-
- }
-
- // itend();
- // printf("cg_filtered_pre time: %f\n", (float)itval());
-
- del_lfvector(h);
- del_lfvector(s);
- del_lfvector(p);
- del_lfvector(r);
-
- printf("iterations: %d\n", iterations);
-
- return iterations<conjgrad_looplimit;
-}
-*/
-// version 1.4
-static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *bigI)
-{
- unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100;
- float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0, tol = 0;
- lfVector *r = create_lfvector(numverts);
- lfVector *p = create_lfvector(numverts);
- lfVector *s = create_lfvector(numverts);
- lfVector *h = create_lfvector(numverts);
- lfVector *bhat = create_lfvector(numverts);
- lfVector *btemp = create_lfvector(numverts);
-
- BuildPPinv(lA, P, Pinv);
-
- initdiag_bfmatrix(bigI, I);
- sub_bfmatrix_Smatrix(bigI, bigI, S);
-
- // x = Sx_0+(I-S)z
- filter(dv, S);
- add_lfvector_lfvector(dv, dv, z, numverts);
-
- // b_hat = S(b-A(I-S)z)
- mul_bfmatrix_lfvector(r, lA, z);
- mul_bfmatrix_lfvector(bhat, bigI, r);
- sub_lfvector_lfvector(bhat, lB, bhat, numverts);
-
- // r = S(b-Ax)
- mul_bfmatrix_lfvector(r, lA, dv);
- sub_lfvector_lfvector(r, lB, r, numverts);
- filter(r, S);
-
- // p = SP^-1r
- mul_prevfmatrix_lfvector(p, Pinv, r);
- filter(p, S);
-
- // delta0 = bhat^TP^-1bhat
- mul_prevfmatrix_lfvector(btemp, Pinv, bhat);
- delta0 = dot_lfvector(bhat, btemp, numverts);
-
- // deltaNew = r^TP
- deltaNew = dot_lfvector(r, p, numverts);
-
- /*
- filter(dv, S);
- add_lfvector_lfvector(dv, dv, z, numverts);
-
- mul_bfmatrix_lfvector(r, lA, dv);
- sub_lfvector_lfvector(r, lB, r, numverts);
- filter(r, S);
-
- mul_prevfmatrix_lfvector(p, Pinv, r);
- filter(p, S);
-
- deltaNew = dot_lfvector(r, p, numverts);
-
- delta0 = deltaNew * sqrt(conjgrad_epsilon);
- */
-
- // itstart();
-
- tol = (0.01*0.2);
-
- while ((deltaNew > delta0*tol*tol) && (iterations < conjgrad_looplimit))
- {
- iterations++;
-
- mul_bfmatrix_lfvector(s, lA, p);
- filter(s, S);
-
- alpha = deltaNew / dot_lfvector(p, s, numverts);
-
- add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
-
- add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
-
- mul_prevfmatrix_lfvector(h, Pinv, r);
- filter(h, S);
-
- deltaOld = deltaNew;
-
- deltaNew = dot_lfvector(r, h, numverts);
-
- add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
-
- filter(p, S);
-
- }
-
- // itend();
- // printf("cg_filtered_pre time: %f\n", (float)itval());
-
- del_lfvector(btemp);
- del_lfvector(bhat);
- del_lfvector(h);
- del_lfvector(s);
- del_lfvector(p);
- del_lfvector(r);
-
- // printf("iterations: %d\n", iterations);
-
- return iterations<conjgrad_looplimit;
-}
-#endif
-
-// outer product is NOT cross product!!!
-DO_INLINE void dfdx_spring_type1(float to[3][3], float extent[3], float length, float L, float dot, float k)
-{
- // dir is unit length direction, rest is spring's restlength, k is spring constant.
- // return (outerprod(dir, dir)*k + (I - outerprod(dir, dir))*(k - ((k*L)/length)));
- float temp[3][3];
- float temp1 = k * (1.0f - (L / length));
-
- mul_fvectorT_fvectorS(temp, extent, extent, 1.0f / dot);
- sub_fmatrix_fmatrix(to, I, temp);
- mul_fmatrix_S(to, temp1);
-
- mul_fvectorT_fvectorS(temp, extent, extent, k/ dot);
- add_fmatrix_fmatrix(to, to, temp);
-
- /*
- mul_fvectorT_fvector(temp, dir, dir);
- sub_fmatrix_fmatrix(to, I, temp);
- mul_fmatrix_S(to, k* (1.0f-(L/length)));
- mul_fmatrix_S(temp, k);
- add_fmatrix_fmatrix(to, temp, to);
- */
-}
-
-DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3], float length, float L, float k, float cb)
-{
- // return outerprod(dir, dir)*fbstar_jacobi(length, L, k, cb);
- mul_fvectorT_fvectorS(to, dir, dir, fbstar_jacobi(length, L, k, cb));
-}
-
-DO_INLINE void dfdv_damp(float to[3][3], float dir[3], float damping)
-{
- // derivative of force wrt velocity.
- mul_fvectorT_fvectorS(to, dir, dir, damping);
-
-}
-
-DO_INLINE void dfdx_spring(float to[3][3], float dir[3], float length, float L, float k)
-{
- // dir is unit length direction, rest is spring's restlength, k is spring constant.
- //return ( (I-outerprod(dir, dir))*Min(1.0f, rest/length) - I) * -k;
- mul_fvectorT_fvector(to, dir, dir);
- sub_fmatrix_fmatrix(to, I, to);
-
- mul_fmatrix_S(to, (L/length));
- sub_fmatrix_fmatrix(to, to, I);
- mul_fmatrix_S(to, -k);
-}
-
-// unused atm
-DO_INLINE void dfdx_damp(float to[3][3], float dir[3], float length, const float vel[3], float rest, float damping)
-{
- // inner spring damping vel is the relative velocity of the endpoints.
- // return (I-outerprod(dir, dir)) * (-damping * -(dot(dir, vel)/Max(length, rest)));
- mul_fvectorT_fvector(to, dir, dir);
- sub_fmatrix_fmatrix(to, I, to);
- mul_fmatrix_S(to, (-damping * -(dot_v3v3(dir, vel)/MAX2(length, rest))));
-
-}
-
-DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *UNUSED(lF), lfVector *X, lfVector *V, fmatrix3x3 *UNUSED(dFdV), fmatrix3x3 *UNUSED(dFdX), float time)
-{
- Cloth *cloth = clmd->clothObject;
- ClothVertex *verts = cloth->verts;
- float extent[3];
- float length = 0, dot = 0;
- float dir[3] = {0, 0, 0};
- float vel[3];
- float k = 0.0f;
- float L = s->restlen;
- float cb; /* = clmd->sim_parms->structural; */ /*UNUSED*/
-
- float nullf[3] = {0, 0, 0};
- float stretch_force[3] = {0, 0, 0};
- float bending_force[3] = {0, 0, 0};
- float damping_force[3] = {0, 0, 0};
- float nulldfdx[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
-
- float scaling = 0.0;
-
- int no_compress = clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
-
- copy_v3_v3(s->f, nullf);
- cp_fmatrix(s->dfdx, nulldfdx);
- cp_fmatrix(s->dfdv, nulldfdx);
-
- // calculate elonglation
- sub_v3_v3v3(extent, X[s->kl], X[s->ij]);
- sub_v3_v3v3(vel, V[s->kl], V[s->ij]);
- dot = dot_v3v3(extent, extent);
- length = sqrtf(dot);
-
- s->flags &= ~CLOTH_SPRING_FLAG_NEEDED;
-
- if (length > ALMOST_ZERO) {
- /*
- if (length>L)
- {
- if ((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) &&
- ((((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen))) // cut spring!
- {
- s->flags |= CSPRING_FLAG_DEACTIVATE;
- return;
- }
- }
- */
- mul_fvector_S(dir, extent, 1.0f/length);
- }
- else {
- mul_fvector_S(dir, extent, 0.0f);
- }
-
- // calculate force of structural + shear springs
- if ((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR) || (s->type & CLOTH_SPRING_TYPE_SEWING) ) {
- if (length > L || no_compress) {
- s->flags |= CLOTH_SPRING_FLAG_NEEDED;
-
- k = clmd->sim_parms->structural;
-
- scaling = k + s->stiffness * fabsf(clmd->sim_parms->max_struct - k);
-
- k = scaling / (clmd->sim_parms->avg_spring_len + FLT_EPSILON);
-
- // TODO: verify, half verified (couldn't see error)
- if (s->type & CLOTH_SPRING_TYPE_SEWING) {
- // sewing springs usually have a large distance at first so clamp the force so we don't get tunnelling through colission objects
- float force = k*(length-L);
- if (force > clmd->sim_parms->max_sewing) {
- force = clmd->sim_parms->max_sewing;
- }
- mul_fvector_S(stretch_force, dir, force);
- }
- else {
- mul_fvector_S(stretch_force, dir, k * (length - L));
- }
-
- VECADD(s->f, s->f, stretch_force);
-
- // Ascher & Boxman, p.21: Damping only during elonglation
- // something wrong with it...
- mul_fvector_S(damping_force, dir, clmd->sim_parms->Cdis * dot_v3v3(vel, dir));
- VECADD(s->f, s->f, damping_force);
-
- /* VERIFIED */
- dfdx_spring(s->dfdx, dir, length, L, k);
-
- /* VERIFIED */
- dfdv_damp(s->dfdv, dir, clmd->sim_parms->Cdis);
-
- }
- }
- else if (s->type & CLOTH_SPRING_TYPE_GOAL) {
- float tvect[3];
-
- s->flags |= CLOTH_SPRING_FLAG_NEEDED;
-
- // current_position = xold + t * (newposition - xold)
- sub_v3_v3v3(tvect, verts[s->ij].xconst, verts[s->ij].xold);
- mul_fvector_S(tvect, tvect, time);
- VECADD(tvect, tvect, verts[s->ij].xold);
-
- sub_v3_v3v3(extent, X[s->ij], tvect);
-
- // SEE MSG BELOW (these are UNUSED)
- // dot = dot_v3v3(extent, extent);
- // length = sqrt(dot);
-
- k = clmd->sim_parms->goalspring;
-
- scaling = k + s->stiffness * fabsf(clmd->sim_parms->max_struct - k);
-
- k = verts [s->ij].goal * scaling / (clmd->sim_parms->avg_spring_len + FLT_EPSILON);
-
- VECADDS(s->f, s->f, extent, -k);
-
- mul_fvector_S(damping_force, dir, clmd->sim_parms->goalfrict * 0.01f * dot_v3v3(vel, dir));
- VECADD(s->f, s->f, damping_force);
-
- // HERE IS THE PROBLEM!!!!
- // dfdx_spring(s->dfdx, dir, length, 0.0, k);
- // dfdv_damp(s->dfdv, dir, MIN2(1.0, (clmd->sim_parms->goalfrict/100.0)));
- }
- else { /* calculate force of bending springs */
- if (length < L) {
- s->flags |= CLOTH_SPRING_FLAG_NEEDED;
-
- k = clmd->sim_parms->bending;
-
- scaling = k + s->stiffness * fabsf(clmd->sim_parms->max_bend - k);
- cb = k = scaling / (20.0f * (clmd->sim_parms->avg_spring_len + FLT_EPSILON));
-
- mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb));
- VECADD(s->f, s->f, bending_force);
-
- dfdx_spring_type2(s->dfdx, dir, length, L, k, cb);
- }
- }
-}
-
-DO_INLINE void cloth_apply_spring_force(ClothModifierData *UNUSED(clmd), ClothSpring *s, lfVector *lF, lfVector *UNUSED(X), lfVector *UNUSED(V), fmatrix3x3 *dFdV, fmatrix3x3 *dFdX)
-{
- if (s->flags & CLOTH_SPRING_FLAG_NEEDED) {
- if (!(s->type & CLOTH_SPRING_TYPE_BENDING)) {
- sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv);
- sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv);
- add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv);
- }
-
- VECADD(lF[s->ij], lF[s->ij], s->f);
-
- if (!(s->type & CLOTH_SPRING_TYPE_GOAL))
- sub_v3_v3v3(lF[s->kl], lF[s->kl], s->f);
-
- sub_fmatrix_fmatrix(dFdX[s->kl].m, dFdX[s->kl].m, s->dfdx);
- sub_fmatrix_fmatrix(dFdX[s->ij].m, dFdX[s->ij].m, s->dfdx);
- add_fmatrix_fmatrix(dFdX[s->matrix_index].m, dFdX[s->matrix_index].m, s->dfdx);
- }
-}
-
-
-static void CalcFloat( float *v1, float *v2, float *v3, float *n)
-{
- float n1[3], n2[3];
-
- n1[0] = v1[0]-v2[0];
- n2[0] = v2[0]-v3[0];
- n1[1] = v1[1]-v2[1];
- n2[1] = v2[1]-v3[1];
- n1[2] = v1[2]-v2[2];
- n2[2] = v2[2]-v3[2];
- n[0] = n1[1]*n2[2]-n1[2]*n2[1];
- n[1] = n1[2]*n2[0]-n1[0]*n2[2];
- n[2] = n1[0]*n2[1]-n1[1]*n2[0];
-}
-
-static void CalcFloat4( float *v1, float *v2, float *v3, float *v4, float *n)
-{
- /* real cross! */
- float n1[3], n2[3];
-
- n1[0] = v1[0]-v3[0];
- n1[1] = v1[1]-v3[1];
- n1[2] = v1[2]-v3[2];
-
- n2[0] = v2[0]-v4[0];
- n2[1] = v2[1]-v4[1];
- n2[2] = v2[2]-v4[2];
-
- n[0] = n1[1]*n2[2]-n1[2]*n2[1];
- n[1] = n1[2]*n2[0]-n1[0]*n2[2];
- n[2] = n1[0]*n2[1]-n1[1]*n2[0];
-}
-
-static float calculateVertexWindForce(const float wind[3], const float vertexnormal[3])
-{
- return dot_v3v3(wind, vertexnormal);
-}
-
-typedef struct HairGridVert {
- float velocity[3];
- float density;
-} HairGridVert;
-#define HAIR_GRID_INDEX(vec, min, max, axis) (int)((vec[axis] - min[axis]) / (max[axis] - min[axis]) * 9.99f)
-/* Smoothing of hair velocities:
- * adapted from
- * Volumetric Methods for Simulation and Rendering of Hair
- * by Lena Petrovic, Mark Henne and John Anderson
- * Pixar Technical Memo #06-08, Pixar Animation Studios
- */
-static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, unsigned int numverts)
-{
- /* TODO: This is an initial implementation and should be made much better in due time.
- * What should at least be implemented is a grid size parameter and a smoothing kernel
- * for bigger grids.
- */
-
- /* 10x10x10 grid gives nice initial results */
- HairGridVert grid[10][10][10];
- HairGridVert colg[10][10][10];
- ListBase *colliders = get_collider_cache(clmd->scene, NULL, NULL);
- ColliderCache *col = NULL;
- float gmin[3], gmax[3], density;
- /* 2.0f is an experimental value that seems to give good results */
- float smoothfac = 2.0f * clmd->sim_parms->velocity_smooth;
- float collfac = 2.0f * clmd->sim_parms->collider_friction;
- unsigned int v = 0;
- int i = 0;
- int j = 0;
- int k = 0;
-
- INIT_MINMAX(gmin, gmax);
-
- for (i = 0; i < numverts; i++)
- DO_MINMAX(lX[i], gmin, gmax);
-
- /* initialize grid */
- for (i = 0; i < 10; i++) {
- for (j = 0; j < 10; j++) {
- for (k = 0; k < 10; k++) {
- grid[i][j][k].velocity[0] = 0.0f;
- grid[i][j][k].velocity[1] = 0.0f;
- grid[i][j][k].velocity[2] = 0.0f;
- grid[i][j][k].density = 0.0f;
-
- colg[i][j][k].velocity[0] = 0.0f;
- colg[i][j][k].velocity[1] = 0.0f;
- colg[i][j][k].velocity[2] = 0.0f;
- colg[i][j][k].density = 0.0f;
- }
- }
- }
-
- /* gather velocities & density */
- if (smoothfac > 0.0f) for (v = 0; v < numverts; v++) {
- i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
- j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
- k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
- if (i < 0 || j < 0 || k < 0 || i >= 10 || j >= 10 || k >= 10)
- continue;
-
- grid[i][j][k].velocity[0] += lV[v][0];
- grid[i][j][k].velocity[1] += lV[v][1];
- grid[i][j][k].velocity[2] += lV[v][2];
- grid[i][j][k].density += 1.0f;
- }
-
- /* gather colliders */
- if (colliders && collfac > 0.0f) for (col = colliders->first; col; col = col->next) {
- MVert *loc0 = col->collmd->x;
- MVert *loc1 = col->collmd->xnew;
- float vel[3];
-
- for (v=0; v<col->collmd->numverts; v++, loc0++, loc1++) {
- i = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 0);
-
- if (i>=0 && i<10) {
- j = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 1);
-
- if (j>=0 && j<10) {
- k = HAIR_GRID_INDEX(loc1->co, gmin, gmax, 2);
-
- if (k>=0 && k<10) {
- sub_v3_v3v3(vel, loc1->co, loc0->co);
-
- colg[i][j][k].velocity[0] += vel[0];
- colg[i][j][k].velocity[1] += vel[1];
- colg[i][j][k].velocity[2] += vel[2];
- colg[i][j][k].density += 1.0f;
- }
- }
- }
- }
- }
-
-
- /* divide velocity with density */
- for (i = 0; i < 10; i++) {
- for (j = 0; j < 10; j++) {
- for (k = 0; k < 10; k++) {
- density = grid[i][j][k].density;
- if (density > 0.0f) {
- grid[i][j][k].velocity[0] /= density;
- grid[i][j][k].velocity[1] /= density;
- grid[i][j][k].velocity[2] /= density;
- }
-
- density = colg[i][j][k].density;
- if (density > 0.0f) {
- colg[i][j][k].velocity[0] /= density;
- colg[i][j][k].velocity[1] /= density;
- colg[i][j][k].velocity[2] /= density;
- }
- }
- }
- }
-
- /* calculate forces */
- for (v = 0; v < numverts; v++) {
- i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
- j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
- k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
- if (i < 0 || j < 0 || k < 0 || i >= 10 || j >= 10 || k >= 10)
- continue;
-
- lF[v][0] += smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]);
- lF[v][1] += smoothfac * (grid[i][j][k].velocity[1] - lV[v][1]);
- lF[v][2] += smoothfac * (grid[i][j][k].velocity[2] - lV[v][2]);
-
- if (colg[i][j][k].density > 0.0f) {
- lF[v][0] += collfac * (colg[i][j][k].velocity[0] - lV[v][0]);
- lF[v][1] += collfac * (colg[i][j][k].velocity[1] - lV[v][1]);
- lF[v][2] += collfac * (colg[i][j][k].velocity[2] - lV[v][2]);
- }
- }
-
- free_collider_cache(&colliders);
-}
-
-static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
-{
- /* Collect forces and derivatives: F, dFdX, dFdV */
- Cloth *cloth = clmd->clothObject;
- unsigned int i = 0;
- float spring_air = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
- float gravity[3] = {0.0f, 0.0f, 0.0f};
- float tm2[3][3] = {{0}};
- MFace *mfaces = cloth->mfaces;
- unsigned int numverts = cloth->numverts;
- LinkNode *search;
- lfVector *winvec;
- EffectedPoint epoint;
-
- tm2[0][0] = tm2[1][1] = tm2[2][2] = -spring_air;
-
- /* global acceleration (gravitation) */
- if (clmd->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
- copy_v3_v3(gravity, clmd->scene->physics_settings.gravity);
- mul_fvector_S(gravity, gravity, 0.001f * clmd->sim_parms->effector_weights->global_gravity); /* scale gravity force */
- }
-
- /* set dFdX jacobi matrix to zero */
- init_bfmatrix(dFdX, ZERO);
- /* set dFdX jacobi matrix diagonal entries to -spring_air */
- initdiag_bfmatrix(dFdV, tm2);
-
- init_lfvector(lF, gravity, numverts);
-
- if (clmd->sim_parms->velocity_smooth > 0.0f || clmd->sim_parms->collider_friction > 0.0f)
- hair_velocity_smoothing(clmd, lF, lX, lV, numverts);
-
- /* multiply lF with mass matrix
- * force = mass * acceleration (in this case: gravity)
- */
- for (i = 0; i < numverts; i++) {
- float temp[3];
- copy_v3_v3(temp, lF[i]);
- mul_fmatrix_fvector(lF[i], M[i].m, temp);
- }
-
- submul_lfvectorS(lF, lV, spring_air, numverts);
-
- /* handle external forces like wind */
- if (effectors) {
- // 0 = force, 1 = normalized force
- winvec = create_lfvector(cloth->numverts);
-
- if (!winvec)
- printf("winvec: out of memory in implicit.c\n");
-
- // precalculate wind forces
- for (i = 0; i < cloth->numverts; i++) {
- pd_point_from_loc(clmd->scene, (float*)lX[i], (float*)lV[i], i, &epoint);
- pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL);
- }
-
- for (i = 0; i < cloth->numfaces; i++) {
- float trinormal[3] = {0, 0, 0}; // normalized triangle normal
- float triunnormal[3] = {0, 0, 0}; // not-normalized-triangle normal
- float tmp[3] = {0, 0, 0};
- float factor = (mfaces[i].v4) ? 0.25 : 1.0 / 3.0;
- factor *= 0.02f;
-
- // calculate face normal
- if (mfaces[i].v4)
- CalcFloat4(lX[mfaces[i].v1], lX[mfaces[i].v2], lX[mfaces[i].v3], lX[mfaces[i].v4], triunnormal);
- else
- CalcFloat(lX[mfaces[i].v1], lX[mfaces[i].v2], lX[mfaces[i].v3], triunnormal);
-
- normalize_v3_v3(trinormal, triunnormal);
-
- // add wind from v1
- copy_v3_v3(tmp, trinormal);
- mul_v3_fl(tmp, calculateVertexWindForce(winvec[mfaces[i].v1], triunnormal));
- VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], tmp, factor);
-
- // add wind from v2
- copy_v3_v3(tmp, trinormal);
- mul_v3_fl(tmp, calculateVertexWindForce(winvec[mfaces[i].v2], triunnormal));
- VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], tmp, factor);
-
- // add wind from v3
- copy_v3_v3(tmp, trinormal);
- mul_v3_fl(tmp, calculateVertexWindForce(winvec[mfaces[i].v3], triunnormal));
- VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], tmp, factor);
-
- // add wind from v4
- if (mfaces[i].v4) {
- copy_v3_v3(tmp, trinormal);
- mul_v3_fl(tmp, calculateVertexWindForce(winvec[mfaces[i].v4], triunnormal));
- VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], tmp, factor);
- }
- }
-
- /* Hair has only edges */
- if (cloth->numfaces == 0) {
- ClothSpring *spring;
- float edgevec[3] = {0, 0, 0}; //edge vector
- float edgeunnormal[3] = {0, 0, 0}; // not-normalized-edge normal
- float tmp[3] = {0, 0, 0};
- float factor = 0.01;
-
- search = cloth->springs;
- while (search) {
- spring = search->link;
-
- if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) {
- sub_v3_v3v3(edgevec, (float*)lX[spring->ij], (float*)lX[spring->kl]);
-
- project_v3_v3v3(tmp, winvec[spring->ij], edgevec);
- sub_v3_v3v3(edgeunnormal, winvec[spring->ij], tmp);
- /* hair doesn't stretch too much so we can use restlen pretty safely */
- VECADDS(lF[spring->ij], lF[spring->ij], edgeunnormal, spring->restlen * factor);
-
- project_v3_v3v3(tmp, winvec[spring->kl], edgevec);
- sub_v3_v3v3(edgeunnormal, winvec[spring->kl], tmp);
- VECADDS(lF[spring->kl], lF[spring->kl], edgeunnormal, spring->restlen * factor);
- }
-
- search = search->next;
- }
- }
-
- del_lfvector(winvec);
- }
-
- // calculate spring forces
- search = cloth->springs;
- while (search) {
- // only handle active springs
- ClothSpring *spring = search->link;
- if (!(spring->flags & CLOTH_SPRING_FLAG_DEACTIVATE))
- cloth_calc_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX, time);
-
- search = search->next;
- }
-
- // apply spring forces
- search = cloth->springs;
- while (search) {
- // only handle active springs
- ClothSpring *spring = search->link;
- if (!(spring->flags & CLOTH_SPRING_FLAG_DEACTIVATE))
- cloth_apply_spring_force(clmd, search->link, lF, lX, lV, dFdV, dFdX);
- search = search->next;
- }
- // printf("\n");
-}
-
-static void simulate_implicit_euler(lfVector *Vnew, lfVector *UNUSED(lX), lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, lfVector *olddV, fmatrix3x3 *UNUSED(P), fmatrix3x3 *UNUSED(Pinv), fmatrix3x3 *M, fmatrix3x3 *UNUSED(bigI))
-{
- unsigned int numverts = dFdV[0].vcount;
-
- lfVector *dFdXmV = create_lfvector(numverts);
- zero_lfvector(dV, numverts);
-
- cp_bfmatrix(A, M);
-
- subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt));
-
- mul_bfmatrix_lfvector(dFdXmV, dFdX, lV);
-
- add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts);
-
- // itstart();
-
- cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */
- // cg_filtered_pre(dV, A, B, z, S, P, Pinv, bigI);
-
- // itend();
- // printf("cg_filtered calc time: %f\n", (float)itval());
-
- cp_lfvector(olddV, dV, numverts);
-
- // advance velocities
- add_lfvector_lfvector(Vnew, lV, dV, numverts);
-
-
- del_lfvector(dFdXmV);
-}
-
-/* computes where the cloth would be if it were subject to perfectly stiff edges
- * (edge distance constraints) in a lagrangian solver. then add forces to help
- * guide the implicit solver to that state. this function is called after
- * collisions*/
-static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothModifierData *clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
-{
- Cloth *cloth= clmd->clothObject;
- float (*cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces");
- float *masses = MEM_callocN(sizeof(float)*cloth->numverts, "cos cloth_calc_helper_forces");
- LinkNode *node;
- ClothSpring *spring;
- ClothVertex *cv;
- int i, steps;
-
- cv = cloth->verts;
- for (i=0; i<cloth->numverts; i++, cv++) {
- copy_v3_v3(cos[i], cv->tx);
-
- if (cv->goal == 1.0f || len_squared_v3v3(initial_cos[i], cv->tx) != 0.0f) {
- masses[i] = 1e+10;
- }
- else {
- masses[i] = cv->mass;
- }
- }
-
- steps = 55;
- for (i=0; i<steps; i++) {
- for (node=cloth->springs; node; node=node->next) {
- /* ClothVertex *cv1, *cv2; */ /* UNUSED */
- int v1, v2;
- float len, c, l, vec[3];
-
- spring = node->link;
- if (spring->type != CLOTH_SPRING_TYPE_STRUCTURAL && spring->type != CLOTH_SPRING_TYPE_SHEAR)
- continue;
-
- v1 = spring->ij; v2 = spring->kl;
- /* cv1 = cloth->verts + v1; */ /* UNUSED */
- /* cv2 = cloth->verts + v2; */ /* UNUSED */
- len = len_v3v3(cos[v1], cos[v2]);
-
- sub_v3_v3v3(vec, cos[v1], cos[v2]);
- normalize_v3(vec);
-
- c = (len - spring->restlen);
- if (c == 0.0f)
- continue;
-
- l = c / ((1.0f / masses[v1]) + (1.0f / masses[v2]));
-
- mul_v3_fl(vec, -(1.0f / masses[v1]) * l);
- add_v3_v3(cos[v1], vec);
-
- sub_v3_v3v3(vec, cos[v2], cos[v1]);
- normalize_v3(vec);
-
- mul_v3_fl(vec, -(1.0f / masses[v2]) * l);
- add_v3_v3(cos[v2], vec);
- }
- }
-
- cv = cloth->verts;
- for (i=0; i<cloth->numverts; i++, cv++) {
- float vec[3];
-
- /*compute forces*/
- sub_v3_v3v3(vec, cos[i], cv->tx);
- mul_v3_fl(vec, cv->mass*dt*20.0f);
- add_v3_v3(cv->tv, vec);
- //copy_v3_v3(cv->tx, cos[i]);
- }
-
- MEM_freeN(cos);
- MEM_freeN(masses);
-
- return 1;
-}
-
-int implicit_solver(Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
-{
- unsigned int i=0;
- float step=0.0f, tf=clmd->sim_parms->timescale;
- Cloth *cloth = clmd->clothObject;
- ClothVertex *verts = cloth->verts, *cv;
- unsigned int numverts = cloth->numverts;
- float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
- float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
- float (*initial_cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "initial_cos implicit.c");
- Implicit_Data *id = cloth->implicit;
- int do_extra_solve;
-
- if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { /* do goal stuff */
-
- /* Update vertex constraints for pinned vertices */
- update_matrixS(verts, cloth->numverts, id->S);
-
- for (i = 0; i < numverts; i++) {
- // update velocities with constrained velocities from pinned verts
- if (verts [i].flags & CLOTH_VERT_FLAG_PINNED) {
- sub_v3_v3v3(id->V[i], verts[i].xconst, verts[i].xold);
- // mul_v3_fl(id->V[i], clmd->sim_parms->stepsPerFrame);
- }
- }
- }
-
- while (step < tf) {
- // damping velocity for artistic reasons
- mul_lfvectorS(id->V, id->V, clmd->sim_parms->vel_damping, numverts);
-
- // calculate forces
- cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, id->M);
-
- // calculate new velocity
- simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
-
- // advance positions
- add_lfvector_lfvectorS(id->Xnew, id->X, id->Vnew, dt, numverts);
-
- /* move pinned verts to correct position */
- for (i = 0; i < numverts; i++) {
- if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) {
- if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
- float tvect[3] = {0.0f, 0.0f, 0.0f};
- sub_v3_v3v3(tvect, verts[i].xconst, verts[i].xold);
- mul_fvector_S(tvect, tvect, step+dt);
- VECADD(tvect, tvect, verts[i].xold);
- copy_v3_v3(id->Xnew[i], tvect);
- }
- }
-
- copy_v3_v3(verts[i].txold, id->X[i]);
- }
-
- if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED && clmd->clothObject->bvhtree) {
- // collisions
- // itstart();
-
- // update verts to current positions
- for (i = 0; i < numverts; i++) {
- copy_v3_v3(verts[i].tx, id->Xnew[i]);
-
- sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
- copy_v3_v3(verts[i].v, verts[i].tv);
- }
-
- for (i=0, cv=cloth->verts; i<cloth->numverts; i++, cv++) {
- copy_v3_v3(initial_cos[i], cv->tx);
- }
-
- // call collision function
- // TODO: check if "step" or "step+dt" is correct - dg
- do_extra_solve = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
-
- // copy corrected positions back to simulation
- for (i = 0; i < numverts; i++) {
- // correct velocity again, just to be sure we had to change it due to adaptive collisions
- sub_v3_v3v3(verts[i].tv, verts[i].tx, id->X[i]);
- }
-
- //if (do_extra_solve)
- // cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
-
- if (do_extra_solve) {
- for (i = 0; i < numverts; i++) {
- if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
- continue;
-
- copy_v3_v3(id->Xnew[i], verts[i].tx);
- copy_v3_v3(id->Vnew[i], verts[i].tv);
- mul_v3_fl(id->Vnew[i], spf);
- }
- }
-
- // X = Xnew;
- cp_lfvector(id->X, id->Xnew, numverts);
-
- // if there were collisions, advance the velocity from v_n+1/2 to v_n+1
-
- if (do_extra_solve) {
- // V = Vnew;
- cp_lfvector(id->V, id->Vnew, numverts);
-
- // calculate
- cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M);
-
- simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
- }
- }
- else {
- // X = Xnew;
- cp_lfvector(id->X, id->Xnew, numverts);
- }
-
- // itend();
- // printf("collision time: %f\n", (float)itval());
-
- // V = Vnew;
- cp_lfvector(id->V, id->Vnew, numverts);
-
- step += dt;
- }
-
- for (i = 0; i < numverts; i++) {
- if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED)) {
- copy_v3_v3(verts[i].txold, verts[i].xconst); // TODO: test --> should be .x
- copy_v3_v3(verts[i].x, verts[i].xconst);
- copy_v3_v3(verts[i].v, id->V[i]);
- }
- else {
- copy_v3_v3(verts[i].txold, id->X[i]);
- copy_v3_v3(verts[i].x, id->X[i]);
- copy_v3_v3(verts[i].v, id->V[i]);
- }
- }
-
- MEM_freeN(initial_cos);
-
- return 1;
-}
-
-void implicit_set_positions(ClothModifierData *clmd)
-{
- Cloth *cloth = clmd->clothObject;
- ClothVertex *verts = cloth->verts;
- unsigned int numverts = cloth->numverts, i;
- Implicit_Data *id = cloth->implicit;
-
- for (i = 0; i < numverts; i++) {
- copy_v3_v3(id->X[i], verts[i].x);
- copy_v3_v3(id->V[i], verts[i].v);
- }
- if (G.debug_value > 0)
- printf("implicit_set_positions\n");
-}
-
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 51cf26063c7..09ce9484a69 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -161,21 +161,24 @@ static AdrBit2Path ma_mode_bits[] = {
{ \
*tot = sizeof(items) / sizeof(AdrBit2Path); \
return items; \
- }
+ } (void)0
/* This function checks if a Blocktype+Adrcode combo, returning a mapping table */
static AdrBit2Path *adrcode_bitmaps_to_paths(int blocktype, int adrcode, int *tot)
{
/* Object layers */
- if ((blocktype == ID_OB) && (adrcode == OB_LAY))
- RET_ABP(ob_layer_bits)
- else if ((blocktype == ID_MA) && (adrcode == MA_MODE))
- RET_ABP(ma_mode_bits)
+ if ((blocktype == ID_OB) && (adrcode == OB_LAY)) {
+ RET_ABP(ob_layer_bits);
+ }
+ else if ((blocktype == ID_MA) && (adrcode == MA_MODE)) {
+ RET_ABP(ma_mode_bits);
+ }
// XXX TODO: add other types...
/* Normal curve */
return NULL;
}
+#undef RET_ABP
/* *************************************************** */
/* ADRCODE to RNA-Path Conversion Code - Standard */
@@ -919,11 +922,11 @@ static char *get_rna_access(int blocktype, int adrcode, char actname[], char con
BLI_snprintf(buf, sizeof(buf), "pose.bones[\"%s\"].constraints[\"%s\"]", actname, constname);
}
else if (actname && actname[0]) {
- if ((blocktype == ID_OB) && strcmp(actname, "Object") == 0) {
+ if ((blocktype == ID_OB) && STREQ(actname, "Object")) {
/* Actionified "Object" IPO's... no extra path stuff needed */
buf[0] = '\0'; /* empty string */
}
- else if ((blocktype == ID_KE) && strcmp(actname, "Shape") == 0) {
+ else if ((blocktype == ID_KE) && STREQ(actname, "Shape")) {
/* Actionified "Shape" IPO's - these are forced onto object level via the action container there... */
strcpy(buf, "data.shape_keys");
}
@@ -1323,7 +1326,7 @@ static void icu_to_fcurves(ID *id, ListBase *groups, ListBase *list, IpoCurve *i
* - we now need as 'frames'
*/
if ( (id) && (icu->blocktype == GS(id->name)) &&
- (fcu->rna_path && strcmp(fcu->rna_path, "eval_time") == 0) )
+ (fcu->rna_path && STREQ(fcu->rna_path, "eval_time")) )
{
Curve *cu = (Curve *)id;
@@ -1400,9 +1403,9 @@ static void ipo_to_animato(ID *id, Ipo *ipo, char actname[], char constname[], S
* F-Curves for bones). This may be added later... for now let's just dump without them...
*/
if (actname) {
- if ((ipo->blocktype == ID_OB) && (strcmp(actname, "Object") == 0))
+ if ((ipo->blocktype == ID_OB) && STREQ(actname, "Object"))
actname = NULL;
- else if ((ipo->blocktype == ID_OB) && (strcmp(actname, "Shape") == 0))
+ else if ((ipo->blocktype == ID_OB) && STREQ(actname, "Shape"))
actname = NULL;
}
@@ -1523,7 +1526,7 @@ static void ipo_to_animdata(ID *id, Ipo *ipo, char actname[], char constname[],
if (G.debug & G_DEBUG) {
printf("ipo to animdata - ID:%s, IPO:%s, actname:%s constname:%s seqname:%s curves:%d\n",
id->name + 2, ipo->id.name + 2, (actname) ? actname : "<None>", (constname) ? constname : "<None>", (seq) ? (seq->name + 2) : "<None>",
- BLI_countlist(&ipo->curve));
+ BLI_listbase_count(&ipo->curve));
}
/* Convert curves to animato system (separated into separate lists of F-Curves for animation and drivers),
@@ -1648,6 +1651,9 @@ static void nlastrips_to_animdata(ID *id, ListBase *strips)
nlt = add_nlatrack(adt, NULL);
BKE_nlatrack_add_strip(nlt, strip);
}
+
+ /* ensure that strip has a name */
+ BKE_nlastrip_validate_name(adt, strip);
}
/* modifiers */
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 69b375fba58..560a3c0726b 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -73,10 +73,6 @@
#define IPO_BEZTRIPLE 100
#define IPO_BPOINT 101
-/* extern, not threadsafe */
-int slurph_opt = 1;
-
-
void BKE_key_free(Key *key)
{
KeyBlock *kb;
@@ -171,7 +167,11 @@ Key *BKE_key_copy(Key *key)
kbn = kbn->next;
kb = kb->next;
}
-
+
+ if (key->id.lib) {
+ BKE_id_lib_local_paths(G.main, key->id.lib, &keyn->id);
+ }
+
return keyn;
}
@@ -607,7 +607,7 @@ static void cp_key(const int start, int end, const int tot, char *poin, Key *key
k1 = key_block_get_data(key, actkb, kb, &freek1);
kref = key_block_get_data(key, actkb, key->refkey, &freekref);
- /* this exception is needed for slurphing */
+ /* this exception is needed curves with multiple splines */
if (start != 0) {
poin += poinsize * start;
@@ -891,7 +891,7 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
}
}
- /* this exception needed for slurphing */
+ /* this exception is needed for curves with multiple splines */
if (start != 0) {
poin += poinsize * start;
@@ -1086,7 +1086,7 @@ static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cac
if (cache) {
if (cache->defgroup_weights == NULL) {
- int num_defgroup = BLI_countlist(&ob->defbase);
+ int num_defgroup = BLI_listbase_count(&ob->defbase);
cache->defgroup_weights =
MEM_callocN(sizeof(*cache->defgroup_weights) * num_defgroup,
"cached defgroup weights");
@@ -1168,53 +1168,29 @@ void BKE_keyblock_free_per_block_weights(Key *key, float **per_keyblock_weights,
MEM_freeN(per_keyblock_weights);
}
-static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int tot)
+static void do_mesh_key(Object *ob, Key *key, char *out, const int tot)
{
KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob);
float t[4];
int flag = 0;
- if (key->slurph && key->type != KEY_RELATIVE) {
+ if (key->type == KEY_RELATIVE) {
+ WeightsArrayCache cache = {0, NULL};
+ float **per_keyblock_weights;
+ per_keyblock_weights = BKE_keyblock_get_per_block_weights(ob, key, &cache);
+ BKE_key_evaluate_relative(0, tot, tot, (char *)out, key, actkb, per_keyblock_weights, KEY_MODE_DUMMY);
+ BKE_keyblock_free_per_block_weights(key, per_keyblock_weights, &cache);
+ }
+ else {
const float ctime_scaled = key->ctime / 100.0f;
- float delta = (float)key->slurph / tot;
- float cfra = BKE_scene_frame_get(scene);
- int step, a;
- if (tot > 100 && slurph_opt) {
- step = tot / 50;
- delta *= step;
- /* in do_key and cp_key the case a>tot is handled */
- }
- else {
- step = 1;
- }
+ flag = setkeys(ctime_scaled, &key->block, k, t, 0);
- for (a = 0; a < tot; a += step, cfra += delta) {
- flag = setkeys(ctime_scaled, &key->block, k, t, 0);
-
- if (flag == 0)
- do_key(a, a + step, tot, (char *)out, key, actkb, k, t, KEY_MODE_DUMMY);
- else
- cp_key(a, a + step, tot, (char *)out, key, actkb, k[2], NULL, KEY_MODE_DUMMY);
- }
- }
- else {
- if (key->type == KEY_RELATIVE) {
- WeightsArrayCache cache = {0, NULL};
- float **per_keyblock_weights;
- per_keyblock_weights = BKE_keyblock_get_per_block_weights(ob, key, &cache);
- BKE_key_evaluate_relative(0, tot, tot, (char *)out, key, actkb, per_keyblock_weights, KEY_MODE_DUMMY);
- BKE_keyblock_free_per_block_weights(key, per_keyblock_weights, &cache);
+ if (flag == 0) {
+ do_key(0, tot, tot, (char *)out, key, actkb, k, t, KEY_MODE_DUMMY);
}
else {
- const float ctime_scaled = key->ctime / 100.0f;
-
- flag = setkeys(ctime_scaled, &key->block, k, t, 0);
-
- if (flag == 0)
- do_key(0, tot, tot, (char *)out, key, actkb, k, t, KEY_MODE_DUMMY);
- else
- cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, KEY_MODE_DUMMY);
+ cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, KEY_MODE_DUMMY);
}
}
}
@@ -1259,135 +1235,63 @@ static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, char *out, const
}
}
-static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const int tot)
+static void do_curve_key(Object *ob, Key *key, char *out, const int tot)
{
Curve *cu = ob->data;
KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob);
float t[4];
int flag = 0;
- if (key->slurph && key->type != KEY_RELATIVE) {
+ if (key->type == KEY_RELATIVE) {
+ do_rel_cu_key(cu, cu->key, actkb, out, tot);
+ }
+ else {
const float ctime_scaled = key->ctime / 100.0f;
- float delta = (float)key->slurph / tot;
- float cfra = BKE_scene_frame_get(scene);
- Nurb *nu;
- int i = 0, remain = 0;
- int step, a;
-
- if (tot > 100 && slurph_opt) {
- step = tot / 50;
- delta *= step;
- /* in do_key and cp_key the case a>tot has been handled */
- }
- else {
- step = 1;
- }
-
- for (nu = cu->nurb.first; nu; nu = nu->next) {
- int estep, mode;
-
- if (nu->bp) {
- mode = KEY_MODE_BPOINT;
- estep = nu->pntsu * nu->pntsv;
- }
- else if (nu->bezt) {
- mode = KEY_MODE_BEZTRIPLE;
- estep = 3 * nu->pntsu;
- }
- else {
- mode = 0;
- estep = 0;
- }
-
- a = 0;
- while (a < estep) {
- int count;
-
- if (remain <= 0) {
- cfra += delta;
- flag = setkeys(ctime_scaled, &key->block, k, t, 0);
-
- remain = step;
- }
-
- count = min_ii(remain, estep);
- if (mode == KEY_MODE_BEZTRIPLE) {
- count += 3 - count % 3;
- }
- if (flag == 0)
- do_key(i, i + count, tot, (char *)out, key, actkb, k, t, mode);
- else
- cp_key(i, i + count, tot, (char *)out, key, actkb, k[2], NULL, mode);
+ flag = setkeys(ctime_scaled, &key->block, k, t, 0);
- a += count;
- i += count;
- remain -= count;
- }
- }
- }
- else {
- if (key->type == KEY_RELATIVE) {
- do_rel_cu_key(cu, cu->key, actkb, out, tot);
+ if (flag == 0) {
+ do_cu_key(cu, key, actkb, k, t, out, tot);
}
else {
- const float ctime_scaled = key->ctime / 100.0f;
-
- flag = setkeys(ctime_scaled, &key->block, k, t, 0);
-
- if (flag == 0) do_cu_key(cu, key, actkb, k, t, out, tot);
- else cp_cu_key(cu, key, actkb, k[2], 0, tot, out, tot);
+ cp_cu_key(cu, key, actkb, k[2], 0, tot, out, tot);
}
}
}
-static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int tot)
+static void do_latt_key(Object *ob, Key *key, char *out, const int tot)
{
Lattice *lt = ob->data;
KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob);
float t[4];
int flag;
- if (key->slurph && key->type != KEY_RELATIVE) {
- const float ctime_scaled = key->ctime / 100.0f;
- float delta = (float)key->slurph / tot;
- float cfra = BKE_scene_frame_get(scene);
- int a;
-
- for (a = 0; a < tot; a++, cfra += delta) {
- flag = setkeys(ctime_scaled, &key->block, k, t, 0);
-
- if (flag == 0)
- do_key(a, a + 1, tot, out, key, actkb, k, t, KEY_MODE_DUMMY);
- else
- cp_key(a, a + 1, tot, out, key, actkb, k[2], NULL, KEY_MODE_DUMMY);
- }
+ if (key->type == KEY_RELATIVE) {
+ float **per_keyblock_weights;
+ per_keyblock_weights = BKE_keyblock_get_per_block_weights(ob, key, NULL);
+ BKE_key_evaluate_relative(0, tot, tot, (char *)out, key, actkb, per_keyblock_weights, KEY_MODE_DUMMY);
+ BKE_keyblock_free_per_block_weights(key, per_keyblock_weights, NULL);
}
else {
- if (key->type == KEY_RELATIVE) {
- float **per_keyblock_weights;
- per_keyblock_weights = BKE_keyblock_get_per_block_weights(ob, key, NULL);
- BKE_key_evaluate_relative(0, tot, tot, (char *)out, key, actkb, per_keyblock_weights, KEY_MODE_DUMMY);
- BKE_keyblock_free_per_block_weights(key, per_keyblock_weights, NULL);
+ const float ctime_scaled = key->ctime / 100.0f;
+
+ flag = setkeys(ctime_scaled, &key->block, k, t, 0);
+
+ if (flag == 0) {
+ do_key(0, tot, tot, (char *)out, key, actkb, k, t, KEY_MODE_DUMMY);
}
else {
- const float ctime_scaled = key->ctime / 100.0f;
-
- flag = setkeys(ctime_scaled, &key->block, k, t, 0);
-
- if (flag == 0)
- do_key(0, tot, tot, (char *)out, key, actkb, k, t, KEY_MODE_DUMMY);
- else
- cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, KEY_MODE_DUMMY);
+ cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, KEY_MODE_DUMMY);
}
}
-
+
if (lt->flag & LT_OUTSIDE) outside_lattice(lt);
}
/* returns key coordinates (+ tilt) when key applied, NULL otherwise */
-float *BKE_key_evaluate_object_ex(Scene *scene, Object *ob, int *r_totelem,
- float *arr, size_t arr_size)
+float *BKE_key_evaluate_object_ex(
+ Object *ob, int *r_totelem,
+ float *arr, size_t arr_size)
{
Key *key = BKE_key_from_object(ob);
KeyBlock *actkb = BKE_keyblock_from_object(ob);
@@ -1469,10 +1373,10 @@ float *BKE_key_evaluate_object_ex(Scene *scene, Object *ob, int *r_totelem,
}
else {
- if (ob->type == OB_MESH) do_mesh_key(scene, ob, key, out, tot);
- else if (ob->type == OB_LATTICE) do_latt_key(scene, ob, key, out, tot);
- else if (ob->type == OB_CURVE) do_curve_key(scene, ob, key, out, tot);
- else if (ob->type == OB_SURF) do_curve_key(scene, ob, key, out, tot);
+ if (ob->type == OB_MESH) do_mesh_key(ob, key, out, tot);
+ else if (ob->type == OB_LATTICE) do_latt_key(ob, key, out, tot);
+ else if (ob->type == OB_CURVE) do_curve_key(ob, key, out, tot);
+ else if (ob->type == OB_SURF) do_curve_key(ob, key, out, tot);
}
if (r_totelem) {
@@ -1481,9 +1385,9 @@ float *BKE_key_evaluate_object_ex(Scene *scene, Object *ob, int *r_totelem,
return (float *)out;
}
-float *BKE_key_evaluate_object(Scene *scene, Object *ob, int *r_totelem)
+float *BKE_key_evaluate_object(Object *ob, int *r_totelem)
{
- return BKE_key_evaluate_object_ex(scene, ob, r_totelem, NULL, 0);
+ return BKE_key_evaluate_object_ex(ob, r_totelem, NULL, 0);
}
Key *BKE_key_from_object(Object *ob)
@@ -1518,7 +1422,7 @@ KeyBlock *BKE_keyblock_add(Key *key, const char *name)
BLI_addtail(&key->block, kb);
kb->type = KEY_CARDINAL;
- tot = BLI_countlist(&key->block);
+ tot = BLI_listbase_count(&key->block);
if (name) {
BLI_strncpy(kb->name, name, sizeof(kb->name));
}
@@ -1669,31 +1573,43 @@ char *BKE_keyblock_curval_rnapath_get(Key *key, KeyBlock *kb)
/* conversion functions */
/************************* Lattice ************************/
-void BKE_key_convert_from_lattice(Lattice *lt, KeyBlock *kb)
+void BKE_keyblock_update_from_lattice(Lattice *lt, KeyBlock *kb)
{
BPoint *bp;
- float *fp;
+ float (*fp)[3];
int a, tot;
+ BLI_assert(kb->totelem == lt->pntsu * lt->pntsv * lt->pntsw);
+
+ tot = kb->totelem;
+ if (tot == 0) return;
+
+ bp = lt->def;
+ fp = kb->data;
+ for (a = 0; a < kb->totelem; a++, fp++, bp++) {
+ copy_v3_v3(*fp, bp->vec);
+ }
+}
+
+void BKE_keyblock_convert_from_lattice(Lattice *lt, KeyBlock *kb)
+{
+ int tot;
+
tot = lt->pntsu * lt->pntsv * lt->pntsw;
if (tot == 0) return;
- if (kb->data) MEM_freeN(kb->data);
+ MEM_SAFE_FREE(kb->data);
- kb->data = MEM_mallocN(lt->key->elemsize * tot, "kb->data");
+ kb->data = MEM_mallocN(lt->key->elemsize * tot, __func__);
kb->totelem = tot;
- bp = lt->def;
- fp = kb->data;
- for (a = 0; a < kb->totelem; a++, fp += 3, bp++) {
- copy_v3_v3(fp, bp->vec);
- }
+ BKE_keyblock_update_from_lattice(lt, kb);
}
-void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt)
+void BKE_keyblock_convert_to_lattice(KeyBlock *kb, Lattice *lt)
{
BPoint *bp;
- const float *fp;
+ const float (*fp)[3];
int a, tot;
bp = lt->def;
@@ -1702,13 +1618,13 @@ void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt)
tot = lt->pntsu * lt->pntsv * lt->pntsw;
tot = min_ii(kb->totelem, tot);
- for (a = 0; a < tot; a++, fp += 3, bp++) {
- copy_v3_v3(bp->vec, fp);
+ for (a = 0; a < tot; a++, fp++, bp++) {
+ copy_v3_v3(bp->vec, *fp);
}
}
/************************* Curve ************************/
-void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
+void BKE_keyblock_update_from_curve(Curve *UNUSED(cu), KeyBlock *kb, ListBase *nurb)
{
Nurb *nu;
BezTriple *bezt;
@@ -1717,49 +1633,52 @@ void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
int a, tot;
/* count */
- tot = BKE_nurbList_verts_count(nurb);
- if (tot == 0) return;
+ BLI_assert(BKE_nurbList_verts_count(nurb) == kb->totelem);
- if (kb->data) MEM_freeN(kb->data);
-
- kb->data = MEM_mallocN(cu->key->elemsize * tot, "kb->data");
- kb->totelem = tot;
+ tot = kb->totelem;
+ if (tot == 0) return;
- nu = nurb->first;
fp = kb->data;
- while (nu) {
-
+ for (nu = nurb->first; nu; nu = nu->next) {
if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- copy_v3_v3(fp, bezt->vec[0]);
- fp += 3;
- copy_v3_v3(fp, bezt->vec[1]);
- fp += 3;
- copy_v3_v3(fp, bezt->vec[2]);
- fp += 3;
+ for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
+ int i;
+
+ for (i = 0; i < 3; i++, fp += 3) {
+ copy_v3_v3(fp, bezt->vec[i]);
+ }
fp[0] = bezt->alfa;
fp += 3; /* alphas */
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
+
+ ;
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, fp += 4, bp++) {
copy_v3_v3(fp, bp->vec);
fp[3] = bp->alfa;
-
- fp += 4;
- bp++;
}
}
- nu = nu->next;
}
}
-void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
+void BKE_keyblock_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
+{
+ int tot;
+
+ /* count */
+ tot = BKE_nurbList_verts_count(nurb);
+ if (tot == 0) return;
+
+ MEM_SAFE_FREE(kb->data);
+
+ kb->data = MEM_mallocN(cu->key->elemsize * tot, __func__);
+ kb->totelem = tot;
+
+ BKE_keyblock_update_from_curve(cu, kb, nurb);
+}
+
+void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
{
Nurb *nu;
BezTriple *bezt;
@@ -1767,74 +1686,68 @@ void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
const float *fp;
int a, tot;
- nu = nurb->first;
- fp = kb->data;
-
tot = BKE_nurbList_verts_count(nurb);
-
tot = min_ii(kb->totelem, tot);
- while (nu && tot > 0) {
-
+ fp = kb->data;
+ for (nu = nurb->first; nu && tot > 0; nu = nu->next) {
if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a-- && tot > 0) {
- copy_v3_v3(bezt->vec[0], fp);
- fp += 3;
- copy_v3_v3(bezt->vec[1], fp);
- fp += 3;
- copy_v3_v3(bezt->vec[2], fp);
- fp += 3;
+ for (a = nu->pntsu, bezt = nu->bezt; a && tot > 0; a--, tot -= 3, bezt++) {
+ int i;
+
+ for (i = 0; i < 3; i++, fp += 3) {
+ copy_v3_v3(bezt->vec[i], fp);
+ }
bezt->alfa = fp[0];
fp += 3; /* alphas */
-
- tot -= 3;
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a-- && tot > 0) {
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a && tot; a--, tot--, fp += 4, bp++) {
copy_v3_v3(bp->vec, fp);
bp->alfa = fp[3];
-
- fp += 4;
- tot--;
- bp++;
}
}
- nu = nu->next;
}
}
/************************* Mesh ************************/
-void BKE_key_convert_from_mesh(Mesh *me, KeyBlock *kb)
+void BKE_keyblock_update_from_mesh(Mesh *me, KeyBlock *kb)
{
MVert *mvert;
- float *fp;
- int a;
-
- if (me->totvert == 0) return;
+ float (*fp)[3];
+ int a, tot;
- if (kb->data) MEM_freeN(kb->data);
+ BLI_assert(me->totvert == kb->totelem);
- kb->data = MEM_mallocN(me->key->elemsize * me->totvert, "kb->data");
- kb->totelem = me->totvert;
+ tot = me->totvert;
+ if (tot == 0) return;
mvert = me->mvert;
fp = kb->data;
- for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) {
- copy_v3_v3(fp, mvert->co);
-
+ for (a = 0; a < tot; a++, fp++, mvert++) {
+ copy_v3_v3(*fp, mvert->co);
}
}
-void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me)
+void BKE_keyblock_convert_from_mesh(Mesh *me, KeyBlock *kb)
+{
+ int tot = me->totvert;
+
+ if (me->totvert == 0) return;
+
+ MEM_SAFE_FREE(kb->data);
+
+ kb->data = MEM_mallocN(me->key->elemsize * tot, __func__);
+ kb->totelem = tot;
+
+ BKE_keyblock_update_from_mesh(me, kb);
+}
+
+void BKE_keyblock_convert_to_mesh(KeyBlock *kb, Mesh *me)
{
MVert *mvert;
- const float *fp;
+ const float (*fp)[3];
int a, tot;
mvert = me->mvert;
@@ -1842,94 +1755,76 @@ void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me)
tot = min_ii(kb->totelem, me->totvert);
- for (a = 0; a < tot; a++, fp += 3, mvert++) {
- copy_v3_v3(mvert->co, fp);
+ for (a = 0; a < tot; a++, fp++, mvert++) {
+ copy_v3_v3(mvert->co, *fp);
}
}
-/************************* vert coords ************************/
-float (*BKE_key_convert_to_vertcos(Object *ob, KeyBlock *kb))[3]
+/************************* raw coords ************************/
+void BKE_keyblock_update_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3])
{
- float (*vertCos)[3], *co;
- const float *fp = kb->data;
- int tot = 0, a;
+ float (*co)[3] = vertCos;
+ float *fp = kb->data;
+ int tot, a;
- /* Count of vertex coords in array */
- if (ob->type == OB_MESH) {
- Mesh *me = (Mesh *)ob->data;
- tot = me->totvert;
- }
- else if (ob->type == OB_LATTICE) {
- Lattice *lt = (Lattice *)ob->data;
- tot = lt->pntsu * lt->pntsv * lt->pntsw;
+#ifndef NDEBUG
+ if (ob->type == OB_LATTICE) {
+ Lattice *lt = ob->data;
+ BLI_assert((lt->pntsu * lt->pntsv * lt->pntsw) == kb->totelem);
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
- Curve *cu = (Curve *)ob->data;
- tot = BKE_nurbList_verts_count(&cu->nurb);
+ Curve *cu = ob->data;
+ BLI_assert(BKE_nurbList_verts_count(&cu->nurb) == kb->totelem);
}
+ else if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ BLI_assert(me->totvert == kb->totelem);
+ }
+ else {
+ BLI_assert(0 == kb->totelem);
+ }
+#endif
- if (tot == 0) return NULL;
-
- vertCos = MEM_mallocN(tot * sizeof(*vertCos), "BKE_key_convert_to_vertcos vertCos");
-
- /* Copy coords to array */
- co = (float *)vertCos;
+ tot = kb->totelem;
+ if (tot == 0) return;
+ /* Copy coords to keyblock */
if (ELEM(ob->type, OB_MESH, OB_LATTICE)) {
- for (a = 0; a < tot; a++, fp += 3, co += 3) {
- copy_v3_v3(co, fp);
+ for (a = 0; a < tot; a++, fp += 3, co++) {
+ copy_v3_v3(fp, *co);
}
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = (Curve *)ob->data;
- Nurb *nu = cu->nurb.first;
+ Nurb *nu;
BezTriple *bezt;
BPoint *bp;
- while (nu) {
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->bezt) {
- int i;
- bezt = nu->bezt;
- a = nu->pntsu;
+ for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
+ int i;
- while (a--) {
- for (i = 0; i < 3; i++) {
- copy_v3_v3(co, fp);
- fp += 3; co += 3;
+ for (i = 0; i < 3; i++, fp += 3, co++) {
+ copy_v3_v3(fp, *co);
}
-
fp += 3; /* skip alphas */
-
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
-
- while (a--) {
- copy_v3_v3(co, fp);
-
- fp += 4;
- co += 3;
-
- bp++;
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, co++) {
+ copy_v3_v3(fp, *co);
}
}
-
- nu = nu->next;
}
}
-
- return vertCos;
}
-void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3])
+void BKE_keyblock_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3])
{
- float *co = (float *)vertCos, *fp;
- int tot = 0, a, elemsize;
+ int tot = 0, elemsize;
- if (kb->data) MEM_freeN(kb->data);
+ MEM_SAFE_FREE(kb->data);
/* Count of vertex coords in array */
if (ob->type == OB_MESH) {
@@ -1948,110 +1843,105 @@ void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3])
tot = BKE_nurbList_verts_count(&cu->nurb);
}
- if (tot == 0) {
- kb->data = NULL;
- return;
- }
+ if (tot == 0) return;
- fp = kb->data = MEM_mallocN(tot * elemsize, "BKE_key_convert_to_vertcos vertCos");
+ kb->data = MEM_mallocN(tot * elemsize, __func__);
/* Copy coords to keyblock */
+ BKE_keyblock_update_from_vertcos(ob, kb, vertCos);
+}
+
+float (*BKE_keyblock_convert_to_vertcos(Object *ob, KeyBlock *kb))[3]
+{
+ float (*vertCos)[3], (*co)[3];
+ const float *fp = kb->data;
+ int tot = 0, a;
+ /* Count of vertex coords in array */
+ if (ob->type == OB_MESH) {
+ Mesh *me = (Mesh *)ob->data;
+ tot = me->totvert;
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = (Lattice *)ob->data;
+ tot = lt->pntsu * lt->pntsv * lt->pntsw;
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ Curve *cu = (Curve *)ob->data;
+ tot = BKE_nurbList_verts_count(&cu->nurb);
+ }
+
+ if (tot == 0) return NULL;
+
+ co = vertCos = MEM_mallocN(tot * sizeof(*vertCos), __func__);
+
+ /* Copy coords to array */
if (ELEM(ob->type, OB_MESH, OB_LATTICE)) {
- for (a = 0; a < tot; a++, fp += 3, co += 3) {
- copy_v3_v3(fp, co);
+ for (a = 0; a < tot; a++, fp += 3, co++) {
+ copy_v3_v3(*co, fp);
}
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = (Curve *)ob->data;
- Nurb *nu = cu->nurb.first;
+ Nurb *nu;
BezTriple *bezt;
BPoint *bp;
- while (nu) {
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->bezt) {
- int i;
- bezt = nu->bezt;
- a = nu->pntsu;
+ for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
+ int i;
- while (a--) {
- for (i = 0; i < 3; i++) {
- copy_v3_v3(fp, co);
- fp += 3; co += 3;
+ for (i = 0; i < 3; i++, fp += 3, co++) {
+ copy_v3_v3(*co, fp);
}
-
fp += 3; /* skip alphas */
-
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
-
- while (a--) {
- copy_v3_v3(fp, co);
-
- fp += 4;
- co += 3;
-
- bp++;
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, co++) {
+ copy_v3_v3(*co, fp);
}
}
-
- nu = nu->next;
}
}
+
+ return vertCos;
}
-void BKE_key_convert_from_offset(Object *ob, KeyBlock *kb, float (*ofs)[3])
+/************************* raw coord offsets ************************/
+void BKE_keyblock_update_from_offset(Object *ob, KeyBlock *kb, float (*ofs)[3])
{
int a;
- float *co = (float *)ofs, *fp = kb->data;
+ float *fp = kb->data;
if (ELEM(ob->type, OB_MESH, OB_LATTICE)) {
- for (a = 0; a < kb->totelem; a++, fp += 3, co += 3) {
- add_v3_v3(fp, co);
+ for (a = 0; a < kb->totelem; a++, fp += 3, ofs++) {
+ add_v3_v3(fp, *ofs);
}
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = (Curve *)ob->data;
- Nurb *nu = cu->nurb.first;
+ Nurb *nu;
BezTriple *bezt;
BPoint *bp;
- while (nu) {
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->bezt) {
- int i;
- bezt = nu->bezt;
- a = nu->pntsu;
+ for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
+ int i;
- while (a--) {
- for (i = 0; i < 3; i++) {
- add_v3_v3(fp, co);
- fp += 3; co += 3;
+ for (i = 0; i < 3; i++, fp += 3, ofs++) {
+ add_v3_v3(fp, *ofs);
}
-
fp += 3; /* skip alphas */
-
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
-
- while (a--) {
- add_v3_v3(fp, co);
-
- fp += 4;
- co += 3;
-
- bp++;
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, ofs++) {
+ add_v3_v3(fp, *ofs);
}
}
-
- nu = nu->next;
}
}
}
@@ -2143,3 +2033,22 @@ bool BKE_keyblock_move(Object *ob, int org_index, int new_index)
return true;
}
+
+/**
+ * Check if given keyblock (as index) is used as basis by others in given key.
+ */
+bool BKE_keyblock_is_basis(Key *key, const int index)
+{
+ KeyBlock *kb;
+ int i;
+
+ if (key->type == KEY_RELATIVE) {
+ for (i = 0, kb = key->block.first; kb; i++, kb = kb->next) {
+ if ((i != index) && (kb->relative == index)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 4a413850ec0..93b9c22566d 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -41,7 +41,6 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
-#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -127,6 +126,10 @@ Lamp *BKE_lamp_copy(Lamp *la)
if (la->preview)
lan->preview = BKE_previewimg_copy(la->preview);
+ if (la->id.lib) {
+ BKE_id_lib_local_paths(G.main, la->id.lib, &lan->id);
+ }
+
return lan;
}
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 3f12e3efcc7..fa62308ec53 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -284,6 +284,10 @@ Lattice *BKE_lattice_copy(Lattice *lt)
ltn->editlatt = NULL;
+ if (lt->id.lib) {
+ BKE_id_lib_local_paths(G.main, lt->id.lib, &ltn->id);
+ }
+
return ltn;
}
@@ -575,7 +579,7 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di
/* test for cyclic */
bl = ob->curve_cache->bev.first;
- if (!bl->nr) return 0;
+ if (!bl->nr) return false;
if (bl->poly > -1) cycl = 1;
if (cycl == 0) {
@@ -608,9 +612,9 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di
/* weight - not used but could be added */
}
}
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* for each point, rotate & translate to curve */
@@ -634,9 +638,7 @@ static bool calc_curve_deform(Scene *scene, Object *par, float co[3],
#endif
if (par->curve_cache->path == NULL) {
- return 0; /* happens on append, cyclic dependencies
- * and empty curves
- */
+ return false; /* happens on append, cyclic dependencies and empty curves */
}
/* options */
@@ -718,9 +720,9 @@ static bool calc_curve_deform(Scene *scene, Object *par, float co[3],
if (r_quat)
copy_qt_qt(r_quat, quat);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3],
@@ -939,10 +941,10 @@ bool object_deform_mball(Object *ob, ListBase *dispbase)
(float(*)[3])dl->verts, dl->nr, NULL, 1.0f);
}
- return 1;
+ return true;
}
else {
- return 0;
+ return false;
}
}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index b49eee3ea22..fa4f9c6ed52 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -139,7 +139,7 @@ void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id)
BKE_bpath_traverse_id(bmain, id,
BKE_bpath_relocate_visitor,
BKE_BPATH_TRAVERSE_SKIP_MULTIFILE,
- bpath_user_data);
+ (void *)bpath_user_data);
}
void id_lib_extern(ID *id)
@@ -351,7 +351,7 @@ bool id_copy(ID *id, ID **newid, bool test)
case ID_VF:
return false; /* not implemented */
case ID_TXT:
- if (!test) *newid = (ID *)BKE_text_copy((Text *)id);
+ if (!test) *newid = (ID *)BKE_text_copy(G.main, (Text *)id);
return true;
case ID_SCRIPT:
return false; /* deprecated */
@@ -378,7 +378,8 @@ bool id_copy(ID *id, ID **newid, bool test)
case ID_WM:
return false; /* can't be copied from here */
case ID_GD:
- return false; /* not implemented */
+ if (!test) *newid = (ID *)gpencil_data_duplicate((bGPdata *)id, false);
+ return true;
case ID_MSK:
if (!test) *newid = (ID *)BKE_mask_copy((Mask *)id);
return true;
@@ -1202,7 +1203,7 @@ static ID *is_dupid(ListBase *lb, ID *id, const char *name)
/* do not test alphabetic! */
/* optimized */
if (idtest->name[2] == name[0]) {
- if (strcmp(name, idtest->name + 2) == 0) break;
+ if (STREQ(name, idtest->name + 2)) break;
}
}
}
@@ -1260,7 +1261,7 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name)
if ( (id != idtest) &&
(idtest->lib == NULL) &&
(*name == *(idtest->name + 2)) &&
- (strncmp(name, idtest->name + 2, left_len) == 0) &&
+ STREQLEN(name, idtest->name + 2, left_len) &&
(BLI_split_name_num(leftest, &nrtest, idtest->name + 2, '.') == left_len)
)
{
@@ -1571,7 +1572,7 @@ void test_idbutton(char *name)
ID *idtest;
- lb = which_libbase(G.main, GS(name) );
+ lb = which_libbase(G.main, GS(name));
if (lb == NULL) return;
/* search for id */
@@ -1590,7 +1591,7 @@ void rename_id(ID *id, const char *name)
ListBase *lb;
BLI_strncpy(id->name + 2, name, sizeof(id->name) - 2);
- lb = which_libbase(G.main, GS(id->name) );
+ lb = which_libbase(G.main, GS(id->name));
new_id(lb, id, name);
}
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index bcdaf9b7af0..b97bf0ed9b0 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -53,8 +53,6 @@
#include "BKE_colortools.h"
#include "BKE_animsys.h"
-#include "RNA_access.h"
-
static const char *modifier_name[LS_MODIFIER_NUM] = {
NULL,
"Along Stroke",
@@ -201,8 +199,11 @@ FreestyleLineStyle *BKE_linestyle_copy(FreestyleLineStyle *linestyle)
new_linestyle->dash3 = linestyle->dash3;
new_linestyle->gap3 = linestyle->gap3;
new_linestyle->panel = linestyle->panel;
+ new_linestyle->sort_key = linestyle->sort_key;
+ new_linestyle->integration_type = linestyle->integration_type;
new_linestyle->texstep = linestyle->texstep;
new_linestyle->pr_texture = linestyle->pr_texture;
+ new_linestyle->use_nodes = linestyle->use_nodes;
for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next)
BKE_linestyle_color_modifier_copy(new_linestyle, m);
for (m = (LineStyleModifier *)linestyle->alpha_modifiers.first; m; m = m->next)
@@ -212,6 +213,10 @@ FreestyleLineStyle *BKE_linestyle_copy(FreestyleLineStyle *linestyle)
for (m = (LineStyleModifier *)linestyle->geometry_modifiers.first; m; m = m->next)
BKE_linestyle_geometry_modifier_copy(new_linestyle, m);
+ if (linestyle->id.lib) {
+ BKE_id_lib_local_paths(G.main, linestyle->id.lib, &new_linestyle->id);
+ }
+
return new_linestyle;
}
@@ -278,6 +283,9 @@ LineStyleModifier *BKE_linestyle_color_modifier_add(FreestyleLineStyle *linestyl
LineStyleModifier *m;
m = alloc_color_modifier(name, type);
+ if (UNLIKELY(m == NULL)) {
+ return NULL;
+ }
m->blend = MA_RAMP_BLEND;
switch (type) {
@@ -312,6 +320,9 @@ LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linesty
LineStyleModifier *new_m;
new_m = alloc_color_modifier(m->name, m->type);
+ if (UNLIKELY(new_m == NULL)) {
+ return NULL;
+ }
new_m->influence = m->influence;
new_m->flags = m->flags;
new_m->blend = m->blend;
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 83ad2f1b2d2..83ca6cd8d72 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -50,6 +50,7 @@
#include "DNA_sequence_types.h"
#include "BKE_curve.h"
+#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mask.h"
@@ -59,8 +60,6 @@
#include "BKE_movieclip.h"
#include "BKE_image.h"
-#include "NOD_composite.h"
-
static struct {
ListBase splines;
struct GHash *id_hash;
@@ -857,6 +856,10 @@ Mask *BKE_mask_copy(Mask *mask)
mask_new->id.us++;
}
+ if (mask->id.lib) {
+ BKE_id_lib_local_paths(G.main, mask->id.lib, &mask_new->id);
+ }
+
return mask_new;
}
@@ -1187,11 +1190,12 @@ void BKE_mask_point_parent_matrix_get(MaskSplinePoint *point, float ctime, float
MovieTrackingPlaneTrack *plane_track = BKE_tracking_plane_track_get_named(tracking, ob, parent->sub_parent);
if (plane_track) {
- MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr);
+ float corners[4][2];
float aspx, aspy;
float frame_size[2], H[3][3], mask_from_clip_matrix[3][3], mask_to_clip_matrix[3][3];
- BKE_tracking_homography_between_two_quads(parent->parent_corners_orig, plane_marker->corners, H);
+ BKE_tracking_plane_marker_get_subframe_corners(plane_track, ctime, corners);
+ BKE_tracking_homography_between_two_quads(parent->parent_corners_orig, corners, H);
unit_m3(mask_from_clip_matrix);
@@ -1457,7 +1461,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool d
{
if (found == 1) {
#if 0
- printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes),
+ printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_listbase_count(&masklay->splines_shapes),
masklay_shape_a->frame);
#endif
@@ -1466,7 +1470,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool d
else if (found == 2) {
float w = masklay_shape_b->frame - masklay_shape_a->frame;
#if 0
- printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes),
+ printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_listbase_count(&masklay->splines_shapes),
masklay_shape_a->frame, masklay_shape_b->frame);
#endif
BKE_mask_layer_shape_to_mask_interp(masklay, masklay_shape_a, masklay_shape_b,
@@ -1833,7 +1837,7 @@ static int mask_layer_shape_sort_cb(const void *masklay_shape_a_ptr, const void
void BKE_mask_layer_shape_sort(MaskLayer *masklay)
{
- BLI_sortlist(&masklay->splines_shapes, mask_layer_shape_sort_cb);
+ BLI_listbase_sort(&masklay->splines_shapes, mask_layer_shape_sort_cb);
}
bool BKE_mask_layer_shape_spline_from_index(MaskLayer *masklay, int index,
diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c
index 3ed6148054c..5517fc36bc1 100644
--- a/source/blender/blenkernel/intern/mask_evaluate.c
+++ b/source/blender/blenkernel/intern/mask_evaluate.c
@@ -40,8 +40,6 @@
#include "BLI_math.h"
#include "DNA_mask_types.h"
-#include "DNA_node_types.h"
-#include "DNA_scene_types.h"
#include "BKE_curve.h"
#include "BKE_mask.h"
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 4dc8ed21463..387d093051e 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -572,7 +572,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
unsigned int masklay_index;
MemArena *sf_arena;
- mr_handle->layers_tot = (unsigned int)BLI_countlist(&mask->masklayers);
+ mr_handle->layers_tot = (unsigned int)BLI_listbase_count(&mask->masklayers);
mr_handle->layers = MEM_mallocN(sizeof(MaskRasterLayer) * mr_handle->layers_tot, "MaskRasterLayer");
BLI_rctf_init_minmax(&mr_handle->bounds);
@@ -608,7 +608,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
continue;
}
- tot_splines = (unsigned int)BLI_countlist(&masklay->splines);
+ tot_splines = (unsigned int)BLI_listbase_count(&masklay->splines);
open_spline_ranges = MEM_callocN(sizeof(*open_spline_ranges) * tot_splines, __func__);
BLI_scanfill_begin_arena(&sf_ctx, sf_arena);
@@ -956,7 +956,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
&isect_remvertbase,
&isect_remedgebase)))
{
- unsigned int sf_vert_tot_isect = (unsigned int)BLI_countlist(&sf_ctx.fillvertbase);
+ unsigned int sf_vert_tot_isect = (unsigned int)BLI_listbase_count(&sf_ctx.fillvertbase);
unsigned int i = sf_vert_tot;
face_coords = MEM_reallocN(face_coords, sizeof(float[3]) * (sf_vert_tot + sf_vert_tot_isect));
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index eeca60f7ef4..9b682f101ad 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -116,7 +116,7 @@ void BKE_material_free_ex(Material *ma, bool do_id_user)
MEM_freeN(ma->texpaintslot);
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
}
void init_material(Material *ma)
@@ -252,6 +252,10 @@ Material *BKE_material_copy(Material *ma)
BLI_listbase_clear(&man->gpumaterial);
+ if (ma->id.lib) {
+ BKE_id_lib_local_paths(G.main, ma->id.lib, &man->id);
+ }
+
return man;
}
@@ -681,16 +685,16 @@ Material *give_current_material(Object *ob, short act)
/* if object cannot have material, (totcolp == NULL) */
totcolp = give_totcolp(ob);
if (totcolp == NULL || ob->totcol == 0) return NULL;
-
- if (act < 0) {
- printf("Negative material index!\n");
- }
-
+
/* return NULL for invalid 'act', can happen for mesh face indices */
if (act > ob->totcol)
return NULL;
- else if (act <= 0)
+ else if (act <= 0) {
+ if (act < 0) {
+ printf("Negative material index!\n");
+ }
return NULL;
+ }
if (ob->matbits && ob->matbits[act - 1]) { /* in object */
ma = ob->mat[act - 1];
@@ -1023,7 +1027,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
Group *group;
for (group = G.main->group.first; group; group = group->id.next) {
- if (!group->id.lib && strcmp(group->id.name, ma->group->id.name) == 0) {
+ if (!group->id.lib && STREQ(group->id.name, ma->group->id.name)) {
ma->group = group;
}
}
@@ -1137,28 +1141,28 @@ static bool material_in_nodetree(bNodeTree *ntree, Material *mat)
if (node->id) {
if (GS(node->id->name) == ID_MA) {
if (node->id == (ID *)mat) {
- return 1;
+ return true;
}
}
else if (node->type == NODE_GROUP) {
if (material_in_nodetree((bNodeTree *)node->id, mat)) {
- return 1;
+ return true;
}
}
}
}
- return 0;
+ return false;
}
bool material_in_material(Material *parmat, Material *mat)
{
if (parmat == mat)
- return 1;
+ return true;
else if (parmat->nodetree && parmat->use_nodes)
return material_in_nodetree(parmat->nodetree, mat);
else
- return 0;
+ return false;
}
@@ -1313,6 +1317,26 @@ static bool get_mtex_slot_valid_texpaint(struct MTex *mtex)
mtex->tex->ima);
}
+static bNode *nodetree_uv_node_recursive(bNode *node)
+{
+ bNode *inode;
+ bNodeSocket *sock;
+
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (sock->link) {
+ inode = sock->link->fromnode;
+ if (inode->typeinfo->nclass == NODE_CLASS_INPUT && inode->typeinfo->type == SH_NODE_UVMAP) {
+ return inode;
+ }
+ else {
+ return nodetree_uv_node_recursive(inode);
+ }
+ }
+ }
+
+ return NULL;
+}
+
void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
{
MTex **mtex;
@@ -1320,7 +1344,7 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
short index = 0, i;
bool use_nodes = BKE_scene_use_new_shading_nodes(scene);
- bool is_bi = BKE_scene_uses_blender_internal(scene);
+ bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene);
if (!ma)
return;
@@ -1364,7 +1388,27 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
if (node->typeinfo->nclass == NODE_CLASS_TEXTURE && node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
if (active_node == node)
ma->paint_active_slot = index;
- ma->texpaintslot[index++].ima = (Image *)node->id;
+ ma->texpaintslot[index].ima = (Image *)node->id;
+
+ /* for new renderer, we need to traverse the treeback in search of a UV node */
+ if (use_nodes) {
+ bNode *uvnode = nodetree_uv_node_recursive(node);
+
+ if (uvnode) {
+ NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage;
+ ma->texpaintslot[index].uvname = storage->uv_map;
+ /* set a value to index so UI knows that we have a valid pointer for the mesh */
+ ma->texpaintslot[index].index = 0;
+ }
+ else {
+ /* just invalidate the index here so UV map does not get displayed on the UI */
+ ma->texpaintslot[index].index = -1;
+ }
+ }
+ else {
+ ma->texpaintslot[index].index = -1;
+ }
+ index++;
}
}
}
@@ -1724,7 +1768,7 @@ void paste_matcopybuf(Material *ma)
MEM_freeN(ma->nodetree);
}
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
id = (ma->id);
memcpy(ma, &matcopybuf, sizeof(Material));
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 453c6df6e3b..ce20636233a 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -238,6 +238,10 @@ MetaBall *BKE_mball_copy(MetaBall *mb)
mbn->editelems = NULL;
mbn->lastelem = NULL;
+ if (mb->id.lib) {
+ BKE_id_lib_local_paths(G.main, mb->id.lib, &mbn->id);
+ }
+
return mbn;
}
@@ -464,7 +468,7 @@ bool BKE_mball_is_basis_for(Object *ob1, Object *ob2)
BLI_split_name_num(basis1name, &basis1nr, ob1->id.name + 2, '.');
BLI_split_name_num(basis2name, &basis2nr, ob2->id.name + 2, '.');
- if (!strcmp(basis1name, basis2name)) {
+ if (STREQ(basis1name, basis2name)) {
return BKE_mball_is_basis(ob1);
}
else {
@@ -499,7 +503,7 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object)
/* Object ob has to be in same "group" ... it means, that it has to have
* same base of its name */
- if (strcmp(obname, basisname) == 0) {
+ if (STREQ(obname, basisname)) {
MetaBall *mb = ob->data;
/* Copy properties from selected/edited metaball */
@@ -541,7 +545,7 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
/* object ob has to be in same "group" ... it means, that it has to have same base of its name */
- if (strcmp(obname, basisname) == 0) {
+ if (STREQ(obname, basisname)) {
if (obnr < basisnr) {
basis = ob;
basisnr = obnr;
@@ -909,7 +913,11 @@ static void docube(PROCESS *process, CUBE *cube, MetaBall *mb)
CORNER *c1, *c2;
int i, index = 0, count, indexar[8];
- for (i = 0; i < 8; i++) if (cube->corners[i]->value > 0.0f) index += (1 << i);
+ for (i = 0; i < 8; i++) {
+ if (cube->corners[i]->value > 0.0f) {
+ index += (1 << i);
+ }
+ }
for (polys = cubetable[index]; polys; polys = polys->next) {
INTLIST *edges;
@@ -1671,7 +1679,7 @@ static float init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *sce
int nr;
BLI_split_name_num(name, &nr, bob->id.name + 2, '.');
- if (strcmp(obname, name) == 0) {
+ if (STREQ(obname, name)) {
mb = bob->data;
if (mb->editelems) ml = mb->editelems->first;
@@ -2235,7 +2243,7 @@ static void mball_count(EvaluationContext *eval_ctx, PROCESS *process, Scene *sc
/* object ob has to be in same "group" ... it means, that it has to have
* same base of its name */
- if (strcmp(obname, basisname) == 0) {
+ if (STREQ(obname, basisname)) {
MetaBall *mb = ob->data;
/* if object is in edit mode, then dynamic list of all MetaElems
@@ -2436,10 +2444,10 @@ bool BKE_mball_center_bounds(MetaBall *mb, float r_cent[3])
if (BKE_mball_minmax(mb, min, max)) {
mid_v3_v3v3(r_cent, min, max);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
void BKE_mball_transform(MetaBall *mb, float mat[4][4])
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 2e80379522c..809d2137187 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -414,6 +414,16 @@ void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
me->mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
}
+bool BKE_mesh_has_custom_loop_normals(Mesh *me)
+{
+ if (me->edit_btmesh) {
+ return CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_CUSTOMLOOPNORMAL);
+ }
+ else {
+ return CustomData_has_layer(&me->ldata, CD_CUSTOMLOOPNORMAL);
+ }
+}
+
/* Note: unlinking is called when me->id.us is 0, question remains how
* much unlinking of Library data in Mesh should be done... probably
* we need a more generic method, like the expand() functions in
@@ -562,6 +572,10 @@ Mesh *BKE_mesh_copy_ex(Main *bmain, Mesh *me)
men->key = BKE_key_copy(me->key);
if (men->key) men->key->from = (ID *)men;
+ if (me->id.lib) {
+ BKE_id_lib_local_paths(bmain, me->id.lib, &men->id);
+ }
+
return men;
}
@@ -699,7 +713,7 @@ bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int
}
/* Loop until we do have exactly the same name for all layers! */
- for (i = 1; (strcmp(cdlp->name, cdlu->name) != 0 || (cdlf && strcmp(cdlp->name, cdlf->name) != 0)); i++) {
+ for (i = 1; !STREQ(cdlp->name, cdlu->name) || (cdlf && !STREQ(cdlp->name, cdlf->name)); i++) {
switch (i % step) {
case 0:
BLI_strncpy(cdlp->name, cdlu->name, sizeof(cdlp->name));
@@ -1487,7 +1501,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use
}
else {
me = BKE_mesh_add(G.main, "Mesh");
- DM_to_mesh(dm, me, ob, CD_MASK_MESH);
+ DM_to_mesh(dm, me, ob, CD_MASK_MESH, false);
}
me->totcol = cu->totcol;
@@ -2242,8 +2256,7 @@ Mesh *BKE_mesh_new_from_object(
dm = mesh_create_derived_view(sce, ob, mask);
tmpmesh = BKE_mesh_add(bmain, "Mesh");
- DM_to_mesh(dm, tmpmesh, ob, mask);
- dm->release(dm);
+ DM_to_mesh(dm, tmpmesh, ob, mask, true);
}
/* BKE_mesh_add/copy gives us a user count we don't need */
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 4c9e44682c3..40a09eba658 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -39,6 +39,7 @@
#include "BLI_utildefines.h"
#include "BLI_memarena.h"
+#include "BLI_mempool.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
#include "BLI_bitmap.h"
@@ -46,6 +47,8 @@
#include "BLI_linklist.h"
#include "BLI_linklist_stack.h"
#include "BLI_alloca.h"
+#include "BLI_stack.h"
+#include "BLI_task.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
@@ -58,8 +61,8 @@
// #define DEBUG_TIME
+#include "PIL_time.h"
#ifdef DEBUG_TIME
-# include "PIL_time.h"
# include "PIL_time_utildefines.h"
#endif
@@ -316,19 +319,783 @@ void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces,
MEM_freeN(fnors);
}
-/**
- * Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
- * Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry (splitting edges).
+void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoops)
+{
+ if (!(lnors_spacearr->lspacearr && lnors_spacearr->loops_pool)) {
+ MemArena *mem;
+
+ if (!lnors_spacearr->mem) {
+ lnors_spacearr->mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ }
+ mem = lnors_spacearr->mem;
+ lnors_spacearr->lspacearr = BLI_memarena_calloc(mem, sizeof(MLoopNorSpace *) * (size_t)numLoops);
+ lnors_spacearr->loops_pool = BLI_memarena_alloc(mem, sizeof(LinkNode) * (size_t)numLoops);
+ }
+}
+
+void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr)
+{
+ BLI_memarena_clear(lnors_spacearr->mem);
+ lnors_spacearr->lspacearr = NULL;
+ lnors_spacearr->loops_pool = NULL;
+}
+
+void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr)
+{
+ BLI_memarena_free(lnors_spacearr->mem);
+ lnors_spacearr->lspacearr = NULL;
+ lnors_spacearr->loops_pool = NULL;
+ lnors_spacearr->mem = NULL;
+}
+
+MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr)
+{
+ return BLI_memarena_calloc(lnors_spacearr->mem, sizeof(MLoopNorSpace));
+}
+
+/* This threshold is a bit touchy (usual float precision issue), this value seems OK. */
+#define LNOR_SPACE_TRIGO_THRESHOLD (1.0f - 1e-6f)
+
+/* Should only be called once.
+ * Beware, this modifies ref_vec and other_vec in place!
+ * In case no valid space can be generated, ref_alpha and ref_beta are set to zero (which means 'use auto lnors').
*/
-void BKE_mesh_normals_loop_split(MVert *mverts, const int UNUSED(numVerts), MEdge *medges, const int numEdges,
- MLoop *mloops, float (*r_loopnors)[3], const int numLoops,
- MPoly *mpolys, float (*polynors)[3], const int numPolys, float split_angle)
+void BKE_lnor_space_define(MLoopNorSpace *lnor_space, const float lnor[3],
+ float vec_ref[3], float vec_other[3], BLI_Stack *edge_vectors)
+{
+ const float pi2 = (float)M_PI * 2.0f;
+ float tvec[3], dtp;
+ const float dtp_ref = dot_v3v3(vec_ref, lnor);
+ const float dtp_other = dot_v3v3(vec_other, lnor);
+
+ if (UNLIKELY(fabsf(dtp_ref) >= LNOR_SPACE_TRIGO_THRESHOLD || fabsf(dtp_other) >= LNOR_SPACE_TRIGO_THRESHOLD)) {
+ /* If vec_ref or vec_other are too much aligned with lnor, we can't build lnor space,
+ * tag it as invalid and abort. */
+ lnor_space->ref_alpha = lnor_space->ref_beta = 0.0f;
+ return;
+ }
+
+ copy_v3_v3(lnor_space->vec_lnor, lnor);
+
+ /* Compute ref alpha, average angle of all available edge vectors to lnor. */
+ if (edge_vectors) {
+ float alpha = 0.0f;
+ int nbr = 0;
+ while (!BLI_stack_is_empty(edge_vectors)) {
+ const float *vec = BLI_stack_peek(edge_vectors);
+ alpha += saacosf(dot_v3v3(vec, lnor));
+ BLI_stack_discard(edge_vectors);
+ nbr++;
+ }
+ BLI_assert(nbr > 2); /* This piece of code shall only be called for more than one loop... */
+ lnor_space->ref_alpha = alpha / (float)nbr;
+ }
+ else {
+ lnor_space->ref_alpha = (saacosf(dot_v3v3(vec_ref, lnor)) + saacosf(dot_v3v3(vec_other, lnor))) / 2.0f;
+ }
+
+ /* Project vec_ref on lnor's ortho plane. */
+ mul_v3_v3fl(tvec, lnor, dtp_ref);
+ sub_v3_v3(vec_ref, tvec);
+ normalize_v3_v3(lnor_space->vec_ref, vec_ref);
+
+ cross_v3_v3v3(tvec, lnor, lnor_space->vec_ref);
+ normalize_v3_v3(lnor_space->vec_ortho, tvec);
+
+ /* Project vec_other on lnor's ortho plane. */
+ mul_v3_v3fl(tvec, lnor, dtp_other);
+ sub_v3_v3(vec_other, tvec);
+ normalize_v3(vec_other);
+
+ /* Beta is angle between ref_vec and other_vec, around lnor. */
+ dtp = dot_v3v3(lnor_space->vec_ref, vec_other);
+ if (LIKELY(dtp < LNOR_SPACE_TRIGO_THRESHOLD)) {
+ const float beta = saacos(dtp);
+ lnor_space->ref_beta = (dot_v3v3(lnor_space->vec_ortho, vec_other) < 0.0f) ? pi2 - beta : beta;
+ }
+ else {
+ lnor_space->ref_beta = pi2;
+ }
+}
+
+void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, const int ml_index,
+ const bool do_add_loop)
+{
+ lnors_spacearr->lspacearr[ml_index] = lnor_space;
+ if (do_add_loop) {
+ BLI_linklist_prepend_nlink(&lnor_space->loops, SET_INT_IN_POINTER(ml_index), &lnors_spacearr->loops_pool[ml_index]);
+ }
+}
+
+MINLINE float unit_short_to_float(const short val)
+{
+ return (float)val / (float)SHRT_MAX;
+}
+
+MINLINE short unit_float_to_short(const float val)
+{
+ /* Rounding... */
+ return (short)floorf(val * (float)SHRT_MAX + 0.5f);
+}
+
+void BKE_lnor_space_custom_data_to_normal(MLoopNorSpace *lnor_space, const short clnor_data[2], float r_custom_lnor[3])
+{
+ /* NOP custom normal data or invalid lnor space, return. */
+ if (clnor_data[0] == 0 || lnor_space->ref_alpha == 0.0f || lnor_space->ref_beta == 0.0f) {
+ copy_v3_v3(r_custom_lnor, lnor_space->vec_lnor);
+ return;
+ }
+
+ {
+ /* TODO Check whether using sincosf() gives any noticeable benefit
+ * (could not even get it working under linux though)! */
+ const float pi2 = (float)(M_PI * 2.0);
+ const float alphafac = unit_short_to_float(clnor_data[0]);
+ const float alpha = (alphafac > 0.0f ? lnor_space->ref_alpha : pi2 - lnor_space->ref_alpha) * alphafac;
+ const float betafac = unit_short_to_float(clnor_data[1]);
+
+ mul_v3_v3fl(r_custom_lnor, lnor_space->vec_lnor, cosf(alpha));
+
+ if (betafac == 0.0f) {
+ madd_v3_v3fl(r_custom_lnor, lnor_space->vec_ref, sinf(alpha));
+ }
+ else {
+ const float sinalpha = sinf(alpha);
+ const float beta = (betafac > 0.0f ? lnor_space->ref_beta : pi2 - lnor_space->ref_beta) * betafac;
+ madd_v3_v3fl(r_custom_lnor, lnor_space->vec_ref, sinalpha * cosf(beta));
+ madd_v3_v3fl(r_custom_lnor, lnor_space->vec_ortho, sinalpha * sinf(beta));
+ }
+ }
+}
+
+void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2])
{
+ /* We use null vector as NOP custom normal (can be simpler than giving autocomputed lnor...). */
+ if (is_zero_v3(custom_lnor) || compare_v3v3(lnor_space->vec_lnor, custom_lnor, 1e-4f)) {
+ r_clnor_data[0] = r_clnor_data[1] = 0;
+ return;
+ }
+
+ {
+ const float pi2 = (float)(M_PI * 2.0);
+ const float cos_alpha = dot_v3v3(lnor_space->vec_lnor, custom_lnor);
+ float vec[3], cos_beta;
+ float alpha;
+
+ alpha = saacosf(cos_alpha);
+ if (alpha > lnor_space->ref_alpha) {
+ /* Note we could stick to [0, pi] range here, but makes decoding more complex, not worth it. */
+ r_clnor_data[0] = unit_float_to_short(-(pi2 - alpha) / (pi2 - lnor_space->ref_alpha));
+ }
+ else {
+ r_clnor_data[0] = unit_float_to_short(alpha / lnor_space->ref_alpha);
+ }
+
+ /* Project custom lnor on (vec_ref, vec_ortho) plane. */
+ mul_v3_v3fl(vec, lnor_space->vec_lnor, -cos_alpha);
+ add_v3_v3(vec, custom_lnor);
+ normalize_v3(vec);
+
+ cos_beta = dot_v3v3(lnor_space->vec_ref, vec);
+
+ if (cos_beta < LNOR_SPACE_TRIGO_THRESHOLD) {
+ float beta = saacosf(cos_beta);
+ if (dot_v3v3(lnor_space->vec_ortho, vec) < 0.0f) {
+ beta = pi2 - beta;
+ }
+
+ if (beta > lnor_space->ref_beta) {
+ r_clnor_data[1] = unit_float_to_short(-(pi2 - beta) / (pi2 - lnor_space->ref_beta));
+ }
+ else {
+ r_clnor_data[1] = unit_float_to_short(beta / lnor_space->ref_beta);
+ }
+ }
+ else {
+ r_clnor_data[1] = 0;
+ }
+ }
+}
+
+#define LOOP_SPLIT_TASK_BLOCK_SIZE 1024
+
+typedef struct LoopSplitTaskData {
+ /* Specific to each instance (each task). */
+ MLoopNorSpace *lnor_space; /* We have to create those outside of tasks, since afaik memarena is not threadsafe. */
+ float (*lnor)[3];
+ const MLoop *ml_curr;
+ const MLoop *ml_prev;
+ int ml_curr_index;
+ int ml_prev_index;
+ const int *e2l_prev; /* Also used a flag to switch between single or fan process! */
+ int mp_index;
+
+ /* This one is special, it's owned and managed by worker tasks, avoid to have to create it for each fan! */
+ BLI_Stack *edge_vectors;
+
+ char pad_c;
+} LoopSplitTaskData;
+
+typedef struct LoopSplitTaskDataCommon {
+ /* Read/write.
+ * Note we do not need to protect it, though, since two different tasks will *always* affect different
+ * elements in the arrays. */
+ MLoopNorSpaceArray *lnors_spacearr;
+ BLI_bitmap *sharp_verts;
+ float (*loopnors)[3];
+ short (*clnors_data)[2];
+
+ /* Read-only. */
+ const MVert *mverts;
+ const MEdge *medges;
+ const MLoop *mloops;
+ const MPoly *mpolys;
+ const int (*edge_to_loops)[2];
+ const int *loop_to_poly;
+ const float (*polynors)[3];
+
+ int numPolys;
+
+ /* ***** Workers communication. ***** */
+ ThreadQueue *task_queue;
+
+} LoopSplitTaskDataCommon;
+
#define INDEX_UNSET INT_MIN
#define INDEX_INVALID -1
/* See comment about edge_to_loops below. */
#define IS_EDGE_SHARP(_e2l) (ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID))
+static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
+{
+ MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
+ short (*clnors_data)[2] = common_data->clnors_data;
+
+ const MVert *mverts = common_data->mverts;
+ const MEdge *medges = common_data->medges;
+ const float (*polynors)[3] = common_data->polynors;
+
+ MLoopNorSpace *lnor_space = data->lnor_space;
+ float (*lnor)[3] = data->lnor;
+ const MLoop *ml_curr = data->ml_curr;
+ const MLoop *ml_prev = data->ml_prev;
+ const int ml_curr_index = data->ml_curr_index;
+#if 0 /* Not needed for 'single' loop. */
+ const int ml_prev_index = data->ml_prev_index;
+ const int *e2l_prev = data->e2l_prev;
+#endif
+ const int mp_index = data->mp_index;
+
+ /* Simple case (both edges around that vertex are sharp in current polygon),
+ * this loop just takes its poly normal.
+ */
+ copy_v3_v3(*lnor, polynors[mp_index]);
+
+ /* printf("BASIC: handling loop %d / edge %d / vert %d\n", ml_curr_index, ml_curr->e, ml_curr->v); */
+
+ /* If needed, generate this (simple!) lnor space. */
+ if (lnors_spacearr) {
+ float vec_curr[3], vec_prev[3];
+
+ const unsigned int mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */
+ const MVert *mv_pivot = &mverts[mv_pivot_index];
+ const MEdge *me_curr = &medges[ml_curr->e];
+ const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &mverts[me_curr->v2] : &mverts[me_curr->v1];
+ const MEdge *me_prev = &medges[ml_prev->e];
+ const MVert *mv_3 = (me_prev->v1 == mv_pivot_index) ? &mverts[me_prev->v2] : &mverts[me_prev->v1];
+
+ sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co);
+ normalize_v3(vec_curr);
+ sub_v3_v3v3(vec_prev, mv_3->co, mv_pivot->co);
+ normalize_v3(vec_prev);
+
+ BKE_lnor_space_define(lnor_space, *lnor, vec_curr, vec_prev, NULL);
+ /* We know there is only one loop in this space, no need to create a linklist in this case... */
+ BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, ml_curr_index, false);
+
+ if (clnors_data) {
+ BKE_lnor_space_custom_data_to_normal(lnor_space, clnors_data[ml_curr_index], *lnor);
+ }
+ }
+}
+
+static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
+{
+ MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
+ float (*loopnors)[3] = common_data->loopnors;
+ short (*clnors_data)[2] = common_data->clnors_data;
+
+ const MVert *mverts = common_data->mverts;
+ const MEdge *medges = common_data->medges;
+ const MLoop *mloops = common_data->mloops;
+ const MPoly *mpolys = common_data->mpolys;
+ const int (*edge_to_loops)[2] = common_data->edge_to_loops;
+ const int *loop_to_poly = common_data->loop_to_poly;
+ const float (*polynors)[3] = common_data->polynors;
+
+ MLoopNorSpace *lnor_space = data->lnor_space;
+#if 0 /* Not needed for 'fan' loops. */
+ float (*lnor)[3] = data->lnor;
+#endif
+ const MLoop *ml_curr = data->ml_curr;
+ const MLoop *ml_prev = data->ml_prev;
+ const int ml_curr_index = data->ml_curr_index;
+ const int ml_prev_index = data->ml_prev_index;
+ const int mp_index = data->mp_index;
+ const int *e2l_prev = data->e2l_prev;
+
+ BLI_Stack *edge_vectors = data->edge_vectors;
+
+ /* Gah... We have to fan around current vertex, until we find the other non-smooth edge,
+ * and accumulate face normals into the vertex!
+ * Note in case this vertex has only one sharp edges, this is a waste because the normal is the same as
+ * the vertex normal, but I do not see any easy way to detect that (would need to count number
+ * of sharp edges per vertex, I doubt the additional memory usage would be worth it, especially as
+ * it should not be a common case in real-life meshes anyway).
+ */
+ const unsigned int mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */
+ const MVert *mv_pivot = &mverts[mv_pivot_index];
+ const MEdge *me_org = &medges[ml_curr->e]; /* ml_curr would be mlfan_prev if we needed that one */
+ const int *e2lfan_curr;
+ float vec_curr[3], vec_prev[3], vec_org[3];
+ const MLoop *mlfan_curr, *mlfan_next;
+ const MPoly *mpfan_next;
+ float lnor[3] = {0.0f, 0.0f, 0.0f};
+ /* mlfan_vert_index: the loop of our current edge might not be the loop of our current vertex! */
+ int mlfan_curr_index, mlfan_vert_index, mpfan_curr_index;
+
+ /* We validate clnors data on the fly - cheapest way to do! */
+ int clnors_avg[2] = {0, 0};
+ short (*clnor_ref)[2] = NULL;
+ int clnors_nbr = 0;
+ bool clnors_invalid = false;
+
+ /* Temp loop normal stack. */
+ BLI_SMALLSTACK_DECLARE(normal, float *);
+ /* Temp clnors stack. */
+ BLI_SMALLSTACK_DECLARE(clnors, short *);
+
+ e2lfan_curr = e2l_prev;
+ mlfan_curr = ml_prev;
+ mlfan_curr_index = ml_prev_index;
+ mlfan_vert_index = ml_curr_index;
+ mpfan_curr_index = mp_index;
+
+ BLI_assert(mlfan_curr_index >= 0);
+ BLI_assert(mlfan_vert_index >= 0);
+ BLI_assert(mpfan_curr_index >= 0);
+
+ /* Only need to compute previous edge's vector once, then we can just reuse old current one! */
+ {
+ const MVert *mv_2 = (me_org->v1 == mv_pivot_index) ? &mverts[me_org->v2] : &mverts[me_org->v1];
+
+ sub_v3_v3v3(vec_org, mv_2->co, mv_pivot->co);
+ normalize_v3(vec_org);
+ copy_v3_v3(vec_prev, vec_org);
+
+ if (lnors_spacearr) {
+ BLI_stack_push(edge_vectors, vec_org);
+ }
+ }
+
+ /* printf("FAN: vert %d, start edge %d\n", mv_pivot_index, ml_curr->e); */
+
+ while (true) {
+ const MEdge *me_curr = &medges[mlfan_curr->e];
+ /* Compute edge vectors.
+ * NOTE: We could pre-compute those into an array, in the first iteration, instead of computing them
+ * twice (or more) here. However, time gained is not worth memory and time lost,
+ * given the fact that this code should not be called that much in real-life meshes...
+ */
+ {
+ const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &mverts[me_curr->v2] : &mverts[me_curr->v1];
+
+ sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co);
+ normalize_v3(vec_curr);
+ }
+
+ /* printf("\thandling edge %d / loop %d\n", mlfan_curr->e, mlfan_curr_index); */
+
+ {
+ /* Code similar to accumulate_vertex_normals_poly. */
+ /* Calculate angle between the two poly edges incident on this vertex. */
+ const float fac = saacos(dot_v3v3(vec_curr, vec_prev));
+ /* Accumulate */
+ madd_v3_v3fl(lnor, polynors[mpfan_curr_index], fac);
+
+ if (clnors_data) {
+ /* Accumulate all clnors, if they are not all equal we have to fix that! */
+ short (*clnor)[2] = &clnors_data[mlfan_vert_index];
+ if (clnors_nbr) {
+ clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
+ }
+ else {
+ clnor_ref = clnor;
+ }
+ clnors_avg[0] += (*clnor)[0];
+ clnors_avg[1] += (*clnor)[1];
+ clnors_nbr++;
+ /* We store here a pointer to all custom lnors processed. */
+ BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor);
+ }
+ }
+
+ /* We store here a pointer to all loop-normals processed. */
+ BLI_SMALLSTACK_PUSH(normal, (float *)(loopnors[mlfan_vert_index]));
+
+ if (lnors_spacearr) {
+ /* Assign current lnor space to current 'vertex' loop. */
+ BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, mlfan_vert_index, true);
+ if (me_curr != me_org) {
+ /* We store here all edges-normalized vectors processed. */
+ BLI_stack_push(edge_vectors, vec_curr);
+ }
+ }
+
+ if (IS_EDGE_SHARP(e2lfan_curr) || (me_curr == me_org)) {
+ /* Current edge is sharp and we have finished with this fan of faces around this vert,
+ * or this vert is smooth, and we have completed a full turn around it.
+ */
+ /* printf("FAN: Finished!\n"); */
+ break;
+ }
+
+ copy_v3_v3(vec_prev, vec_curr);
+
+ /* Warning! This is rather complex!
+ * We have to find our next edge around the vertex (fan mode).
+ * First we find the next loop, which is either previous or next to mlfan_curr_index, depending
+ * whether both loops using current edge are in the same direction or not, and whether
+ * mlfan_curr_index actually uses the vertex we are fanning around!
+ * mlfan_curr_index is the index of mlfan_next here, and mlfan_next is not the real next one
+ * (i.e. not the future mlfan_curr)...
+ */
+ mlfan_curr_index = (e2lfan_curr[0] == mlfan_curr_index) ? e2lfan_curr[1] : e2lfan_curr[0];
+ mpfan_curr_index = loop_to_poly[mlfan_curr_index];
+
+ BLI_assert(mlfan_curr_index >= 0);
+ BLI_assert(mpfan_curr_index >= 0);
+
+ mlfan_next = &mloops[mlfan_curr_index];
+ mpfan_next = &mpolys[mpfan_curr_index];
+ if ((mlfan_curr->v == mlfan_next->v && mlfan_curr->v == mv_pivot_index) ||
+ (mlfan_curr->v != mlfan_next->v && mlfan_curr->v != mv_pivot_index))
+ {
+ /* We need the previous loop, but current one is our vertex's loop. */
+ mlfan_vert_index = mlfan_curr_index;
+ if (--mlfan_curr_index < mpfan_next->loopstart) {
+ mlfan_curr_index = mpfan_next->loopstart + mpfan_next->totloop - 1;
+ }
+ }
+ else {
+ /* We need the next loop, which is also our vertex's loop. */
+ if (++mlfan_curr_index >= mpfan_next->loopstart + mpfan_next->totloop) {
+ mlfan_curr_index = mpfan_next->loopstart;
+ }
+ mlfan_vert_index = mlfan_curr_index;
+ }
+ mlfan_curr = &mloops[mlfan_curr_index];
+ /* And now we are back in sync, mlfan_curr_index is the index of mlfan_curr! Pff! */
+
+ e2lfan_curr = edge_to_loops[mlfan_curr->e];
+ }
+
+ {
+ float lnor_len = normalize_v3(lnor);
+
+ /* If we are generating lnor spacearr, we can now define the one for this fan,
+ * and optionally compute final lnor from custom data too!
+ */
+ if (lnors_spacearr) {
+ if (UNLIKELY(lnor_len == 0.0f)) {
+ /* Use vertex normal as fallback! */
+ copy_v3_v3(lnor, loopnors[mlfan_vert_index]);
+ lnor_len = 1.0f;
+ }
+
+ BKE_lnor_space_define(lnor_space, lnor, vec_org, vec_curr, edge_vectors);
+
+ if (clnors_data) {
+ if (clnors_invalid) {
+ short *clnor;
+
+ clnors_avg[0] /= clnors_nbr;
+ clnors_avg[1] /= clnors_nbr;
+ /* Fix/update all clnors of this fan with computed average value. */
+ printf("Invalid clnors in this fan!\n");
+ while ((clnor = BLI_SMALLSTACK_POP(clnors))) {
+ //print_v2("org clnor", clnor);
+ clnor[0] = (short)clnors_avg[0];
+ clnor[1] = (short)clnors_avg[1];
+ }
+ //print_v2("new clnors", clnors_avg);
+ }
+ /* Extra bonus: since smallstack is local to this func, no more need to empty it at all cost! */
+
+ BKE_lnor_space_custom_data_to_normal(lnor_space, *clnor_ref, lnor);
+ }
+ }
+
+ /* In case we get a zero normal here, just use vertex normal already set! */
+ if (LIKELY(lnor_len != 0.0f)) {
+ /* Copy back the final computed normal into all related loop-normals. */
+ float *nor;
+
+ while ((nor = BLI_SMALLSTACK_POP(normal))) {
+ copy_v3_v3(nor, lnor);
+ }
+ }
+ /* Extra bonus: since smallstack is local to this func, no more need to empty it at all cost! */
+ }
+}
+
+static void loop_split_worker_do(
+ LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data, BLI_Stack *edge_vectors)
+{
+ BLI_assert(data->ml_curr);
+ if (data->e2l_prev) {
+ BLI_assert((edge_vectors == NULL) || BLI_stack_is_empty(edge_vectors));
+ data->edge_vectors = edge_vectors;
+ split_loop_nor_fan_do(common_data, data);
+ }
+ else {
+ /* No need for edge_vectors for 'single' case! */
+ split_loop_nor_single_do(common_data, data);
+ }
+}
+
+static void loop_split_worker(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(threadid))
+{
+ LoopSplitTaskDataCommon *common_data = taskdata;
+ LoopSplitTaskData *data_buff;
+
+ /* Temp edge vectors stack, only used when computing lnor spacearr. */
+ BLI_Stack *edge_vectors = common_data->lnors_spacearr ? BLI_stack_new(sizeof(float[3]), __func__) : NULL;
+
+#ifdef DEBUG_TIME
+ TIMEIT_START(loop_split_worker);
+#endif
+
+ while ((data_buff = BLI_thread_queue_pop(common_data->task_queue))) {
+ LoopSplitTaskData *data = data_buff;
+ int i;
+
+ for (i = 0; i < LOOP_SPLIT_TASK_BLOCK_SIZE; i++, data++) {
+ /* A NULL ml_curr is used to tag ended data! */
+ if (data->ml_curr == NULL) {
+ break;
+ }
+ loop_split_worker_do(common_data, data, edge_vectors);
+ }
+
+ MEM_freeN(data_buff);
+ }
+
+ if (edge_vectors) {
+ BLI_stack_free(edge_vectors);
+ }
+
+#ifdef DEBUG_TIME
+ TIMEIT_END(loop_split_worker);
+#endif
+}
+
+/* Note we use data_buff to detect whether we are in threaded context or not, in later case it is NULL. */
+static void loop_split_generator_do(LoopSplitTaskDataCommon *common_data, const bool threaded)
+{
+ MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr;
+ BLI_bitmap *sharp_verts = common_data->sharp_verts;
+ float (*loopnors)[3] = common_data->loopnors;
+
+ const MLoop *mloops = common_data->mloops;
+ const MPoly *mpolys = common_data->mpolys;
+ const int (*edge_to_loops)[2] = common_data->edge_to_loops;
+ const int numPolys = common_data->numPolys;
+
+ const MPoly *mp;
+ int mp_index;
+
+ LoopSplitTaskData *data, *data_buff = NULL, data_mem;
+ int data_idx = 0;
+
+ /* Temp edge vectors stack, only used when computing lnor spacearr (and we are not multi-threading). */
+ BLI_Stack *edge_vectors = (lnors_spacearr && !data_buff) ? BLI_stack_new(sizeof(float[3]), __func__) : NULL;
+
+#ifdef DEBUG_TIME
+ TIMEIT_START(loop_split_generator);
+#endif
+
+ if (!threaded) {
+ memset(&data_mem, 0, sizeof(data_mem));
+ data = &data_mem;
+ }
+
+ /* We now know edges that can be smoothed (with their vector, and their two loops), and edges that will be hard!
+ * Now, time to generate the normals.
+ */
+ for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
+ const MLoop *ml_curr, *ml_prev;
+ float (*lnors)[3];
+ const int ml_last_index = (mp->loopstart + mp->totloop) - 1;
+ int ml_curr_index = mp->loopstart;
+ int ml_prev_index = ml_last_index;
+
+ ml_curr = &mloops[ml_curr_index];
+ ml_prev = &mloops[ml_prev_index];
+ lnors = &loopnors[ml_curr_index];
+
+ for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++, lnors++) {
+ const int *e2l_curr = edge_to_loops[ml_curr->e];
+ const int *e2l_prev = edge_to_loops[ml_prev->e];
+
+ if (!IS_EDGE_SHARP(e2l_curr) && (!lnors_spacearr || BLI_BITMAP_TEST_BOOL(sharp_verts, ml_curr->v))) {
+ /* A smooth edge, and we are not generating lnor_spacearr, or the related vertex is sharp.
+ * We skip it because it is either:
+ * - in the middle of a 'smooth fan' already computed (or that will be as soon as we hit
+ * one of its ends, i.e. one of its two sharp edges), or...
+ * - the related vertex is a "full smooth" one, in which case pre-populated normals from vertex
+ * are just fine (or it has already be handled in a previous loop in case of needed lnors spacearr)!
+ */
+ /* printf("Skipping loop %d / edge %d / vert %d(%d)\n", ml_curr_index, ml_curr->e, ml_curr->v, sharp_verts[ml_curr->v]); */
+ }
+ else {
+ if (threaded) {
+ if (data_idx == 0) {
+ data_buff = MEM_callocN(sizeof(*data_buff) * LOOP_SPLIT_TASK_BLOCK_SIZE, __func__);
+ }
+ data = &data_buff[data_idx];
+ }
+
+ if (IS_EDGE_SHARP(e2l_curr) && IS_EDGE_SHARP(e2l_prev)) {
+ data->lnor = lnors;
+ data->ml_curr = ml_curr;
+ data->ml_prev = ml_prev;
+ data->ml_curr_index = ml_curr_index;
+#if 0 /* Not needed for 'single' loop. */
+ data->ml_prev_index = ml_prev_index;
+ data->e2l_prev = NULL; /* Tag as 'single' task. */
+#endif
+ data->mp_index = mp_index;
+ if (lnors_spacearr) {
+ data->lnor_space = BKE_lnor_space_create(lnors_spacearr);
+ }
+ }
+ /* We *do not need* to check/tag loops as already computed!
+ * Due to the fact a loop only links to one of its two edges, a same fan *will never be walked
+ * more than once!*
+ * Since we consider edges having neighbor polys with inverted (flipped) normals as sharp, we are sure
+ * that no fan will be skipped, even only considering the case (sharp curr_edge, smooth prev_edge),
+ * and not the alternative (smooth curr_edge, sharp prev_edge).
+ * All this due/thanks to link between normals and loop ordering (i.e. winding).
+ */
+ else {
+#if 0 /* Not needed for 'fan' loops. */
+ data->lnor = lnors;
+#endif
+ data->ml_curr = ml_curr;
+ data->ml_prev = ml_prev;
+ data->ml_curr_index = ml_curr_index;
+ data->ml_prev_index = ml_prev_index;
+ data->e2l_prev = e2l_prev; /* Also tag as 'fan' task. */
+ data->mp_index = mp_index;
+ if (lnors_spacearr) {
+ data->lnor_space = BKE_lnor_space_create(lnors_spacearr);
+ /* Tag related vertex as sharp, to avoid fanning around it again (in case it was a smooth one).
+ * This *has* to be done outside of workers tasks! */
+ BLI_BITMAP_ENABLE(sharp_verts, ml_curr->v);
+ }
+ }
+
+ if (threaded) {
+ data_idx++;
+ if (data_idx == LOOP_SPLIT_TASK_BLOCK_SIZE) {
+ BLI_thread_queue_push(common_data->task_queue, data_buff);
+ data_idx = 0;
+ }
+ }
+ else {
+ loop_split_worker_do(common_data, data, edge_vectors);
+ memset(data, 0, sizeof(data_mem));
+ }
+ }
+
+ ml_prev = ml_curr;
+ ml_prev_index = ml_curr_index;
+ }
+ }
+
+ if (threaded) {
+ /* Last block of data... Since it is calloc'ed and we use first NULL item as stopper, everything is fine. */
+ if (LIKELY(data_idx)) {
+ BLI_thread_queue_push(common_data->task_queue, data_buff);
+ }
+
+ /* This will signal all other worker threads to wake up and finish! */
+ BLI_thread_queue_nowait(common_data->task_queue);
+ }
+
+ if (edge_vectors) {
+ BLI_stack_free(edge_vectors);
+ }
+
+#ifdef DEBUG_TIME
+ TIMEIT_END(loop_split_generator);
+#endif
+}
+
+static void loop_split_generator(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(threadid))
+{
+ LoopSplitTaskDataCommon *common_data = taskdata;
+
+ loop_split_generator_do(common_data, true);
+}
+
+/**
+ * Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
+ * Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry (splitting edges).
+ */
+void BKE_mesh_normals_loop_split(
+ MVert *mverts, const int numVerts, MEdge *medges, const int numEdges,
+ MLoop *mloops, float (*r_loopnors)[3], const int numLoops,
+ MPoly *mpolys, const float (*polynors)[3], const int numPolys,
+ const bool use_split_normals, float split_angle,
+ MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], int *r_loop_to_poly)
+{
+
+ /* For now this is not supported. If we do not use split normals, we do not generate anything fancy! */
+ BLI_assert(use_split_normals || !(r_lnors_spacearr));
+
+ if (!use_split_normals) {
+ /* In this case, we simply fill lnors with vnors (or fnors for flat faces), quite simple!
+ * Note this is done here to keep some logic and consistency in this quite complex code,
+ * since we may want to use lnors even when mesh's 'autosmooth' is disabled (see e.g. mesh mapping code).
+ * As usual, we could handle that on case-by-case basis, but simpler to keep it well confined here.
+ */
+ int mp_index;
+
+ for (mp_index = 0; mp_index < numPolys; mp_index++) {
+ MPoly *mp = &mpolys[mp_index];
+ int ml_index = mp->loopstart;
+ const int ml_index_end = ml_index + mp->totloop;
+ const bool is_poly_flat = ((mp->flag & ME_SMOOTH) == 0);
+
+ for (; ml_index < ml_index_end; ml_index++) {
+ if (r_loop_to_poly) {
+ r_loop_to_poly[ml_index] = mp_index;
+ }
+ if (is_poly_flat) {
+ copy_v3_v3(r_loopnors[ml_index], polynors[mp_index]);
+ }
+ else {
+ normal_short_to_float_v3(r_loopnors[ml_index], mverts[mloops[ml_index].v].no);
+ }
+ }
+ }
+ return;
+ }
+
+ {
+
/* Mapping edge -> loops.
* If that edge is used by more than two loops (polys), it is always sharp (and tagged as such, see below).
* We also use the second loop index as a kind of flag: smooth edge: > 0,
@@ -341,21 +1108,39 @@ void BKE_mesh_normals_loop_split(MVert *mverts, const int UNUSED(numVerts), MEdg
int (*edge_to_loops)[2] = MEM_callocN(sizeof(int[2]) * (size_t)numEdges, __func__);
/* Simple mapping from a loop to its polygon index. */
- int *loop_to_poly = MEM_mallocN(sizeof(int) * (size_t)numLoops, __func__);
+ int *loop_to_poly = r_loop_to_poly ? r_loop_to_poly : MEM_mallocN(sizeof(int) * (size_t)numLoops, __func__);
MPoly *mp;
- int mp_index;
- const bool check_angle = (split_angle < (float)M_PI);
+ int mp_index, me_index;
+ bool check_angle = (split_angle < (float)M_PI);
+ int i;
- /* Temp normal stack. */
- BLI_SMALLSTACK_DECLARE(normal, float *);
+ BLI_bitmap *sharp_verts = NULL;
+ MLoopNorSpaceArray _lnors_spacearr = {NULL};
+
+ LoopSplitTaskDataCommon common_data = {NULL};
#ifdef DEBUG_TIME
TIMEIT_START(BKE_mesh_normals_loop_split);
#endif
if (check_angle) {
- split_angle = cosf(split_angle);
+ /* When using custom loop normals, disable the angle feature! */
+ if (clnors_data) {
+ check_angle = false;
+ }
+ else {
+ split_angle = cosf(split_angle);
+ }
+ }
+
+ if (!r_lnors_spacearr && clnors_data) {
+ /* We need to compute lnor spacearr if some custom lnor data are given to us! */
+ r_lnors_spacearr = &_lnors_spacearr;
+ }
+ if (r_lnors_spacearr) {
+ BKE_lnor_spacearr_init(r_lnors_spacearr, numLoops);
+ sharp_verts = BLI_BITMAP_NEW((size_t)numVerts, __func__);
}
/* This first loop check which edges are actually smooth, and compute edge vectors. */
@@ -409,187 +1194,271 @@ void BKE_mesh_normals_loop_split(MVert *mverts, const int UNUSED(numVerts), MEdg
}
}
- /* We now know edges that can be smoothed (with their vector, and their two loops), and edges that will be hard!
- * Now, time to generate the normals.
- */
- for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
- MLoop *ml_curr, *ml_prev;
- float (*lnors)[3];
- const int ml_last_index = (mp->loopstart + mp->totloop) - 1;
- int ml_curr_index = mp->loopstart;
- int ml_prev_index = ml_last_index;
+ if (r_lnors_spacearr) {
+ /* Tag vertices that have at least one sharp edge as 'sharp' (used for the lnor spacearr computation).
+ * XXX This third loop over edges is a bit disappointing, could not find any other way yet.
+ * Not really performance-critical anyway.
+ */
+ for (me_index = 0; me_index < numEdges; me_index++) {
+ const int *e2l = edge_to_loops[me_index];
+ const MEdge *me = &medges[me_index];
+ if (IS_EDGE_SHARP(e2l)) {
+ BLI_BITMAP_ENABLE(sharp_verts, me->v1);
+ BLI_BITMAP_ENABLE(sharp_verts, me->v2);
+ }
+ }
+ }
- ml_curr = &mloops[ml_curr_index];
- ml_prev = &mloops[ml_prev_index];
- lnors = &r_loopnors[ml_curr_index];
+ /* Init data common to all tasks. */
+ common_data.lnors_spacearr = r_lnors_spacearr;
+ common_data.loopnors = r_loopnors;
+ common_data.clnors_data = clnors_data;
- for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++, lnors++) {
- const int *e2l_curr = edge_to_loops[ml_curr->e];
- const int *e2l_prev = edge_to_loops[ml_prev->e];
+ common_data.mverts = mverts;
+ common_data.medges = medges;
+ common_data.mloops = mloops;
+ common_data.mpolys = mpolys;
+ common_data.sharp_verts = sharp_verts;
+ common_data.edge_to_loops = (const int(*)[2])edge_to_loops;
+ common_data.loop_to_poly = loop_to_poly;
+ common_data.polynors = polynors;
+ common_data.numPolys = numPolys;
- if (!IS_EDGE_SHARP(e2l_curr)) {
- /* A smooth edge.
- * We skip it because it is either:
- * - in the middle of a 'smooth fan' already computed (or that will be as soon as we hit
- * one of its ends, i.e. one of its two sharp edges), or...
- * - the related vertex is a "full smooth" one, in which case pre-populated normals from vertex
- * are just fine!
- */
- }
- else if (IS_EDGE_SHARP(e2l_prev)) {
- /* Simple case (both edges around that vertex are sharp in current polygon),
- * this vertex just takes its poly normal.
- */
- copy_v3_v3(*lnors, polynors[mp_index]);
- /* No need to mark loop as done here, we won't run into it again anyway! */
- }
- /* We *do not need* to check/tag loops as already computed!
- * Due to the fact a loop only links to one of its two edges, a same fan *will never be walked more than
- * once!*
- * Since we consider edges having neighbor polys with inverted (flipped) normals as sharp, we are sure that
- * no fan will be skipped, even only considering the case (sharp curr_edge, smooth prev_edge), and not the
- * alternative (smooth curr_edge, sharp prev_edge).
- * All this due/thanks to link between normals and loop ordering.
- */
- else {
- /* Gah... We have to fan around current vertex, until we find the other non-smooth edge,
- * and accumulate face normals into the vertex!
- * Note in case this vertex has only one sharp edges, this is a waste because the normal is the same as
- * the vertex normal, but I do not see any easy way to detect that (would need to count number
- * of sharp edges per vertex, I doubt the additional memory usage would be worth it, especially as
- * it should not be a common case in real-life meshes anyway).
- */
- const unsigned int mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */
- const MVert *mv_pivot = &mverts[mv_pivot_index];
- const int *e2lfan_curr;
- float vec_curr[3], vec_prev[3];
- MLoop *mlfan_curr, *mlfan_next;
- MPoly *mpfan_next;
- float lnor[3] = {0.0f, 0.0f, 0.0f};
- /* mlfan_vert_index: the loop of our current edge might not be the loop of our current vertex! */
- int mlfan_curr_index, mlfan_vert_index, mpfan_curr_index;
-
- e2lfan_curr = e2l_prev;
- mlfan_curr = ml_prev;
- mlfan_curr_index = ml_prev_index;
- mlfan_vert_index = ml_curr_index;
- mpfan_curr_index = mp_index;
-
- BLI_assert(mlfan_curr_index >= 0);
- BLI_assert(mlfan_vert_index >= 0);
- BLI_assert(mpfan_curr_index >= 0);
-
- /* Only need to compute previous edge's vector once, then we can just reuse old current one! */
- {
- const MEdge *me_prev = &medges[ml_curr->e]; /* ml_curr would be mlfan_prev if we needed that one */
- const MVert *mv_2 = (me_prev->v1 == mv_pivot_index) ? &mverts[me_prev->v2] : &mverts[me_prev->v1];
+ if (numLoops < LOOP_SPLIT_TASK_BLOCK_SIZE * 8) {
+ /* Not enough loops to be worth the whole threading overhead... */
+ loop_split_generator_do(&common_data, false);
+ }
+ else {
+ TaskScheduler *task_scheduler;
+ TaskPool *task_pool;
+ int nbr_workers;
- sub_v3_v3v3(vec_prev, mv_2->co, mv_pivot->co);
- normalize_v3(vec_prev);
- }
+ common_data.task_queue = BLI_thread_queue_init();
- while (true) {
- /* Compute edge vectors.
- * NOTE: We could pre-compute those into an array, in the first iteration, instead of computing them
- * twice (or more) here. However, time gained is not worth memory and time lost,
- * given the fact that this code should not be called that much in real-life meshes...
- */
- {
- const MEdge *me_curr = &medges[mlfan_curr->e];
- const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &mverts[me_curr->v2] :
- &mverts[me_curr->v1];
-
- sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co);
- normalize_v3(vec_curr);
- }
+ task_scheduler = BLI_task_scheduler_get();
+ task_pool = BLI_task_pool_create(task_scheduler, NULL);
- {
- /* Code similar to accumulate_vertex_normals_poly. */
- /* Calculate angle between the two poly edges incident on this vertex. */
- const float fac = saacos(dot_v3v3(vec_curr, vec_prev));
- /* Accumulate */
- madd_v3_v3fl(lnor, polynors[mpfan_curr_index], fac);
- }
+ nbr_workers = max_ii(2, BLI_task_scheduler_num_threads(task_scheduler));
+ for (i = 1; i < nbr_workers; i++) {
+ BLI_task_pool_push(task_pool, loop_split_worker, &common_data, false, TASK_PRIORITY_HIGH);
+ }
+ BLI_task_pool_push(task_pool, loop_split_generator, &common_data, false, TASK_PRIORITY_HIGH);
+ BLI_task_pool_work_and_wait(task_pool);
- /* We store here a pointer to all loop-normals processed. */
- BLI_SMALLSTACK_PUSH(normal, &(r_loopnors[mlfan_vert_index][0]));
+ BLI_task_pool_free(task_pool);
- if (IS_EDGE_SHARP(e2lfan_curr)) {
- /* Current edge is sharp, we have finished with this fan of faces around this vert! */
- break;
- }
+ BLI_thread_queue_free(common_data.task_queue);
+ }
- copy_v3_v3(vec_prev, vec_curr);
-
- /* Warning! This is rather complex!
- * We have to find our next edge around the vertex (fan mode).
- * First we find the next loop, which is either previous or next to mlfan_curr_index, depending
- * whether both loops using current edge are in the same direction or not, and whether
- * mlfan_curr_index actually uses the vertex we are fanning around!
- * mlfan_curr_index is the index of mlfan_next here, and mlfan_next is not the real next one
- * (i.e. not the future mlfan_curr)...
- */
- mlfan_curr_index = (e2lfan_curr[0] == mlfan_curr_index) ? e2lfan_curr[1] : e2lfan_curr[0];
- mpfan_curr_index = loop_to_poly[mlfan_curr_index];
-
- BLI_assert(mlfan_curr_index >= 0);
- BLI_assert(mpfan_curr_index >= 0);
-
- mlfan_next = &mloops[mlfan_curr_index];
- mpfan_next = &mpolys[mpfan_curr_index];
- if ((mlfan_curr->v == mlfan_next->v && mlfan_curr->v == mv_pivot_index) ||
- (mlfan_curr->v != mlfan_next->v && mlfan_curr->v != mv_pivot_index))
- {
- /* We need the previous loop, but current one is our vertex's loop. */
- mlfan_vert_index = mlfan_curr_index;
- if (--mlfan_curr_index < mpfan_next->loopstart) {
- mlfan_curr_index = mpfan_next->loopstart + mpfan_next->totloop - 1;
- }
+ MEM_freeN(edge_to_loops);
+ if (!r_loop_to_poly) {
+ MEM_freeN(loop_to_poly);
+ }
+
+ if (r_lnors_spacearr) {
+ MEM_freeN(sharp_verts);
+ if (r_lnors_spacearr == &_lnors_spacearr) {
+ BKE_lnor_spacearr_free(r_lnors_spacearr);
+ }
+ }
+
+#ifdef DEBUG_TIME
+ TIMEIT_END(BKE_mesh_normals_loop_split);
+#endif
+
+ }
+}
+
+#undef INDEX_UNSET
+#undef INDEX_INVALID
+#undef IS_EDGE_SHARP
+
+/**
+ * Compute internal representation of given custom normals (as an array of float[2]).
+ * It also makes sure the mesh matches those custom normals, by setting sharp edges flag as needed to get a
+ * same custom lnor for all loops sharing a same smooth fan.
+ * If use_vertices if true, custom_loopnors is assumed to be per-vertex, not per-loop
+ * (this allows to set whole vert's normals at once, useful in some cases).
+ */
+static void mesh_normals_loop_custom_set(
+ MVert *mverts, const int numVerts, MEdge *medges, const int numEdges,
+ MLoop *mloops, float (*custom_loopnors)[3], const int numLoops,
+ MPoly *mpolys, const float (*polynors)[3], const int numPolys,
+ short (*r_clnors_data)[2], const bool use_vertices)
+{
+ /* We *may* make that poor BKE_mesh_normals_loop_split() even more complex by making it handling that
+ * feature too, would probably be more efficient in absolute.
+ * However, this function *is not* performance-critical, since it is mostly expected to be called
+ * by io addons when importing custom normals, and modifier (and perhaps from some editing tools later?).
+ * So better to keep some simplicity here, and just call BKE_mesh_normals_loop_split() twice!
+ */
+ MLoopNorSpaceArray lnors_spacearr = {NULL};
+ BLI_bitmap *done_loops = BLI_BITMAP_NEW((size_t)numLoops, __func__);
+ float (*lnors)[3] = MEM_callocN(sizeof(*lnors) * (size_t)numLoops, __func__);
+ int *loop_to_poly = MEM_mallocN(sizeof(int) * (size_t)numLoops, __func__);
+ /* In this case we always consider split nors as ON, and do not want to use angle to define smooth fans! */
+ const bool use_split_normals = true;
+ const float split_angle = (float)M_PI;
+ int i;
+
+ BLI_SMALLSTACK_DECLARE(clnors_data, short *);
+
+ /* Compute current lnor spacearr. */
+ BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops, lnors, numLoops,
+ mpolys, polynors, numPolys, use_split_normals, split_angle,
+ &lnors_spacearr, NULL, loop_to_poly);
+
+ /* Now, check each current smooth fan (one lnor space per smooth fan!), and if all its matching custom lnors
+ * are not (enough) equal, add sharp edges as needed.
+ * This way, next time we run BKE_mesh_normals_loop_split(), we'll get lnor spacearr/smooth fans matching
+ * given custom lnors.
+ * Note this code *will never* unsharp edges!
+ * And quite obviously, when we set custom normals per vertices, running this is absolutely useless.
+ */
+ if (!use_vertices) {
+ for (i = 0; i < numLoops; i++) {
+ if (!lnors_spacearr.lspacearr[i]) {
+ /* This should not happen in theory, but in some rare case (probably ugly geometry)
+ * we can get some NULL loopspacearr at this point. :/
+ * Maybe we should set those loops' edges as sharp?
+ */
+ BLI_BITMAP_ENABLE(done_loops, i);
+ printf("WARNING! Getting invalid NULL loop space for loop %d!\n", i);
+ continue;
+ }
+
+ if (!BLI_BITMAP_TEST(done_loops, i)) {
+ /* Notes:
+ * * In case of mono-loop smooth fan, loops is NULL, so everything is fine (we have nothing to do).
+ * * Loops in this linklist are ordered (in reversed order compared to how they were discovered by
+ * BKE_mesh_normals_loop_split(), but this is not a problem). Which means if we find a
+ * mismatching clnor, we know all remaining loops will have to be in a new, different smooth fan/
+ * lnor space.
+ * * In smooth fan case, we compare each clnor against a ref one, to avoid small differences adding
+ * up into a real big one in the end!
+ */
+ LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
+ MLoop *prev_ml = NULL;
+ const float *org_nor = NULL;
+
+ while (loops) {
+ const int lidx = GET_INT_FROM_POINTER(loops->link);
+ MLoop *ml = &mloops[lidx];
+ const int nidx = lidx;
+ float *nor = custom_loopnors[nidx];
+
+ if (!org_nor) {
+ org_nor = nor;
}
- else {
- /* We need the next loop, which is also our vertex's loop. */
- if (++mlfan_curr_index >= mpfan_next->loopstart + mpfan_next->totloop) {
- mlfan_curr_index = mpfan_next->loopstart;
- }
- mlfan_vert_index = mlfan_curr_index;
+ else if (dot_v3v3(org_nor, nor) < LNOR_SPACE_TRIGO_THRESHOLD) {
+ /* Current normal differs too much from org one, we have to tag the edge between
+ * previous loop's face and current's one as sharp.
+ * We know those two loops do not point to the same edge, since we do not allow reversed winding
+ * in a same smooth fan.
+ */
+ const MPoly *mp = &mpolys[loop_to_poly[lidx]];
+ const MLoop *mlp = &mloops[(lidx == mp->loopstart) ? mp->loopstart + mp->totloop - 1 : lidx - 1];
+ medges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e].flag |= ME_SHARP;
+
+ org_nor = nor;
}
- mlfan_curr = &mloops[mlfan_curr_index];
- /* And now we are back in sync, mlfan_curr_index is the index of mlfan_curr! Pff! */
- e2lfan_curr = edge_to_loops[mlfan_curr->e];
+ prev_ml = ml;
+ loops = loops->next;
+ BLI_BITMAP_ENABLE(done_loops, lidx);
}
+ BLI_BITMAP_ENABLE(done_loops, i); /* For single loops, where lnors_spacearr.lspacearr[i]->loops is NULL. */
+ }
+ }
- /* In case we get a zero normal here, just use vertex normal already set! */
- if (LIKELY(normalize_v3(lnor) != 0.0f)) {
- /* Copy back the final computed normal into all related loop-normals. */
- float *nor;
- while ((nor = BLI_SMALLSTACK_POP(normal))) {
- copy_v3_v3(nor, lnor);
- }
+ /* And now, recompute our new auto lnors and lnor spacearr! */
+ BKE_lnor_spacearr_clear(&lnors_spacearr);
+ BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops, lnors, numLoops,
+ mpolys, polynors, numPolys, use_split_normals, split_angle,
+ &lnors_spacearr, NULL, loop_to_poly);
+ }
+ else {
+ BLI_BITMAP_SET_ALL(done_loops, true, (size_t)numLoops);
+ }
+
+ /* And we just have to convert plain object-space custom normals to our lnor space-encoded ones. */
+ for (i = 0; i < numLoops; i++) {
+ if (!lnors_spacearr.lspacearr[i]) {
+ BLI_BITMAP_DISABLE(done_loops, i);
+ printf("WARNING! Still getting invalid NULL loop space in second loop for loop %d!\n", i);
+ continue;
+ }
+
+ if (BLI_BITMAP_TEST_BOOL(done_loops, i)) {
+ /* Note we accumulate and average all custom normals in current smooth fan, to avoid getting different
+ * clnors data (tiny differences in plain custom normals can give rather huge differences in
+ * computed 2D factors).
+ */
+ LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
+ if (loops) {
+ int nbr_nors = 0;
+ float avg_nor[3];
+ short clnor_data_tmp[2], *clnor_data;
+
+ zero_v3(avg_nor);
+ while (loops) {
+ const int lidx = GET_INT_FROM_POINTER(loops->link);
+ const int nidx = use_vertices ? (int)mloops[lidx].v : lidx;
+ float *nor = custom_loopnors[nidx];
+
+ nbr_nors++;
+ add_v3_v3(avg_nor, nor);
+ BLI_SMALLSTACK_PUSH(clnors_data, (short *)r_clnors_data[lidx]);
+
+ loops = loops->next;
+ BLI_BITMAP_DISABLE(done_loops, lidx);
}
- else {
- /* We still have to clear the stack! */
- while (BLI_SMALLSTACK_POP(normal));
+
+ mul_v3_fl(avg_nor, 1.0f / (float)nbr_nors);
+ BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], avg_nor, clnor_data_tmp);
+
+ while ((clnor_data = BLI_SMALLSTACK_POP(clnors_data))) {
+ clnor_data[0] = clnor_data_tmp[0];
+ clnor_data[1] = clnor_data_tmp[1];
}
}
+ else {
+ const int nidx = use_vertices ? (int)mloops[i].v : i;
+ float *nor = custom_loopnors[nidx];
- ml_prev = ml_curr;
- ml_prev_index = ml_curr_index;
+ BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], nor, r_clnors_data[i]);
+ BLI_BITMAP_DISABLE(done_loops, i);
+ }
}
}
- MEM_freeN(edge_to_loops);
+ MEM_freeN(lnors);
MEM_freeN(loop_to_poly);
+ MEM_freeN(done_loops);
+ BKE_lnor_spacearr_free(&lnors_spacearr);
+}
-#ifdef DEBUG_TIME
- TIMEIT_END(BKE_mesh_normals_loop_split);
-#endif
+void BKE_mesh_normals_loop_custom_set(
+ MVert *mverts, const int numVerts, MEdge *medges, const int numEdges,
+ MLoop *mloops, float (*custom_loopnors)[3], const int numLoops,
+ MPoly *mpolys, const float (*polynors)[3], const int numPolys,
+ short (*r_clnors_data)[2])
+{
+ mesh_normals_loop_custom_set(mverts, numVerts, medges, numEdges, mloops, custom_loopnors, numLoops,
+ mpolys, polynors, numPolys, r_clnors_data, false);
+}
-#undef INDEX_UNSET
-#undef INDEX_INVALID
-#undef IS_EDGE_SHARP
+void BKE_mesh_normals_loop_custom_from_vertices_set(
+ MVert *mverts, float (*custom_vertnors)[3], const int numVerts,
+ MEdge *medges, const int numEdges, MLoop *mloops, const int numLoops,
+ MPoly *mpolys, const float (*polynors)[3], const int numPolys,
+ short (*r_clnors_data)[2])
+{
+ mesh_normals_loop_custom_set(mverts, numVerts, medges, numEdges, mloops, custom_vertnors, numLoops,
+ mpolys, polynors, numPolys, r_clnors_data, true);
}
+#undef LNOR_SPACE_TRIGO_THRESHOLD
/** \} */
@@ -896,13 +1765,6 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
mvarray[loopstart[2].v].co
);
}
- else if (mpoly->totloop == 4) {
- return area_quad_v3(mvarray[loopstart[0].v].co,
- mvarray[loopstart[1].v].co,
- mvarray[loopstart[2].v].co,
- mvarray[loopstart[3].v].co
- );
- }
else {
int i;
MLoop *l_iter = loopstart;
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 53d1aae104c..8d9fbe46f19 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -32,10 +32,12 @@
#include "DNA_meshdata_types.h"
#include "BLI_utildefines.h"
+#include "BLI_bitmap.h"
#include "BLI_math.h"
#include "BKE_mesh_mapping.h"
#include "BKE_customdata.h"
+#include "BLI_memarena.h"
#include "BLI_strict_flags.h"
@@ -156,18 +158,25 @@ void BKE_mesh_uv_vert_map_free(UvVertMap *vmap)
}
}
-/* Generates a map where the key is the vertex and the value is a list
- * of polys that use that vertex as a corner. The lists are allocated
- * from one memory pool. */
-void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem,
- const MPoly *mpoly, const MLoop *mloop,
- int totvert, int totpoly, int totloop)
+/**
+
+
+ * Generates a map where the key is the vertex and the value is a list
+ * of polys or loops that use that vertex as a corner. The lists are allocated
+ * from one memory pool.
+ *
+ * Wrapped by #BKE_mesh_vert_poly_map_create & BKE_mesh_vert_loop_map_create
+ */
+static void mesh_vert_poly_or_loop_map_create(
+ MeshElemMap **r_map, int **r_mem,
+ const MPoly *mpoly, const MLoop *mloop,
+ int totvert, int totpoly, int totloop, const bool do_loops)
{
- MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totvert, "vert poly map");
+ MeshElemMap *map = MEM_callocN(sizeof(MeshElemMap) * (size_t)totvert, __func__);
int *indices, *index_iter;
int i, j;
- indices = index_iter = MEM_mallocN(sizeof(int) * (size_t)totloop, "vert poly map mem");
+ indices = index_iter = MEM_mallocN(sizeof(int) * (size_t)totloop, __func__);
/* Count number of polys for each vertex */
for (i = 0; i < totpoly; i++) {
@@ -193,7 +202,7 @@ void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem,
for (j = 0; j < p->totloop; j++) {
unsigned int v = mloop[p->loopstart + j].v;
- map[v].indices[map[v].count] = i;
+ map[v].indices[map[v].count] = do_loops ? p->loopstart + j : i;
map[v].count++;
}
}
@@ -202,6 +211,28 @@ void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem,
*r_mem = indices;
}
+/**
+ * Generates a map where the key is the vertex and the value is a list of polys that use that vertex as a corner.
+ * The lists are allocated from one memory pool.
+ */
+void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map, int **r_mem,
+ const MPoly *mpoly, const MLoop *mloop,
+ int totvert, int totpoly, int totloop)
+{
+ mesh_vert_poly_or_loop_map_create(r_map, r_mem, mpoly, mloop, totvert, totpoly, totloop, false);
+}
+
+/**
+ * Generates a map where the key is the vertex and the value is a list of loops that use that vertex as a corner.
+ * The lists are allocated from one memory pool.
+ */
+void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map, int **r_mem,
+ const MPoly *mpoly, const MLoop *mloop,
+ int totvert, int totpoly, int totloop)
+{
+ mesh_vert_poly_or_loop_map_create(r_map, r_mem, mpoly, mloop, totvert, totpoly, totloop, true);
+}
+
/* Generates a map where the key is the vertex and the value is a list
* of edges that use that vertex as an endpoint. The lists are allocated
* from one memory pool. */
@@ -345,26 +376,30 @@ void BKE_mesh_origindex_map_create(MeshElemMap **r_map, int **r_mem,
/** \} */
-
/* -------------------------------------------------------------------- */
-/** \name Mesh Smooth Groups
+/** \name Mesh loops/poly islands.
+ * Used currently for UVs and 'smooth groups'.
* \{ */
-/**
- * Calculate smooth groups from sharp edges.
- *
- * \param r_totgroup The total number of groups, 1 or more.
- * \return Polygon aligned array of group index values (bitflags if use_bitflags is true), starting at 1.
+/** Callback deciding whether the given poly/loop/edge define an island boundary or not.
*/
-int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
- const MPoly *mpoly, const int totpoly,
- const MLoop *mloop, const int totloop,
- int *r_totgroup, const bool use_bitflags)
+typedef bool (*MeshRemap_CheckIslandBoundary)(
+ const struct MPoly *mpoly, const struct MLoop *mloop, const struct MEdge *medge,
+ const int nbr_egde_users);
+
+static void poly_edge_loop_islands_calc(
+ const MEdge *medge, const int totedge, const MPoly *mpoly, const int totpoly,
+ const MLoop *mloop, const int totloop, MeshElemMap *edge_poly_map,
+ const bool use_bitflags, MeshRemap_CheckIslandBoundary edge_boundary_check,
+ int **r_poly_groups, int *r_totgroup, BLI_bitmap **r_edge_borders, int *r_totedgeborder)
{
int *poly_groups;
int *poly_stack;
+ BLI_bitmap *edge_borders = NULL;
+ int num_edgeborders = 0;
+
int poly_prev = 0;
const int temp_poly_group_id = 3; /* Placeholder value. */
const int poly_group_id_overflowed = 5; /* Group we could not find any available bit, will be reset to 0 at end */
@@ -372,18 +407,27 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
bool group_id_overflow = false;
/* map vars */
- MeshElemMap *edge_poly_map;
- int *edge_poly_mem;
+ int *edge_poly_mem = NULL;
if (totpoly == 0) {
*r_totgroup = 0;
- return NULL;
+ *r_poly_groups = NULL;
+ if (r_edge_borders) {
+ *r_edge_borders = NULL;
+ *r_totedgeborder = 0;
+ }
+ return;
}
- BKE_mesh_edge_poly_map_create(&edge_poly_map, &edge_poly_mem,
- medge, totedge,
- mpoly, totpoly,
- mloop, totloop);
+ if (r_edge_borders) {
+ edge_borders = BLI_BITMAP_NEW(totedge, __func__);
+ *r_totedgeborder = 0;
+ }
+
+ if (!edge_poly_map) {
+ BKE_mesh_edge_poly_map_create(&edge_poly_map, &edge_poly_mem,
+ medge, totedge, mpoly, totpoly, mloop, totloop);
+ }
poly_groups = MEM_callocN(sizeof(int) * (size_t)totpoly, __func__);
poly_stack = MEM_mallocN(sizeof(int) * (size_t)totpoly, __func__);
@@ -416,22 +460,20 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
while (ps_curr_idx != ps_end_idx) {
const MPoly *mp;
const MLoop *ml;
- bool sharp_poly;
int j;
poly = poly_stack[ps_curr_idx++];
BLI_assert(poly_groups[poly] == poly_group_id);
mp = &mpoly[poly];
- sharp_poly = !(mp->flag & ME_SMOOTH);
for (ml = &mloop[mp->loopstart], j = mp->totloop; j--; ml++) {
/* loop over poly users */
- const MeshElemMap *map_ele = &edge_poly_map[ml->e];
+ const int me_idx = (int)ml->e;
+ const MEdge *me = &medge[me_idx];
+ const MeshElemMap *map_ele = &edge_poly_map[me_idx];
const int *p = map_ele->indices;
int i = map_ele->count;
- /* Edge is smooth only if its poly is not sharp, edge is not sharp,
- * and edge is used by exactly two polygons. */
- if (!sharp_poly && !(medge[ml->e].flag & ME_SHARP) && i == 2) {
+ if (!edge_boundary_check(mp, ml, me, i)) {
for (; i--; p++) {
/* if we meet other non initialized its a bug */
BLI_assert(ELEM(poly_groups[*p], 0, poly_group_id));
@@ -442,14 +484,20 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
}
}
}
- else if (use_bitflags) {
- /* Find contiguous smooth groups already assigned, these are the values we can't reuse! */
- for (; i--; p++) {
- int bit = poly_groups[*p];
- if (!ELEM(bit, 0, poly_group_id, poly_group_id_overflowed) &&
- !(bit_poly_group_mask & bit))
- {
- bit_poly_group_mask |= bit;
+ else {
+ if (edge_borders && !BLI_BITMAP_TEST(edge_borders, me_idx)) {
+ BLI_BITMAP_ENABLE(edge_borders, me_idx);
+ num_edgeborders++;
+ }
+ if (use_bitflags) {
+ /* Find contiguous smooth groups already assigned, these are the values we can't reuse! */
+ for (; i--; p++) {
+ int bit = poly_groups[*p];
+ if (!ELEM(bit, 0, poly_group_id, poly_group_id_overflowed) &&
+ !(bit_poly_group_mask & bit))
+ {
+ bit_poly_group_mask |= bit;
+ }
}
}
}
@@ -502,12 +550,258 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
tot_group++;
}
- MEM_freeN(edge_poly_map);
- MEM_freeN(edge_poly_mem);
+ if (edge_poly_mem) {
+ MEM_freeN(edge_poly_map);
+ MEM_freeN(edge_poly_mem);
+ }
MEM_freeN(poly_stack);
*r_totgroup = tot_group;
+ *r_poly_groups = poly_groups;
+ if (r_edge_borders) {
+ *r_edge_borders = edge_borders;
+ *r_totedgeborder = num_edgeborders;
+ }
+}
+
+static bool poly_is_island_boundary_smooth_cb(
+ const MPoly *mp, const MLoop *UNUSED(ml), const MEdge *me,
+ const int nbr_egde_users)
+{
+ /* Edge is sharp if its poly is sharp, or edge itself is sharp, or edge is not used by exactly two polygons. */
+ return (!(mp->flag & ME_SMOOTH) || (me->flag & ME_SHARP) || (nbr_egde_users != 2));
+}
+
+/**
+ * Calculate smooth groups from sharp edges.
+ *
+ * \param r_totgroup The total number of groups, 1 or more.
+ * \return Polygon aligned array of group index values (bitflags if use_bitflags is true), starting at 1
+ * (0 being used as 'invalid' flag).
+ * Note it's callers's responsibility to MEM_freeN returned array.
+ */
+int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totedge,
+ const MPoly *mpoly, const int totpoly,
+ const MLoop *mloop, const int totloop,
+ int *r_totgroup, const bool use_bitflags)
+{
+ int *poly_groups = NULL;
+
+ poly_edge_loop_islands_calc(
+ medge, totedge, mpoly, totpoly, mloop, totloop, NULL, use_bitflags,
+ poly_is_island_boundary_smooth_cb, &poly_groups, r_totgroup, NULL, NULL);
return poly_groups;
}
+
+#define MISLAND_DEFAULT_BUFSIZE 64
+
+void BKE_mesh_loop_islands_init(
+ MeshIslandStore *island_store,
+ const short item_type, const int items_num, const short island_type, const short innercut_type)
+{
+ MemArena *mem = island_store->mem;
+
+ if (mem == NULL) {
+ mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ island_store->mem = mem;
+ }
+ /* else memarena should be cleared */
+
+ BLI_assert(ELEM(item_type, MISLAND_TYPE_VERT, MISLAND_TYPE_EDGE, MISLAND_TYPE_POLY, MISLAND_TYPE_LOOP));
+ BLI_assert(ELEM(island_type, MISLAND_TYPE_VERT, MISLAND_TYPE_EDGE, MISLAND_TYPE_POLY, MISLAND_TYPE_LOOP));
+
+ island_store->item_type = item_type;
+ island_store->items_to_islands_num = items_num;
+ island_store->items_to_islands = BLI_memarena_alloc(mem, sizeof(*island_store->items_to_islands) * (size_t)items_num);
+
+ island_store->island_type = island_type;
+ island_store->islands_num_alloc = MISLAND_DEFAULT_BUFSIZE;
+ island_store->islands = BLI_memarena_alloc(mem, sizeof(*island_store->islands) * island_store->islands_num_alloc);
+
+ island_store->innercut_type = innercut_type;
+ island_store->innercuts = BLI_memarena_alloc(mem, sizeof(*island_store->innercuts) * island_store->islands_num_alloc);
+}
+
+void BKE_mesh_loop_islands_clear(MeshIslandStore *island_store)
+{
+ island_store->item_type = MISLAND_TYPE_NONE;
+ island_store->items_to_islands_num = 0;
+ island_store->items_to_islands = NULL;
+
+ island_store->island_type = MISLAND_TYPE_NONE;
+ island_store->islands_num = 0;
+ island_store->islands = NULL;
+
+ island_store->innercut_type = MISLAND_TYPE_NONE;
+ island_store->innercuts = NULL;
+
+ if (island_store->mem) {
+ BLI_memarena_clear(island_store->mem);
+ }
+
+ island_store->islands_num_alloc = 0;
+}
+
+void BKE_mesh_loop_islands_free(MeshIslandStore *island_store)
+{
+ if (island_store->mem) {
+ BLI_memarena_free(island_store->mem);
+ island_store->mem = NULL;
+ }
+}
+
+void BKE_mesh_loop_islands_add(
+ MeshIslandStore *island_store, const int item_num, int *items_indices,
+ const int num_island_items, int *island_item_indices,
+ const int num_innercut_items, int *innercut_item_indices)
+{
+ MemArena *mem = island_store->mem;
+
+ MeshElemMap *isld, *innrcut;
+ const int curr_island_idx = island_store->islands_num++;
+ const size_t curr_num_islands = (size_t)island_store->islands_num;
+ int i = item_num;
+
+ island_store->items_to_islands_num = item_num;
+ while (i--) {
+ island_store->items_to_islands[items_indices[i]] = curr_island_idx;
+ }
+
+ if (UNLIKELY(curr_num_islands > island_store->islands_num_alloc)) {
+ MeshElemMap **islds, **innrcuts;
+
+ island_store->islands_num_alloc *= 2;
+ islds = BLI_memarena_alloc(mem, sizeof(*islds) * island_store->islands_num_alloc);
+ memcpy(islds, island_store->islands, sizeof(*islds) * (curr_num_islands - 1));
+ island_store->islands = islds;
+
+ innrcuts = BLI_memarena_alloc(mem, sizeof(*innrcuts) * island_store->islands_num_alloc);
+ memcpy(innrcuts, island_store->innercuts, sizeof(*innrcuts) * (curr_num_islands - 1));
+ island_store->innercuts = innrcuts;
+ }
+
+ island_store->islands[curr_island_idx] = isld = BLI_memarena_alloc(mem, sizeof(*isld));
+ isld->count = num_island_items;
+ isld->indices = BLI_memarena_alloc(mem, sizeof(*isld->indices) * (size_t)num_island_items);
+ memcpy(isld->indices, island_item_indices, sizeof(*isld->indices) * (size_t)num_island_items);
+
+ island_store->innercuts[curr_island_idx] = innrcut = BLI_memarena_alloc(mem, sizeof(*innrcut));
+ innrcut->count = num_innercut_items;
+ innrcut->indices = BLI_memarena_alloc(mem, sizeof(*innrcut->indices) * (size_t)num_innercut_items);
+ memcpy(innrcut->indices, innercut_item_indices, sizeof(*innrcut->indices) * (size_t)num_innercut_items);
+}
+
+/* TODO: I'm not sure edge seam flag is enough to define UV islands? Maybe we should also consider UVmaps values
+ * themselves (i.e. different UV-edges for a same mesh-edge => boundary edge too?).
+ * Would make things much more complex though, and each UVMap would then need its own mesh mapping,
+ * not sure we want that at all!
+ */
+static bool mesh_check_island_boundary_uv(
+ const MPoly *UNUSED(mp), const MLoop *UNUSED(ml), const MEdge *me,
+ const int UNUSED(nbr_egde_users))
+{
+ /* Edge is UV boundary if tagged as seam. */
+ return (me->flag & ME_SEAM) != 0;
+}
+
+/**
+ * \note all this could be optimized...
+ * Not sure it would be worth the more complex code, though, those loops
+ * are supposed to be really quick to do...
+ */
+bool BKE_mesh_calc_islands_loop_poly_uv(
+ MVert *UNUSED(verts), const int UNUSED(totvert),
+ MEdge *edges, const int totedge,
+ MPoly *polys, const int totpoly,
+ MLoop *loops, const int totloop,
+ MeshIslandStore *r_island_store)
+{
+ int *poly_groups = NULL;
+ int num_poly_groups;
+
+ /* map vars */
+ MeshElemMap *edge_poly_map;
+ int *edge_poly_mem;
+
+ int *poly_indices;
+ int *loop_indices;
+ int num_pidx, num_lidx;
+
+ /* Those are used to detect 'inner cuts', i.e. edges that are borders, and yet have two or more polys of
+ * a same group using them (typical case: seam used to unwrap properly a cylinder). */
+ BLI_bitmap *edge_borders;
+ int num_edge_borders;
+ char *edge_border_count = NULL;
+ int *edge_innercut_indices = NULL;
+ int num_einnercuts = 0;
+
+ int grp_idx, p_idx, pl_idx, l_idx;
+
+ BKE_mesh_loop_islands_clear(r_island_store);
+ BKE_mesh_loop_islands_init(r_island_store, MISLAND_TYPE_LOOP, totloop, MISLAND_TYPE_POLY, MISLAND_TYPE_EDGE);
+
+ BKE_mesh_edge_poly_map_create(&edge_poly_map, &edge_poly_mem,
+ edges, totedge, polys, totpoly, loops, totloop);
+
+ poly_edge_loop_islands_calc(
+ edges, totedge, polys, totpoly, loops, totloop, edge_poly_map, false,
+ mesh_check_island_boundary_uv, &poly_groups, &num_poly_groups, &edge_borders, &num_edge_borders);
+
+ if (!num_poly_groups) {
+ /* Should never happen... */
+ return false;
+ }
+
+ if (num_edge_borders) {
+ edge_border_count = MEM_mallocN(sizeof(*edge_border_count) * (size_t)totedge, __func__);
+ edge_innercut_indices = MEM_mallocN(sizeof(*edge_innercut_indices) * (size_t)num_edge_borders, __func__);
+ }
+
+ poly_indices = MEM_mallocN(sizeof(*poly_indices) * (size_t)totpoly, __func__);
+ loop_indices = MEM_mallocN(sizeof(*loop_indices) * (size_t)totloop, __func__);
+
+ /* Note: here we ignore '0' invalid group - this should *never* happen in this case anyway? */
+ for (grp_idx = 1; grp_idx <= num_poly_groups; grp_idx++) {
+ num_pidx = num_lidx = 0;
+ if (num_edge_borders) {
+ num_einnercuts = 0;
+ memset(edge_border_count, 0, sizeof(*edge_border_count) * (size_t)totedge);
+ }
+
+ for (p_idx = 0; p_idx < totpoly; p_idx++) {
+ MPoly *mp;
+
+ if (poly_groups[p_idx] != grp_idx) {
+ continue;
+ }
+
+ mp = &polys[p_idx];
+ poly_indices[num_pidx++] = p_idx;
+ for (l_idx = mp->loopstart, pl_idx = 0; pl_idx < mp->totloop; l_idx++, pl_idx++) {
+ MLoop *ml = &loops[l_idx];
+ loop_indices[num_lidx++] = l_idx;
+ if (num_edge_borders && BLI_BITMAP_TEST(edge_borders, ml->e) && (edge_border_count[ml->e] < 2)) {
+ edge_border_count[ml->e]++;
+ if (edge_border_count[ml->e] == 2) {
+ edge_innercut_indices[num_einnercuts++] = (int)ml->e;
+ }
+ }
+ }
+ }
+
+ BKE_mesh_loop_islands_add(r_island_store, num_lidx, loop_indices, num_pidx, poly_indices,
+ num_einnercuts, edge_innercut_indices);
+ }
+
+ MEM_freeN(poly_indices);
+ MEM_freeN(loop_indices);
+ MEM_freeN(poly_groups);
+ if (num_edge_borders) {
+ MEM_freeN(edge_border_count);
+ MEM_freeN(edge_innercut_indices);
+ }
+ return true;
+}
+
/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
new file mode 100644
index 00000000000..aca72614094
--- /dev/null
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -0,0 +1,2010 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/mesh_remap.c
+ * \ingroup bke
+ *
+ * Functions for mapping data between meshes.
+ */
+
+#include <limits.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_meshdata_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
+#include "BLI_astar.h"
+#include "BLI_bitmap.h"
+#include "BLI_math.h"
+#include "BLI_memarena.h"
+#include "BLI_polyfill2d.h"
+#include "BLI_rand.h"
+
+#include "BKE_bvhutils.h"
+#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_remap.h" /* own include */
+
+#include "BLI_strict_flags.h"
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Mesh to mesh mapping
+ * \{ */
+
+void BKE_mesh_remap_init(MeshPairRemap *map, const int items_num)
+{
+ MemArena *mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
+ BKE_mesh_remap_free(map);
+
+ map->items = BLI_memarena_alloc(mem, sizeof(*map->items) * (size_t)items_num);
+ map->items_num = items_num;
+
+ map->mem = mem;
+}
+
+void BKE_mesh_remap_free(MeshPairRemap *map)
+{
+ if (map->mem) {
+ BLI_memarena_free((MemArena *)map->mem);
+ }
+
+ map->items_num = 0;
+ map->items = NULL;
+ map->mem = NULL;
+}
+
+static void mesh_remap_item_define(
+ MeshPairRemap *map, const int index, const float UNUSED(hit_dist), const int island,
+ const int sources_num, const int *indices_src, const float *weights_src)
+{
+ MeshPairRemapItem *mapit = &map->items[index];
+ MemArena *mem = map->mem;
+
+ if (sources_num) {
+ mapit->sources_num = sources_num;
+ mapit->indices_src = BLI_memarena_alloc(mem, sizeof(*mapit->indices_src) * (size_t)sources_num);
+ memcpy(mapit->indices_src, indices_src, sizeof(*mapit->indices_src) * (size_t)sources_num);
+ mapit->weights_src = BLI_memarena_alloc(mem, sizeof(*mapit->weights_src) * (size_t)sources_num);
+ memcpy(mapit->weights_src, weights_src, sizeof(*mapit->weights_src) * (size_t)sources_num);
+ }
+ else {
+ mapit->sources_num = 0;
+ mapit->indices_src = NULL;
+ mapit->weights_src = NULL;
+ }
+ /* UNUSED */
+ // mapit->hit_dist = hit_dist;
+ mapit->island = island;
+}
+
+void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, const int index)
+{
+ mesh_remap_item_define(map, index, FLT_MAX, 0, 0, NULL, NULL);
+}
+
+static int mesh_remap_interp_poly_data_get(
+ const MPoly *mp, MLoop *mloops, const float (*vcos_src)[3], const float point[3],
+ size_t *buff_size, float (**vcos)[3], const bool use_loops, int **indices, float **weights,
+ const bool do_weights, int *r_closest_index)
+{
+ MLoop *ml;
+ float (*vco)[3];
+ float ref_dist_sq = FLT_MAX;
+ int *index;
+ const int sources_num = mp->totloop;
+ int i;
+
+ if ((size_t)sources_num > *buff_size) {
+ *buff_size = (size_t)sources_num;
+ *vcos = MEM_reallocN(*vcos, sizeof(**vcos) * *buff_size);
+ *indices = MEM_reallocN(*indices, sizeof(**indices) * *buff_size);
+ if (do_weights) {
+ *weights = MEM_reallocN(*weights, sizeof(**weights) * *buff_size);
+ }
+ }
+
+ for (i = 0, ml = &mloops[mp->loopstart], vco = *vcos, index = *indices; i < sources_num; i++, ml++, vco++, index++) {
+ *index = use_loops ? (int)mp->loopstart + i : (int)ml->v;
+ copy_v3_v3(*vco, vcos_src[ml->v]);
+ if (r_closest_index) {
+ /* Find closest vert/loop in this case. */
+ const float dist_sq = len_squared_v3v3(point, *vco);
+ if (dist_sq < ref_dist_sq) {
+ ref_dist_sq = dist_sq;
+ *r_closest_index = *index;
+ }
+ }
+ }
+
+ if (do_weights) {
+ interp_weights_poly_v3(*weights, *vcos, sources_num, point);
+ }
+
+ return sources_num;
+}
+
+static bool mesh_remap_bvhtree_query_nearest(
+ BVHTreeFromMesh *treedata, BVHTreeNearest *nearest, const SpaceTransform *space_transform,
+ const float in_co[3], const float max_dist_sq,
+ float *r_hit_dist)
+{
+ float co[3];
+
+ copy_v3_v3(co, in_co);
+
+ /* Convert the vertex to tree coordinates, if needed. */
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, co);
+ }
+
+ /* Use local proximity heuristics (to reduce the nearest search). */
+ if (nearest->index != -1) {
+ nearest->dist_sq = min_ff(len_squared_v3v3(co, nearest->co), max_dist_sq);
+ }
+ else {
+ nearest->dist_sq = max_dist_sq;
+ }
+ /* Compute and store result. If invalid (-1 index), keep FLT_MAX dist. */
+ BLI_bvhtree_find_nearest(treedata->tree, co, nearest, treedata->nearest_callback, treedata);
+
+ if ((nearest->index != -1) && (nearest->dist_sq <= max_dist_sq)) {
+ *r_hit_dist = sqrtf(nearest->dist_sq);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+static bool mesh_remap_bvhtree_query_raycast(
+ BVHTreeFromMesh *treedata, BVHTreeRayHit *rayhit, const SpaceTransform *space_transform,
+ const float in_co[3], const float in_no[3], const float radius, const float max_dist,
+ float *r_hit_dist)
+{
+ BVHTreeRayHit rayhit_tmp;
+ float co[3], no[3];
+
+ copy_v3_v3(co, in_co);
+ copy_v3_v3(no, in_no);
+
+ /* Convert the vertex to tree coordinates, if needed. */
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, co);
+ BLI_space_transform_apply_normal(space_transform, no);
+ }
+
+ rayhit->index = -1;
+ rayhit->dist = max_dist;
+ BLI_bvhtree_ray_cast(treedata->tree, co, no, radius, rayhit, treedata->raycast_callback, treedata);
+
+ /* Also cast in the other direction! */
+ rayhit_tmp = *rayhit;
+ negate_v3(no);
+ BLI_bvhtree_ray_cast(treedata->tree, co, no, radius, &rayhit_tmp, treedata->raycast_callback, treedata);
+ if (rayhit_tmp.dist < rayhit->dist) {
+ *rayhit = rayhit_tmp;
+ }
+
+ if ((rayhit->index != -1) && (rayhit->dist <= max_dist)) {
+ *r_hit_dist = rayhit->dist;
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+/* Little helper when dealing with source islands */
+typedef struct IslandResult {
+ float factor; /* A factor, based on which best island for a given set of elements will be selected. */
+ int index_src; /* Index of the source. */
+ float hit_dist; /* The actual hit distance. */
+ float hit_point[3]; /* The hit point, if relevant. */
+} IslandResult;
+
+/* Note about all bvh/raycasting stuff below:
+ * * We must use our ray radius as BVH epsilon too, else rays not hitting anything but 'passing near' an item
+ * would be missed (since BVH handling would not detect them, 'refining' callbacks won't be executed,
+ * even though they would return a valid hit).
+ * * However, in 'islands' case where each hit gets a weight, 'precise' hits should have a better weight than
+ * 'approximate' hits. To address that, we simplify things with:
+ * ** A first raycast with default, given rayradius;
+ * ** If first one fails, we do more raycasting with bigger radius, but if hit is found
+ * it will get smaller weight.
+ * This only concerns loops, currently (because of islands), and 'sampled' edges/polys norproj.
+ */
+
+/* At most n raycasts per 'real' ray. */
+#define MREMAP_RAYCAST_APPROXIMATE_NR 3
+/* Each approximated raycasts will have n times bigger radius than previous one. */
+#define MREMAP_RAYCAST_APPROXIMATE_FAC 5.0f
+/* BVH epsilon value we have to give to bvh 'constructor' when doing approximated raycasting. */
+#define MREMAP_RAYCAST_APPROXIMATE_BVHEPSILON(_ray_radius) \
+ ((float)MREMAP_RAYCAST_APPROXIMATE_NR * MREMAP_RAYCAST_APPROXIMATE_FAC * (_ray_radius))
+
+/* min 16 rays/face, max 400. */
+#define MREMAP_RAYCAST_TRI_SAMPLES_MIN 4
+#define MREMAP_RAYCAST_TRI_SAMPLES_MAX 20
+
+/* Will be enough in 99% of cases. */
+#define MREMAP_DEFAULT_BUFSIZE 32
+
+void BKE_mesh_remap_calc_verts_from_dm(
+ const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius,
+ const MVert *verts_dst, const int numverts_dst, const bool UNUSED(dirty_nors_dst), DerivedMesh *dm_src,
+ MeshPairRemap *r_map)
+{
+ const float full_weight = 1.0f;
+ const float max_dist_sq = max_dist * max_dist;
+ int i;
+
+ BLI_assert(mode & MREMAP_MODE_VERT);
+
+ BKE_mesh_remap_init(r_map, numverts_dst);
+
+ if (mode == MREMAP_MODE_TOPOLOGY) {
+ BLI_assert(numverts_dst == dm_src->getNumVerts(dm_src));
+ for (i = 0; i < numverts_dst; i++) {
+ mesh_remap_item_define(r_map, i, FLT_MAX, 0, 1, &i, &full_weight);
+ }
+ }
+ else {
+ BVHTreeFromMesh treedata = {NULL};
+ BVHTreeNearest nearest = {0};
+ BVHTreeRayHit rayhit = {0};
+ float hit_dist;
+
+ if (mode == MREMAP_MODE_VERT_NEAREST) {
+ bvhtree_from_mesh_verts(&treedata, dm_src, 0.0f, 2, 6);
+ nearest.index = -1;
+
+ for (i = 0; i < numverts_dst; i++) {
+ float tmp_co[3];
+
+ copy_v3_v3(tmp_co, verts_dst[i].co);
+
+ if (mesh_remap_bvhtree_query_nearest(
+ &treedata, &nearest, space_transform,
+ tmp_co, max_dist_sq, &hit_dist))
+ {
+ mesh_remap_item_define(r_map, i, hit_dist, 0, 1, &nearest.index, &full_weight);
+ }
+ else {
+ /* No source for this dest vertex! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+ }
+ else if (ELEM(mode, MREMAP_MODE_VERT_EDGE_NEAREST, MREMAP_MODE_VERT_EDGEINTERP_NEAREST)) {
+ MEdge *edges_src = dm_src->getEdgeArray(dm_src);
+ float (*vcos_src)[3] = MEM_mallocN(sizeof(*vcos_src) * (size_t)dm_src->getNumVerts(dm_src), __func__);
+ dm_src->getVertCos(dm_src, vcos_src);
+
+ bvhtree_from_mesh_edges(&treedata, dm_src, 0.0f, 2, 6);
+ nearest.index = -1;
+
+ for (i = 0; i < numverts_dst; i++) {
+ float tmp_co[3];
+
+ copy_v3_v3(tmp_co, verts_dst[i].co);
+
+ if (mesh_remap_bvhtree_query_nearest(
+ &treedata, &nearest, space_transform,
+ tmp_co, max_dist_sq, &hit_dist))
+ {
+ MEdge *me = &edges_src[nearest.index];
+ const float *v1cos = vcos_src[me->v1];
+ const float *v2cos = vcos_src[me->v2];
+
+ if (mode == MREMAP_MODE_VERT_EDGE_NEAREST) {
+ const float dist_v1 = len_squared_v3v3(tmp_co, v1cos);
+ const float dist_v2 = len_squared_v3v3(tmp_co, v2cos);
+ const int index = (int)((dist_v1 > dist_v2) ? me->v2 : me->v1);
+ mesh_remap_item_define(r_map, i, hit_dist, 0, 1, &index, &full_weight);
+ }
+ else if (mode == MREMAP_MODE_VERT_EDGEINTERP_NEAREST) {
+ int indices[2];
+ float weights[2];
+
+ indices[0] = (int)me->v1;
+ indices[1] = (int)me->v2;
+
+ /* Weight is inverse of point factor here... */
+ weights[0] = line_point_factor_v3(tmp_co, v2cos, v1cos);
+ CLAMP(weights[0], 0.0f, 1.0f);
+ weights[1] = 1.0f - weights[0];
+
+ mesh_remap_item_define(r_map, i, hit_dist, 0, 2, indices, weights);
+ }
+ }
+ else {
+ /* No source for this dest vertex! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+
+ MEM_freeN(vcos_src);
+ }
+ else if (ELEM(mode, MREMAP_MODE_VERT_POLY_NEAREST, MREMAP_MODE_VERT_POLYINTERP_NEAREST,
+ MREMAP_MODE_VERT_POLYINTERP_VNORPROJ))
+ {
+ MPoly *polys_src = dm_src->getPolyArray(dm_src);
+ MLoop *loops_src = dm_src->getLoopArray(dm_src);
+ float (*vcos_src)[3] = MEM_mallocN(sizeof(*vcos_src) * (size_t)dm_src->getNumVerts(dm_src), __func__);
+ int *tessface_to_poly_map_src;
+
+ size_t tmp_buff_size = MREMAP_DEFAULT_BUFSIZE;
+ float (*vcos)[3] = MEM_mallocN(sizeof(*vcos) * tmp_buff_size, __func__);
+ int *indices = MEM_mallocN(sizeof(*indices) * tmp_buff_size, __func__);
+ float *weights = MEM_mallocN(sizeof(*weights) * tmp_buff_size, __func__);
+
+ dm_src->getVertCos(dm_src, vcos_src);
+ bvhtree_from_mesh_faces(&treedata, dm_src, (mode & MREMAP_USE_NORPROJ) ? ray_radius : 0.0f, 2, 6);
+ /* bvhtree here uses tesselated faces... */
+ tessface_to_poly_map_src = dm_src->getTessFaceDataArray(dm_src, CD_ORIGINDEX);
+
+ if (mode == MREMAP_MODE_VERT_POLYINTERP_VNORPROJ) {
+ for (i = 0; i < numverts_dst; i++) {
+ float tmp_co[3], tmp_no[3];
+
+ copy_v3_v3(tmp_co, verts_dst[i].co);
+ normal_short_to_float_v3(tmp_no, verts_dst[i].no);
+
+ if (mesh_remap_bvhtree_query_raycast(
+ &treedata, &rayhit, space_transform,
+ tmp_co, tmp_no, ray_radius, max_dist, &hit_dist))
+ {
+ MPoly *mp_src = &polys_src[tessface_to_poly_map_src[rayhit.index]];
+ const int sources_num = mesh_remap_interp_poly_data_get(
+ mp_src, loops_src, (const float (*)[3])vcos_src, rayhit.co,
+ &tmp_buff_size, &vcos, false, &indices, &weights, true, NULL);
+
+ mesh_remap_item_define(r_map, i, hit_dist, 0, sources_num, indices, weights);
+ }
+ else {
+ /* No source for this dest vertex! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+ }
+ else {
+ nearest.index = -1;
+
+ for (i = 0; i < numverts_dst; i++) {
+ float tmp_co[3];
+
+ /* Convert the vertex to tree coordinates. */
+ copy_v3_v3(tmp_co, verts_dst[i].co);
+
+ if (mesh_remap_bvhtree_query_nearest(
+ &treedata, &nearest, space_transform,
+ tmp_co, max_dist_sq, &hit_dist))
+ {
+ MPoly *mp = &polys_src[tessface_to_poly_map_src[nearest.index]];
+
+ if (mode == MREMAP_MODE_VERT_POLY_NEAREST) {
+ int index;
+ mesh_remap_interp_poly_data_get(
+ mp, loops_src, (const float (*)[3])vcos_src, nearest.co,
+ &tmp_buff_size, &vcos, false, &indices, &weights, false,
+ &index);
+
+ mesh_remap_item_define(r_map, i, hit_dist, 0, 1, &index, &full_weight);
+ }
+ else if (mode == MREMAP_MODE_VERT_POLYINTERP_NEAREST) {
+ const int sources_num = mesh_remap_interp_poly_data_get(
+ mp, loops_src, (const float (*)[3])vcos_src, nearest.co,
+ &tmp_buff_size, &vcos, false, &indices, &weights, true,
+ NULL);
+
+ mesh_remap_item_define(r_map, i, hit_dist, 0, sources_num, indices, weights);
+ }
+ }
+ else {
+ /* No source for this dest vertex! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+ }
+
+ MEM_freeN(vcos_src);
+ MEM_freeN(vcos);
+ MEM_freeN(indices);
+ MEM_freeN(weights);
+ }
+ else {
+ printf("WARNING! Unsupported mesh-to-mesh vertex mapping mode (%d)!\n", mode);
+ memset(r_map->items, 0, sizeof(*r_map->items) * (size_t)numverts_dst);
+ }
+
+ free_bvhtree_from_mesh(&treedata);
+ }
+}
+
+void BKE_mesh_remap_calc_edges_from_dm(
+ const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius,
+ const MVert *verts_dst, const int numverts_dst, const MEdge *edges_dst, const int numedges_dst,
+ const bool UNUSED(dirty_nors_dst), DerivedMesh *dm_src, MeshPairRemap *r_map)
+{
+ const float full_weight = 1.0f;
+ const float max_dist_sq = max_dist * max_dist;
+ int i;
+
+ BLI_assert(mode & MREMAP_MODE_EDGE);
+
+ BKE_mesh_remap_init(r_map, numedges_dst);
+
+ if (mode == MREMAP_MODE_TOPOLOGY) {
+ BLI_assert(numedges_dst == dm_src->getNumEdges(dm_src));
+ for (i = 0; i < numedges_dst; i++) {
+ mesh_remap_item_define(r_map, i, FLT_MAX, 0, 1, &i, &full_weight);
+ }
+ }
+ else {
+ BVHTreeFromMesh treedata = {NULL};
+ BVHTreeNearest nearest = {0};
+ BVHTreeRayHit rayhit = {0};
+ float hit_dist;
+
+ if (mode == MREMAP_MODE_EDGE_VERT_NEAREST) {
+ const int num_verts_src = dm_src->getNumVerts(dm_src);
+ const int num_edges_src = dm_src->getNumEdges(dm_src);
+ MEdge *edges_src = dm_src->getEdgeArray(dm_src);
+ float (*vcos_src)[3] = MEM_mallocN(sizeof(*vcos_src) * (size_t)dm_src->getNumVerts(dm_src), __func__);
+
+ MeshElemMap *vert_to_edge_src_map;
+ int *vert_to_edge_src_map_mem;
+
+ struct {
+ float hit_dist;
+ int index;
+ } *v_dst_to_src_map = MEM_mallocN(sizeof(*v_dst_to_src_map) * (size_t)numverts_dst, __func__);
+
+ for (i = 0; i < numverts_dst; i++) {
+ v_dst_to_src_map[i].hit_dist = -1.0f;
+ }
+
+ BKE_mesh_vert_edge_map_create(&vert_to_edge_src_map, &vert_to_edge_src_map_mem,
+ edges_src, num_verts_src, num_edges_src);
+
+ dm_src->getVertCos(dm_src, vcos_src);
+
+ bvhtree_from_mesh_verts(&treedata, dm_src, 0.0f, 2, 6);
+ nearest.index = -1;
+
+ for (i = 0; i < numedges_dst; i++) {
+ const MEdge *e_dst = &edges_dst[i];
+ float best_totdist = FLT_MAX;
+ int best_eidx_src = -1;
+ int j = 2;
+
+ while (j--) {
+ const unsigned int vidx_dst = j ? e_dst->v1 : e_dst->v2;
+
+ /* Compute closest verts only once! */
+ if (v_dst_to_src_map[vidx_dst].hit_dist == -1.0f) {
+ float tmp_co[3];
+
+ copy_v3_v3(tmp_co, verts_dst[vidx_dst].co);
+
+ if (mesh_remap_bvhtree_query_nearest(
+ &treedata, &nearest, space_transform,
+ tmp_co, max_dist_sq, &hit_dist))
+ {
+ v_dst_to_src_map[vidx_dst].hit_dist = hit_dist;
+ v_dst_to_src_map[vidx_dst].index = nearest.index;
+ }
+ else {
+ /* No source for this dest vert! */
+ v_dst_to_src_map[vidx_dst].hit_dist = FLT_MAX;
+ }
+ }
+ }
+
+ /* Now, check all source edges of closest sources vertices, and select the one giving the smallest
+ * total verts-to-verts distance. */
+ for (j = 2; j--;) {
+ const unsigned int vidx_dst = j ? e_dst->v1 : e_dst->v2;
+ const float first_dist = v_dst_to_src_map[vidx_dst].hit_dist;
+ const int vidx_src = v_dst_to_src_map[vidx_dst].index;
+ int *eidx_src, k;
+
+ if (vidx_src < 0) {
+ continue;
+ }
+
+ eidx_src = vert_to_edge_src_map[vidx_src].indices;
+ k = vert_to_edge_src_map[vidx_src].count;
+
+ for (; k--; eidx_src++) {
+ MEdge *e_src = &edges_src[*eidx_src];
+ const float *other_co_src = vcos_src[BKE_mesh_edge_other_vert(e_src, vidx_src)];
+ const float *other_co_dst = verts_dst[BKE_mesh_edge_other_vert(e_dst, (int)vidx_dst)].co;
+ const float totdist = first_dist + len_v3v3(other_co_src, other_co_dst);
+
+ if (totdist < best_totdist) {
+ best_totdist = totdist;
+ best_eidx_src = *eidx_src;
+ }
+ }
+ }
+
+ if (best_eidx_src >= 0) {
+ const float *co1_src = vcos_src[edges_src[best_eidx_src].v1];
+ const float *co2_src = vcos_src[edges_src[best_eidx_src].v2];
+ const float *co1_dst = verts_dst[e_dst->v1].co;
+ const float *co2_dst = verts_dst[e_dst->v2].co;
+ float co_src[3], co_dst[3];
+
+ /* TODO: would need an isect_seg_seg_v3(), actually! */
+ const int isect_type = isect_line_line_v3(co1_src, co2_src, co1_dst, co2_dst, co_src, co_dst);
+ if (isect_type != 0) {
+ const float fac_src = line_point_factor_v3(co_src, co1_src, co2_src);
+ const float fac_dst = line_point_factor_v3(co_dst, co1_dst, co2_dst);
+ if (fac_src < 0.0f) {
+ copy_v3_v3(co_src, co1_src);
+ }
+ else if (fac_src > 1.0f) {
+ copy_v3_v3(co_src, co2_src);
+ }
+ if (fac_dst < 0.0f) {
+ copy_v3_v3(co_dst, co1_dst);
+ }
+ else if (fac_dst > 1.0f) {
+ copy_v3_v3(co_dst, co2_dst);
+ }
+ }
+ hit_dist = len_v3v3(co_dst, co_src);
+ mesh_remap_item_define(r_map, i, hit_dist, 0, 1, &best_eidx_src, &full_weight);
+ }
+ else {
+ /* No source for this dest edge! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+
+ MEM_freeN(vcos_src);
+ MEM_freeN(v_dst_to_src_map);
+ MEM_freeN(vert_to_edge_src_map);
+ MEM_freeN(vert_to_edge_src_map_mem);
+ }
+ else if (mode == MREMAP_MODE_EDGE_NEAREST) {
+ bvhtree_from_mesh_edges(&treedata, dm_src, 0.0f, 2, 6);
+ nearest.index = -1;
+
+ for (i = 0; i < numedges_dst; i++) {
+ float tmp_co[3];
+
+ interp_v3_v3v3(tmp_co, verts_dst[edges_dst[i].v1].co, verts_dst[edges_dst[i].v2].co, 0.5f);
+
+ if (mesh_remap_bvhtree_query_nearest(
+ &treedata, &nearest, space_transform,
+ tmp_co, max_dist_sq, &hit_dist))
+ {
+ mesh_remap_item_define(r_map, i, hit_dist, 0, 1, &nearest.index, &full_weight);
+ }
+ else {
+ /* No source for this dest edge! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+ }
+ else if (mode == MREMAP_MODE_EDGE_POLY_NEAREST) {
+ MEdge *edges_src = dm_src->getEdgeArray(dm_src);
+ MPoly *polys_src = dm_src->getPolyArray(dm_src);
+ MLoop *loops_src = dm_src->getLoopArray(dm_src);
+ float (*vcos_src)[3] = MEM_mallocN(sizeof(*vcos_src) * (size_t)dm_src->getNumVerts(dm_src), __func__);
+ int *tessface_to_poly_map_src;
+
+ dm_src->getVertCos(dm_src, vcos_src);
+ bvhtree_from_mesh_faces(&treedata, dm_src, 0.0f, 2, 6);
+ /* bvhtree here uses tesselated faces... */
+ tessface_to_poly_map_src = dm_src->getTessFaceDataArray(dm_src, CD_ORIGINDEX);
+
+ for (i = 0; i < numedges_dst; i++) {
+ float tmp_co[3];
+
+ interp_v3_v3v3(tmp_co, verts_dst[edges_dst[i].v1].co, verts_dst[edges_dst[i].v2].co, 0.5f);
+
+ if (mesh_remap_bvhtree_query_nearest(
+ &treedata, &nearest, space_transform,
+ tmp_co, max_dist_sq, &hit_dist))
+ {
+ MPoly *mp_src = &polys_src[tessface_to_poly_map_src[nearest.index]];
+ MLoop *ml_src = &loops_src[mp_src->loopstart];
+ int nloops = mp_src->totloop;
+ float best_dist_sq = FLT_MAX;
+ int best_eidx_src = -1;
+
+ for (; nloops--; ml_src++) {
+ MEdge *me_src = &edges_src[ml_src->e];
+ float *co1_src = vcos_src[me_src->v1];
+ float *co2_src = vcos_src[me_src->v2];
+ float co_src[3];
+ float dist_sq;
+
+ interp_v3_v3v3(co_src, co1_src, co2_src, 0.5f);
+ dist_sq = len_squared_v3v3(tmp_co, co_src);
+ if (dist_sq < best_dist_sq) {
+ best_dist_sq = dist_sq;
+ best_eidx_src = (int)ml_src->e;
+ }
+ }
+ if (best_eidx_src >= 0) {
+ mesh_remap_item_define(r_map, i, hit_dist, 0, 1, &best_eidx_src, &full_weight);
+ }
+ }
+ else {
+ /* No source for this dest edge! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+
+ MEM_freeN(vcos_src);
+ }
+ else if (mode == MREMAP_MODE_EDGE_EDGEINTERP_VNORPROJ) {
+ const int num_rays_min = 5, num_rays_max = 100;
+ const int numedges_src = dm_src->getNumEdges(dm_src);
+
+ /* Subtleness - this one we can allocate only max number of cast rays per edges! */
+ int *indices = MEM_mallocN(sizeof(*indices) * (size_t)min_ii(numedges_src, num_rays_max), __func__);
+ /* Here it's simpler to just allocate for all edges :/ */
+ float *weights = MEM_mallocN(sizeof(*weights) * (size_t)numedges_src, __func__);
+
+ bvhtree_from_mesh_edges(&treedata, dm_src, MREMAP_RAYCAST_APPROXIMATE_BVHEPSILON(ray_radius), 2, 6);
+
+ for (i = 0; i < numedges_dst; i++) {
+ /* For each dst edge, we sample some rays from it (interpolated from its vertices)
+ * and use their hits to interpolate from source edges. */
+ const MEdge *me = &edges_dst[i];
+ float tmp_co[3], v1_co[3], v2_co[3];
+ float tmp_no[3], v1_no[3], v2_no[3];
+
+ int grid_size;
+ float edge_dst_len;
+ float grid_step;
+
+ float totweights = 0.0f;
+ float hit_dist_accum = 0.0f;
+ int sources_num = 0;
+ int j;
+
+ copy_v3_v3(v1_co, verts_dst[me->v1].co);
+ copy_v3_v3(v2_co, verts_dst[me->v2].co);
+
+ normal_short_to_float_v3(v1_no, verts_dst[me->v1].no);
+ normal_short_to_float_v3(v2_no, verts_dst[me->v2].no);
+
+ /* We do our transform here, allows to interpolate from normals already in src space. */
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, v1_co);
+ BLI_space_transform_apply(space_transform, v2_co);
+ BLI_space_transform_apply_normal(space_transform, v1_no);
+ BLI_space_transform_apply_normal(space_transform, v2_no);
+ }
+
+ fill_vn_fl(weights, (int)numedges_src, 0.0f);
+
+ /* We adjust our ray-casting grid to ray_radius (the smaller, the more rays are cast),
+ * with lower/upper bounds. */
+ edge_dst_len = len_v3v3(v1_co, v2_co);
+
+ grid_size = (int)((edge_dst_len / ray_radius) + 0.5f);
+ CLAMP(grid_size, num_rays_min, num_rays_max); /* min 5 rays/edge, max 100. */
+
+ grid_step = 1.0f / (float)grid_size; /* Not actual distance here, rather an interp fac... */
+
+ /* And now we can cast all our rays, and see what we get! */
+ for (j = 0; j < grid_size; j++) {
+ const float fac = grid_step * (float)j;
+
+ int n = (ray_radius > 0.0f) ? MREMAP_RAYCAST_APPROXIMATE_NR : 1;
+ float w = 1.0f;
+
+ interp_v3_v3v3(tmp_co, v1_co, v2_co, fac);
+ interp_v3_v3v3_slerp_safe(tmp_no, v1_no, v2_no, fac);
+
+ while (n--) {
+ /* Note we handle dest to src space conversion ourself, here! */
+ if (mesh_remap_bvhtree_query_raycast(
+ &treedata, &rayhit, NULL,
+ tmp_co, tmp_no, ray_radius / w, max_dist, &hit_dist))
+ {
+ weights[rayhit.index] += w;
+ totweights += w;
+ hit_dist_accum += hit_dist;
+ break;
+ }
+ /* Next iteration will get bigger radius but smaller weight! */
+ w /= MREMAP_RAYCAST_APPROXIMATE_FAC;
+ }
+ }
+ /* A sampling is valid (as in, its result can be considered as valid sources) only if at least
+ * half of the rays found a source! */
+ if (totweights > ((float)grid_size / 2.0f)) {
+ for (j = 0; j < (int)numedges_src; j++) {
+ if (!weights[j]) {
+ continue;
+ }
+ /* Note: sources_num is always <= j! */
+ weights[sources_num] = weights[j] / totweights;
+ indices[sources_num] = j;
+ sources_num++;
+ }
+ mesh_remap_item_define(r_map, i, hit_dist_accum / totweights, 0,
+ sources_num, indices, weights);
+ }
+ else {
+ /* No source for this dest edge! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+
+ MEM_freeN(indices);
+ MEM_freeN(weights);
+ }
+ else {
+ printf("WARNING! Unsupported mesh-to-mesh edge mapping mode (%d)!\n", mode);
+ memset(r_map->items, 0, sizeof(*r_map->items) * (size_t)numedges_dst);
+ }
+
+ free_bvhtree_from_mesh(&treedata);
+ }
+}
+
+#define POLY_UNSET 0
+#define POLY_CENTER_INIT 1
+#define POLY_COMPLETE 2
+
+static void mesh_island_to_astar_graph_edge_process(
+ MeshIslandStore *islands, const int island_index, BLI_AStarGraph *as_graph,
+ MVert *verts, MPoly *polys, MLoop *loops,
+ const int edge_idx, BLI_bitmap *done_edges, MeshElemMap *edge_to_poly_map, const bool is_edge_innercut,
+ int *poly_island_index_map, float (*poly_centers)[3], unsigned char *poly_status)
+{
+ int *poly_island_indices = BLI_array_alloca(poly_island_indices, (size_t)edge_to_poly_map[edge_idx].count);
+ int i, j;
+
+ for (i = 0; i < edge_to_poly_map[edge_idx].count; i++) {
+ const int pidx = edge_to_poly_map[edge_idx].indices[i];
+ MPoly *mp = &polys[pidx];
+ const int pidx_isld = islands ? poly_island_index_map[pidx] : pidx;
+ void *custom_data = is_edge_innercut ? SET_INT_IN_POINTER(edge_idx) : SET_INT_IN_POINTER(-1);
+
+ if (UNLIKELY(islands && (islands->items_to_islands[mp->loopstart] != island_index))) {
+ /* poly not in current island, happens with border edges... */
+ poly_island_indices[i] = -1;
+ continue;
+ }
+
+ if (poly_status[pidx_isld] == POLY_COMPLETE) {
+ poly_island_indices[i] = pidx_isld;
+ continue;
+ }
+
+ if (poly_status[pidx_isld] == POLY_UNSET) {
+ BKE_mesh_calc_poly_center(mp, &loops[mp->loopstart], verts, poly_centers[pidx_isld]);
+ BLI_astar_node_init(as_graph, pidx_isld, poly_centers[pidx_isld]);
+ poly_status[pidx_isld] = POLY_CENTER_INIT;
+ }
+
+ for (j = i; j--;) {
+ float dist_cost;
+ const int pidx_isld_other = poly_island_indices[j];
+
+ if (pidx_isld_other == -1 || poly_status[pidx_isld_other] == POLY_COMPLETE) {
+ /* If the other poly is complete, that link has already been added! */
+ continue;
+ }
+ dist_cost = len_v3v3(poly_centers[pidx_isld_other], poly_centers[pidx_isld]);
+ BLI_astar_node_link_add(as_graph, pidx_isld_other, pidx_isld, dist_cost, custom_data);
+ }
+
+ poly_island_indices[i] = pidx_isld;
+ }
+
+ BLI_BITMAP_ENABLE(done_edges, edge_idx);
+}
+
+static void mesh_island_to_astar_graph(
+ MeshIslandStore *islands, const int island_index,
+ MVert *verts, MeshElemMap *edge_to_poly_map, const int numedges, MLoop *loops, MPoly *polys, const int numpolys,
+ BLI_AStarGraph *r_as_graph)
+{
+ MeshElemMap *island_poly_map = islands ? islands->islands[island_index] : NULL;
+ MeshElemMap *island_einnercut_map = islands ? islands->innercuts[island_index] : NULL;
+
+ int *poly_island_index_map = NULL;
+ BLI_bitmap *done_edges = BLI_BITMAP_NEW(numedges, __func__);
+
+ const int node_num = islands ? island_poly_map->count : numpolys;
+ unsigned char *poly_status = MEM_callocN(sizeof(*poly_status) * (size_t)node_num, __func__);
+ float (*poly_centers)[3];
+
+ int pidx_isld;
+ int i;
+
+ BLI_astar_graph_init(r_as_graph, node_num, NULL);
+ /* poly_centers is owned by graph memarena. */
+ poly_centers = BLI_memarena_calloc(r_as_graph->mem, sizeof(*poly_centers) * (size_t)node_num);
+
+ if (islands) {
+ /* poly_island_index_map is owned by graph memarena. */
+ poly_island_index_map = BLI_memarena_calloc(r_as_graph->mem, sizeof(*poly_island_index_map) * (size_t)numpolys);
+ for (i = island_poly_map->count; i--;) {
+ poly_island_index_map[island_poly_map->indices[i]] = i;
+ }
+
+ r_as_graph->custom_data = poly_island_index_map;
+
+ for (i = island_einnercut_map->count; i--;) {
+ mesh_island_to_astar_graph_edge_process(
+ islands, island_index, r_as_graph, verts, polys, loops,
+ island_einnercut_map->indices[i], done_edges, edge_to_poly_map, true,
+ poly_island_index_map, poly_centers, poly_status);
+ }
+ }
+
+ for (pidx_isld = node_num; pidx_isld--;) {
+ const int pidx = islands ? island_poly_map->indices[pidx_isld] : pidx_isld;
+ MPoly *mp = &polys[pidx];
+ int pl_idx, l_idx;
+
+ if (poly_status[pidx_isld] == POLY_COMPLETE) {
+ continue;
+ }
+
+ for (pl_idx = 0, l_idx = mp->loopstart; pl_idx < mp->totloop; pl_idx++, l_idx++) {
+ MLoop *ml = &loops[l_idx];
+
+ if (BLI_BITMAP_TEST(done_edges, ml->e)) {
+ continue;
+ }
+
+ mesh_island_to_astar_graph_edge_process(
+ islands, island_index, r_as_graph, verts, polys, loops,
+ (int)ml->e, done_edges, edge_to_poly_map, false,
+ poly_island_index_map, poly_centers, poly_status);
+ }
+ poly_status[pidx_isld] = POLY_COMPLETE;
+ }
+
+ MEM_freeN(done_edges);
+ MEM_freeN(poly_status);
+}
+
+#undef POLY_UNSET
+#undef POLY_CENTER_INIT
+#undef POLY_COMPLETE
+
+/* Our 'f_cost' callback func, to find shortest poly-path between two remapped-loops.
+ * Note we do not want to make innercuts 'walls' here, just detect when the shortest path goes by those. */
+static float mesh_remap_calc_loops_astar_f_cost(
+ BLI_AStarGraph *as_graph, BLI_AStarSolution *as_solution, BLI_AStarGNLink *link,
+ const int node_idx_curr, const int node_idx_next, const int node_idx_dst)
+{
+ float *co_next, *co_dest;
+
+ if (link && (GET_INT_FROM_POINTER(link->custom_data) != -1)) {
+ /* An innercut edge... We tag our solution as potentially crossing innercuts.
+ * Note it might not be the case in the end (AStar will explore around optimal path), but helps
+ * trimming off some processing later... */
+ if (!GET_INT_FROM_POINTER(as_solution->custom_data)) {
+ as_solution->custom_data = SET_INT_IN_POINTER(true);
+ }
+ }
+
+ /* Our heuristic part of current f_cost is distance from next node to destination one.
+ * It is guaranteed to be less than (or equal to) actual shortest poly-path between next node and destination one.
+ */
+ co_next = (float *)as_graph->nodes[node_idx_next].custom_data;
+ co_dest = (float *)as_graph->nodes[node_idx_dst].custom_data;
+ return (link ? (as_solution->g_costs[node_idx_curr] + link->cost) : 0.0f) + len_v3v3(co_next, co_dest);
+}
+
+#define ASTAR_STEPS_MAX 64
+
+
+void BKE_mesh_remap_calc_loops_from_dm(
+ const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius,
+ MVert *verts_dst, const int numverts_dst, MEdge *edges_dst, const int numedges_dst,
+ MLoop *loops_dst, const int numloops_dst, MPoly *polys_dst, const int numpolys_dst,
+ CustomData *ldata_dst, CustomData *pdata_dst,
+ const bool use_split_nors_dst, const float split_angle_dst, const bool dirty_nors_dst,
+ DerivedMesh *dm_src, const bool use_split_nors_src, const float split_angle_src,
+ MeshRemapIslandsCalc gen_islands_src, const float islands_precision_src, MeshPairRemap *r_map)
+{
+ const float full_weight = 1.0f;
+ const float max_dist_sq = max_dist * max_dist;
+
+ int i;
+
+ BLI_assert(mode & MREMAP_MODE_LOOP);
+ BLI_assert((islands_precision_src >= 0.0f) && (islands_precision_src <= 1.0f));
+
+ BKE_mesh_remap_init(r_map, numloops_dst);
+
+ if (mode == MREMAP_MODE_TOPOLOGY) {
+ /* In topology mapping, we assume meshes are identical, islands included! */
+ BLI_assert(numloops_dst == dm_src->getNumLoops(dm_src));
+ for (i = 0; i < numloops_dst; i++) {
+ mesh_remap_item_define(r_map, i, FLT_MAX, 0, 1, &i, &full_weight);
+ }
+ }
+ else {
+ BVHTreeFromMesh *treedata = NULL;
+ BVHTreeNearest nearest = {0};
+ BVHTreeRayHit rayhit = {0};
+ int num_trees = 0;
+ float hit_dist;
+
+ const bool use_from_vert = (mode & MREMAP_USE_VERT);
+
+ MeshIslandStore island_store = {0};
+ bool use_islands = false;
+
+ BLI_AStarGraph *as_graphdata = NULL;
+ BLI_AStarSolution as_solution = {0};
+ const int isld_steps_src = islands_precision_src ?
+ max_ii((int)(ASTAR_STEPS_MAX * islands_precision_src + 0.499f), 1) : 0;
+
+ float (*poly_nors_src)[3] = NULL;
+ float (*loop_nors_src)[3] = NULL;
+ float (*poly_nors_dst)[3] = NULL;
+ float (*loop_nors_dst)[3] = NULL;
+
+ MeshElemMap *vert_to_loop_map_src = NULL;
+ int *vert_to_loop_map_src_buff = NULL;
+ MeshElemMap *vert_to_poly_map_src = NULL;
+ int *vert_to_poly_map_src_buff = NULL;
+ MeshElemMap *edge_to_poly_map_src = NULL;
+ int *edge_to_poly_map_src_buff = NULL;
+ MeshElemMap *poly_to_tessface_map_src = NULL;
+ int *poly_to_tessface_map_src_buff = NULL;
+
+ /* Unlike above, those are one-to-one mappings, simpler! */
+ int *loop_to_poly_map_src = NULL;
+ int *tessface_to_poly_map_src = NULL;
+
+ bool verts_allocated_src;
+ MVert *verts_src = DM_get_vert_array(dm_src, &verts_allocated_src);
+ const int num_verts_src = dm_src->getNumVerts(dm_src);
+ float (*vcos_src)[3] = NULL;
+ bool edges_allocated_src;
+ MEdge *edges_src = DM_get_edge_array(dm_src, &edges_allocated_src);
+ const int num_edges_src = dm_src->getNumEdges(dm_src);
+ bool loops_allocated_src;
+ MLoop *loops_src = DM_get_loop_array(dm_src, &loops_allocated_src);
+ const int num_loops_src = dm_src->getNumLoops(dm_src);
+ bool polys_allocated_src;
+ MPoly *polys_src = DM_get_poly_array(dm_src, &polys_allocated_src);
+ const int num_polys_src = dm_src->getNumPolys(dm_src);
+ bool faces_allocated_src = false;
+ MFace *faces_src = NULL;
+ int num_faces_src = 0;
+
+ size_t buff_size_interp = MREMAP_DEFAULT_BUFSIZE;
+ float (*vcos_interp)[3] = NULL;
+ int *indices_interp = NULL;
+ float *weights_interp = NULL;
+
+ int tindex, pidx_dst, lidx_dst, plidx_dst, pidx_src, lidx_src, plidx_src;
+
+ IslandResult **islands_res;
+ size_t islands_res_buff_size = MREMAP_DEFAULT_BUFSIZE;
+
+ const float bvh_epsilon = (mode & MREMAP_USE_NORPROJ) ? MREMAP_RAYCAST_APPROXIMATE_BVHEPSILON(ray_radius) : 0.0f;
+
+ if (!use_from_vert) {
+ vcos_src = MEM_mallocN(sizeof(*vcos_src) * (size_t)num_verts_src, __func__);
+ dm_src->getVertCos(dm_src, vcos_src);
+
+ vcos_interp = MEM_mallocN(sizeof(*vcos_interp) * buff_size_interp, __func__);
+ indices_interp = MEM_mallocN(sizeof(*indices_interp) * buff_size_interp, __func__);
+ weights_interp = MEM_mallocN(sizeof(*weights_interp) * buff_size_interp, __func__);
+ }
+
+ {
+ const bool need_lnors_src = (mode & MREMAP_USE_LOOP) && (mode & MREMAP_USE_NORMAL);
+ const bool need_lnors_dst = need_lnors_src || (mode & MREMAP_USE_NORPROJ);
+ const bool need_pnors_src = need_lnors_src || ((mode & MREMAP_USE_POLY) && (mode & MREMAP_USE_NORMAL));
+ const bool need_pnors_dst = need_lnors_dst || need_pnors_src;
+
+ if (need_pnors_dst) {
+ /* Cache poly nors into a temp CDLayer. */
+ poly_nors_dst = CustomData_get_layer(pdata_dst, CD_NORMAL);
+ if (!poly_nors_dst) {
+ poly_nors_dst = CustomData_add_layer(pdata_dst, CD_NORMAL, CD_CALLOC, NULL, numpolys_dst);
+ CustomData_set_layer_flag(pdata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
+ if (dirty_nors_dst) {
+ BKE_mesh_calc_normals_poly(verts_dst, numverts_dst, loops_dst, polys_dst,
+ numloops_dst, numpolys_dst, poly_nors_dst, true);
+ }
+ }
+ if (need_lnors_dst) {
+ short (*custom_nors_dst)[2] = CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL);
+
+ /* Cache poly nors into a temp CDLayer. */
+ loop_nors_dst = CustomData_get_layer(ldata_dst, CD_NORMAL);
+ if (dirty_nors_dst || !loop_nors_dst) {
+ if (!loop_nors_dst) {
+ loop_nors_dst = CustomData_add_layer(ldata_dst, CD_NORMAL, CD_CALLOC, NULL, numloops_dst);
+ CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
+ BKE_mesh_normals_loop_split(verts_dst, numverts_dst, edges_dst, numedges_dst,
+ loops_dst, loop_nors_dst, numloops_dst,
+ polys_dst, (const float (*)[3])poly_nors_dst, numpolys_dst,
+ use_split_nors_dst, split_angle_dst, NULL, custom_nors_dst, NULL);
+ }
+ }
+ if (need_pnors_src || need_lnors_src) {
+ /* Simpler for now, calcNormals never stores pnors :( */
+ dm_src->calcLoopNormals(dm_src, use_split_nors_src, split_angle_src);
+
+ if (need_pnors_src) {
+ poly_nors_src = dm_src->getPolyDataArray(dm_src, CD_NORMAL);
+ }
+ if (need_lnors_src) {
+ loop_nors_src = dm_src->getLoopDataArray(dm_src, CD_NORMAL);
+ }
+ }
+ }
+
+ if (use_from_vert) {
+ BKE_mesh_vert_loop_map_create(&vert_to_loop_map_src, &vert_to_loop_map_src_buff,
+ polys_src, loops_src, num_verts_src, num_polys_src, num_loops_src);
+ if (mode & MREMAP_USE_POLY) {
+ BKE_mesh_vert_poly_map_create(&vert_to_poly_map_src, &vert_to_poly_map_src_buff,
+ polys_src, loops_src, num_verts_src, num_polys_src, num_loops_src);
+ }
+ }
+
+ /* Needed for islands (or plain mesh) to AStar graph conversion. */
+ BKE_mesh_edge_poly_map_create(&edge_to_poly_map_src, &edge_to_poly_map_src_buff,
+ edges_src, num_edges_src, polys_src, num_polys_src, loops_src, num_loops_src);
+ if (use_from_vert) {
+ loop_to_poly_map_src = MEM_mallocN(sizeof(*loop_to_poly_map_src) * (size_t)num_loops_src, __func__);
+ for (pidx_src = 0; pidx_src < num_polys_src; pidx_src++) {
+ MPoly *mp = &polys_src[pidx_src];
+ for (plidx_src = 0, lidx_src = mp->loopstart; plidx_src < mp->totloop; plidx_src++, lidx_src++) {
+ loop_to_poly_map_src[lidx_src] = pidx_src;
+ }
+ }
+ }
+
+ /* Island makes things slightly more complex here.
+ * Basically, we:
+ * * Make one treedata for each island's elements.
+ * * Check all loops of a same dest poly against all treedata.
+ * * Choose the island's elements giving the best results.
+ */
+
+ /* First, generate the islands, if possible. */
+ if (gen_islands_src) {
+ use_islands = gen_islands_src(
+ verts_src, num_verts_src,
+ edges_src, num_edges_src,
+ polys_src, num_polys_src,
+ loops_src, num_loops_src,
+ &island_store);
+
+ num_trees = use_islands ? island_store.islands_num : 1;
+ treedata = MEM_callocN(sizeof(*treedata) * (size_t)num_trees, __func__);
+ if (isld_steps_src) {
+ as_graphdata = MEM_callocN(sizeof(*as_graphdata) * (size_t)num_trees, __func__);
+ }
+
+ if (use_islands) {
+ /* We expect our islands to contain poly indices, with edge indices of 'inner cuts',
+ * and a mapping loops -> islands indices.
+ * This implies all loops of a same poly are in the same island. */
+ BLI_assert((island_store.item_type == MISLAND_TYPE_LOOP) &&
+ (island_store.island_type == MISLAND_TYPE_POLY) &&
+ (island_store.innercut_type == MISLAND_TYPE_EDGE));
+ }
+ }
+ else {
+ num_trees = 1;
+ treedata = MEM_callocN(sizeof(*treedata), __func__);
+ if (isld_steps_src) {
+ as_graphdata = MEM_callocN(sizeof(*as_graphdata), __func__);
+ }
+ }
+
+ /* Build our AStar graphs. */
+ if (isld_steps_src) {
+ for (tindex = 0; tindex < num_trees; tindex++) {
+ mesh_island_to_astar_graph(
+ use_islands ? &island_store : NULL, tindex, verts_src, edge_to_poly_map_src, num_edges_src,
+ loops_src, polys_src, num_polys_src, &as_graphdata[tindex]);
+ }
+ }
+
+ /* Build our BVHtrees, either from verts or tessfaces. */
+ if (use_from_vert) {
+ if (use_islands) {
+ BLI_bitmap *verts_active = BLI_BITMAP_NEW((size_t)num_verts_src, __func__);
+
+ for (tindex = 0; tindex < num_trees; tindex++) {
+ MeshElemMap *isld = island_store.islands[tindex];
+ int num_verts_active = 0;
+ BLI_BITMAP_SET_ALL(verts_active, false, (size_t)num_verts_src);
+ for (i = 0; i < isld->count; i++) {
+ MPoly *mp_src = &polys_src[isld->indices[i]];
+ for (lidx_src = mp_src->loopstart; lidx_src < mp_src->loopstart + mp_src->totloop; lidx_src++) {
+ BLI_BITMAP_ENABLE(verts_active, loops_src[lidx_src].v);
+ num_verts_active++;
+ }
+ }
+ /* verts 'ownership' is transfered to treedata here, which will handle its freeing. */
+ bvhtree_from_mesh_verts_ex(&treedata[tindex], verts_src, num_verts_src, verts_allocated_src,
+ verts_active, num_verts_active, bvh_epsilon, 2, 6);
+ if (verts_allocated_src) {
+ verts_allocated_src = false; /* Only 'give' our verts once, to first tree! */
+ }
+ }
+
+ MEM_freeN(verts_active);
+ }
+ else {
+ BLI_assert(num_trees == 1);
+ bvhtree_from_mesh_verts(&treedata[0], dm_src, bvh_epsilon, 2, 6);
+ }
+ }
+ else { /* We use polygons. */
+ if (use_islands) {
+ /* bvhtree here uses tesselated faces... */
+ const unsigned int dirty_tess_flag = dm_src->dirty & DM_DIRTY_TESS_CDLAYERS;
+ BLI_bitmap *faces_active;
+
+ /* We do not care about tessellated data here, only geometry itself is important. */
+ if (dirty_tess_flag) {
+ dm_src->dirty &= ~dirty_tess_flag;
+ }
+ DM_ensure_tessface(dm_src);
+ if (dirty_tess_flag) {
+ dm_src->dirty |= dirty_tess_flag;
+ }
+ faces_src = DM_get_tessface_array(dm_src, &faces_allocated_src);
+ num_faces_src = dm_src->getNumTessFaces(dm_src);
+ tessface_to_poly_map_src = dm_src->getTessFaceDataArray(dm_src, CD_ORIGINDEX);
+ faces_active = BLI_BITMAP_NEW((size_t)num_faces_src, __func__);
+
+ for (tindex = 0; tindex < num_trees; tindex++) {
+ int num_faces_active = 0;
+ BLI_BITMAP_SET_ALL(faces_active, false, (size_t)num_faces_src);
+ for (i = 0; i < num_faces_src; i++) {
+ MPoly *mp_src = &polys_src[tessface_to_poly_map_src[i]];
+ if (island_store.items_to_islands[mp_src->loopstart] == tindex) {
+ BLI_BITMAP_ENABLE(faces_active, i);
+ num_faces_active++;
+ }
+ }
+ /* verts 'ownership' is transfered to treedata here, which will handle its freeing. */
+ bvhtree_from_mesh_faces_ex(
+ &treedata[tindex], verts_src, verts_allocated_src,
+ faces_src, num_faces_src, faces_allocated_src,
+ faces_active, num_faces_active, bvh_epsilon, 2, 6);
+ if (verts_allocated_src) {
+ verts_allocated_src = false; /* Only 'give' our verts once, to first tree! */
+ }
+ if (faces_allocated_src) {
+ faces_allocated_src = false; /* Only 'give' our faces once, to first tree! */
+ }
+ }
+
+ MEM_freeN(faces_active);
+ }
+ else {
+ BLI_assert(num_trees == 1);
+ bvhtree_from_mesh_faces(&treedata[0], dm_src, bvh_epsilon, 2, 6);
+ tessface_to_poly_map_src = dm_src->getTessFaceDataArray(dm_src, CD_ORIGINDEX);
+ }
+ }
+
+ /* And check each dest poly! */
+ islands_res = MEM_mallocN(sizeof(*islands_res) * (size_t)num_trees, __func__);
+ for (tindex = 0; tindex < num_trees; tindex++) {
+ islands_res[tindex] = MEM_mallocN(sizeof(**islands_res) * islands_res_buff_size, __func__);
+ }
+
+ for (pidx_dst = 0; pidx_dst < numpolys_dst; pidx_dst++) {
+ MPoly *mp_dst = &polys_dst[pidx_dst];
+ float (*pnor_dst)[3] = &poly_nors_dst[pidx_dst];
+
+ if ((size_t)mp_dst->totloop > islands_res_buff_size) {
+ islands_res_buff_size = (size_t)mp_dst->totloop;
+ for (tindex = 0; tindex < num_trees; tindex++) {
+ islands_res[tindex] = MEM_reallocN(islands_res[tindex], sizeof(**islands_res) * islands_res_buff_size);
+ }
+ }
+
+ for (tindex = 0; tindex < num_trees; tindex++) {
+ BVHTreeFromMesh *tdata = &treedata[tindex];
+ MLoop *ml_dst = &loops_dst[mp_dst->loopstart];
+
+ for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++, ml_dst++) {
+ if (use_from_vert) {
+ float tmp_co[3];
+ MeshElemMap *vert_to_refelem_map_src = NULL;
+
+ copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
+ nearest.index = -1;
+
+ if (mesh_remap_bvhtree_query_nearest(
+ tdata, &nearest, space_transform,
+ tmp_co, max_dist_sq, &hit_dist))
+ {
+ float (*nor_dst)[3];
+ float (*nors_src)[3];
+ float best_nor_dot = -2.0f;
+ int best_index_src = -1;
+
+ if (mode == MREMAP_MODE_LOOP_NEAREST_LOOPNOR) {
+ nor_dst = &loop_nors_dst[plidx_dst + mp_dst->loopstart];
+ nors_src = loop_nors_src;
+ vert_to_refelem_map_src = vert_to_loop_map_src;
+ }
+ else { /* if (mode == MREMAP_MODE_LOOP_NEAREST_POLYNOR) { */
+ nor_dst = pnor_dst;
+ nors_src = poly_nors_src;
+ vert_to_refelem_map_src = vert_to_poly_map_src;
+ }
+
+ for (i = vert_to_refelem_map_src[nearest.index].count; i--;) {
+ const int index_src = vert_to_refelem_map_src[nearest.index].indices[i];
+ const float dot = dot_v3v3(nors_src[index_src], *nor_dst);
+ if (dot > best_nor_dot) {
+ best_nor_dot = dot;
+ best_index_src = index_src;
+ }
+ }
+ if (mode == MREMAP_MODE_LOOP_NEAREST_POLYNOR) {
+ /* Our best_index_src is a poly one for now!
+ * Have to find its loop matching our closest vertex. */
+ MPoly *mp_src = &polys_src[best_index_src];
+ MLoop *ml_src = &loops_src[mp_src->loopstart];
+ for (plidx_src = 0; plidx_src < mp_src->totloop; plidx_src++, ml_src++) {
+ if ((int)ml_src->v == nearest.index) {
+ best_index_src = plidx_src + mp_src->loopstart;
+ break;
+ }
+ }
+ }
+ islands_res[tindex][plidx_dst].factor = hit_dist ? (1.0f / (hit_dist * best_nor_dot)) : 1e18f;
+ islands_res[tindex][plidx_dst].hit_dist = hit_dist;
+ islands_res[tindex][plidx_dst].index_src = best_index_src;
+ }
+ else {
+ /* No source for this dest loop! */
+ islands_res[tindex][plidx_dst].factor = 0.0f;
+ islands_res[tindex][plidx_dst].hit_dist = FLT_MAX;
+ islands_res[tindex][plidx_dst].index_src = -1;
+ }
+ }
+ else if (mode & MREMAP_USE_NORPROJ) {
+ float tmp_co[3], tmp_no[3];
+
+ int n = (ray_radius > 0.0f) ? MREMAP_RAYCAST_APPROXIMATE_NR : 1;
+ float w = 1.0f;
+
+ copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
+ copy_v3_v3(tmp_no, loop_nors_dst[plidx_dst + mp_dst->loopstart]);
+
+ /* We do our transform here, since we may do several raycast/nearest queries. */
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, tmp_co);
+ BLI_space_transform_apply_normal(space_transform, tmp_no);
+ }
+
+ while (n--) {
+ /* Note we handle dest to src space conversion ourself, here! */
+ if (mesh_remap_bvhtree_query_raycast(
+ tdata, &rayhit, NULL,
+ tmp_co, tmp_no, ray_radius / w, max_dist, &hit_dist))
+ {
+ islands_res[tindex][plidx_dst].factor = (hit_dist ? (1.0f / hit_dist) : 1e18f) * w;
+ islands_res[tindex][plidx_dst].hit_dist = hit_dist;
+ islands_res[tindex][plidx_dst].index_src = tessface_to_poly_map_src[rayhit.index];
+ copy_v3_v3(islands_res[tindex][plidx_dst].hit_point, rayhit.co);
+ break;
+ }
+ /* Next iteration will get bigger radius but smaller weight! */
+ w /= MREMAP_RAYCAST_APPROXIMATE_FAC;
+ }
+ if (n == -1) {
+ /* Fallback to 'nearest' hit here, loops usually comes in 'face group', not good to
+ * have only part of one dest face's loops to map to source.
+ * Note that since we give this a null weight, if whole weight for a given face
+ * is null, it means none of its loop mapped to this source island, hence we can skip it
+ * later.
+ */
+ copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
+ nearest.index = -1;
+
+ /* In any case, this fallback nearest hit should have no weight at all
+ * in 'best island' decision! */
+ islands_res[tindex][plidx_dst].factor = 0.0f;
+
+ /* Note we handle dest to src space conversion ourself, here! */
+ if (mesh_remap_bvhtree_query_nearest(
+ tdata, &nearest, NULL,
+ tmp_co, max_dist_sq, &hit_dist))
+ {
+ islands_res[tindex][plidx_dst].hit_dist = hit_dist;
+ islands_res[tindex][plidx_dst].index_src = tessface_to_poly_map_src[nearest.index];
+ copy_v3_v3(islands_res[tindex][plidx_dst].hit_point, nearest.co);
+ }
+ else {
+ /* No source for this dest loop! */
+ islands_res[tindex][plidx_dst].hit_dist = FLT_MAX;
+ islands_res[tindex][plidx_dst].index_src = -1;
+ }
+ }
+ }
+ else { /* Nearest poly either to use all its loops/verts or just closest one. */
+ float tmp_co[3];
+
+ copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
+ nearest.index = -1;
+
+ if (mesh_remap_bvhtree_query_nearest(
+ tdata, &nearest, space_transform,
+ tmp_co, max_dist_sq, &hit_dist))
+ {
+ islands_res[tindex][plidx_dst].factor = hit_dist ? (1.0f / hit_dist) : 1e18f;
+ islands_res[tindex][plidx_dst].hit_dist = hit_dist;
+ islands_res[tindex][plidx_dst].index_src = tessface_to_poly_map_src[nearest.index];
+ copy_v3_v3(islands_res[tindex][plidx_dst].hit_point, nearest.co);
+ }
+ else {
+ /* No source for this dest loop! */
+ islands_res[tindex][plidx_dst].factor = 0.0f;
+ islands_res[tindex][plidx_dst].hit_dist = FLT_MAX;
+ islands_res[tindex][plidx_dst].index_src = -1;
+ }
+ }
+ }
+ }
+
+ /* And now, find best island to use! */
+ /* We have to first select the 'best source island' for given dst poly and its loops.
+ * Then, we have to check that poly does not 'spread' across some island's limits
+ * (like inner seams for UVs, etc.).
+ * Note we only still partially support that kind of situation here, i.e. polys spreading over actual cracks
+ * (like a narrow space without faces on src, splitting a 'tube-like' geometry). That kind of situation
+ * should be relatively rare, though.
+ */
+ /* XXX This block in itself is big and complex enough to be a separate function but... it uses a bunch
+ * of locale vars. Not worth sending all that through parameters (for now at least). */
+ {
+ BLI_AStarGraph *as_graph = NULL;
+ int *poly_island_index_map = NULL;
+ int pidx_src_prev = -1;
+
+ MeshElemMap *best_island = NULL;
+ float best_island_fac = 0.0f;
+ int best_island_index = -1;
+
+ for (tindex = 0; tindex < num_trees; tindex++) {
+ float island_fac = 0.0f;
+
+ for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++) {
+ island_fac += islands_res[tindex][plidx_dst].factor;
+ }
+ island_fac /= (float)mp_dst->totloop;
+
+ if (island_fac > best_island_fac) {
+ best_island_fac = island_fac;
+ best_island_index = tindex;
+ }
+ }
+
+ if (best_island_index != -1 && isld_steps_src) {
+ best_island = use_islands ? island_store.islands[best_island_index] : NULL;
+ as_graph = &as_graphdata[best_island_index];
+ poly_island_index_map = (int *)as_graph->custom_data;
+ BLI_astar_solution_init(as_graph, &as_solution, NULL);
+ }
+
+ for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++) {
+ IslandResult *isld_res;
+ lidx_dst = plidx_dst + mp_dst->loopstart;
+
+ if (best_island_index == -1) {
+ /* No source for any loops of our dest poly in any source islands. */
+ BKE_mesh_remap_item_define_invalid(r_map, lidx_dst);
+ continue;
+ }
+
+ as_solution.custom_data = SET_INT_IN_POINTER(false);
+
+ isld_res = &islands_res[best_island_index][plidx_dst];
+ if (use_from_vert) {
+ /* Indices stored in islands_res are those of loops, one per dest loop. */
+ lidx_src = isld_res->index_src;
+ if (lidx_src >= 0) {
+ pidx_src = loop_to_poly_map_src[lidx_src];
+ /* If prev and curr poly are the same, no need to do anything more!!! */
+ if (!ELEM(pidx_src_prev, -1, pidx_src) && isld_steps_src) {
+ int pidx_isld_src, pidx_isld_src_prev;
+ if (poly_island_index_map) {
+ pidx_isld_src = poly_island_index_map[pidx_src];
+ pidx_isld_src_prev = poly_island_index_map[pidx_src_prev];
+ }
+ else {
+ pidx_isld_src = pidx_src;
+ pidx_isld_src_prev = pidx_src_prev;
+ }
+
+ BLI_astar_graph_solve(
+ as_graph, pidx_isld_src_prev, pidx_isld_src,
+ mesh_remap_calc_loops_astar_f_cost, &as_solution, isld_steps_src);
+ if (GET_INT_FROM_POINTER(as_solution.custom_data) && (as_solution.steps > 0)) {
+ /* Find first 'cutting edge' on path, and bring back lidx_src on poly just
+ * before that edge.
+ * Note we could try to be much smarter (like e.g. storing a whole poly's indices,
+ * and making decision (on which side of cutting edge(s!) to be) on the end,
+ * but this is one more level of complexity, better to first see if
+ * simple solution works!
+ */
+ int last_valid_pidx_isld_src = -1;
+ /* Note we go backward here, from dest to src poly. */
+ for (i = as_solution.steps - 1; i--;) {
+ BLI_AStarGNLink *as_link = as_solution.prev_links[pidx_isld_src];
+ const int eidx = GET_INT_FROM_POINTER(as_link->custom_data);
+ pidx_isld_src = as_solution.prev_nodes[pidx_isld_src];
+ BLI_assert(pidx_isld_src != -1);
+ if (eidx != -1) {
+ /* we are 'crossing' a cutting edge. */
+ last_valid_pidx_isld_src = pidx_isld_src;
+ }
+ }
+ if (last_valid_pidx_isld_src != -1) {
+ /* Find a new valid loop in that new poly (nearest one for now).
+ * Note we could be much more subtle here, again that's for later... */
+ MPoly *mp_src;
+ MLoop *ml_src, *ml_dst = &loops_dst[lidx_dst];
+ int j;
+ float best_dist_sq = FLT_MAX;
+ float tmp_co[3];
+
+ copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
+
+ /* We do our transform here, since we may do several raycast/nearest queries. */
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, tmp_co);
+ }
+
+ pidx_src = use_islands ? best_island->indices[last_valid_pidx_isld_src] :
+ last_valid_pidx_isld_src;
+ mp_src = &polys_src[pidx_src];
+ ml_src = &loops_src[mp_src->loopstart];
+ for (j = 0; j < mp_src->totloop; j++, ml_src++) {
+ const float dist_sq = len_squared_v3v3(verts_src[ml_src->v].co, tmp_co);
+ if (dist_sq < best_dist_sq) {
+ best_dist_sq = dist_sq;
+ lidx_src = mp_src->loopstart + j;
+ }
+ }
+ }
+ }
+ }
+ mesh_remap_item_define(
+ r_map, lidx_dst, isld_res->hit_dist,
+ best_island_index, 1, &lidx_src, &full_weight);
+ pidx_src_prev = pidx_src;
+ }
+ else {
+ /* No source for this loop in this island. */
+ /* TODO: would probably be better to get a source at all cost in best island anyway? */
+ mesh_remap_item_define(
+ r_map, lidx_dst, FLT_MAX,
+ best_island_index, 0, NULL, NULL);
+ }
+ }
+ else {
+ /* Else, we use source poly, indices stored in islands_res are those of polygons. */
+ pidx_src = isld_res->index_src;
+ if (pidx_src >= 0) {
+ MPoly *mp_src = &polys_src[pidx_src];
+ float *hit_co = isld_res->hit_point;
+ int best_loop_index_src;
+
+ /* If prev and curr poly are the same, no need to do anything more!!! */
+ if (!ELEM(pidx_src_prev, -1, pidx_src) && isld_steps_src) {
+ int pidx_isld_src, pidx_isld_src_prev;
+ if (poly_island_index_map) {
+ pidx_isld_src = poly_island_index_map[pidx_src];
+ pidx_isld_src_prev = poly_island_index_map[pidx_src_prev];
+ }
+ else {
+ pidx_isld_src = pidx_src;
+ pidx_isld_src_prev = pidx_src_prev;
+ }
+
+ BLI_astar_graph_solve(
+ as_graph, pidx_isld_src_prev, pidx_isld_src,
+ mesh_remap_calc_loops_astar_f_cost, &as_solution, isld_steps_src);
+ if (GET_INT_FROM_POINTER(as_solution.custom_data) && (as_solution.steps > 0)) {
+ /* Find first 'cutting edge' on path, and bring back lidx_src on poly just
+ * before that edge.
+ * Note we could try to be much smarter (like e.g. storing a whole poly's indices,
+ * and making decision (one which side of cutting edge(s!) to be on the end,
+ * but this is one more level of complexity, better to first see if
+ * simple solution works!
+ */
+ int last_valid_pidx_isld_src = -1;
+ /* Note we go backward here, from dest to src poly. */
+ for (i = as_solution.steps - 1; i--;) {
+ BLI_AStarGNLink *as_link = as_solution.prev_links[pidx_isld_src];
+ int eidx = GET_INT_FROM_POINTER(as_link->custom_data);
+
+ pidx_isld_src = as_solution.prev_nodes[pidx_isld_src];
+ BLI_assert(pidx_isld_src != -1);
+ if (eidx != -1) {
+ /* we are 'crossing' a cutting edge. */
+ last_valid_pidx_isld_src = pidx_isld_src;
+ }
+ }
+ if (last_valid_pidx_isld_src != -1) {
+ /* Find a new valid loop in that new poly (nearest point on poly for now).
+ * Note we could be much more subtle here, again that's for later... */
+ MLoop *ml_dst = &loops_dst[lidx_dst];
+ float best_dist_sq = FLT_MAX;
+ float tmp_co[3];
+ int j;
+
+ copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co);
+
+ /* We do our transform here, since we may do several raycast/nearest queries. */
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, tmp_co);
+ }
+
+ pidx_src = use_islands ? best_island->indices[last_valid_pidx_isld_src] :
+ last_valid_pidx_isld_src;
+ mp_src = &polys_src[pidx_src];
+
+ /* Create that one on demand. */
+ if (poly_to_tessface_map_src == NULL) {
+ BKE_mesh_origindex_map_create(
+ &poly_to_tessface_map_src, &poly_to_tessface_map_src_buff,
+ num_faces_src, tessface_to_poly_map_src, num_polys_src);
+ }
+
+ for (j = poly_to_tessface_map_src[pidx_src].count; j--;) {
+ float h[3];
+ MFace *mf = &faces_src[poly_to_tessface_map_src[pidx_src].indices[j]];
+ float dist_sq;
+
+ closest_on_tri_to_point_v3(
+ h, tmp_co,
+ vcos_src[mf->v1], vcos_src[mf->v2], vcos_src[mf->v3]);
+ dist_sq = len_squared_v3v3(tmp_co, h);
+ if (dist_sq < best_dist_sq) {
+ copy_v3_v3(hit_co, h);
+ best_dist_sq = dist_sq;
+ }
+ if (mf->v4) {
+ closest_on_tri_to_point_v3(
+ h, tmp_co,
+ vcos_src[mf->v1], vcos_src[mf->v3], vcos_src[mf->v4]);
+ dist_sq = len_squared_v3v3(tmp_co, h);
+ if (dist_sq < best_dist_sq) {
+ copy_v3_v3(hit_co, h);
+ best_dist_sq = dist_sq;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (mode == MREMAP_MODE_LOOP_POLY_NEAREST) {
+ mesh_remap_interp_poly_data_get(
+ mp_src, loops_src, (const float (*)[3])vcos_src, hit_co,
+ &buff_size_interp, &vcos_interp, true, &indices_interp,
+ &weights_interp, false, &best_loop_index_src);
+
+ mesh_remap_item_define(
+ r_map, lidx_dst, isld_res->hit_dist,
+ best_island_index, 1, &best_loop_index_src, &full_weight);
+ }
+ else {
+ const int sources_num = mesh_remap_interp_poly_data_get(
+ mp_src, loops_src, (const float (*)[3])vcos_src, hit_co,
+ &buff_size_interp, &vcos_interp, true, &indices_interp,
+ &weights_interp, true, NULL);
+
+ mesh_remap_item_define(
+ r_map, lidx_dst,
+ isld_res->hit_dist, best_island_index,
+ sources_num, indices_interp, weights_interp);
+ }
+
+ pidx_src_prev = pidx_src;
+ }
+ else {
+ /* No source for this loop in this island. */
+ /* TODO: would probably be better to get a source at all cost in best island anyway? */
+ mesh_remap_item_define(r_map, lidx_dst, FLT_MAX, best_island_index, 0, NULL, NULL);
+ }
+ }
+ }
+
+ BLI_astar_solution_clear(&as_solution);
+ }
+ }
+
+ for (tindex = 0; tindex < num_trees; tindex++) {
+ MEM_freeN(islands_res[tindex]);
+ free_bvhtree_from_mesh(&treedata[tindex]);
+ if (isld_steps_src) {
+ BLI_astar_graph_free(&as_graphdata[tindex]);
+ }
+ }
+ MEM_freeN(islands_res);
+ BKE_mesh_loop_islands_free(&island_store);
+ MEM_freeN(treedata);
+ if (isld_steps_src) {
+ MEM_freeN(as_graphdata);
+ BLI_astar_solution_free(&as_solution);
+ }
+
+ if (verts_allocated_src) {
+ MEM_freeN(verts_src);
+ }
+ if (vcos_src) {
+ MEM_freeN(vcos_src);
+ }
+ if (edges_allocated_src) {
+ MEM_freeN(edges_src);
+ }
+ if (loops_allocated_src) {
+ MEM_freeN(loops_src);
+ }
+ if (polys_allocated_src) {
+ MEM_freeN(polys_src);
+ }
+ if (faces_allocated_src) {
+ MEM_freeN(faces_src);
+ }
+ if (vert_to_loop_map_src_buff) {
+ MEM_freeN(vert_to_loop_map_src_buff);
+ }
+ if (vert_to_poly_map_src_buff) {
+ MEM_freeN(vert_to_poly_map_src_buff);
+ }
+ if (edge_to_poly_map_src_buff) {
+ MEM_freeN(edge_to_poly_map_src_buff);
+ }
+ if (poly_to_tessface_map_src_buff) {
+ MEM_freeN(poly_to_tessface_map_src_buff);
+ }
+ if (loop_to_poly_map_src) {
+ MEM_freeN(loop_to_poly_map_src);
+ }
+ if (vcos_interp) {
+ MEM_freeN(vcos_interp);
+ }
+ if (indices_interp) {
+ MEM_freeN(indices_interp);
+ }
+ if (weights_interp) {
+ MEM_freeN(weights_interp);
+ }
+ }
+}
+
+void BKE_mesh_remap_calc_polys_from_dm(
+ const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius,
+ MVert *verts_dst, const int numverts_dst, MLoop *loops_dst, const int numloops_dst,
+ MPoly *polys_dst, const int numpolys_dst, CustomData *pdata_dst, const bool dirty_nors_dst,
+ DerivedMesh *dm_src, MeshPairRemap *r_map)
+{
+ const float full_weight = 1.0f;
+ const float max_dist_sq = max_dist * max_dist;
+ float (*poly_nors_dst)[3] = NULL;
+ int i;
+
+ BLI_assert(mode & MREMAP_MODE_POLY);
+
+ if (mode & (MREMAP_USE_NORMAL | MREMAP_USE_NORPROJ)) {
+ /* Cache poly nors into a temp CDLayer. */
+ poly_nors_dst = CustomData_get_layer(pdata_dst, CD_NORMAL);
+ if (!poly_nors_dst) {
+ poly_nors_dst = CustomData_add_layer(pdata_dst, CD_NORMAL, CD_CALLOC, NULL, numpolys_dst);
+ CustomData_set_layer_flag(pdata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
+ if (dirty_nors_dst) {
+ BKE_mesh_calc_normals_poly(verts_dst, numverts_dst, loops_dst, polys_dst, numloops_dst, numpolys_dst,
+ poly_nors_dst, true);
+ }
+ }
+
+ BKE_mesh_remap_init(r_map, numpolys_dst);
+
+ if (mode == MREMAP_MODE_TOPOLOGY) {
+ BLI_assert(numpolys_dst == dm_src->getNumPolys(dm_src));
+ for (i = 0; i < numpolys_dst; i++) {
+ mesh_remap_item_define(r_map, i, FLT_MAX, 0, 1, &i, &full_weight);
+ }
+ }
+ else {
+ BVHTreeFromMesh treedata = {NULL};
+ BVHTreeNearest nearest = {0};
+ BVHTreeRayHit rayhit = {0};
+ float hit_dist;
+
+ int *tessface_to_poly_map_src;
+
+ bvhtree_from_mesh_faces(
+ &treedata, dm_src,
+ (mode & MREMAP_USE_NORPROJ) ? MREMAP_RAYCAST_APPROXIMATE_BVHEPSILON(ray_radius) : 0.0f,
+ 2, 6);
+ /* bvhtree here uses tesselated faces... */
+ tessface_to_poly_map_src = dm_src->getTessFaceDataArray(dm_src, CD_ORIGINDEX);
+
+ if (mode == MREMAP_MODE_POLY_NEAREST) {
+ nearest.index = -1;
+
+ for (i = 0; i < numpolys_dst; i++) {
+ MPoly *mp = &polys_dst[i];
+ float tmp_co[3];
+
+ BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
+
+ if (mesh_remap_bvhtree_query_nearest(
+ &treedata, &nearest, space_transform,
+ tmp_co, max_dist_sq, &hit_dist))
+ {
+ mesh_remap_item_define(
+ r_map, i, hit_dist, 0,
+ 1, &tessface_to_poly_map_src[nearest.index], &full_weight);
+ }
+ else {
+ /* No source for this dest poly! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+ }
+ else if (mode == MREMAP_MODE_POLY_NOR) {
+ BLI_assert(poly_nors_dst);
+
+ for (i = 0; i < numpolys_dst; i++) {
+ MPoly *mp = &polys_dst[i];
+ float tmp_co[3], tmp_no[3];
+
+ BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
+ copy_v3_v3(tmp_no, poly_nors_dst[i]);
+
+ if (mesh_remap_bvhtree_query_raycast(
+ &treedata, &rayhit, space_transform,
+ tmp_co, tmp_no, ray_radius, max_dist, &hit_dist))
+ {
+ mesh_remap_item_define(
+ r_map, i, hit_dist, 0,
+ 1, &tessface_to_poly_map_src[rayhit.index], &full_weight);
+ }
+ else {
+ /* No source for this dest poly! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+ }
+ else if (mode == MREMAP_MODE_POLY_POLYINTERP_PNORPROJ) {
+ /* We cast our rays randomly, with a pseudo-even distribution (since we spread across tessellated tris,
+ * with additional weighting based on each tri's relative area).
+ */
+ RNG *rng = BLI_rng_new(0);
+
+ const size_t numpolys_src = (size_t)dm_src->getNumPolys(dm_src);
+
+ /* Here it's simpler to just allocate for all polys :/ */
+ int *indices = MEM_mallocN(sizeof(*indices) * numpolys_src, __func__);
+ float *weights = MEM_mallocN(sizeof(*weights) * numpolys_src, __func__);
+
+ size_t tmp_poly_size = MREMAP_DEFAULT_BUFSIZE;
+ float (*poly_vcos_2d)[2] = MEM_mallocN(sizeof(*poly_vcos_2d) * tmp_poly_size, __func__);
+ /* Tessellated 2D poly, always (num_loops - 2) triangles. */
+ int (*tri_vidx_2d)[3] = MEM_mallocN(sizeof(*tri_vidx_2d) * (tmp_poly_size - 2), __func__);
+
+ for (i = 0; i < numpolys_dst; i++) {
+ /* For each dst poly, we sample some rays from it (2D grid in pnor space)
+ * and use their hits to interpolate from source polys. */
+ /* Note: dst poly is early-converted into src space! */
+ MPoly *mp = &polys_dst[i];
+ float tmp_co[3], tmp_no[3];
+
+ int tot_rays, done_rays = 0;
+ float poly_area_2d_inv, done_area = 0.0f;
+
+ const float zvec[3] = {0.0f, 0.0f, 1.0f};
+ float pcent_dst[3];
+ float to_pnor_2d_mat[3][3], from_pnor_2d_mat[3][3];
+ float poly_dst_2d_min[2], poly_dst_2d_max[2], poly_dst_2d_z;
+ float poly_dst_2d_size[2];
+
+ float totweights = 0.0f;
+ float hit_dist_accum = 0.0f;
+ int sources_num = 0;
+ const int tris_num = mp->totloop - 2;
+ int j;
+
+ BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, pcent_dst);
+ copy_v3_v3(tmp_no, poly_nors_dst[i]);
+ /* We do our transform here, else it'd be redone by raycast helper for each ray, ugh! */
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, pcent_dst);
+ BLI_space_transform_apply_normal(space_transform, tmp_no);
+ }
+
+ fill_vn_fl(weights, (int)numpolys_src, 0.0f);
+
+ if (UNLIKELY((size_t)mp->totloop > tmp_poly_size)) {
+ tmp_poly_size = (size_t)mp->totloop;
+ poly_vcos_2d = MEM_reallocN(poly_vcos_2d, sizeof(*poly_vcos_2d) * tmp_poly_size);
+ tri_vidx_2d = MEM_reallocN(tri_vidx_2d, sizeof(*tri_vidx_2d) * (tmp_poly_size - 2));
+ }
+
+ rotation_between_vecs_to_mat3(to_pnor_2d_mat, tmp_no, zvec);
+ invert_m3_m3(from_pnor_2d_mat, to_pnor_2d_mat);
+
+ mul_m3_v3(to_pnor_2d_mat, pcent_dst);
+ poly_dst_2d_z = pcent_dst[2];
+
+ /* Get (2D) bounding square of our poly. */
+ INIT_MINMAX2(poly_dst_2d_min, poly_dst_2d_max);
+
+ for (j = 0; j < mp->totloop; j++) {
+ MLoop *ml = &loops_dst[j + mp->loopstart];
+ copy_v3_v3(tmp_co, verts_dst[ml->v].co);
+ if (space_transform) {
+ BLI_space_transform_apply(space_transform, tmp_co);
+ }
+ mul_v2_m3v3(poly_vcos_2d[j], to_pnor_2d_mat, tmp_co);
+ minmax_v2v2_v2(poly_dst_2d_min, poly_dst_2d_max, poly_vcos_2d[j]);
+ }
+
+ /* We adjust our ray-casting grid to ray_radius (the smaller, the more rays are cast),
+ * with lower/upper bounds. */
+ sub_v2_v2v2(poly_dst_2d_size, poly_dst_2d_max, poly_dst_2d_min);
+
+ if (ray_radius) {
+ tot_rays = (int)((max_ff(poly_dst_2d_size[0], poly_dst_2d_size[1]) / ray_radius) + 0.5f);
+ CLAMP(tot_rays, MREMAP_RAYCAST_TRI_SAMPLES_MIN, MREMAP_RAYCAST_TRI_SAMPLES_MAX);
+ }
+ else {
+ /* If no radius (pure rays), give max number of rays! */
+ tot_rays = MREMAP_RAYCAST_TRI_SAMPLES_MIN;
+ }
+ tot_rays *= tot_rays;
+
+ poly_area_2d_inv = 1.0f / area_poly_v2((const float(*)[2])poly_vcos_2d, (unsigned int)mp->totloop);
+
+ /* Tessellate our poly. */
+ if (mp->totloop == 3) {
+ tri_vidx_2d[0][0] = 0;
+ tri_vidx_2d[0][1] = 1;
+ tri_vidx_2d[0][2] = 2;
+ }
+ if (mp->totloop == 4) {
+ tri_vidx_2d[0][0] = 0;
+ tri_vidx_2d[0][1] = 1;
+ tri_vidx_2d[0][2] = 2;
+ tri_vidx_2d[1][0] = 0;
+ tri_vidx_2d[1][1] = 2;
+ tri_vidx_2d[1][2] = 3;
+ }
+ else {
+ BLI_polyfill_calc((const float(*)[2])poly_vcos_2d, (unsigned int)mp->totloop, -1,
+ (unsigned int (*)[3])tri_vidx_2d);
+ }
+
+ for (j = 0; j < tris_num; j++) {
+ float *v1 = poly_vcos_2d[tri_vidx_2d[j][0]];
+ float *v2 = poly_vcos_2d[tri_vidx_2d[j][1]];
+ float *v3 = poly_vcos_2d[tri_vidx_2d[j][2]];
+ int rays_num;
+
+ /* All this allows us to get 'absolute' number of rays for each tri, avoiding accumulating
+ * errors over iterations, and helping better even distribution. */
+ done_area += area_tri_v2(v1, v2, v3);
+ rays_num = (int)((float)tot_rays * done_area * poly_area_2d_inv + 0.5f) - done_rays;
+ done_rays += rays_num;
+
+ while (rays_num--) {
+ int n = (ray_radius > 0.0f) ? MREMAP_RAYCAST_APPROXIMATE_NR : 1;
+ float w = 1.0f;
+
+ BLI_rng_get_tri_sample_float_v2(rng, v1, v2, v3, tmp_co);
+
+ tmp_co[2] = poly_dst_2d_z;
+ mul_m3_v3(from_pnor_2d_mat, tmp_co);
+
+ /* At this point, tmp_co is a point on our poly surface, in mesh_src space! */
+ while (n--) {
+ /* Note we handle dest to src space conversion ourself, here! */
+
+ if (mesh_remap_bvhtree_query_raycast(
+ &treedata, &rayhit, NULL,
+ tmp_co, tmp_no, ray_radius / w, max_dist, &hit_dist))
+ {
+ weights[tessface_to_poly_map_src[rayhit.index]] += w;
+ totweights += w;
+ hit_dist_accum += hit_dist;
+ break;
+ }
+ /* Next iteration will get bigger radius but smaller weight! */
+ w /= MREMAP_RAYCAST_APPROXIMATE_FAC;
+ }
+ }
+ }
+
+ if (totweights > 0.0f) {
+ for (j = 0; j < (int)numpolys_src; j++) {
+ if (!weights[j]) {
+ continue;
+ }
+ /* Note: sources_num is always <= j! */
+ weights[sources_num] = weights[j] / totweights;
+ indices[sources_num] = j;
+ sources_num++;
+ }
+ mesh_remap_item_define(r_map, i, hit_dist_accum / totweights, 0, sources_num, indices, weights);
+ }
+ else {
+ /* No source for this dest poly! */
+ BKE_mesh_remap_item_define_invalid(r_map, i);
+ }
+ }
+
+ MEM_freeN(tri_vidx_2d);
+ MEM_freeN(poly_vcos_2d);
+ MEM_freeN(indices);
+ MEM_freeN(weights);
+ BLI_rng_free(rng);
+ }
+ else {
+ printf("WARNING! Unsupported mesh-to-mesh poly mapping mode (%d)!\n", mode);
+ memset(r_map->items, 0, sizeof(*r_map->items) * (size_t)numpolys_dst);
+ }
+
+ free_bvhtree_from_mesh(&treedata);
+ }
+}
+
+#undef MREMAP_RAYCAST_APPROXIMATE_NR
+#undef MREMAP_RAYCAST_APPROXIMATE_FAC
+#undef MREMAP_RAYCAST_APPROXIMATE_BVHEPSILON
+#undef MREMAP_RAYCAST_TRI_SAMPLES_MIN
+#undef MREMAP_RAYCAST_TRI_SAMPLES_MAX
+#undef MREMAP_DEFAULT_BUFSIZE
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index f3a9e894eb3..7de993e1099 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -222,11 +222,11 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
const bool do_verbose, const bool do_fixes,
bool *r_changed)
{
-# define REMOVE_EDGE_TAG(_me) { _me->v2 = _me->v1; do_edge_free = true; } (void)0
+# define REMOVE_EDGE_TAG(_me) { _me->v2 = _me->v1; free_flag.edges = do_fixes; } (void)0
# define IS_REMOVED_EDGE(_me) (_me->v2 == _me->v1)
-# define REMOVE_LOOP_TAG(_ml) { _ml->e = INVALID_LOOP_EDGE_MARKER; do_polyloop_free = true; } (void)0
-# define REMOVE_POLY_TAG(_mp) { _mp->totloop *= -1; do_polyloop_free = true; } (void)0
+# define REMOVE_LOOP_TAG(_ml) { _ml->e = INVALID_LOOP_EDGE_MARKER; free_flag.polyloops = do_fixes; } (void)0
+# define REMOVE_POLY_TAG(_mp) { _mp->totloop *= -1; free_flag.polyloops = do_fixes; } (void)0
MVert *mv = mverts;
MEdge *me;
@@ -237,26 +237,46 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
bool is_valid = true;
- bool do_edge_free = false;
- bool do_face_free = false;
- bool do_polyloop_free = false; /* This regroups loops and polys! */
-
- bool verts_fixed = false;
- bool vert_weights_fixed = false;
- bool msel_fixed = false;
-
- bool do_edge_recalc = false;
+ union {
+ struct {
+ int verts : 1;
+ int verts_weight : 1;
+ };
+ int as_flag;
+ } fix_flag;
+
+ union {
+ struct {
+ int edges : 1;
+ int faces : 1;
+ /* This regroups loops and polys! */
+ int polyloops : 1;
+ int mselect : 1;
+ };
+ int as_flag;
+ } free_flag;
+
+ union {
+ struct {
+ int edges : 1;
+ };
+ int as_flag;
+ } recalc_flag;
EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, totedge);
BLI_assert(!(do_fixes && mesh == NULL));
+ fix_flag.as_flag = 0;
+ free_flag.as_flag = 0;
+ recalc_flag.as_flag = 0;
+
PRINT_MSG("%s: verts(%u), edges(%u), loops(%u), polygons(%u)\n",
__func__, totvert, totedge, totloop, totpoly);
if (totedge == 0 && totpoly != 0) {
PRINT_ERR("\tLogical error, %u polygons and 0 edges\n", totpoly);
- do_edge_recalc = do_fixes;
+ recalc_flag.edges = do_fixes;
}
for (i = 0; i < totvert; i++, mv++) {
@@ -269,7 +289,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
if (do_fixes) {
zero_v3(mv->co);
- verts_fixed = true;
+ fix_flag.verts = true;
}
}
@@ -281,13 +301,14 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
PRINT_ERR("\tVertex %u: has zero normal, assuming Z-up normal\n", i);
if (do_fixes) {
mv->no[2] = SHRT_MAX;
- verts_fixed = true;
+ fix_flag.verts = true;
}
}
}
for (i = 0, me = medges; i < totedge; i++, me++) {
bool remove = false;
+
if (me->v1 == me->v2) {
PRINT_ERR("\tEdge %u: has matching verts, both %u\n", i, me->v1);
remove = do_fixes;
@@ -301,14 +322,16 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
remove = do_fixes;
}
- if (BLI_edgehash_haskey(edge_hash, me->v1, me->v2)) {
+ if ((me->v1 != me->v2) && BLI_edgehash_haskey(edge_hash, me->v1, me->v2)) {
PRINT_ERR("\tEdge %u: is a duplicate of %d\n", i,
GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, me->v1, me->v2)));
remove = do_fixes;
}
if (remove == false) {
- BLI_edgehash_insert(edge_hash, me->v1, me->v2, SET_INT_IN_POINTER(i));
+ if (me->v1 != me->v2) {
+ BLI_edgehash_insert(edge_hash, me->v1, me->v2, SET_INT_IN_POINTER(i));
+ }
}
else {
REMOVE_EDGE_TAG(me);
@@ -316,7 +339,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
if (mfaces && !mpolys) {
-# define REMOVE_FACE_TAG(_mf) { _mf->v3 = 0; do_face_free = true; } (void)0
+# define REMOVE_FACE_TAG(_mf) { _mf->v3 = 0; free_flag.faces = do_fixes; } (void)0
# define CHECK_FACE_VERT_INDEX(a, b) \
if (mf->a == mf->b) { \
PRINT_ERR(" face %u: verts invalid, " STRINGIFY(a) "/" STRINGIFY(b) " both %u\n", i, mf->a); \
@@ -326,7 +349,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
if (!BLI_edgehash_haskey(edge_hash, mf->a, mf->b)) { \
PRINT_ERR(" face %u: edge " STRINGIFY(a) "/" STRINGIFY(b) \
" (%u,%u) is missing edge data\n", i, mf->a, mf->b); \
- do_edge_recalc = true; \
+ recalc_flag.edges = do_fixes; \
} (void)0
MFace *mf;
@@ -531,7 +554,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
/* Edge not existing. */
PRINT_ERR("\tPoly %u needs missing edge (%u, %u)\n", sp->index, v1, v2);
if (do_fixes)
- do_edge_recalc = true;
+ recalc_flag.edges = true;
else
sp->invalid = true;
}
@@ -755,19 +778,19 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
MDeformWeight *dw;
for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) {
- /* note, greater then max defgroups is accounted for in our code, but not < 0 */
+ /* note, greater than max defgroups is accounted for in our code, but not < 0 */
if (!finite(dw->weight)) {
PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
if (do_fixes) {
dw->weight = 0.0f;
- vert_weights_fixed = true;
+ fix_flag.verts_weight = true;
}
}
else if (dw->weight < 0.0f || dw->weight > 1.0f) {
PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
if (do_fixes) {
CLAMP(dw->weight, 0.0f, 1.0f);
- vert_weights_fixed = true;
+ fix_flag.verts_weight = true;
}
}
@@ -775,13 +798,14 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
PRINT_ERR("\tVertex deform %u, has invalid group %d\n", i, dw->def_nr);
if (do_fixes) {
defvert_remove_group(dv, dw);
+ fix_flag.verts_weight = true;
+
if (dv->dw) {
/* re-allocated, the new values compensate for stepping
* within the for loop and may not be valid */
j--;
dw = dv->dw + j;
- vert_weights_fixed = true;
}
else { /* all freed */
break;
@@ -798,26 +822,25 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
# undef REMOVE_POLY_TAG
if (mesh) {
- if (do_face_free) {
+ if (free_flag.faces) {
BKE_mesh_strip_loose_faces(mesh);
}
- if (do_polyloop_free) {
+ if (free_flag.polyloops) {
BKE_mesh_strip_loose_polysloops(mesh);
}
- if (do_edge_free) {
+ if (free_flag.edges) {
BKE_mesh_strip_loose_edges(mesh);
}
- if (do_edge_recalc) {
+ if (recalc_flag.edges) {
BKE_mesh_calc_edges(mesh, true, false);
}
}
if (mesh && mesh->mselect) {
MSelect *msel;
- bool free_msel = false;
for (i = 0, msel = mesh->mselect; i < mesh->totselect; i++, msel++) {
int tot_elem = 0;
@@ -825,7 +848,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
if (msel->index < 0) {
PRINT_ERR("\tMesh select element %d type %d index is negative, "
"resetting selection stack.\n", i, msel->type);
- free_msel = true;
+ free_flag.mselect = do_fixes;
break;
}
@@ -845,12 +868,12 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
PRINT_ERR("\tMesh select element %d type %d index %d is larger than data array size %d, "
"resetting selection stack.\n", i, msel->type, msel->index, tot_elem);
- free_msel = true;
+ free_flag.mselect = do_fixes;
break;
}
}
- if (free_msel) {
+ if (free_flag.mselect) {
MEM_freeN(mesh->mselect);
mesh->mselect = NULL;
mesh->totselect = 0;
@@ -859,7 +882,11 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
PRINT_MSG("%s: finished\n\n", __func__);
- *r_changed = (verts_fixed || vert_weights_fixed || do_polyloop_free || do_edge_free || do_edge_recalc || msel_fixed);
+ *r_changed = (fix_flag.as_flag || free_flag.as_flag || recalc_flag.as_flag);
+
+ if (do_fixes == false) {
+ BLI_assert(*r_changed == false);
+ }
return is_valid;
}
@@ -963,7 +990,7 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata,
*
* \returns true if a change is made.
*/
-int BKE_mesh_validate(Mesh *me, const int do_verbose)
+int BKE_mesh_validate(Mesh *me, const int do_verbose, const int cddata_check_mask)
{
bool is_valid = true;
bool changed;
@@ -974,7 +1001,7 @@ int BKE_mesh_validate(Mesh *me, const int do_verbose)
is_valid &= BKE_mesh_validate_all_customdata(
&me->vdata, &me->edata, &me->ldata, &me->pdata,
- true,
+ cddata_check_mask,
do_verbose, true,
&changed);
@@ -1445,12 +1472,14 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool update, const bool select)
/* mesh loops (bmesh only) */
for (mp = mesh->mpoly, i = 0; i < totpoly; mp++, i++) {
MLoop *l = &mesh->mloop[mp->loopstart];
- int j, l_prev = (l + (mp->totloop - 1))->v;
+ int j, v_prev = (l + (mp->totloop - 1))->v;
for (j = 0; j < mp->totloop; j++, l++) {
- if (!BLI_edgehash_haskey(eh, l_prev, l->v)) {
- BLI_edgehash_insert(eh, l_prev, l->v, NULL);
+ if (v_prev != l->v) {
+ if (!BLI_edgehash_haskey(eh, v_prev, l->v)) {
+ BLI_edgehash_insert(eh, v_prev, l->v, NULL);
+ }
}
- l_prev = l->v;
+ v_prev = l->v;
}
}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index a9e853c873e..42247d866e4 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -47,7 +47,6 @@
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
-#include "DNA_meshdata_types.h"
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
@@ -57,6 +56,7 @@
#include "BLF_translation.h"
+#include "BKE_appdir.h"
#include "BKE_key.h"
#include "BKE_multires.h"
#include "BKE_DerivedMesh.h"
@@ -143,13 +143,14 @@ void modifier_free(ModifierData *md)
MEM_freeN(md);
}
-void modifier_unique_name(ListBase *modifiers, ModifierData *md)
+bool modifier_unique_name(ListBase *modifiers, ModifierData *md)
{
if (modifiers && md) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- BLI_uniquename(modifiers, md, DATA_(mti->name), '.', offsetof(ModifierData, name), sizeof(md->name));
+ return BLI_uniquename(modifiers, md, DATA_(mti->name), '.', offsetof(ModifierData, name), sizeof(md->name));
}
+ return false;
}
bool modifier_dependsOnTime(ModifierData *md)
@@ -262,8 +263,8 @@ void modifier_copyData_generic(const ModifierData *md_src, ModifierData *md_dst)
{
ModifierTypeInfo *mti = modifierType_getInfo(md_src->type);
const size_t data_size = sizeof(ModifierData);
- const char *md_src_data = ((char *)md_src) + data_size;
- char *md_dst_data = ((char *)md_dst) + data_size;
+ const char *md_src_data = ((const char *)md_src) + data_size;
+ char *md_dst_data = ((char *)md_dst) + data_size;
BLI_assert(data_size <= (size_t)mti->structSize);
memcpy(md_dst_data, md_src_data, (size_t)mti->structSize - data_size);
}
@@ -713,7 +714,7 @@ const char *modifier_path_relbase(Object *ob)
else {
/* last resort, better then using "" which resolves to the current
* working directory */
- return BLI_temp_dir_session();
+ return BKE_tempdir_session();
}
}
@@ -723,7 +724,7 @@ void modifier_path_init(char *path, int path_maxlen, const char *name)
/* elubie: changed this to default to the same dir as the render output
* to prevent saving to C:\ on Windows */
BLI_join_dirfile(path, path_maxlen,
- G.relbase_valid ? "//" : BLI_temp_dir_session(),
+ G.relbase_valid ? "//" : BKE_tempdir_session(),
name);
}
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index e28adb7c0e0..73f75f4f96d 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -69,7 +69,6 @@
#include "BKE_image.h" /* openanim */
#include "BKE_tracking.h"
-#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
@@ -78,8 +77,6 @@
# include "intern/openexr/openexr_multi.h"
#endif
-#include "NOD_composite.h"
-
/*********************** movieclip buffer loaders *************************/
static int sequence_guess_offset(const char *full_name, int head_len, unsigned short numlen)
@@ -391,7 +388,7 @@ static int user_frame_to_cache_frame(MovieClip *clip, int framenr)
static void moviecache_keydata(void *userkey, int *framenr, int *proxy, int *render_flags)
{
- MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *)userkey;
+ const MovieClipImBufCacheKey *key = userkey;
*framenr = key->framenr;
*proxy = key->proxy;
@@ -400,7 +397,7 @@ static void moviecache_keydata(void *userkey, int *framenr, int *proxy, int *ren
static unsigned int moviecache_hashhash(const void *keyv)
{
- MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *)keyv;
+ const MovieClipImBufCacheKey *key = keyv;
int rval = key->framenr;
return rval;
@@ -408,8 +405,8 @@ static unsigned int moviecache_hashhash(const void *keyv)
static bool moviecache_hashcmp(const void *av, const void *bv)
{
- const MovieClipImBufCacheKey *a = (MovieClipImBufCacheKey *)av;
- const MovieClipImBufCacheKey *b = (MovieClipImBufCacheKey *)bv;
+ const MovieClipImBufCacheKey *a = av;
+ const MovieClipImBufCacheKey *b = bv;
return ((a->framenr != b->framenr) ||
(a->proxy != b->proxy) ||
@@ -528,6 +525,15 @@ static bool put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, i
}
}
+static bool moviecache_check_free_proxy(ImBuf *UNUSED(ibuf),
+ void *userkey,
+ void *UNUSED(userdata))
+{
+ MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *)userkey;
+
+ return !(key->proxy == IMB_PROXY_NONE && key->render_flag == 0);
+}
+
/*********************** common functions *************************/
/* only image block itself */
@@ -615,7 +621,7 @@ MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
BLI_strncpy(strtest, clip->name, sizeof(clip->name));
BLI_path_abs(strtest, G.main->name);
- if (strcmp(strtest, str) == 0) {
+ if (STREQ(strtest, str)) {
BLI_strncpy(clip->name, name, sizeof(clip->name)); /* for stringcode */
clip->id.us++; /* officially should not, it doesn't link here! */
@@ -784,10 +790,10 @@ static ImBuf *postprocess_frame(MovieClip *clip, MovieClipUser *user, ImBuf *ibu
}
if (postprocess_flag) {
- bool disable_red = (postprocess_flag & MOVIECLIP_DISABLE_RED) != 0,
- disable_green = (postprocess_flag & MOVIECLIP_DISABLE_GREEN) != 0,
- disable_blue = (postprocess_flag & MOVIECLIP_DISABLE_BLUE) != 0,
- grayscale = (postprocess_flag & MOVIECLIP_PREVIEW_GRAYSCALE) != 0;
+ bool disable_red = (postprocess_flag & MOVIECLIP_DISABLE_RED) != 0;
+ bool disable_green = (postprocess_flag & MOVIECLIP_DISABLE_GREEN) != 0;
+ bool disable_blue = (postprocess_flag & MOVIECLIP_DISABLE_BLUE) != 0;
+ bool grayscale = (postprocess_flag & MOVIECLIP_PREVIEW_GRAYSCALE) != 0;
if (disable_red || disable_green || disable_blue || grayscale)
BKE_tracking_disable_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1);
@@ -1170,6 +1176,15 @@ void BKE_movieclip_clear_cache(MovieClip *clip)
free_buffers(clip);
}
+void BKE_movieclip_clear_proxy_cache(MovieClip *clip)
+{
+ if (clip->cache && clip->cache->moviecache) {
+ IMB_moviecache_cleanup(clip->cache->moviecache,
+ moviecache_check_free_proxy,
+ NULL);
+ }
+}
+
void BKE_movieclip_reload(MovieClip *clip)
{
/* clear cache */
@@ -1261,7 +1276,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
scopes->frame_width = ibuf->x;
scopes->frame_height = ibuf->y;
- scopes->use_track_mask = track->flag & TRACK_PREVIEW_ALPHA;
+ scopes->use_track_mask = (track->flag & TRACK_PREVIEW_ALPHA) != 0;
}
IMB_freeImBuf(ibuf);
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 9f5e049fe24..220d0f7c604 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -1600,7 +1600,7 @@ void multires_load_old_250(Mesh *me)
int nvert = mf->v4 ? 4 : 3;
int totdisp = mdisps[i].totdisp / nvert;
- for (j = 0; j < mf->v4 ? 4 : 3; j++, k++) {
+ for (j = 0; j < nvert; j++, k++) {
mdisps2[k].disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disp in conversion");
mdisps2[k].totdisp = totdisp;
mdisps2[k].level = mdisps[i].level;
@@ -1641,7 +1641,8 @@ void multires_free(Multires *mr)
lvl = lvl->next;
}
- MEM_freeN(mr->verts);
+ /* mr->verts may be NULL when loading old files, see direct_link_mesh() in readfile.c, and T43560. */
+ MEM_SAFE_FREE(mr->verts);
BLI_freelistN(&mr->levels);
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 19e45142960..9a04312aaab 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -268,7 +268,7 @@ NlaTrack *add_nlatrack(AnimData *adt, NlaTrack *prev)
/* set settings requiring the track to not be part of the stack yet */
nlt->flag = NLATRACK_SELECTED;
- nlt->index = BLI_countlist(&adt->nla_tracks);
+ nlt->index = BLI_listbase_count(&adt->nla_tracks);
/* add track to stack, and make it the active one */
if (prev)
@@ -299,13 +299,12 @@ NlaStrip *add_nlastrip(bAction *act)
/* generic settings
* - selected flag to highlight this to the user
- * - auto-blends to ensure that blend in/out values are automatically
- * determined by overlaps of strips
+ * - (XXX) disabled Auto-Blends, as this was often causing some unwanted effects
* - (XXX) synchronization of strip-length in accordance with changes to action-length
* is not done though, since this should only really happens in editmode for strips now
* though this decision is still subject to further review...
*/
- strip->flag = NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_AUTO_BLENDS;
+ strip->flag = NLASTRIP_FLAG_SELECT;
/* assign the action reference */
strip->act = act;
@@ -567,7 +566,7 @@ bool BKE_nlastrips_has_space(ListBase *strips, float start, float end)
/* sanity checks */
if ((strips == NULL) || IS_EQF(start, end))
- return 0;
+ return false;
if (start > end) {
puts("BKE_nlastrips_has_space() error... start and end arguments swapped");
SWAP(float, start, end);
@@ -579,17 +578,17 @@ bool BKE_nlastrips_has_space(ListBase *strips, float start, float end)
* we've gone past the window we need to check for, so things are fine
*/
if (strip->start >= end)
- return 1;
+ return true;
/* if the end of the strip is greater than either of the boundaries, the range
* must fall within the extents of the strip
*/
if ((strip->end > start) || (strip->end > end))
- return 0;
+ return false;
}
/* if we are still here, we haven't encountered any overlapping strips */
- return 1;
+ return true;
}
/* Rearrange the strips in the track so that they are always in order
@@ -646,11 +645,11 @@ bool BKE_nlastrips_add_strip(ListBase *strips, NlaStrip *strip)
/* sanity checks */
if (ELEM(NULL, strips, strip))
- return 0;
+ return false;
/* check if any space to add */
if (BKE_nlastrips_has_space(strips, strip->start, strip->end) == 0)
- return 0;
+ return false;
/* find the right place to add the strip to the nominated track */
for (ns = strips->first; ns; ns = ns->next) {
@@ -667,7 +666,7 @@ bool BKE_nlastrips_add_strip(ListBase *strips, NlaStrip *strip)
}
/* added... */
- return 1;
+ return true;
}
@@ -785,11 +784,11 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
{
/* sanity checks */
if (ELEM(NULL, mstrip, strip))
- return 0;
+ return false;
/* firstly, check if the meta-strip has space for this */
if (BKE_nlastrips_has_space(&mstrip->strips, strip->start, strip->end) == 0)
- return 0;
+ return false;
/* check if this would need to be added to the ends of the meta,
* and subsequently, if the neighboring strips allow us enough room
@@ -803,10 +802,10 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
BLI_addhead(&mstrip->strips, strip);
mstrip->start = strip->start;
- return 1;
+ return true;
}
else /* failed... no room before */
- return 0;
+ return false;
}
else if (strip->end > mstrip->end) {
/* check if strip to the right (if it exists) starts before the
@@ -817,10 +816,10 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
BLI_addtail(&mstrip->strips, strip);
mstrip->end = strip->end;
- return 1;
+ return true;
}
else /* failed... no room after */
- return 0;
+ return false;
}
else {
/* just try to add to the meta-strip (no dimension changes needed) */
@@ -988,7 +987,7 @@ bool BKE_nlatrack_has_space(NlaTrack *nlt, float start, float end)
* - bounds cannot be equal (0-length is nasty)
*/
if ((nlt == NULL) || (nlt->flag & NLATRACK_PROTECTED) || IS_EQF(start, end))
- return 0;
+ return false;
if (start > end) {
puts("BKE_nlatrack_has_space() error... start and end arguments swapped");
@@ -1019,8 +1018,12 @@ bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip)
{
/* sanity checks */
if (ELEM(NULL, nlt, strip))
- return 0;
+ return false;
+ /* do not allow adding strips if this track is locked */
+ if (nlt->flag & NLATRACK_PROTECTED)
+ return false;
+
/* try to add the strip to the track using a more generic function */
return BKE_nlastrips_add_strip(&nlt->strips, strip);
}
@@ -1036,11 +1039,11 @@ bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2])
if (bounds)
bounds[0] = bounds[1] = 0.0f;
else
- return 0;
+ return false;
/* sanity checks */
if (ELEM(NULL, nlt, nlt->strips.first))
- return 0;
+ return false;
/* lower bound is first strip's start frame */
strip = nlt->strips.first;
@@ -1051,7 +1054,7 @@ bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2])
bounds[1] = strip->end;
/* done */
- return 1;
+ return true;
}
/* NLA Strips -------------------------------------- */
@@ -1105,7 +1108,7 @@ bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max)
/* sanity checks */
if ((strip == NULL) || IS_EQF(stripLen, 0.0f) || IS_EQF(boundsLen, 0.0f))
- return 0;
+ return false;
/* only ok if at least part of the strip is within the bounding window
* - first 2 cases cover when the strip length is less than the bounding area
@@ -1115,17 +1118,17 @@ bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max)
!(IN_RANGE(strip->start, min, max) ||
IN_RANGE(strip->end, min, max)))
{
- return 0;
+ return false;
}
if ((stripLen > boundsLen) &&
!(IN_RANGE(min, strip->start, strip->end) ||
IN_RANGE(max, strip->start, strip->end)) )
{
- return 0;
+ return false;
}
/* should be ok! */
- return 1;
+ return true;
}
@@ -1209,11 +1212,11 @@ static bool nlastrip_is_first(AnimData *adt, NlaStrip *strip)
/* sanity checks */
if (ELEM(NULL, adt, strip))
- return 0;
+ return false;
/* check if strip has any strips before it */
if (strip->prev)
- return 0;
+ return false;
/* check other tracks to see if they have a strip that's earlier */
/* TODO: or should we check that the strip's track is also the first? */
@@ -1222,12 +1225,12 @@ static bool nlastrip_is_first(AnimData *adt, NlaStrip *strip)
ns = nlt->strips.first;
if (ns) {
if (ns->start < strip->start)
- return 0;
+ return false;
}
}
/* should be first now */
- return 1;
+ return true;
}
/* Animated Strips ------------------------------------------- */
@@ -1239,16 +1242,16 @@ bool BKE_nlatrack_has_animated_strips(NlaTrack *nlt)
/* sanity checks */
if (ELEM(NULL, nlt, nlt->strips.first))
- return 0;
+ return false;
/* check each strip for F-Curves only (don't care about whether the flags are set) */
for (strip = nlt->strips.first; strip; strip = strip->next) {
if (strip->fcurves.first)
- return 1;
+ return true;
}
/* none found */
- return 0;
+ return false;
}
/* Check if given NLA-Tracks have any strips with own F-Curves */
@@ -1258,16 +1261,16 @@ bool BKE_nlatracks_have_animated_strips(ListBase *tracks)
/* sanity checks */
if (ELEM(NULL, tracks, tracks->first))
- return 0;
+ return false;
/* check each track, stopping on the first hit */
for (nlt = tracks->first; nlt; nlt = nlt->next) {
if (BKE_nlatrack_has_animated_strips(nlt))
- return 1;
+ return true;
}
/* none found */
- return 0;
+ return false;
}
/* Validate the NLA-Strips 'control' F-Curves based on the flags set*/
@@ -1326,7 +1329,7 @@ void BKE_nlastrip_validate_fcurves(NlaStrip *strip)
static bool nla_editbone_name_check(void *arg, const char *name)
{
- return BLI_ghash_haskey((GHash *)arg, (void *)name);
+ return BLI_ghash_haskey((GHash *)arg, (const void *)name);
}
/* Find (and set) a unique name for a strip from the whole AnimData block
@@ -1524,6 +1527,88 @@ void BKE_nla_validate_state(AnimData *adt)
}
}
+/* Action Stashing -------------------------------------- */
+
+/* name of stashed tracks - the translation stuff is included here to save extra work */
+#define STASH_TRACK_NAME DATA_("[Action Stash]")
+
+/* Check if an action is "stashed" in the NLA already
+ *
+ * The criteria for this are:
+ * 1) The action in question lives in a "stash" track
+ * 2) We only check first-level strips. That is, we will not check inside meta strips.
+ */
+bool BKE_nla_action_is_stashed(AnimData *adt, bAction *act)
+{
+ NlaTrack *nlt;
+ NlaStrip *strip;
+
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ if (strstr(nlt->name, STASH_TRACK_NAME)) {
+ for (strip = nlt->strips.first; strip; strip = strip->next) {
+ if (strip->act == act)
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/* "Stash" an action (i.e. store it as a track/layer in the NLA, but non-contributing)
+ * to retain it in the file for future uses
+ */
+bool BKE_nla_action_stash(AnimData *adt)
+{
+ NlaTrack *prev_track = NULL;
+ NlaTrack *nlt;
+ NlaStrip *strip;
+
+ /* sanity check */
+ if (ELEM(NULL, adt, adt->action)) {
+ printf("%s: Invalid argument - %p %p\n", __func__, adt, adt->action);
+ return false;
+ }
+
+ /* do not add if it is already stashed */
+ if (BKE_nla_action_is_stashed(adt, adt->action))
+ return false;
+
+ /* create a new track, and add this immediately above the previous stashing track */
+ for (prev_track = adt->nla_tracks.last; prev_track; prev_track = prev_track->prev) {
+ if (strstr(prev_track->name, STASH_TRACK_NAME)) {
+ break;
+ }
+ }
+
+ nlt = add_nlatrack(adt, prev_track);
+ BLI_assert(nlt != NULL);
+
+ BLI_strncpy(nlt->name, STASH_TRACK_NAME, sizeof(nlt->name));
+ BLI_uniquename(&adt->nla_tracks, nlt, STASH_TRACK_NAME, '.', offsetof(NlaTrack, name), sizeof(nlt->name));
+
+ /* add the action as a strip in this new track
+ * NOTE: a new user is created here
+ */
+ strip = add_nlastrip(adt->action);
+ BLI_assert(strip != NULL);
+
+ BKE_nlatrack_add_strip(nlt, strip);
+ BKE_nlastrip_validate_name(adt, strip);
+
+ /* mark the stash track and strip so that they doesn't disturb the stack animation,
+ * and are unlikely to draw attention to itself (or be accidentally bumped around)
+ *
+ * NOTE: this must be done *after* adding the strip to the track, or else
+ * the strip locking will prevent the strip from getting added
+ */
+ nlt->flag = (NLATRACK_MUTED | NLATRACK_PROTECTED);
+ strip->flag &= ~(NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_ACTIVE);
+
+ /* succeeded */
+ return true;
+}
+
/* Core Tools ------------------------------------------- */
/* For the given AnimData block, add the active action to the NLA
@@ -1576,7 +1661,6 @@ void BKE_nla_action_pushdown(AnimData *adt)
}
}
-
/* Find the active strip + track combo, and set them up as the tweaking track,
* and return if successful or not.
*/
@@ -1587,13 +1671,13 @@ bool BKE_nla_tweakmode_enter(AnimData *adt)
/* verify that data is valid */
if (ELEM(NULL, adt, adt->nla_tracks.first))
- return 0;
+ return false;
/* if block is already in tweakmode, just leave, but we should report
* that this block is in tweakmode (as our returncode)
*/
if (adt->flag & ADT_NLA_EDIT_ON)
- return 1;
+ return true;
/* go over the tracks, finding the active one, and its active strip
* - if we cannot find both, then there's nothing to do
@@ -1642,7 +1726,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt)
printf("NLA tweakmode enter - neither active requirement found\n");
printf("\tactiveTrack = %p, activeStrip = %p\n", (void *)activeTrack, (void *)activeStrip);
}
- return 0;
+ return false;
}
/* go over all the tracks up to the active one, tagging each strip that uses the same
@@ -1677,7 +1761,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt)
adt->flag |= ADT_NLA_EDIT_ON;
/* done! */
- return 1;
+ return true;
}
/* Exit tweakmode for this AnimData block */
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 3a7bfb03e07..c7010e42aac 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -955,7 +955,7 @@ void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
ntree->update |= NTREE_UPDATE_LINKS;
}
-int nodeLinkIsHidden(bNodeLink *link)
+bool nodeLinkIsHidden(bNodeLink *link)
{
return nodeSocketIsHidden(link->fromsock) || nodeSocketIsHidden(link->tosock);
}
@@ -1202,6 +1202,10 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool do_
/* node tree will generate its own interface type */
newtree->interface_type = NULL;
+ if (ntree->id.lib) {
+ BKE_id_lib_local_paths(bmain, ntree->id.lib, &newtree->id);
+ }
+
return newtree;
}
@@ -2246,7 +2250,7 @@ StructRNA *ntreeInterfaceTypeGet(bNodeTree *ntree, int create)
ntree_interface_identifier_base(ntree, base);
/* RNA identifier may have a number suffix, but should start with the idbase string */
- if (strncmp(RNA_struct_identifier(srna), base, sizeof(base)) != 0) {
+ if (!STREQLEN(RNA_struct_identifier(srna), base, sizeof(base))) {
/* generate new unique RNA identifier from the ID name */
ntree_interface_identifier(ntree, base, identifier, sizeof(identifier), name, description);
@@ -2293,8 +2297,8 @@ bool ntreeHasType(const bNodeTree *ntree, int type)
if (ntree)
for (node = ntree->nodes.first; node; node = node->next)
if (node->type == type)
- return 1;
- return 0;
+ return true;
+ return false;
}
bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
@@ -2559,8 +2563,8 @@ bool BKE_node_clipboard_validate(void)
/* lists must be aligned */
- BLI_assert(BLI_countlist(&node_clipboard.nodes) ==
- BLI_countlist(&node_clipboard.nodes_extra_info));
+ BLI_assert(BLI_listbase_count(&node_clipboard.nodes) ==
+ BLI_listbase_count(&node_clipboard.nodes_extra_info));
for (node = node_clipboard.nodes.first, node_info = node_clipboard.nodes_extra_info.first;
node;
@@ -2877,7 +2881,7 @@ static void ntree_update_node_level(bNodeTree *ntree)
}
}
-static void ntree_update_link_pointers(bNodeTree *ntree)
+void ntreeTagUsedSockets(bNodeTree *ntree)
{
bNode *node;
bNodeSocket *sock;
@@ -2886,22 +2890,43 @@ static void ntree_update_link_pointers(bNodeTree *ntree)
/* first clear data */
for (node = ntree->nodes.first; node; node = node->next) {
for (sock = node->inputs.first; sock; sock = sock->next) {
- sock->link = NULL;
sock->flag &= ~SOCK_IN_USE;
}
for (sock = node->outputs.first; sock; sock = sock->next) {
sock->flag &= ~SOCK_IN_USE;
}
}
-
+
for (link = ntree->links.first; link; link = link->next) {
- link->tosock->link = link;
+ /* link is unused if either side is disabled */
+ if ((link->fromsock->flag & SOCK_UNAVAIL) || (link->tosock->flag & SOCK_UNAVAIL))
+ continue;
link->fromsock->flag |= SOCK_IN_USE;
link->tosock->flag |= SOCK_IN_USE;
}
}
+static void ntree_update_link_pointers(bNodeTree *ntree)
+{
+ bNode *node;
+ bNodeSocket *sock;
+ bNodeLink *link;
+
+ /* first clear data */
+ for (node = ntree->nodes.first; node; node = node->next) {
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ sock->link = NULL;
+ }
+ }
+
+ for (link = ntree->links.first; link; link = link->next) {
+ link->tosock->link = link;
+ }
+
+ ntreeTagUsedSockets(ntree);
+}
+
static void ntree_validate_links(bNodeTree *ntree)
{
bNodeLink *link;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 53b0e0cf4a1..d63e2516805 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -96,6 +96,7 @@
#include "BKE_editmesh.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
+#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
@@ -107,6 +108,7 @@
#include "BKE_sequencer.h"
#include "BKE_speaker.h"
#include "BKE_softbody.h"
+#include "BKE_subsurf.h"
#include "BKE_material.h"
#include "BKE_camera.h"
#include "BKE_image.h"
@@ -119,6 +121,8 @@
#include "BPY_extern.h"
#endif
+#include "CCGSubSurf.h"
+
#include "GPU_material.h"
/* Vertex parent modifies original BMesh which is not safe for threading.
@@ -325,6 +329,45 @@ void BKE_object_free_derived_caches(Object *ob)
BKE_object_free_curve_cache(ob);
}
+void BKE_object_free_caches(Object *object)
+{
+ ModifierData *md;
+ short update_flag = 0;
+
+ /* Free particle system caches holding paths. */
+ if (object->particlesystem.first) {
+ ParticleSystem *psys;
+ for (psys = object->particlesystem.first;
+ psys != NULL;
+ psys = psys->next)
+ {
+ psys_free_path_cache(psys, psys->edit);
+ update_flag |= PSYS_RECALC;
+ }
+ }
+
+ /* Free memory used by cached derived meshes in the particle system modifiers. */
+ for (md = object->modifiers.first; md != NULL; md = md->next) {
+ if (md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
+ if (psmd->dm != NULL) {
+ psmd->dm->needsFree = 1;
+ psmd->dm->release(psmd->dm);
+ psmd->dm = NULL;
+ update_flag |= OB_RECALC_DATA;
+ }
+ }
+ }
+
+ /* Tag object for update, so once memory critical operation is over and
+ * scene update routines are back to it's business the object will be
+ * guaranteed to be in a known state.
+ */
+ if (update_flag != 0) {
+ DAG_id_tag_update(&object->id, update_flag);
+ }
+}
+
/* do not free object itself */
void BKE_object_free_ex(Object *ob, bool do_id_user)
{
@@ -381,7 +424,7 @@ void BKE_object_free_ex(Object *ob, bool do_id_user)
free_controllers(&ob->controllers);
free_actuators(&ob->actuators);
- BKE_constraints_free(&ob->constraints);
+ BKE_constraints_free_ex(&ob->constraints, do_id_user);
free_partdeflect(ob->pd);
BKE_rigidbody_free_object(ob);
@@ -432,6 +475,7 @@ void BKE_object_unlink(Object *ob)
Scene *sce;
SceneRenderLayer *srl;
FreestyleLineSet *lineset;
+ bNodeTree *ntree;
Curve *cu;
Tex *tex;
Group *group;
@@ -633,17 +677,22 @@ void BKE_object_unlink(Object *ob)
}
/* materials */
- mat = bmain->mat.first;
- while (mat) {
-
+ for (mat = bmain->mat.first; mat; mat = mat->id.next) {
+ if (mat->nodetree) {
+ ntreeSwitchID(mat->nodetree, &ob->id, NULL);
+ }
for (a = 0; a < MAX_MTEX; a++) {
if (mat->mtex[a] && ob == mat->mtex[a]->object) {
/* actually, test for lib here... to do */
mat->mtex[a]->object = NULL;
}
}
+ }
- mat = mat->id.next;
+ /* node trees */
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next) {
+ if (ntree->type == NTREE_SHADER)
+ ntreeSwitchID(ntree, &ob->id, NULL);
}
/* textures */
@@ -673,6 +722,7 @@ void BKE_object_unlink(Object *ob)
if (sce->camera == ob) sce->camera = NULL;
if (sce->toolsettings->skgen_template == ob) sce->toolsettings->skgen_template = NULL;
if (sce->toolsettings->particle.object == ob) sce->toolsettings->particle.object = NULL;
+ if (sce->toolsettings->particle.shape_object == ob) sce->toolsettings->particle.shape_object = NULL;
#ifdef DURIAN_CAMERA_SWITCH
{
@@ -1068,14 +1118,14 @@ static int lod_cmp(const void *a, const void *b)
void BKE_object_lod_sort(Object *ob)
{
- BLI_sortlist(&ob->lodlevels, lod_cmp);
+ BLI_listbase_sort(&ob->lodlevels, lod_cmp);
}
bool BKE_object_lod_remove(Object *ob, int level)
{
LodLevel *rem;
- if (level < 1 || level > BLI_countlist(&ob->lodlevels) - 1)
+ if (level < 1 || level > BLI_listbase_count(&ob->lodlevels) - 1)
return false;
rem = BLI_findlink(&ob->lodlevels, level);
@@ -1088,7 +1138,7 @@ bool BKE_object_lod_remove(Object *ob, int level)
MEM_freeN(rem);
/* If there are no user defined lods, remove the base lod as well */
- if (BLI_countlist(&ob->lodlevels) == 1) {
+ if (BLI_listbase_is_single(&ob->lodlevels)) {
LodLevel *base = ob->lodlevels.first;
BLI_remlink(&ob->lodlevels, base);
MEM_freeN(base);
@@ -1126,7 +1176,7 @@ static LodLevel *lod_level_select(Object *ob, const float camera_position[3])
bool BKE_object_lod_is_usable(Object *ob, Scene *scene)
{
- bool active = (scene) ? ob == OBACT : 0;
+ bool active = (scene) ? ob == OBACT : false;
return (ob->mode == OB_MODE_OBJECT || !active);
}
@@ -1223,7 +1273,7 @@ BulletSoftBody *copy_bulletsoftbody(BulletSoftBody *bsb)
return bsbn;
}
-static ParticleSystem *copy_particlesystem(ParticleSystem *psys)
+ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
{
ParticleSystem *psysn;
ParticleData *pa;
@@ -1303,7 +1353,7 @@ void BKE_object_copy_particlesystems(Object *obn, Object *ob)
BLI_listbase_clear(&obn->particlesystem);
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
- npsys = copy_particlesystem(psys);
+ npsys = BKE_object_copy_particlesystem(psys);
BLI_addtail(&obn->particlesystem, npsys);
@@ -1392,10 +1442,10 @@ bool BKE_object_pose_context_check(Object *ob)
(ob->pose) &&
(ob->mode & OB_MODE_POSE))
{
- return 1;
+ return true;
}
else {
- return 0;
+ return false;
}
}
@@ -1508,6 +1558,10 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
/* Copy runtime surve data. */
obn->curve_cache = NULL;
+ if (ob->id.lib) {
+ BKE_id_lib_local_paths(bmain, ob->id.lib, &obn->id);
+ }
+
return obn;
}
@@ -2009,12 +2063,16 @@ void BKE_object_to_mat4(Object *ob, float mat[4][4])
add_v3_v3v3(mat[3], ob->loc, ob->dloc);
}
+static void ob_get_parent_matrix(Scene *scene, Object *ob, Object *par, float parentmat[4][4]);
+
void BKE_object_matrix_local_get(struct Object *ob, float mat[4][4])
{
if (ob->parent) {
- float invmat[4][4]; /* for inverse of parent's matrix */
- invert_m4_m4(invmat, ob->parent->obmat);
- mul_m4_m4m4(mat, invmat, ob->obmat);
+ float par_imat[4][4];
+
+ ob_get_parent_matrix(NULL, ob, ob->parent, par_imat);
+ invert_m4(par_imat);
+ mul_m4_m4m4(mat, par_imat, ob->obmat);
}
else {
copy_m4_m4(mat, ob->obmat);
@@ -2151,26 +2209,60 @@ static void give_parvert(Object *par, int nr, float vec[3])
int numVerts = dm->getNumVerts(dm);
if (nr < numVerts) {
- /* avoid dm->getVertDataArray() since it allocates arrays in the dm (not thread safe) */
- int i;
+ bool use_special_ss_case = false;
+
+ if (dm->type == DM_TYPE_CCGDM) {
+ ModifierData *md;
+ VirtualModifierData virtualModifierData;
+ use_special_ss_case = true;
+ for (md = modifiers_getVirtualModifierList(par, &virtualModifierData);
+ md != NULL;
+ md = md->next)
+ {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ /* TODO(sergey): Check for disabled modifiers. */
+ if (mti->type != eModifierTypeType_OnlyDeform && md->next != NULL) {
+ use_special_ss_case = false;
+ break;
+ }
+ }
+ }
- if (em && dm->type == DM_TYPE_EDITBMESH) {
- if (em->bm->elem_table_dirty & BM_VERT) {
-#ifdef VPARENT_THREADING_HACK
- BLI_mutex_lock(&vparent_lock);
+ if (!use_special_ss_case) {
+ /* avoid dm->getVertDataArray() since it allocates arrays in the dm (not thread safe) */
+ if (em && dm->type == DM_TYPE_EDITBMESH) {
if (em->bm->elem_table_dirty & BM_VERT) {
- BM_mesh_elem_table_ensure(em->bm, BM_VERT);
- }
- BLI_mutex_unlock(&vparent_lock);
+#ifdef VPARENT_THREADING_HACK
+ BLI_mutex_lock(&vparent_lock);
+ if (em->bm->elem_table_dirty & BM_VERT) {
+ BM_mesh_elem_table_ensure(em->bm, BM_VERT);
+ }
+ BLI_mutex_unlock(&vparent_lock);
#else
- BLI_assert(!"Not safe for threading");
- BM_mesh_elem_table_ensure(em->bm, BM_VERT);
+ BLI_assert(!"Not safe for threading");
+ BM_mesh_elem_table_ensure(em->bm, BM_VERT);
#endif
+ }
+ }
+ }
+
+ if (use_special_ss_case) {
+ /* Special case if the last modifier is SS and no constructive modifier are in front of it. */
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGVert *ccg_vert = ccgSubSurf_getVert(ccgdm->ss, SET_INT_IN_POINTER(nr));
+ /* In case we deleted some verts, nr may refer to inexistent one now, see T42557. */
+ if (ccg_vert) {
+ float *co = ccgSubSurf_getVertData(ccgdm->ss, ccg_vert);
+ add_v3_v3(vec, co);
+ count++;
}
}
+ else if (CustomData_has_layer(&dm->vertData, CD_ORIGINDEX) &&
+ !(em && dm->type == DM_TYPE_EDITBMESH))
+ {
+ int i;
- /* get the average of all verts with (original index == nr) */
- if (CustomData_has_layer(&dm->vertData, CD_ORIGINDEX)) {
+ /* Get the average of all verts with (original index == nr). */
for (i = 0; i < numVerts; i++) {
const int *index = dm->getVertData(dm, i, CD_ORIGINDEX);
if (*index == nr) {
@@ -2357,7 +2449,7 @@ static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat
/* include framerate */
fac1 = (1.0f / (1.0f + fabsf(ob->sf)));
- if (fac1 >= 1.0f) return 0;
+ if (fac1 >= 1.0f) return false;
fac2 = 1.0f - fac1;
fp1 = obmat[0];
@@ -2366,7 +2458,7 @@ static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat
fp1[0] = fac1 * fp1[0] + fac2 * fp2[0];
}
- return 1;
+ return true;
}
/* note, scene is the active scene while actual_scene is the scene the object resides in */
@@ -2490,17 +2582,16 @@ void BKE_object_apply_mat4(Object *ob, float mat[4][4], const bool use_compat, c
mul_m4_m4m4(diff_mat, parent_mat, ob->parentinv);
invert_m4_m4(imat, diff_mat);
mul_m4_m4m4(rmat, imat, mat); /* get the parent relative matrix */
- BKE_object_apply_mat4(ob, rmat, use_compat, false);
/* same as below, use rmat rather than mat */
mat4_to_loc_rot_size(ob->loc, rot, ob->size, rmat);
- BKE_object_mat3_to_rot(ob, rot, use_compat);
}
else {
mat4_to_loc_rot_size(ob->loc, rot, ob->size, mat);
- BKE_object_mat3_to_rot(ob, rot, use_compat);
}
+ BKE_object_mat3_to_rot(ob, rot, use_compat);
+
sub_v3_v3(ob->loc, ob->dloc);
if (ob->dscale[0] != 0.0f) ob->size[0] /= ob->dscale[0];
@@ -3255,7 +3346,7 @@ int BKE_object_insert_ptcache(Object *ob)
LinkData *link = NULL;
int i = 0;
- BLI_sortlist(&ob->pc_ids, pc_cmp);
+ BLI_listbase_sort(&ob->pc_ids, pc_cmp);
for (link = ob->pc_ids.first, i = 0; link; link = link->next, i++) {
int index = GET_INT_FROM_POINTER(link->data);
@@ -3300,7 +3391,7 @@ void BKE_object_delete_ptcache(Object *ob, int index)
/* shape key utility function */
/************************* Mesh ************************/
-static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, const bool from_mix)
+static KeyBlock *insert_meshkey(Object *ob, const char *name, const bool from_mix)
{
Mesh *me = ob->data;
Key *key = me->key;
@@ -3316,12 +3407,12 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, cons
if (newkey || from_mix == false) {
/* create from mesh */
kb = BKE_keyblock_add_ctime(key, name, false);
- BKE_key_convert_from_mesh(me, kb);
+ BKE_keyblock_convert_from_mesh(me, kb);
}
else {
/* copy from current values */
int totelem;
- float *data = BKE_key_evaluate_object(scene, ob, &totelem);
+ float *data = BKE_key_evaluate_object(ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, false);
@@ -3332,7 +3423,7 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, cons
return kb;
}
/************************* Lattice ************************/
-static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, const bool from_mix)
+static KeyBlock *insert_lattkey(Object *ob, const char *name, const bool from_mix)
{
Lattice *lt = ob->data;
Key *key = lt->key;
@@ -3353,13 +3444,13 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, cons
kb->totelem = basekb->totelem;
}
else {
- BKE_key_convert_from_lattice(lt, kb);
+ BKE_keyblock_convert_from_lattice(lt, kb);
}
}
else {
/* copy from current values */
int totelem;
- float *data = BKE_key_evaluate_object(scene, ob, &totelem);
+ float *data = BKE_key_evaluate_object(ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, false);
@@ -3370,7 +3461,7 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, cons
return kb;
}
/************************* Curve ************************/
-static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, const bool from_mix)
+static KeyBlock *insert_curvekey(Object *ob, const char *name, const bool from_mix)
{
Curve *cu = ob->data;
Key *key = cu->key;
@@ -3393,13 +3484,13 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, con
kb->totelem = basekb->totelem;
}
else {
- BKE_key_convert_from_curve(cu, kb, lb);
+ BKE_keyblock_convert_from_curve(cu, kb, lb);
}
}
else {
/* copy from current values */
int totelem;
- float *data = BKE_key_evaluate_object(scene, ob, &totelem);
+ float *data = BKE_key_evaluate_object(ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, false);
@@ -3410,22 +3501,35 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, con
return kb;
}
-KeyBlock *BKE_object_insert_shape_key(Scene *scene, Object *ob, const char *name, const bool from_mix)
+KeyBlock *BKE_object_insert_shape_key(Object *ob, const char *name, const bool from_mix)
{
switch (ob->type) {
case OB_MESH:
- return insert_meshkey(scene, ob, name, from_mix);
+ return insert_meshkey(ob, name, from_mix);
case OB_CURVE:
case OB_SURF:
- return insert_curvekey(scene, ob, name, from_mix);
+ return insert_curvekey(ob, name, from_mix);
case OB_LATTICE:
- return insert_lattkey(scene, ob, name, from_mix);
+ return insert_lattkey(ob, name, from_mix);
default:
return NULL;
}
}
+bool BKE_object_flag_test_recursive(const Object *ob, short flag)
+{
+ if (ob->flag & flag) {
+ return true;
+ }
+ else if (ob->parent) {
+ return BKE_object_flag_test_recursive(ob->parent, flag);
+ }
+ else {
+ return false;
+ }
+}
+
bool BKE_object_is_child_recursive(Object *ob_parent, Object *ob_child)
{
for (ob_child = ob_child->parent; ob_child; ob_child = ob_child->parent) {
@@ -3464,6 +3568,88 @@ int BKE_object_is_modified(Scene *scene, Object *ob)
return flag;
}
+/* Check of objects moves in time. */
+/* NOTE: This function is currently optimized for usage in combination
+ * with mti->canDeform, so modifiers can quickly check if their target
+ * objects moves (causing deformation motion blur) or not.
+ *
+ * This makes it possible to give some degree of false-positives here,
+ * but it's currently an acceptable tradeoff between complexity and check
+ * speed. In combination with checks of modifier stack and real life usage
+ * percentage of false-positives shouldn't be that hight.
+ */
+static bool object_moves_in_time(Object *object)
+{
+ AnimData *adt = object->adt;
+ if (adt != NULL) {
+ /* If object has any sort of animation data assume it is moving. */
+ if (adt->action != NULL ||
+ !BLI_listbase_is_empty(&adt->nla_tracks) ||
+ !BLI_listbase_is_empty(&adt->drivers) ||
+ !BLI_listbase_is_empty(&adt->overrides))
+ {
+ return true;
+ }
+ }
+ if (!BLI_listbase_is_empty(&object->constraints)) {
+ return true;
+ }
+ if (object->parent != NULL) {
+ /* TODO(sergey): Do recursive check here? */
+ return true;
+ }
+ return false;
+}
+
+static bool constructive_modifier_is_deform_modified(ModifierData *md)
+{
+ /* TODO(sergey): Consider generalizing this a bit so all modifier logic
+ * is concentrated in MOD_{modifier}.c file,
+ */
+ if (md->type == eModifierType_Array) {
+ ArrayModifierData *amd = (ArrayModifierData *)md;
+ /* TODO(sergey): Check if curve is deformed. */
+ return (amd->start_cap != NULL && object_moves_in_time(amd->start_cap)) ||
+ (amd->end_cap != NULL && object_moves_in_time(amd->end_cap)) ||
+ (amd->curve_ob != NULL && object_moves_in_time(amd->curve_ob)) ||
+ (amd->offset_ob != NULL && object_moves_in_time(amd->offset_ob));
+ }
+ else if (md->type == eModifierType_Mirror) {
+ MirrorModifierData *mmd = (MirrorModifierData *)md;
+ return mmd->mirror_ob != NULL && object_moves_in_time(mmd->mirror_ob);
+ }
+ else if (md->type == eModifierType_Screw) {
+ ScrewModifierData *smd = (ScrewModifierData *)md;
+ return smd->ob_axis != NULL && object_moves_in_time(smd->ob_axis);
+ }
+ return false;
+}
+
+static bool modifiers_has_animation_check(Object *ob)
+{
+ /* TODO(sergey): This is a bit code duplication with depsgraph, but
+ * would be nicer to solve this as a part of new dependency graph
+ * work, so we avoid conflicts and so.
+ */
+ if (ob->adt != NULL) {
+ AnimData *adt = ob->adt;
+ FCurve *fcu;
+ if (adt->action != NULL) {
+ for (fcu = adt->action->curves.first; fcu; fcu = fcu->next) {
+ if (fcu->rna_path && strstr(fcu->rna_path, "modifiers[")) {
+ return true;
+ }
+ }
+ }
+ for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
+ if (fcu->rna_path && strstr(fcu->rna_path, "modifiers[")) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/* test if object is affected by deforming modifiers (for motion blur). again
* most important is to avoid false positives, this is to skip computations
* and we can still if there was actual deformation afterwards */
@@ -3472,6 +3658,7 @@ int BKE_object_is_deform_modified(Scene *scene, Object *ob)
ModifierData *md;
VirtualModifierData virtualModifierData;
int flag = 0;
+ const bool is_modifier_animated = modifiers_has_animation_check(ob);
if (BKE_key_from_object(ob))
flag |= eModifierMode_Realtime | eModifierMode_Render;
@@ -3482,8 +3669,14 @@ int BKE_object_is_deform_modified(Scene *scene, Object *ob)
md = md->next)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ bool can_deform = mti->type == eModifierTypeType_OnlyDeform ||
+ is_modifier_animated;
+
+ if (!can_deform) {
+ can_deform = constructive_modifier_is_deform_modified(md);
+ }
- if (mti->type == eModifierTypeType_OnlyDeform) {
+ if (can_deform) {
if (!(flag & eModifierMode_Render) && modifier_isEnabled(scene, md, eModifierMode_Render))
flag |= eModifierMode_Render;
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index e53bd26b9a2..e46929dde4a 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -27,18 +27,457 @@
#include "MEM_guardedalloc.h"
+#include "BLF_translation.h"
+
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
+#include "DNA_armature_types.h"
+#include "DNA_cloth_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
+#include "DNA_scene_types.h"
+
#include "BKE_action.h"
+#include "BKE_deform.h"
+#include "BKE_editmesh.h"
#include "BKE_object_deform.h" /* own include */
#include "BKE_object.h"
#include "BKE_modifier.h"
-#include "DNA_armature_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
+/** \name Misc helpers
+ * \{ */
+
+static Lattice *object_defgroup_lattice_get(ID *id)
+{
+ Lattice *lt = (Lattice *)id;
+ BLI_assert(GS(id->name) == ID_LT);
+ return (lt->editlatt) ? lt->editlatt->latt : lt;
+}
+
+/**
+ * Update users of vgroups from this object, according to given map.
+ *
+ * Use it when you remove or reorder vgroups in the object.
+ *
+ * \param map an array mapping old indices to new indices.
+ */
+void BKE_object_defgroup_remap_update_users(Object *ob, int *map)
+{
+ ModifierData *md;
+ ParticleSystem *psys;
+ int a;
+
+ /* these cases don't use names to refer to vertex groups, so when
+ * they get removed the numbers get out of sync, this corrects that */
+
+ if (ob->soft) {
+ ob->soft->vertgroup = map[ob->soft->vertgroup];
+ }
+
+ for (md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Explode) {
+ ExplodeModifierData *emd = (ExplodeModifierData *)md;
+ emd->vgroup = map[emd->vgroup];
+ }
+ else if (md->type == eModifierType_Cloth) {
+ ClothModifierData *clmd = (ClothModifierData *)md;
+ ClothSimSettings *clsim = clmd->sim_parms;
+
+ if (clsim) {
+ clsim->vgroup_mass = map[clsim->vgroup_mass];
+ clsim->vgroup_bend = map[clsim->vgroup_bend];
+ clsim->vgroup_struct = map[clsim->vgroup_struct];
+ }
+ }
+ }
+
+ for (psys = ob->particlesystem.first; psys; psys = psys->next) {
+ for (a = 0; a < PSYS_TOT_VG; a++) {
+ psys->vgroup[a] = map[psys->vgroup[a]];
+ }
+ }
+}
+/** \} */
+
+
+/** \name Group creation
+ * \{ */
+
+/**
+ * Add a vgroup of given name to object. *Does not* handle MDeformVert data at all!
+ */
+bDeformGroup *BKE_object_defgroup_add_name(Object *ob, const char *name)
+{
+ bDeformGroup *defgroup;
+
+ if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type))
+ return NULL;
+
+ defgroup = BKE_defgroup_new(ob, name);
+
+ ob->actdef = BLI_listbase_count(&ob->defbase);
+
+ return defgroup;
+}
+
+/**
+ * Add a vgroup of default name to object. *Does not* handle MDeformVert data at all!
+ */
+bDeformGroup *BKE_object_defgroup_add(Object *ob)
+{
+ return BKE_object_defgroup_add_name(ob, DATA_("Group"));
+}
+
+/**
+ * Create MDeformVert data for given ID. Work in Object mode only.
+ */
+MDeformVert *BKE_object_defgroup_data_create(ID *id)
+{
+ if (GS(id->name) == ID_ME) {
+ Mesh *me = (Mesh *)id;
+ me->dvert = CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
+ return me->dvert;
+ }
+ else if (GS(id->name) == ID_LT) {
+ Lattice *lt = (Lattice *)id;
+ lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert");
+ return lt->dvert;
+ }
+
+ return NULL;
+}
+/** \} */
+
+
+/** \name Group clearing
+ * \{ */
+
+/**
+ * Remove all verts (or only selected ones) from given vgroup. Work in Object and Edit modes.
+ *
+ * \param allverts If true, remove all vertices, else only selected ones.
+ * \return True if any vertex was removed, false otherwise.
+ */
+bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection)
+{
+ MDeformVert *dv;
+ const int def_nr = BLI_findindex(&ob->defbase, dg);
+ bool changed = false;
+
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+
+ if (me->edit_btmesh) {
+ BMEditMesh *em = me->edit_btmesh;
+ const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+
+ if (cd_dvert_offset != -1) {
+ BMVert *eve;
+ BMIter iter;
+
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
+ dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+
+ if (dv && dv->dw && (!use_selection || BM_elem_flag_test(eve, BM_ELEM_SELECT))) {
+ MDeformWeight *dw = defvert_find_index(dv, def_nr);
+ defvert_remove_group(dv, dw); /* dw can be NULL */
+ changed = true;
+ }
+ }
+ }
+ }
+ else {
+ if (me->dvert) {
+ MVert *mv;
+ int i;
+
+ mv = me->mvert;
+ dv = me->dvert;
+
+ for (i = 0; i < me->totvert; i++, mv++, dv++) {
+ if (mv->flag & SELECT) {
+ if (dv->dw && (!use_selection || (mv->flag & SELECT))) {
+ MDeformWeight *dw = defvert_find_index(dv, def_nr);
+ defvert_remove_group(dv, dw); /* dw can be NULL */
+ changed = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
+
+ if (lt->dvert) {
+ BPoint *bp;
+ int i, tot = lt->pntsu * lt->pntsv * lt->pntsw;
+
+ for (i = 0, bp = lt->def; i < tot; i++, bp++) {
+ if (!use_selection || (bp->f1 & SELECT)) {
+ MDeformWeight *dw;
+
+ dv = &lt->dvert[i];
+
+ dw = defvert_find_index(dv, def_nr);
+ defvert_remove_group(dv, dw); /* dw can be NULL */
+ changed = true;
+ }
+ }
+ }
+ }
+
+ return changed;
+}
+
+/**
+ * Remove all verts (or only selected ones) from all vgroups. Work in Object and Edit modes.
+ *
+ * \param allverts If true, remove all vertices, else only selected ones.
+ * \return True if any vertex was removed, false otherwise.
+ */
+bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
+{
+ bDeformGroup *dg;
+ bool changed = false;
+
+ for (dg = ob->defbase.first; dg; dg = dg->next) {
+ if (BKE_object_defgroup_clear(ob, dg, use_selection)) {
+ changed = true;
+ }
+ }
+
+ return changed;
+}
+/** \} */
+
+
+/** \name Group removal
+ * \{ */
+
+static void object_defgroup_remove_update_users(Object *ob, const int idx)
+{
+ int i, defbase_tot = BLI_listbase_count(&ob->defbase) + 1;
+ int *map = MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del");
+
+ map[idx] = map[0] = 0;
+ for (i = 1; i < idx; i++) {
+ map[i] = i;
+ }
+ for (i = idx + 1; i < defbase_tot; i++) {
+ map[i] = i - 1;
+ }
+
+ BKE_object_defgroup_remap_update_users(ob, map);
+ MEM_freeN(map);
+}
+
+static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const int def_nr)
+{
+ object_defgroup_remove_update_users(ob, def_nr + 1);
+
+ /* Remove the group */
+ BLI_freelinkN(&ob->defbase, dg);
+
+ /* Update the active deform index if necessary */
+ if (ob->actdef > def_nr)
+ ob->actdef--;
+
+ /* remove all dverts */
+ if (BLI_listbase_is_empty(&ob->defbase)) {
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
+ me->dvert = NULL;
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
+ if (lt->dvert) {
+ MEM_freeN(lt->dvert);
+ lt->dvert = NULL;
+ }
+ }
+ }
+ else if (ob->actdef < 1) { /* Keep a valid active index if we still have some vgroups. */
+ ob->actdef = 1;
+ }
+}
+
+static void object_defgroup_remove_object_mode(Object *ob, bDeformGroup *dg)
+{
+ MDeformVert *dvert_array = NULL;
+ int dvert_tot = 0;
+ const int def_nr = BLI_findindex(&ob->defbase, dg);
+
+ BLI_assert(def_nr != -1);
+
+ BKE_object_defgroup_array_get(ob->data, &dvert_array, &dvert_tot);
+
+ if (dvert_array) {
+ int i, j;
+ MDeformVert *dv;
+ for (i = 0, dv = dvert_array; i < dvert_tot; i++, dv++) {
+ MDeformWeight *dw;
+
+ dw = defvert_find_index(dv, def_nr);
+ defvert_remove_group(dv, dw); /* dw can be NULL */
+
+ /* inline, make into a function if anything else needs to do this */
+ for (j = 0; j < dv->totweight; j++) {
+ if (dv->dw[j].def_nr > def_nr) {
+ dv->dw[j].def_nr--;
+ }
+ }
+ /* done */
+ }
+ }
+
+ object_defgroup_remove_common(ob, dg, def_nr);
+}
+
+static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg)
+{
+ int i;
+ const int def_nr = BLI_findindex(&ob->defbase, dg);
+
+ BLI_assert(def_nr != -1);
+
+ /* Make sure that no verts are using this group - if none were removed, we can skip next per-vert update. */
+ if (!BKE_object_defgroup_clear(ob, dg, false)) {
+ /* Nothing to do. */
+ }
+ /* Else, make sure that any groups with higher indices are adjusted accordingly */
+ else if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+
+ BMIter iter;
+ BMVert *eve;
+ MDeformVert *dvert;
+
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
+ dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+
+ if (dvert) {
+ for (i = 0; i < dvert->totweight; i++) {
+ if (dvert->dw[i].def_nr > def_nr) {
+ dvert->dw[i].def_nr--;
+ }
+ }
+ }
+ }
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = ((Lattice *)(ob->data))->editlatt->latt;
+ BPoint *bp;
+ MDeformVert *dvert = lt->dvert;
+ int a, tot;
+
+ if (dvert) {
+ tot = lt->pntsu * lt->pntsv * lt->pntsw;
+ for (a = 0, bp = lt->def; a < tot; a++, bp++, dvert++) {
+ for (i = 0; i < dvert->totweight; i++) {
+ if (dvert->dw[i].def_nr > def_nr) {
+ dvert->dw[i].def_nr--;
+ }
+ }
+ }
+ }
+ }
+
+ object_defgroup_remove_common(ob, dg, def_nr);
+}
+
+/**
+ * Remove given vgroup from object. Work in Object and Edit modes.
+ */
+void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup)
+{
+ if (BKE_object_is_in_editmode_vgroup(ob))
+ object_defgroup_remove_edit_mode(ob, defgroup);
+ else
+ object_defgroup_remove_object_mode(ob, defgroup);
+}
+
+/**
+ * Remove all vgroups from object. Work in Object and Edit modes.
+ */
+void BKE_object_defgroup_remove_all(Object *ob)
+{
+ bDeformGroup *dg = (bDeformGroup *)ob->defbase.first;
+ const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
+
+ if (dg) {
+ while (dg) {
+ bDeformGroup *next_dg = dg->next;
+
+ if (edit_mode)
+ object_defgroup_remove_edit_mode(ob, dg);
+ else
+ object_defgroup_remove_object_mode(ob, dg);
+
+ dg = next_dg;
+ }
+ }
+ else { /* ob->defbase is empty... */
+ /* remove all dverts */
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
+ me->dvert = NULL;
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
+ if (lt->dvert) {
+ MEM_freeN(lt->dvert);
+ lt->dvert = NULL;
+ }
+ }
+ /* Fix counters/indices */
+ ob->actdef = 0;
+ }
+}
+
+/**
+ * Get MDeformVert vgroup data from given object. Should only be used in Object mode.
+ *
+ * \return True if the id type supports weights.
+ */
+bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot)
+{
+ if (id) {
+ switch (GS(id->name)) {
+ case ID_ME:
+ {
+ Mesh *me = (Mesh *)id;
+ *dvert_arr = me->dvert;
+ *dvert_tot = me->totvert;
+ return true;
+ }
+ case ID_LT:
+ {
+ Lattice *lt = object_defgroup_lattice_get(id);
+ *dvert_arr = lt->dvert;
+ *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw;
+ return true;
+ }
+ }
+ }
+
+ *dvert_arr = NULL;
+ *dvert_tot = 0;
+ return false;
+}
+/** \} */
/* --- functions for getting vgroup aligned maps --- */
@@ -46,11 +485,11 @@
* gets the status of "flag" for each bDeformGroup
* in ob->defbase and returns an array containing them
*/
-bool *BKE_objdef_lock_flags_get(Object *ob, const int defbase_tot)
+bool *BKE_object_defgroup_lock_flags_get(Object *ob, const int defbase_tot)
{
bool is_locked = false;
int i;
- //int defbase_tot = BLI_countlist(&ob->defbase);
+ //int defbase_tot = BLI_listbase_count(&ob->defbase);
bool *lock_flags = MEM_mallocN(defbase_tot * sizeof(bool), "defflags");
bDeformGroup *defgroup;
@@ -66,21 +505,21 @@ bool *BKE_objdef_lock_flags_get(Object *ob, const int defbase_tot)
return NULL;
}
-bool *BKE_objdef_validmap_get(Object *ob, const int defbase_tot)
+bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
{
bDeformGroup *dg;
ModifierData *md;
- bool *vgroup_validmap;
+ bool *defgroup_validmap;
GHash *gh;
int i, step1 = 1;
- //int defbase_tot = BLI_countlist(&ob->defbase);
+ //int defbase_tot = BLI_listbase_count(&ob->defbase);
VirtualModifierData virtualModifierData;
if (BLI_listbase_is_empty(&ob->defbase)) {
return NULL;
}
- gh = BLI_ghash_str_new_ex("BKE_objdef_validmap_get gh", defbase_tot);
+ gh = BLI_ghash_str_new_ex(__func__, defbase_tot);
/* add all names to a hash table */
for (dg = ob->defbase.first; dg; dg = dg->next) {
@@ -115,23 +554,23 @@ bool *BKE_objdef_validmap_get(Object *ob, const int defbase_tot)
}
}
- vgroup_validmap = MEM_mallocN(sizeof(*vgroup_validmap) * defbase_tot, "wpaint valid map");
+ defgroup_validmap = MEM_mallocN(sizeof(*defgroup_validmap) * defbase_tot, "wpaint valid map");
/* add all names to a hash table */
for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
- vgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
+ defgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
}
BLI_assert(i == BLI_ghash_size(gh));
BLI_ghash_free(gh, NULL, NULL);
- return vgroup_validmap;
+ return defgroup_validmap;
}
/* Returns total selected vgroups,
* wpi.defbase_sel is assumed malloc'd, all values are set */
-bool *BKE_objdef_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
+bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
{
bool *dg_selection = MEM_mallocN(defbase_tot * sizeof(bool), __func__);
bDeformGroup *defgroup;
@@ -158,3 +597,86 @@ bool *BKE_objdef_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_t
return dg_selection;
}
+
+
+/**
+ * Return the subset type of the Vertex Group Selection
+ */
+bool *BKE_object_defgroup_subset_from_select_type(
+ Object *ob, eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count)
+{
+ bool *defgroup_validmap = NULL;
+ *r_defgroup_tot = BLI_listbase_count(&ob->defbase);
+
+ switch (subset_type) {
+ case WT_VGROUP_ACTIVE:
+ {
+ const int def_nr_active = ob->actdef - 1;
+ defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
+ memset(defgroup_validmap, false, *r_defgroup_tot * sizeof(*defgroup_validmap));
+ if ((def_nr_active >= 0) && (def_nr_active < *r_defgroup_tot)) {
+ *r_subset_count = 1;
+ defgroup_validmap[def_nr_active] = true;
+ }
+ else {
+ *r_subset_count = 0;
+ }
+ break;
+ }
+ case WT_VGROUP_BONE_SELECT:
+ {
+ defgroup_validmap = BKE_object_defgroup_selected_get(ob, *r_defgroup_tot, r_subset_count);
+ break;
+ }
+ case WT_VGROUP_BONE_DEFORM:
+ {
+ int i;
+ defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
+ *r_subset_count = 0;
+ for (i = 0; i < *r_defgroup_tot; i++) {
+ if (defgroup_validmap[i] == true) {
+ *r_subset_count += 1;
+ }
+ }
+ break;
+ }
+ case WT_VGROUP_BONE_DEFORM_OFF:
+ {
+ int i;
+ defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
+ *r_subset_count = 0;
+ for (i = 0; i < *r_defgroup_tot; i++) {
+ defgroup_validmap[i] = !defgroup_validmap[i];
+ if (defgroup_validmap[i] == true) {
+ *r_subset_count += 1;
+ }
+ }
+ break;
+ }
+ case WT_VGROUP_ALL:
+ default:
+ {
+ defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
+ memset(defgroup_validmap, true, *r_defgroup_tot * sizeof(*defgroup_validmap));
+ *r_subset_count = *r_defgroup_tot;
+ break;
+ }
+ }
+
+ return defgroup_validmap;
+}
+
+/**
+ * store indices from the defgroup_validmap (faster lookups in some cases)
+ */
+void BKE_object_defgroup_subset_to_index_array(
+ const bool *defgroup_validmap, const int defgroup_tot, int *r_defgroup_subset_map)
+{
+ int i, j = 0;
+ for (i = 0; i < defgroup_tot; i++) {
+ if (defgroup_validmap[i]) {
+ r_defgroup_subset_map[j++] = i;
+ }
+ }
+}
+
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 0d82c6e89a1..c77f65f69e1 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -969,9 +969,9 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
}
/* some hair paths might be non-existent so they can't be used for duplication */
- if (hair &&
- ((a < totpart && psys->pathcache[a]->steps < 0) ||
- (a >= totpart && psys->childcache[a - totpart]->steps < 0)))
+ if (hair && psys->pathcache &&
+ ((a < totpart && psys->pathcache[a]->segments < 0) ||
+ (a >= totpart && psys->childcache[a - totpart]->segments < 0)))
{
continue;
}
@@ -1240,7 +1240,7 @@ int count_duplilist(Object *ob)
DupliApplyData *duplilist_apply(Object *ob, ListBase *duplilist)
{
DupliApplyData *apply_data = NULL;
- int num_objects = BLI_countlist(duplilist);
+ int num_objects = BLI_listbase_count(duplilist);
if (num_objects > 0) {
DupliObject *dob;
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 373ad34e7bd..12e82d3a34f 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -1002,7 +1002,7 @@ static void cache_filename(char *string, const char *path, const char *relbase,
BLI_join_dirfile(cachepath, sizeof(cachepath), path, fname);
- BKE_makepicstring_from_type(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, true, true);
+ BKE_image_path_from_imtype(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, true, true);
}
/* silly functions but useful to inline when the args do a lot of indirections */
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index d186b4299a5..8d56b1247fe 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -376,7 +376,7 @@ int checkPackedFile(const char *filename, PackedFile *pf)
BLI_strncpy(name, filename, sizeof(name));
BLI_path_abs(name, G.main->name);
- if (BLI_stat(name, &st)) {
+ if (BLI_stat(name, &st) == -1) {
ret_val = PF_NOFILE;
}
else if (st.st_size != pf->size) {
@@ -429,9 +429,6 @@ char *unpackFile(ReportList *reports, const char *abs_name, const char *local_na
char *newname = NULL;
const char *temp = NULL;
- // char newabs[FILE_MAX];
- // char newlocal[FILE_MAX];
-
if (pf != NULL) {
switch (how) {
case -1:
@@ -480,17 +477,54 @@ char *unpackFile(ReportList *reports, const char *abs_name, const char *local_na
return newname;
}
+static void unpack_generate_paths(
+ const char *name, ID *id, char *abspath_r, char *relpath_r, size_t abspathlen, size_t relpathlen)
+{
+ char tempname[FILE_MAX];
+ char tempdir[FILE_MAXDIR];
+
+ BLI_split_dirfile(name, tempdir, tempname, sizeof(tempdir), sizeof(tempname));
+
+ if (tempname[0] == '\0') {
+ /* Note: we do not have any real way to re-create extension out of data... */
+ BLI_strncpy(tempname, id->name + 2, sizeof(tempname));
+ printf("%s\n", tempname);
+ BLI_filename_make_safe(tempname);
+ printf("%s\n", tempname);
+ }
+
+ if (tempdir[0] == '\0') {
+ /* Fallback to relative dir. */
+ BLI_strncpy(tempdir, "//", sizeof(tempdir));
+ }
+
+ switch (GS(id->name)) {
+ case ID_VF:
+ BLI_snprintf(relpath_r, relpathlen, "//fonts/%s", tempname);
+ break;
+ case ID_SO:
+ BLI_snprintf(relpath_r, relpathlen, "//sounds/%s", tempname);
+ break;
+ case ID_IM:
+ BLI_snprintf(relpath_r, relpathlen, "//textures/%s", tempname);
+ break;
+ }
+
+ {
+ size_t len = BLI_strncpy_rlen(abspath_r, tempdir, abspathlen);
+ BLI_strncpy(abspath_r + len, tempname, abspathlen - len);
+ }
+}
int unpackVFont(ReportList *reports, VFont *vfont, int how)
{
- char localname[FILE_MAX], fi[FILE_MAXFILE];
+ char localname[FILE_MAX], absname[FILE_MAX];
char *newname;
int ret_value = RET_ERROR;
if (vfont != NULL) {
- BLI_split_file_part(vfont->name, fi, sizeof(fi));
- BLI_snprintf(localname, sizeof(localname), "//fonts/%s", fi);
- newname = unpackFile(reports, vfont->name, localname, vfont->packedfile, how);
+ unpack_generate_paths(vfont->name, (ID *)vfont, absname, localname, sizeof(absname), sizeof(localname));
+ newname = unpackFile(reports, absname, localname, vfont->packedfile, how);
if (newname != NULL) {
ret_value = RET_OK;
freePackedFile(vfont->packedfile);
@@ -505,14 +539,13 @@ int unpackVFont(ReportList *reports, VFont *vfont, int how)
int unpackSound(Main *bmain, ReportList *reports, bSound *sound, int how)
{
- char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
+ char localname[FILE_MAX], absname[FILE_MAX];
char *newname;
int ret_value = RET_ERROR;
if (sound != NULL) {
- BLI_split_file_part(sound->name, fi, sizeof(fi));
- BLI_snprintf(localname, sizeof(localname), "//sounds/%s", fi);
- newname = unpackFile(reports, sound->name, localname, sound->packedfile, how);
+ unpack_generate_paths(sound->name, (ID *)sound, absname, localname, sizeof(absname), sizeof(localname));
+ newname = unpackFile(reports, absname, localname, sound->packedfile, how);
if (newname != NULL) {
BLI_strncpy(sound->name, newname, sizeof(sound->name));
MEM_freeN(newname);
@@ -531,14 +564,13 @@ int unpackSound(Main *bmain, ReportList *reports, bSound *sound, int how)
int unpackImage(ReportList *reports, Image *ima, int how)
{
- char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
+ char localname[FILE_MAX], absname[FILE_MAX];
char *newname;
int ret_value = RET_ERROR;
if (ima != NULL && ima->name[0]) {
- BLI_split_file_part(ima->name, fi, sizeof(fi));
- BLI_snprintf(localname, sizeof(localname), "//textures/%s", fi);
- newname = unpackFile(reports, ima->name, localname, ima->packedfile, how);
+ unpack_generate_paths(ima->name, (ID *)ima, absname, localname, sizeof(absname), sizeof(localname));
+ newname = unpackFile(reports, absname, localname, ima->packedfile, how);
if (newname != NULL) {
ret_value = RET_OK;
freePackedFile(ima->packedfile);
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index d16575d80c8..431eec0d220 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -48,6 +48,7 @@
#include "BLI_listbase.h"
#include "BKE_brush.h"
+#include "BKE_colortools.h"
#include "BKE_main.h"
#include "BKE_context.h"
#include "BKE_crazyspace.h"
@@ -316,7 +317,7 @@ void BKE_paint_curve_set(Brush *br, PaintCurve *pc)
void BKE_palette_color_remove(Palette *palette, PaletteColor *color)
{
if (color) {
- int numcolors = BLI_countlist(&palette->colors);
+ int numcolors = BLI_listbase_count(&palette->colors);
if ((numcolors == palette->active_color + 1) && (numcolors != 1))
palette->active_color--;
@@ -352,7 +353,7 @@ PaletteColor *BKE_palette_color_add(Palette *palette)
{
PaletteColor *color = MEM_callocN(sizeof(*color), "Pallete Color");
BLI_addtail(&palette->colors, color);
- palette->active_color = BLI_countlist(&palette->colors) - 1;
+ palette->active_color = BLI_listbase_count(&palette->colors) - 1;
return color;
}
@@ -395,7 +396,22 @@ bool BKE_paint_select_elem_test(Object *ob)
BKE_paint_select_face_test(ob));
}
-void BKE_paint_init(Paint *p, const char col[3])
+void BKE_paint_cavity_curve_preset(Paint *p, int preset)
+{
+ CurveMap *cm = NULL;
+
+ if (!p->cavity_curve)
+ p->cavity_curve = curvemapping_add(1, 0, 0, 1, 1);
+
+ cm = p->cavity_curve->cm;
+ cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+
+ p->cavity_curve->preset = preset;
+ curvemap_reset(cm, &p->cavity_curve->clipr, p->cavity_curve->preset, CURVEMAP_SLOPE_POSITIVE);
+ curvemapping_changed(p->cavity_curve, false);
+}
+
+void BKE_paint_init(UnifiedPaintSettings *ups, Paint *p, const char col[3])
{
Brush *brush;
@@ -407,12 +423,18 @@ void BKE_paint_init(Paint *p, const char col[3])
memcpy(p->paint_cursor_col, col, 3);
p->paint_cursor_col[3] = 128;
+ ups->last_stroke_valid = false;
+ zero_v3(ups->average_stroke_accum);
+ ups->average_stroke_counter = 0;
+ if (!p->cavity_curve)
+ BKE_paint_cavity_curve_preset(p, CURVE_PRESET_LINE);
}
void BKE_paint_free(Paint *paint)
{
id_us_min((ID *)paint->brush);
id_us_min((ID *)paint->palette);
+ curvemapping_free(paint->cavity_curve);
}
/* called when copying scene settings, so even if 'src' and 'tar' are the same
@@ -424,6 +446,19 @@ void BKE_paint_copy(Paint *src, Paint *tar)
tar->brush = src->brush;
id_us_plus((ID *)tar->brush);
id_us_plus((ID *)tar->palette);
+ tar->cavity_curve = curvemapping_copy(src->cavity_curve);
+}
+
+void BKE_paint_stroke_get_average(Scene *scene, Object *ob, float stroke[3])
+{
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+ if (ups->last_stroke_valid && ups->average_stroke_counter > 0) {
+ float fac = 1.0f / ups->average_stroke_counter;
+ mul_v3_v3fl(stroke, ups->average_stroke_accum, fac);
+ }
+ else {
+ copy_v3_v3(stroke, ob->obmat[3]);
+ }
}
/* returns non-zero if any of the face's vertices
@@ -477,19 +512,48 @@ float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level,
/* threshold to move before updating the brush rotation */
#define RAKE_THRESHHOLD 20
-void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, const float mouse_pos[2])
+static void update_brush_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, float rotation)
{
- const float u = 0.5f;
- const float r = RAKE_THRESHHOLD;
+ if (brush->mtex.brush_angle_mode & MTEX_ANGLE_RAKE)
+ ups->brush_rotation = rotation;
+ else
+ ups->brush_rotation = 0.0f;
- float dpos[2];
- sub_v2_v2v2(dpos, ups->last_rake, mouse_pos);
+ if (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE)
+ /* here, translation contains the mouse coordinates. */
+ ups->brush_rotation_sec = rotation;
+ else
+ ups->brush_rotation_sec = 0.0f;
+}
+
+void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, const float mouse_pos[2])
+{
+ if ((brush->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) || (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) {
+ const float u = 0.5f;
+ const float r = RAKE_THRESHHOLD;
+ float rotation;
+
+ float dpos[2];
+ sub_v2_v2v2(dpos, ups->last_rake, mouse_pos);
+
+ if (len_squared_v2(dpos) >= r * r) {
+ rotation = atan2f(dpos[0], dpos[1]);
+
+ interp_v2_v2v2(ups->last_rake, ups->last_rake,
+ mouse_pos, u);
- if (len_squared_v2(dpos) >= r * r) {
- ups->brush_rotation = atan2f(dpos[0], dpos[1]);
+ ups->last_rake_angle = rotation;
- interp_v2_v2v2(ups->last_rake, ups->last_rake,
- mouse_pos, u);
+ update_brush_rake_rotation(ups, brush, rotation);
+ }
+ /* make sure we reset here to the last rotation to avoid accumulating
+ * values in case a random rotation is also added */
+ else {
+ update_brush_rake_rotation(ups, brush, ups->last_rake_angle);
+ }
+ }
+ else {
+ ups->brush_rotation = ups->brush_rotation_sec = 0.0f;
}
}
@@ -644,11 +708,11 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
VirtualModifierData virtualModifierData;
if (mmd || ob->sculpt->bm)
- return 0;
+ return false;
/* non-locked shape keys could be handled in the same way as deformed mesh */
if ((ob->shapeflag & OB_SHAPE_LOCK) == 0 && me->key && ob->shapenr)
- return 1;
+ return true;
md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
@@ -658,11 +722,11 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
if (!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
if (ELEM(md->type, eModifierType_ShapeKey, eModifierType_Multires)) continue;
- if (mti->type == eModifierTypeType_OnlyDeform) return 1;
- else if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) return 1;
+ if (mti->type == eModifierTypeType_OnlyDeform) return true;
+ else if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) return true;
}
- return 0;
+ return false;
}
/**
@@ -740,7 +804,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
BKE_free_sculptsession_deformMats(ss);
- ss->orig_cos = (ss->kb) ? BKE_key_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL);
+ ss->orig_cos = (ss->kb) ? BKE_keyblock_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL);
BKE_crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos);
BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
@@ -755,14 +819,14 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
}
if (ss->kb != NULL && ss->deform_cos == NULL) {
- ss->deform_cos = BKE_key_convert_to_vertcos(ob, ss->kb);
+ ss->deform_cos = BKE_keyblock_convert_to_vertcos(ob, ss->kb);
}
/* if pbvh is deformed, key block is already applied to it */
if (ss->kb) {
bool pbvh_deformd = BKE_pbvh_isDeformed(ss->pbvh);
if (!pbvh_deformd || ss->deform_cos == NULL) {
- float (*vertCos)[3] = BKE_key_convert_to_vertcos(ob, ss->kb);
+ float (*vertCos)[3] = BKE_keyblock_convert_to_vertcos(ob, ss->kb);
if (vertCos) {
if (!pbvh_deformd) {
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 530573d6e38..291efd03a66 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -53,6 +53,7 @@
#include "BLI_utildefines.h"
#include "BLI_kdtree.h"
#include "BLI_rand.h"
+#include "BLI_task.h"
#include "BLI_threads.h"
#include "BLI_linklist.h"
@@ -63,6 +64,7 @@
#include "BKE_boids.h"
#include "BKE_cloth.h"
+#include "BKE_colortools.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_group.h"
@@ -101,9 +103,9 @@ void psys_init_rng(void)
static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx,
ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex);
-static void do_child_modifiers(ParticleSimulationData *sim,
- ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa,
- float *orco, float mat[4][4], ParticleKey *state, float t);
+extern void do_child_modifiers(ParticleSimulationData *sim,
+ ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3],
+ ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t);
/* few helpers for countall etc. */
int count_particles(ParticleSystem *psys)
@@ -137,7 +139,7 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur)
#define PATH_CACHE_BUF_SIZE 1024
-static ParticleCacheKey **psys_alloc_path_cache_buffers(ListBase *bufs, int tot, int steps)
+static ParticleCacheKey **psys_alloc_path_cache_buffers(ListBase *bufs, int tot, int totkeys)
{
LinkData *buf;
ParticleCacheKey **cache;
@@ -150,10 +152,10 @@ static ParticleCacheKey **psys_alloc_path_cache_buffers(ListBase *bufs, int tot,
while (totkey < tot) {
totbufkey = MIN2(tot - totkey, PATH_CACHE_BUF_SIZE);
buf = MEM_callocN(sizeof(LinkData), "PathCacheLinkData");
- buf->data = MEM_callocN(sizeof(ParticleCacheKey) * totbufkey * steps, "ParticleCacheKey");
+ buf->data = MEM_callocN(sizeof(ParticleCacheKey) * totbufkey * totkeys, "ParticleCacheKey");
for (i = 0; i < totbufkey; i++)
- cache[totkey + i] = ((ParticleCacheKey *)buf->data) + i * steps;
+ cache[totkey + i] = ((ParticleCacheKey *)buf->data) + i * totkeys;
totkey += totbufkey;
BLI_addtail(bufs, buf);
@@ -270,11 +272,11 @@ void psys_enable_all(Object *ob)
for (; psys; psys = psys->next)
psys->flag &= ~PSYS_DISABLED;
}
-int psys_in_edit_mode(Scene *scene, ParticleSystem *psys)
+bool psys_in_edit_mode(Scene *scene, ParticleSystem *psys)
{
return (scene->basact && (scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys == psys_get_current((scene->basact)->object) && (psys->edit || psys->pointcache->edit) && !psys->renderdata);
}
-int psys_check_enabled(Object *ob, ParticleSystem *psys)
+bool psys_check_enabled(Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd;
@@ -292,7 +294,7 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
return 1;
}
-int psys_check_edited(ParticleSystem *psys)
+bool psys_check_edited(ParticleSystem *psys)
{
if (psys->part && psys->part->type == PART_HAIR)
return (psys->flag & PSYS_EDITED || (psys->edit && psys->edit->edited));
@@ -372,6 +374,12 @@ void BKE_particlesettings_free(ParticleSettings *part)
MTex *mtex;
int a;
BKE_free_animdata(&part->id);
+
+ if (part->clumpcurve)
+ curvemapping_free(part->clumpcurve);
+ if (part->roughcurve)
+ curvemapping_free(part->roughcurve);
+
free_partdeflect(part->pd);
free_partdeflect(part->pd2);
@@ -406,8 +414,7 @@ void free_hair(Object *UNUSED(ob), ParticleSystem *psys, int dynamics)
if (psys->clmd) {
if (dynamics) {
BKE_ptcache_free_list(&psys->ptcaches);
- psys->clmd->point_cache = psys->pointcache = NULL;
- BLI_listbase_clear(&psys->clmd->ptcaches);
+ psys->pointcache = NULL;
modifier_free((ModifierData *)psys->clmd);
@@ -591,89 +598,6 @@ void psys_free(Object *ob, ParticleSystem *psys)
* rendering, to make different render settings possible without
* removing the previous data. this should be solved properly once */
-typedef struct ParticleRenderElem {
- int curchild, totchild, reduce;
- float lambda, t, scalemin, scalemax;
-} ParticleRenderElem;
-
-typedef struct ParticleRenderData {
- ChildParticle *child;
- ParticleCacheKey **pathcache;
- ParticleCacheKey **childcache;
- ListBase pathcachebufs, childcachebufs;
- int totchild, totcached, totchildcache;
- DerivedMesh *dm;
- int totdmvert, totdmedge, totdmface;
-
- float mat[4][4];
- float viewmat[4][4], winmat[4][4];
- int winx, winy;
-
- int do_simplify;
- int timeoffset;
- ParticleRenderElem *elems;
-
- /* ORIGINDEX */
- const int *index_mf_to_mpoly;
- const int *index_mp_to_orig;
-} ParticleRenderData;
-
-static float psys_render_viewport_falloff(double rate, float dist, float width)
-{
- return pow(rate, dist / width);
-}
-
-static float psys_render_projected_area(ParticleSystem *psys, const float center[3], float area, double vprate, float *viewport)
-{
- ParticleRenderData *data = psys->renderdata;
- float co[4], view[3], ortho1[3], ortho2[3], w, dx, dy, radius;
-
- /* transform to view space */
- copy_v3_v3(co, center);
- co[3] = 1.0f;
- mul_m4_v4(data->viewmat, co);
-
- /* compute two vectors orthogonal to view vector */
- normalize_v3_v3(view, co);
- ortho_basis_v3v3_v3(ortho1, ortho2, view);
-
- /* compute on screen minification */
- w = co[2] * data->winmat[2][3] + data->winmat[3][3];
- dx = data->winx * ortho2[0] * data->winmat[0][0];
- dy = data->winy * ortho2[1] * data->winmat[1][1];
- w = sqrtf(dx * dx + dy * dy) / w;
-
- /* w squared because we are working with area */
- area = area * w * w;
-
- /* viewport of the screen test */
-
- /* project point on screen */
- mul_m4_v4(data->winmat, co);
- if (co[3] != 0.0f) {
- co[0] = 0.5f * data->winx * (1.0f + co[0] / co[3]);
- co[1] = 0.5f * data->winy * (1.0f + co[1] / co[3]);
- }
-
- /* screen space radius */
- radius = sqrtf(area / (float)M_PI);
-
- /* make smaller using fallof once over screen edge */
- *viewport = 1.0f;
-
- if (co[0] + radius < 0.0f)
- *viewport *= psys_render_viewport_falloff(vprate, -(co[0] + radius), data->winx);
- else if (co[0] - radius > data->winx)
- *viewport *= psys_render_viewport_falloff(vprate, (co[0] - radius) - data->winx, data->winx);
-
- if (co[1] + radius < 0.0f)
- *viewport *= psys_render_viewport_falloff(vprate, -(co[1] + radius), data->winy);
- else if (co[1] - radius > data->winy)
- *viewport *= psys_render_viewport_falloff(vprate, (co[1] - radius) - data->winy, data->winy);
-
- return area;
-}
-
void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset)
{
ParticleRenderData *data;
@@ -788,191 +712,6 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
}
}
-/* BMESH_TODO, for orig face data, we need to use MPoly */
-
-int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
-{
- DerivedMesh *dm = ctx->dm;
- Mesh *me = (Mesh *)(ctx->sim.ob->data);
- MFace *mf, *mface;
- MVert *mvert;
- ParticleRenderData *data;
- ParticleRenderElem *elems, *elem;
- ParticleSettings *part = ctx->sim.psys->part;
- float *facearea, (*facecenter)[3], size[3], fac, powrate, scaleclamp;
- float co1[3], co2[3], co3[3], co4[3], lambda, arearatio, t, area, viewport;
- double vprate;
- int *facetotvert;
- int a, b, totorigface, totface, newtot, skipped;
-
- /* double lookup */
- const int *index_mf_to_mpoly;
- const int *index_mp_to_orig;
-
- if (part->ren_as != PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
- return tot;
- if (!ctx->sim.psys->renderdata)
- return tot;
-
- data = ctx->sim.psys->renderdata;
- if (data->timeoffset)
- return 0;
- if (!(part->simplify_flag & PART_SIMPLIFY_ENABLE))
- return tot;
-
- mvert = dm->getVertArray(dm);
- mface = dm->getTessFaceArray(dm);
- totface = dm->getNumTessFaces(dm);
- totorigface = me->totpoly;
-
- if (totface == 0 || totorigface == 0)
- return tot;
-
- index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
- index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if (index_mf_to_mpoly == NULL) {
- index_mp_to_orig = NULL;
- }
-
- facearea = MEM_callocN(sizeof(float) * totorigface, "SimplifyFaceArea");
- facecenter = MEM_callocN(sizeof(float[3]) * totorigface, "SimplifyFaceCenter");
- facetotvert = MEM_callocN(sizeof(int) * totorigface, "SimplifyFaceArea");
- elems = MEM_callocN(sizeof(ParticleRenderElem) * totorigface, "SimplifyFaceElem");
-
- if (data->elems)
- MEM_freeN(data->elems);
-
- data->do_simplify = true;
- data->elems = elems;
- data->index_mf_to_mpoly = index_mf_to_mpoly;
- data->index_mp_to_orig = index_mp_to_orig;
-
- /* compute number of children per original face */
- for (a = 0; a < tot; a++) {
- b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, ctx->index[a]) : ctx->index[a];
- if (b != ORIGINDEX_NONE) {
- elems[b].totchild++;
- }
- }
-
- /* compute areas and centers of original faces */
- for (mf = mface, a = 0; a < totface; a++, mf++) {
- b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
-
- if (b != ORIGINDEX_NONE) {
- copy_v3_v3(co1, mvert[mf->v1].co);
- copy_v3_v3(co2, mvert[mf->v2].co);
- copy_v3_v3(co3, mvert[mf->v3].co);
-
- add_v3_v3(facecenter[b], co1);
- add_v3_v3(facecenter[b], co2);
- add_v3_v3(facecenter[b], co3);
-
- if (mf->v4) {
- copy_v3_v3(co4, mvert[mf->v4].co);
- add_v3_v3(facecenter[b], co4);
- facearea[b] += area_quad_v3(co1, co2, co3, co4);
- facetotvert[b] += 4;
- }
- else {
- facearea[b] += area_tri_v3(co1, co2, co3);
- facetotvert[b] += 3;
- }
- }
- }
-
- for (a = 0; a < totorigface; a++)
- if (facetotvert[a] > 0)
- mul_v3_fl(facecenter[a], 1.0f / facetotvert[a]);
-
- /* for conversion from BU area / pixel area to reference screen size */
- BKE_mesh_texspace_get(me, 0, 0, size);
- fac = ((size[0] + size[1] + size[2]) / 3.0f) / part->simplify_refsize;
- fac = fac * fac;
-
- powrate = log(0.5f) / log(part->simplify_rate * 0.5f);
- if (part->simplify_flag & PART_SIMPLIFY_VIEWPORT)
- vprate = pow(1.0f - part->simplify_viewport, 5.0);
- else
- vprate = 1.0;
-
- /* set simplification parameters per original face */
- for (a = 0, elem = elems; a < totorigface; a++, elem++) {
- area = psys_render_projected_area(ctx->sim.psys, facecenter[a], facearea[a], vprate, &viewport);
- arearatio = fac * area / facearea[a];
-
- if ((arearatio < 1.0f || viewport < 1.0f) && elem->totchild) {
- /* lambda is percentage of elements to keep */
- lambda = (arearatio < 1.0f) ? powf(arearatio, powrate) : 1.0f;
- lambda *= viewport;
-
- lambda = MAX2(lambda, 1.0f / elem->totchild);
-
- /* compute transition region */
- t = part->simplify_transition;
- elem->t = (lambda - t < 0.0f) ? lambda : (lambda + t > 1.0f) ? 1.0f - lambda : t;
- elem->reduce = 1;
-
- /* scale at end and beginning of the transition region */
- elem->scalemax = (lambda + t < 1.0f) ? 1.0f / lambda : 1.0f / (1.0f - elem->t * elem->t / t);
- elem->scalemin = (lambda + t < 1.0f) ? 0.0f : elem->scalemax * (1.0f - elem->t / t);
-
- elem->scalemin = sqrtf(elem->scalemin);
- elem->scalemax = sqrtf(elem->scalemax);
-
- /* clamp scaling */
- scaleclamp = (float)min_ii(elem->totchild, 10);
- elem->scalemin = MIN2(scaleclamp, elem->scalemin);
- elem->scalemax = MIN2(scaleclamp, elem->scalemax);
-
- /* extend lambda to include transition */
- lambda = lambda + elem->t;
- if (lambda > 1.0f)
- lambda = 1.0f;
- }
- else {
- lambda = arearatio;
-
- elem->scalemax = 1.0f; //sqrt(lambda);
- elem->scalemin = 1.0f; //sqrt(lambda);
- elem->reduce = 0;
- }
-
- elem->lambda = lambda;
- elem->scalemin = sqrtf(elem->scalemin);
- elem->scalemax = sqrtf(elem->scalemax);
- elem->curchild = 0;
- }
-
- MEM_freeN(facearea);
- MEM_freeN(facecenter);
- MEM_freeN(facetotvert);
-
- /* move indices and set random number skipping */
- ctx->skip = MEM_callocN(sizeof(int) * tot, "SimplificationSkip");
-
- skipped = 0;
- for (a = 0, newtot = 0; a < tot; a++) {
- b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, ctx->index[a]) : ctx->index[a];
-
- if (b != ORIGINDEX_NONE) {
- if (elems[b].curchild++ < ceil(elems[b].lambda * elems[b].totchild)) {
- ctx->index[newtot] = ctx->index[a];
- ctx->skip[newtot] = skipped;
- skipped = 0;
- newtot++;
- }
- else skipped++;
- }
- else skipped++;
- }
-
- for (a = 0, elem = elems; a < totorigface; a++, elem++)
- elem->curchild = 0;
-
- return newtot;
-}
-
bool psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float *params)
{
ParticleRenderData *data;
@@ -981,14 +720,14 @@ bool psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float
int b;
if (!(psys->renderdata && (psys->part->simplify_flag & PART_SIMPLIFY_ENABLE)))
- return 0;
+ return false;
data = psys->renderdata;
if (!data->do_simplify)
- return 0;
+ return false;
b = (data->index_mf_to_mpoly) ? DM_origindex_mface_mpoly(data->index_mf_to_mpoly, data->index_mp_to_orig, cpa->num) : cpa->num;
if (b == ORIGINDEX_NONE) {
- return 0;
+ return false;
}
elem = &data->elems[b];
@@ -1043,7 +782,7 @@ static float interpolate_particle_value(float v1, float v2, float v3, float v4,
return value;
}
-void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, int velocity)
+void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, bool velocity)
{
float t[4];
@@ -1073,7 +812,6 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic
}
-
typedef struct ParticleInterpolationData {
HairKey *hkey[2];
@@ -1400,9 +1138,9 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach
ParticleCacheKey *cur = first;
/* scale the requested time to fit the entire path even if the path is cut early */
- t *= (first + first->steps)->time;
+ t *= (first + first->segments)->time;
- while (i < first->steps && cur->time < t)
+ while (i < first->segments && cur->time < t)
cur++;
if (cur->time == t)
@@ -1569,12 +1307,13 @@ void psys_interpolate_uvs(const MTFace *tface, int quad, const float w[4], float
void psys_interpolate_mcol(const MCol *mcol, int quad, const float w[4], MCol *mc)
{
- char *cp, *cp1, *cp2, *cp3, *cp4;
+ const char *cp1, *cp2, *cp3, *cp4;
+ char *cp;
cp = (char *)mc;
- cp1 = (char *)&mcol[0];
- cp2 = (char *)&mcol[1];
- cp3 = (char *)&mcol[2];
+ cp1 = (const char *)&mcol[0];
+ cp2 = (const char *)&mcol[1];
+ cp3 = (const char *)&mcol[2];
if (quad) {
cp4 = (char *)&mcol[3];
@@ -1906,6 +1645,42 @@ static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index),
/************************************************/
/* Particles on emitter */
/************************************************/
+
+CustomDataMask psys_emitter_customdata_mask(ParticleSystem *psys)
+{
+ CustomDataMask dataMask = 0;
+ MTex *mtex;
+ int i;
+
+ if (!psys->part)
+ return 0;
+
+ for (i = 0; i < MAX_MTEX; i++) {
+ mtex = psys->part->mtex[i];
+ if (mtex && mtex->mapto && (mtex->texco & TEXCO_UV))
+ dataMask |= CD_MASK_MTFACE;
+ }
+
+ if (psys->part->tanfac != 0.0f)
+ dataMask |= CD_MASK_MTFACE;
+
+ /* ask for vertexgroups if we need them */
+ for (i = 0; i < PSYS_TOT_VG; i++) {
+ if (psys->vgroup[i]) {
+ dataMask |= CD_MASK_MDEFORMVERT;
+ break;
+ }
+ }
+
+ /* particles only need this if they are after a non deform modifier, and
+ * the modifier stack will only create them in that case. */
+ dataMask |= CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORIGINDEX;
+
+ dataMask |= CD_MASK_ORCO;
+
+ return dataMask;
+}
+
void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache,
float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
float orco[3], float ornor[3])
@@ -1930,202 +1705,11 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in
/* Path Cache */
/************************************************/
-static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat, short type, short axis, float obmat[4][4], int smooth_start)
-{
- float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f};
- float t, dt = 1.f, result[3];
-
- if (par == NULL || type == PART_KINK_NO)
- return;
-
- CLAMP(time, 0.f, 1.f);
-
- if (shape != 0.0f && type != PART_KINK_BRAID) {
- if (shape < 0.0f)
- time = (float)pow(time, 1.f + shape);
- else
- time = (float)pow(time, 1.f / (1.f - shape));
- }
-
- t = time * freq * (float)M_PI;
-
- if (smooth_start) {
- dt = fabsf(t);
- /* smooth the beginning of kink */
- CLAMP(dt, 0.f, (float)M_PI);
- dt = sinf(dt / 2.f);
- }
-
- if (type != PART_KINK_RADIAL) {
- float temp[3];
-
- kink[axis] = 1.f;
-
- if (obmat)
- mul_mat3_m4_v3(obmat, kink);
-
- if (par_rot)
- mul_qt_v3(par_rot, kink);
-
- /* make sure kink is normal to strand */
- project_v3_v3v3(temp, kink, par->vel);
- sub_v3_v3(kink, temp);
- normalize_v3(kink);
- }
-
- copy_v3_v3(result, state->co);
- sub_v3_v3v3(par_vec, par->co, state->co);
-
- switch (type) {
- case PART_KINK_CURL:
- {
- negate_v3(par_vec);
-
- if (flat > 0.f) {
- float proj[3];
- project_v3_v3v3(proj, par_vec, par->vel);
- madd_v3_v3fl(par_vec, proj, -flat);
-
- project_v3_v3v3(proj, par_vec, kink);
- madd_v3_v3fl(par_vec, proj, -flat);
- }
-
- axis_angle_to_quat(q1, kink, (float)M_PI / 2.f);
-
- mul_qt_v3(q1, par_vec);
-
- madd_v3_v3fl(par_vec, kink, amplitude);
-
- /* rotate kink vector around strand tangent */
- if (t != 0.f) {
- axis_angle_to_quat(q1, par->vel, t);
- mul_qt_v3(q1, par_vec);
- }
-
- add_v3_v3v3(result, par->co, par_vec);
- break;
- }
- case PART_KINK_RADIAL:
- {
- if (flat > 0.f) {
- float proj[3];
- /* flatten along strand */
- project_v3_v3v3(proj, par_vec, par->vel);
- madd_v3_v3fl(result, proj, flat);
- }
-
- madd_v3_v3fl(result, par_vec, -amplitude * sinf(t));
- break;
- }
- case PART_KINK_WAVE:
- {
- madd_v3_v3fl(result, kink, amplitude * sinf(t));
-
- if (flat > 0.f) {
- float proj[3];
- /* flatten along wave */
- project_v3_v3v3(proj, par_vec, kink);
- madd_v3_v3fl(result, proj, flat);
-
- /* flatten along strand */
- project_v3_v3v3(proj, par_vec, par->vel);
- madd_v3_v3fl(result, proj, flat);
- }
- break;
- }
- case PART_KINK_BRAID:
- {
- float y_vec[3] = {0.f, 1.f, 0.f};
- float z_vec[3] = {0.f, 0.f, 1.f};
- float vec_one[3], state_co[3];
- float inp_y, inp_z, length;
-
- if (par_rot) {
- mul_qt_v3(par_rot, y_vec);
- mul_qt_v3(par_rot, z_vec);
- }
-
- negate_v3(par_vec);
- normalize_v3_v3(vec_one, par_vec);
-
- inp_y = dot_v3v3(y_vec, vec_one);
- inp_z = dot_v3v3(z_vec, vec_one);
-
- if (inp_y > 0.5f) {
- copy_v3_v3(state_co, y_vec);
-
- mul_v3_fl(y_vec, amplitude * cosf(t));
- mul_v3_fl(z_vec, amplitude / 2.f * sinf(2.f * t));
- }
- else if (inp_z > 0.0f) {
- mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.f));
- madd_v3_v3fl(state_co, y_vec, -0.5f);
-
- mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.f));
- mul_v3_fl(z_vec, amplitude / 2.f * cosf(2.f * t + (float)M_PI / 6.f));
- }
- else {
- mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.f));
- madd_v3_v3fl(state_co, y_vec, -0.5f);
-
- mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.f));
- mul_v3_fl(z_vec, amplitude / 2.f * -sinf(2.f * t + (float)M_PI / 3.f));
- }
-
- mul_v3_fl(state_co, amplitude);
- add_v3_v3(state_co, par->co);
- sub_v3_v3v3(par_vec, state->co, state_co);
-
- length = normalize_v3(par_vec);
- mul_v3_fl(par_vec, MIN2(length, amplitude / 2.f));
-
- add_v3_v3v3(state_co, par->co, y_vec);
- add_v3_v3(state_co, z_vec);
- add_v3_v3(state_co, par_vec);
-
- shape = 2.f * (float)M_PI * (1.f + shape);
-
- if (t < shape) {
- shape = t / shape;
- shape = (float)sqrt((double)shape);
- interp_v3_v3v3(result, result, state_co, shape);
- }
- else {
- copy_v3_v3(result, state_co);
- }
- break;
- }
- }
-
- /* blend the start of the kink */
- if (dt < 1.f)
- interp_v3_v3v3(state->co, state->co, result, dt);
- else
- copy_v3_v3(state->co, result);
-}
-
-static float do_clump(ParticleKey *state, ParticleKey *par, float time, float clumpfac, float clumppow, float pa_clump)
-{
- float clump = 0.f;
-
- if (par && clumpfac != 0.0f) {
- float cpow;
-
- if (clumppow < 0.0f)
- cpow = 1.0f + clumppow;
- else
- cpow = 1.0f + 9.0f * clumppow;
-
- if (clumpfac < 0.0f) /* clump roots instead of tips */
- clump = -clumpfac * pa_clump * (float)pow(1.0 - (double)time, (double)cpow);
- else
- clump = clumpfac * pa_clump * (float)pow((double)time, (double)cpow);
-
- interp_v3_v3v3(state->co, state->co, par->co, clump);
- }
+extern void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat,
+ short type, short axis, float obmat[4][4], int smooth_start);
+extern float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
+ bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve);
- return clump;
-}
void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
{
EffectedPoint point;
@@ -2166,12 +1750,14 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
}
}
}
-int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
+
+int do_guides(ParticleSettings *part, ListBase *effectors, ParticleKey *state, int index, float time)
{
+ CurveMapping *clumpcurve = (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) ? part->clumpcurve : NULL;
+ CurveMapping *roughcurve = (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) ? part->roughcurve : NULL;
EffectorCache *eff;
PartDeflect *pd;
Curve *cu;
- ParticleKey key, par;
GuideEffectorData *data;
float effect[3] = {0.0f, 0.0f, 0.0f}, veffect[3] = {0.0f, 0.0f, 0.0f};
@@ -2180,78 +1766,92 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
float vec_to_point[3];
if (effectors) for (eff = effectors->first; eff; eff = eff->next) {
- pd = eff->pd;
-
- if (pd->forcefield != PFIELD_GUIDE)
- continue;
-
- data = eff->guide_data + index;
-
- if (data->strength <= 0.0f)
- continue;
-
- guidetime = time / (1.0f - pd->free_end);
-
- if (guidetime > 1.0f)
- continue;
-
- cu = (Curve *)eff->ob->data;
-
- if (pd->flag & PFIELD_GUIDE_PATH_ADD) {
- if (where_on_path(eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius, &weight) == 0)
- return 0;
- }
- else {
- if (where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius, &weight) == 0)
- return 0;
- }
-
- mul_m4_v3(eff->ob->obmat, guidevec);
- mul_mat3_m4_v3(eff->ob->obmat, guidedir);
-
- normalize_v3(guidedir);
-
- copy_v3_v3(vec_to_point, data->vec_to_point);
-
- if (guidetime != 0.0f) {
- /* curve direction */
- cross_v3_v3v3(temp, eff->guide_dir, guidedir);
- angle = dot_v3v3(eff->guide_dir, guidedir) / (len_v3(eff->guide_dir));
- angle = saacos(angle);
- axis_angle_to_quat(rot2, temp, angle);
- mul_qt_v3(rot2, vec_to_point);
-
- /* curve tilt */
- axis_angle_to_quat(rot2, guidedir, guidevec[3] - eff->guide_loc[3]);
- mul_qt_v3(rot2, vec_to_point);
- }
-
- /* curve taper */
- if (cu->taperobj)
- mul_v3_fl(vec_to_point, BKE_displist_calc_taper(eff->scene, cu->taperobj, (int)(data->strength * guidetime * 100.0f), 100));
-
- else { /* curve size*/
- if (cu->flag & CU_PATH_RADIUS) {
- mul_v3_fl(vec_to_point, radius);
- }
+ pd = eff->pd;
+
+ if (pd->forcefield != PFIELD_GUIDE)
+ continue;
+
+ data = eff->guide_data + index;
+
+ if (data->strength <= 0.0f)
+ continue;
+
+ guidetime = time / (1.0f - pd->free_end);
+
+ if (guidetime > 1.0f)
+ continue;
+
+ cu = (Curve *)eff->ob->data;
+
+ if (pd->flag & PFIELD_GUIDE_PATH_ADD) {
+ if (where_on_path(eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius, &weight) == 0)
+ return 0;
+ }
+ else {
+ if (where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius, &weight) == 0)
+ return 0;
+ }
+
+ mul_m4_v3(eff->ob->obmat, guidevec);
+ mul_mat3_m4_v3(eff->ob->obmat, guidedir);
+
+ normalize_v3(guidedir);
+
+ copy_v3_v3(vec_to_point, data->vec_to_point);
+
+ if (guidetime != 0.0f) {
+ /* curve direction */
+ cross_v3_v3v3(temp, eff->guide_dir, guidedir);
+ angle = dot_v3v3(eff->guide_dir, guidedir) / (len_v3(eff->guide_dir));
+ angle = saacos(angle);
+ axis_angle_to_quat(rot2, temp, angle);
+ mul_qt_v3(rot2, vec_to_point);
+
+ /* curve tilt */
+ axis_angle_to_quat(rot2, guidedir, guidevec[3] - eff->guide_loc[3]);
+ mul_qt_v3(rot2, vec_to_point);
+ }
+
+ /* curve taper */
+ if (cu->taperobj)
+ mul_v3_fl(vec_to_point, BKE_displist_calc_taper(eff->scene, cu->taperobj, (int)(data->strength * guidetime * 100.0f), 100));
+
+ else { /* curve size*/
+ if (cu->flag & CU_PATH_RADIUS) {
+ mul_v3_fl(vec_to_point, radius);
}
- par.co[0] = par.co[1] = par.co[2] = 0.0f;
+ }
+
+ if (clumpcurve)
+ curvemapping_changed_all(clumpcurve);
+ if (roughcurve)
+ curvemapping_changed_all(roughcurve);
+
+ {
+ ParticleKey key;
+ float par_co[3] = {0.0f, 0.0f, 0.0f};
+ float par_vel[3] = {0.0f, 0.0f, 0.0f};
+ float par_rot[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ float orco_offset[3] = {0.0f, 0.0f, 0.0f};
+
copy_v3_v3(key.co, vec_to_point);
- do_kink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, 0.f, pd->kink, pd->kink_axis, 0, 0);
- do_clump(&key, &par, guidetime, pd->clump_fac, pd->clump_pow, 1.0f);
+ do_kink(&key, par_co, par_vel, par_rot, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, 0.f, pd->kink, pd->kink_axis, 0, 0);
+ do_clump(&key, par_co, guidetime, orco_offset, pd->clump_fac, pd->clump_pow, 1.0f,
+ part->child_flag & PART_CHILD_USE_CLUMP_NOISE, part->clump_noise_size, clumpcurve);
copy_v3_v3(vec_to_point, key.co);
-
- add_v3_v3(vec_to_point, guidevec);
-
- //sub_v3_v3v3(pa_loc, pa_loc, pa_zero);
- madd_v3_v3fl(effect, vec_to_point, data->strength);
- madd_v3_v3fl(veffect, guidedir, data->strength);
- totstrength += data->strength;
-
- if (pd->flag & PFIELD_GUIDE_PATH_WEIGHT)
- totstrength *= weight;
}
-
+
+ add_v3_v3(vec_to_point, guidevec);
+
+ //sub_v3_v3v3(pa_loc, pa_loc, pa_zero);
+ madd_v3_v3fl(effect, vec_to_point, data->strength);
+ madd_v3_v3fl(veffect, guidedir, data->strength);
+ totstrength += data->strength;
+
+ if (pd->flag & PFIELD_GUIDE_PATH_WEIGHT)
+ totstrength *= weight;
+ }
+
if (totstrength != 0.0f) {
if (totstrength > 1.0f)
mul_v3_fl(effect, 1.0f / totstrength);
@@ -2266,41 +1866,7 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
}
return 0;
}
-static void do_rough(float *loc, float mat[4][4], float t, float fac, float size, float thres, ParticleKey *state)
-{
- float rough[3];
- float rco[3];
-
- if (thres != 0.0f) {
- if (fabsf((float)(-1.5f + loc[0] + loc[1] + loc[2])) < 1.5f * thres) {
- return;
- }
- }
-
- copy_v3_v3(rco, loc);
- mul_v3_fl(rco, t);
- rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
- rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
- rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
- madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
- madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
- madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
-}
-static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float shape, ParticleKey *state)
-{
- float rough[2];
- float roughfac;
-
- roughfac = fac * (float)pow((double)t, shape);
- copy_v2_v2(rough, loc);
- rough[0] = -1.0f + 2.0f * rough[0];
- rough[1] = -1.0f + 2.0f * rough[1];
- mul_v2_fl(rough, roughfac);
-
- madd_v3_v3fl(state->co, mat[0], rough[0]);
- madd_v3_v3fl(state->co, mat[1], rough[1]);
-}
static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheKey *ca, int k, int steps, float *UNUSED(rootco), float effector, float UNUSED(dfra), float UNUSED(cfra), float *length, float *vec)
{
float force[3] = {0.0f, 0.0f, 0.0f};
@@ -2332,20 +1898,6 @@ static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheK
if (k < steps)
*length = len_v3(vec);
}
-static int check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *state, float max_length, float *cur_length, float length, float *dvec)
-{
- if (*cur_length + length > max_length) {
- mul_v3_fl(dvec, (max_length - *cur_length) / length);
- add_v3_v3v3(state->co, (state - 1)->co, dvec);
- keys->steps = k;
- /* something over the maximum step value */
- return k = 100000;
- }
- else {
- *cur_length += length;
- return k;
- }
-}
static void offset_child(ChildParticle *cpa, ParticleKey *par, float *par_rot, ParticleKey *child, float flat, float radius)
{
copy_v3_v3(child->co, cpa->fuv);
@@ -2424,49 +1976,15 @@ void psys_find_parents(ParticleSimulationData *sim)
BLI_kdtree_free(tree);
}
-static void get_strand_normal(Material *ma, const float surfnor[3], float surfdist, float nor[3])
-{
- float cross[3], nstrand[3], vnor[3], blend;
-
- if (!((ma->mode & MA_STR_SURFDIFF) || (ma->strand_surfnor > 0.0f)))
- return;
-
- if (ma->mode & MA_STR_SURFDIFF) {
- cross_v3_v3v3(cross, surfnor, nor);
- cross_v3_v3v3(nstrand, nor, cross);
-
- blend = dot_v3v3(nstrand, surfnor);
- CLAMP(blend, 0.0f, 1.0f);
-
- interp_v3_v3v3(vnor, nstrand, surfnor, blend);
- normalize_v3(vnor);
- }
- else {
- copy_v3_v3(vnor, nor);
- }
-
- if (ma->strand_surfnor > 0.0f) {
- if (ma->strand_surfnor > surfdist) {
- blend = (ma->strand_surfnor - surfdist) / ma->strand_surfnor;
- interp_v3_v3v3(vnor, vnor, surfnor, blend);
- normalize_v3(vnor);
- }
- }
-
- copy_v3_v3(nor, vnor);
-}
-
-static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, int editupdate)
+static bool psys_thread_context_init_path(ParticleThreadContext *ctx, ParticleSimulationData *sim, Scene *scene, float cfra, int editupdate)
{
- ParticleThreadContext *ctx = threads[0].ctx;
-/* Object *ob = ctx->sim.ob; */
- ParticleSystem *psys = ctx->sim.psys;
+ ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
-/* ParticleEditSettings *pset = &scene->toolsettings->particle; */
int totparent = 0, between = 0;
- int steps = (int)pow(2.0, (double)part->draw_step);
+ int segments = 1 << part->draw_step;
int totchild = psys->totchild;
- int i, seed, totthread = threads[0].tot;
+
+ psys_thread_context_init(ctx, sim);
/*---start figuring out what is actually wanted---*/
if (psys_in_edit_mode(scene, psys)) {
@@ -2475,7 +1993,7 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c
if (psys->renderdata == 0 && (psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0)
totchild = 0;
- steps = (int)pow(2.0, (double)pset->draw_step);
+ segments = 1 << pset->draw_step;
}
if (totchild && part->childtype == PART_CHILD_FACES) {
@@ -2489,28 +2007,22 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c
}
if (psys->renderdata)
- steps = (int)pow(2.0, (double)part->ren_step);
+ segments = 1 << part->ren_step;
else {
totchild = (int)((float)totchild * (float)part->disp / 100.0f);
totparent = MIN2(totparent, totchild);
}
- if (totchild == 0) return 0;
-
- /* init random number generator */
- seed = 31415926 + ctx->sim.psys->seed;
-
- if (ctx->editupdate || totchild < 10000)
- totthread = 1;
-
- for (i = 0; i < totthread; i++) {
- threads[i].rng_path = BLI_rng_new(seed);
- threads[i].tot = totthread;
- }
+ if (totchild == 0)
+ return false;
/* fill context values */
ctx->between = between;
- ctx->steps = steps;
+ ctx->segments = segments;
+ if (ELEM(part->kink, PART_KINK_SPIRAL))
+ ctx->extra_segments = max_ii(part->kink_extra_steps, 1);
+ else
+ ctx->extra_segments = 0;
ctx->totchild = totchild;
ctx->totparent = totparent;
ctx->parent_pass = 0;
@@ -2529,31 +2041,36 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c
if (psys->part->flag & PART_CHILD_EFFECT)
ctx->vg_effector = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_EFFECTOR);
- /* set correct ipo timing */
-#if 0 // XXX old animation system
- if (part->flag & PART_ABS_TIME && part->ipo) {
- calc_ipo(part->ipo, cfra);
- execute_ipo((ID *)part, part->ipo);
- }
-#endif // XXX old animation system
+ /* prepare curvemapping tables */
+ if ((part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && part->clumpcurve)
+ curvemapping_changed_all(part->clumpcurve);
+ if ((part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && part->roughcurve)
+ curvemapping_changed_all(part->roughcurve);
- return 1;
+ return true;
+}
+
+static void psys_task_init_path(ParticleTask *task, ParticleSimulationData *sim)
+{
+ /* init random number generator */
+ int seed = 31415926 + sim->psys->seed;
+
+ task->rng_path = BLI_rng_new(seed);
}
/* note: this function must be thread safe, except for branching! */
-static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *child_keys, int i)
+static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cpa, ParticleCacheKey *child_keys, int i)
{
- ParticleThreadContext *ctx = thread->ctx;
+ ParticleThreadContext *ctx = task->ctx;
Object *ob = ctx->sim.ob;
ParticleSystem *psys = ctx->sim.psys;
ParticleSettings *part = psys->part;
ParticleCacheKey **cache = psys->childcache;
- ParticleCacheKey **pcache = psys_in_edit_mode(ctx->sim.scene, psys) ? psys->edit->pathcache : psys->pathcache;
- ParticleCacheKey *child, *par = NULL, *key[4];
+ ParticleCacheKey **pcache = psys_in_edit_mode(ctx->sim.scene, psys) && psys->edit ? psys->edit->pathcache : psys->pathcache;
+ ParticleCacheKey *child, *key[4];
ParticleTexture ptex;
float *cpa_fuv = 0, *par_rot = 0, rot[4];
- float orco[3], ornor[3], hairmat[4][4], t, dvec[3], off1[4][3], off2[4][3];
- float length, max_length = 1.0f, cur_length = 0.0f;
+ float orco[3], ornor[3], hairmat[4][4], dvec[3], off1[4][3], off2[4][3];
float eff_length, eff_vec[3], weight[4];
int k, cpa_num;
short cpa_from;
@@ -2585,7 +2102,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
if (!needupdate)
return;
else
- memset(child_keys, 0, sizeof(*child_keys) * (ctx->steps + 1));
+ memset(child_keys, 0, sizeof(*child_keys) * (ctx->segments + 1));
}
/* get parent paths */
@@ -2608,14 +2125,14 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
if (part->flag & PART_CHILD_LONG_HAIR) {
/* For long hair use tip distance/root distance as parting factor instead of root to tip angle. */
float d1 = len_v3v3(key[0]->co, key[w]->co);
- float d2 = len_v3v3((key[0] + key[0]->steps - 1)->co, (key[w] + key[w]->steps - 1)->co);
+ float d2 = len_v3v3((key[0] + key[0]->segments - 1)->co, (key[w] + key[w]->segments - 1)->co);
d = d1 > 0.f ? d2 / d1 - 1.f : 10000.f;
}
else {
float v1[3], v2[3];
- sub_v3_v3v3(v1, (key[0] + key[0]->steps - 1)->co, key[0]->co);
- sub_v3_v3v3(v2, (key[w] + key[w]->steps - 1)->co, key[w]->co);
+ sub_v3_v3v3(v1, (key[0] + key[0]->segments - 1)->co, key[0]->co);
+ sub_v3_v3v3(v2, (key[w] + key[w]->segments - 1)->co, key[w]->co);
normalize_v3(v1);
normalize_v3(v2);
@@ -2663,7 +2180,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
if (!(psys->edit->points[cpa->parent].flag & PEP_EDIT_RECALC))
return;
- memset(child_keys, 0, sizeof(*child_keys) * (ctx->steps + 1));
+ memset(child_keys, 0, sizeof(*child_keys) * (ctx->segments + 1));
}
/* get the parent path */
@@ -2682,18 +2199,18 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
psys_mat_hair_to_global(ob, ctx->sim.psmd->dm, psys->part->from, pa, hairmat);
}
- child_keys->steps = ctx->steps;
+ child_keys->segments = ctx->segments;
/* get different child parameters from textures & vgroups */
get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
if (ptex.exist < psys_frand(psys, i + 24)) {
- child_keys->steps = -1;
+ child_keys->segments = -1;
return;
}
/* create the child path */
- for (k = 0, child = child_keys; k <= ctx->steps; k++, child++) {
+ for (k = 0, child = child_keys; k <= ctx->segments; k++, child++) {
if (ctx->between) {
int w = 0;
@@ -2711,7 +2228,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
/* Fade the effect of rotation for even lengths in the end */
project_v3_v3v3(dvec, off2[w], (key[w] + k)->vel);
- madd_v3_v3fl(off2[w], dvec, -(float)k / (float)ctx->steps);
+ madd_v3_v3fl(off2[w], dvec, -(float)k / (float)ctx->segments);
}
add_v3_v3(off2[w], (key[w] + k)->co);
@@ -2735,14 +2252,14 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
offset_child(cpa, (ParticleKey *)(key[0] + k), par_rot, (ParticleKey *)child, part->childflat, part->childrad);
}
- child->time = (float)k / (float)ctx->steps;
+ child->time = (float)k / (float)ctx->segments;
}
/* apply effectors */
if (part->flag & PART_CHILD_EFFECT) {
- for (k = 0, child = child_keys; k <= ctx->steps; k++, child++) {
+ for (k = 0, child = child_keys; k <= ctx->segments; k++, child++) {
if (k) {
- do_path_effectors(&ctx->sim, cpa->pa[0], child, k, ctx->steps, child_keys->co, ptex.effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
+ do_path_effectors(&ctx->sim, cpa->pa[0], child, k, ctx->segments, child_keys->co, ptex.effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
}
else {
sub_v3_v3v3(eff_vec, (child + 1)->co, child->co);
@@ -2751,147 +2268,119 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
}
}
- for (k = 0, child = child_keys; k <= ctx->steps; k++, child++) {
- t = (float)k / (float)ctx->steps;
-
- if (ctx->totparent)
- /* this is now threadsafe, virtual parents are calculated before rest of children */
- par = (i >= ctx->totparent) ? cache[cpa->parent] : NULL;
- else if (cpa->parent >= 0)
- par = pcache[cpa->parent];
-
- if (par) {
- if (k) {
- mul_qt_qtqt(rot, (par + k)->rot, par->rot);
- par_rot = rot;
- }
- else {
- par_rot = par->rot;
+ {
+ ParticleData *pa = NULL;
+ ParticleCacheKey *par = NULL;
+ float par_co[3];
+ float par_orco[3];
+
+ if (ctx->totparent) {
+ if (i >= ctx->totparent) {
+ pa = &psys->particles[cpa->parent];
+ /* this is now threadsafe, virtual parents are calculated before rest of children */
+ par = cache[cpa->parent];
}
- par += k;
- }
-
- /* apply different deformations to the child path */
- do_child_modifiers(&ctx->sim, &ptex, (ParticleKey *)par, par_rot, cpa, orco, hairmat, (ParticleKey *)child, t);
-
- /* we have to correct velocity because of kink & clump */
- if (k > 1) {
- sub_v3_v3v3((child - 1)->vel, child->co, (child - 2)->co);
- mul_v3_fl((child - 1)->vel, 0.5);
-
- if (ctx->ma && (part->draw_col == PART_DRAW_COL_MAT))
- get_strand_normal(ctx->ma, ornor, cur_length, (child - 1)->vel);
}
-
- if (k == ctx->steps)
- sub_v3_v3v3(child->vel, child->co, (child - 1)->co);
-
- /* check if path needs to be cut before actual end of data points */
- if (k) {
- sub_v3_v3v3(dvec, child->co, (child - 1)->co);
- length = 1.0f / (float)ctx->steps;
- k = check_path_length(k, child_keys, child, max_length, &cur_length, length, dvec);
- }
- else {
- /* initialize length calculation */
- max_length = ptex.length;
- cur_length = 0.0f;
+ else if (cpa->parent >= 0) {
+ pa = &psys->particles[cpa->parent];
+ par = pcache[cpa->parent];
}
-
- if (ctx->ma && (part->draw_col == PART_DRAW_COL_MAT)) {
- copy_v3_v3(child->col, &ctx->ma->r);
- get_strand_normal(ctx->ma, ornor, cur_length, child->vel);
+
+ if (pa) {
+ ListBase modifiers;
+ BLI_listbase_clear(&modifiers);
+
+ psys_particle_on_emitter(ctx->sim.psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset,
+ par_co, NULL, NULL, NULL, par_orco, NULL);
+
+ psys_apply_child_modifiers(ctx, &modifiers, cpa, &ptex, orco, ornor, hairmat, child_keys, par, par_orco);
}
+ else
+ zero_v3(par_orco);
}
/* Hide virtual parents */
if (i < ctx->totparent)
- child_keys->steps = -1;
+ child_keys->segments = -1;
}
-static void *exec_child_path_cache(void *data)
+static void exec_child_path_cache(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(threadid))
{
- ParticleThread *thread = (ParticleThread *)data;
- ParticleThreadContext *ctx = thread->ctx;
+ ParticleTask *task = taskdata;
+ ParticleThreadContext *ctx = task->ctx;
ParticleSystem *psys = ctx->sim.psys;
ParticleCacheKey **cache = psys->childcache;
ChildParticle *cpa;
- int i, totchild = ctx->totchild, first = 0;
+ int i;
- if (thread->tot > 1) {
- first = ctx->parent_pass ? 0 : ctx->totparent;
- totchild = ctx->parent_pass ? ctx->totparent : ctx->totchild;
+ cpa = psys->child + task->begin;
+ for (i = task->begin; i < task->end; ++i, ++cpa) {
+ psys_thread_create_path(task, cpa, cache[i], i);
}
-
- cpa = psys->child + first + thread->num;
- for (i = first + thread->num; i < totchild; i += thread->tot, cpa += thread->tot)
- psys_thread_create_path(thread, cpa, cache[i], i);
-
- return 0;
}
void psys_cache_child_paths(ParticleSimulationData *sim, float cfra, int editupdate)
{
- ParticleThread *pthreads;
- ParticleThreadContext *ctx;
- ListBase threads;
- int i, totchild, totparent, totthread;
-
+ TaskScheduler *task_scheduler;
+ TaskPool *task_pool;
+ ParticleThreadContext ctx;
+ ParticleTask *tasks_parent, *tasks_child;
+ int numtasks_parent, numtasks_child;
+ int i, totchild, totparent;
+
if (sim->psys->flag & PSYS_GLOBAL_HAIR)
return;
-
- pthreads = psys_threads_create(sim);
-
- if (!psys_threads_init_path(pthreads, sim->scene, cfra, editupdate)) {
- psys_threads_free(pthreads);
+
+ /* create a task pool for child path tasks */
+ if (!psys_thread_context_init_path(&ctx, sim, sim->scene, cfra, editupdate))
return;
- }
-
- ctx = pthreads[0].ctx;
- totchild = ctx->totchild;
- totparent = ctx->totparent;
-
+
+ task_scheduler = BLI_task_scheduler_get();
+ task_pool = BLI_task_pool_create(task_scheduler, &ctx);
+ totchild = ctx.totchild;
+ totparent = ctx.totparent;
+
if (editupdate && sim->psys->childcache && totchild == sim->psys->totchildcache) {
; /* just overwrite the existing cache */
}
else {
/* clear out old and create new empty path cache */
free_child_path_cache(sim->psys);
- sim->psys->childcache = psys_alloc_path_cache_buffers(&sim->psys->childcachebufs, totchild, ctx->steps + 1);
+
+ sim->psys->childcache = psys_alloc_path_cache_buffers(&sim->psys->childcachebufs, totchild, ctx.segments + ctx.extra_segments + 1);
sim->psys->totchildcache = totchild;
}
-
- totthread = pthreads[0].tot;
-
- if (totthread > 1) {
-
- /* make virtual child parents thread safe by calculating them first */
- if (totparent) {
- BLI_init_threads(&threads, exec_child_path_cache, totthread);
-
- for (i = 0; i < totthread; i++) {
- pthreads[i].ctx->parent_pass = 1;
- BLI_insert_thread(&threads, &pthreads[i]);
- }
-
- BLI_end_threads(&threads);
-
- for (i = 0; i < totthread; i++)
- pthreads[i].ctx->parent_pass = 0;
- }
-
- BLI_init_threads(&threads, exec_child_path_cache, totthread);
-
- for (i = 0; i < totthread; i++)
- BLI_insert_thread(&threads, &pthreads[i]);
-
- BLI_end_threads(&threads);
+
+ /* cache parent paths */
+ ctx.parent_pass = 1;
+ psys_tasks_create(&ctx, totparent, &tasks_parent, &numtasks_parent);
+ for (i = 0; i < numtasks_parent; ++i) {
+ ParticleTask *task = &tasks_parent[i];
+
+ psys_task_init_path(task, sim);
+ BLI_task_pool_push(task_pool, exec_child_path_cache, task, false, TASK_PRIORITY_LOW);
}
- else
- exec_child_path_cache(&pthreads[0]);
+ BLI_task_pool_work_and_wait(task_pool);
+
+ /* cache child paths */
+ ctx.parent_pass = 0;
+ psys_tasks_create(&ctx, totchild, &tasks_child, &numtasks_child);
+ for (i = 0; i < numtasks_child; ++i) {
+ ParticleTask *task = &tasks_child[i];
+
+ psys_task_init_path(task, sim);
+ BLI_task_pool_push(task_pool, exec_child_path_cache, task, false, TASK_PRIORITY_LOW);
+ }
+ BLI_task_pool_work_and_wait(task_pool);
- psys_threads_free(pthreads);
+ BLI_task_pool_free(task_pool);
+
+ psys_tasks_free(tasks_parent, numtasks_parent);
+ psys_tasks_free(tasks_child, numtasks_child);
+
+ psys_thread_context_free(&ctx);
}
+
/* figure out incremental rotations along path starting from unit quat */
static void cache_key_incremental_rotation(ParticleCacheKey *key0, ParticleCacheKey *key1, ParticleCacheKey *key2, float *prev_tangent, int i)
{
@@ -2959,7 +2448,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
float prev_tangent[3] = {0.0f, 0.0f, 0.0f}, hairmat[4][4];
float rotmat[3][3];
int k;
- int steps = (int)pow(2.0, (double)(psys->renderdata ? part->ren_step : part->draw_step));
+ int segments = (int)pow(2.0, (double)(psys->renderdata ? part->ren_step : part->draw_step));
int totpart = psys->totpart;
float length, vec[3];
float *vg_effector = NULL;
@@ -2979,7 +2468,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
/* clear out old and create new empty path cache */
psys_free_path_cache(psys, psys->edit);
- cache = psys->pathcache = psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps + 1);
+ cache = psys->pathcache = psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, segments + 1);
psys->lattice_deform_data = psys_create_lattice_deform_data(sim);
ma = give_current_material(sim->ob, psys->part->omat);
@@ -3000,7 +2489,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
}
/*---first main loop: create all actual particles' paths---*/
- LOOP_SHOWN_PARTICLES {
+ LOOP_PARTICLES {
if (!psys->totchild) {
psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f);
pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p));
@@ -3014,9 +2503,9 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
pind.dm = hair_dm;
- memset(cache[p], 0, sizeof(*cache[p]) * (steps + 1));
+ memset(cache[p], 0, sizeof(*cache[p]) * (segments + 1));
- cache[p]->steps = steps;
+ cache[p]->segments = segments;
/*--get the first data points--*/
init_particle_interpolation(sim->ob, sim->psys, pa, &pind);
@@ -3038,15 +2527,15 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
}
if (birthtime >= dietime) {
- cache[p]->steps = -1;
+ cache[p]->segments = -1;
continue;
}
dietime = birthtime + pa_length * (dietime - birthtime);
/*--interpolate actual path from data points--*/
- for (k = 0, ca = cache[p]; k <= steps; k++, ca++) {
- time = (float)k / (float)steps;
+ for (k = 0, ca = cache[p]; k <= segments; k++, ca++) {
+ time = (float)k / (float)segments;
t = birthtime + time * (dietime - birthtime);
result.time = -t;
do_particle_interpolation(psys, p, pa, t, &pind, &result);
@@ -3061,7 +2550,15 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
copy_v3_v3(ca->col, col);
}
-
+
+ if (part->type == PART_HAIR) {
+ HairKey *hkey;
+
+ for (k = 0, hkey = pa->hair; k < pa->totkey; ++k, ++hkey) {
+ mul_v3_m4v3(hkey->world_co, hairmat, hkey->co);
+ }
+ }
+
/*--modify paths and calculate rotation & velocity--*/
if (!(psys->flag & PSYS_GLOBAL_HAIR)) {
@@ -3074,29 +2571,29 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co);
length = len_v3(vec);
- for (k = 1, ca = cache[p] + 1; k <= steps; k++, ca++)
- do_path_effectors(sim, p, ca, k, steps, cache[p]->co, effector, dfra, cfra, &length, vec);
+ for (k = 1, ca = cache[p] + 1; k <= segments; k++, ca++)
+ do_path_effectors(sim, p, ca, k, segments, cache[p]->co, effector, dfra, cfra, &length, vec);
}
/* apply guide curves to path data */
if (sim->psys->effectors && (psys->part->flag & PART_CHILD_EFFECT) == 0) {
- for (k = 0, ca = cache[p]; k <= steps; k++, ca++)
+ for (k = 0, ca = cache[p]; k <= segments; k++, ca++)
/* ca is safe to cast, since only co and vel are used */
- do_guides(sim->psys->effectors, (ParticleKey *)ca, p, (float)k / (float)steps);
+ do_guides(sim->psys->part, sim->psys->effectors, (ParticleKey *)ca, p, (float)k / (float)segments);
}
/* lattices have to be calculated separately to avoid mixups between effector calculations */
if (psys->lattice_deform_data) {
- for (k = 0, ca = cache[p]; k <= steps; k++, ca++)
+ for (k = 0, ca = cache[p]; k <= segments; k++, ca++)
calc_latt_deform(psys->lattice_deform_data, ca->co, 1.0f);
}
}
/* finally do rotation & velocity */
- for (k = 1, ca = cache[p] + 1; k <= steps; k++, ca++) {
+ for (k = 1, ca = cache[p] + 1; k <= segments; k++, ca++) {
cache_key_incremental_rotation(ca, ca - 1, ca - 2, prev_tangent, k);
- if (k == steps)
+ if (k == segments)
copy_qt_qt(ca->rot, (ca - 1)->rot);
/* set velocity */
@@ -3105,7 +2602,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
if (k == 1)
copy_v3_v3((ca - 1)->vel, ca->vel);
- ca->time = (float)k / (float)steps;
+ ca->time = (float)k / (float)segments;
}
/* First rotation is based on emitting face orientation.
* This is way better than having flipping rotations resulting
@@ -3149,17 +2646,17 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
float t, time = 0.0f, keytime = 0.0f /*, frs_sec */;
float hairmat[4][4], rotmat[3][3], prev_tangent[3] = {0.0f, 0.0f, 0.0f};
int k, i;
- int steps = (int)pow(2.0, (double)pset->draw_step);
+ int segments = 1 << pset->draw_step;
int totpart = edit->totpoint, recalc_set = 0;
float sel_col[3];
float nosel_col[3];
- steps = MAX2(steps, 4);
+ segments = MAX2(segments, 4);
if (!cache || edit->totpoint != edit->totcached) {
/* clear out old and create new empty path cache */
psys_free_path_cache(edit->psys, edit);
- cache = edit->pathcache = psys_alloc_path_cache_buffers(&edit->pathcachebufs, totpart, steps + 1);
+ cache = edit->pathcache = psys_alloc_path_cache_buffers(&edit->pathcachebufs, totpart, segments + 1);
/* set flag for update (child particles check this too) */
for (i = 0, point = edit->points; i < totpart; i++, point++)
@@ -3206,9 +2703,9 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
}
- memset(cache[i], 0, sizeof(*cache[i]) * (steps + 1));
+ memset(cache[i], 0, sizeof(*cache[i]) * (segments + 1));
- cache[i]->steps = steps;
+ cache[i]->segments = segments;
/*--get the first data points--*/
init_particle_interpolation(ob, psys, pa, &pind);
@@ -3224,13 +2721,13 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
dietime = pind.dietime;
if (birthtime >= dietime) {
- cache[i]->steps = -1;
+ cache[i]->segments = -1;
continue;
}
/*--interpolate actual path from data points--*/
- for (k = 0, ca = cache[i]; k <= steps; k++, ca++) {
- time = (float)k / (float)steps;
+ for (k = 0, ca = cache[i]; k <= segments; k++, ca++) {
+ time = (float)k / (float)segments;
t = birthtime + time * (dietime - birthtime);
result.time = -t;
do_particle_interpolation(psys, i, pa, t, &pind, &result);
@@ -3243,7 +2740,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
if (k) {
cache_key_incremental_rotation(ca, ca - 1, ca - 2, prev_tangent, k);
- if (k == steps)
+ if (k == segments)
copy_qt_qt(ca->rot, (ca - 1)->rot);
/* set velocity */
@@ -3277,7 +2774,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
/* at the moment this is only used for weight painting.
* will need to move out of this check if its used elsewhere. */
- t2 = birthtime + ((float)k / (float)steps) * (dietime - birthtime);
+ t2 = birthtime + ((float)k / (float)segments) * (dietime - birthtime);
while (pind.hkey[1]->time < t2) pind.hkey[1]++;
pind.hkey[0] = pind.hkey[1] - 1;
@@ -3514,8 +3011,8 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n
psys->part = psys_new_settings(DATA_("ParticleSettings"), NULL);
- if (BLI_countlist(&ob->particlesystem) > 1)
- BLI_snprintf(psys->name, sizeof(psys->name), DATA_("ParticleSystem %i"), BLI_countlist(&ob->particlesystem));
+ if (BLI_listbase_count_ex(&ob->particlesystem, 2) > 1)
+ BLI_snprintf(psys->name, sizeof(psys->name), DATA_("ParticleSystem %i"), BLI_listbase_count(&ob->particlesystem));
else
BLI_strncpy(psys->name, DATA_("ParticleSystem"), sizeof(psys->name));
@@ -3524,7 +3021,7 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n
if (name)
BLI_strncpy_utf8(md->name, name, sizeof(md->name));
else
- BLI_snprintf(md->name, sizeof(md->name), DATA_("ParticleSystem %i"), BLI_countlist(&ob->particlesystem));
+ BLI_snprintf(md->name, sizeof(md->name), DATA_("ParticleSystem %i"), BLI_listbase_count(&ob->particlesystem));
modifier_unique_name(&ob->modifiers, md);
psmd = (ParticleSystemModifierData *) md;
@@ -3581,6 +3078,7 @@ void object_remove_particle_system(Scene *UNUSED(scene), Object *ob)
DAG_relations_tag_update(G.main);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
+
static void default_particle_settings(ParticleSettings *part)
{
part->type = PART_EMITTER;
@@ -3611,6 +3109,8 @@ static void default_particle_settings(ParticleSettings *part)
part->adapt_pix = 3;
part->kink_axis = 2;
part->kink_amp_clump = 1.f;
+ part->kink_extra_steps = 4;
+ part->clump_noise_size = 1.0f;
part->reactevent = PART_EVENT_DEATH;
part->disp = 100;
part->from = PART_FROM_FACE;
@@ -3678,6 +3178,30 @@ ParticleSettings *psys_new_settings(const char *name, Main *main)
return part;
}
+void BKE_particlesettings_clump_curve_init(ParticleSettings *part)
+{
+ CurveMapping *cumap = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+
+ cumap->cm[0].curve[0].x = 0.0f;
+ cumap->cm[0].curve[0].y = 1.0f;
+ cumap->cm[0].curve[1].x = 1.0f;
+ cumap->cm[0].curve[1].y = 1.0f;
+
+ part->clumpcurve = cumap;
+}
+
+void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
+{
+ CurveMapping *cumap = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+
+ cumap->cm[0].curve[0].x = 0.0f;
+ cumap->cm[0].curve[0].y = 1.0f;
+ cumap->cm[0].curve[1].x = 1.0f;
+ cumap->cm[0].curve[1].y = 1.0f;
+
+ part->roughcurve = cumap;
+}
+
ParticleSettings *BKE_particlesettings_copy(ParticleSettings *part)
{
ParticleSettings *partn;
@@ -3689,6 +3213,11 @@ ParticleSettings *BKE_particlesettings_copy(ParticleSettings *part)
partn->effector_weights = MEM_dupallocN(part->effector_weights);
partn->fluid = MEM_dupallocN(part->fluid);
+ if (part->clumpcurve)
+ partn->clumpcurve = curvemapping_copy(part->clumpcurve);
+ if (part->roughcurve)
+ partn->roughcurve = curvemapping_copy(part->roughcurve);
+
partn->boids = boid_copy_settings(part->boids);
for (a = 0; a < MAX_MTEX; a++) {
@@ -3701,6 +3230,10 @@ ParticleSettings *BKE_particlesettings_copy(ParticleSettings *part)
BLI_duplicatelist(&partn->dupliweights, &part->dupliweights);
+ if (part->id.lib) {
+ BKE_id_lib_local_paths(G.main, part->id.lib, &partn->id);
+ }
+
return partn;
}
@@ -3836,7 +3369,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
float value, rgba[4], texvec[3];
ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
- ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink =
+ ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink_freq = ptex->kink_amp =
ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
ptex->length = 1.0f - part->randlength * psys_frand(psys, child_index + 26);
@@ -3876,21 +3409,23 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
break;
}
- externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL);
+ externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL, false);
if ((event & mtex->mapto) & PAMAP_ROUGH)
ptex->rough1 = ptex->rough2 = ptex->roughe = texture_value_blend(def, ptex->rough1, value, mtex->roughfac, blend);
SET_PARTICLE_TEXTURE(PAMAP_LENGTH, ptex->length, mtex->lengthfac);
SET_PARTICLE_TEXTURE(PAMAP_CLUMP, ptex->clump, mtex->clumpfac);
- SET_PARTICLE_TEXTURE(PAMAP_KINK, ptex->kink, mtex->kinkfac);
+ SET_PARTICLE_TEXTURE(PAMAP_KINK_AMP, ptex->kink_amp, mtex->kinkampfac);
+ SET_PARTICLE_TEXTURE(PAMAP_KINK_FREQ, ptex->kink_freq, mtex->kinkfac);
SET_PARTICLE_TEXTURE(PAMAP_DENS, ptex->exist, mtex->padensfac);
}
}
CLAMP_PARTICLE_TEXTURE_POS(PAMAP_LENGTH, ptex->length);
CLAMP_PARTICLE_TEXTURE_POS(PAMAP_CLUMP, ptex->clump);
- CLAMP_PARTICLE_TEXTURE_POS(PAMAP_KINK, ptex->kink);
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_KINK_AMP, ptex->kink_amp);
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_KINK_FREQ, ptex->kink_freq);
CLAMP_PARTICLE_TEXTURE_POS(PAMAP_ROUGH, ptex->rough1);
CLAMP_PARTICLE_TEXTURE_POS(PAMAP_DENS, ptex->exist);
}
@@ -3907,7 +3442,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
/* initialize ptex */
ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
- ptex->gravity = ptex->field = ptex->length = ptex->clump = ptex->kink =
+ ptex->gravity = ptex->field = ptex->length = ptex->clump = ptex->kink_freq = ptex->kink_amp =
ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
ptex->time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart;
@@ -3957,7 +3492,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
break;
}
- externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL);
+ externtex(mtex, texvec, &value, rgba, rgba + 1, rgba + 2, rgba + 3, 0, NULL, false);
if ((event & mtex->mapto) & PAMAP_TIME) {
/* the first time has to set the base value for time regardless of blend mode */
@@ -4061,7 +3596,7 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
if (ctx->vg_clump)
ptex->clump *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_clump);
if (ctx->vg_kink)
- ptex->kink *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_kink);
+ ptex->kink_freq *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_kink);
if (ctx->vg_rough1)
ptex->rough1 *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_rough1);
if (ctx->vg_rough2)
@@ -4071,55 +3606,6 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
if (ctx->vg_effector)
ptex->effector *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_effector);
}
-static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, float mat[4][4], ParticleKey *state, float t)
-{
- ParticleSettings *part = sim->psys->part;
- int i = cpa - sim->psys->child;
- int guided = 0;
-
- float kink_freq = part->kink_freq;
- float rough1 = part->rough1;
- float rough2 = part->rough2;
- float rough_end = part->rough_end;
-
- if (ptex) {
- kink_freq *= ptex->kink;
- rough1 *= ptex->rough1;
- rough2 *= ptex->rough2;
- rough_end *= ptex->roughe;
- }
-
- if (part->flag & PART_CHILD_EFFECT)
- /* state is safe to cast, since only co and vel are used */
- guided = do_guides(sim->psys->effectors, (ParticleKey *)state, cpa->parent, t);
-
- if (guided == 0) {
- float clump = do_clump(state, par, t, part->clumpfac, part->clumppow, ptex ? ptex->clump : 1.f);
-
- if (kink_freq != 0.f) {
- float kink_amp = part->kink_amp * (1.f - part->kink_amp_clump * clump);
-
- do_kink(state, par, par_rot, t, kink_freq, part->kink_shape,
- kink_amp, part->kink_flat, part->kink, part->kink_axis,
- sim->ob->obmat, sim->psys->part->childtype == PART_CHILD_FACES);
- }
- }
-
- if (rough1 > 0.f)
- do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
-
- if (rough2 > 0.f) {
- float vec[3];
- psys_frand_vec(sim->psys, i + 27, vec);
- do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
- }
-
- if (rough_end > 0.f) {
- float vec[3];
- psys_frand_vec(sim->psys, i + 27, vec);
- do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
- }
-}
/* get's hair (or keyed) particles state at the "path time" specified in state->time */
void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, const bool vel)
{
@@ -4186,7 +3672,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
mul_mat3_m4_v3(hairmat, state->vel);
if (sim->psys->effectors && (part->flag & PART_CHILD_GUIDE) == 0) {
- do_guides(sim->psys->effectors, state, p, state->time);
+ do_guides(sim->psys->part, sim->psys->effectors, state, p, state->time);
/* TODO: proper velocity handling */
}
@@ -4208,6 +3694,8 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
copy_qt_qt(state->rot, result.rot);
}
else {
+ float par_co[3], par_orco[3];
+
cpa = psys->child + p - totpart;
if (state->time < 0.0f)
@@ -4244,6 +3732,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
pa = psys->particles + cpa->parent;
+ psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco, 0);
if (part->type == PART_HAIR)
psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
else
@@ -4263,8 +3752,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
cpa_num = pa->num;
cpa_fuv = pa->fuv;
-
-
+ psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, par_co, 0, 0, 0, par_orco, 0);
if (part->type == PART_HAIR) {
psys_particle_on_emitter(psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco, 0);
psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
@@ -4322,7 +3810,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
copy_particle_key(&tstate, state, 1);
/* apply different deformations to the child path */
- do_child_modifiers(sim, &ptex, par, par->rot, cpa, orco, hairmat, state, t);
+ do_child_modifiers(sim, &ptex, par->co, par->vel, par->rot, par_orco, cpa, orco, hairmat, state, t);
/* try to estimate correct velocity */
if (vel) {
@@ -4417,6 +3905,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
float mat[4][4];
ParticleKey *key1;
float t = (cfra - pa->time) / pa->lifetime;
+ float par_orco[3] = {0.0f, 0.0f, 0.0f};
key1 = &pa->state;
offset_child(cpa, key1, key1->rot, state, part->childflat, part->childrad);
@@ -4424,7 +3913,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
CLAMP(t, 0.0f, 1.0f);
unit_m4(mat);
- do_child_modifiers(sim, NULL, key1, key1->rot, cpa, cpa->fuv, mat, state, t);
+ do_child_modifiers(sim, NULL, key1->co, key1->vel, key1->rot, par_orco, cpa, cpa->fuv, mat, state, t);
if (psys->lattice_deform_data)
calc_latt_deform(psys->lattice_deform_data, state->co, 1.0f);
@@ -4552,7 +4041,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
float loc[3], nor[3], vec[3], side[3], len;
float xvec[3] = {-1.0, 0.0, 0.0}, nmat[3][3];
- sub_v3_v3v3(vec, (cache + cache->steps)->co, cache->co);
+ sub_v3_v3v3(vec, (cache + cache->segments)->co, cache->co);
len = normalize_v3(vec);
if (pa == NULL && psys->part->childflat != PART_CHILD_FACES)
@@ -4564,14 +4053,13 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
psys_particle_on_emitter(psmd, PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, loc, nor, 0, 0, 0, 0);
if (psys->part->rotmode == PART_ROT_VEL) {
- copy_m3_m4(nmat, ob->imat);
- transpose_m3(nmat);
+ transpose_m3_m4(nmat, ob->imat);
mul_m3_v3(nmat, nor);
normalize_v3(nor);
/* make sure that we get a proper side vector */
- if (fabsf(dot_v3v3(nor, vec)) > 0.999999) {
- if (fabsf(dot_v3v3(nor, xvec)) > 0.999999) {
+ if (fabsf(dot_v3v3(nor, vec)) > 0.999999f) {
+ if (fabsf(dot_v3v3(nor, xvec)) > 0.999999f) {
nor[0] = 0.0f;
nor[1] = 1.0f;
nor[2] = 0.0f;
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
new file mode 100644
index 00000000000..7b2e07ea96f
--- /dev/null
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -0,0 +1,732 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/particle_child.c
+ * \ingroup bke
+ */
+
+#include "BLI_math.h"
+#include "BLI_noise.h"
+
+#include "DNA_material_types.h"
+
+#include "BKE_colortools.h"
+#include "BKE_particle.h"
+
+struct Material;
+
+void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape, float amplitude, float flat,
+ short type, short axis, float obmat[4][4], int smooth_start);
+float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
+ bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve);
+void do_child_modifiers(ParticleSimulationData *sim,
+ ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3],
+ ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t);
+
+static void get_strand_normal(Material *ma, const float surfnor[3], float surfdist, float nor[3])
+{
+ float cross[3], nstrand[3], vnor[3], blend;
+
+ if (!((ma->mode & MA_STR_SURFDIFF) || (ma->strand_surfnor > 0.0f)))
+ return;
+
+ if (ma->mode & MA_STR_SURFDIFF) {
+ cross_v3_v3v3(cross, surfnor, nor);
+ cross_v3_v3v3(nstrand, nor, cross);
+
+ blend = dot_v3v3(nstrand, surfnor);
+ CLAMP(blend, 0.0f, 1.0f);
+
+ interp_v3_v3v3(vnor, nstrand, surfnor, blend);
+ normalize_v3(vnor);
+ }
+ else {
+ copy_v3_v3(vnor, nor);
+ }
+
+ if (ma->strand_surfnor > 0.0f) {
+ if (ma->strand_surfnor > surfdist) {
+ blend = (ma->strand_surfnor - surfdist) / ma->strand_surfnor;
+ interp_v3_v3v3(vnor, vnor, surfnor, blend);
+ normalize_v3(vnor);
+ }
+ }
+
+ copy_v3_v3(nor, vnor);
+}
+
+/* ------------------------------------------------------------------------- */
+
+typedef struct ParticlePathIterator {
+ ParticleCacheKey *key;
+ int index;
+ float time;
+
+ ParticleCacheKey *parent_key;
+ float parent_rotation[4];
+} ParticlePathIterator;
+
+static void psys_path_iter_get(ParticlePathIterator *iter, ParticleCacheKey *keys, int totkeys,
+ ParticleCacheKey *parent, int index)
+{
+ BLI_assert(index >= 0 && index < totkeys);
+
+ iter->key = keys + index;
+ iter->index = index;
+ iter->time = (float)index / (float)(totkeys - 1);
+
+ if (parent) {
+ iter->parent_key = parent + index;
+ if (index > 0)
+ mul_qt_qtqt(iter->parent_rotation, iter->parent_key->rot, parent->rot);
+ else
+ copy_qt_qt(iter->parent_rotation, parent->rot);
+ }
+ else {
+ iter->parent_key = NULL;
+ unit_qt(iter->parent_rotation);
+ }
+}
+
+typedef struct ParticlePathModifier {
+ struct ParticlePathModifier *next, *prev;
+
+ void (*apply)(ParticleCacheKey *keys, int totkeys, ParticleCacheKey *parent_keys);
+} ParticlePathModifier;
+
+/* ------------------------------------------------------------------------- */
+
+static void do_kink_spiral_deform(ParticleKey *state, const float dir[3], const float kink[3],
+ float time, float freq, float shape, float amplitude,
+ const float spiral_start[3])
+{
+ float result[3];
+
+ CLAMP(time, 0.f, 1.f);
+
+ copy_v3_v3(result, state->co);
+
+ {
+ /* Creates a logarithmic spiral:
+ * r(theta) = a * exp(b * theta)
+ *
+ * The "density" parameter b is defined by the shape parameter
+ * and goes up to the Golden Spiral for 1.0
+ * http://en.wikipedia.org/wiki/Golden_spiral
+ */
+ const float b = shape * (1.0f + sqrtf(5.0f)) / (float)M_PI * 0.25f;
+ /* angle of the spiral against the curve (rotated opposite to make a smooth transition) */
+ const float start_angle = ((b != 0.0f) ? atanf(1.0f / b) :
+ (float)-M_PI_2) + (b > 0.0f ? -(float)M_PI_2 : (float)M_PI_2);
+
+ float spiral_axis[3], rot[3][3];
+ float vec[3];
+
+ float theta = freq * time * 2.0f * (float)M_PI;
+ float radius = amplitude * expf(b * theta);
+
+ /* a bit more intuitive than using negative frequency for this */
+ if (amplitude < 0.0f)
+ theta = -theta;
+
+ cross_v3_v3v3(spiral_axis, dir, kink);
+ normalize_v3(spiral_axis);
+
+ mul_v3_v3fl(vec, kink, -radius);
+
+ axis_angle_normalized_to_mat3(rot, spiral_axis, theta);
+ mul_m3_v3(rot, vec);
+
+ madd_v3_v3fl(vec, kink, amplitude);
+
+ axis_angle_normalized_to_mat3(rot, spiral_axis, -start_angle);
+ mul_m3_v3(rot, vec);
+
+ add_v3_v3v3(result, spiral_start, vec);
+ }
+
+ copy_v3_v3(state->co, result);
+}
+
+static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, const float parent_orco[3],
+ ChildParticle *cpa, const float orco[3], float hairmat[4][4],
+ ParticleCacheKey *keys, ParticleCacheKey *parent_keys, int *r_totkeys, float *r_max_length)
+{
+ struct ParticleSettings *part = ctx->sim.psys->part;
+ const int seed = ctx->sim.psys->child_seed + (int)(cpa - ctx->sim.psys->child);
+ const int totkeys = ctx->segments + 1;
+ const int extrakeys = ctx->extra_segments;
+
+ float kink_amp_random = part->kink_amp_random;
+ float kink_amp = part->kink_amp * (1.0f - kink_amp_random * psys_frand(ctx->sim.psys, 93541 + seed));
+ float kink_freq = part->kink_freq;
+ float kink_shape = part->kink_shape;
+ float kink_axis_random = part->kink_axis_random;
+ float rough1 = part->rough1;
+ float rough2 = part->rough2;
+ float rough_end = part->rough_end;
+
+ ParticlePathIterator iter;
+ ParticleCacheKey *key;
+ int k;
+
+ float dir[3];
+ float spiral_start[3] = {0.0f, 0.0f, 0.0f};
+ float spiral_start_time = 0.0f;
+ float spiral_par_co[3] = {0.0f, 0.0f, 0.0f};
+ float spiral_par_vel[3] = {0.0f, 0.0f, 0.0f};
+ float spiral_par_rot[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ float totlen;
+ float cut_time;
+ int start_index = 0, end_index = 0;
+ float kink_base[3];
+
+ if (ptex) {
+ kink_amp *= ptex->kink_amp;
+ kink_freq *= ptex->kink_freq;
+ rough1 *= ptex->rough1;
+ rough2 *= ptex->rough2;
+ rough_end *= ptex->roughe;
+ }
+
+ cut_time = (totkeys - 1) * ptex->length;
+ zero_v3(spiral_start);
+
+ for (k = 0, key = keys; k < totkeys-1; k++, key++) {
+ if ((float)(k + 1) >= cut_time) {
+ float fac = cut_time - (float)k;
+ ParticleCacheKey *par = parent_keys + k;
+
+ start_index = k + 1;
+ end_index = start_index + extrakeys;
+
+ spiral_start_time = ((float)k + fac) / (float)(totkeys - 1);
+ interp_v3_v3v3(spiral_start, key->co, (key+1)->co, fac);
+
+ interp_v3_v3v3(spiral_par_co, par->co, (par+1)->co, fac);
+ interp_v3_v3v3(spiral_par_vel, par->vel, (par+1)->vel, fac);
+ interp_qt_qtqt(spiral_par_rot, par->rot, (par+1)->rot, fac);
+
+ break;
+ }
+ }
+
+ zero_v3(dir);
+
+ zero_v3(kink_base);
+ kink_base[part->kink_axis] = 1.0f;
+ mul_mat3_m4_v3(ctx->sim.ob->obmat, kink_base);
+
+ for (k = 0, key = keys; k < end_index; k++, key++) {
+ float par_time;
+ float *par_co, *par_vel, *par_rot;
+
+ psys_path_iter_get(&iter, keys, end_index, NULL, k);
+ if (k < start_index) {
+ sub_v3_v3v3(dir, (key+1)->co, key->co);
+ normalize_v3(dir);
+
+ par_time = (float)k / (float)(totkeys - 1);
+ par_co = parent_keys[k].co;
+ par_vel = parent_keys[k].vel;
+ par_rot = parent_keys[k].rot;
+ }
+ else {
+ float spiral_time = (float)(k - start_index) / (float)(extrakeys-1);
+ float kink[3], tmp[3];
+
+ /* use same time value for every point on the spiral */
+ par_time = spiral_start_time;
+ par_co = spiral_par_co;
+ par_vel = spiral_par_vel;
+ par_rot = spiral_par_rot;
+
+ project_v3_v3v3(tmp, kink_base, dir);
+ sub_v3_v3v3(kink, kink_base, tmp);
+ normalize_v3(kink);
+
+ if (kink_axis_random > 0.0f) {
+ float a = kink_axis_random * (psys_frand(ctx->sim.psys, 7112 + seed) * 2.0f - 1.0f) * (float)M_PI;
+ float rot[3][3];
+
+ axis_angle_normalized_to_mat3(rot, dir, a);
+ mul_m3_v3(rot, kink);
+ }
+
+ do_kink_spiral_deform((ParticleKey *)key, dir, kink, spiral_time, kink_freq, kink_shape, kink_amp, spiral_start);
+ }
+
+ /* apply different deformations to the child path */
+ do_child_modifiers(&ctx->sim, ptex, par_co, par_vel, par_rot, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, par_time);
+ }
+
+ totlen = 0.0f;
+ for (k = 0, key = keys; k < end_index-1; k++, key++)
+ totlen += len_v3v3((key+1)->co, key->co);
+
+ *r_totkeys = end_index;
+ *r_max_length = totlen;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static bool check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *key, float max_length, float step_length, float *cur_length, float dvec[3])
+{
+ if (*cur_length + step_length > max_length) {
+ sub_v3_v3v3(dvec, key->co, (key-1)->co);
+ mul_v3_fl(dvec, (max_length - *cur_length) / step_length);
+ add_v3_v3v3(key->co, (key-1)->co, dvec);
+ keys->segments = k;
+ /* something over the maximum step value */
+ return false;
+ }
+ else {
+ *cur_length += step_length;
+ return true;
+ }
+}
+
+void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *modifiers,
+ ChildParticle *cpa, ParticleTexture *ptex, const float orco[3], const float ornor[3], float hairmat[4][4],
+ ParticleCacheKey *keys, ParticleCacheKey *parent_keys, const float parent_orco[3])
+{
+ struct ParticleSettings *part = ctx->sim.psys->part;
+ struct Material *ma = ctx->ma;
+ const bool draw_col_ma = (part->draw_col == PART_DRAW_COL_MAT);
+ const bool use_length_check = !ELEM(part->kink, PART_KINK_SPIRAL);
+
+ ParticlePathModifier *mod;
+ ParticleCacheKey *key;
+ int totkeys, k;
+ float max_length;
+
+#if 0 /* TODO for the future: use true particle modifiers that work on the whole curve */
+ for (mod = modifiers->first; mod; mod = mod->next) {
+ mod->apply(keys, totkeys, parent_keys);
+ }
+#else
+ (void)modifiers;
+ (void)mod;
+
+ if (part->kink == PART_KINK_SPIRAL) {
+ do_kink_spiral(ctx, ptex, parent_orco, cpa, orco, hairmat, keys, parent_keys, &totkeys, &max_length);
+ keys->segments = totkeys - 1;
+ }
+ else {
+ ParticlePathIterator iter;
+
+ totkeys = ctx->segments + 1;
+ max_length = ptex->length;
+
+ for (k = 0, key = keys; k < totkeys; k++, key++) {
+ ParticleKey *par;
+
+ psys_path_iter_get(&iter, keys, totkeys, parent_keys, k);
+ par = (ParticleKey *)iter.parent_key;
+
+ /* apply different deformations to the child path */
+ do_child_modifiers(&ctx->sim, ptex, par->co, par->vel, iter.parent_rotation, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, iter.time);
+ }
+ }
+
+ {
+ const float step_length = 1.0f / (float)(totkeys - 1);
+
+ float cur_length = 0.0f;
+
+ /* we have to correct velocity because of kink & clump */
+ for (k = 0, key = keys; k < totkeys; ++k, ++key) {
+ if (k >= 2) {
+ sub_v3_v3v3((key-1)->vel, key->co, (key-2)->co);
+ mul_v3_fl((key-1)->vel, 0.5);
+
+ if (ma && draw_col_ma)
+ get_strand_normal(ma, ornor, cur_length, (key-1)->vel);
+ }
+
+ if (use_length_check && k > 1) {
+ float dvec[3];
+ /* check if path needs to be cut before actual end of data points */
+ if (!check_path_length(k, keys, key, max_length, step_length, &cur_length, dvec)) {
+ /* last key */
+ sub_v3_v3v3(key->vel, key->co, (key-1)->co);
+ if (ma && draw_col_ma) {
+ copy_v3_v3(key->col, &ma->r);
+ }
+ break;
+ }
+ }
+ if (k == totkeys-1) {
+ /* last key */
+ sub_v3_v3v3(key->vel, key->co, (key-1)->co);
+ }
+
+ if (ma && draw_col_ma) {
+ copy_v3_v3(key->col, &ma->r);
+ get_strand_normal(ma, ornor, cur_length, key->vel);
+ }
+ }
+ }
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+
+void do_kink(ParticleKey *state, const float par_co[3], const float par_vel[3], const float par_rot[4], float time, float freq, float shape,
+ float amplitude, float flat, short type, short axis, float obmat[4][4], int smooth_start)
+{
+ float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f};
+ float t, dt = 1.f, result[3];
+
+ if (ELEM(type, PART_KINK_NO, PART_KINK_SPIRAL))
+ return;
+
+ CLAMP(time, 0.f, 1.f);
+
+ if (shape != 0.0f && !ELEM(type, PART_KINK_BRAID)) {
+ if (shape < 0.0f)
+ time = (float)pow(time, 1.f + shape);
+ else
+ time = (float)pow(time, 1.f / (1.f - shape));
+ }
+
+ t = time * freq * (float)M_PI;
+
+ if (smooth_start) {
+ dt = fabsf(t);
+ /* smooth the beginning of kink */
+ CLAMP(dt, 0.f, (float)M_PI);
+ dt = sinf(dt / 2.f);
+ }
+
+ if (!ELEM(type, PART_KINK_RADIAL)) {
+ float temp[3];
+
+ kink[axis] = 1.f;
+
+ if (obmat)
+ mul_mat3_m4_v3(obmat, kink);
+
+ mul_qt_v3(par_rot, kink);
+
+ /* make sure kink is normal to strand */
+ project_v3_v3v3(temp, kink, par_vel);
+ sub_v3_v3(kink, temp);
+ normalize_v3(kink);
+ }
+
+ copy_v3_v3(result, state->co);
+ sub_v3_v3v3(par_vec, par_co, state->co);
+
+ switch (type) {
+ case PART_KINK_CURL:
+ {
+ float curl_offset[3];
+
+ /* rotate kink vector around strand tangent */
+ mul_v3_v3fl(curl_offset, kink, amplitude);
+ axis_angle_to_quat(q1, par_vel, t);
+ mul_qt_v3(q1, curl_offset);
+
+ interp_v3_v3v3(par_vec, state->co, par_co, flat);
+ add_v3_v3v3(result, par_vec, curl_offset);
+ break;
+ }
+ case PART_KINK_RADIAL:
+ {
+ if (flat > 0.f) {
+ float proj[3];
+ /* flatten along strand */
+ project_v3_v3v3(proj, par_vec, par_vel);
+ madd_v3_v3fl(result, proj, flat);
+ }
+
+ madd_v3_v3fl(result, par_vec, -amplitude * sinf(t));
+ break;
+ }
+ case PART_KINK_WAVE:
+ {
+ madd_v3_v3fl(result, kink, amplitude * sinf(t));
+
+ if (flat > 0.f) {
+ float proj[3];
+ /* flatten along wave */
+ project_v3_v3v3(proj, par_vec, kink);
+ madd_v3_v3fl(result, proj, flat);
+
+ /* flatten along strand */
+ project_v3_v3v3(proj, par_vec, par_vel);
+ madd_v3_v3fl(result, proj, flat);
+ }
+ break;
+ }
+ case PART_KINK_BRAID:
+ {
+ float y_vec[3] = {0.f, 1.f, 0.f};
+ float z_vec[3] = {0.f, 0.f, 1.f};
+ float vec_one[3], state_co[3];
+ float inp_y, inp_z, length;
+
+ if (par_rot) {
+ mul_qt_v3(par_rot, y_vec);
+ mul_qt_v3(par_rot, z_vec);
+ }
+
+ negate_v3(par_vec);
+ normalize_v3_v3(vec_one, par_vec);
+
+ inp_y = dot_v3v3(y_vec, vec_one);
+ inp_z = dot_v3v3(z_vec, vec_one);
+
+ if (inp_y > 0.5f) {
+ copy_v3_v3(state_co, y_vec);
+
+ mul_v3_fl(y_vec, amplitude * cosf(t));
+ mul_v3_fl(z_vec, amplitude / 2.f * sinf(2.f * t));
+ }
+ else if (inp_z > 0.0f) {
+ mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.f));
+ madd_v3_v3fl(state_co, y_vec, -0.5f);
+
+ mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.f));
+ mul_v3_fl(z_vec, amplitude / 2.f * cosf(2.f * t + (float)M_PI / 6.f));
+ }
+ else {
+ mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.f));
+ madd_v3_v3fl(state_co, y_vec, -0.5f);
+
+ mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.f));
+ mul_v3_fl(z_vec, amplitude / 2.f * -sinf(2.f * t + (float)M_PI / 3.f));
+ }
+
+ mul_v3_fl(state_co, amplitude);
+ add_v3_v3(state_co, par_co);
+ sub_v3_v3v3(par_vec, state->co, state_co);
+
+ length = normalize_v3(par_vec);
+ mul_v3_fl(par_vec, MIN2(length, amplitude / 2.f));
+
+ add_v3_v3v3(state_co, par_co, y_vec);
+ add_v3_v3(state_co, z_vec);
+ add_v3_v3(state_co, par_vec);
+
+ shape = 2.f * (float)M_PI * (1.f + shape);
+
+ if (t < shape) {
+ shape = t / shape;
+ shape = (float)sqrt((double)shape);
+ interp_v3_v3v3(result, result, state_co, shape);
+ }
+ else {
+ copy_v3_v3(result, state_co);
+ }
+ break;
+ }
+ }
+
+ /* blend the start of the kink */
+ if (dt < 1.f)
+ interp_v3_v3v3(state->co, state->co, result, dt);
+ else
+ copy_v3_v3(state->co, result);
+}
+
+static float do_clump_level(float result[3], const float co[3], const float par_co[3], float time,
+ float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve)
+{
+ float clump = 0.0f;
+
+ if (clumpcurve) {
+ clump = pa_clump * (1.0f - CLAMPIS(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f));
+
+ interp_v3_v3v3(result, co, par_co, clump);
+ }
+ else if (clumpfac != 0.0f) {
+ float cpow;
+
+ if (clumppow < 0.0f)
+ cpow = 1.0f + clumppow;
+ else
+ cpow = 1.0f + 9.0f * clumppow;
+
+ if (clumpfac < 0.0f) /* clump roots instead of tips */
+ clump = -clumpfac * pa_clump * (float)pow(1.0 - (double)time, (double)cpow);
+ else
+ clump = clumpfac * pa_clump * (float)pow((double)time, (double)cpow);
+
+ interp_v3_v3v3(result, co, par_co, clump);
+ }
+
+ return clump;
+}
+
+float do_clump(ParticleKey *state, const float par_co[3], float time, const float orco_offset[3], float clumpfac, float clumppow, float pa_clump,
+ bool use_clump_noise, float clump_noise_size, CurveMapping *clumpcurve)
+{
+ float clump;
+
+ if (use_clump_noise && clump_noise_size != 0.0f) {
+ float center[3], noisevec[3];
+ float da[4], pa[12];
+
+ mul_v3_v3fl(noisevec, orco_offset, 1.0f / clump_noise_size);
+ voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0);
+ mul_v3_fl(&pa[0], clump_noise_size);
+ add_v3_v3v3(center, par_co, &pa[0]);
+
+ do_clump_level(state->co, state->co, center, time, clumpfac, clumppow, pa_clump, clumpcurve);
+ }
+
+ clump = do_clump_level(state->co, state->co, par_co, time, clumpfac, clumppow, pa_clump, clumpcurve);
+
+ return clump;
+}
+
+static void do_rough(const float loc[3], float mat[4][4], float t, float fac, float size, float thres, ParticleKey *state)
+{
+ float rough[3];
+ float rco[3];
+
+ if (thres != 0.0f) {
+ if (fabsf((float)(-1.5f + loc[0] + loc[1] + loc[2])) < 1.5f * thres) {
+ return;
+ }
+ }
+
+ copy_v3_v3(rco, loc);
+ mul_v3_fl(rco, t);
+ rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
+ rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
+ rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
+
+ madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
+ madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
+ madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
+}
+
+static void do_rough_end(const float loc[3], float mat[4][4], float t, float fac, float shape, ParticleKey *state)
+{
+ float rough[2];
+ float roughfac;
+
+ roughfac = fac * (float)pow((double)t, shape);
+ copy_v2_v2(rough, loc);
+ rough[0] = -1.0f + 2.0f * rough[0];
+ rough[1] = -1.0f + 2.0f * rough[1];
+ mul_v2_fl(rough, roughfac);
+
+ madd_v3_v3fl(state->co, mat[0], rough[0]);
+ madd_v3_v3fl(state->co, mat[1], rough[1]);
+}
+
+static void do_rough_curve(const float loc[3], float mat[4][4], float time, float fac, float size, CurveMapping *roughcurve, ParticleKey *state)
+{
+ float rough[3];
+ float rco[3];
+
+ if (!roughcurve)
+ return;
+
+ fac *= CLAMPIS(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f);
+
+ copy_v3_v3(rco, loc);
+ mul_v3_fl(rco, time);
+ rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
+ rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
+ rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
+
+ madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
+ madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
+ madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
+}
+
+void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *ptex, const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3],
+ ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t)
+{
+ ParticleSettings *part = sim->psys->part;
+ CurveMapping *clumpcurve = (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) ? part->clumpcurve : NULL;
+ CurveMapping *roughcurve = (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) ? part->roughcurve : NULL;
+ int i = cpa - sim->psys->child;
+ int guided = 0;
+
+ float kink_amp = part->kink_amp;
+ float kink_amp_clump = part->kink_amp_clump;
+ float kink_freq = part->kink_freq;
+ float rough1 = part->rough1;
+ float rough2 = part->rough2;
+ float rough_end = part->rough_end;
+ const bool smooth_start = (sim->psys->part->childtype == PART_CHILD_FACES);
+
+ if (ptex) {
+ kink_amp *= ptex->kink_amp;
+ kink_freq *= ptex->kink_freq;
+ rough1 *= ptex->rough1;
+ rough2 *= ptex->rough2;
+ rough_end *= ptex->roughe;
+ }
+
+ if (part->flag & PART_CHILD_EFFECT)
+ /* state is safe to cast, since only co and vel are used */
+ guided = do_guides(sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t);
+
+ if (guided == 0) {
+ float orco_offset[3];
+ float clump;
+
+ sub_v3_v3v3(orco_offset, orco, par_orco);
+ clump = do_clump(state, par_co, t, orco_offset, part->clumpfac, part->clumppow, ptex ? ptex->clump : 1.f,
+ part->child_flag & PART_CHILD_USE_CLUMP_NOISE, part->clump_noise_size, clumpcurve);
+
+ if (kink_freq != 0.f) {
+ kink_amp *= (1.f - kink_amp_clump * clump);
+
+ do_kink(state, par_co, par_vel, par_rot, t, kink_freq, part->kink_shape,
+ kink_amp, part->kink_flat, part->kink, part->kink_axis,
+ sim->ob->obmat, smooth_start);
+ }
+ }
+
+ if (roughcurve) {
+ do_rough_curve(orco, mat, t, rough1, part->rough1_size, roughcurve, state);
+ }
+ else {
+ if (rough1 > 0.f)
+ do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
+
+ if (rough2 > 0.f) {
+ float vec[3];
+ psys_frand_vec(sim->psys, i + 27, vec);
+ do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
+ }
+
+ if (rough_end > 0.f) {
+ float vec[3];
+ psys_frand_vec(sim->psys, i + 27, vec);
+ do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
new file mode 100644
index 00000000000..245c2432105
--- /dev/null
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -0,0 +1,1417 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by Janne Karhu.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Raul Fernandez Hernandez (Farsthary),
+ * Stephen Swhitehorn,
+ * Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/particle_distribute.c
+ * \ingroup bke
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_jitter.h"
+#include "BLI_kdtree.h"
+#include "BLI_math.h"
+#include "BLI_rand.h"
+#include "BLI_sort.h"
+#include "BLI_task.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_particle_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_mesh.h"
+#include "BKE_object.h"
+#include "BKE_particle.h"
+
+static int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot);
+
+static void alloc_child_particles(ParticleSystem *psys, int tot)
+{
+ if (psys->child) {
+ /* only re-allocate if we have to */
+ if (psys->part->childtype && psys->totchild == tot) {
+ memset(psys->child, 0, tot*sizeof(ChildParticle));
+ return;
+ }
+
+ MEM_freeN(psys->child);
+ psys->child=NULL;
+ psys->totchild=0;
+ }
+
+ if (psys->part->childtype) {
+ psys->totchild= tot;
+ if (psys->totchild)
+ psys->child= MEM_callocN(psys->totchild*sizeof(ChildParticle), "child_particles");
+ }
+}
+
+static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, ParticleSystem *psys)
+{
+ ChildParticle *cpa = NULL;
+ int i, p;
+ int child_nbr= psys_get_child_number(scene, psys);
+ int totpart= psys_get_tot_child(scene, psys);
+
+ alloc_child_particles(psys, totpart);
+
+ cpa = psys->child;
+ for (i=0; i<child_nbr; i++) {
+ for (p=0; p<psys->totpart; p++,cpa++) {
+ float length=2.0;
+ cpa->parent=p;
+
+ /* create even spherical distribution inside unit sphere */
+ while (length>=1.0f) {
+ cpa->fuv[0]=2.0f*BLI_frand()-1.0f;
+ cpa->fuv[1]=2.0f*BLI_frand()-1.0f;
+ cpa->fuv[2]=2.0f*BLI_frand()-1.0f;
+ length=len_v3(cpa->fuv);
+ }
+
+ cpa->num=-1;
+ }
+ }
+ /* dmcache must be updated for parent particles if children from faces is used */
+ psys_calc_dmcache(ob, finaldm, psys);
+}
+static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
+{
+ ParticleData *pa=NULL;
+ float min[3], max[3], delta[3], d;
+ MVert *mv, *mvert = dm->getVertDataArray(dm,0);
+ int totvert=dm->getNumVerts(dm), from=psys->part->from;
+ int i, j, k, p, res=psys->part->grid_res, size[3], axis;
+
+ /* find bounding box of dm */
+ if (totvert > 0) {
+ mv=mvert;
+ copy_v3_v3(min, mv->co);
+ copy_v3_v3(max, mv->co);
+ mv++;
+ for (i = 1; i < totvert; i++, mv++) {
+ minmax_v3v3_v3(min, max, mv->co);
+ }
+ }
+ else {
+ zero_v3(min);
+ zero_v3(max);
+ }
+
+ sub_v3_v3v3(delta, max, min);
+
+ /* determine major axis */
+ axis = axis_dominant_v3_single(delta);
+
+ d = delta[axis]/(float)res;
+
+ size[axis] = res;
+ size[(axis+1)%3] = (int)ceil(delta[(axis+1)%3]/d);
+ size[(axis+2)%3] = (int)ceil(delta[(axis+2)%3]/d);
+
+ /* float errors grrr.. */
+ size[(axis+1)%3] = MIN2(size[(axis+1)%3],res);
+ size[(axis+2)%3] = MIN2(size[(axis+2)%3],res);
+
+ size[0] = MAX2(size[0], 1);
+ size[1] = MAX2(size[1], 1);
+ size[2] = MAX2(size[2], 1);
+
+ /* no full offset for flat/thin objects */
+ min[0]+= d < delta[0] ? d/2.f : delta[0]/2.f;
+ min[1]+= d < delta[1] ? d/2.f : delta[1]/2.f;
+ min[2]+= d < delta[2] ? d/2.f : delta[2]/2.f;
+
+ for (i=0,p=0,pa=psys->particles; i<res; i++) {
+ for (j=0; j<res; j++) {
+ for (k=0; k<res; k++,p++,pa++) {
+ pa->fuv[0] = min[0] + (float)i*d;
+ pa->fuv[1] = min[1] + (float)j*d;
+ pa->fuv[2] = min[2] + (float)k*d;
+ pa->flag |= PARS_UNEXIST;
+ pa->hair_index = 0; /* abused in volume calculation */
+ }
+ }
+ }
+
+ /* enable particles near verts/edges/faces/inside surface */
+ if (from==PART_FROM_VERT) {
+ float vec[3];
+
+ pa=psys->particles;
+
+ min[0] -= d/2.0f;
+ min[1] -= d/2.0f;
+ min[2] -= d/2.0f;
+
+ for (i=0,mv=mvert; i<totvert; i++,mv++) {
+ sub_v3_v3v3(vec,mv->co,min);
+ vec[0]/=delta[0];
+ vec[1]/=delta[1];
+ vec[2]/=delta[2];
+ pa[((int)(vec[0] * (size[0] - 1)) * res +
+ (int)(vec[1] * (size[1] - 1))) * res +
+ (int)(vec[2] * (size[2] - 1))].flag &= ~PARS_UNEXIST;
+ }
+ }
+ else if (ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
+ float co1[3], co2[3];
+
+ MFace *mface= NULL, *mface_array;
+ float v1[3], v2[3], v3[3], v4[4], lambda;
+ int a, a1, a2, a0mul, a1mul, a2mul, totface;
+ int amax= from==PART_FROM_FACE ? 3 : 1;
+
+ totface=dm->getNumTessFaces(dm);
+ mface=mface_array=dm->getTessFaceDataArray(dm,CD_MFACE);
+
+ for (a=0; a<amax; a++) {
+ if (a==0) { a0mul=res*res; a1mul=res; a2mul=1; }
+ else if (a==1) { a0mul=res; a1mul=1; a2mul=res*res; }
+ else { a0mul=1; a1mul=res*res; a2mul=res; }
+
+ for (a1=0; a1<size[(a+1)%3]; a1++) {
+ for (a2=0; a2<size[(a+2)%3]; a2++) {
+ mface= mface_array;
+
+ pa = psys->particles + a1*a1mul + a2*a2mul;
+ copy_v3_v3(co1, pa->fuv);
+ co1[a] -= d < delta[a] ? d/2.f : delta[a]/2.f;
+ copy_v3_v3(co2, co1);
+ co2[a] += delta[a] + 0.001f*d;
+ co1[a] -= 0.001f*d;
+
+ /* lets intersect the faces */
+ for (i=0; i<totface; i++,mface++) {
+ copy_v3_v3(v1, mvert[mface->v1].co);
+ copy_v3_v3(v2, mvert[mface->v2].co);
+ copy_v3_v3(v3, mvert[mface->v3].co);
+
+ if (isect_axial_line_tri_v3(a, co1, co2, v2, v3, v1, &lambda)) {
+ if (from==PART_FROM_FACE)
+ (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
+ else /* store number of intersections */
+ (pa+(int)(lambda*size[a])*a0mul)->hair_index++;
+ }
+ else if (mface->v4) {
+ copy_v3_v3(v4, mvert[mface->v4].co);
+
+ if (isect_axial_line_tri_v3(a, co1, co2, v4, v1, v3, &lambda)) {
+ if (from==PART_FROM_FACE)
+ (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
+ else
+ (pa+(int)(lambda*size[a])*a0mul)->hair_index++;
+ }
+ }
+ }
+
+ if (from==PART_FROM_VOLUME) {
+ int in=pa->hair_index%2;
+ if (in) pa->hair_index++;
+ for (i=0; i<size[0]; i++) {
+ if (in || (pa+i*a0mul)->hair_index%2)
+ (pa+i*a0mul)->flag &= ~PARS_UNEXIST;
+ /* odd intersections == in->out / out->in */
+ /* even intersections -> in stays same */
+ in=(in + (pa+i*a0mul)->hair_index) % 2;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (psys->part->flag & PART_GRID_HEXAGONAL) {
+ for (i=0,p=0,pa=psys->particles; i<res; i++) {
+ for (j=0; j<res; j++) {
+ for (k=0; k<res; k++,p++,pa++) {
+ if (j%2)
+ pa->fuv[0] += d/2.f;
+
+ if (k%2) {
+ pa->fuv[0] += d/2.f;
+ pa->fuv[1] += d/2.f;
+ }
+ }
+ }
+ }
+ }
+
+ if (psys->part->flag & PART_GRID_INVERT) {
+ for (i=0; i<size[0]; i++) {
+ for (j=0; j<size[1]; j++) {
+ pa=psys->particles + res*(i*res + j);
+ for (k=0; k<size[2]; k++, pa++) {
+ pa->flag ^= PARS_UNEXIST;
+ }
+ }
+ }
+ }
+
+ if (psys->part->grid_rand > 0.f) {
+ float rfac = d * psys->part->grid_rand;
+ for (p=0,pa=psys->particles; p<psys->totpart; p++,pa++) {
+ if (pa->flag & PARS_UNEXIST)
+ continue;
+
+ pa->fuv[0] += rfac * (psys_frand(psys, p + 31) - 0.5f);
+ pa->fuv[1] += rfac * (psys_frand(psys, p + 32) - 0.5f);
+ pa->fuv[2] += rfac * (psys_frand(psys, p + 33) - 0.5f);
+ }
+ }
+}
+
+/* modified copy from rayshade.c */
+static void hammersley_create(float *out, int n, int seed, float amount)
+{
+ RNG *rng;
+ double p, t, offs[2];
+ int k, kk;
+
+ rng = BLI_rng_new(31415926 + n + seed);
+ offs[0] = BLI_rng_get_double(rng) + (double)amount;
+ offs[1] = BLI_rng_get_double(rng) + (double)amount;
+ BLI_rng_free(rng);
+
+ for (k = 0; k < n; k++) {
+ t = 0;
+ for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1)
+ if (kk & 1) /* kk mod 2 = 1 */
+ t += p;
+
+ out[2*k + 0] = fmod((double)k/(double)n + offs[0], 1.0);
+ out[2*k + 1] = fmod(t + offs[1], 1.0);
+ }
+}
+
+/* almost exact copy of BLI_jitter_init */
+static void init_mv_jit(float *jit, int num, int seed2, float amount)
+{
+ RNG *rng;
+ float *jit2, x, rad1, rad2, rad3;
+ int i, num2;
+
+ if (num==0) return;
+
+ rad1= (float)(1.0f/sqrtf((float)num));
+ rad2= (float)(1.0f/((float)num));
+ rad3= (float)sqrtf((float)num)/((float)num);
+
+ rng = BLI_rng_new(31415926 + num + seed2);
+ x= 0;
+ num2 = 2 * num;
+ for (i=0; i<num2; i+=2) {
+
+ jit[i] = x + amount*rad1*(0.5f - BLI_rng_get_float(rng));
+ jit[i+1] = i/(2.0f*num) + amount*rad1*(0.5f - BLI_rng_get_float(rng));
+
+ jit[i]-= (float)floor(jit[i]);
+ jit[i+1]-= (float)floor(jit[i+1]);
+
+ x+= rad3;
+ x -= (float)floor(x);
+ }
+
+ jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
+
+ for (i=0 ; i<4 ; i++) {
+ BLI_jitterate1((float (*)[2])jit, (float (*)[2])jit2, num, rad1);
+ BLI_jitterate1((float (*)[2])jit, (float (*)[2])jit2, num, rad1);
+ BLI_jitterate2((float (*)[2])jit, (float (*)[2])jit2, num, rad2);
+ }
+ MEM_freeN(jit2);
+ BLI_rng_free(rng);
+}
+
+static void psys_uv_to_w(float u, float v, int quad, float *w)
+{
+ float vert[4][3], co[3];
+
+ if (!quad) {
+ if (u+v > 1.0f)
+ v= 1.0f-v;
+ else
+ u= 1.0f-u;
+ }
+
+ vert[0][0] = 0.0f; vert[0][1] = 0.0f; vert[0][2] = 0.0f;
+ vert[1][0] = 1.0f; vert[1][1] = 0.0f; vert[1][2] = 0.0f;
+ vert[2][0] = 1.0f; vert[2][1] = 1.0f; vert[2][2] = 0.0f;
+
+ co[0] = u;
+ co[1] = v;
+ co[2] = 0.0f;
+
+ if (quad) {
+ vert[3][0] = 0.0f; vert[3][1] = 1.0f; vert[3][2] = 0.0f;
+ interp_weights_poly_v3( w,vert, 4, co);
+ }
+ else {
+ interp_weights_poly_v3( w,vert, 3, co);
+ w[3] = 0.0f;
+ }
+}
+
+/* Find the index in "sum" array before "value" is crossed. */
+static int distribute_binary_search(float *sum, int n, float value)
+{
+ int mid, low=0, high=n;
+
+ if (value == 0.f)
+ return 0;
+
+ while (low <= high) {
+ mid= (low + high)/2;
+
+ if (sum[mid] < value && value <= sum[mid+1])
+ return mid;
+
+ if (sum[mid] >= value)
+ high= mid - 1;
+ else if (sum[mid] < value)
+ low= mid + 1;
+ else
+ return mid;
+ }
+
+ return low;
+}
+
+/* the max number if calls to rng_* funcs within psys_thread_distribute_particle
+ * be sure to keep up to date if this changes */
+#define PSYS_RND_DIST_SKIP 2
+
+/* note: this function must be thread safe, for from == PART_FROM_CHILD */
+#define ONLY_WORKING_WITH_PA_VERTS 0
+static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, int p)
+{
+ ParticleThreadContext *ctx= thread->ctx;
+ int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
+
+ /* TODO_PARTICLE - use original index */
+ pa->num= ctx->index[p];
+ pa->fuv[0] = 1.0f;
+ pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
+
+#if ONLY_WORKING_WITH_PA_VERTS
+ if (ctx->tree) {
+ KDTreeNearest ptn[3];
+ int w, maxw;
+
+ psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
+ BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1);
+ maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3);
+
+ for (w=0; w<maxw; w++) {
+ pa->verts[w]=ptn->num;
+ }
+ }
+#endif
+
+ if (rng_skip_tot > 0) /* should never be below zero */
+ BLI_rng_skip(thread->rng, rng_skip_tot);
+}
+
+static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, int p) {
+ ParticleThreadContext *ctx= thread->ctx;
+ DerivedMesh *dm= ctx->dm;
+ float randu, randv;
+ int distr= ctx->distr;
+ int i;
+ int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
+
+ MFace *mface;
+
+ pa->num = i = ctx->index[p];
+ mface = dm->getTessFaceData(dm,i,CD_MFACE);
+
+ switch (distr) {
+ case PART_DISTR_JIT:
+ if (ctx->jitlevel == 1) {
+ if (mface->v4)
+ psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv);
+ else
+ psys_uv_to_w(1.0f / 3.0f, 1.0f / 3.0f, mface->v4, pa->fuv);
+ }
+ else {
+ float offset = fmod(ctx->jitoff[i] + (float)p, (float)ctx->jitlevel);
+ if (!isnan(offset)) {
+ psys_uv_to_w(ctx->jit[2*(int)offset], ctx->jit[2*(int)offset+1], mface->v4, pa->fuv);
+ }
+ }
+ break;
+ case PART_DISTR_RAND:
+ randu= BLI_rng_get_float(thread->rng);
+ randv= BLI_rng_get_float(thread->rng);
+ rng_skip_tot -= 2;
+
+ psys_uv_to_w(randu, randv, mface->v4, pa->fuv);
+ break;
+ }
+ pa->foffset= 0.0f;
+
+ if (rng_skip_tot > 0) /* should never be below zero */
+ BLI_rng_skip(thread->rng, rng_skip_tot);
+}
+
+static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, int p) {
+ ParticleThreadContext *ctx= thread->ctx;
+ DerivedMesh *dm= ctx->dm;
+ float *v1, *v2, *v3, *v4, nor[3], co1[3], co2[3];
+ float cur_d, min_d, randu, randv;
+ int distr= ctx->distr;
+ int i, intersect, tot;
+ int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
+
+ MFace *mface;
+ MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
+
+ pa->num = i = ctx->index[p];
+ mface = dm->getTessFaceData(dm,i,CD_MFACE);
+
+ switch (distr) {
+ case PART_DISTR_JIT:
+ if (ctx->jitlevel == 1) {
+ if (mface->v4)
+ psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv);
+ else
+ psys_uv_to_w(1.0f / 3.0f, 1.0f / 3.0f, mface->v4, pa->fuv);
+ }
+ else {
+ float offset = fmod(ctx->jitoff[i] + (float)p, (float)ctx->jitlevel);
+ if (!isnan(offset)) {
+ psys_uv_to_w(ctx->jit[2*(int)offset], ctx->jit[2*(int)offset+1], mface->v4, pa->fuv);
+ }
+ }
+ break;
+ case PART_DISTR_RAND:
+ randu= BLI_rng_get_float(thread->rng);
+ randv= BLI_rng_get_float(thread->rng);
+ rng_skip_tot -= 2;
+
+ psys_uv_to_w(randu, randv, mface->v4, pa->fuv);
+ break;
+ }
+ pa->foffset= 0.0f;
+
+ /* experimental */
+ tot=dm->getNumTessFaces(dm);
+
+ psys_interpolate_face(mvert,mface,0,0,pa->fuv,co1,nor,0,0,0,0);
+
+ normalize_v3(nor);
+ mul_v3_fl(nor,-100.0);
+
+ add_v3_v3v3(co2,co1,nor);
+
+ min_d=2.0;
+ intersect=0;
+
+ for (i=0,mface=dm->getTessFaceDataArray(dm,CD_MFACE); i<tot; i++,mface++) {
+ if (i==pa->num) continue;
+
+ v1=mvert[mface->v1].co;
+ v2=mvert[mface->v2].co;
+ v3=mvert[mface->v3].co;
+
+ if (isect_line_tri_v3(co1, co2, v2, v3, v1, &cur_d, 0)) {
+ if (cur_d<min_d) {
+ min_d=cur_d;
+ pa->foffset=cur_d*50.0f; /* to the middle of volume */
+ intersect=1;
+ }
+ }
+ if (mface->v4) {
+ v4=mvert[mface->v4].co;
+
+ if (isect_line_tri_v3(co1, co2, v4, v1, v3, &cur_d, 0)) {
+ if (cur_d<min_d) {
+ min_d=cur_d;
+ pa->foffset=cur_d*50.0f; /* to the middle of volume */
+ intersect=1;
+ }
+ }
+ }
+ }
+ if (intersect==0)
+ pa->foffset=0.0;
+ else {
+ switch (distr) {
+ case PART_DISTR_JIT:
+ pa->foffset *= ctx->jit[p % (2 * ctx->jitlevel)];
+ break;
+ case PART_DISTR_RAND:
+ pa->foffset *= BLI_frand();
+ break;
+ }
+ }
+
+ if (rng_skip_tot > 0) /* should never be below zero */
+ BLI_rng_skip(thread->rng, rng_skip_tot);
+}
+
+static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, int p) {
+ ParticleThreadContext *ctx= thread->ctx;
+ Object *ob= ctx->sim.ob;
+ DerivedMesh *dm= ctx->dm;
+ float orco1[3], co1[3], nor1[3];
+ float randu, randv;
+ int cfrom= ctx->cfrom;
+ int i;
+ int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
+
+ MFace *mf;
+
+ if (ctx->index[p] < 0) {
+ cpa->num=0;
+ cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]=0.0f;
+ cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
+ return;
+ }
+
+ mf= dm->getTessFaceData(dm, ctx->index[p], CD_MFACE);
+
+ randu= BLI_rng_get_float(thread->rng);
+ randv= BLI_rng_get_float(thread->rng);
+ rng_skip_tot -= 2;
+
+ psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
+
+ cpa->num = ctx->index[p];
+
+ if (ctx->tree) {
+ KDTreeNearest ptn[10];
+ int w,maxw;//, do_seams;
+ float maxd /*, mind,dd */, totw= 0.0f;
+ int parent[10];
+ float pweight[10];
+
+ psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1,NULL);
+ BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1);
+ maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3);
+
+ maxd=ptn[maxw-1].dist;
+ /* mind=ptn[0].dist; */ /* UNUSED */
+
+ /* the weights here could be done better */
+ for (w=0; w<maxw; w++) {
+ parent[w]=ptn[w].index;
+ pweight[w]=(float)pow(2.0,(double)(-6.0f*ptn[w].dist/maxd));
+ }
+ for (;w<10; w++) {
+ parent[w]=-1;
+ pweight[w]=0.0f;
+ }
+
+ for (w=0,i=0; w<maxw && i<4; w++) {
+ if (parent[w]>=0) {
+ cpa->pa[i]=parent[w];
+ cpa->w[i]=pweight[w];
+ totw+=pweight[w];
+ i++;
+ }
+ }
+ for (;i<4; i++) {
+ cpa->pa[i]=-1;
+ cpa->w[i]=0.0f;
+ }
+
+ if (totw > 0.0f) {
+ for (w = 0; w < 4; w++) {
+ cpa->w[w] /= totw;
+ }
+ }
+
+ cpa->parent=cpa->pa[0];
+ }
+
+ if (rng_skip_tot > 0) /* should never be below zero */
+ BLI_rng_skip(thread->rng, rng_skip_tot);
+}
+
+static void exec_distribute_parent(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(threadid))
+{
+ ParticleTask *task = taskdata;
+ ParticleSystem *psys= task->ctx->sim.psys;
+ ParticleData *pa;
+ int p;
+
+ pa= psys->particles + task->begin;
+ switch (psys->part->from) {
+ case PART_FROM_FACE:
+ for (p = task->begin; p < task->end; ++p, ++pa)
+ distribute_from_faces_exec(task, pa, p);
+ break;
+ case PART_FROM_VOLUME:
+ for (p = task->begin; p < task->end; ++p, ++pa)
+ distribute_from_volume_exec(task, pa, p);
+ break;
+ case PART_FROM_VERT:
+ for (p = task->begin; p < task->end; ++p, ++pa)
+ distribute_from_verts_exec(task, pa, p);
+ break;
+ }
+}
+
+static void exec_distribute_child(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(threadid))
+{
+ ParticleTask *task = taskdata;
+ ParticleSystem *psys = task->ctx->sim.psys;
+ ChildParticle *cpa;
+ int p;
+
+ /* RNG skipping at the beginning */
+ cpa = psys->child;
+ for (p = 0; p < task->begin; ++p, ++cpa) {
+ if (task->ctx->skip) /* simplification skip */
+ BLI_rng_skip(task->rng, PSYS_RND_DIST_SKIP * task->ctx->skip[p]);
+
+ BLI_rng_skip(task->rng, PSYS_RND_DIST_SKIP);
+ }
+
+ for (; p < task->end; ++p, ++cpa) {
+ if (task->ctx->skip) /* simplification skip */
+ BLI_rng_skip(task->rng, PSYS_RND_DIST_SKIP * task->ctx->skip[p]);
+
+ distribute_children_exec(task, cpa, p);
+ }
+}
+
+static int distribute_compare_orig_index(const void *p1, const void *p2, void *user_data)
+{
+ int *orig_index = (int *) user_data;
+ int index1 = orig_index[*(const int *)p1];
+ int index2 = orig_index[*(const int *)p2];
+
+ if (index1 < index2)
+ return -1;
+ else if (index1 == index2) {
+ /* this pointer comparison appears to make qsort stable for glibc,
+ * and apparently on solaris too, makes the renders reproducible */
+ if (p1 < p2)
+ return -1;
+ else if (p1 == p2)
+ return 0;
+ else
+ return 1;
+ }
+ else
+ return 1;
+}
+
+static void distribute_invalid(Scene *scene, ParticleSystem *psys, int from)
+{
+ if (from == PART_FROM_CHILD) {
+ ChildParticle *cpa;
+ int p, totchild = psys_get_tot_child(scene, psys);
+
+ if (psys->child && totchild) {
+ for (p=0,cpa=psys->child; p<totchild; p++,cpa++) {
+ cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3] = 0.0;
+ cpa->foffset= 0.0f;
+ cpa->parent=0;
+ cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
+ cpa->num= -1;
+ }
+ }
+ }
+ else {
+ PARTICLE_P;
+ LOOP_PARTICLES {
+ pa->fuv[0] = pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
+ pa->foffset= 0.0f;
+ pa->num= -1;
+ }
+ }
+}
+
+/* Creates a distribution of coordinates on a DerivedMesh */
+/* This is to denote functionality that does not yet work with mesh - only derived mesh */
+static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, ParticleSimulationData *sim, int from)
+{
+ Scene *scene = sim->scene;
+ DerivedMesh *finaldm = sim->psmd->dm;
+ Object *ob = sim->ob;
+ ParticleSystem *psys= sim->psys;
+ ParticleData *pa=0, *tpars= 0;
+ ParticleSettings *part;
+ ParticleSeam *seams= 0;
+ KDTree *tree=0;
+ DerivedMesh *dm= NULL;
+ float *jit= NULL;
+ int i, p=0;
+ int cfrom=0;
+ int totelem=0, totpart, *particle_element=0, children=0, totseam=0;
+ int jitlevel= 1, distr;
+ float *element_weight=NULL,*element_sum=NULL,*jitter_offset=NULL, *vweight=NULL;
+ float cur, maxweight=0.0, tweight, totweight, inv_totweight, co[3], nor[3], orco[3];
+
+ if (ELEM(NULL, ob, psys, psys->part))
+ return 0;
+
+ part=psys->part;
+ totpart=psys->totpart;
+ if (totpart==0)
+ return 0;
+
+ if (!finaldm->deformedOnly && !finaldm->getTessFaceDataArray(finaldm, CD_ORIGINDEX)) {
+ printf("Can't create particles with the current modifier stack, disable destructive modifiers\n");
+// XXX error("Can't paint with the current modifier stack, disable destructive modifiers");
+ return 0;
+ }
+
+ psys_thread_context_init(ctx, sim);
+
+ /* First handle special cases */
+ if (from == PART_FROM_CHILD) {
+ /* Simple children */
+ if (part->childtype != PART_CHILD_FACES) {
+ BLI_srandom(31415926 + psys->seed + psys->child_seed);
+ distribute_simple_children(scene, ob, finaldm, psys);
+ return 0;
+ }
+ }
+ else {
+ /* Grid distribution */
+ if (part->distr==PART_DISTR_GRID && from != PART_FROM_VERT) {
+ BLI_srandom(31415926 + psys->seed);
+ dm= CDDM_from_mesh((Mesh*)ob->data);
+ DM_ensure_tessface(dm);
+ distribute_grid(dm,psys);
+ dm->release(dm);
+ return 0;
+ }
+ }
+
+ /* Create trees and original coordinates if needed */
+ if (from == PART_FROM_CHILD) {
+ distr=PART_DISTR_RAND;
+ BLI_srandom(31415926 + psys->seed + psys->child_seed);
+ dm= finaldm;
+
+ /* BMESH ONLY */
+ DM_ensure_tessface(dm);
+
+ children=1;
+
+ tree=BLI_kdtree_new(totpart);
+
+ for (p=0,pa=psys->particles; p<totpart; p++,pa++) {
+ psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,NULL);
+ BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco, 1, 1);
+ BLI_kdtree_insert(tree, p, orco);
+ }
+
+ BLI_kdtree_balance(tree);
+
+ totpart = psys_get_tot_child(scene, psys);
+ cfrom = from = PART_FROM_FACE;
+ }
+ else {
+ distr = part->distr;
+ BLI_srandom(31415926 + psys->seed);
+
+ if (psys->part->use_modifier_stack)
+ dm = finaldm;
+ else
+ dm= CDDM_from_mesh((Mesh*)ob->data);
+
+ /* BMESH ONLY, for verts we don't care about tessfaces */
+ if (from != PART_FROM_VERT) {
+ DM_ensure_tessface(dm);
+ }
+
+ /* we need orco for consistent distributions */
+ if (!CustomData_has_layer(&dm->vertData, CD_ORCO))
+ DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob));
+
+ if (from == PART_FROM_VERT) {
+ MVert *mv= dm->getVertDataArray(dm, CD_MVERT);
+ float (*orcodata)[3] = dm->getVertDataArray(dm, CD_ORCO);
+ int totvert = dm->getNumVerts(dm);
+
+ tree=BLI_kdtree_new(totvert);
+
+ for (p=0; p<totvert; p++) {
+ if (orcodata) {
+ copy_v3_v3(co,orcodata[p]);
+ BKE_mesh_orco_verts_transform((Mesh*)ob->data, &co, 1, 1);
+ }
+ else
+ copy_v3_v3(co,mv[p].co);
+ BLI_kdtree_insert(tree, p, co);
+ }
+
+ BLI_kdtree_balance(tree);
+ }
+ }
+
+ /* Get total number of emission elements and allocate needed arrays */
+ totelem = (from == PART_FROM_VERT) ? dm->getNumVerts(dm) : dm->getNumTessFaces(dm);
+
+ if (totelem == 0) {
+ distribute_invalid(scene, psys, children ? PART_FROM_CHILD : 0);
+
+ if (G.debug & G_DEBUG)
+ fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
+
+ if (dm != finaldm) dm->release(dm);
+
+ BLI_kdtree_free(tree);
+
+ return 0;
+ }
+
+ element_weight = MEM_callocN(sizeof(float)*totelem, "particle_distribution_weights");
+ particle_element= MEM_callocN(sizeof(int)*totpart, "particle_distribution_indexes");
+ element_sum = MEM_callocN(sizeof(float)*(totelem+1), "particle_distribution_sum");
+ jitter_offset = MEM_callocN(sizeof(float)*totelem, "particle_distribution_jitoff");
+
+ /* Calculate weights from face areas */
+ if ((part->flag&PART_EDISTR || children) && from != PART_FROM_VERT) {
+ MVert *v1, *v2, *v3, *v4;
+ float totarea=0.f, co1[3], co2[3], co3[3], co4[3];
+ float (*orcodata)[3];
+
+ orcodata= dm->getVertDataArray(dm, CD_ORCO);
+
+ for (i=0; i<totelem; i++) {
+ MFace *mf=dm->getTessFaceData(dm,i,CD_MFACE);
+
+ if (orcodata) {
+ copy_v3_v3(co1, orcodata[mf->v1]);
+ copy_v3_v3(co2, orcodata[mf->v2]);
+ copy_v3_v3(co3, orcodata[mf->v3]);
+ BKE_mesh_orco_verts_transform((Mesh*)ob->data, &co1, 1, 1);
+ BKE_mesh_orco_verts_transform((Mesh*)ob->data, &co2, 1, 1);
+ BKE_mesh_orco_verts_transform((Mesh*)ob->data, &co3, 1, 1);
+ if (mf->v4) {
+ copy_v3_v3(co4, orcodata[mf->v4]);
+ BKE_mesh_orco_verts_transform((Mesh*)ob->data, &co4, 1, 1);
+ }
+ }
+ else {
+ v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT);
+ v2= (MVert*)dm->getVertData(dm,mf->v2,CD_MVERT);
+ v3= (MVert*)dm->getVertData(dm,mf->v3,CD_MVERT);
+ copy_v3_v3(co1, v1->co);
+ copy_v3_v3(co2, v2->co);
+ copy_v3_v3(co3, v3->co);
+ if (mf->v4) {
+ v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT);
+ copy_v3_v3(co4, v4->co);
+ }
+ }
+
+ cur = mf->v4 ? area_quad_v3(co1, co2, co3, co4) : area_tri_v3(co1, co2, co3);
+
+ if (cur > maxweight)
+ maxweight = cur;
+
+ element_weight[i] = cur;
+ totarea += cur;
+ }
+
+ for (i=0; i<totelem; i++)
+ element_weight[i] /= totarea;
+
+ maxweight /= totarea;
+ }
+ else {
+ float min=1.0f/(float)(MIN2(totelem,totpart));
+ for (i=0; i<totelem; i++)
+ element_weight[i]=min;
+ maxweight=min;
+ }
+
+ /* Calculate weights from vgroup */
+ vweight = psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY);
+
+ if (vweight) {
+ if (from==PART_FROM_VERT) {
+ for (i=0;i<totelem; i++)
+ element_weight[i]*=vweight[i];
+ }
+ else { /* PART_FROM_FACE / PART_FROM_VOLUME */
+ for (i=0;i<totelem; i++) {
+ MFace *mf=dm->getTessFaceData(dm,i,CD_MFACE);
+ tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
+
+ if (mf->v4) {
+ tweight += vweight[mf->v4];
+ tweight /= 4.0f;
+ }
+ else {
+ tweight /= 3.0f;
+ }
+
+ element_weight[i]*=tweight;
+ }
+ }
+ MEM_freeN(vweight);
+ }
+
+ /* Calculate total weight of all elements */
+ totweight= 0.0f;
+ for (i=0;i<totelem; i++)
+ totweight += element_weight[i];
+
+ inv_totweight = (totweight > 0.f ? 1.f/totweight : 0.f);
+
+ /* Calculate cumulative weights */
+ element_sum[0] = 0.0f;
+ for (i=0; i<totelem; i++)
+ element_sum[i+1] = element_sum[i] + element_weight[i] * inv_totweight;
+
+ /* Finally assign elements to particles */
+ if ((part->flag&PART_TRAND) || (part->simplify_flag&PART_SIMPLIFY_ENABLE)) {
+ float pos;
+
+ for (p=0; p<totpart; p++) {
+ /* In theory element_sum[totelem] should be 1.0, but due to float errors this is not necessarily always true, so scale pos accordingly. */
+ pos= BLI_frand() * element_sum[totelem];
+ particle_element[p] = distribute_binary_search(element_sum, totelem, pos);
+ particle_element[p] = MIN2(totelem-1, particle_element[p]);
+ jitter_offset[particle_element[p]] = pos;
+ }
+ }
+ else {
+ double step, pos;
+
+ step= (totpart < 2) ? 0.5 : 1.0/(double)totpart;
+ pos= 1e-6; /* tiny offset to avoid zero weight face */
+ i= 0;
+
+ for (p=0; p<totpart; p++, pos+=step) {
+ while ((i < totelem) && (pos > (double)element_sum[i + 1]))
+ i++;
+
+ particle_element[p] = MIN2(totelem-1, i);
+
+ /* avoid zero weight face */
+ if (p == totpart-1 && element_weight[particle_element[p]] == 0.0f)
+ particle_element[p] = particle_element[p-1];
+
+ jitter_offset[particle_element[p]] = pos;
+ }
+ }
+
+ MEM_freeN(element_sum);
+
+ /* For hair, sort by origindex (allows optimization's in rendering), */
+ /* however with virtual parents the children need to be in random order. */
+ if (part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0f)) {
+ int *orig_index = NULL;
+
+ if (from == PART_FROM_VERT) {
+ if (dm->numVertData)
+ orig_index = dm->getVertDataArray(dm, CD_ORIGINDEX);
+ }
+ else {
+ if (dm->numTessFaceData)
+ orig_index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+ }
+
+ if (orig_index) {
+ BLI_qsort_r(particle_element, totpart, sizeof(int), distribute_compare_orig_index, orig_index);
+ }
+ }
+
+ /* Create jittering if needed */
+ if (distr==PART_DISTR_JIT && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
+ jitlevel= part->userjit;
+
+ if (jitlevel == 0) {
+ jitlevel= totpart/totelem;
+ if (part->flag & PART_EDISTR) jitlevel*= 2; /* looks better in general, not very scietific */
+ if (jitlevel<3) jitlevel= 3;
+ }
+
+ jit= MEM_callocN((2+ jitlevel*2)*sizeof(float), "jit");
+
+ /* for small amounts of particles we use regular jitter since it looks
+ * a bit better, for larger amounts we switch to hammersley sequence
+ * because it is much faster */
+ if (jitlevel < 25)
+ init_mv_jit(jit, jitlevel, psys->seed, part->jitfac);
+ else
+ hammersley_create(jit, jitlevel+1, psys->seed, part->jitfac);
+ BLI_array_randomize(jit, 2*sizeof(float), jitlevel, psys->seed); /* for custom jit or even distribution */
+ }
+
+ /* Setup things for threaded distribution */
+ ctx->tree= tree;
+ ctx->seams= seams;
+ ctx->totseam= totseam;
+ ctx->sim.psys= psys;
+ ctx->index= particle_element;
+ ctx->jit= jit;
+ ctx->jitlevel= jitlevel;
+ ctx->jitoff= jitter_offset;
+ ctx->weight= element_weight;
+ ctx->maxweight= maxweight;
+ ctx->cfrom= cfrom;
+ ctx->distr= distr;
+ ctx->dm= dm;
+ ctx->tpars= tpars;
+
+ if (children) {
+ totpart= psys_render_simplify_distribution(ctx, totpart);
+ alloc_child_particles(psys, totpart);
+ }
+
+ return 1;
+}
+
+static void psys_task_init_distribute(ParticleTask *task, ParticleSimulationData *sim)
+{
+ /* init random number generator */
+ int seed = 31415926 + sim->psys->seed;
+
+ task->rng = BLI_rng_new(seed);
+}
+
+static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
+{
+ TaskScheduler *task_scheduler;
+ TaskPool *task_pool;
+ ParticleThreadContext ctx;
+ ParticleTask *tasks;
+ DerivedMesh *finaldm = sim->psmd->dm;
+ int i, totpart, numtasks;
+
+ /* create a task pool for distribution tasks */
+ if (!psys_thread_context_init_distribute(&ctx, sim, from))
+ return;
+
+ task_scheduler = BLI_task_scheduler_get();
+ task_pool = BLI_task_pool_create(task_scheduler, &ctx);
+
+ totpart = (from == PART_FROM_CHILD ? sim->psys->totchild : sim->psys->totpart);
+ psys_tasks_create(&ctx, totpart, &tasks, &numtasks);
+ for (i = 0; i < numtasks; ++i) {
+ ParticleTask *task = &tasks[i];
+
+ psys_task_init_distribute(task, sim);
+ if (from == PART_FROM_CHILD)
+ BLI_task_pool_push(task_pool, exec_distribute_child, task, false, TASK_PRIORITY_LOW);
+ else
+ BLI_task_pool_push(task_pool, exec_distribute_parent, task, false, TASK_PRIORITY_LOW);
+ }
+ BLI_task_pool_work_and_wait(task_pool);
+
+ BLI_task_pool_free(task_pool);
+
+ psys_calc_dmcache(sim->ob, finaldm, sim->psys);
+
+ if (ctx.dm != finaldm)
+ ctx.dm->release(ctx.dm);
+
+ psys_tasks_free(tasks, numtasks);
+
+ psys_thread_context_free(&ctx);
+}
+
+/* ready for future use, to emit particles without geometry */
+static void distribute_particles_on_shape(ParticleSimulationData *sim, int UNUSED(from))
+{
+ distribute_invalid(sim->scene, sim->psys, 0);
+
+ fprintf(stderr,"Shape emission not yet possible!\n");
+}
+
+void distribute_particles(ParticleSimulationData *sim, int from)
+{
+ PARTICLE_PSMD;
+ int distr_error=0;
+
+ if (psmd) {
+ if (psmd->dm)
+ distribute_particles_on_dm(sim, from);
+ else
+ distr_error=1;
+ }
+ else
+ distribute_particles_on_shape(sim, from);
+
+ if (distr_error) {
+ distribute_invalid(sim->scene, sim->psys, from);
+
+ fprintf(stderr,"Particle distribution error!\n");
+ }
+}
+
+/* ======== Simplify ======== */
+
+static float psys_render_viewport_falloff(double rate, float dist, float width)
+{
+ return pow(rate, dist / width);
+}
+
+static float psys_render_projected_area(ParticleSystem *psys, const float center[3], float area, double vprate, float *viewport)
+{
+ ParticleRenderData *data = psys->renderdata;
+ float co[4], view[3], ortho1[3], ortho2[3], w, dx, dy, radius;
+
+ /* transform to view space */
+ copy_v3_v3(co, center);
+ co[3] = 1.0f;
+ mul_m4_v4(data->viewmat, co);
+
+ /* compute two vectors orthogonal to view vector */
+ normalize_v3_v3(view, co);
+ ortho_basis_v3v3_v3(ortho1, ortho2, view);
+
+ /* compute on screen minification */
+ w = co[2] * data->winmat[2][3] + data->winmat[3][3];
+ dx = data->winx * ortho2[0] * data->winmat[0][0];
+ dy = data->winy * ortho2[1] * data->winmat[1][1];
+ w = sqrtf(dx * dx + dy * dy) / w;
+
+ /* w squared because we are working with area */
+ area = area * w * w;
+
+ /* viewport of the screen test */
+
+ /* project point on screen */
+ mul_m4_v4(data->winmat, co);
+ if (co[3] != 0.0f) {
+ co[0] = 0.5f * data->winx * (1.0f + co[0] / co[3]);
+ co[1] = 0.5f * data->winy * (1.0f + co[1] / co[3]);
+ }
+
+ /* screen space radius */
+ radius = sqrtf(area / (float)M_PI);
+
+ /* make smaller using fallof once over screen edge */
+ *viewport = 1.0f;
+
+ if (co[0] + radius < 0.0f)
+ *viewport *= psys_render_viewport_falloff(vprate, -(co[0] + radius), data->winx);
+ else if (co[0] - radius > data->winx)
+ *viewport *= psys_render_viewport_falloff(vprate, (co[0] - radius) - data->winx, data->winx);
+
+ if (co[1] + radius < 0.0f)
+ *viewport *= psys_render_viewport_falloff(vprate, -(co[1] + radius), data->winy);
+ else if (co[1] - radius > data->winy)
+ *viewport *= psys_render_viewport_falloff(vprate, (co[1] - radius) - data->winy, data->winy);
+
+ return area;
+}
+
+/* BMESH_TODO, for orig face data, we need to use MPoly */
+static int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
+{
+ DerivedMesh *dm = ctx->dm;
+ Mesh *me = (Mesh *)(ctx->sim.ob->data);
+ MFace *mf, *mface;
+ MVert *mvert;
+ ParticleRenderData *data;
+ ParticleRenderElem *elems, *elem;
+ ParticleSettings *part = ctx->sim.psys->part;
+ float *facearea, (*facecenter)[3], size[3], fac, powrate, scaleclamp;
+ float co1[3], co2[3], co3[3], co4[3], lambda, arearatio, t, area, viewport;
+ double vprate;
+ int *facetotvert;
+ int a, b, totorigface, totface, newtot, skipped;
+
+ /* double lookup */
+ const int *index_mf_to_mpoly;
+ const int *index_mp_to_orig;
+
+ if (part->ren_as != PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
+ return tot;
+ if (!ctx->sim.psys->renderdata)
+ return tot;
+
+ data = ctx->sim.psys->renderdata;
+ if (data->timeoffset)
+ return 0;
+ if (!(part->simplify_flag & PART_SIMPLIFY_ENABLE))
+ return tot;
+
+ mvert = dm->getVertArray(dm);
+ mface = dm->getTessFaceArray(dm);
+ totface = dm->getNumTessFaces(dm);
+ totorigface = me->totpoly;
+
+ if (totface == 0 || totorigface == 0)
+ return tot;
+
+ index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+ index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ if (index_mf_to_mpoly == NULL) {
+ index_mp_to_orig = NULL;
+ }
+
+ facearea = MEM_callocN(sizeof(float) * totorigface, "SimplifyFaceArea");
+ facecenter = MEM_callocN(sizeof(float[3]) * totorigface, "SimplifyFaceCenter");
+ facetotvert = MEM_callocN(sizeof(int) * totorigface, "SimplifyFaceArea");
+ elems = MEM_callocN(sizeof(ParticleRenderElem) * totorigface, "SimplifyFaceElem");
+
+ if (data->elems)
+ MEM_freeN(data->elems);
+
+ data->do_simplify = true;
+ data->elems = elems;
+ data->index_mf_to_mpoly = index_mf_to_mpoly;
+ data->index_mp_to_orig = index_mp_to_orig;
+
+ /* compute number of children per original face */
+ for (a = 0; a < tot; a++) {
+ b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, ctx->index[a]) : ctx->index[a];
+ if (b != ORIGINDEX_NONE) {
+ elems[b].totchild++;
+ }
+ }
+
+ /* compute areas and centers of original faces */
+ for (mf = mface, a = 0; a < totface; a++, mf++) {
+ b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
+
+ if (b != ORIGINDEX_NONE) {
+ copy_v3_v3(co1, mvert[mf->v1].co);
+ copy_v3_v3(co2, mvert[mf->v2].co);
+ copy_v3_v3(co3, mvert[mf->v3].co);
+
+ add_v3_v3(facecenter[b], co1);
+ add_v3_v3(facecenter[b], co2);
+ add_v3_v3(facecenter[b], co3);
+
+ if (mf->v4) {
+ copy_v3_v3(co4, mvert[mf->v4].co);
+ add_v3_v3(facecenter[b], co4);
+ facearea[b] += area_quad_v3(co1, co2, co3, co4);
+ facetotvert[b] += 4;
+ }
+ else {
+ facearea[b] += area_tri_v3(co1, co2, co3);
+ facetotvert[b] += 3;
+ }
+ }
+ }
+
+ for (a = 0; a < totorigface; a++)
+ if (facetotvert[a] > 0)
+ mul_v3_fl(facecenter[a], 1.0f / facetotvert[a]);
+
+ /* for conversion from BU area / pixel area to reference screen size */
+ BKE_mesh_texspace_get(me, 0, 0, size);
+ fac = ((size[0] + size[1] + size[2]) / 3.0f) / part->simplify_refsize;
+ fac = fac * fac;
+
+ powrate = log(0.5f) / log(part->simplify_rate * 0.5f);
+ if (part->simplify_flag & PART_SIMPLIFY_VIEWPORT)
+ vprate = pow(1.0f - part->simplify_viewport, 5.0);
+ else
+ vprate = 1.0;
+
+ /* set simplification parameters per original face */
+ for (a = 0, elem = elems; a < totorigface; a++, elem++) {
+ area = psys_render_projected_area(ctx->sim.psys, facecenter[a], facearea[a], vprate, &viewport);
+ arearatio = fac * area / facearea[a];
+
+ if ((arearatio < 1.0f || viewport < 1.0f) && elem->totchild) {
+ /* lambda is percentage of elements to keep */
+ lambda = (arearatio < 1.0f) ? powf(arearatio, powrate) : 1.0f;
+ lambda *= viewport;
+
+ lambda = MAX2(lambda, 1.0f / elem->totchild);
+
+ /* compute transition region */
+ t = part->simplify_transition;
+ elem->t = (lambda - t < 0.0f) ? lambda : (lambda + t > 1.0f) ? 1.0f - lambda : t;
+ elem->reduce = 1;
+
+ /* scale at end and beginning of the transition region */
+ elem->scalemax = (lambda + t < 1.0f) ? 1.0f / lambda : 1.0f / (1.0f - elem->t * elem->t / t);
+ elem->scalemin = (lambda + t < 1.0f) ? 0.0f : elem->scalemax * (1.0f - elem->t / t);
+
+ elem->scalemin = sqrtf(elem->scalemin);
+ elem->scalemax = sqrtf(elem->scalemax);
+
+ /* clamp scaling */
+ scaleclamp = (float)min_ii(elem->totchild, 10);
+ elem->scalemin = MIN2(scaleclamp, elem->scalemin);
+ elem->scalemax = MIN2(scaleclamp, elem->scalemax);
+
+ /* extend lambda to include transition */
+ lambda = lambda + elem->t;
+ if (lambda > 1.0f)
+ lambda = 1.0f;
+ }
+ else {
+ lambda = arearatio;
+
+ elem->scalemax = 1.0f; //sqrt(lambda);
+ elem->scalemin = 1.0f; //sqrt(lambda);
+ elem->reduce = 0;
+ }
+
+ elem->lambda = lambda;
+ elem->scalemin = sqrtf(elem->scalemin);
+ elem->scalemax = sqrtf(elem->scalemax);
+ elem->curchild = 0;
+ }
+
+ MEM_freeN(facearea);
+ MEM_freeN(facecenter);
+ MEM_freeN(facetotvert);
+
+ /* move indices and set random number skipping */
+ ctx->skip = MEM_callocN(sizeof(int) * tot, "SimplificationSkip");
+
+ skipped = 0;
+ for (a = 0, newtot = 0; a < tot; a++) {
+ b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, ctx->index[a]) : ctx->index[a];
+
+ if (b != ORIGINDEX_NONE) {
+ if (elems[b].curchild++ < ceil(elems[b].lambda * elems[b].totchild)) {
+ ctx->index[newtot] = ctx->index[a];
+ ctx->skip[newtot] = skipped;
+ skipped = 0;
+ newtot++;
+ }
+ else skipped++;
+ }
+ else skipped++;
+ }
+
+ for (a = 0, elem = elems; a < totorigface; a++, elem++)
+ elem->curchild = 0;
+
+ return newtot;
+}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 155299b69c3..b7ebcfa9b0b 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -68,6 +68,7 @@
#include "BLI_kdtree.h"
#include "BLI_kdopbvh.h"
#include "BLI_sort.h"
+#include "BLI_task.h"
#include "BLI_threads.h"
#include "BLI_linklist.h"
@@ -284,7 +285,7 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
}
}
-static int get_psys_child_number(struct Scene *scene, ParticleSystem *psys)
+int psys_get_child_number(Scene *scene, ParticleSystem *psys)
{
int nbr;
@@ -299,30 +300,9 @@ static int get_psys_child_number(struct Scene *scene, ParticleSystem *psys)
return get_render_child_particle_number(&scene->r, nbr);
}
-static int get_psys_tot_child(struct Scene *scene, ParticleSystem *psys)
+int psys_get_tot_child(Scene *scene, ParticleSystem *psys)
{
- return psys->totpart*get_psys_child_number(scene, psys);
-}
-
-static void alloc_child_particles(ParticleSystem *psys, int tot)
-{
- if (psys->child) {
- /* only re-allocate if we have to */
- if (psys->part->childtype && psys->totchild == tot) {
- memset(psys->child, 0, tot*sizeof(ChildParticle));
- return;
- }
-
- MEM_freeN(psys->child);
- psys->child=NULL;
- psys->totchild=0;
- }
-
- if (psys->part->childtype) {
- psys->totchild= tot;
- if (psys->totchild)
- psys->child= MEM_callocN(psys->totchild*sizeof(ChildParticle), "child_particles");
- }
+ return psys->totpart*psys_get_child_number(scene, psys);
}
/************************************************/
@@ -452,1053 +432,60 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
}
}
-static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, ParticleSystem *psys)
-{
- ChildParticle *cpa = NULL;
- int i, p;
- int child_nbr= get_psys_child_number(scene, psys);
- int totpart= get_psys_tot_child(scene, psys);
-
- alloc_child_particles(psys, totpart);
-
- cpa = psys->child;
- for (i=0; i<child_nbr; i++) {
- for (p=0; p<psys->totpart; p++,cpa++) {
- float length=2.0;
- cpa->parent=p;
-
- /* create even spherical distribution inside unit sphere */
- while (length>=1.0f) {
- cpa->fuv[0]=2.0f*BLI_frand()-1.0f;
- cpa->fuv[1]=2.0f*BLI_frand()-1.0f;
- cpa->fuv[2]=2.0f*BLI_frand()-1.0f;
- length=len_v3(cpa->fuv);
- }
-
- cpa->num=-1;
- }
- }
- /* dmcache must be updated for parent particles if children from faces is used */
- psys_calc_dmcache(ob, finaldm, psys);
-}
-static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
-{
- ParticleData *pa=NULL;
- float min[3], max[3], delta[3], d;
- MVert *mv, *mvert = dm->getVertDataArray(dm,0);
- int totvert=dm->getNumVerts(dm), from=psys->part->from;
- int i, j, k, p, res=psys->part->grid_res, size[3], axis;
-
- /* find bounding box of dm */
- if (totvert > 0) {
- mv=mvert;
- copy_v3_v3(min, mv->co);
- copy_v3_v3(max, mv->co);
- mv++;
- for (i = 1; i < totvert; i++, mv++) {
- minmax_v3v3_v3(min, max, mv->co);
- }
- }
- else {
- zero_v3(min);
- zero_v3(max);
- }
-
- sub_v3_v3v3(delta, max, min);
-
- /* determine major axis */
- axis = axis_dominant_v3_single(delta);
-
- d = delta[axis]/(float)res;
-
- size[axis] = res;
- size[(axis+1)%3] = (int)ceil(delta[(axis+1)%3]/d);
- size[(axis+2)%3] = (int)ceil(delta[(axis+2)%3]/d);
-
- /* float errors grrr.. */
- size[(axis+1)%3] = MIN2(size[(axis+1)%3],res);
- size[(axis+2)%3] = MIN2(size[(axis+2)%3],res);
-
- size[0] = MAX2(size[0], 1);
- size[1] = MAX2(size[1], 1);
- size[2] = MAX2(size[2], 1);
-
- /* no full offset for flat/thin objects */
- min[0]+= d < delta[0] ? d/2.f : delta[0]/2.f;
- min[1]+= d < delta[1] ? d/2.f : delta[1]/2.f;
- min[2]+= d < delta[2] ? d/2.f : delta[2]/2.f;
-
- for (i=0,p=0,pa=psys->particles; i<res; i++) {
- for (j=0; j<res; j++) {
- for (k=0; k<res; k++,p++,pa++) {
- pa->fuv[0] = min[0] + (float)i*d;
- pa->fuv[1] = min[1] + (float)j*d;
- pa->fuv[2] = min[2] + (float)k*d;
- pa->flag |= PARS_UNEXIST;
- pa->hair_index = 0; /* abused in volume calculation */
- }
- }
- }
-
- /* enable particles near verts/edges/faces/inside surface */
- if (from==PART_FROM_VERT) {
- float vec[3];
-
- pa=psys->particles;
-
- min[0] -= d/2.0f;
- min[1] -= d/2.0f;
- min[2] -= d/2.0f;
-
- for (i=0,mv=mvert; i<totvert; i++,mv++) {
- sub_v3_v3v3(vec,mv->co,min);
- vec[0]/=delta[0];
- vec[1]/=delta[1];
- vec[2]/=delta[2];
- pa[((int)(vec[0] * (size[0] - 1)) * res +
- (int)(vec[1] * (size[1] - 1))) * res +
- (int)(vec[2] * (size[2] - 1))].flag &= ~PARS_UNEXIST;
- }
- }
- else if (ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
- float co1[3], co2[3];
-
- MFace *mface= NULL, *mface_array;
- float v1[3], v2[3], v3[3], v4[4], lambda;
- int a, a1, a2, a0mul, a1mul, a2mul, totface;
- int amax= from==PART_FROM_FACE ? 3 : 1;
-
- totface=dm->getNumTessFaces(dm);
- mface=mface_array=dm->getTessFaceDataArray(dm,CD_MFACE);
-
- for (a=0; a<amax; a++) {
- if (a==0) { a0mul=res*res; a1mul=res; a2mul=1; }
- else if (a==1) { a0mul=res; a1mul=1; a2mul=res*res; }
- else { a0mul=1; a1mul=res*res; a2mul=res; }
-
- for (a1=0; a1<size[(a+1)%3]; a1++) {
- for (a2=0; a2<size[(a+2)%3]; a2++) {
- mface= mface_array;
-
- pa = psys->particles + a1*a1mul + a2*a2mul;
- copy_v3_v3(co1, pa->fuv);
- co1[a] -= d < delta[a] ? d/2.f : delta[a]/2.f;
- copy_v3_v3(co2, co1);
- co2[a] += delta[a] + 0.001f*d;
- co1[a] -= 0.001f*d;
-
- /* lets intersect the faces */
- for (i=0; i<totface; i++,mface++) {
- copy_v3_v3(v1, mvert[mface->v1].co);
- copy_v3_v3(v2, mvert[mface->v2].co);
- copy_v3_v3(v3, mvert[mface->v3].co);
-
- if (isect_axial_line_tri_v3(a, co1, co2, v2, v3, v1, &lambda)) {
- if (from==PART_FROM_FACE)
- (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
- else /* store number of intersections */
- (pa+(int)(lambda*size[a])*a0mul)->hair_index++;
- }
- else if (mface->v4) {
- copy_v3_v3(v4, mvert[mface->v4].co);
-
- if (isect_axial_line_tri_v3(a, co1, co2, v4, v1, v3, &lambda)) {
- if (from==PART_FROM_FACE)
- (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
- else
- (pa+(int)(lambda*size[a])*a0mul)->hair_index++;
- }
- }
- }
-
- if (from==PART_FROM_VOLUME) {
- int in=pa->hair_index%2;
- if (in) pa->hair_index++;
- for (i=0; i<size[0]; i++) {
- if (in || (pa+i*a0mul)->hair_index%2)
- (pa+i*a0mul)->flag &= ~PARS_UNEXIST;
- /* odd intersections == in->out / out->in */
- /* even intersections -> in stays same */
- in=(in + (pa+i*a0mul)->hair_index) % 2;
- }
- }
- }
- }
- }
- }
-
- if (psys->part->flag & PART_GRID_HEXAGONAL) {
- for (i=0,p=0,pa=psys->particles; i<res; i++) {
- for (j=0; j<res; j++) {
- for (k=0; k<res; k++,p++,pa++) {
- if (j%2)
- pa->fuv[0] += d/2.f;
-
- if (k%2) {
- pa->fuv[0] += d/2.f;
- pa->fuv[1] += d/2.f;
- }
- }
- }
- }
- }
-
- if (psys->part->flag & PART_GRID_INVERT) {
- for (i=0; i<size[0]; i++) {
- for (j=0; j<size[1]; j++) {
- pa=psys->particles + res*(i*res + j);
- for (k=0; k<size[2]; k++, pa++) {
- pa->flag ^= PARS_UNEXIST;
- }
- }
- }
- }
-
- if (psys->part->grid_rand > 0.f) {
- float rfac = d * psys->part->grid_rand;
- for (p=0,pa=psys->particles; p<psys->totpart; p++,pa++) {
- if (pa->flag & PARS_UNEXIST)
- continue;
-
- pa->fuv[0] += rfac * (psys_frand(psys, p + 31) - 0.5f);
- pa->fuv[1] += rfac * (psys_frand(psys, p + 32) - 0.5f);
- pa->fuv[2] += rfac * (psys_frand(psys, p + 33) - 0.5f);
- }
- }
-}
-
-/* modified copy from rayshade.c */
-static void hammersley_create(float *out, int n, int seed, float amount)
-{
- RNG *rng;
- double p, t, offs[2];
- int k, kk;
-
- rng = BLI_rng_new(31415926 + n + seed);
- offs[0] = BLI_rng_get_double(rng) + (double)amount;
- offs[1] = BLI_rng_get_double(rng) + (double)amount;
- BLI_rng_free(rng);
-
- for (k = 0; k < n; k++) {
- t = 0;
- for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1)
- if (kk & 1) /* kk mod 2 = 1 */
- t += p;
-
- out[2*k + 0] = fmod((double)k/(double)n + offs[0], 1.0);
- out[2*k + 1] = fmod(t + offs[1], 1.0);
- }
-}
-
-/* almost exact copy of BLI_jitter_init */
-static void init_mv_jit(float *jit, int num, int seed2, float amount)
-{
- RNG *rng;
- float *jit2, x, rad1, rad2, rad3;
- int i, num2;
-
- if (num==0) return;
-
- rad1= (float)(1.0f/sqrtf((float)num));
- rad2= (float)(1.0f/((float)num));
- rad3= (float)sqrtf((float)num)/((float)num);
-
- rng = BLI_rng_new(31415926 + num + seed2);
- x= 0;
- num2 = 2 * num;
- for (i=0; i<num2; i+=2) {
-
- jit[i] = x + amount*rad1*(0.5f - BLI_rng_get_float(rng));
- jit[i+1] = i/(2.0f*num) + amount*rad1*(0.5f - BLI_rng_get_float(rng));
-
- jit[i]-= (float)floor(jit[i]);
- jit[i+1]-= (float)floor(jit[i+1]);
-
- x+= rad3;
- x -= (float)floor(x);
- }
-
- jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
-
- for (i=0 ; i<4 ; i++) {
- BLI_jitterate1((float (*)[2])jit, (float (*)[2])jit2, num, rad1);
- BLI_jitterate1((float (*)[2])jit, (float (*)[2])jit2, num, rad1);
- BLI_jitterate2((float (*)[2])jit, (float (*)[2])jit2, num, rad2);
- }
- MEM_freeN(jit2);
- BLI_rng_free(rng);
-}
-
-static void psys_uv_to_w(float u, float v, int quad, float *w)
-{
- float vert[4][3], co[3];
-
- if (!quad) {
- if (u+v > 1.0f)
- v= 1.0f-v;
- else
- u= 1.0f-u;
- }
-
- vert[0][0] = 0.0f; vert[0][1] = 0.0f; vert[0][2] = 0.0f;
- vert[1][0] = 1.0f; vert[1][1] = 0.0f; vert[1][2] = 0.0f;
- vert[2][0] = 1.0f; vert[2][1] = 1.0f; vert[2][2] = 0.0f;
-
- co[0] = u;
- co[1] = v;
- co[2] = 0.0f;
-
- if (quad) {
- vert[3][0] = 0.0f; vert[3][1] = 1.0f; vert[3][2] = 0.0f;
- interp_weights_poly_v3( w,vert, 4, co);
- }
- else {
- interp_weights_poly_v3( w,vert, 3, co);
- w[3] = 0.0f;
- }
-}
-
-/* Find the index in "sum" array before "value" is crossed. */
-static int distribute_binary_search(float *sum, int n, float value)
-{
- int mid, low=0, high=n;
-
- if (value == 0.f)
- return 0;
-
- while (low <= high) {
- mid= (low + high)/2;
-
- if (sum[mid] < value && value <= sum[mid+1])
- return mid;
-
- if (sum[mid] >= value)
- high= mid - 1;
- else if (sum[mid] < value)
- low= mid + 1;
- else
- return mid;
- }
-
- return low;
-}
-
-/* the max number if calls to rng_* funcs within psys_thread_distribute_particle
- * be sure to keep up to date if this changes */
-#define PSYS_RND_DIST_SKIP 2
-
-/* note: this function must be thread safe, for from == PART_FROM_CHILD */
-#define ONLY_WORKING_WITH_PA_VERTS 0
-static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
-{
- ParticleThreadContext *ctx= thread->ctx;
- Object *ob= ctx->sim.ob;
- DerivedMesh *dm= ctx->dm;
- float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3];
- float cur_d, min_d, randu, randv;
- int from= ctx->from;
- int cfrom= ctx->cfrom;
- int distr= ctx->distr;
- int i, intersect, tot;
- int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
-
- if (from == PART_FROM_VERT) {
- /* TODO_PARTICLE - use original index */
- pa->num= ctx->index[p];
- pa->fuv[0] = 1.0f;
- pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
-
-#if ONLY_WORKING_WITH_PA_VERTS
- if (ctx->tree) {
- KDTreeNearest ptn[3];
- int w, maxw;
-
- psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
- BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1);
- maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3);
-
- for (w=0; w<maxw; w++) {
- pa->verts[w]=ptn->num;
- }
- }
-#endif
- }
- else if (from == PART_FROM_FACE || from == PART_FROM_VOLUME) {
- MFace *mface;
-
- pa->num = i = ctx->index[p];
- mface = dm->getTessFaceData(dm,i,CD_MFACE);
-
- switch (distr) {
- case PART_DISTR_JIT:
- if (ctx->jitlevel == 1) {
- if (mface->v4)
- psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv);
- else
- psys_uv_to_w(1.0f / 3.0f, 1.0f / 3.0f, mface->v4, pa->fuv);
- }
- else {
- ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel);
- if (!isnan(ctx->jitoff[i])) {
- psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv);
- ctx->jitoff[i]++;
- }
- }
- break;
- case PART_DISTR_RAND:
- randu= BLI_rng_get_float(thread->rng);
- randv= BLI_rng_get_float(thread->rng);
- rng_skip_tot -= 2;
-
- psys_uv_to_w(randu, randv, mface->v4, pa->fuv);
- break;
- }
- pa->foffset= 0.0f;
-
- /* experimental */
- if (from==PART_FROM_VOLUME) {
- MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
-
- tot=dm->getNumTessFaces(dm);
-
- psys_interpolate_face(mvert,mface,0,0,pa->fuv,co1,nor,0,0,0,0);
-
- normalize_v3(nor);
- mul_v3_fl(nor,-100.0);
-
- add_v3_v3v3(co2,co1,nor);
-
- min_d=2.0;
- intersect=0;
-
- for (i=0,mface=dm->getTessFaceDataArray(dm,CD_MFACE); i<tot; i++,mface++) {
- if (i==pa->num) continue;
-
- v1=mvert[mface->v1].co;
- v2=mvert[mface->v2].co;
- v3=mvert[mface->v3].co;
-
- if (isect_line_tri_v3(co1, co2, v2, v3, v1, &cur_d, 0)) {
- if (cur_d<min_d) {
- min_d=cur_d;
- pa->foffset=cur_d*50.0f; /* to the middle of volume */
- intersect=1;
- }
- }
- if (mface->v4) {
- v4=mvert[mface->v4].co;
-
- if (isect_line_tri_v3(co1, co2, v4, v1, v3, &cur_d, 0)) {
- if (cur_d<min_d) {
- min_d=cur_d;
- pa->foffset=cur_d*50.0f; /* to the middle of volume */
- intersect=1;
- }
- }
- }
- }
- if (intersect==0)
- pa->foffset=0.0;
- else {
- switch (distr) {
- case PART_DISTR_JIT:
- pa->foffset *= ctx->jit[p % (2 * ctx->jitlevel)];
- break;
- case PART_DISTR_RAND:
- pa->foffset *= BLI_frand();
- break;
- }
- }
- }
- }
- else if (from == PART_FROM_CHILD) {
- MFace *mf;
-
- if (ctx->index[p] < 0) {
- cpa->num=0;
- cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]=0.0f;
- cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
- return;
- }
-
- mf= dm->getTessFaceData(dm, ctx->index[p], CD_MFACE);
-
- randu= BLI_rng_get_float(thread->rng);
- randv= BLI_rng_get_float(thread->rng);
- rng_skip_tot -= 2;
-
- psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
-
- cpa->num = ctx->index[p];
-
- if (ctx->tree) {
- KDTreeNearest ptn[10];
- int w,maxw;//, do_seams;
- float maxd /*, mind,dd */, totw= 0.0f;
- int parent[10];
- float pweight[10];
-
- psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1,NULL);
- BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco1, 1, 1);
- maxw = BLI_kdtree_find_nearest_n(ctx->tree,orco1,ptn,3);
-
- maxd=ptn[maxw-1].dist;
- /* mind=ptn[0].dist; */ /* UNUSED */
-
- /* the weights here could be done better */
- for (w=0; w<maxw; w++) {
- parent[w]=ptn[w].index;
- pweight[w]=(float)pow(2.0,(double)(-6.0f*ptn[w].dist/maxd));
- }
- for (;w<10; w++) {
- parent[w]=-1;
- pweight[w]=0.0f;
- }
-
- for (w=0,i=0; w<maxw && i<4; w++) {
- if (parent[w]>=0) {
- cpa->pa[i]=parent[w];
- cpa->w[i]=pweight[w];
- totw+=pweight[w];
- i++;
- }
- }
- for (;i<4; i++) {
- cpa->pa[i]=-1;
- cpa->w[i]=0.0f;
- }
-
- if (totw>0.0f) for (w=0; w<4; w++)
- cpa->w[w]/=totw;
-
- cpa->parent=cpa->pa[0];
- }
- }
-
- if (rng_skip_tot > 0) /* should never be below zero */
- BLI_rng_skip(thread->rng, rng_skip_tot);
-}
-
-static void *distribute_threads_exec_cb(void *data)
+/* threaded child particle distribution and path caching */
+void psys_thread_context_init(ParticleThreadContext *ctx, ParticleSimulationData *sim)
{
- ParticleThread *thread= (ParticleThread*)data;
- ParticleSystem *psys= thread->ctx->sim.psys;
- ParticleData *pa;
- ChildParticle *cpa;
- int p, totpart;
-
- if (thread->ctx->from == PART_FROM_CHILD) {
- totpart= psys->totchild;
- cpa= psys->child;
-
- for (p=0; p<totpart; p++, cpa++) {
- if (thread->ctx->skip) /* simplification skip */
- BLI_rng_skip(thread->rng, PSYS_RND_DIST_SKIP * thread->ctx->skip[p]);
-
- if ((p+thread->num) % thread->tot == 0)
- distribute_threads_exec(thread, NULL, cpa, p);
- else /* thread skip */
- BLI_rng_skip(thread->rng, PSYS_RND_DIST_SKIP);
- }
- }
- else {
- totpart= psys->totpart;
- pa= psys->particles + thread->num;
- for (p=thread->num; p<totpart; p+=thread->tot, pa+=thread->tot)
- distribute_threads_exec(thread, pa, NULL, p);
- }
-
- return 0;
+ memset(ctx, 0, sizeof(ParticleThreadContext));
+ ctx->sim = *sim;
+ ctx->dm = ctx->sim.psmd->dm;
+ ctx->ma = give_current_material(sim->ob, sim->psys->part->omat);
}
-static int distribute_compare_orig_index(const void *p1, const void *p2, void *user_data)
-{
- int *orig_index = (int *) user_data;
- int index1 = orig_index[*(const int *)p1];
- int index2 = orig_index[*(const int *)p2];
-
- if (index1 < index2)
- return -1;
- else if (index1 == index2) {
- /* this pointer comparison appears to make qsort stable for glibc,
- * and apparently on solaris too, makes the renders reproducible */
- if (p1 < p2)
- return -1;
- else if (p1 == p2)
- return 0;
- else
- return 1;
- }
- else
- return 1;
-}
+#define MAX_PARTICLES_PER_TASK 256 /* XXX arbitrary - maybe use at least number of points instead for better balancing? */
-static void distribute_invalid(Scene *scene, ParticleSystem *psys, int from)
+BLI_INLINE int ceil_ii(int a, int b)
{
- if (from == PART_FROM_CHILD) {
- ChildParticle *cpa;
- int p, totchild = get_psys_tot_child(scene, psys);
-
- if (psys->child && totchild) {
- for (p=0,cpa=psys->child; p<totchild; p++,cpa++) {
- cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3] = 0.0;
- cpa->foffset= 0.0f;
- cpa->parent=0;
- cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
- cpa->num= -1;
- }
- }
- }
- else {
- PARTICLE_P;
- LOOP_PARTICLES {
- pa->fuv[0] = pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
- pa->foffset= 0.0f;
- pa->num= -1;
- }
- }
+ return (a + b - 1) / b;
}
-/* Creates a distribution of coordinates on a DerivedMesh */
-/* This is to denote functionality that does not yet work with mesh - only derived mesh */
-static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from)
+void psys_tasks_create(ParticleThreadContext *ctx, int totpart, ParticleTask **r_tasks, int *r_numtasks)
{
- ParticleThreadContext *ctx= threads[0].ctx;
- Object *ob= ctx->sim.ob;
- ParticleSystem *psys= ctx->sim.psys;
- ParticleData *pa=0, *tpars= 0;
- ParticleSettings *part;
- ParticleSeam *seams= 0;
- KDTree *tree=0;
- DerivedMesh *dm= NULL;
- float *jit= NULL;
- int i, seed, p=0, totthread= threads[0].tot;
- int cfrom=0;
- int totelem=0, totpart, *particle_element=0, children=0, totseam=0;
- int jitlevel= 1, distr;
- float *element_weight=NULL,*element_sum=NULL,*jitter_offset=NULL, *vweight=NULL;
- float cur, maxweight=0.0, tweight, totweight, inv_totweight, co[3], nor[3], orco[3];
+ ParticleTask *tasks;
+ int numtasks = ceil_ii(totpart, MAX_PARTICLES_PER_TASK);
+ float particles_per_task = (float)totpart / (float)numtasks, p, pnext;
+ int i;
- if (ELEM(NULL, ob, psys, psys->part))
- return 0;
-
- part=psys->part;
- totpart=psys->totpart;
- if (totpart==0)
- return 0;
-
- if (!finaldm->deformedOnly && !finaldm->getTessFaceDataArray(finaldm, CD_ORIGINDEX)) {
- printf("Can't create particles with the current modifier stack, disable destructive modifiers\n");
-// XXX error("Can't paint with the current modifier stack, disable destructive modifiers");
- return 0;
- }
-
- /* First handle special cases */
- if (from == PART_FROM_CHILD) {
- /* Simple children */
- if (part->childtype != PART_CHILD_FACES) {
- BLI_srandom(31415926 + psys->seed + psys->child_seed);
- distribute_simple_children(scene, ob, finaldm, psys);
- return 0;
- }
- }
- else {
- /* Grid distribution */
- if (part->distr==PART_DISTR_GRID && from != PART_FROM_VERT) {
- BLI_srandom(31415926 + psys->seed);
- dm= CDDM_from_mesh((Mesh*)ob->data);
- DM_ensure_tessface(dm);
- distribute_grid(dm,psys);
- dm->release(dm);
- return 0;
- }
- }
+ tasks = MEM_callocN(sizeof(ParticleTask) * numtasks, "ParticleThread");
+ *r_numtasks = numtasks;
+ *r_tasks = tasks;
- /* Create trees and original coordinates if needed */
- if (from == PART_FROM_CHILD) {
- distr=PART_DISTR_RAND;
- BLI_srandom(31415926 + psys->seed + psys->child_seed);
- dm= finaldm;
-
- /* BMESH ONLY */
- DM_ensure_tessface(dm);
-
- children=1;
-
- tree=BLI_kdtree_new(totpart);
-
- for (p=0,pa=psys->particles; p<totpart; p++,pa++) {
- psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,NULL);
- BKE_mesh_orco_verts_transform((Mesh*)ob->data, &orco, 1, 1);
- BLI_kdtree_insert(tree, p, orco);
- }
-
- BLI_kdtree_balance(tree);
-
- totpart = get_psys_tot_child(scene, psys);
- cfrom = from = PART_FROM_FACE;
- }
- else {
- distr = part->distr;
- BLI_srandom(31415926 + psys->seed);
+ p = 0.0f;
+ for (i = 0; i < numtasks; i++, p = pnext) {
+ pnext = p + particles_per_task;
- if (psys->part->use_modifier_stack)
- dm = finaldm;
- else
- dm= CDDM_from_mesh((Mesh*)ob->data);
-
- /* BMESH ONLY, for verts we don't care about tessfaces */
- if (from != PART_FROM_VERT) {
- DM_ensure_tessface(dm);
- }
-
- /* we need orco for consistent distributions */
- if (!CustomData_has_layer(&dm->vertData, CD_ORCO))
- DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob));
-
- if (from == PART_FROM_VERT) {
- MVert *mv= dm->getVertDataArray(dm, CD_MVERT);
- float (*orcodata)[3] = dm->getVertDataArray(dm, CD_ORCO);
- int totvert = dm->getNumVerts(dm);
-
- tree=BLI_kdtree_new(totvert);
-
- for (p=0; p<totvert; p++) {
- if (orcodata) {
- copy_v3_v3(co,orcodata[p]);
- BKE_mesh_orco_verts_transform((Mesh*)ob->data, &co, 1, 1);
- }
- else
- copy_v3_v3(co,mv[p].co);
- BLI_kdtree_insert(tree, p, co);
- }
-
- BLI_kdtree_balance(tree);
- }
+ tasks[i].ctx = ctx;
+ tasks[i].begin = (int)p;
+ tasks[i].end = min_ii((int)pnext, totpart);
}
-
- /* Get total number of emission elements and allocate needed arrays */
- totelem = (from == PART_FROM_VERT) ? dm->getNumVerts(dm) : dm->getNumTessFaces(dm);
-
- if (totelem == 0) {
- distribute_invalid(scene, psys, children ? PART_FROM_CHILD : 0);
-
- if (G.debug & G_DEBUG)
- fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
-
- if (dm != finaldm) dm->release(dm);
-
- BLI_kdtree_free(tree);
-
- return 0;
- }
-
- element_weight = MEM_callocN(sizeof(float)*totelem, "particle_distribution_weights");
- particle_element= MEM_callocN(sizeof(int)*totpart, "particle_distribution_indexes");
- element_sum = MEM_callocN(sizeof(float)*(totelem+1), "particle_distribution_sum");
- jitter_offset = MEM_callocN(sizeof(float)*totelem, "particle_distribution_jitoff");
-
- /* Calculate weights from face areas */
- if ((part->flag&PART_EDISTR || children) && from != PART_FROM_VERT) {
- MVert *v1, *v2, *v3, *v4;
- float totarea=0.f, co1[3], co2[3], co3[3], co4[3];
- float (*orcodata)[3];
-
- orcodata= dm->getVertDataArray(dm, CD_ORCO);
-
- for (i=0; i<totelem; i++) {
- MFace *mf=dm->getTessFaceData(dm,i,CD_MFACE);
-
- if (orcodata) {
- copy_v3_v3(co1, orcodata[mf->v1]);
- copy_v3_v3(co2, orcodata[mf->v2]);
- copy_v3_v3(co3, orcodata[mf->v3]);
- BKE_mesh_orco_verts_transform((Mesh*)ob->data, &co1, 1, 1);
- BKE_mesh_orco_verts_transform((Mesh*)ob->data, &co2, 1, 1);
- BKE_mesh_orco_verts_transform((Mesh*)ob->data, &co3, 1, 1);
- if (mf->v4) {
- copy_v3_v3(co4, orcodata[mf->v4]);
- BKE_mesh_orco_verts_transform((Mesh*)ob->data, &co4, 1, 1);
- }
- }
- else {
- v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT);
- v2= (MVert*)dm->getVertData(dm,mf->v2,CD_MVERT);
- v3= (MVert*)dm->getVertData(dm,mf->v3,CD_MVERT);
- copy_v3_v3(co1, v1->co);
- copy_v3_v3(co2, v2->co);
- copy_v3_v3(co3, v3->co);
- if (mf->v4) {
- v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT);
- copy_v3_v3(co4, v4->co);
- }
- }
-
- cur = mf->v4 ? area_quad_v3(co1, co2, co3, co4) : area_tri_v3(co1, co2, co3);
-
- if (cur > maxweight)
- maxweight = cur;
-
- element_weight[i] = cur;
- totarea += cur;
- }
-
- for (i=0; i<totelem; i++)
- element_weight[i] /= totarea;
-
- maxweight /= totarea;
- }
- else {
- float min=1.0f/(float)(MIN2(totelem,totpart));
- for (i=0; i<totelem; i++)
- element_weight[i]=min;
- maxweight=min;
- }
-
- /* Calculate weights from vgroup */
- vweight = psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY);
-
- if (vweight) {
- if (from==PART_FROM_VERT) {
- for (i=0;i<totelem; i++)
- element_weight[i]*=vweight[i];
- }
- else { /* PART_FROM_FACE / PART_FROM_VOLUME */
- for (i=0;i<totelem; i++) {
- MFace *mf=dm->getTessFaceData(dm,i,CD_MFACE);
- tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
-
- if (mf->v4) {
- tweight += vweight[mf->v4];
- tweight /= 4.0f;
- }
- else {
- tweight /= 3.0f;
- }
-
- element_weight[i]*=tweight;
- }
- }
- MEM_freeN(vweight);
- }
-
- /* Calculate total weight of all elements */
- totweight= 0.0f;
- for (i=0;i<totelem; i++)
- totweight += element_weight[i];
-
- inv_totweight = (totweight > 0.f ? 1.f/totweight : 0.f);
-
- /* Calculate cumulative weights */
- element_sum[0] = 0.0f;
- for (i=0; i<totelem; i++)
- element_sum[i+1] = element_sum[i] + element_weight[i] * inv_totweight;
-
- /* Finally assign elements to particles */
- if ((part->flag&PART_TRAND) || (part->simplify_flag&PART_SIMPLIFY_ENABLE)) {
- float pos;
-
- for (p=0; p<totpart; p++) {
- /* In theory element_sum[totelem] should be 1.0, but due to float errors this is not necessarily always true, so scale pos accordingly. */
- pos= BLI_frand() * element_sum[totelem];
- particle_element[p] = distribute_binary_search(element_sum, totelem, pos);
- particle_element[p] = MIN2(totelem-1, particle_element[p]);
- jitter_offset[particle_element[p]] = pos;
- }
- }
- else {
- double step, pos;
-
- step= (totpart < 2) ? 0.5 : 1.0/(double)totpart;
- pos= 1e-6; /* tiny offset to avoid zero weight face */
- i= 0;
-
- for (p=0; p<totpart; p++, pos+=step) {
- while ((i < totelem) && (pos > (double)element_sum[i + 1]))
- i++;
-
- particle_element[p] = MIN2(totelem-1, i);
-
- /* avoid zero weight face */
- if (p == totpart-1 && element_weight[particle_element[p]] == 0.0f)
- particle_element[p] = particle_element[p-1];
-
- jitter_offset[particle_element[p]] = pos;
- }
- }
-
- MEM_freeN(element_sum);
-
- /* For hair, sort by origindex (allows optimization's in rendering), */
- /* however with virtual parents the children need to be in random order. */
- if (part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0f)) {
- int *orig_index = NULL;
-
- if (from == PART_FROM_VERT) {
- if (dm->numVertData)
- orig_index = dm->getVertDataArray(dm, CD_ORIGINDEX);
- }
- else {
- if (dm->numTessFaceData)
- orig_index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
- }
-
- if (orig_index) {
- BLI_qsort_r(particle_element, totpart, sizeof(int), distribute_compare_orig_index, orig_index);
- }
- }
-
- /* Create jittering if needed */
- if (distr==PART_DISTR_JIT && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
- jitlevel= part->userjit;
-
- if (jitlevel == 0) {
- jitlevel= totpart/totelem;
- if (part->flag & PART_EDISTR) jitlevel*= 2; /* looks better in general, not very scietific */
- if (jitlevel<3) jitlevel= 3;
- }
-
- jit= MEM_callocN((2+ jitlevel*2)*sizeof(float), "jit");
-
- /* for small amounts of particles we use regular jitter since it looks
- * a bit better, for larger amounts we switch to hammersley sequence
- * because it is much faster */
- if (jitlevel < 25)
- init_mv_jit(jit, jitlevel, psys->seed, part->jitfac);
- else
- hammersley_create(jit, jitlevel+1, psys->seed, part->jitfac);
- BLI_array_randomize(jit, 2*sizeof(float), jitlevel, psys->seed); /* for custom jit or even distribution */
- }
-
- /* Setup things for threaded distribution */
- ctx->tree= tree;
- ctx->seams= seams;
- ctx->totseam= totseam;
- ctx->sim.psys= psys;
- ctx->index= particle_element;
- ctx->jit= jit;
- ctx->jitlevel= jitlevel;
- ctx->jitoff= jitter_offset;
- ctx->weight= element_weight;
- ctx->maxweight= maxweight;
- ctx->from= (children) ? PART_FROM_CHILD : from;
- ctx->cfrom= cfrom;
- ctx->distr= distr;
- ctx->dm= dm;
- ctx->tpars= tpars;
-
- if (children) {
- totpart= psys_render_simplify_distribution(ctx, totpart);
- alloc_child_particles(psys, totpart);
- }
-
- if (!children || psys->totchild < 10000)
- totthread= 1;
-
- seed= 31415926 + ctx->sim.psys->seed;
- for (i=0; i<totthread; i++) {
- threads[i].rng= BLI_rng_new(seed);
- threads[i].tot= totthread;
- }
-
- return 1;
-}
-
-static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
-{
- DerivedMesh *finaldm = sim->psmd->dm;
- ListBase threads;
- ParticleThread *pthreads;
- ParticleThreadContext *ctx;
- int i, totthread;
-
- pthreads= psys_threads_create(sim);
-
- if (!distribute_threads_init_data(pthreads, sim->scene, finaldm, from)) {
- psys_threads_free(pthreads);
- return;
- }
-
- totthread= pthreads[0].tot;
- if (totthread > 1) {
- BLI_init_threads(&threads, distribute_threads_exec_cb, totthread);
-
- for (i=0; i<totthread; i++)
- BLI_insert_thread(&threads, &pthreads[i]);
-
- BLI_end_threads(&threads);
- }
- else
- distribute_threads_exec_cb(&pthreads[0]);
-
- psys_calc_dmcache(sim->ob, finaldm, sim->psys);
-
- ctx= pthreads[0].ctx;
- if (ctx->dm != finaldm)
- ctx->dm->release(ctx->dm);
-
- psys_threads_free(pthreads);
-}
-
-/* ready for future use, to emit particles without geometry */
-static void distribute_particles_on_shape(ParticleSimulationData *sim, int UNUSED(from))
-{
- distribute_invalid(sim->scene, sim->psys, 0);
-
- fprintf(stderr,"Shape emission not yet possible!\n");
}
-static void distribute_particles(ParticleSimulationData *sim, int from)
+void psys_tasks_free(ParticleTask *tasks, int numtasks)
{
- PARTICLE_PSMD;
- int distr_error=0;
-
- if (psmd) {
- if (psmd->dm)
- distribute_particles_on_dm(sim, from);
- else
- distr_error=1;
- }
- else
- distribute_particles_on_shape(sim, from);
-
- if (distr_error) {
- distribute_invalid(sim->scene, sim->psys, from);
-
- fprintf(stderr,"Particle distribution error!\n");
- }
-}
-
-/* threaded child particle distribution and path caching */
-ParticleThread *psys_threads_create(ParticleSimulationData *sim)
-{
- ParticleThread *threads;
- ParticleThreadContext *ctx;
- int i, totthread = BKE_scene_num_threads(sim->scene);
+ int i;
- threads= MEM_callocN(sizeof(ParticleThread)*totthread, "ParticleThread");
- ctx= MEM_callocN(sizeof(ParticleThreadContext), "ParticleThreadContext");
-
- ctx->sim = *sim;
- ctx->dm= ctx->sim.psmd->dm;
- ctx->ma= give_current_material(sim->ob, sim->psys->part->omat);
-
- memset(threads, 0, sizeof(ParticleThread)*totthread);
-
- for (i=0; i<totthread; i++) {
- threads[i].ctx= ctx;
- threads[i].num= i;
- threads[i].tot= totthread;
+ /* threads */
+ for (i = 0; i < numtasks; ++i) {
+ if (tasks[i].rng)
+ BLI_rng_free(tasks[i].rng);
+ if (tasks[i].rng_path)
+ BLI_rng_free(tasks[i].rng_path);
}
- return threads;
+ MEM_freeN(tasks);
}
-void psys_threads_free(ParticleThread *threads)
+void psys_thread_context_free(ParticleThreadContext *ctx)
{
- ParticleThreadContext *ctx= threads[0].ctx;
- int i, totthread= threads[0].tot;
-
/* path caching */
if (ctx->vg_length)
MEM_freeN(ctx->vg_length);
@@ -1527,17 +514,6 @@ void psys_threads_free(ParticleThread *threads)
if (ctx->seams) MEM_freeN(ctx->seams);
//if (ctx->vertpart) MEM_freeN(ctx->vertpart);
BLI_kdtree_free(ctx->tree);
-
- /* threads */
- for (i=0; i<totthread; i++) {
- if (threads[i].rng)
- BLI_rng_free(threads[i].rng);
- if (threads[i].rng_path)
- BLI_rng_free(threads[i].rng_path);
- }
-
- MEM_freeN(ctx);
- MEM_freeN(threads);
}
static void initialize_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p)
@@ -1670,7 +646,7 @@ static void get_angular_velocity_vector(short avemode, ParticleKey *state, float
}
}
-void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, ParticleKey *state, float dtime, float cfra)
+void psys_get_birth_coords(ParticleSimulationData *sim, ParticleData *pa, ParticleKey *state, float dtime, float cfra)
{
Object *ob = sim->ob;
ParticleSystem *psys = sim->psys;
@@ -2002,7 +978,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
psys->flag |= PSYS_OB_ANIM_RESTORE;
}
- psys_get_birth_coordinates(sim, pa, &pa->state, dtime, cfra);
+ psys_get_birth_coords(sim, pa, &pa->state, dtime, cfra);
/* Initialize particle settings which depends on texture.
*
@@ -2215,7 +1191,7 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
ParticleSettings *part = psys->part;
*sfra = MAX2(1, (int)part->sta);
- *efra = MIN2((int)(part->end + part->lifetime + 1.0f), scene->r.efra);
+ *efra = MIN2((int)(part->end + part->lifetime + 1.0f), MAX2(scene->r.pefra, scene->r.efra));
}
/************************************************/
@@ -2764,24 +1740,6 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
sphdata->pass++;
}
-/* powf is really slow for raising to integer powers. */
-MINLINE float pow2(float x)
-{
- return x * x;
-}
-MINLINE float pow3(float x)
-{
- return pow2(x) * x;
-}
-MINLINE float pow4(float x)
-{
- return pow2(pow2(x));
-}
-MINLINE float pow7(float x)
-{
- return pow2(pow3(x)) * x;
-}
-
static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSED(squared_dist))
{
SPHRangeData *pfr = (SPHRangeData *)userdata;
@@ -2803,7 +1761,7 @@ static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSE
/* Smoothing factor. Utilise the Wendland kernel. gnuplot:
* q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x)
* plot [0:2] q1(x) */
- q = qfac / pow3(pfr->h) * pow4(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h);
+ q = qfac / pow3f(pfr->h) * pow4f(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h);
q *= pfr->npsys->part->mass;
if (pfr->use_size)
@@ -2857,7 +1815,7 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo
float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f);
// Use speed of sound squared
- float stiffness = pow2(fluid->stiffness_k);
+ float stiffness = pow2f(fluid->stiffness_k);
ParticleData *npa;
float vec[3];
@@ -2878,10 +1836,10 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo
pfr.pa = pa;
sph_evaluate_func(NULL, psys, state->co, &pfr, interaction_radius, sphclassical_neighbour_accum_cb);
- pressure = stiffness * (pow7(pa->sphdensity / rest_density) - 1.0f);
+ pressure = stiffness * (pow7f(pa->sphdensity / rest_density) - 1.0f);
/* multiply by mass so that we return a force, not accel */
- qfac2 *= sphdata->mass / pow3(pfr.h);
+ qfac2 *= sphdata->mass / pow3f(pfr.h);
pfn = pfr.neighbors;
for (i = 0; i < pfr.tot_neighbors; i++, pfn++) {
@@ -2902,19 +1860,19 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo
if (rij_h > 2.0f)
continue;
- npressure = stiffness * (pow7(npa->sphdensity / rest_density) - 1.0f);
+ npressure = stiffness * (pow7f(npa->sphdensity / rest_density) - 1.0f);
/* First derivative of smoothing factor. Utilise the Wendland kernel.
* gnuplot:
* q2(x) = 2.0 * (2.0 - x)**4 - 4.0 * (2.0 - x)**3 * (1.0 + 2.0 * x)
* plot [0:2] q2(x)
* Particles > 2h away are excluded above. */
- dq = qfac2 * (2.0f * pow4(2.0f - rij_h) - 4.0f * pow3(2.0f - rij_h) * (1.0f + 2.0f * rij_h) );
+ dq = qfac2 * (2.0f * pow4f(2.0f - rij_h) - 4.0f * pow3f(2.0f - rij_h) * (1.0f + 2.0f * rij_h) );
if (pfn->psys->part->flag & PART_SIZEMASS)
dq *= npa->size;
- pressureTerm = pressure / pow2(pa->sphdensity) + npressure / pow2(npa->sphdensity);
+ pressureTerm = pressure / pow2f(pa->sphdensity) + npressure / pow2f(npa->sphdensity);
/* Note that 'minus' is removed, because vec = vecBA, not vecAB.
* This applies to the viscosity calculation below, too. */
@@ -3128,7 +2086,7 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa
tkey.time=pa->state.time;
if (part->type != PART_HAIR) {
- if (do_guides(sim->psys->effectors, &tkey, p, time)) {
+ if (do_guides(sim->psys->part, sim->psys->effectors, &tkey, p, time)) {
copy_v3_v3(pa->state.co,tkey.co);
/* guides don't produce valid velocity */
sub_v3_v3v3(pa->state.vel, tkey.co, pa->prev_state.co);
@@ -3923,7 +2881,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
Base *base;
int distr=0, alloc=0, skip=0;
- if ((psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
+ if ((psys->part->childtype && psys->totchild != psys_get_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
alloc=1;
if (alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT)))
@@ -3933,7 +2891,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
if (alloc)
realloc_particles(sim, sim->psys->totpart);
- if (get_psys_tot_child(sim->scene, psys)) {
+ if (psys_get_tot_child(sim->scene, psys)) {
/* don't generate children while computing the hair keys */
if (!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
distribute_particles(sim, PART_FROM_CHILD);
@@ -3994,125 +2952,234 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
psys_free_path_cache(psys, NULL);
}
-static void do_hair_dynamics(ParticleSimulationData *sim)
+static bool psys_hair_use_simulation(ParticleData *pa, float max_length)
{
- ParticleSystem *psys = sim->psys;
- DerivedMesh *dm = psys->hair_in_dm;
- MVert *mvert = NULL;
- MEdge *medge = NULL;
- MDeformVert *dvert = NULL;
+ /* Minimum segment length relative to average length.
+ * Hairs with segments below this length will be excluded from the simulation,
+ * because otherwise the solver will become unstable.
+ * The hair system should always make sure the hair segments have reasonable length ratios,
+ * but this can happen in old files when e.g. cutting hair.
+ */
+ const float min_length = 0.1f * max_length;
+
HairKey *key;
- PARTICLE_P;
- int totpoint = 0;
- int totedge;
int k;
- float hairmat[4][4];
- float (*deformedVerts)[3];
-
- if (!psys->clmd) {
- psys->clmd = (ClothModifierData*)modifier_new(eModifierType_Cloth);
- psys->clmd->sim_parms->goalspring = 0.0f;
- psys->clmd->sim_parms->vel_damping = 1.0f;
- psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL|CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
- psys->clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_SELF;
+
+ if (pa->totkey < 2)
+ return false;
+
+ for (k=1, key=pa->hair+1; k<pa->totkey; k++,key++) {
+ float length = len_v3v3(key->co, (key-1)->co);
+ if (length < min_length)
+ return false;
}
+
+ return true;
+}
- /* create a dm from hair vertices */
- LOOP_PARTICLES
- totpoint += pa->totkey;
-
- totedge = totpoint;
- totpoint += psys->totpart;
-
- if (dm && (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm))) {
- dm->release(dm);
- dm = psys->hair_in_dm = NULL;
+static MDeformVert *hair_set_pinning(MDeformVert *dvert, float weight)
+{
+ if (dvert) {
+ if (!dvert->totweight) {
+ dvert->dw = MEM_callocN(sizeof(MDeformWeight), "deformWeight");
+ dvert->totweight = 1;
+ }
+
+ dvert->dw->weight = weight;
+ dvert++;
}
+ return dvert;
+}
+static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int totedge, DerivedMesh **r_dm, ClothHairData **r_hairdata)
+{
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part = psys->part;
+ DerivedMesh *dm;
+ ClothHairData *hairdata;
+ MVert *mvert;
+ MEdge *medge;
+ MDeformVert *dvert;
+ HairKey *key;
+ PARTICLE_P;
+ int k, hair_index;
+ float hairmat[4][4];
+ float max_length;
+ float hair_radius;
+
+ dm = *r_dm;
if (!dm) {
- dm = psys->hair_in_dm = CDDM_new(totpoint, totedge, 0, 0, 0);
+ *r_dm = dm = CDDM_new(totpoint, totedge, 0, 0, 0);
DM_add_vert_layer(dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
}
-
mvert = CDDM_get_verts(dm);
medge = CDDM_get_edges(dm);
dvert = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
-
+
+ hairdata = *r_hairdata;
+ if (!hairdata) {
+ *r_hairdata = hairdata = MEM_mallocN(sizeof(ClothHairData) * totpoint, "hair data");
+ }
+
+ /* calculate maximum segment length */
+ max_length = 0.0f;
+ LOOP_PARTICLES {
+ for (k=1, key=pa->hair+1; k<pa->totkey; k++,key++) {
+ float length = len_v3v3(key->co, (key-1)->co);
+ if (max_length < length)
+ max_length = length;
+ }
+ }
+
psys->clmd->sim_parms->vgroup_mass = 1;
-
+
+ /* XXX placeholder for more flexible future hair settings */
+ hair_radius = part->size;
+
/* make vgroup for pin roots etc.. */
- psys->particles->hair_index = 1;
+ hair_index = 1;
LOOP_PARTICLES {
- if (p)
- pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey + 1;
-
+ float root_mat[4][4];
+ float bending_stiffness;
+ bool use_hair;
+
+ pa->hair_index = hair_index;
+ use_hair = psys_hair_use_simulation(pa, max_length);
+
psys_mat_hair_to_object(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
-
+ mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat);
+ normalize_m4(root_mat);
+
+ bending_stiffness = CLAMPIS(1.0f - part->bending_random * psys_frand(psys, p + 666), 0.0f, 1.0f);
+
for (k=0, key=pa->hair; k<pa->totkey; k++,key++) {
+ ClothHairData *hair;
+ float *co, *co_next;
+
+ co = key->co;
+ co_next = (key+1)->co;
/* create fake root before actual root to resist bending */
if (k==0) {
- float temp[3];
- sub_v3_v3v3(temp, key->co, (key+1)->co);
- copy_v3_v3(mvert->co, key->co);
- add_v3_v3v3(mvert->co, mvert->co, temp);
+ hair = &psys->clmd->hairdata[pa->hair_index - 1];
+ copy_v3_v3(hair->loc, root_mat[3]);
+ copy_m3_m4(hair->rot, root_mat);
+
+ hair->radius = hair_radius;
+ hair->bending_stiffness = bending_stiffness;
+
+ add_v3_v3v3(mvert->co, co, co);
+ sub_v3_v3(mvert->co, co_next);
mul_m4_v3(hairmat, mvert->co);
- mvert++;
-
+
medge->v1 = pa->hair_index - 1;
medge->v2 = pa->hair_index;
+
+ dvert = hair_set_pinning(dvert, 1.0f);
+
+ mvert++;
medge++;
-
- if (dvert) {
- if (!dvert->totweight) {
- dvert->dw = MEM_callocN(sizeof(MDeformWeight), "deformWeight");
- dvert->totweight = 1;
- }
-
- dvert->dw->weight = 1.0f;
- dvert++;
- }
}
-
- copy_v3_v3(mvert->co, key->co);
+
+ /* store root transform in cloth data */
+ hair = &psys->clmd->hairdata[pa->hair_index + k];
+ copy_v3_v3(hair->loc, root_mat[3]);
+ copy_m3_m4(hair->rot, root_mat);
+
+ hair->radius = hair_radius;
+ hair->bending_stiffness = bending_stiffness;
+
+ copy_v3_v3(mvert->co, co);
mul_m4_v3(hairmat, mvert->co);
- mvert++;
if (k) {
medge->v1 = pa->hair_index + k - 1;
medge->v2 = pa->hair_index + k;
- medge++;
- }
-
- if (dvert) {
- if (!dvert->totweight) {
- dvert->dw = MEM_callocN(sizeof(MDeformWeight), "deformWeight");
- dvert->totweight = 1;
- }
- /* roots should be 1.0, the rest can be anything from 0.0 to 1.0 */
- dvert->dw->weight = key->weight;
- dvert++;
}
+
+ /* roots and disabled hairs should be 1.0, the rest can be anything from 0.0 to 1.0 */
+ if (use_hair)
+ dvert = hair_set_pinning(dvert, key->weight);
+ else
+ dvert = hair_set_pinning(dvert, 1.0f);
+
+ mvert++;
+ if (k)
+ medge++;
}
+
+ hair_index += pa->totkey + 1;
}
+}
+static void do_hair_dynamics(ParticleSimulationData *sim)
+{
+ ParticleSystem *psys = sim->psys;
+ PARTICLE_P;
+ EffectorWeights *clmd_effweights;
+ int totpoint;
+ int totedge;
+ float (*deformedVerts)[3];
+ bool realloc_roots;
+
+ if (!psys->clmd) {
+ psys->clmd = (ClothModifierData*)modifier_new(eModifierType_Cloth);
+ psys->clmd->sim_parms->goalspring = 0.0f;
+ psys->clmd->sim_parms->vel_damping = 1.0f;
+ psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL|CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
+ psys->clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_SELF;
+ }
+
+ /* count simulated points */
+ totpoint = 0;
+ totedge = 0;
+ LOOP_PARTICLES {
+ /* "out" dm contains all hairs */
+ totedge += pa->totkey;
+ totpoint += pa->totkey + 1; /* +1 for virtual root point */
+ }
+
+ realloc_roots = false; /* whether hair root info array has to be reallocated */
+ if (psys->hair_in_dm) {
+ DerivedMesh *dm = psys->hair_in_dm;
+ if (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm)) {
+ dm->release(dm);
+ psys->hair_in_dm = NULL;
+ realloc_roots = true;
+ }
+ }
+
+ if (!psys->hair_in_dm || !psys->clmd->hairdata || realloc_roots) {
+ if (psys->clmd->hairdata) {
+ MEM_freeN(psys->clmd->hairdata);
+ psys->clmd->hairdata = NULL;
+ }
+ }
+
+ hair_create_input_dm(sim, totpoint, totedge, &psys->hair_in_dm, &psys->clmd->hairdata);
+
if (psys->hair_out_dm)
psys->hair_out_dm->release(psys->hair_out_dm);
-
+
psys->clmd->point_cache = psys->pointcache;
+ /* for hair sim we replace the internal cloth effector weights temporarily
+ * to use the particle settings
+ */
+ clmd_effweights = psys->clmd->sim_parms->effector_weights;
psys->clmd->sim_parms->effector_weights = psys->part->effector_weights;
-
- deformedVerts = MEM_mallocN(sizeof(*deformedVerts) * dm->getNumVerts(dm), "do_hair_dynamics vertexCos");
- psys->hair_out_dm = CDDM_copy(dm);
+
+ deformedVerts = MEM_mallocN(sizeof(*deformedVerts) * psys->hair_in_dm->getNumVerts(psys->hair_in_dm), "do_hair_dynamics vertexCos");
+ psys->hair_out_dm = CDDM_copy(psys->hair_in_dm);
psys->hair_out_dm->getVertCos(psys->hair_out_dm, deformedVerts);
-
- clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, deformedVerts);
-
+
+ clothModifier_do(psys->clmd, sim->scene, sim->ob, psys->hair_in_dm, deformedVerts);
+
CDDM_apply_vert_coords(psys->hair_out_dm, deformedVerts);
-
+
MEM_freeN(deformedVerts);
-
- psys->clmd->sim_parms->effector_weights = NULL;
+
+ /* restore cloth effector weights */
+ psys->clmd->sim_parms->effector_weights = clmd_effweights;
}
static void hair_step(ParticleSimulationData *sim, float cfra)
{
@@ -4503,7 +3570,7 @@ static void update_children(ParticleSimulationData *sim)
/* don't generate children while growing hair - waste of time */
psys_free_children(sim->psys);
else if (sim->psys->part->childtype) {
- if (sim->psys->totchild != get_psys_tot_child(sim->scene, sim->psys))
+ if (sim->psys->totchild != psys_get_tot_child(sim->scene, sim->psys))
distribute_particles(sim, PART_FROM_CHILD);
else {
/* Children are up to date, nothing to do. */
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index ff6fae08460..5e07437d426 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -281,7 +281,7 @@ static int map_insert_vert(PBVH *bvh, GHash *map,
/* Find vertices used by the faces in this node and update the draw buffers */
static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
{
- GHashIterator *iter;
+ GHashIterator gh_iter;
GHash *map;
int i, j, totface;
bool has_visible = false;
@@ -314,22 +314,17 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
"bvh node vert indices");
/* Build the vertex list, unique verts first */
- for (iter = BLI_ghashIterator_new(map), i = 0;
- BLI_ghashIterator_done(iter) == false;
- BLI_ghashIterator_step(iter), ++i)
- {
- void *value = BLI_ghashIterator_getValue(iter);
+ GHASH_ITER (gh_iter, map) {
+ void *value = BLI_ghashIterator_getValue(&gh_iter);
int ndx = GET_INT_FROM_POINTER(value);
if (ndx < 0)
ndx = -ndx + node->uniq_verts - 1;
node->vert_indices[ndx] =
- GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(iter));
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter));
}
- BLI_ghashIterator_free(iter);
-
for (i = 0; i < totface; ++i) {
MFace *f = bvh->faces + node->prim_indices[i];
int sides = f->v4 ? 4 : 3;
@@ -943,7 +938,7 @@ static bool update_search_cb(PBVHNode *node, void *data_v)
if (node->flag & PBVH_Leaf)
return (node->flag & flag) != 0;
- return 1;
+ return true;
}
static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
@@ -1474,10 +1469,10 @@ bool ray_face_intersection(const float ray_start[3],
(t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
{
*fdist = dist;
- return 1;
+ return true;
}
else {
- return 0;
+ return false;
}
}
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index b77407cdcb2..2b9f7cf1bc5 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -50,7 +50,6 @@
#include "BLI_threads.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_system.h"
#include "BLF_translation.h"
@@ -58,6 +57,7 @@
#include "WM_api.h"
+#include "BKE_appdir.h"
#include "BKE_anim.h"
#include "BKE_blender.h"
#include "BKE_cloth.h"
@@ -84,8 +84,12 @@
#endif
#ifdef WITH_LZO
-#include "minilzo.h"
-#define LZO_HEAP_ALLOC(var,size) \
+# ifdef WITH_SYSTEM_LZO
+# include <lzo/lzo1x.h>
+# else
+# include "minilzo.h"
+# endif
+# define LZO_HEAP_ALLOC(var,size) \
lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
#endif
@@ -797,7 +801,7 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v)
/* version header */
ptcache_file_read(pf, version, 4, sizeof(char));
- if (strncmp(version, SMOKE_CACHE_VERSION, 4))
+ if (!STREQLEN(version, SMOKE_CACHE_VERSION, 4))
{
/* reset file pointer */
fseek(pf->fp, -4, SEEK_CUR);
@@ -979,7 +983,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
/* version header */
ptcache_file_read(pf, version, 1, sizeof(char) * 4);
- if (strncmp(version, DPAINT_CACHE_VERSION, 4)) {
+ if (!STREQLEN(version, DPAINT_CACHE_VERSION, 4)) {
printf("Dynamic Paint: Invalid cache version: '%c%c%c%c'!\n", UNPACK4(version));
return 0;
}
@@ -1068,8 +1072,6 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl
{
RigidBodyWorld *rbw = rb_v;
Object *ob = NULL;
- ParticleKey keys[4];
- float dfra;
if (rbw->objects)
ob = rbw->objects[index];
@@ -1078,6 +1080,11 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl
RigidBodyOb *rbo = ob->rigidbody_object;
if (rbo->type == RBO_TYPE_ACTIVE) {
+ ParticleKey keys[4];
+ ParticleKey result;
+ float dfra;
+
+ memset(keys, 0, sizeof(keys));
copy_v3_v3(keys[1].co, rbo->pos);
copy_qt_qt(keys[1].rot, rbo->orn);
@@ -1087,16 +1094,17 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl
memcpy(keys[2].rot, data + 3, 4 * sizeof(float));
}
else {
- BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2);
+ BKE_ptcache_make_particle_key(&keys[2], 0, data, cfra2);
}
dfra = cfra2 - cfra1;
- psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, keys, 1);
- interp_qt_qtqt(keys->rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra);
+ /* note: keys[0] and keys[3] unused for type < 1 (crappy) */
+ psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &result, true);
+ interp_qt_qtqt(result.rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra);
- copy_v3_v3(rbo->pos, keys->co);
- copy_qt_qt(rbo->orn, keys->rot);
+ copy_v3_v3(rbo->pos, result.co);
+ copy_qt_qt(rbo->orn, result.rot);
}
}
}
@@ -1490,7 +1498,7 @@ static int ptcache_path(PTCacheID *pid, char *filename)
/* use the temp path. this is weak but better then not using point cache at all */
/* temporary directory is assumed to exist and ALWAYS has a trailing slash */
- BLI_snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH, BLI_temp_dir_session());
+ BLI_snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH, BKE_tempdir_session());
return BLI_add_slash(filename); /* new strlen() */
}
@@ -1737,7 +1745,7 @@ static int ptcache_file_header_begin_read(PTCacheFile *pf)
if (fread(bphysics, sizeof(char), 8, pf->fp) != 8)
error = 1;
- if (!error && strncmp(bphysics, "BPHYSICS", 8))
+ if (!error && !STREQLEN(bphysics, "BPHYSICS", 8))
error = 1;
if (!error && !fread(&typeflag, sizeof(unsigned int), 1, pf->fp))
@@ -2468,7 +2476,7 @@ static int ptcache_write_needed(PTCacheID *pid, int cfra, int *overwrite)
PointCache *cache = pid->cache;
int ofra = 0, efra = cache->endframe;
- /* allways start from scratch on the first frame */
+ /* always start from scratch on the first frame */
if (cfra && cfra == cache->startframe) {
BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, cfra);
cache->flag &= ~PTCACHE_REDO_NEEDED;
@@ -2592,17 +2600,24 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
if (pid->cache->flag & PTCACHE_DISK_CACHE) {
ptcache_path(pid, path);
- len = ptcache_filename(pid, filename, cfra, 0, 0); /* no path */
-
dir = opendir(path);
if (dir==NULL)
return;
-
+
+ len = ptcache_filename(pid, filename, cfra, 0, 0); /* no path */
+ /* append underscore terminator to ensure we don't match similar names
+ * from objects whose names start with the same prefix
+ */
+ if (len < sizeof(filename) - 2) {
+ BLI_strncpy(filename + len, "_", sizeof(filename) - 2 - len);
+ len += 1;
+ }
+
BLI_snprintf(ext, sizeof(ext), "_%02u"PTCACHE_EXT, pid->stack_index);
while ((de = readdir(dir)) != NULL) {
if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
- if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+ if (STREQLEN(filename, de->d_name, len)) { /* do we have the right prefix */
if (mode == PTCACHE_CLEAR_ALL) {
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
@@ -2808,7 +2823,7 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
while ((de = readdir(dir)) != NULL) {
if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
- if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+ if (STREQLEN(filename, de->d_name, len)) { /* do we have the right prefix */
/* read the number of the file */
unsigned int frame, len2 = (int)strlen(de->d_name);
char num[7];
@@ -2989,7 +3004,7 @@ void BKE_ptcache_remove(void)
return;
while ((de = readdir(dir)) != NULL) {
- if ( strcmp(de->d_name, ".")==0 || strcmp(de->d_name, "..")==0) {
+ if (FILENAME_IS_CURRPAR(de->d_name)) {
/* do nothing */
}
else if (strstr(de->d_name, PTCACHE_EXT)) { /* do we have the right extension?*/
@@ -3546,7 +3561,7 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const c
while ((de = readdir(dir)) != NULL) {
if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
- if (strncmp(old_filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+ if (STREQLEN(old_filename, de->d_name, len)) { /* do we have the right prefix */
/* read the number of the file */
int frame, len2 = (int)strlen(de->d_name);
char num[7];
@@ -3601,7 +3616,7 @@ void BKE_ptcache_load_external(PTCacheID *pid)
while ((de = readdir(dir)) != NULL) {
if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
- if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+ if (STREQLEN(filename, de->d_name, len)) { /* do we have the right prefix */
/* read the number of the file */
int frame, len2 = (int)strlen(de->d_name);
char num[7];
diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c
index bb04d548a44..100df5fd121 100644
--- a/source/blender/blenkernel/intern/property.c
+++ b/source/blender/blenkernel/intern/property.c
@@ -131,60 +131,6 @@ bProperty *BKE_bproperty_new(int type)
return prop;
}
-/* used by BKE_bproperty_unique() only */
-static bProperty *bproperty_get(bProperty *first, bProperty *self, const char *name)
-{
- bProperty *p;
- for (p = first; p; p = p->next) {
- if (p != self && (strcmp(p->name, name) == 0))
- return p;
- }
- return NULL;
-}
-void BKE_bproperty_unique(bProperty *first, bProperty *prop, int force)
-{
- bProperty *p;
-
- /* set the first if its not set */
- if (first == NULL) {
- first = prop;
- while (first->prev) {
- first = first->prev;
- }
- }
-
- if (force) {
- /* change other names to make them unique */
- while ((p = bproperty_get(first, prop, prop->name))) {
- BKE_bproperty_unique(first, p, 0);
- }
- }
- else {
- /* change our own name until its unique */
- if (bproperty_get(first, prop, prop->name)) {
- /* there is a collision */
- char new_name[sizeof(prop->name)];
- char base_name[sizeof(prop->name)];
- char num[sizeof(prop->name)];
- int i = 0;
-
- /* strip numbers */
- BLI_strncpy(base_name, prop->name, sizeof(base_name));
- for (i = strlen(base_name) - 1; (i >= 0 && isdigit(base_name[i])); i--) {
- base_name[i] = '\0';
- }
- i = 0;
-
- do { /* ensure we have enough chars for the new number in the name */
- const size_t num_len = BLI_snprintf(num, sizeof(num), "%d", i++);
- BLI_snprintf(new_name, sizeof(prop->name),
- "%.*s%s", (int)(sizeof(prop->name) - num_len), base_name, num);
- } while (bproperty_get(first, prop, new_name));
-
- BLI_strncpy(prop->name, new_name, sizeof(prop->name));
- }
- }
-}
bProperty *BKE_bproperty_object_get(Object *ob, const char *name)
{
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 3d61b0bdefb..aaf54b82f32 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -62,8 +62,6 @@
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
-#include "RNA_access.h"
-
#ifdef WITH_BULLET
/* ************************************** */
@@ -401,7 +399,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
height = size[2];
}
else if (rbo->shape == RB_SHAPE_SPHERE) {
- /* take radius to the the largest dimension to try and encompass everything */
+ /* take radius to the largest dimension to try and encompass everything */
radius = MAX3(size[0], size[1], size[2]);
}
@@ -440,6 +438,10 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
new_shape = rigidbody_get_shape_trimesh_from_mesh(ob);
break;
}
+ /* use box shape if we can't fall back to old shape */
+ if (new_shape == NULL && rbo->physics_shape == NULL) {
+ new_shape = RB_shape_new_box(size[0], size[1], size[2]);
+ }
/* assign new collision shape if creation was successful */
if (new_shape) {
if (rbo->physics_shape)
@@ -447,11 +449,6 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
rbo->physics_shape = new_shape;
RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo));
}
- /* use box shape if we can't fall back to old shape */
- else if (rbo->physics_shape == NULL) {
- rbo->shape = RB_SHAPE_BOX;
- rigidbody_validate_sim_shape(ob, true);
- }
}
/* --------------------- */
@@ -483,7 +480,7 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
height = size[2];
}
else if (rbo->shape == RB_SHAPE_SPHERE) {
- /* take radius to the the largest dimension to try and encompass everything */
+ /* take radius to the largest dimension to try and encompass everything */
radius = max_fff(size[0], size[1], size[2]) * 0.5f;
}
@@ -1158,7 +1155,7 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
GroupObject *go;
int i, n;
- n = BLI_countlist(&rbw->group->gobject);
+ n = BLI_listbase_count(&rbw->group->gobject);
if (rbw->numbodies != n) {
rbw->numbodies = n;
@@ -1499,7 +1496,7 @@ void BKE_rigidbody_rebuild_world(Scene *scene, float ctime)
cache = rbw->pointcache;
/* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */
- if (rbw->physics_world == NULL || rbw->numbodies != BLI_countlist(&rbw->group->gobject)) {
+ if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->gobject)) {
cache->flag |= PTCACHE_OUTDATED;
}
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 4be75344133..c902659c039 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -323,15 +323,23 @@ void unlink_actuators(ListBase *lb)
void free_actuator(bActuator *act)
{
- bSoundActuator *sa;
-
if (act->data) {
switch (act->type) {
- case ACT_SOUND:
- sa = (bSoundActuator *) act->data;
- if (sa->sound)
- id_us_min((ID *) sa->sound);
- break;
+ case ACT_ACTION:
+ case ACT_SHAPEACTION:
+ {
+ bActionActuator *aa = (bActionActuator *)act->data;
+ if (aa->act)
+ id_us_min((ID *)aa->act);
+ break;
+ }
+ case ACT_SOUND:
+ {
+ bSoundActuator *sa = (bSoundActuator *) act->data;
+ if (sa->sound)
+ id_us_min((ID *)sa->sound);
+ break;
+ }
}
MEM_freeN(act->data);
@@ -351,7 +359,6 @@ void free_actuators(ListBase *lb)
bActuator *copy_actuator(bActuator *act)
{
bActuator *actn;
- bSoundActuator *sa;
act->mynew=actn= MEM_dupallocN(act);
actn->flag |= ACT_NEW;
@@ -360,11 +367,21 @@ bActuator *copy_actuator(bActuator *act)
}
switch (act->type) {
+ case ACT_ACTION:
+ case ACT_SHAPEACTION:
+ {
+ bActionActuator *aa = (bActionActuator *)act->data;
+ if (aa->act)
+ id_us_plus((ID *)aa->act);
+ break;
+ }
case ACT_SOUND:
- sa= (bSoundActuator *)act->data;
+ {
+ bSoundActuator *sa = (bSoundActuator *)act->data;
if (sa->sound)
- id_us_plus((ID *) sa->sound);
+ id_us_plus((ID *)sa->sound);
break;
+ }
}
return actn;
}
@@ -479,7 +496,7 @@ void init_actuator(bActuator *act)
sta->turnspeed = 120.f;
sta->dist = 1.f;
sta->velocity= 3.f;
- sta->flag = ACT_STEERING_AUTOMATICFACING;
+ sta->flag = ACT_STEERING_AUTOMATICFACING | ACT_STEERING_LOCKZVEL;
sta->facingaxis = 1;
break;
case ACT_MOUSE:
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 5bfd6e8a120..f94f7cd8f0b 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -63,12 +63,14 @@
#include "BKE_anim.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
+#include "BKE_armature.h"
#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
#include "BKE_editmesh.h"
#include "BKE_fcurve.h"
#include "BKE_freestyle.h"
#include "BKE_global.h"
+#include "BKE_gpencil.h"
#include "BKE_group.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
@@ -98,6 +100,10 @@
# include <sys/time.h>
#endif
+const char *RE_engine_id_BLENDER_RENDER = "BLENDER_RENDER";
+const char *RE_engine_id_BLENDER_GAME = "BLENDER_GAME";
+const char *RE_engine_id_CYCLES = "CYCLES";
+
void free_avicodecdata(AviCodecData *acd)
{
if (acd) {
@@ -303,6 +309,19 @@ Scene *BKE_scene_copy(Scene *sce, int type)
BKE_sequence_base_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL);
}
}
+
+ /* grease pencil */
+ if (scen->gpd) {
+ if (type == SCE_COPY_FULL) {
+ scen->gpd = gpencil_data_duplicate(scen->gpd, false);
+ }
+ else if (type == SCE_COPY_EMPTY) {
+ scen->gpd = NULL;
+ }
+ else {
+ id_us_plus((ID *)scen->gpd);
+ }
+ }
return scen;
}
@@ -595,7 +614,7 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
sce->r.ffcodecdata.audio_bitrate = 192;
sce->r.ffcodecdata.audio_channels = 2;
- BLI_strncpy(sce->r.engine, "BLENDER_RENDER", sizeof(sce->r.engine));
+ BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_RENDER, sizeof(sce->r.engine));
sce->audio.distance_model = 2.0f;
sce->audio.doppler_factor = 1.0f;
@@ -670,6 +689,12 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
BLI_strncpy(sce->sequencer_colorspace_settings.name, colorspace_name,
sizeof(sce->sequencer_colorspace_settings.name));
+ /* Safe Areas */
+ copy_v2_fl2(sce->safe_areas.title, 3.5f / 100.0f, 3.5f / 100.0f);
+ copy_v2_fl2(sce->safe_areas.action, 10.0f / 100.0f, 5.0f / 100.0f);
+ copy_v2_fl2(sce->safe_areas.title_center, 17.5f / 100.0f, 5.0f / 100.0f);
+ copy_v2_fl2(sce->safe_areas.action_center, 15.0f / 100.0f, 5.0f / 100.0f);
+
return sce;
}
@@ -1092,27 +1117,24 @@ void BKE_scene_base_select(Scene *sce, Base *selbase)
}
/* checks for cycle, returns 1 if it's all OK */
-int BKE_scene_validate_setscene(Main *bmain, Scene *sce)
+bool BKE_scene_validate_setscene(Main *bmain, Scene *sce)
{
- Scene *scene;
+ Scene *sce_iter;
int a, totscene;
+
+ if (sce->set == NULL) return true;
+ totscene = BLI_listbase_count(&bmain->scene);
- if (sce->set == NULL) return 1;
-
- totscene = 0;
- for (scene = bmain->scene.first; scene; scene = scene->id.next)
- totscene++;
-
- for (a = 0, scene = sce; scene->set; scene = scene->set, a++) {
+ for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) {
/* more iterations than scenes means we have a cycle */
if (a > totscene) {
/* the tested scene gets zero'ed, that's typically current scene */
sce->set = NULL;
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
/* This function is needed to cope with fractional frames - including two Blender rendering features
@@ -1242,8 +1264,35 @@ static void scene_depsgraph_hack(EvaluationContext *eval_ctx, Scene *scene, Scen
}
}
}
+}
+
+/* That's like really a bummer, because currently animation data for armatures
+ * might want to use pose, and pose might be missing on the object.
+ * This happens when changing visible layers, which leads to situations when
+ * pose is missing or marked for recalc, animation will change it and then
+ * object update will restore the pose.
+ *
+ * This could be solved by the new dependency graph, but for until then we'll
+ * do an extra pass on the objects to ensure it's all fine.
+ */
+#define POSE_ANIMATION_WORKAROUND
+#ifdef POSE_ANIMATION_WORKAROUND
+static void scene_armature_depsgraph_workaround(Main *bmain)
+{
+ Object *ob;
+ if (BLI_listbase_is_empty(&bmain->armature) || !DAG_id_type_tagged(bmain, ID_OB)) {
+ return;
+ }
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->type == OB_ARMATURE && ob->adt && ob->adt->recalc & ADT_RECALC_ANIM) {
+ if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) {
+ BKE_pose_rebuild(ob, ob->data);
+ }
+ }
+ }
}
+#endif
static void scene_rebuild_rbw_recursive(Scene *scene, float ctime)
{
@@ -1593,9 +1642,9 @@ static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene)
Object *obedit = scene->obedit;
if (obedit) {
Mesh *mesh = obedit->data;
- /* TODO(sergey): Check object recalc flags as well? */
if ((obedit->type == OB_MESH) &&
- (mesh->id.flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)))
+ ((obedit->id.flag & LIB_ID_RECALC_ALL) ||
+ (mesh->id.flag & LIB_ID_RECALC_ALL)))
{
if (check_rendered_viewport_visible(bmain)) {
BMesh *bm = mesh->edit_btmesh->bm;
@@ -1736,6 +1785,10 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
BKE_mask_evaluate_all_masks(bmain, ctime, true);
+#ifdef POSE_ANIMATION_WORKAROUND
+ scene_armature_depsgraph_workaround(bmain);
+#endif
+
/* All 'standard' (i.e. without any dependencies) animation is handled here,
* with an 'local' to 'macro' order of evaluation. This should ensure that
* settings stored nestled within a hierarchy (i.e. settings in a Texture block
@@ -1805,13 +1858,13 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *
Scene *sce;
if (act == -1) {
- return 0;
+ return false;
}
else if ( (scene->r.layers.first == scene->r.layers.last) &&
(scene->r.layers.first == srl))
{
/* ensure 1 layer is kept */
- return 0;
+ return false;
}
BLI_remlink(&scene->r.layers, srl);
@@ -1833,7 +1886,7 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *
}
}
- return 1;
+ return true;
}
/* render simplification */
@@ -1902,9 +1955,13 @@ bool BKE_scene_use_new_shading_nodes(Scene *scene)
bool BKE_scene_uses_blender_internal(struct Scene *scene)
{
- return strcmp("BLENDER_RENDER", scene->r.engine) == 0;
+ return STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER);
}
+bool BKE_scene_uses_blender_game(struct Scene *scene)
+{
+ return STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME);
+}
void BKE_scene_base_flag_to_objects(struct Scene *scene)
{
@@ -1946,7 +2003,7 @@ void BKE_scene_disable_color_management(Scene *scene)
bool BKE_scene_check_color_management_enabled(const Scene *scene)
{
- return strcmp(scene->display_settings.display_device, "None") != 0;
+ return !STREQ(scene->display_settings.display_device, "None");
}
bool BKE_scene_check_rigidbody_active(const Scene *scene)
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index b2296151cf7..a6ac4551f4a 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -39,6 +39,8 @@
#include "MEM_guardedalloc.h"
+#include "GPU_compositing.h"
+
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -46,6 +48,7 @@
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
+#include "BLI_rect.h"
#include "BKE_idprop.h"
#include "BKE_screen.h"
@@ -137,7 +140,7 @@ void BKE_spacetype_register(SpaceType *st)
BLI_addtail(&spacetypes, st);
}
-int BKE_spacetype_exists(int spaceid)
+bool BKE_spacetype_exists(int spaceid)
{
return BKE_spacetype_from_id(spaceid) != NULL;
}
@@ -402,16 +405,34 @@ ARegion *BKE_area_find_region_active_win(ScrArea *sa)
return NULL;
}
-/* note, using this function is generally a last resort, you really want to be
+/**
+ * \note, ideally we can get the area from the context,
+ * there are a few places however where this isn't practical.
+ */
+ScrArea *BKE_screen_find_area_from_space(struct bScreen *sc, SpaceLink *sl)
+{
+ ScrArea *sa;
+
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ if (BLI_findindex(&sa->spacedata, sl) != -1) {
+ break;
+ }
+ }
+
+ return sa;
+}
+
+/**
+ * \note Using this function is generally a last resort, you really want to be
* using the context when you can - campbell
- * -1 for any type */
+ */
ScrArea *BKE_screen_find_big_area(bScreen *sc, const int spacetype, const short min)
{
ScrArea *sa, *big = NULL;
int size, maxsize = 0;
for (sa = sc->areabase.first; sa; sa = sa->next) {
- if ((spacetype == -1) || sa->spacetype == spacetype) {
+ if ((spacetype == SPACE_TYPE_ANY) || (sa->spacetype == spacetype)) {
if (min <= sa->winx && min <= sa->winy) {
size = sa->winx * sa->winy;
if (size > maxsize) {
@@ -425,6 +446,22 @@ ScrArea *BKE_screen_find_big_area(bScreen *sc, const int spacetype, const short
return big;
}
+ScrArea *BKE_screen_find_area_xy(bScreen *sc, const int spacetype, int x, int y)
+{
+ ScrArea *sa, *sa_found = NULL;
+
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ if (BLI_rcti_isect_pt(&sa->totrct, x, y)) {
+ if ((spacetype == SPACE_TYPE_ANY) || (sa->spacetype == spacetype)) {
+ sa_found = sa;
+ }
+ break;
+ }
+ }
+ return sa_found;
+}
+
+
/**
* Utility function to get the active layer to use when adding new objects.
*/
@@ -563,3 +600,26 @@ float BKE_screen_view3d_zoom_from_fac(float zoomfac)
{
return ((sqrtf(4.0f * zoomfac) - (float)M_SQRT2) * 50.0f);
}
+
+void BKE_screen_gpu_fx_validate(GPUFXSettings *fx_settings)
+{
+ /* currently we use DOF from the camera _only_,
+ * so we never allocate this, only copy from the Camera */
+#if 0
+ if ((fx_settings->dof == NULL) &&
+ (fx_settings->fx_flag & GPU_FX_FLAG_DOF))
+ {
+ GPUDOFSettings *fx_dof;
+ fx_dof = fx_settings->dof = MEM_callocN(sizeof(GPUDOFSettings), __func__);
+ }
+#endif
+
+ if ((fx_settings->ssao == NULL) &&
+ (fx_settings->fx_flag & GPU_FX_FLAG_SSAO))
+ {
+ GPUSSAOSettings *fx_ssao;
+ fx_ssao = fx_settings->ssao = MEM_callocN(sizeof(GPUSSAOSettings), __func__);
+
+ GPU_fx_compositor_init_ssao_settings(fx_ssao);
+ }
+}
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index 4268b33cb14..41f17665065 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -46,7 +46,7 @@ typedef struct SeqCacheKey {
struct Sequence *seq;
SeqRenderData context;
float cfra;
- seq_stripelem_ibuf_t type;
+ eSeqStripElemIBuf type;
} SeqCacheKey;
typedef struct SeqPreprocessCacheElem {
@@ -54,7 +54,7 @@ typedef struct SeqPreprocessCacheElem {
struct Sequence *seq;
SeqRenderData context;
- seq_stripelem_ibuf_t type;
+ eSeqStripElemIBuf type;
ImBuf *ibuf;
} SeqPreprocessCacheElem;
@@ -95,10 +95,10 @@ static unsigned int seq_hash_render_data(const SeqRenderData *a)
static unsigned int seqcache_hashhash(const void *key_)
{
- const SeqCacheKey *key = (SeqCacheKey *) key_;
+ const SeqCacheKey *key = key_;
unsigned int rval = seq_hash_render_data(&key->context);
- rval ^= *(unsigned int *) &key->cfra;
+ rval ^= *(const unsigned int *) &key->cfra;
rval += key->type;
rval ^= ((intptr_t) key->seq) << 6;
@@ -107,8 +107,8 @@ static unsigned int seqcache_hashhash(const void *key_)
static bool seqcache_hashcmp(const void *a_, const void *b_)
{
- const SeqCacheKey *a = (SeqCacheKey *) a_;
- const SeqCacheKey *b = (SeqCacheKey *) b_;
+ const SeqCacheKey *a = a_;
+ const SeqCacheKey *b = b_;
return ((a->seq != b->seq) ||
(a->cfra != b->cfra) ||
@@ -148,7 +148,7 @@ void BKE_sequencer_cache_cleanup_sequence(Sequence *seq)
IMB_moviecache_cleanup(moviecache, seqcache_key_check_seq, seq);
}
-struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type)
+struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context, Sequence *seq, float cfra, eSeqStripElemIBuf type)
{
if (moviecache && seq) {
SeqCacheKey key;
@@ -164,7 +164,7 @@ struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context, Sequence *se
return NULL;
}
-void BKE_sequencer_cache_put(const SeqRenderData *context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type, ImBuf *i)
+void BKE_sequencer_cache_put(const SeqRenderData *context, Sequence *seq, float cfra, eSeqStripElemIBuf type, ImBuf *i)
{
SeqCacheKey key;
@@ -210,7 +210,7 @@ static void preprocessed_cache_destruct(void)
preprocess_cache = NULL;
}
-ImBuf *BKE_sequencer_preprocessed_cache_get(const SeqRenderData *context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type)
+ImBuf *BKE_sequencer_preprocessed_cache_get(const SeqRenderData *context, Sequence *seq, float cfra, eSeqStripElemIBuf type)
{
SeqPreprocessCacheElem *elem;
@@ -237,7 +237,7 @@ ImBuf *BKE_sequencer_preprocessed_cache_get(const SeqRenderData *context, Sequen
return NULL;
}
-void BKE_sequencer_preprocessed_cache_put(const SeqRenderData *context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type, ImBuf *ibuf)
+void BKE_sequencer_preprocessed_cache_put(const SeqRenderData *context, Sequence *seq, float cfra, eSeqStripElemIBuf type, ImBuf *ibuf)
{
SeqPreprocessCacheElem *elem;
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 11a6cb7acc3..6157d63047e 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2670,8 +2670,8 @@ static void do_gaussian_blur_effect_byte(Sequence *seq,
{
#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
GaussianBlurVars *data = seq->effectdata;
- const int size_x = (int) (data->size_x + 0.5f),
- size_y = (int) (data->size_y + 0.5f);
+ const int size_x = (int) (data->size_x + 0.5f);
+ const int size_y = (int) (data->size_y + 0.5f);
int i, j;
/* Make gaussian weight tabke. */
@@ -2754,8 +2754,8 @@ static void do_gaussian_blur_effect_float(Sequence *seq,
{
#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
GaussianBlurVars *data = seq->effectdata;
- const int size_x = (int) (data->size_x + 0.5f),
- size_y = (int) (data->size_y + 0.5f);
+ const int size_x = (int) (data->size_x + 0.5f);
+ const int size_y = (int) (data->size_y + 0.5f);
int i, j;
/* Make gaussian weight tabke. */
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 0a22faf3c26..cb23b1eb88e 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -515,24 +515,22 @@ void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixe
/*********************** sequencer pipeline functions *************************/
-SeqRenderData BKE_sequencer_new_render_data(EvaluationContext *eval_ctx,
- Main *bmain, Scene *scene, int rectx, int recty,
- int preview_render_size)
-{
- SeqRenderData rval;
-
- rval.bmain = bmain;
- rval.scene = scene;
- rval.rectx = rectx;
- rval.recty = recty;
- rval.preview_render_size = preview_render_size;
- rval.motion_blur_samples = 0;
- rval.motion_blur_shutter = 0;
- rval.eval_ctx = eval_ctx;
- rval.skip_cache = false;
- rval.is_proxy_render = false;
-
- return rval;
+void BKE_sequencer_new_render_data(
+ EvaluationContext *eval_ctx,
+ Main *bmain, Scene *scene, int rectx, int recty,
+ int preview_render_size,
+ SeqRenderData *r_context)
+{
+ r_context->eval_ctx = eval_ctx;
+ r_context->bmain = bmain;
+ r_context->scene = scene;
+ r_context->rectx = rectx;
+ r_context->recty = recty;
+ r_context->preview_render_size = preview_render_size;
+ r_context->motion_blur_samples = 0;
+ r_context->motion_blur_shutter = 0;
+ r_context->skip_cache = false;
+ r_context->is_proxy_render = false;
}
/* ************************* iterator ************************** */
@@ -892,7 +890,6 @@ void BKE_sequencer_sort(Scene *scene)
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *seqt;
-
if (ed == NULL)
return;
@@ -1293,6 +1290,7 @@ typedef struct SeqIndexBuildContext {
int tc_flags;
int size_flags;
int quality;
+ bool overwrite;
Main *bmain;
Scene *scene;
@@ -1332,7 +1330,7 @@ static double seq_rendersize_to_scale_factor(int size)
return 0.25;
}
-static void seq_open_anim_file(Sequence *seq)
+static void seq_open_anim_file(Sequence *seq, bool openfile)
{
char name[FILE_MAX];
StripProxy *proxy;
@@ -1345,8 +1343,14 @@ static void seq_open_anim_file(Sequence *seq)
seq->strip->dir, seq->strip->stripdata->name);
BLI_path_abs(name, G.main->name);
- seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
- seq->streamindex, seq->strip->colorspace_settings.name);
+ if (openfile) {
+ seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
+ seq->streamindex, seq->strip->colorspace_settings.name);
+ }
+ else {
+ seq->anim = openanim_noload(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0),
+ seq->streamindex, seq->strip->colorspace_settings.name);
+ }
if (seq->anim == NULL) {
return;
@@ -1453,14 +1457,14 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
return NULL;
}
- /* proxies are generated in default color space */
- seq->strip->proxy->anim = openanim(name, IB_rect, 0, NULL);
+ seq->strip->proxy->anim = openanim(name, IB_rect, 0,
+ seq->strip->colorspace_settings.name);
}
if (seq->strip->proxy->anim == NULL) {
return NULL;
}
- seq_open_anim_file(seq);
+ seq_open_anim_file(seq, true);
frameno = IMB_anim_index_get_frame_index(seq->anim, seq->strip->proxy->tc, frameno);
@@ -1484,26 +1488,36 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
}
}
-static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, int cfra, int proxy_render_size)
+static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, int cfra,
+ int proxy_render_size, const bool overwrite)
{
char name[PROXY_MAXFILE];
int quality;
int rectx, recty;
int ok;
- ImBuf *ibuf;
+ ImBuf *ibuf_tmp, *ibuf;
if (!seq_proxy_get_fname(seq, cfra, proxy_render_size, name)) {
return;
}
- ibuf = seq_render_strip(context, seq, cfra);
+ if (!overwrite && BLI_exists(name)) {
+ return;
+ }
+
+ ibuf_tmp = seq_render_strip(context, seq, cfra);
- rectx = (proxy_render_size * ibuf->x) / 100;
- recty = (proxy_render_size * ibuf->y) / 100;
+ rectx = (proxy_render_size * ibuf_tmp->x) / 100;
+ recty = (proxy_render_size * ibuf_tmp->y) / 100;
- if (ibuf->x != rectx || ibuf->y != recty) {
+ if (ibuf_tmp->x != rectx || ibuf_tmp->y != recty) {
+ ibuf = IMB_dupImBuf(ibuf_tmp);
+ IMB_freeImBuf(ibuf_tmp);
IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
}
+ else {
+ ibuf = ibuf_tmp;
+ }
/* depth = 32 is intentionally left in, otherwise ALPHA channels
* won't work... */
@@ -1524,7 +1538,7 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i
IMB_freeImBuf(ibuf);
}
-SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *scene, Sequence *seq)
+SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *scene, Sequence *seq, struct GSet *file_list)
{
SeqIndexBuildContext *context;
Sequence *nseq;
@@ -1544,6 +1558,7 @@ SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *sc
context->tc_flags = nseq->strip->proxy->build_tc_flags;
context->size_flags = nseq->strip->proxy->build_size_flags;
context->quality = nseq->strip->proxy->quality;
+ context->overwrite = (nseq->strip->proxy->build_flags & SEQ_PROXY_SKIP_EXISTING) == 0;
context->bmain = bmain;
context->scene = scene;
@@ -1551,11 +1566,12 @@ SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *sc
context->seq = nseq;
if (nseq->type == SEQ_TYPE_MOVIE) {
- seq_open_anim_file(nseq);
+ seq_open_anim_file(nseq, true);
if (nseq->anim) {
context->index_context = IMB_anim_index_rebuild_context(nseq->anim,
- context->tc_flags, context->size_flags, context->quality);
+ context->tc_flags, context->size_flags, context->quality,
+ context->overwrite, file_list);
}
}
@@ -1564,6 +1580,7 @@ SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(Main *bmain, Scene *sc
void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, short *do_update, float *progress)
{
+ const bool overwrite = context->overwrite;
SeqRenderData render_context;
Sequence *seq = context->seq;
Scene *scene = context->scene;
@@ -1589,24 +1606,27 @@ void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, short *stop, sho
/* fail safe code */
- render_context = BKE_sequencer_new_render_data(bmain->eval_ctx, bmain, context->scene,
- (scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f,
- (scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f, 100);
+ BKE_sequencer_new_render_data(
+ bmain->eval_ctx, bmain, context->scene,
+ (scene->r.size * (float) scene->r.xsch) / 100.0f + 0.5f,
+ (scene->r.size * (float) scene->r.ysch) / 100.0f + 0.5f, 100,
+ &render_context);
+
render_context.skip_cache = true;
render_context.is_proxy_render = true;
for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) {
if (context->size_flags & IMB_PROXY_25) {
- seq_proxy_build_frame(&render_context, seq, cfra, 25);
+ seq_proxy_build_frame(&render_context, seq, cfra, 25, overwrite);
}
if (context->size_flags & IMB_PROXY_50) {
- seq_proxy_build_frame(&render_context, seq, cfra, 50);
+ seq_proxy_build_frame(&render_context, seq, cfra, 50, overwrite);
}
if (context->size_flags & IMB_PROXY_75) {
- seq_proxy_build_frame(&render_context, seq, cfra, 75);
+ seq_proxy_build_frame(&render_context, seq, cfra, 75, overwrite);
}
if (context->size_flags & IMB_PROXY_100) {
- seq_proxy_build_frame(&render_context, seq, cfra, 100);
+ seq_proxy_build_frame(&render_context, seq, cfra, 100, overwrite);
}
*progress = (float) (cfra - seq->startdisp - seq->startstill) / (seq->enddisp - seq->endstill - seq->startdisp - seq->startstill);
@@ -1630,6 +1650,22 @@ void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop
MEM_freeN(context);
}
+void BKE_sequencer_proxy_set(struct Sequence *seq, bool value)
+{
+ if (value) {
+ seq->flag |= SEQ_USE_PROXY;
+ if (seq->strip->proxy == NULL) {
+ seq->strip->proxy = MEM_callocN(sizeof(struct StripProxy), "StripProxy");
+ seq->strip->proxy->quality = 90;
+ seq->strip->proxy->build_tc_flags = SEQ_PROXY_TC_ALL;
+ seq->strip->proxy->build_size_flags = SEQ_PROXY_IMAGE_SIZE_25;
+ }
+ }
+ else {
+ seq->flag ^= SEQ_USE_PROXY;
+ }
+}
+
/*********************** color balance *************************/
static StripColorBalance calc_cb(StripColorBalance *cb_)
@@ -2525,6 +2561,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
int do_seq;
// bool have_seq = false; /* UNUSED */
bool have_comp = false;
+ bool use_gpencil = true;
Scene *scene;
int is_thread_main = BLI_thread_is_main();
@@ -2549,6 +2586,10 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
BKE_scene_camera_switch_update(scene);
camera = scene->camera;
}
+
+ if (seq->flag & SEQ_SCENE_NO_GPENCIL) {
+ use_gpencil = false;
+ }
if (have_comp == false && camera == NULL) {
scene->r.cfra = oldcfra;
@@ -2582,7 +2623,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
ibuf = sequencer_view3d_cb(scene, camera, width, height, IB_rect,
context->scene->r.seq_prev_type,
(context->scene->r.seq_flag & R_SEQ_SOLID_TEX) != 0,
- true, scene->r.alphamode, err_out);
+ use_gpencil, true, scene->r.alphamode, err_out);
if (ibuf == NULL) {
fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
}
@@ -2599,7 +2640,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
* When rendering from command line renderer is called from main thread, in this
* case it's always safe to render scene here
*/
- if (!is_thread_main || is_rendering == false || is_background) {
+ if (!is_thread_main || is_rendering == false || is_background || context->eval_ctx->mode == DAG_EVAL_RENDER) {
if (re == NULL)
re = RE_NewRender(scene->id.name);
@@ -2745,15 +2786,22 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, Sequence *s
case SEQ_TYPE_MOVIE:
{
- seq_open_anim_file(seq);
+ seq_open_anim_file(seq, false);
if (seq->anim) {
+ IMB_Proxy_Size proxy_size = seq_rendersize_to_proxysize(context->preview_render_size);
IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
ibuf = IMB_anim_absolute(seq->anim, nr + seq->anim_startofs,
seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
- seq_rendersize_to_proxysize(context->preview_render_size));
+ proxy_size);
+ /* fetching for requested proxy size failed, try fetching the original instead */
+ if (!ibuf && proxy_size != IMB_PROXY_NONE) {
+ ibuf = IMB_anim_absolute(seq->anim, nr + seq->anim_startofs,
+ seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
+ IMB_PROXY_NONE);
+ }
if (ibuf) {
BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false);
@@ -3096,7 +3144,7 @@ ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int cha
if (ed == NULL) return NULL;
if ((chanshown < 0) && !BLI_listbase_is_empty(&ed->metastack)) {
- int count = BLI_countlist(&ed->metastack);
+ int count = BLI_listbase_count(&ed->metastack);
count = max_ii(count + chanshown, 0);
seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep;
}
@@ -3411,7 +3459,7 @@ static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *cha
/* recurs downwards to see if this seq depends on the changed seq */
if (seq == NULL)
- return 0;
+ return false;
if (seq == changed_seq)
free_imbuf = true;
@@ -3529,28 +3577,16 @@ bool BKE_sequence_single_check(Sequence *seq)
}
/* check if the selected seq's reference unselected seq's */
-bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase, bool one_only)
+bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
{
Sequence *seq;
- /* is there a valid selection select */
+ /* is there more than 1 select */
bool ok = false;
- /* is there one selected already? */
- bool first = false;
for (seq = seqbase->first; seq; seq = seq->next) {
if (seq->flag & SELECT) {
- if (one_only) {
- ok = true;
- break;
- }
- else {
- if (first) {
- ok = true;
- break;
- }
- else
- first = true;
- }
+ ok = true;
+ break;
}
}
@@ -3728,21 +3764,23 @@ Sequence *BKE_sequencer_foreground_frame_get(Scene *scene, int frame)
}
/* return 0 if there werent enough space */
-bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
+bool BKE_sequence_base_shuffle_ex(ListBase *seqbasep, Sequence *test, Scene *evil_scene, int channel_delta)
{
- int orig_machine = test->machine;
- test->machine++;
+ const int orig_machine = test->machine;
+ BLI_assert(ELEM(channel_delta, -1, 1));
+
+ test->machine += channel_delta;
BKE_sequence_calc(evil_scene, test);
- while (BKE_sequence_test_overlap(seqbasep, test) ) {
- if (test->machine >= MAXSEQ) {
+ while (BKE_sequence_test_overlap(seqbasep, test)) {
+ if ((channel_delta > 0) ? (test->machine >= MAXSEQ) : (test->machine <= 1)) {
break;
}
- test->machine++;
+
+ test->machine += channel_delta;
BKE_sequence_calc(evil_scene, test); // XXX - I don't think this is needed since were only moving vertically, Campbell.
}
-
- if (test->machine >= MAXSEQ) {
+ if ((test->machine < 1) || (test->machine > MAXSEQ)) {
/* Blender 2.4x would remove the strip.
* nicer to move it to the end */
@@ -3766,6 +3804,11 @@ bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_s
}
}
+bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
+{
+ return BKE_sequence_base_shuffle_ex(seqbasep, test, evil_scene, 1);
+}
+
static int shuffle_seq_time_offset_test(ListBase *seqbasep, char dir)
{
int offset = 0;
@@ -4687,3 +4730,70 @@ bool BKE_sequence_is_valid_check(Sequence *seq)
return true;
}
+int BKE_sequencer_find_next_prev_edit(
+ Scene *scene, int cfra, const short side,
+ const bool do_skip_mute, const bool do_center, const bool do_unselected)
+{
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *seq;
+
+ int dist, best_dist, best_frame = cfra;
+ int seq_frames[2], seq_frames_tot;
+
+ /* in case where both is passed, frame just finds the nearest end while frame_left the nearest start */
+
+ best_dist = MAXFRAME * 2;
+
+ if (ed == NULL) return cfra;
+
+ for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ int i;
+
+ if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
+ continue;
+ }
+
+ if (do_unselected && (seq->flag & SELECT))
+ continue;
+
+ if (do_center) {
+ seq_frames[0] = (seq->startdisp + seq->enddisp) / 2;
+ seq_frames_tot = 1;
+ }
+ else {
+ seq_frames[0] = seq->startdisp;
+ seq_frames[1] = seq->enddisp;
+
+ seq_frames_tot = 2;
+ }
+
+ for (i = 0; i < seq_frames_tot; i++) {
+ const int seq_frame = seq_frames[i];
+
+ dist = MAXFRAME * 2;
+
+ switch (side) {
+ case SEQ_SIDE_LEFT:
+ if (seq_frame < cfra) {
+ dist = cfra - seq_frame;
+ }
+ break;
+ case SEQ_SIDE_RIGHT:
+ if (seq_frame > cfra) {
+ dist = seq_frame - cfra;
+ }
+ break;
+ case SEQ_SIDE_BOTH:
+ dist = abs(seq_frame - cfra);
+ break;
+ }
+
+ if (dist < best_dist) {
+ best_frame = seq_frame;
+ best_dist = dist;
+ }
+ }
+ }
+
+ return best_frame;
+}
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index d2a4d15a2c6..2ff81cd5394 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -52,7 +52,6 @@
#include "BKE_deform.h"
#include "BKE_mesh.h" /* for OMP limits. */
#include "BKE_subsurf.h"
-#include "BKE_editmesh.h"
#include "BLI_strict_flags.h"
@@ -90,7 +89,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
#ifndef __APPLE__
-#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(treeData, calc) schedule(static) if(calc->numVerts > BKE_MESH_OMP_LIMIT)
+#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(treeData, calc) schedule(static) if (calc->numVerts > BKE_MESH_OMP_LIMIT)
#endif
for (i = 0; i < calc->numVerts; ++i) {
float *co = calc->vertexCos[i];
@@ -395,7 +394,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
/* Find the nearest vertex */
#ifndef __APPLE__
-#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(calc, treeData) schedule(static) if(calc->numVerts > BKE_MESH_OMP_LIMIT)
+#pragma omp parallel for default(none) private(i) firstprivate(nearest) shared(calc, treeData) schedule(static) if (calc->numVerts > BKE_MESH_OMP_LIMIT)
#endif
for (i = 0; i < calc->numVerts; ++i) {
float *co = calc->vertexCos[i];
diff --git a/source/blender/blenkernel/intern/sketch.c b/source/blender/blenkernel/intern/sketch.c
index da5dd76681d..0d355abb49b 100644
--- a/source/blender/blenkernel/intern/sketch.c
+++ b/source/blender/blenkernel/intern/sketch.c
@@ -81,6 +81,10 @@ void sk_initPoint(SK_Point *pt, SK_DrawData *dd, const float no[3])
}
pt->p2d[0] = dd->mval[0];
pt->p2d[1] = dd->mval[1];
+
+ pt->size = 0.0f;
+ pt->type = PT_CONTINUOUS;
+ pt->mode = PT_SNAP;
/* more init code here */
}
@@ -192,14 +196,14 @@ void sk_appendStrokePoint(SK_Stroke *stk, SK_Point *pt)
void sk_insertStrokePoints(SK_Stroke *stk, SK_Point *pts, int len, int start, int end)
{
- int size = end - start + 1;
+ int size = end - start;
sk_growStrokeBufferN(stk, len - size);
if (len != size) {
- int tail_size = stk->nb_points - end + 1;
+ int tail_size = stk->nb_points - end;
- memmove(stk->points + start + len, stk->points + end + 1, tail_size * sizeof(SK_Point));
+ memmove(stk->points + start + len, stk->points + end, tail_size * sizeof(SK_Point));
}
memcpy(stk->points + start, pts, len * sizeof(SK_Point));
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 306c5b0c791..7b3c84f7235 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -60,6 +60,7 @@
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
+#include "BKE_appdir.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_bvhutils.h"
@@ -209,7 +210,8 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[
/* smoke_turbulence_init uses non-threadsafe functions from fftw3 lib (like fftw_plan & co). */
BLI_lock_thread(LOCK_FFTW);
- sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BLI_temp_dir_session(), use_fire, use_colors, sds);
+ sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BKE_tempdir_session(), use_fire, use_colors);
+
BLI_unlock_thread(LOCK_FFTW);
sds->res_wt[0] = res[0] * (sds->amplify + 1);
@@ -744,7 +746,8 @@ static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds
BVHTreeFromMesh treeData = {NULL};
int numverts, i, z;
- float surface_distance = 0.6;
+ /* slightly rounded-up sqrt(3 * (0.5)^2) == max. distance of cell boundary along the diagonal */
+ const float surface_distance = 0.867f;
float *vert_vel = NULL;
int has_velocity = 0;
@@ -975,7 +978,7 @@ static bool subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int
/* if other is dynamic paint canvas, don't update */
if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN))
- return 1;
+ return true;
/* if object has parents, update them too */
if (parent_recursion) {
@@ -987,7 +990,7 @@ static bool subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int
/* skip subframe if object is parented
* to vertex of a dynamic paint canvas */
if (is_domain && (ob->partype == PARVERT1 || ob->partype == PARVERT3))
- return 0;
+ return false;
/* also update constraint targets */
for (con = ob->constraints.first; con; con = con->next) {
@@ -1033,7 +1036,7 @@ static bool subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int
BKE_pose_where_is(scene, ob);
}
- return 0;
+ return false;
}
/**********************************************************
@@ -1446,7 +1449,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
static void sample_derivedmesh(
SmokeFlowSettings *sfs, MVert *mvert, MTFace *tface, MFace *mface,
- float *influence_map, float *velocity_map, int index, int base_res[3], float flow_center[3],
+ float *influence_map, float *velocity_map, int index, const int base_res[3], float flow_center[3],
BVHTreeFromMesh *treeData, const float ray_start[3], const float *vert_vel,
bool has_velocity, int defgrp_index, MDeformVert *dvert, float x, float y, float z)
{
@@ -2047,7 +2050,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value
if (fuel && fuel[index] > FLT_EPSILON) {
/* instead of using 1.0 for all new fuel add slight falloff
* to reduce flow blockiness */
- float value = 1.0f - powf(1.0f - emission_value, 2.0f);
+ float value = 1.0f - pow2f(1.0f - emission_value);
if (value > react[index]) {
float f = fuel_flow / fuel[index];
@@ -2157,6 +2160,9 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd
if (sfs->source == MOD_SMOKE_FLOW_SOURCE_PARTICLES) {
/* emit_from_particles() updates timestep internally */
emit_from_particles(collob, sds, sfs, &em_temp, scene, sdt);
+ if (!(sfs->flags & MOD_SMOKE_FLOW_USE_PART_SIZE)) {
+ hires_multiplier = 1;
+ }
}
else { /* MOD_SMOKE_FLOW_SOURCE_MESH */
/* update flow object frame */
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 13575560669..3cc2337d4f1 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -522,10 +522,8 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M)
mima->maxz = max_ff(mima->maxz, v[2] + hull);
}
-
- mima++;
- mface++;
-
+ mima++;
+ mface++;
}
return;
}
@@ -707,7 +705,7 @@ static void add_2nd_order_roller(Object *ob, float UNUSED(stiffness), int *count
}
}
if ((bs2->v2 !=notthis)&&(bs2->v2 > v0)) {
- (*counter)++;/*hit */
+ (*counter)++; /* hit */
if (addsprings) {
bs3->v1= v0;
bs3->v2= bs2->v2;
@@ -1945,7 +1943,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
float dist;
closest_to_line_segment_v3(ve, opco, nv1, nv2);
- sub_v3_v3v3(ve, opco, ve);
+ sub_v3_v3v3(ve, opco, ve);
dist = normalize_v3(ve);
if ((dist < outerfacethickness)&&(dist < mindistedge )) {
copy_v3_v3(coledge, ve);
@@ -3349,7 +3347,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */
/* insert *other second order* springs if desired */
if (sb->secondspring > 0.0000001f) {
- add_2nd_order_springs(ob, sb->secondspring); /* exploits the the first run of build_bps_springlist(ob);*/
+ add_2nd_order_springs(ob, sb->secondspring); /* exploits the first run of build_bps_springlist(ob);*/
build_bps_springlist(ob); /* yes we need to do it again*/
}
springs_from_mesh(ob); /* write the 'rest'-length of the springs */
@@ -3561,7 +3559,7 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
if (ob->softflag & OB_SB_EDGES) {
if (ob->type==OB_CURVE) {
- totspring= totvert - BLI_countlist(&cu->nurb);
+ totspring = totvert - BLI_listbase_count(&cu->nurb);
}
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index da6ead06d98..b9d70664874 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -36,6 +36,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_threads.h"
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
@@ -116,6 +117,13 @@ void BKE_sound_free(bSound *sound)
}
sound_free_waveform(sound);
+
+ if (sound->spinlock) {
+ BLI_spin_end(sound->spinlock);
+ MEM_freeN(sound->spinlock);
+ sound->spinlock = NULL;
+ }
+
#endif /* WITH_AUDASPACE */
}
@@ -296,12 +304,6 @@ void sound_cache(bSound *sound)
sound->playback_handle = sound->handle;
}
-void sound_cache_notifying(struct Main *main, bSound *sound)
-{
- sound_cache(sound);
- sound_update_sequencer(main, sound);
-}
-
void sound_delete_cache(bSound *sound)
{
sound->flags &= ~SOUND_FLAGS_CACHING;
@@ -615,6 +617,7 @@ void sound_seek_scene(struct Main *bmain, struct Scene *scene)
for (screen = bmain->screen.first; screen; screen = screen->id.next) {
if (screen->animtimer) {
animation_playing = 1;
+ break;
}
}
@@ -672,30 +675,54 @@ int sound_scene_playing(struct Scene *scene)
void sound_free_waveform(bSound *sound)
{
- if (sound->waveform) {
- MEM_freeN(((SoundWaveform *)sound->waveform)->data);
- MEM_freeN(sound->waveform);
+ SoundWaveform *waveform = sound->waveform;
+ if (waveform) {
+ if (waveform->data) {
+ MEM_freeN(waveform->data);
+ }
+ MEM_freeN(waveform);
}
sound->waveform = NULL;
}
-void sound_read_waveform(bSound *sound)
+void sound_read_waveform(bSound *sound, short *stop)
{
- AUD_SoundInfo info;
-
- info = AUD_getInfo(sound->playback_handle);
+ AUD_SoundInfo info = AUD_getInfo(sound->playback_handle);
+ SoundWaveform *waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform");
if (info.length > 0) {
- SoundWaveform *waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform");
int length = info.length * SOUND_WAVE_SAMPLES_PER_SECOND;
-
+
waveform->data = MEM_mallocN(length * sizeof(float) * 3, "SoundWaveform.samples");
- waveform->length = AUD_readSound(sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND);
+ waveform->length = AUD_readSound(sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND, stop);
+ }
+ else {
+ /* Create an empty waveform here if the sound couldn't be
+ * read. This indicates that reading the waveform is "done",
+ * whereas just setting sound->waveform to NULL causes other
+ * code to think the waveform still needs to be created. */
+ waveform->data = NULL;
+ waveform->length = 0;
+ }
- sound_free_waveform(sound);
- sound->waveform = waveform;
+ if (*stop) {
+ if (waveform->data) {
+ MEM_freeN(waveform->data);
+ }
+ MEM_freeN(waveform);
+ BLI_spin_lock(sound->spinlock);
+ sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+ BLI_spin_unlock(sound->spinlock);
+ return;
}
+
+ sound_free_waveform(sound);
+
+ BLI_spin_lock(sound->spinlock);
+ sound->waveform = waveform;
+ sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+ BLI_spin_unlock(sound->spinlock);
}
void sound_update_scene(Main *bmain, struct Scene *scene)
@@ -830,7 +857,7 @@ void sound_stop_scene(struct Scene *UNUSED(scene)) {}
void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {}
float sound_sync_scene(struct Scene *UNUSED(scene)) { return NAN_FLT; }
int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; }
-void sound_read_waveform(struct bSound *UNUSED(sound)) {}
+void sound_read_waveform(struct bSound *sound, short *stop) { UNUSED_VARS(sound, stop); }
void sound_init_main(struct Main *UNUSED(bmain)) {}
void sound_set_cfra(int UNUSED(cfra)) {}
void sound_update_sequencer(struct Main *UNUSED(main), struct bSound *UNUSED(sound)) {}
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index 08daa09cc85..b11d0ae03b0 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -67,6 +67,10 @@ Speaker *BKE_speaker_copy(Speaker *spk)
if (spkn->sound)
spkn->sound->id.us++;
+ if (spk->id.lib) {
+ BKE_id_lib_local_paths(G.main, spk->id.lib, &spkn->id);
+ }
+
return spkn;
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index f03e2eaff4a..9519c7b25a1 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -41,7 +41,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -66,8 +65,6 @@
#include "BKE_scene.h"
#include "BKE_subsurf.h"
-#include "PIL_time.h"
-
#ifndef USE_DYNSIZE
# include "BLI_array.h"
#endif
@@ -75,7 +72,6 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
-#include "GPU_material.h"
#include "CCGSubSurf.h"
@@ -411,7 +407,7 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
CCGFace **faceMap;
MTFace *tf;
MLoopUV *mluv;
- CCGFaceIterator *fi;
+ CCGFaceIterator fi;
int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n);
/* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
@@ -438,11 +434,10 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
/* make a map from original faces to CCGFaces */
faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
- for (fi = ccgSubSurf_getFaceIterator(uvss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(uvss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f;
}
- ccgFaceIterator_free(fi);
/* load coordinates from uvss into tface */
tf = tface;
@@ -699,9 +694,9 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
- CCGVertIterator *vi;
- CCGEdgeIterator *ei;
- CCGFaceIterator *fi;
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
CCGKey key;
int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
@@ -711,25 +706,23 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
if (!ccgSubSurf_getNumVerts(ss))
r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0;
- for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
float *co = ccgSubSurf_getVertData(ss, v);
minmax_v3_v3v3(co, r_min, r_max);
}
- ccgVertIterator_free(vi);
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
for (i = 0; i < edgeSize; i++)
minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max);
}
- ccgEdgeIterator_free(ei);
- for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
for (S = 0; S < numVerts; S++) {
@@ -740,7 +733,6 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), r_min, r_max);
}
}
- ccgFaceIterator_free(fi);
}
static int ccgDM_getNumVerts(DerivedMesh *dm)
@@ -1067,8 +1059,9 @@ void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly,
const MDisps *md = &mdisps[mpoly[i].loopstart + j];
int hidden_gridsize = BKE_ccg_gridsize(md->level);
int factor = BKE_ccg_factor(level, md->level);
+ BLI_bitmap *hidden = md->hidden;
- if (!md->hidden)
+ if (!hidden)
continue;
for (y = 0; y < gridSize; y++) {
@@ -1077,7 +1070,7 @@ void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly,
vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
offset = (y * factor) * hidden_gridsize + (x * factor);
- if (BLI_BITMAP_TEST(md->hidden, offset))
+ if (BLI_BITMAP_TEST(hidden, offset))
mvert[vndx].flag |= ME_HIDE;
}
}
@@ -1433,9 +1426,9 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3])
int edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
int i;
- CCGVertIterator *vi;
- CCGEdgeIterator *ei;
- CCGFaceIterator *fi;
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
CCGFace **faceMap2;
CCGEdge **edgeMap2;
CCGVert **vertMap2;
@@ -1443,30 +1436,27 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3])
totvert = ccgSubSurf_getNumVerts(ss);
vertMap2 = MEM_mallocN(totvert * sizeof(*vertMap2), "vertmap");
- for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
}
- ccgVertIterator_free(vi);
totedge = ccgSubSurf_getNumEdges(ss);
edgeMap2 = MEM_mallocN(totedge * sizeof(*edgeMap2), "edgemap");
- for (ei = ccgSubSurf_getEdgeIterator(ss), i = 0; !ccgEdgeIterator_isStopped(ei); i++, ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei), i = 0; !ccgEdgeIterator_isStopped(&ei); i++, ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
}
- ccgEdgeIterator_free(ei);
totface = ccgSubSurf_getNumFaces(ss);
faceMap2 = MEM_mallocN(totface * sizeof(*faceMap2), "facemap");
- for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f;
}
- ccgFaceIterator_free(fi);
i = 0;
for (index = 0; index < totface; index++) {
@@ -1516,12 +1506,12 @@ static void ccgDM_foreachMappedVert(
DMForeachFlag flag)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGVertIterator *vi;
+ CCGVertIterator vi;
CCGKey key;
CCG_key_top_level(&key, ccgdm->ss);
- for (vi = ccgSubSurf_getVertIterator(ccgdm->ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ccgdm->ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
const int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
if (index != -1) {
@@ -1530,8 +1520,6 @@ static void ccgDM_foreachMappedVert(
func(userData, index, CCG_elem_co(&key, vd), no, NULL);
}
}
-
- ccgVertIterator_free(vi);
}
static void ccgDM_foreachMappedEdge(
@@ -1541,14 +1529,14 @@ static void ccgDM_foreachMappedEdge(
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
- CCGEdgeIterator *ei;
+ CCGEdgeIterator ei;
CCGKey key;
int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
CCG_key_top_level(&key, ss);
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
const int index = ccgDM_getEdgeMapIndex(ss, e);
if (index != -1) {
@@ -1558,8 +1546,6 @@ static void ccgDM_foreachMappedEdge(
}
}
}
-
- ccgEdgeIterator_free(ei);
}
static void ccgDM_foreachMappedLoop(
@@ -1597,28 +1583,26 @@ static void ccgDM_drawVerts(DerivedMesh *dm)
CCGSubSurf *ss = ccgdm->ss;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
- CCGVertIterator *vi;
- CCGEdgeIterator *ei;
- CCGFaceIterator *fi;
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
glBegin(GL_POINTS);
- for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
glVertex3fv(ccgSubSurf_getVertData(ss, v));
}
- ccgVertIterator_free(vi);
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
int x;
for (x = 1; x < edgeSize - 1; x++)
glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
}
- ccgEdgeIterator_free(ei);
- for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
glVertex3fv(ccgSubSurf_getFaceCenterData(f));
@@ -1630,7 +1614,6 @@ static void ccgDM_drawVerts(DerivedMesh *dm)
for (x = 1; x < gridSize - 1; x++)
glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
}
- ccgFaceIterator_free(fi);
glEnd();
}
@@ -1888,64 +1871,6 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
}
}
-static void ccgdm_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert)
-{
- const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- int b;
-
- /* orco texture coordinates */
- if (attribs->totorco) {
- /*const*/ float (*array)[3] = attribs->orco.array;
- const float *orco = (array) ? array[index] : zero;
-
- if (attribs->orco.gl_texco)
- glTexCoord3fv(orco);
- else
- glVertexAttrib3fvARB(attribs->orco.gl_index, orco);
- }
-
- /* uv texture coordinates */
- for (b = 0; b < attribs->tottface; b++) {
- const float *uv;
-
- if (attribs->tface[b].array) {
- MTFace *tf = &attribs->tface[b].array[a];
- uv = tf->uv[vert];
- }
- else {
- uv = zero;
- }
-
- if (attribs->tface[b].gl_texco)
- glTexCoord2fv(uv);
- else
- glVertexAttrib2fvARB(attribs->tface[b].gl_index, uv);
- }
-
- /* vertex colors */
- for (b = 0; b < attribs->totmcol; b++) {
- GLubyte col[4];
-
- if (attribs->mcol[b].array) {
- MCol *cp = &attribs->mcol[b].array[a * 4 + vert];
- col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
- }
- else {
- col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
- }
-
- glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col);
- }
-
- /* tangent for normal mapping */
- if (attribs->tottang) {
- /*const*/ float (*array)[4] = attribs->tang.array;
- const float *tang = (array) ? array[a * 4 + vert] : zero;
-
- glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
- }
-}
-
/* Only used by non-editmesh types */
static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
DMSetMaterial setMaterial,
@@ -1976,7 +1901,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \
else \
index = 0; \
- ccgdm_draw_attrib_vertex(&attribs, a, index, vert); \
+ DM_draw_attrib_vertex(&attribs, a, index, vert); \
} (void)0
totface = ccgSubSurf_getNumFaces(ss);
@@ -2147,7 +2072,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \
else \
index = 0; \
- ccgdm_draw_attrib_vertex(&attribs, a, index, vert); \
+ DM_draw_attrib_vertex(&attribs, a, index, vert); \
} (void)0
totface = ccgSubSurf_getNumFaces(ss);
@@ -2289,7 +2214,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
DMSetDrawOptionsTex drawParams,
- DMSetDrawOptions drawParamsMapped,
+ DMSetDrawOptionsMappedTex drawParamsMapped,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag flag)
{
@@ -2361,7 +2286,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
if (drawParams)
draw_option = drawParams(tf, (mcol != NULL), mat_nr);
else if (index != ORIGINDEX_NONE)
- draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index) : DM_DRAW_OPTION_NORMAL;
+ draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index, mat_nr) : DM_DRAW_OPTION_NORMAL;
else
draw_option = GPU_enable_material(mat_nr, NULL) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP;
@@ -2530,7 +2455,7 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm,
}
static void ccgDM_drawMappedFacesTex(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
+ DMSetDrawOptionsMappedTex setDrawOptions,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag flag)
{
@@ -2586,6 +2511,7 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
DMFlagMat *faceFlags = ccgdm->faceFlags;
int useColors = flag & DM_DRAW_USE_COLORS;
int gridFaces = gridSize - 1, totface;
+ int prev_mat_nr = -1;
CCG_key_top_level(&key, ss);
@@ -2626,9 +2552,16 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
{
DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
- if (index == ORIGINDEX_NONE)
- draw_option = setMaterial(faceFlags ? faceFlags[origIndex].mat_nr + 1 : 1, NULL); /* XXX, no faceFlags no material */
- else if (setDrawOptions)
+ if (setMaterial) {
+ int mat_nr = faceFlags ? faceFlags[origIndex].mat_nr + 1 : 1;
+
+ if (mat_nr != prev_mat_nr) {
+ setMaterial(mat_nr, NULL); /* XXX, no faceFlags no material */
+ prev_mat_nr = mat_nr;
+ }
+ }
+
+ if (setDrawOptions && (index != ORIGINDEX_NONE))
draw_option = setDrawOptions(userData, index);
if (draw_option != DM_DRAW_OPTION_SKIP) {
@@ -2745,15 +2678,15 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm,
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
- CCGEdgeIterator *ei;
+ CCGEdgeIterator ei;
CCGKey key;
int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
CCG_key_top_level(&key, ss);
ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
int index = ccgDM_getEdgeMapIndex(ss, e);
@@ -2771,8 +2704,6 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm,
}
glEnd();
}
-
- ccgEdgeIterator_free(ei);
}
static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
@@ -2783,14 +2714,14 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGKey key;
- CCGEdgeIterator *ei;
+ CCGEdgeIterator ei;
int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
CCG_key_top_level(&key, ss);
ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
int index = ccgDM_getEdgeMapIndex(ss, e);
@@ -2809,8 +2740,6 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
}
glEnd();
}
-
- ccgEdgeIterator_free(ei);
}
static void ccgDM_foreachMappedFaceCenter(
@@ -2822,12 +2751,12 @@ static void ccgDM_foreachMappedFaceCenter(
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGKey key;
- CCGFaceIterator *fi;
+ CCGFaceIterator fi;
CCG_key_top_level(&key, ss);
- for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
const int index = ccgDM_getFaceMapIndex(ss, f);
if (index != -1) {
@@ -2837,8 +2766,6 @@ static void ccgDM_foreachMappedFaceCenter(
func(userData, index, CCG_elem_co(&key, vd), no);
}
}
-
- ccgFaceIterator_free(fi);
}
static void ccgDM_release(DerivedMesh *dm)
@@ -3434,9 +3361,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
DerivedMesh *dm)
{
CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
- CCGVertIterator *vi;
- CCGEdgeIterator *ei;
- CCGFaceIterator *fi;
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
int index, totvert, totedge, totface;
int i;
int vertNum, edgeNum, faceNum;
@@ -3538,6 +3465,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
ccgdm->dm.calcNormals = ccgDM_calcNormals;
ccgdm->dm.calcLoopNormals = CDDM_calc_loop_normals;
+ ccgdm->dm.calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr;
ccgdm->dm.recalcTessellation = ccgDM_recalcTessellation;
ccgdm->dm.getVertCos = ccgdm_getVertCos;
@@ -3569,30 +3497,27 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
totvert = ccgSubSurf_getNumVerts(ss);
ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
- for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
}
- ccgVertIterator_free(vi);
totedge = ccgSubSurf_getNumEdges(ss);
ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
}
- ccgEdgeIterator_free(ei);
totface = ccgSubSurf_getNumFaces(ss);
ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
- for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))].face = f;
}
- ccgFaceIterator_free(fi);
ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap");
@@ -3997,13 +3922,13 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
*/
CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA);
float edge_sum[3], face_sum[3];
- CCGVertIterator *vi;
+ CCGVertIterator vi;
DerivedMesh *dm = CDDM_from_mesh(me);
ss_sync_from_derivedmesh(ss, dm, NULL, 0);
- for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
int N = ccgSubSurf_getVertNumEdges(v);
int numFaces = ccgSubSurf_getVertNumFaces(v);
@@ -4032,7 +3957,6 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
r_positions[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5));
r_positions[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5));
}
- ccgVertIterator_free(vi);
ccgSubSurf_free(ss);
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 8a272cd9d81..9f441b45db9 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -369,14 +369,18 @@ int BKE_text_reload(Text *text)
buffer = MEM_mallocN(len, "text_buffer");
- // under windows fread can return less then len bytes because
- // of CR stripping
+ /* under windows fread can return less than len bytes because
+ * of CR stripping */
len = fread(buffer, 1, len, fp);
fclose(fp);
- BLI_stat(str, &st);
- text->mtime = st.st_mtime;
+ if (BLI_stat(str, &st) != -1) {
+ text->mtime = st.st_mtime;
+ }
+ else {
+ text->mtime = 0;
+ }
text_from_buf(text, buffer, len);
@@ -425,14 +429,18 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const
fseek(fp, 0L, SEEK_SET);
buffer = MEM_mallocN(len, "text_buffer");
- // under windows fread can return less then len bytes because
- // of CR stripping
+ /* under windows fread can return less than len bytes because
+ * of CR stripping */
len = fread(buffer, 1, len, fp);
fclose(fp);
- BLI_stat(str, &st);
- ta->mtime = st.st_mtime;
+ if (BLI_stat(str, &st) != -1) {
+ ta->mtime = st.st_mtime;
+ }
+ else {
+ ta->mtime = 0;
+ }
text_from_buf(ta, buffer, len);
@@ -446,7 +454,7 @@ Text *BKE_text_load(Main *bmain, const char *file, const char *relpath)
return BKE_text_load_ex(bmain, file, relpath, false);
}
-Text *BKE_text_copy(Text *ta)
+Text *BKE_text_copy(Main *bmain, Text *ta)
{
Text *tan;
TextLine *line, *tmp;
@@ -455,8 +463,7 @@ Text *BKE_text_copy(Text *ta)
/* file name can be NULL */
if (ta->name) {
- tan->name = MEM_mallocN(strlen(ta->name) + 1, "text_name");
- strcpy(tan->name, ta->name);
+ tan->name = BLI_strdup(ta->name);
}
else {
tan->name = NULL;
@@ -490,6 +497,10 @@ Text *BKE_text_copy(Text *ta)
init_undo_text(tan);
+ if (ta->id.lib) {
+ BKE_id_lib_local_paths(bmain, ta->id.lib, &tan->id);
+ }
+
return tan;
}
@@ -505,10 +516,14 @@ void BKE_text_unlink(Main *bmain, Text *text)
bNodeTree *ntree;
bNode *node;
Material *mat;
+ Lamp *la;
+ Tex *te;
+ World *wo;
+ FreestyleLineStyle *linestyle;
Scene *sce;
SceneRenderLayer *srl;
FreestyleModuleConfig *module;
- short update;
+ bool update;
for (ob = bmain->object.first; ob; ob = ob->id.next) {
/* game controllers */
@@ -560,23 +575,97 @@ void BKE_text_unlink(Main *bmain, Text *text)
}
/* nodes */
+ for (la = bmain->lamp.first; la; la = la->id.next) {
+ ntree = la->nodetree;
+ if (!ntree)
+ continue;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == NODE_FRAME) {
+ if ((Text *)node->id == text) {
+ node->id = NULL;
+ }
+ }
+ }
+ }
+
+ for (linestyle = bmain->linestyle.first; linestyle; linestyle = linestyle->id.next) {
+ ntree = linestyle->nodetree;
+ if (!ntree)
+ continue;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == NODE_FRAME) {
+ if ((Text *)node->id == text) {
+ node->id = NULL;
+ }
+ }
+ }
+ }
+
for (mat = bmain->mat.first; mat; mat = mat->id.next) {
ntree = mat->nodetree;
if (!ntree)
continue;
for (node = ntree->nodes.first; node; node = node->next) {
- if (node->type == SH_NODE_SCRIPT) {
+ if (ELEM(node->type, SH_NODE_SCRIPT, NODE_FRAME)) {
+ if ((Text *)node->id == text) {
+ node->id = NULL;
+ }
+ }
+ }
+ }
+
+ for (te = bmain->tex.first; te; te = te->id.next) {
+ ntree = te->nodetree;
+ if (!ntree)
+ continue;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == NODE_FRAME) {
+ if ((Text *)node->id == text) {
+ node->id = NULL;
+ }
+ }
+ }
+ }
+
+ for (wo = bmain->world.first; wo; wo = wo->id.next) {
+ ntree = wo->nodetree;
+ if (!ntree)
+ continue;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == NODE_FRAME) {
+ if ((Text *)node->id == text) {
+ node->id = NULL;
+ }
+ }
+ }
+ }
+
+ for (sce = bmain->scene.first; sce; sce = sce->id.next) {
+ ntree = sce->nodetree;
+ if (!ntree)
+ continue;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == NODE_FRAME) {
Text *ntext = (Text *)node->id;
if (ntext == text) node->id = NULL;
}
}
+
+ /* Freestyle (while looping oer the scene) */
+ for (srl = sce->r.layers.first; srl; srl = srl->next) {
+ for (module = srl->freestyleConfig.modules.first; module; module = module->next) {
+ if (module->script == text)
+ module->script = NULL;
+ }
+ }
}
-
+
for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next) {
for (node = ntree->nodes.first; node; node = node->next) {
- if (node->type == SH_NODE_SCRIPT) {
- Text *ntext = (Text *)node->id;
- if (ntext == text) node->id = NULL;
+ if (ELEM(node->type, SH_NODE_SCRIPT, NODE_FRAME)) {
+ if ((Text *)node->id == text) {
+ node->id = NULL;
+ }
}
}
}
@@ -597,16 +686,6 @@ void BKE_text_unlink(Main *bmain, Text *text)
}
}
- /* Freestyle */
- for (sce = bmain->scene.first; sce; sce = sce->id.next) {
- for (srl = sce->r.layers.first; srl; srl = srl->next) {
- for (module = srl->freestyleConfig.modules.first; module; module = module->next) {
- if (module->script == text)
- module->script = NULL;
- }
- }
- }
-
text->id.us = 0;
}
@@ -614,7 +693,7 @@ void BKE_text_clear(Text *text) /* called directly from rna */
{
int oldstate;
- oldstate = txt_get_undostate( );
+ oldstate = txt_get_undostate();
txt_set_undostate(1);
txt_sel_all(text);
txt_delete_sel(text);
@@ -1515,7 +1594,7 @@ static bool max_undo_test(Text *text, int x)
/* XXX error("Undo limit reached, buffer cleared\n"); */
MEM_freeN(text->undo_buf);
init_undo_text(text);
- return 0;
+ return false;
}
else {
void *tmp = text->undo_buf;
@@ -1526,7 +1605,7 @@ static bool max_undo_test(Text *text, int x)
}
}
- return 1;
+ return true;
}
#if 0 /* UNUSED */
@@ -2474,6 +2553,7 @@ void txt_delete_word(Text *text)
{
txt_jump_right(text, true, true);
txt_delete_sel(text);
+ txt_make_dirty(text);
}
void txt_backspace_char(Text *text)
@@ -2522,6 +2602,7 @@ void txt_backspace_word(Text *text)
{
txt_jump_left(text, true, true);
txt_delete_sel(text);
+ txt_make_dirty(text);
}
/* Max spaces to replace a tab with, currently hardcoded to TXT_TABSIZE = 4.
@@ -2548,13 +2629,13 @@ static bool txt_add_char_intern(Text *text, unsigned int add, bool replace_tabs)
if (add == '\n') {
txt_split_curline(text);
- return 1;
+ return true;
}
/* insert spaces rather than tabs */
if (add == '\t' && replace_tabs) {
txt_convert_tab_to_spaces(text);
- return 1;
+ return true;
}
txt_delete_sel(text);
@@ -2603,7 +2684,7 @@ bool txt_replace_char(Text *text, unsigned int add)
size_t del_size = 0, add_size;
char ch[BLI_UTF8_MAX];
- if (!text->curl) return 0;
+ if (!text->curl) return false;
/* If text is selected or we're at the end of the line just use txt_add_char */
if (text->curc == text->curl->len || txt_has_sel(text) || add == '\n') {
@@ -2642,7 +2723,7 @@ bool txt_replace_char(Text *text, unsigned int add)
text->curc += add_size;
txt_pop_sel(text);
}
- return 1;
+ return true;
}
void txt_indent(Text *text)
@@ -2735,7 +2816,7 @@ void txt_unindent(Text *text)
while (true) {
bool changed = false;
- if (strncmp(text->curl->line, remove, indentlen) == 0) {
+ if (STREQLEN(text->curl->line, remove, indentlen)) {
if (num == 0)
unindented_first = true;
text->curl->len -= indentlen;
@@ -2977,37 +3058,37 @@ bool text_check_delim(const char ch)
for (a = 0; a < (sizeof(delims) - 1); a++) {
if (ch == delims[a])
- return 1;
+ return true;
}
- return 0;
+ return false;
}
bool text_check_digit(const char ch)
{
- if (ch < '0') return 0;
- if (ch <= '9') return 1;
- return 0;
+ if (ch < '0') return false;
+ if (ch <= '9') return true;
+ return false;
}
bool text_check_identifier(const char ch)
{
- if (ch < '0') return 0;
- if (ch <= '9') return 1;
- if (ch < 'A') return 0;
- if (ch <= 'Z' || ch == '_') return 1;
- if (ch < 'a') return 0;
- if (ch <= 'z') return 1;
- return 0;
+ if (ch < '0') return false;
+ if (ch <= '9') return true;
+ if (ch < 'A') return false;
+ if (ch <= 'Z' || ch == '_') return true;
+ if (ch < 'a') return false;
+ if (ch <= 'z') return true;
+ return false;
}
bool text_check_identifier_nodigit(const char ch)
{
- if (ch <= '9') return 0;
- if (ch < 'A') return 0;
- if (ch <= 'Z' || ch == '_') return 1;
- if (ch < 'a') return 0;
- if (ch <= 'z') return 1;
- return 0;
+ if (ch <= '9') return false;
+ if (ch < 'A') return false;
+ if (ch <= 'Z' || ch == '_') return true;
+ if (ch < 'a') return false;
+ if (ch <= 'z') return true;
+ return false;
}
#ifndef WITH_PYTHON
@@ -3025,8 +3106,8 @@ int text_check_identifier_nodigit_unicode(const unsigned int ch)
bool text_check_whitespace(const char ch)
{
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
- return 1;
- return 0;
+ return true;
+ return false;
}
int text_find_identifier_start(const char *str, int i)
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index b1981a3a804..3293cca76fe 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_kdopbvh.h"
#include "BLI_utildefines.h"
@@ -328,7 +327,7 @@ bool do_colorband(const ColorBand *coba, float in, float out[4])
int ipotype;
int a;
- if (coba == NULL || coba->tot == 0) return 0;
+ if (coba == NULL || coba->tot == 0) return false;
cbd1 = coba->data;
@@ -350,7 +349,11 @@ bool do_colorband(const ColorBand *coba, float in, float out[4])
CBData left, right;
/* we're looking for first pos > in */
- for (a = 0; a < coba->tot; a++, cbd1++) if (cbd1->pos > in) break;
+ for (a = 0; a < coba->tot; a++, cbd1++) {
+ if (cbd1->pos > in) {
+ break;
+ }
+ }
if (a == coba->tot) {
cbd2 = cbd1 - 1;
@@ -464,7 +467,7 @@ bool do_colorband(const ColorBand *coba, float in, float out[4])
}
}
}
- return 1; /* OK */
+ return true; /* OK */
}
void colorband_table_RGBA(ColorBand *coba, float **array, int *size)
@@ -746,6 +749,7 @@ void default_mtex(MTex *mtex)
mtex->lengthfac = 1.0f;
mtex->clumpfac = 1.0f;
mtex->kinkfac = 1.0f;
+ mtex->kinkampfac = 1.0f;
mtex->roughfac = 1.0f;
mtex->padensfac = 1.0f;
mtex->lifefac = 1.0f;
@@ -756,6 +760,8 @@ void default_mtex(MTex *mtex)
mtex->fieldfac = 1.0f;
mtex->normapspace = MTEX_NSPACE_TANGENT;
mtex->brush_map_mode = MTEX_MAP_MODE_TILED;
+ mtex->random_angle = 2.0f * (float)M_PI;
+ mtex->brush_angle_mode = 0;
}
@@ -826,8 +832,12 @@ Tex *BKE_texture_copy(Tex *tex)
Tex *texn;
texn = BKE_libblock_copy(&tex->id);
- if (texn->type == TEX_IMAGE) id_us_plus((ID *)texn->ima);
- else texn->ima = NULL;
+ if (BKE_texture_is_image_user(tex)) {
+ id_us_plus((ID *)texn->ima);
+ }
+ else {
+ texn->ima = NULL;
+ }
if (texn->coba) texn->coba = MEM_dupallocN(texn->coba);
if (texn->env) texn->env = BKE_copy_envmap(texn->env);
@@ -843,6 +853,10 @@ Tex *BKE_texture_copy(Tex *tex)
texn->nodetree = ntreeCopyTree(tex->nodetree);
}
+ if (tex->id.lib) {
+ BKE_id_lib_local_paths(G.main, tex->id.lib, &texn->id);
+ }
+
return texn;
}
@@ -1305,7 +1319,7 @@ bool has_current_material_texture(Material *ma)
node = nodeGetActiveID(ma->nodetree, ID_TE);
if (node)
- return 1;
+ return true;
}
return (ma != NULL);
@@ -1594,22 +1608,45 @@ void BKE_free_oceantex(struct OceanTex *ot)
MEM_freeN(ot);
}
+/**
+ * \returns true if this texture can use its #Texture.ima (even if its NULL)
+ */
+bool BKE_texture_is_image_user(const struct Tex *tex)
+{
+ switch (tex->type) {
+ case TEX_IMAGE:
+ {
+ return true;
+ }
+ case TEX_ENVMAP:
+ {
+ if (tex->env) {
+ if (tex->env->stype == ENV_LOAD) {
+ return true;
+ }
+ }
+ break;
+ }
+ }
+
+ return false;
+}
/* ------------------------------------------------------------------------- */
bool BKE_texture_dependsOnTime(const struct Tex *texture)
{
if (texture->ima && BKE_image_is_animated(texture->ima)) {
- return 1;
+ return true;
}
else if (texture->adt) {
/* assume anything in adt means the texture is animated */
- return 1;
+ return true;
}
else if (texture->type == TEX_NOISE) {
/* noise always varies with time */
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* ------------------------------------------------------------------------- */
@@ -1624,7 +1661,7 @@ void BKE_texture_get_value(Scene *scene, Tex *texture, float *tex_co, TexResult
}
/* no node textures for now */
- result_type = multitex_ext_safe(texture, tex_co, texres, NULL, do_color_manage);
+ result_type = multitex_ext_safe(texture, tex_co, texres, NULL, do_color_manage, false);
/* if the texture gave an RGB value, we assume it didn't give a valid
* intensity, since this is in the context of modifiers don't use perceptual color conversion.
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 40d9dc0d7e0..0037002f6d8 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -721,7 +721,7 @@ MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking, MovieT
MovieTrackingTrack *track = tracksbase->first;
while (track) {
- if (!strcmp(track->name, name))
+ if (STREQ(track->name, name))
return track;
track = track->next;
@@ -1267,7 +1267,7 @@ MovieTrackingPlaneTrack *BKE_tracking_plane_track_get_named(MovieTracking *track
plane_track;
plane_track = plane_track->next)
{
- if (!strcmp(plane_track->name, name)) {
+ if (STREQ(plane_track->name, name)) {
return plane_track;
}
}
@@ -1456,6 +1456,35 @@ MovieTrackingPlaneMarker *BKE_tracking_plane_marker_ensure(MovieTrackingPlaneTra
return plane_marker;
}
+void BKE_tracking_plane_marker_get_subframe_corners(MovieTrackingPlaneTrack *plane_track,
+ float framenr,
+ float corners[4][2])
+{
+ MovieTrackingPlaneMarker *marker = BKE_tracking_plane_marker_get(plane_track, (int)framenr);
+ MovieTrackingPlaneMarker *marker_last = plane_track->markers + (plane_track->markersnr - 1);
+ int i;
+ if (marker != marker_last) {
+ MovieTrackingPlaneMarker *marker_next = marker + 1;
+ if (marker_next->framenr == marker->framenr + 1) {
+ float fac = (framenr - (int) framenr) / (marker_next->framenr - marker->framenr);
+ for (i = 0; i < 4; ++i) {
+ interp_v2_v2v2(corners[i], marker->corners[i],
+ marker_next->corners[i], fac);
+ }
+ }
+ else {
+ for (i = 0; i < 4; ++i) {
+ copy_v2_v2(corners[i], marker->corners[i]);
+ }
+ }
+ }
+ else {
+ for (i = 0; i < 4; ++i) {
+ copy_v2_v2(corners[i], marker->corners[i]);
+ }
+ }
+}
+
/*********************** Object *************************/
MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char *name)
@@ -1475,7 +1504,7 @@ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char
BLI_addtail(&tracking->objects, object);
tracking->tot_object++;
- tracking->objectnr = BLI_countlist(&tracking->objects) - 1;
+ tracking->objectnr = BLI_listbase_count(&tracking->objects) - 1;
object->scale = 1.0f;
object->keyframe1 = 1;
@@ -1534,7 +1563,7 @@ MovieTrackingObject *BKE_tracking_object_get_named(MovieTracking *tracking, cons
MovieTrackingObject *object = tracking->objects.first;
while (object) {
- if (!strcmp(object->name, name))
+ if (STREQ(object->name, name))
return object;
object = object->next;
@@ -2410,30 +2439,30 @@ static void tracking_dopesheet_channels_sort(MovieTracking *tracking, int sort_m
if (inverse) {
if (sort_method == TRACKING_DOPE_SORT_NAME) {
- BLI_sortlist(&dopesheet->channels, channels_alpha_inverse_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_alpha_inverse_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
- BLI_sortlist(&dopesheet->channels, channels_longest_segment_inverse_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_longest_segment_inverse_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
- BLI_sortlist(&dopesheet->channels, channels_total_track_inverse_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_total_track_inverse_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
- BLI_sortlist(&dopesheet->channels, channels_average_error_inverse_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_average_error_inverse_sort);
}
}
else {
if (sort_method == TRACKING_DOPE_SORT_NAME) {
- BLI_sortlist(&dopesheet->channels, channels_alpha_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_alpha_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
- BLI_sortlist(&dopesheet->channels, channels_longest_segment_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_longest_segment_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
- BLI_sortlist(&dopesheet->channels, channels_total_track_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_total_track_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
- BLI_sortlist(&dopesheet->channels, channels_average_error_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_average_error_sort);
}
}
}
diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c
new file mode 100644
index 00000000000..4cb3f2ca493
--- /dev/null
+++ b/source/blender/blenkernel/intern/tracking_auto.c
@@ -0,0 +1,568 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ * Keir Mierle
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/tracking_auto.c
+ * \ingroup bke
+ */
+
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_movieclip_types.h"
+#include "DNA_object_types.h" /* SELECT */
+
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "libmv-capi.h"
+#include "tracking_private.h"
+
+typedef struct AutoTrackOptions {
+ int clip_index; /** Index of the clip this track belogs to. */
+ int track_index; /* Index of the track in AutoTrack tracks structure. */
+ MovieTrackingTrack *track; /* Pointer to an original track/ */
+ libmv_TrackRegionOptions track_region_options; /* Options for the region
+ tracker. */
+ bool use_keyframe_match; /* Keyframe pattern matching. */
+
+ /* TODO(sergey): A bit awkward to keep it in here, only used to
+ * place a disabled marker once the tracking fails,
+ * Wither find a more clear way to do it or call it track context
+ * or state, not options.
+ */
+ bool is_failed;
+ int failed_frame;
+} AutoTrackOptions;
+
+typedef struct AutoTrackContext {
+ MovieClip *clips[MAX_ACCESSOR_CLIP];
+ int num_clips;
+
+ MovieClipUser user;
+ int frame_width, frame_height;
+
+ struct libmv_AutoTrack *autotrack;
+ TrackingImageAccessor *image_accessor;
+
+ int num_tracks; /* Number of tracks being tracked. */
+ AutoTrackOptions *options; /* Per-tracking track options. */
+
+ bool backwards;
+ bool sequence;
+ int first_frame;
+ int sync_frame;
+ bool first_sync;
+ SpinLock spin_lock;
+} AutoTrackContext;
+
+static void normalized_to_libmv_frame(const float normalized[2],
+ const int frame_dimensions[2],
+ float result[2])
+{
+ result[0] = normalized[0] * frame_dimensions[0] - 0.5f;
+ result[1] = normalized[1] * frame_dimensions[1] - 0.5f;
+}
+
+static void normalized_relative_to_libmv_frame(const float normalized[2],
+ const float origin[2],
+ const int frame_dimensions[2],
+ float result[2])
+{
+ result[0] = (normalized[0] + origin[0]) * frame_dimensions[0] - 0.5f;
+ result[1] = (normalized[1] + origin[1]) * frame_dimensions[1] - 0.5f;
+}
+
+static void libmv_frame_to_normalized(const float frame_coord[2],
+ const int frame_dimensions[2],
+ float result[2])
+{
+ result[0] = (frame_coord[0] + 0.5f) / frame_dimensions[0];
+ result[1] = (frame_coord[1] + 0.5f) / frame_dimensions[1];
+}
+
+static void libmv_frame_to_normalized_relative(const float frame_coord[2],
+ const float origin[2],
+ const int frame_dimensions[2],
+ float result[2])
+{
+ result[0] = (frame_coord[0] - origin[0]) / frame_dimensions[0];
+ result[1] = (frame_coord[1] - origin[1]) / frame_dimensions[1];
+}
+
+static void dna_marker_to_libmv_marker(/*const*/ MovieTrackingTrack *track,
+ /*const*/ MovieTrackingMarker *marker,
+ int clip,
+ int track_index,
+ int frame_width,
+ int frame_height,
+ bool backwards,
+ libmv_Marker *libmv_marker)
+{
+ const int frame_dimensions[2] = {frame_width, frame_height};
+ int i;
+ libmv_marker->clip = clip;
+ libmv_marker->frame = marker->framenr;
+ libmv_marker->track = track_index;
+
+ normalized_to_libmv_frame(marker->pos,
+ frame_dimensions,
+ libmv_marker->center);
+ for (i = 0; i < 4; ++i) {
+ normalized_relative_to_libmv_frame(marker->pattern_corners[i],
+ marker->pos,
+ frame_dimensions,
+ libmv_marker->patch[i]);
+ }
+
+ normalized_relative_to_libmv_frame(marker->search_min,
+ marker->pos,
+ frame_dimensions,
+ libmv_marker->search_region_min);
+
+ normalized_relative_to_libmv_frame(marker->search_max,
+ marker->pos,
+ frame_dimensions,
+ libmv_marker->search_region_max);
+
+ /* TODO(sergey): All the markers does have 1.0 weight. */
+ libmv_marker->weight = 1.0f;
+
+ if (marker->flag & MARKER_TRACKED) {
+ libmv_marker->source = LIBMV_MARKER_SOURCE_TRACKED;
+ }
+ else {
+ libmv_marker->source = LIBMV_MARKER_SOURCE_MANUAL;
+ }
+ libmv_marker->status = LIBMV_MARKER_STATUS_UNKNOWN;
+ libmv_marker->model_type = LIBMV_MARKER_MODEL_TYPE_POINT;
+ libmv_marker->model_id = 0;
+
+ /* TODO(sergey): We currently don't support reference marker from
+ * different clip.
+ */
+ libmv_marker->reference_clip = clip;
+
+ if (track->pattern_match == TRACK_MATCH_KEYFRAME) {
+ MovieTrackingMarker *keyframe_marker =
+ tracking_get_keyframed_marker(track,
+ marker->framenr,
+ backwards);
+ libmv_marker->reference_frame = keyframe_marker->framenr;
+ }
+ else {
+ libmv_marker->reference_frame = backwards ?
+ marker->framenr - 1 :
+ marker->framenr;
+ }
+
+ libmv_marker->disabled_channels =
+ ((track->flag & TRACK_DISABLE_RED) ? LIBMV_MARKER_CHANNEL_R : 0) |
+ ((track->flag & TRACK_DISABLE_GREEN) ? LIBMV_MARKER_CHANNEL_G : 0) |
+ ((track->flag & TRACK_DISABLE_BLUE) ? LIBMV_MARKER_CHANNEL_B : 0);
+}
+
+static void libmv_marker_to_dna_marker(libmv_Marker *libmv_marker,
+ int frame_width,
+ int frame_height,
+ MovieTrackingMarker *marker)
+{
+ const int frame_dimensions[2] = {frame_width, frame_height};
+ int i;
+ marker->framenr = libmv_marker->frame;
+
+ libmv_frame_to_normalized(libmv_marker->center,
+ frame_dimensions,
+ marker->pos);
+ for (i = 0; i < 4; ++i) {
+ libmv_frame_to_normalized_relative(libmv_marker->patch[i],
+ libmv_marker->center,
+ frame_dimensions,
+ marker->pattern_corners[i]);
+ }
+
+ libmv_frame_to_normalized_relative(libmv_marker->search_region_min,
+ libmv_marker->center,
+ frame_dimensions,
+ marker->search_min);
+
+ libmv_frame_to_normalized_relative(libmv_marker->search_region_max,
+ libmv_marker->center,
+ frame_dimensions,
+ marker->search_max);
+
+ marker->flag = 0;
+ if (libmv_marker->source == LIBMV_MARKER_SOURCE_TRACKED) {
+ marker->flag |= MARKER_TRACKED;
+ }
+ else {
+ marker->flag &= ~MARKER_TRACKED;
+ }
+}
+
+static bool check_track_trackable(MovieClip *clip,
+ MovieTrackingTrack *track,
+ MovieClipUser *user)
+{
+ if (TRACK_SELECTED(track) &&
+ (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0)
+ {
+ MovieTrackingMarker *marker;
+ int frame;
+ frame = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
+ marker = BKE_tracking_marker_get(track, frame);
+ return (marker->flag & MARKER_DISABLED) == 0;
+ }
+ return false;
+}
+
+/* Returns false if marker crossed margin area from frame bounds. */
+static bool tracking_check_marker_margin(libmv_Marker *libmv_marker,
+ int margin,
+ int frame_width,
+ int frame_height)
+{
+ float patch_min[2], patch_max[2];
+ float margin_left, margin_top, margin_right, margin_bottom;
+
+ INIT_MINMAX2(patch_min, patch_max);
+ minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[0]);
+ minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[1]);
+ minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[2]);
+ minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[3]);
+
+ margin_left = max_ff(libmv_marker->center[0] - patch_min[0], margin);
+ margin_top = max_ff(patch_max[1] - libmv_marker->center[1], margin);
+ margin_right = max_ff(patch_max[0] - libmv_marker->center[0], margin);
+ margin_bottom = max_ff(libmv_marker->center[1] - patch_min[1], margin);
+
+ if (libmv_marker->center[0] < margin_left ||
+ libmv_marker->center[0] > frame_width - margin_right ||
+ libmv_marker->center[1] < margin_bottom ||
+ libmv_marker->center[1] > frame_height - margin_top)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
+ MovieClipUser *user,
+ const bool backwards,
+ const bool sequence)
+{
+ AutoTrackContext *context = MEM_callocN(sizeof(AutoTrackContext),
+ "autotrack context");
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingTrack *track;
+ ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ int i, track_index, frame_width, frame_height;
+
+ BKE_movieclip_get_size(clip, user, &frame_width, &frame_height);
+
+ /* TODO(sergey): Currently using only a single clip. */
+ context->clips[0] = clip;
+ context->num_clips = 1;
+
+ context->user = *user;
+ context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
+ context->user.render_flag = 0;
+ context->frame_width = frame_width;
+ context->frame_height = frame_height;
+ context->backwards = backwards;
+ context->sequence = sequence;
+ context->first_frame = user->framenr;
+ context->sync_frame = user->framenr;
+ context->first_sync = true;
+
+ BLI_spin_init(&context->spin_lock);
+
+ context->image_accessor =
+ tracking_image_accessor_new(context->clips, 1, user->framenr);
+ context->autotrack =
+ libmv_autoTrackNew(context->image_accessor->libmv_accessor);
+
+ /* Fill in Autotrack with all markers we know. */
+ track_index = 0;
+ for (track = tracksbase->first;
+ track;
+ track = track->next)
+ {
+ if (check_track_trackable(clip, track, user)) {
+ context->num_tracks++;
+ }
+
+ for (i = 0; i < track->markersnr; ++i) {
+ MovieTrackingMarker *marker = track->markers + i;
+ if ((marker->flag & MARKER_DISABLED) == 0) {
+ libmv_Marker libmv_marker;
+ dna_marker_to_libmv_marker(track,
+ marker,
+ 0,
+ track_index,
+ frame_width,
+ frame_height,
+ backwards,
+ &libmv_marker);
+ libmv_autoTrackAddMarker(context->autotrack,
+ &libmv_marker);
+ }
+ }
+ track_index++;
+ }
+
+ /* Create per-track tracking options. */
+ context->options =
+ MEM_callocN(sizeof(AutoTrackOptions) * context->num_tracks,
+ "auto track options");
+ i = track_index = 0;
+ for (track = tracksbase->first;
+ track;
+ track = track->next)
+ {
+ if (check_track_trackable(clip, track, user)) {
+ AutoTrackOptions *options = &context->options[i++];
+ /* TODO(sergey): Single clip only for now. */
+ options->clip_index = 0;
+ options->track_index = track_index;
+ options->track = track;
+ tracking_configure_tracker(track,
+ NULL,
+ &options->track_region_options);
+ options->use_keyframe_match =
+ track->pattern_match == TRACK_MATCH_KEYFRAME;
+ }
+ ++track_index;
+ }
+
+ return context;
+}
+
+bool BKE_autotrack_context_step(AutoTrackContext *context)
+{
+ int frame_delta = context->backwards ? -1 : 1;
+ bool ok = false;
+ int track;
+
+#pragma omp parallel for if (context->num_tracks > 1)
+ for (track = 0; track < context->num_tracks; ++track) {
+ AutoTrackOptions *options = &context->options[track];
+ libmv_Marker libmv_current_marker,
+ libmv_reference_marker,
+ libmv_tracked_marker;
+ libmv_TrackRegionResult libmv_result;
+ int frame = BKE_movieclip_remap_scene_to_clip_frame(
+ context->clips[options->clip_index],
+ context->user.framenr);
+ bool has_marker;
+
+ BLI_spin_lock(&context->spin_lock);
+ has_marker = libmv_autoTrackGetMarker(context->autotrack,
+ options->clip_index,
+ frame,
+ options->track_index,
+ &libmv_current_marker);
+ BLI_spin_unlock(&context->spin_lock);
+
+ if (has_marker) {
+ if (!tracking_check_marker_margin(&libmv_current_marker,
+ options->track->margin,
+ context->frame_width,
+ context->frame_height))
+ {
+ continue;
+ }
+
+ libmv_tracked_marker = libmv_current_marker;
+ libmv_tracked_marker.frame = frame + frame_delta;
+
+ if (options->use_keyframe_match) {
+ libmv_tracked_marker.reference_frame =
+ libmv_current_marker.reference_frame;
+ libmv_autoTrackGetMarker(context->autotrack,
+ options->clip_index,
+ libmv_tracked_marker.reference_frame,
+ options->track_index,
+ &libmv_reference_marker);
+ }
+ else {
+ libmv_tracked_marker.reference_frame = frame;
+ libmv_reference_marker = libmv_current_marker;
+ }
+
+ if (libmv_autoTrackMarker(context->autotrack,
+ &options->track_region_options,
+ &libmv_tracked_marker,
+ &libmv_result))
+ {
+ BLI_spin_lock(&context->spin_lock);
+ libmv_autoTrackAddMarker(context->autotrack,
+ &libmv_tracked_marker);
+ BLI_spin_unlock(&context->spin_lock);
+ }
+ else {
+ options->is_failed = true;
+ options->failed_frame = frame + frame_delta;
+ }
+ ok = true;
+ }
+ }
+
+ BLI_spin_lock(&context->spin_lock);
+ context->user.framenr += frame_delta;
+ BLI_spin_unlock(&context->spin_lock);
+
+ return ok;
+}
+
+void BKE_autotrack_context_sync(AutoTrackContext *context)
+{
+ int newframe, frame_delta = context->backwards ? -1 : 1;
+ int clip, frame;
+
+ BLI_spin_lock(&context->spin_lock);
+ newframe = context->user.framenr;
+ for (frame = context->sync_frame;
+ frame != (context->backwards ? newframe - 1 : newframe + 1);
+ frame += frame_delta)
+ {
+ MovieTrackingMarker marker;
+ libmv_Marker libmv_marker;
+ int clip = 0;
+ int track;
+ for (track = 0; track < context->num_tracks; ++track) {
+ AutoTrackOptions *options = &context->options[track];
+ int track_frame = BKE_movieclip_remap_scene_to_clip_frame(
+ context->clips[options->clip_index], frame);
+ if (options->is_failed && options->failed_frame == track_frame) {
+ MovieTrackingMarker *prev_marker =
+ BKE_tracking_marker_get_exact(options->track, frame);
+ if (prev_marker) {
+ marker = *prev_marker;
+ marker.framenr = context->backwards ?
+ track_frame - 1 :
+ track_frame + 1;
+ marker.flag |= MARKER_DISABLED;
+ BKE_tracking_marker_insert(options->track, &marker);
+ continue;
+ }
+ }
+ if (libmv_autoTrackGetMarker(context->autotrack,
+ clip,
+ track_frame,
+ options->track_index,
+ &libmv_marker))
+ {
+ libmv_marker_to_dna_marker(&libmv_marker,
+ context->frame_width,
+ context->frame_height,
+ &marker);
+ if (context->first_sync && frame == context->sync_frame) {
+ tracking_marker_insert_disabled(options->track,
+ &marker,
+ !context->backwards,
+ false);
+ }
+ BKE_tracking_marker_insert(options->track, &marker);
+ tracking_marker_insert_disabled(options->track,
+ &marker,
+ context->backwards,
+ false);
+ }
+ }
+ }
+ BLI_spin_unlock(&context->spin_lock);
+
+ for (clip = 0; clip < context->num_clips; ++clip) {
+ MovieTracking *tracking = &context->clips[clip]->tracking;
+ BKE_tracking_dopesheet_tag_update(tracking);
+ }
+
+ context->sync_frame = newframe;
+ context->first_sync = false;
+}
+
+void BKE_autotrack_context_sync_user(AutoTrackContext *context,
+ MovieClipUser *user)
+{
+ user->framenr = context->sync_frame;
+}
+
+void BKE_autotrack_context_finish(AutoTrackContext *context)
+{
+ int clip_index;
+
+ for (clip_index = 0; clip_index < context->num_clips; ++clip_index) {
+ MovieClip *clip = context->clips[clip_index];
+ ListBase *plane_tracks_base =
+ BKE_tracking_get_active_plane_tracks(&clip->tracking);
+ MovieTrackingPlaneTrack *plane_track;
+
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) {
+ int track;
+ for (track = 0; track < context->num_tracks; ++track) {
+ MovieTrackingTrack *old_track;
+ bool do_update = false;
+ int j;
+
+ old_track = context->options[track].track;
+ for (j = 0; j < plane_track->point_tracksnr; j++) {
+ if (plane_track->point_tracks[j] == old_track) {
+ do_update = true;
+ break;
+ }
+ }
+
+ if (do_update) {
+ BKE_tracking_track_plane_from_existing_motion(
+ plane_track,
+ context->first_frame);
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void BKE_autotrack_context_free(AutoTrackContext *context)
+{
+ libmv_autoTrackDestroy(context->autotrack);
+ tracking_image_accessor_destroy(context->image_accessor);
+ MEM_freeN(context->options);
+ BLI_spin_end(&context->spin_lock);
+ MEM_freeN(context);
+}
diff --git a/source/blender/blenkernel/intern/tracking_detect.c b/source/blender/blenkernel/intern/tracking_detect.c
index 62039b761e8..6df51b5441a 100644
--- a/source/blender/blenkernel/intern/tracking_detect.c
+++ b/source/blender/blenkernel/intern/tracking_detect.c
@@ -40,7 +40,6 @@
#include "BKE_tracking.h"
#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
#include "libmv-capi.h"
diff --git a/source/blender/blenkernel/intern/tracking_region_tracker.c b/source/blender/blenkernel/intern/tracking_region_tracker.c
index c41106f37cb..dd7def16ca8 100644
--- a/source/blender/blenkernel/intern/tracking_region_tracker.c
+++ b/source/blender/blenkernel/intern/tracking_region_tracker.c
@@ -35,11 +35,8 @@
#include "MEM_guardedalloc.h"
#include "DNA_movieclip_types.h"
-#include "DNA_object_types.h" /* SELECT */
#include "BLI_utildefines.h"
-#include "BLI_math.h"
-#include "BLI_ghash.h"
#include "BLI_threads.h"
#include "BKE_tracking.h"
@@ -51,170 +48,6 @@
#include "libmv-capi.h"
#include "tracking_private.h"
-typedef struct TrackContext {
- /* the reference marker and cutout search area */
- MovieTrackingMarker reference_marker;
-
- /* keyframed patch. This is the search area */
- float *search_area;
- int search_area_height;
- int search_area_width;
- int framenr;
-
- float *mask;
-} TrackContext;
-
-typedef struct MovieTrackingContext {
- MovieClipUser user;
- MovieClip *clip;
- int clip_flag;
-
- int frames, first_frame;
- bool first_time;
-
- MovieTrackingSettings settings;
- TracksMap *tracks_map;
-
- bool backwards, sequence;
- int sync_frame;
-} MovieTrackingContext;
-
-static void track_context_free(void *customdata)
-{
- TrackContext *track_context = (TrackContext *)customdata;
-
- if (track_context->search_area)
- MEM_freeN(track_context->search_area);
-
- if (track_context->mask)
- MEM_freeN(track_context->mask);
-}
-
-/* Create context for motion 2D tracking, copies all data needed
- * for thread-safe tracking, allowing clip modifications during
- * tracking.
- */
-MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user,
- const bool backwards, const bool sequence)
-{
- MovieTrackingContext *context = MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
- MovieTracking *tracking = &clip->tracking;
- MovieTrackingSettings *settings = &tracking->settings;
- ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
- MovieTrackingTrack *track;
- MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
- int num_tracks = 0;
-
- context->clip = clip;
- context->settings = *settings;
- context->backwards = backwards;
- context->sync_frame = user->framenr;
- context->first_time = true;
- context->first_frame = user->framenr;
- context->sequence = sequence;
-
- /* count */
- track = tracksbase->first;
- while (track) {
- if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) {
- int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
-
- if ((marker->flag & MARKER_DISABLED) == 0)
- num_tracks++;
- }
-
- track = track->next;
- }
-
- /* create tracking contextx for all tracks which would be tracked */
- if (num_tracks) {
- int width, height;
-
- context->tracks_map = tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA,
- num_tracks, sizeof(TrackContext));
-
- BKE_movieclip_get_size(clip, user, &width, &height);
-
- /* create tracking data */
- track = tracksbase->first;
- while (track) {
- if (TRACK_SELECTED(track) && (track->flag & (TRACK_HIDDEN | TRACK_LOCKED)) == 0) {
- int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
-
- if ((marker->flag & MARKER_DISABLED) == 0) {
- TrackContext track_context;
- memset(&track_context, 0, sizeof(TrackContext));
- tracks_map_insert(context->tracks_map, track, &track_context);
- }
- }
-
- track = track->next;
- }
- }
-
- /* store needed clip flags passing to get_buffer functions
- * - MCLIP_USE_PROXY is needed to because timecode affects on movie clip
- * only in case Proxy/Timecode flag is set, so store this flag to use
- * timecodes properly but reset render size to SIZE_FULL so correct resolution
- * would be used for images
- * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might
- * be stored in a different location
- * ignore all the rest possible flags for now
- */
- context->clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS;
-
- context->user = *user;
- context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
- context->user.render_flag = 0;
-
- if (!sequence)
- BLI_begin_threaded_malloc();
-
- return context;
-}
-
-/* Free context used for tracking. */
-void BKE_tracking_context_free(MovieTrackingContext *context)
-{
- if (!context->sequence)
- BLI_end_threaded_malloc();
-
- tracks_map_free(context->tracks_map, track_context_free);
-
- MEM_freeN(context);
-}
-
-/* Synchronize tracks between clip editor and tracking context,
- * by merging them together so all new created tracks and tracked
- * ones presents in the movie clip.
- */
-void BKE_tracking_context_sync(MovieTrackingContext *context)
-{
- MovieTracking *tracking = &context->clip->tracking;
- int newframe;
-
- tracks_map_merge(context->tracks_map, tracking);
-
- if (context->backwards)
- newframe = context->user.framenr + 1;
- else
- newframe = context->user.framenr - 1;
-
- context->sync_frame = newframe;
-
- BKE_tracking_dopesheet_tag_update(tracking);
-}
-
-/* Synchronize clip user's frame number with a frame number from tracking context,
- * used to update current frame displayed in the clip editor while tracking.
- */
-void BKE_tracking_context_sync_user(const MovieTrackingContext *context, MovieClipUser *user)
-{
- user->framenr = context->sync_frame;
-}
-
/* **** utility functions for tracking **** */
/* convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */
@@ -280,7 +113,7 @@ static float *track_get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track,
return gray_pixels;
}
-/* Get image boffer for a given frame
+/* Get image buffer for a given frame
*
* Frame is in clip space.
*/
@@ -296,51 +129,6 @@ static ImBuf *tracking_context_get_frame_ibuf(MovieClip *clip, MovieClipUser *us
return ibuf;
}
-/* Get previous keyframed marker. */
-static MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingTrack *track,
- int curfra, bool backwards)
-{
- MovieTrackingMarker *marker_keyed = NULL;
- MovieTrackingMarker *marker_keyed_fallback = NULL;
- int a = BKE_tracking_marker_get(track, curfra) - track->markers;
-
- while (a >= 0 && a < track->markersnr) {
- int next = backwards ? a + 1 : a - 1;
- bool is_keyframed = false;
- MovieTrackingMarker *cur_marker = &track->markers[a];
- MovieTrackingMarker *next_marker = NULL;
-
- if (next >= 0 && next < track->markersnr)
- next_marker = &track->markers[next];
-
- if ((cur_marker->flag & MARKER_DISABLED) == 0) {
- /* If it'll happen so we didn't find a real keyframe marker,
- * fallback to the first marker in current tracked segment
- * as a keyframe.
- */
- if (next_marker && next_marker->flag & MARKER_DISABLED) {
- if (marker_keyed_fallback == NULL)
- marker_keyed_fallback = cur_marker;
- }
-
- is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0;
- }
-
- if (is_keyframed) {
- marker_keyed = cur_marker;
-
- break;
- }
-
- a = next;
- }
-
- if (marker_keyed == NULL)
- marker_keyed = marker_keyed_fallback;
-
- return marker_keyed;
-}
-
/* Get image buffer for previous marker's keyframe. */
static ImBuf *tracking_context_get_keyframed_ibuf(MovieClip *clip, MovieClipUser *user, int clip_flag,
MovieTrackingTrack *track, int curfra, bool backwards,
@@ -349,7 +137,7 @@ static ImBuf *tracking_context_get_keyframed_ibuf(MovieClip *clip, MovieClipUser
MovieTrackingMarker *marker_keyed;
int keyed_framenr;
- marker_keyed = tracking_context_get_keyframed_marker(track, curfra, backwards);
+ marker_keyed = tracking_get_keyframed_marker(track, curfra, backwards);
if (marker_keyed == NULL) {
return NULL;
}
@@ -381,50 +169,9 @@ static ImBuf *tracking_context_get_reference_ibuf(MovieClip *clip, MovieClipUser
return ibuf;
}
-/* Update track's reference patch (patch from which track is tracking from)
- *
- * Returns false if reference image buffer failed to load.
- */
-static bool track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context,
- MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra,
- int frame_width, int frame_height)
-{
- MovieTrackingMarker *reference_marker = NULL;
- ImBuf *reference_ibuf = NULL;
- int width, height;
-
- /* calculate patch for keyframed position */
- reference_ibuf = tracking_context_get_reference_ibuf(context->clip, &context->user, context->clip_flag,
- track, curfra, context->backwards, &reference_marker);
-
- if (!reference_ibuf)
- return false;
-
- track_context->reference_marker = *reference_marker;
-
- if (track_context->search_area) {
- MEM_freeN(track_context->search_area);
- }
-
- track_context->search_area = track_get_search_floatbuf(reference_ibuf, track, reference_marker, &width, &height);
- track_context->search_area_height = height;
- track_context->search_area_width = width;
-
- if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) {
- if (track_context->mask)
- MEM_freeN(track_context->mask);
-
- track_context->mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
- }
-
- IMB_freeImBuf(reference_ibuf);
-
- return true;
-}
-
/* Fill in libmv tracker options structure with settings need to be used to perform track. */
-static void tracking_configure_tracker(const MovieTrackingTrack *track, float *mask,
- libmv_TrackRegionOptions *options)
+void tracking_configure_tracker(const MovieTrackingTrack *track, float *mask,
+ libmv_TrackRegionOptions *options)
{
options->motion_model = track->motion_model;
@@ -442,102 +189,6 @@ static void tracking_configure_tracker(const MovieTrackingTrack *track, float *m
options->image1_mask = NULL;
}
-/* returns false if marker crossed margin area from frame bounds */
-static bool tracking_check_marker_margin(MovieTrackingTrack *track, MovieTrackingMarker *marker,
- int frame_width, int frame_height)
-{
- float pat_min[2], pat_max[2];
- float margin_left, margin_top, margin_right, margin_bottom;
- float normalized_track_margin[2];
-
- /* margin from frame boundaries */
- BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
-
- normalized_track_margin[0] = (float)track->margin / frame_width;
- normalized_track_margin[1] = (float)track->margin / frame_height;
-
- margin_left = max_ff(-pat_min[0], normalized_track_margin[0]);
- margin_top = max_ff( pat_max[1], normalized_track_margin[1]);
- margin_right = max_ff( pat_max[0], normalized_track_margin[0]);
- margin_bottom = max_ff(-pat_min[1], normalized_track_margin[1]);
-
- /* do not track markers which are too close to boundary */
- if (marker->pos[0] < margin_left || marker->pos[0] > 1.0f - margin_right ||
- marker->pos[1] < margin_bottom || marker->pos[1] > 1.0f - margin_top)
- {
- return false;
- }
-
- return true;
-}
-
-/* Scale search area of marker based on scale changes of pattern area,
- *
- * TODO(sergey): currently based on pattern bounding box scale change,
- * smarter approach here is welcome.
- */
-static void tracking_scale_marker_search(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker)
-{
- float old_pat_min[2], old_pat_max[2];
- float new_pat_min[2], new_pat_max[2];
- float scale_x, scale_y;
-
- BKE_tracking_marker_pattern_minmax(old_marker, old_pat_min, old_pat_max);
- BKE_tracking_marker_pattern_minmax(new_marker, new_pat_min, new_pat_max);
-
- scale_x = (new_pat_max[0] - new_pat_min[0]) / (old_pat_max[0] - old_pat_min[0]);
- scale_y = (new_pat_max[1] - new_pat_min[1]) / (old_pat_max[1] - old_pat_min[1]);
-
- new_marker->search_min[0] *= scale_x;
- new_marker->search_min[1] *= scale_y;
-
- new_marker->search_max[0] *= scale_x;
- new_marker->search_max[1] *= scale_y;
-}
-
-/* Insert new marker which was tracked from old_marker to a new image,
- * will also ensure tracked segment is surrounded by disabled markers.
- */
-static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrackingTrack *track,
- const MovieTrackingMarker *old_marker, int curfra, bool tracked,
- int frame_width, int frame_height,
- const double dst_pixel_x[5], const double dst_pixel_y[5])
-{
- MovieTrackingMarker new_marker;
- int frame_delta = context->backwards ? -1 : 1;
- int nextfra = curfra + frame_delta;
-
- new_marker = *old_marker;
-
- if (tracked) {
- tracking_set_marker_coords_from_tracking(frame_width, frame_height, &new_marker, dst_pixel_x, dst_pixel_y);
- new_marker.flag |= MARKER_TRACKED;
- new_marker.framenr = nextfra;
-
- tracking_scale_marker_search(old_marker, &new_marker);
-
- if (context->first_time) {
- /* check if there's no keyframe/tracked markers before tracking marker.
- * if so -- create disabled marker before currently tracking "segment"
- */
-
- tracking_marker_insert_disabled(track, old_marker, !context->backwards, false);
- }
-
- /* insert currently tracked marker */
- BKE_tracking_marker_insert(track, &new_marker);
-
- /* make currently tracked segment be finished with disabled marker */
- tracking_marker_insert_disabled(track, &new_marker, context->backwards, false);
- }
- else {
- new_marker.framenr = nextfra;
- new_marker.flag |= MARKER_DISABLED;
-
- BKE_tracking_marker_insert(track, &new_marker);
- }
-}
-
/* Peform tracking from a reference_marker to destination_ibuf.
* Uses marker as an initial position guess.
*
@@ -601,130 +252,6 @@ static bool configure_and_run_tracker(ImBuf *destination_ibuf, MovieTrackingTrac
return tracked;
}
-/* Track all the tracks from context one more frame,
- * returns FALSe if nothing was tracked.
- */
-bool BKE_tracking_context_step(MovieTrackingContext *context)
-{
- ImBuf *destination_ibuf;
- int frame_delta = context->backwards ? -1 : 1;
- int curfra = BKE_movieclip_remap_scene_to_clip_frame(context->clip, context->user.framenr);
- int a, map_size;
- bool ok = false;
-
- int frame_width, frame_height;
-
- map_size = tracks_map_get_size(context->tracks_map);
-
- /* Nothing to track, avoid unneeded frames reading to save time and memory. */
- if (!map_size)
- return false;
-
- /* Get an image buffer for frame we're tracking to. */
- context->user.framenr += frame_delta;
-
- destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user,
- context->clip_flag, MOVIECLIP_CACHE_SKIP);
- if (!destination_ibuf)
- return false;
-
- frame_width = destination_ibuf->x;
- frame_height = destination_ibuf->y;
-
-#pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size > 1)
- for (a = 0; a < map_size; a++) {
- TrackContext *track_context = NULL;
- MovieTrackingTrack *track;
- MovieTrackingMarker *marker;
-
- tracks_map_get_indexed_element(context->tracks_map, a, &track, (void **)&track_context);
-
- marker = BKE_tracking_marker_get_exact(track, curfra);
-
- if (marker && (marker->flag & MARKER_DISABLED) == 0) {
- bool tracked = false, need_readjust;
- double dst_pixel_x[5], dst_pixel_y[5];
-
- if (track->pattern_match == TRACK_MATCH_KEYFRAME)
- need_readjust = context->first_time;
- else
- need_readjust = true;
-
- /* do not track markers which are too close to boundary */
- if (tracking_check_marker_margin(track, marker, frame_width, frame_height)) {
- if (need_readjust) {
- if (track_context_update_reference(context, track_context, track, marker,
- curfra, frame_width, frame_height) == false)
- {
- /* happens when reference frame fails to be loaded */
- continue;
- }
- }
-
- tracked = configure_and_run_tracker(destination_ibuf, track,
- &track_context->reference_marker, marker,
- track_context->search_area,
- track_context->search_area_width,
- track_context->search_area_height,
- track_context->mask,
- dst_pixel_x, dst_pixel_y);
- }
-
- BLI_spin_lock(&context->tracks_map->spin_lock);
- tracking_insert_new_marker(context, track, marker, curfra, tracked,
- frame_width, frame_height, dst_pixel_x, dst_pixel_y);
- BLI_spin_unlock(&context->tracks_map->spin_lock);
-
- ok = true;
- }
- }
-
- IMB_freeImBuf(destination_ibuf);
-
- context->first_time = false;
- context->frames++;
-
- return ok;
-}
-
-void BKE_tracking_context_finish(MovieTrackingContext *context)
-{
- MovieClip *clip = context->clip;
- ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
- MovieTrackingPlaneTrack *plane_track;
- int map_size = tracks_map_get_size(context->tracks_map);
-
- for (plane_track = plane_tracks_base->first;
- plane_track;
- plane_track = plane_track->next)
- {
- if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) {
- int i;
- for (i = 0; i < map_size; i++) {
- TrackContext *track_context = NULL;
- MovieTrackingTrack *track, *old_track;
- bool do_update = false;
- int j;
-
- tracks_map_get_indexed_element(context->tracks_map, i, &track, (void **)&track_context);
-
- old_track = BLI_ghash_lookup(context->tracks_map->hash, track);
- for (j = 0; j < plane_track->point_tracksnr; j++) {
- if (plane_track->point_tracks[j] == old_track) {
- do_update = true;
- break;
- }
- }
-
- if (do_update) {
- BKE_tracking_track_plane_from_existing_motion(plane_track, context->first_frame);
- break;
- }
- }
- }
- }
-}
-
static bool refine_marker_reference_frame_get(MovieTrackingTrack *track,
MovieTrackingMarker *marker,
bool backwards,
diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c
index 056220e27d8..d5e2f24e9ed 100644
--- a/source/blender/blenkernel/intern/tracking_solver.c
+++ b/source/blender/blenkernel/intern/tracking_solver.c
@@ -356,7 +356,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip
MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
float aspy = 1.0f / tracking->camera.pixel_aspect;
- int num_tracks = BLI_countlist(tracksbase);
+ int num_tracks = BLI_listbase_count(tracksbase);
int sfra = INT_MAX, efra = INT_MIN;
MovieTrackingTrack *track;
@@ -391,7 +391,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip
last_marker--;
}
- if (first < track->markersnr - 1)
+ if (first <= track->markersnr - 1)
sfra = min_ii(sfra, first_marker->framenr);
if (last >= 0)
@@ -509,6 +509,11 @@ bool BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieT
MovieTrackingReconstruction *reconstruction;
MovieTrackingObject *object;
+ if (!libmv_reconstructionIsValid(context->reconstruction)) {
+ printf("Failed solve the motion: most likely there are no good keyframes\n");
+ return false;
+ }
+
tracks_map_merge(context->tracks_map, tracking);
BKE_tracking_dopesheet_tag_update(tracking);
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index 0a8293630c7..882a6fabef1 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -47,8 +47,13 @@
#include "BLF_translation.h"
+#include "BKE_movieclip.h"
#include "BKE_tracking.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_moviecache.h"
+
#include "tracking_private.h"
#include "libmv-capi.h"
@@ -167,8 +172,7 @@ void tracks_map_merge(TracksMap *map, MovieTracking *tracking)
MovieTrackingTrack *new_track = BKE_tracking_track_duplicate(track);
/* Update old-new track mapping */
- BLI_ghash_remove(map->hash, track, NULL, NULL);
- BLI_ghash_insert(map->hash, track, new_track);
+ BLI_ghash_reinsert(map->hash, track, new_track, NULL, NULL);
BLI_addtail(&tracks, new_track);
}
@@ -390,8 +394,7 @@ void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrack
}
-/* Fill in Libmv C-API camera intrinsics options from tracking structure.
- */
+/* Fill in Libmv C-API camera intrinsics options from tracking structure. */
void tracking_cameraIntrinscisOptionsFromTracking(MovieTracking *tracking,
int calibration_width, int calibration_height,
libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
@@ -453,3 +456,441 @@ void tracking_trackingCameraFromIntrinscisOptions(MovieTracking *tracking,
BLI_assert(!"Unknown distortion model");
}
}
+
+/* Get previous keyframed marker. */
+MovieTrackingMarker *tracking_get_keyframed_marker(MovieTrackingTrack *track,
+ int current_frame,
+ bool backwards)
+{
+ MovieTrackingMarker *marker_keyed = NULL;
+ MovieTrackingMarker *marker_keyed_fallback = NULL;
+ int a = BKE_tracking_marker_get(track, current_frame) - track->markers;
+
+ while (a >= 0 && a < track->markersnr) {
+ int next = backwards ? a + 1 : a - 1;
+ bool is_keyframed = false;
+ MovieTrackingMarker *cur_marker = &track->markers[a];
+ MovieTrackingMarker *next_marker = NULL;
+
+ if (next >= 0 && next < track->markersnr)
+ next_marker = &track->markers[next];
+
+ if ((cur_marker->flag & MARKER_DISABLED) == 0) {
+ /* If it'll happen so we didn't find a real keyframe marker,
+ * fallback to the first marker in current tracked segment
+ * as a keyframe.
+ */
+ if (next_marker && next_marker->flag & MARKER_DISABLED) {
+ if (marker_keyed_fallback == NULL)
+ marker_keyed_fallback = cur_marker;
+ }
+
+ is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0;
+ }
+
+ if (is_keyframed) {
+ marker_keyed = cur_marker;
+
+ break;
+ }
+
+ a = next;
+ }
+
+ if (marker_keyed == NULL)
+ marker_keyed = marker_keyed_fallback;
+
+ return marker_keyed;
+}
+
+/*********************** Frame accessr *************************/
+
+typedef struct AccessCacheKey {
+ int clip_index;
+ int frame;
+ int downscale;
+ libmv_InputMode input_mode;
+ int64_t transform_key;
+} AccessCacheKey;
+
+static unsigned int accesscache_hashhash(const void *key_v)
+{
+ const AccessCacheKey *key = (const AccessCacheKey *) key_v;
+ /* TODP(sergey): Need better hasing here for faster frame access. */
+ return key->clip_index << 16 | key->frame;
+}
+
+static bool accesscache_hashcmp(const void *a_v, const void *b_v)
+{
+ const AccessCacheKey *a = (const AccessCacheKey *) a_v;
+ const AccessCacheKey *b = (const AccessCacheKey *) b_v;
+
+#define COMPARE_FIELD(field)
+ { \
+ if (a->clip_index != b->clip_index) { \
+ return false; \
+ } \
+ } (void) 0
+
+ COMPARE_FIELD(clip_index);
+ COMPARE_FIELD(frame);
+ COMPARE_FIELD(downscale);
+ COMPARE_FIELD(input_mode);
+ COMPARE_FIELD(transform_key);
+
+#undef COMPARE_FIELD
+
+ return true;
+}
+
+static void accesscache_put(TrackingImageAccessor *accessor,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ int64_t transform_key,
+ ImBuf *ibuf)
+{
+ AccessCacheKey key;
+ key.clip_index = clip_index;
+ key.frame = frame;
+ key.input_mode = input_mode;
+ key.downscale = downscale;
+ key.transform_key = transform_key;
+ IMB_moviecache_put(accessor->cache, &key, ibuf);
+}
+
+static ImBuf *accesscache_get(TrackingImageAccessor *accessor,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ int64_t transform_key)
+{
+ AccessCacheKey key;
+ key.clip_index = clip_index;
+ key.frame = frame;
+ key.input_mode = input_mode;
+ key.downscale = downscale;
+ key.transform_key = transform_key;
+ return IMB_moviecache_get(accessor->cache, &key);
+}
+
+static ImBuf *accessor_get_preprocessed_ibuf(TrackingImageAccessor *accessor,
+ int clip_index,
+ int frame)
+{
+ MovieClip *clip;
+ MovieClipUser user;
+ ImBuf *ibuf;
+ int scene_frame;
+
+ BLI_assert(clip_index < accessor->num_clips);
+
+ clip = accessor->clips[clip_index];
+ scene_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, frame);
+ BKE_movieclip_user_set_frame(&user, scene_frame);
+ user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
+ user.render_flag = 0;
+ ibuf = BKE_movieclip_get_ibuf(clip, &user);
+
+ return ibuf;
+}
+
+static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf)
+{
+ ImBuf *grayscale = IMB_allocImBuf(ibuf->x, ibuf->y, 32, 0);
+ size_t size;
+ int i;
+
+ BLI_assert(ibuf->channels == 3 || ibuf->channels == 4);
+
+ /* TODO(sergey): Bummer, currently IMB API only allows to create 4 channels
+ * float buffer, so we do it manually here.
+ *
+ * Will generalize it later.
+ */
+ size = (size_t)grayscale->x * (size_t)grayscale->y * sizeof(float);
+ grayscale->channels = 1;
+ if ((grayscale->rect_float = MEM_mapallocN(size, "tracking grayscale image"))) {
+ grayscale->mall |= IB_rectfloat;
+ grayscale->flags |= IB_rectfloat;
+ }
+
+ for (i = 0; i < grayscale->x * grayscale->y; ++i) {
+ const float *pixel = ibuf->rect_float + ibuf->channels * i;
+
+ grayscale->rect_float[i] = 0.2126f * pixel[0] +
+ 0.7152f * pixel[1] +
+ 0.0722f * pixel[2];
+ }
+
+ return grayscale;
+}
+
+static void ibuf_to_float_image(const ImBuf *ibuf, libmv_FloatImage *float_image)
+{
+ BLI_assert(ibuf->rect_float != NULL);
+ float_image->buffer = ibuf->rect_float;
+ float_image->width = ibuf->x;
+ float_image->height = ibuf->y;
+ float_image->channels = ibuf->channels;
+}
+
+static ImBuf *float_image_to_ibuf(libmv_FloatImage *float_image)
+{
+ ImBuf *ibuf = IMB_allocImBuf(float_image->width, float_image->height, 32, 0);
+ size_t size = (size_t)ibuf->x * (size_t)ibuf->y *
+ float_image->channels * sizeof(float);
+ ibuf->channels = float_image->channels;
+ if ((ibuf->rect_float = MEM_mapallocN(size, "tracking grayscale image"))) {
+ ibuf->mall |= IB_rectfloat;
+ ibuf->flags |= IB_rectfloat;
+ }
+ memcpy(ibuf->rect_float, float_image->buffer, size);
+ return ibuf;
+}
+
+static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ const libmv_Region *region,
+ const libmv_FrameTransform *transform)
+{
+ ImBuf *ibuf, *orig_ibuf, *final_ibuf;
+ int64_t transform_key = 0;
+
+ if (transform != NULL) {
+ transform_key = libmv_frameAccessorgetTransformKey(transform);
+ }
+
+ /* First try to get fully processed image from the cache. */
+ ibuf = accesscache_get(accessor,
+ clip_index,
+ frame,
+ input_mode,
+ downscale,
+ transform_key);
+ if (ibuf != NULL) {
+ return ibuf;
+ }
+
+ /* And now we do postprocessing of the original frame. */
+ orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame);
+
+ if (orig_ibuf == NULL) {
+ return NULL;
+ }
+
+ if (region != NULL) {
+ int width = region->max[0] - region->min[0],
+ height = region->max[1] - region->min[1];
+
+ /* If the requested region goes outside of the actual frame we still
+ * return the requested region size, but only fill it's partially with
+ * the data we can.
+ */
+ int clamped_origin_x = max_ii((int)region->min[0], 0),
+ clamped_origin_y = max_ii((int)region->min[1], 0);
+ int dst_offset_x = clamped_origin_x - (int)region->min[0],
+ dst_offset_y = clamped_origin_y - (int)region->min[1];
+ int clamped_width = width - dst_offset_x,
+ clamped_height = height - dst_offset_y;
+ clamped_width = min_ii(clamped_width, orig_ibuf->x - clamped_origin_x);
+ clamped_height = min_ii(clamped_height, orig_ibuf->y - clamped_origin_y);
+
+ final_ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat);
+
+ if (orig_ibuf->rect_float != NULL) {
+ IMB_rectcpy(final_ibuf, orig_ibuf,
+ dst_offset_x, dst_offset_y,
+ clamped_origin_x, clamped_origin_y,
+ clamped_width, clamped_height);
+ }
+ else {
+ int y;
+ /* TODO(sergey): We don't do any color space or alpha conversion
+ * here. Probably Libmv is better to work in the linear space,
+ * but keep sRGB space here for compatibility for now.
+ */
+ for (y = 0; y < clamped_height; ++y) {
+ int x;
+ for (x = 0; x < clamped_width; ++x) {
+ int src_x = x + clamped_origin_x,
+ src_y = y + clamped_origin_y;
+ int dst_x = x + dst_offset_x,
+ dst_y = y + dst_offset_y;
+ int dst_index = (dst_y * width + dst_x) * 4,
+ src_index = (src_y * orig_ibuf->x + src_x) * 4;
+ rgba_uchar_to_float(final_ibuf->rect_float + dst_index,
+ (unsigned char *)orig_ibuf->rect +
+ src_index);
+ }
+ }
+ }
+ }
+ else {
+ /* Libmv only works with float images,
+ *
+ * This would likely make it so loads of float buffers are being stored
+ * in the cache which is nice on the one hand (faster re-use of the
+ * frames) but on the other hand it bumps the memory usage up.
+ */
+ BLI_lock_thread(LOCK_MOVIECLIP);
+ IMB_float_from_rect(orig_ibuf);
+ BLI_unlock_thread(LOCK_MOVIECLIP);
+ final_ibuf = orig_ibuf;
+ }
+
+ if (downscale > 0) {
+ if (final_ibuf == orig_ibuf) {
+ final_ibuf = IMB_dupImBuf(orig_ibuf);
+ }
+ IMB_scaleImBuf(final_ibuf,
+ ibuf->x / (1 << downscale),
+ ibuf->y / (1 << downscale));
+ }
+
+ if (transform != NULL) {
+ libmv_FloatImage input_image, output_image;
+ ibuf_to_float_image(final_ibuf, &input_image);
+ libmv_frameAccessorgetTransformRun(transform,
+ &input_image,
+ &output_image);
+ if (final_ibuf != orig_ibuf) {
+ IMB_freeImBuf(final_ibuf);
+ }
+ final_ibuf = float_image_to_ibuf(&output_image);
+ libmv_floatImageDestroy(&output_image);
+ }
+
+ if (input_mode == LIBMV_IMAGE_MODE_RGBA) {
+ BLI_assert(ibuf->channels == 3 || ibuf->channels == 4);
+ /* pass */
+ }
+ else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ {
+ if (final_ibuf->channels != 1) {
+ ImBuf *grayscale_ibuf = make_grayscale_ibuf_copy(final_ibuf);
+ if (final_ibuf != orig_ibuf) {
+ /* We dereference original frame later. */
+ IMB_freeImBuf(final_ibuf);
+ }
+ final_ibuf = grayscale_ibuf;
+ }
+ }
+
+ /* it's possible processing still didn't happen at this point,
+ * but we really need a copy of the buffer to be transformed
+ * and to be put to the cache.
+ */
+ if (final_ibuf == orig_ibuf) {
+ final_ibuf = IMB_dupImBuf(orig_ibuf);
+ }
+
+ IMB_freeImBuf(orig_ibuf);
+
+ /* We put postprocessed frame to the cache always for now,
+ * not the smartest thing in the world, but who cares at this point.
+ */
+
+ /* TODO(sergey): Disable cache for now, because we don't store region
+ * in the cache key and can't check whether cached version is usable for
+ * us or not.
+ *
+ * Need to think better about what to cache and when.
+ */
+ if (false) {
+ accesscache_put(accessor,
+ clip_index,
+ frame,
+ input_mode,
+ downscale,
+ transform_key,
+ final_ibuf);
+ }
+
+ return final_ibuf;
+}
+
+static libmv_CacheKey accessor_get_image_callback(
+ struct libmv_FrameAccessorUserData *user_data,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ const libmv_Region *region,
+ const libmv_FrameTransform *transform,
+ float **destination,
+ int *width,
+ int *height,
+ int *channels)
+{
+ TrackingImageAccessor *accessor = (TrackingImageAccessor *) user_data;
+ ImBuf *ibuf;
+
+ BLI_assert(clip_index >= 0 && clip_index < accessor->num_clips);
+
+ ibuf = accessor_get_ibuf(accessor,
+ clip_index,
+ frame,
+ input_mode,
+ downscale,
+ region,
+ transform);
+
+ if (ibuf) {
+ *destination = ibuf->rect_float;
+ *width = ibuf->x;
+ *height = ibuf->y;
+ *channels = ibuf->channels;
+ }
+ else {
+ *destination = NULL;
+ *width = 0;
+ *height = 0;
+ *channels = 0;
+ }
+
+ return ibuf;
+}
+
+static void accessor_release_image_callback(libmv_CacheKey cache_key)
+{
+ ImBuf *ibuf = (ImBuf *) cache_key;
+ IMB_freeImBuf(ibuf);
+}
+
+TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
+ int num_clips,
+ int start_frame)
+{
+ TrackingImageAccessor *accessor =
+ MEM_callocN(sizeof(TrackingImageAccessor), "tracking image accessor");
+
+ BLI_assert(num_clips <= MAX_ACCESSOR_CLIP);
+
+ accessor->cache = IMB_moviecache_create("frame access cache",
+ sizeof(AccessCacheKey),
+ accesscache_hashhash,
+ accesscache_hashcmp);
+
+ memcpy(accessor->clips, clips, num_clips * sizeof(MovieClip *));
+ accessor->num_clips = num_clips;
+ accessor->start_frame = start_frame;
+
+ accessor->libmv_accessor =
+ libmv_FrameAccessorNew((libmv_FrameAccessorUserData *) accessor,
+ accessor_get_image_callback,
+ accessor_release_image_callback);
+
+ return accessor;
+}
+
+void tracking_image_accessor_destroy(TrackingImageAccessor *accessor)
+{
+ IMB_moviecache_free(accessor->cache);
+ libmv_FrameAccessorDestroy(accessor->libmv_accessor);
+ MEM_freeN(accessor);
+}
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 8e3c92314e6..699e0d34161 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -38,8 +38,8 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
-#include "BLI_listbase.h"
#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
#include "BKE_animsys.h"
#include "BKE_global.h"
@@ -49,6 +49,8 @@
#include "BKE_node.h"
#include "BKE_world.h"
+#include "GPU_material.h"
+
void BKE_world_free_ex(World *wrld, bool do_id_user)
{
MTex *mtex;
@@ -69,6 +71,9 @@ void BKE_world_free_ex(World *wrld, bool do_id_user)
MEM_freeN(wrld->nodetree);
}
+ if (wrld->gpumaterial.first)
+ GPU_material_free(&wrld->gpumaterial);
+
BKE_icon_delete((struct ID *)wrld);
wrld->id.icon_id = 0;
}
@@ -134,6 +139,12 @@ World *BKE_world_copy(World *wrld)
if (wrld->preview)
wrldn->preview = BKE_previewimg_copy(wrld->preview);
+ BLI_listbase_clear(&wrldn->gpumaterial);
+
+ if (wrld->id.lib) {
+ BKE_id_lib_local_paths(G.main, wrld->id.lib, &wrldn->id);
+ }
+
return wrldn;
}
@@ -158,6 +169,8 @@ World *localize_world(World *wrld)
wrldn->preview = NULL;
+ BLI_listbase_clear(&wrldn->gpumaterial);
+
return wrldn;
}
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index aef44993912..85eac1f21ed 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -80,7 +80,9 @@ static void filepath_avi(char *string, RenderData *rd);
# include "BKE_writeffmpeg.h"
#endif
-#include "BKE_writeframeserver.h"
+#ifdef WITH_FRAMESERVER
+# include "BKE_writeframeserver.h"
+#endif
bMovieHandle *BKE_movie_handle_get(const char imtype)
{
@@ -251,7 +253,7 @@ static void end_avi(void)
}
#endif /* WITH_AVI */
-/* similar to BKE_makepicstring() */
+/* similar to BKE_image_path_from_imformat() */
void BKE_movie_filepath_get(char *string, RenderData *rd)
{
bMovieHandle *mh = BKE_movie_handle_get(rd->im_format.imtype);
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 739db7b7bdb..128a5da9b68 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -57,7 +57,6 @@
#include "BKE_sound.h"
#include "BKE_writeffmpeg.h"
-#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "ffmpeg_compat.h"
@@ -470,8 +469,8 @@ static int ffmpeg_proprty_valid(AVCodecContext *c, const char *prop_name, IDProp
{
int valid = 1;
- if (strcmp(prop_name, "video") == 0) {
- if (strcmp(curr->name, "bf") == 0) {
+ if (STREQ(prop_name, "video")) {
+ if (STREQ(curr->name, "bf")) {
/* flash codec doesn't support b frames */
valid &= c->codec_id != AV_CODEC_ID_FLV1;
}
@@ -484,7 +483,6 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
AVDictionary **dictionary)
{
IDProperty *prop;
- void *iter;
IDProperty *curr;
/* TODO(sergey): This is actually rather stupid, because changing
@@ -495,7 +493,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
*
* For as long we don't allow editing properties in the interface
* it's all good. bug if we allow editing them, we'll need to
- * repace it with some smarter code which would port settings
+ * replace it with some smarter code which would port settings
* from deprecated to new one.
*/
ffmpeg_set_expert_options(rd);
@@ -509,9 +507,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
return;
}
- iter = IDP_GetGroupIterator(prop);
-
- while ((curr = IDP_GroupIterNext(iter)) != NULL) {
+ for (curr = prop->data.group.first; curr; curr = curr->next) {
if (ffmpeg_proprty_valid(c, prop_name, curr))
set_ffmpeg_property_option(c, curr, dictionary);
}
@@ -602,8 +598,12 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
/* Keep lossless encodes in the RGB domain. */
if (codec_id == AV_CODEC_ID_HUFFYUV) {
- /* HUFFYUV was PIX_FMT_YUV422P before */
- c->pix_fmt = PIX_FMT_RGB32;
+ if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
+ c->pix_fmt = PIX_FMT_BGRA;
+ }
+ else {
+ c->pix_fmt = PIX_FMT_RGB32;
+ }
}
if (codec_id == AV_CODEC_ID_FFV1) {
@@ -624,9 +624,9 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
if ((of->oformat->flags & AVFMT_GLOBALHEADER)
#if 0
- || !strcmp(of->oformat->name, "mp4")
- || !strcmp(of->oformat->name, "mov")
- || !strcmp(of->oformat->name, "3gp")
+ || STREQ(of->oformat->name, "mp4")
+ || STREQ(of->oformat->name, "mov")
+ || STREQ(of->oformat->name, "3gp")
#endif
)
{
@@ -1632,6 +1632,12 @@ bool BKE_ffmpeg_alpha_channel_is_supported(RenderData *rd)
if (codec == AV_CODEC_ID_PNG)
return true;
+ if (codec == AV_CODEC_ID_PNG)
+ return true;
+
+ if (codec == AV_CODEC_ID_HUFFYUV)
+ return true;
+
#ifdef FFMPEG_FFV1_ALPHA_SUPPORTED
if (codec == AV_CODEC_ID_FFV1)
return true;
diff --git a/source/blender/blenkernel/intern/writeframeserver.c b/source/blender/blenkernel/intern/writeframeserver.c
index 746b99ffb52..ae6b19fb019 100644
--- a/source/blender/blenkernel/intern/writeframeserver.c
+++ b/source/blender/blenkernel/intern/writeframeserver.c
@@ -214,7 +214,7 @@ static int handle_request(RenderData *rd, char *req)
*p = 0;
- if (strcmp(path, "/index.html") == 0 || strcmp(path, "/") == 0) {
+ if (STREQ(path, "/index.html") || STREQ(path, "/")) {
safe_puts(index_page);
return -1;
}
@@ -226,7 +226,7 @@ static int handle_request(RenderData *rd, char *req)
write_ppm = 1;
return atoi(path + 12);
}
- if (strcmp(path, "/info.txt") == 0) {
+ if (STREQ(path, "/info.txt")) {
char buf[4096];
sprintf(buf,
@@ -250,7 +250,7 @@ static int handle_request(RenderData *rd, char *req)
safe_puts(buf);
return -1;
}
- if (strcmp(path, "/close.txt") == 0) {
+ if (STREQ(path, "/close.txt")) {
safe_puts(good_bye);
G.is_break = true; /* Abort render */
return -1;
diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h
index 6efa1533e3e..591ee4d0d01 100644
--- a/source/blender/blenkernel/tracking_private.h
+++ b/source/blender/blenkernel/tracking_private.h
@@ -95,4 +95,32 @@ void tracking_cameraIntrinscisOptionsFromTracking(struct MovieTracking *tracking
void tracking_trackingCameraFromIntrinscisOptions(struct MovieTracking *tracking,
const struct libmv_CameraIntrinsicsOptions *camera_intrinsics_options);
+struct libmv_TrackRegionOptions;
+
+void tracking_configure_tracker(const MovieTrackingTrack *track, float *mask,
+ struct libmv_TrackRegionOptions *options);
+
+struct MovieTrackingMarker *tracking_get_keyframed_marker(
+ struct MovieTrackingTrack *track,
+ int current_frame,
+ bool backwards);
+
+/*********************** Frame accessr *************************/
+
+struct libmv_FrameAccessor;
+
+#define MAX_ACCESSOR_CLIP 64
+typedef struct TrackingImageAccessor {
+ struct MovieCache *cache;
+ struct MovieClip *clips[MAX_ACCESSOR_CLIP];
+ int num_clips;
+ int start_frame;
+ struct libmv_FrameAccessor *libmv_accessor;
+} TrackingImageAccessor;
+
+TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
+ int num_clips,
+ int start_frame);
+void tracking_image_accessor_destroy(TrackingImageAccessor *accessor);
+
#endif /* __TRACKING_PRIVATE_H__ */
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h
index db33c5cec8b..c645ff06c00 100644
--- a/source/blender/blenlib/BLI_array.h
+++ b/source/blender/blenlib/BLI_array.h
@@ -34,9 +34,10 @@
*/
/* -------------------------------------------------------------------- */
-/* internal defines */
+/** \name Internal defines
+ * \{ */
-/* this returns the entire size of the array, including any buffering. */
+/** this returns the entire size of the array, including any buffering. */
#define _bli_array_totalsize_dynamic(arr) ( \
((arr) == NULL) ? \
0 : \
@@ -53,7 +54,10 @@
_bli_array_totalsize_dynamic(arr)) \
)
-/* BLI_array.c
+/** \} */
+
+
+/** BLI_array.c
*
* Doing the realloc in a macro isn't so simple,
* so use a function the macros can use.
@@ -64,23 +68,27 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
/* -------------------------------------------------------------------- */
-/* public defines */
-/* use sizeof(*(arr)) to ensure the array exists and is an array */
+/** \name Public defines
+ * \{ */
+
+/** use ``sizeof(*(arr))`` to ensure the array exists and is an array */
#define BLI_array_declare(arr) \
int _##arr##_count = ((void)(sizeof(*(arr))), 0); \
void *_##arr##_static = NULL
-/* this will use stack space, up to maxstatic array elements, before
+/**
+ * this will use stack space, up to maxstatic array elements, before
* switching to dynamic heap allocation */
#define BLI_array_staticdeclare(arr, maxstatic) \
int _##arr##_count = 0; \
char _##arr##_static[maxstatic * sizeof(*(arr))]
-/* this returns the logical size of the array, not including buffering. */
+/** returns the logical size of the array, not including buffering. */
#define BLI_array_count(arr) ((void)0, _##arr##_count)
-/* Grow the array by a fixed number of items.
+/**
+ * Grow the array by a fixed number of items.
*
* Allow for a large 'num' value when the new size is more than double
* to allocate the exact sized array. */
@@ -101,22 +109,21 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
)
-/* returns length of array */
-
+/** returns length of array */
#define BLI_array_grow_items(arr, num) \
(BLI_array_reserve(arr, num), (_##arr##_count += num))
#define BLI_array_grow_one(arr) \
BLI_array_grow_items(arr, 1)
-
-/* appends an item to the array. */
+/** appends an item to the array. */
#define BLI_array_append(arr, item) ( \
(void) BLI_array_grow_one(arr), \
(void) (arr[_##arr##_count - 1] = item) \
)
-/* appends an item to the array and returns a pointer to the item in the array.
+/**
+ * appends an item to the array and returns a pointer to the item in the array.
* item is not a pointer, but actual data value.*/
#define BLI_array_append_r(arr, item) ( \
(void) BLI_array_grow_one(arr), \
@@ -124,7 +131,7 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
(&arr[_##arr##_count - 1]) \
)
-/* appends (grows) & returns a pointer to the uninitialized memory */
+/** appends (grows) & returns a pointer to the uninitialized memory */
#define BLI_array_append_ret(arr) \
(BLI_array_reserve(arr, 1), &arr[(_##arr##_count++)])
@@ -140,28 +147,37 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
NULL \
)
-/* resets the logical size of an array to zero, but doesn't
+/**
+ * resets the logical size of an array to zero, but doesn't
* free the memory. */
#define BLI_array_empty(arr) \
{ _##arr##_count = 0; } (void)0
-/* set the count of the array, doesn't actually increase the allocated array
+/**
+ * set the count of the array, doesn't actually increase the allocated array
* size. don't use this unless you know what you're doing. */
#define BLI_array_count_set(arr, count) \
{ _##arr##_count = (count); }(void)0
-/* only to prevent unused warnings */
+/** only to prevent unused warnings */
#define BLI_array_fake_user(arr) \
((void)_##arr##_count, \
(void)_##arr##_static)
+/** \} */
+
/* -------------------------------------------------------------------- */
-/* other useful defines
- * (unrelated to the main array macros) */
-/* not part of the 'API' but handy funcs,
- * same purpose as BLI_array_staticdeclare()
+/** \name Generic Array Utils
+ * other useful defines
+ * (unrelated to the main array macros)
+ *
+ * \{ */
+
+/**
+ * not part of the 'API' but handy funcs,
+ * same purpose as #BLI_array_staticdeclare()
* but use when the max size is known ahead of time */
#define BLI_array_fixedstack_declare(arr, maxstatic, realsize, allocstr) \
char _##arr##_static[maxstatic * sizeof(*(arr))]; \
@@ -176,17 +192,6 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
MEM_freeN(arr); \
} (void)0
-
-void _bli_array_reverse(void *arr, unsigned int arr_len, size_t arr_stride);
-#define BLI_array_reverse(arr, arr_len) \
- _bli_array_reverse(arr, arr_len, sizeof(*(arr)))
-
-void _bli_array_wrap(void *arr, unsigned int arr_len, size_t arr_stride, int dir);
-#define BLI_array_wrap(arr, arr_len, dir) \
- _bli_array_wrap(arr, arr_len, sizeof(*(arr)), dir)
-
-int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p);
-#define BLI_array_findindex(arr, arr_len, p) \
- _bli_array_findindex(arr, arr_len, sizeof(*(arr)), p)
+/** \} */
#endif /* __BLI_ARRAY_H__ */
diff --git a/source/blender/blenlib/BLI_array_utils.h b/source/blender/blenlib/BLI_array_utils.h
new file mode 100644
index 00000000000..0dd1439e58c
--- /dev/null
+++ b/source/blender/blenlib/BLI_array_utils.h
@@ -0,0 +1,41 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_ARRAY_UTILS_H__
+#define __BLI_ARRAY_UTILS_H__
+
+/** \file BLI_array_utils.h
+ * \ingroup bli
+ * \brief Generic array manipulation API.
+ */
+
+void _bli_array_reverse(void *arr, unsigned int arr_len, size_t arr_stride);
+#define BLI_array_reverse(arr, arr_len) \
+ _bli_array_reverse(arr, arr_len, sizeof(*(arr)))
+
+void _bli_array_wrap(void *arr, unsigned int arr_len, size_t arr_stride, int dir);
+#define BLI_array_wrap(arr, arr_len, dir) \
+ _bli_array_wrap(arr, arr_len, sizeof(*(arr)), dir)
+
+int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p);
+#define BLI_array_findindex(arr, arr_len, p) \
+ _bli_array_findindex(arr, arr_len, sizeof(*(arr)), p)
+
+#endif /* __BLI_ARRAY_UTILS_H__ */
diff --git a/source/blender/blenlib/BLI_astar.h b/source/blender/blenlib/BLI_astar.h
new file mode 100644
index 00000000000..b99a2534d33
--- /dev/null
+++ b/source/blender/blenlib/BLI_astar.h
@@ -0,0 +1,98 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Bastien Montagne.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_ASTAR_H__
+#define __BLI_ASTAR_H__
+
+/** \file BLI_astar.h
+ * \ingroup bli
+ * \brief An implementation of the A* (AStar) algorithm to solve shortest path problem.
+ */
+
+#include "BLI_utildefines.h"
+
+#include "BLI_bitmap.h"
+
+/* -------------------------------------------------------------------- */
+
+typedef struct BLI_AStarGNLink {
+ int nodes[2];
+ float cost;
+
+ void *custom_data;
+} BLI_AStarGNLink;
+
+typedef struct BLI_AStarGNode {
+ struct ListBase neighbor_links;
+
+ void *custom_data;
+} BLI_AStarGNode;
+
+typedef struct BLI_AStarSolution {
+ /* Final 'most useful' data. */
+ int steps; /* Number of steps (i.e. walked links) in path (nodes num, including start and end, is steps + 1). */
+ int *prev_nodes; /* Store the path, in reversed order (from destination to source node), as indices. */
+ BLI_AStarGNLink **prev_links; /* Indices are nodes' ones, as prev_nodes, but they map to relevant link. */
+
+ void *custom_data;
+
+ /* Mostly runtime data. */
+ BLI_bitmap *done_nodes;
+ float *g_costs;
+ int *g_steps;
+
+ struct MemArena *mem; /* Memory arena. */
+} BLI_AStarSolution;
+
+typedef struct BLI_AStarGraph {
+ int node_num;
+ BLI_AStarGNode *nodes;
+
+ void *custom_data;
+
+ struct MemArena *mem; /* Memory arena. */
+} BLI_AStarGraph;
+
+void BLI_astar_node_init(BLI_AStarGraph *as_graph, const int node_index, void *custom_data);
+void BLI_astar_node_link_add(
+ BLI_AStarGraph *as_graph, const int node1_index, const int node2_index, const float cost, void *custom_data);
+int BLI_astar_node_link_other_node(BLI_AStarGNLink *lnk, const int idx);
+
+void BLI_astar_solution_init(BLI_AStarGraph *as_graph, BLI_AStarSolution *as_solution, void *custom_data);
+void BLI_astar_solution_clear(BLI_AStarSolution *as_solution);
+void BLI_astar_solution_free(BLI_AStarSolution *as_solution);
+
+typedef float (*astar_f_cost)(BLI_AStarGraph *as_graph, BLI_AStarSolution *as_solution, BLI_AStarGNLink *link,
+ const int node_idx_curr, const int node_idx_next, const int node_idx_dst);
+
+void BLI_astar_graph_init(BLI_AStarGraph *as_graph, const int node_num, void *custom_data);
+void BLI_astar_graph_free(BLI_AStarGraph *as_graph);
+bool BLI_astar_graph_solve(
+ BLI_AStarGraph *as_graph, const int node_index_src, const int node_index_dst, astar_f_cost f_cost_cb,
+ BLI_AStarSolution *r_solution, const int max_steps);
+
+#endif /* __BLI_ASTAR_H__ */
diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h
index 594bf89b667..60fc143a447 100644
--- a/source/blender/blenlib/BLI_bitmap.h
+++ b/source/blender/blenlib/BLI_bitmap.h
@@ -47,7 +47,7 @@ typedef unsigned int BLI_bitmap;
/* size (in bytes) used to hold '_tot' bits */
#define BLI_BITMAP_SIZE(_tot) \
- (_BITMAP_NUM_BLOCKS(_tot) * sizeof(BLI_bitmap))
+ ((size_t)(_BITMAP_NUM_BLOCKS(_tot)) * sizeof(BLI_bitmap))
/* allocate memory for a bitmap with '_tot' bits; free
* with MEM_freeN() */
@@ -59,25 +59,30 @@ typedef unsigned int BLI_bitmap;
#define BLI_BITMAP_NEW_ALLOCA(_tot) \
((BLI_bitmap *)memset(alloca(BLI_BITMAP_SIZE(_tot)), 0, BLI_BITMAP_SIZE(_tot)))
+/* Allocate using given MemArena */
+#define BLI_BITMAP_NEW_MEMARENA(_mem, _tot) \
+ (CHECK_TYPE_INLINE(_mem, MemArena *), \
+ ((BLI_bitmap *)BLI_memarena_calloc(_mem, BLI_BITMAP_SIZE(_tot))))
+
/* get the value of a single bit at '_index' */
#define BLI_BITMAP_TEST(_bitmap, _index) \
- (CHECK_TYPE_INLINE(_bitmap, BLI_bitmap *), \
+ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \
((_bitmap)[(_index) >> _BITMAP_POWER] & \
(1u << ((_index) & _BITMAP_MASK))))
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index) \
- (CHECK_TYPE_INLINE(_bitmap, BLI_bitmap *), \
+ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \
(BLI_BITMAP_TEST(_bitmap, _index) != 0))
/* set the value of a single bit at '_index' */
#define BLI_BITMAP_ENABLE(_bitmap, _index) \
- (CHECK_TYPE_INLINE(_bitmap, BLI_bitmap *), \
+ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \
((_bitmap)[(_index) >> _BITMAP_POWER] |= \
(1u << ((_index) & _BITMAP_MASK))))
/* clear the value of a single bit at '_index' */
#define BLI_BITMAP_DISABLE(_bitmap, _index) \
- (CHECK_TYPE_INLINE(_bitmap, BLI_bitmap *), \
+ (CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \
((_bitmap)[(_index) >> _BITMAP_POWER] &= \
~(1u << ((_index) & _BITMAP_MASK))))
diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h
index 700abcad9bd..4e5b61da532 100644
--- a/source/blender/blenlib/BLI_buffer.h
+++ b/source/blender/blenlib/BLI_buffer.h
@@ -29,7 +29,7 @@
* declared in since.
*
* Usage examples:
- * \code
+ * \code{.c}
* BLI_buffer_declare_static(int, my_int_array, BLI_BUFFER_NOP, 32);
*
* BLI_buffer_append(my_int_array, int, 42);
diff --git a/source/blender/blenlib/BLI_callbacks.h b/source/blender/blenlib/BLI_callbacks.h
index 2f963cfac51..7cf524749c2 100644
--- a/source/blender/blenlib/BLI_callbacks.h
+++ b/source/blender/blenlib/BLI_callbacks.h
@@ -41,6 +41,7 @@ typedef enum {
BLI_CB_EVT_FRAME_CHANGE_POST,
BLI_CB_EVT_RENDER_PRE,
BLI_CB_EVT_RENDER_POST,
+ BLI_CB_EVT_RENDER_WRITE,
BLI_CB_EVT_RENDER_STATS,
BLI_CB_EVT_RENDER_INIT,
BLI_CB_EVT_RENDER_COMPLETE,
diff --git a/source/blender/blenlib/BLI_compiler_compat.h b/source/blender/blenlib/BLI_compiler_compat.h
index 10c0752c9a7..876d2c459c5 100644
--- a/source/blender/blenlib/BLI_compiler_compat.h
+++ b/source/blender/blenlib/BLI_compiler_compat.h
@@ -37,4 +37,16 @@
# include <malloc.h>
#endif
+#if defined(__cplusplus) && ((__cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1800))
+# define HAS_CPP11_FEATURES
+#endif
+
+#if (defined(__GNUC__) || defined(__clang__)) && defined(HAS_CPP11_FEATURES)
+extern "C++" {
+ /* Some magic to be sure we don't have reference in the type. */
+ template<typename T> static inline T decltype_helper(T x) { return x; }
+# define typeof(x) decltype(decltype_helper(x))
+}
+#endif
+
#endif /* __BLI_COMPILER_COMPAT_H__ */
diff --git a/source/blender/blenlib/BLI_compiler_typecheck.h b/source/blender/blenlib/BLI_compiler_typecheck.h
index 551569b066d..652c4a954b9 100644
--- a/source/blender/blenlib/BLI_compiler_typecheck.h
+++ b/source/blender/blenlib/BLI_compiler_typecheck.h
@@ -51,9 +51,9 @@
}))
#else
-# define CHECK_TYPE(var, type)
-# define CHECK_TYPE_PAIR(var_a, var_b)
-# define CHECK_TYPE_PAIR_INLINE(var_a, var_b) (void)0
+# define CHECK_TYPE(var, type) { EXPR_NOP(var); }(void)0
+# define CHECK_TYPE_PAIR(var_a, var_b) { (EXPR_NOP(var_a), EXPR_NOP(var_b)); }(void)0
+# define CHECK_TYPE_PAIR_INLINE(var_a, var_b) (EXPR_NOP(var_a), EXPR_NOP(var_b))
#endif
/* can be used in simple macros */
@@ -66,22 +66,27 @@
((void)(((type)0) != (0 ? (val) : ((type)0))))
#endif
-#define CHECK_TYPE_NONCONST(var) { \
- void *non_const = 0 ? (var) : NULL; \
- (void)non_const; \
-} (void)0
+#if defined(__GNUC__) || defined(__clang__)
+# define CHECK_TYPE_NONCONST(var) __extension__ ({ \
+ void *non_const = 0 ? (var) : NULL; \
+ (void)non_const; \
+})
+#else
+# define CHECK_TYPE_NONCONST(var) EXPR_NOP(var)
+#endif
+
/**
* CHECK_TYPE_ANY: handy macro, eg:
* ``CHECK_TYPE_ANY(var, Foo *, Bar *, Baz *)``
*
* excuse ridiculously long generated args.
- * <pre>
+ * \code{.py}
* for i in range(63):
* args = [(chr(ord('a') + (c % 26)) + (chr(ord('0') + (c // 26)))) for c in range(i + 1)]
* print("#define _VA_CHECK_TYPE_ANY%d(v, %s) \\" % (i + 2, ", ".join(args)))
* print(" ((void)_Generic((v), %s))" % (": 0, ".join(args) + ": 0"))
- * </pre>
+ * \endcode
*/
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
diff --git a/source/blender/blenlib/BLI_dial.h b/source/blender/blenlib/BLI_dial.h
index c8b57e803d2..ad7680fe03e 100644
--- a/source/blender/blenlib/BLI_dial.h
+++ b/source/blender/blenlib/BLI_dial.h
@@ -34,7 +34,8 @@
* current and previous directions of the digit, and returned to the user.
*
* Usage examples:
- * \code
+ *
+ * \code{.c}
* float start_position[2] = {0.0f, 0.0f};
* float current_position[2];
* float threshold = 0.5f;
@@ -46,7 +47,6 @@
* angle = BLI_dial_angle(dial, curent_position);
*
* MEM_freeN(dial);
- *
* \endcode
*/
diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h
index a0455489d24..ded4b163f71 100644
--- a/source/blender/blenlib/BLI_edgehash.h
+++ b/source/blender/blenlib/BLI_edgehash.h
@@ -26,7 +26,6 @@
/** \file BLI_edgehash.h
* \ingroup bli
* \author Daniel Dunbar
- * \brief A general unordered 2-int pair hash table ADT.
*/
#include "BLI_compiler_attrs.h"
@@ -55,6 +54,9 @@ bool BLI_edgehash_reinsert(EdgeHash *eh, unsigned int v0, unsigned in
void *BLI_edgehash_lookup(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT;
void *BLI_edgehash_lookup_default(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val_default) ATTR_WARN_UNUSED_RESULT;
void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT;
+bool BLI_edgehash_remove(EdgeHash *eh, unsigned int v0, unsigned int v1, EdgeHashFreeFP valfreefp);
+
+void *BLI_edgehash_popkey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT;
bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT;
int BLI_edgehash_size(EdgeHash *eh) ATTR_WARN_UNUSED_RESULT;
void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP valfreefp,
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 4f451a6c741..7898a54002f 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -45,6 +45,8 @@ extern "C" {
#include <limits.h> /* for PATH_MAX */
+#include "BLI_compiler_attrs.h"
+
#ifndef PATH_MAX
# define PATH_MAX 4096
#endif
@@ -53,12 +55,12 @@ struct gzFile;
/* Common */
-int BLI_exists(const char *path);
-int BLI_copy(const char *path, const char *to);
-int BLI_rename(const char *from, const char *to);
-int BLI_delete(const char *path, bool dir, bool recursive);
-int BLI_move(const char *path, const char *to);
-int BLI_create_symlink(const char *path, const char *to);
+int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BLI_copy(const char *path, const char *to) ATTR_NONNULL();
+int BLI_rename(const char *from, const char *to) ATTR_NONNULL();
+int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL();
+int BLI_move(const char *path, const char *to) ATTR_NONNULL();
+int BLI_create_symlink(const char *path, const char *to) ATTR_NONNULL();
/* keep in sync with the definition of struct direntry in BLI_fileops_types.h */
#ifdef WIN32
@@ -73,7 +75,7 @@ typedef struct _stat BLI_stat_t;
typedef struct stat BLI_stat_t;
#endif
-int BLI_stat(const char *path, BLI_stat_t *buffer);
+int BLI_stat(const char *path, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
#ifdef WIN32
int BLI_wstat(const wchar_t *path, BLI_stat_t *buffer);
#endif
@@ -82,39 +84,44 @@ int BLI_wstat(const wchar_t *path, BLI_stat_t *buffer);
struct direntry;
-bool BLI_is_dir(const char *path);
-bool BLI_is_file(const char *path);
-void BLI_dir_create_recursive(const char *dir);
-double BLI_dir_free_space(const char *dir);
-char *BLI_current_working_dir(char *dir, const size_t maxlen);
+bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BLI_is_file(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void BLI_dir_create_recursive(const char *dir) ATTR_NONNULL();
+double BLI_dir_free_space(const char *dir) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+char *BLI_current_working_dir(char *dir, const size_t maxlen) ATTR_NONNULL();
+
+/* Filelist */
-unsigned int BLI_dir_contents(const char *dir, struct direntry **filelist);
-void BLI_free_filelist(struct direntry *filelist, unsigned int nrentries);
+unsigned int BLI_filelist_dir_contents(const char *dir, struct direntry **filelist);
+void BLI_filelist_duplicate(
+ struct direntry **dest_filelist, struct direntry *src_filelist, unsigned int nrentries,
+ void *(*dup_poin)(void *));
+void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries, void (*free_poin)(void *));
/* Files */
-FILE *BLI_fopen(const char *filename, const char *mode);
-void *BLI_gzopen(const char *filename, const char *mode);
-int BLI_open(const char *filename, int oflag, int pmode);
-int BLI_access(const char *filename, int mode);
+FILE *BLI_fopen(const char *filename, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void *BLI_gzopen(const char *filename, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BLI_open(const char *filename, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BLI_access(const char *filename, int mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BLI_file_is_writable(const char *file);
-bool BLI_file_touch(const char *file);
+bool BLI_file_is_writable(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BLI_file_touch(const char *file) ATTR_NONNULL();
#if 0 /* UNUSED */
-int BLI_file_gzip(const char *from, const char *to);
+int BLI_file_gzip(const char *from, const char *to) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
#endif
-char *BLI_file_ungzip_to_mem(const char *from_file, int *r_size);
+char *BLI_file_ungzip_to_mem(const char *from_file, int *r_size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-size_t BLI_file_descriptor_size(int file);
-size_t BLI_file_size(const char *file);
+size_t BLI_file_descriptor_size(int file) ATTR_WARN_UNUSED_RESULT;
+size_t BLI_file_size(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/* compare if one was last modified before the other */
-bool BLI_file_older(const char *file1, const char *file2);
+bool BLI_file_older(const char *file1, const char *file2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/* read ascii file as lines, empty list if reading fails */
-struct LinkNode *BLI_file_read_as_lines(const char *file);
-void BLI_file_free_lines(struct LinkNode *lines);
+struct LinkNode *BLI_file_read_as_lines(const char *file) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void BLI_file_free_lines(struct LinkNode *lines) ATTR_NONNULL();
/* this weirdo pops up in two places ... */
#if !defined(WIN32)
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index af2605894e3..bf2b4126453 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -30,7 +30,6 @@
/** \file BLI_ghash.h
* \ingroup bli
- * \brief A general (pointer -> pointer) hash table ADT
*/
#include "BLI_sys_types.h" /* for bool */
@@ -41,6 +40,7 @@ extern "C" {
#endif
typedef unsigned int (*GHashHashFP) (const void *key);
+/** returns false when equal */
typedef bool (*GHashCmpFP) (const void *a, const void *b);
typedef void (*GHashKeyFreeFP) (void *key);
typedef void (*GHashValFreeFP) (void *val);
@@ -124,17 +124,17 @@ bool BLI_ghashutil_ptrcmp(const void *a, const void *b);
unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n);
#define BLI_ghashutil_strhash(key) ( \
- CHECK_TYPE_INLINE(key, char *), \
+ CHECK_TYPE_ANY(key, char *, const char *, const char * const), \
BLI_ghashutil_strhash_p(key))
unsigned int BLI_ghashutil_strhash_p(const void *key);
bool BLI_ghashutil_strcmp(const void *a, const void *b);
#define BLI_ghashutil_inthash(key) ( \
- CHECK_TYPE_INLINE(&(key), int *), \
+ CHECK_TYPE_ANY(&(key), int *, const int *), \
BLI_ghashutil_uinthash((unsigned int)key))
unsigned int BLI_ghashutil_uinthash(unsigned int key);
#define BLI_ghashutil_inthash_v4(key) ( \
- CHECK_TYPE_INLINE(key, int *), \
+ CHECK_TYPE_ANY(key, int *, const int *), \
BLI_ghashutil_uinthash_v4((const unsigned int *)key))
unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4]);
#define BLI_ghashutil_inthash_v4_p \
diff --git a/source/blender/blenlib/BLI_md5.h b/source/blender/blenlib/BLI_hash_md5.h
index 6a760f53e45..544ae753793 100644
--- a/source/blender/blenlib/BLI_md5.h
+++ b/source/blender/blenlib/BLI_hash_md5.h
@@ -18,30 +18,26 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLI_MD5_H__
-#define __BLI_MD5_H__
+#ifndef __BLI_HASH_MD5_H__
+#define __BLI_HASH_MD5_H__
-/** \file BLI_md5.h
+/** \file BLI_hash_md5.h
* \ingroup bli
*/
-#include <stdio.h>
-#include <stdlib.h>
-
/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
* result is always in little endian byte order, so that a byte-wise
* output yields to the wanted ASCII representation of the message
* digest. */
-void *md5_buffer(const char *buffer, size_t len, void *resblock);
+void *BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock);
/* Compute MD5 message digest for bytes read from STREAM. The
* resulting message digest number will be written into the 16 bytes
* beginning at RESBLOCK. */
-int md5_stream(FILE *stream, void *resblock);
-
-char *md5_to_hexdigest(void *resblock, char r_hex_digest[33]);
+int BLI_hash_md5_stream(FILE *stream, void *resblock);
-#endif
+char *BLI_hash_md5_to_hexdigest(void *resblock, char r_hex_digest[33]);
+#endif /* __BLI_HASH_MD5_H__ */
diff --git a/source/blender/blenlib/BLI_hash_mm2a.h b/source/blender/blenlib/BLI_hash_mm2a.h
new file mode 100644
index 00000000000..007dec4f4d6
--- /dev/null
+++ b/source/blender/blenlib/BLI_hash_mm2a.h
@@ -0,0 +1,45 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_HASH_MM2A_H__
+#define __BLI_HASH_MM2A_H__
+
+/** \file BLI_hash_mm2a.h
+ * \ingroup bli
+ */
+
+#include "BLI_sys_types.h"
+
+typedef struct BLI_HashMurmur2A {
+ uint32_t hash;
+ uint32_t tail;
+ uint32_t count;
+ uint32_t size;
+} BLI_HashMurmur2A;
+
+void BLI_hash_mm2a_init(BLI_HashMurmur2A *mm2, uint32_t seed);
+
+void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t len);
+
+void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data);
+
+uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2);
+
+#endif /* __BLI_HASH_MM2A_H__ */
diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h
index ac9edfd46a2..ea361097b7b 100644
--- a/source/blender/blenlib/BLI_heap.h
+++ b/source/blender/blenlib/BLI_heap.h
@@ -37,6 +37,7 @@ typedef void (*HeapFreeFP)(void *ptr);
* are recycled, so memory usage will not shrink. */
Heap *BLI_heap_new_ex(unsigned int tot_reserve) ATTR_WARN_UNUSED_RESULT;
Heap *BLI_heap_new(void) ATTR_WARN_UNUSED_RESULT;
+void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1);
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1);
/* Insert heap node with a value (often a 'cost') and pointer into the heap,
diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h
index 49d072ddfdc..4981b163cdf 100644
--- a/source/blender/blenlib/BLI_kdopbvh.h
+++ b/source/blender/blenlib/BLI_kdopbvh.h
@@ -105,6 +105,10 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *n
int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit,
BVHTree_RayCastCallback callback, void *userdata);
+/* Calls the callback for every ray intersection */
+int BLI_bvhtree_ray_cast_all(BVHTree *tree, const float co[3], const float dir[3], float radius,
+ BVHTree_RayCastCallback callback, void *userdata);
+
float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3]);
/* range query */
diff --git a/source/blender/blenlib/BLI_linklist.h b/source/blender/blenlib/BLI_linklist.h
index 2ca363ee780..8dbf7b4a908 100644
--- a/source/blender/blenlib/BLI_linklist.h
+++ b/source/blender/blenlib/BLI_linklist.h
@@ -54,6 +54,8 @@ struct LinkNode *BLI_linklist_find(struct LinkNode *list, int index);
void BLI_linklist_reverse(struct LinkNode **listp);
+void BLI_linklist_move_item(struct LinkNode **listp, int curr_index, int new_index);
+
void BLI_linklist_prepend_nlink(struct LinkNode **listp, void *ptr, struct LinkNode *nlink);
void BLI_linklist_prepend(struct LinkNode **listp, void *ptr);
void BLI_linklist_prepend_arena(struct LinkNode **listp, void *ptr, struct MemArena *ma);
diff --git a/source/blender/blenlib/BLI_linklist_stack.h b/source/blender/blenlib/BLI_linklist_stack.h
index 17d40e068b3..9ac233a8fa4 100644
--- a/source/blender/blenlib/BLI_linklist_stack.h
+++ b/source/blender/blenlib/BLI_linklist_stack.h
@@ -51,46 +51,46 @@
#define BLI_LINKSTACK_DECLARE(var, type) \
LinkNode *var; \
- BLI_mempool *_##var##_pool; \
- type _##var##_type
+ BLI_mempool *var##_pool_; \
+ type var##_type_
#define BLI_LINKSTACK_INIT(var) { \
var = NULL; \
- _##var##_pool = BLI_mempool_create(sizeof(LinkNode), 0, 64, BLI_MEMPOOL_NOP); \
+ var##_pool_ = BLI_mempool_create(sizeof(LinkNode), 0, 64, BLI_MEMPOOL_NOP); \
} (void)0
#define BLI_LINKSTACK_SIZE(var) \
- BLI_mempool_count(_##var##_pool)
+ BLI_mempool_count(var##_pool_)
/* check for typeof() */
#ifdef __GNUC__
#define BLI_LINKSTACK_PUSH(var, ptr) ( \
- CHECK_TYPE_INLINE(ptr, typeof(_##var##_type)), \
- BLI_linklist_prepend_pool(&(var), ptr, _##var##_pool))
+ CHECK_TYPE_INLINE(ptr, typeof(var##_type_)), \
+ BLI_linklist_prepend_pool(&(var), ptr, var##_pool_))
#define BLI_LINKSTACK_POP(var) \
- (var ? (typeof(_##var##_type))BLI_linklist_pop_pool(&(var), _##var##_pool) : NULL)
+ (var ? (typeof(var##_type_))BLI_linklist_pop_pool(&(var), var##_pool_) : NULL)
#define BLI_LINKSTACK_POP_DEFAULT(var, r) \
- (var ? (typeof(_##var##_type))BLI_linklist_pop_pool(&(var), _##var##_pool) : r)
+ (var ? (typeof(var##_type_))BLI_linklist_pop_pool(&(var), var##_pool_) : r)
#else /* non gcc */
#define BLI_LINKSTACK_PUSH(var, ptr) ( \
- BLI_linklist_prepend_pool(&(var), ptr, _##var##_pool))
+ BLI_linklist_prepend_pool(&(var), ptr, var##_pool_))
#define BLI_LINKSTACK_POP(var) \
- (var ? BLI_linklist_pop_pool(&(var), _##var##_pool) : NULL)
+ (var ? BLI_linklist_pop_pool(&(var), var##_pool_) : NULL)
#define BLI_LINKSTACK_POP_DEFAULT(var, r) \
- (var ? BLI_linklist_pop_pool(&(var), _##var##_pool) : r)
+ (var ? BLI_linklist_pop_pool(&(var), var##_pool_) : r)
#endif /* gcc check */
#define BLI_LINKSTACK_SWAP(var_a, var_b) { \
- CHECK_TYPE_PAIR(_##var_a##_type, _##var_b##_type); \
+ CHECK_TYPE_PAIR(var_a##_type_, var_b##_type_); \
SWAP(LinkNode *, var_a, var_b); \
- SWAP(BLI_mempool *, _##var_a##_pool, _##var_b##_pool); \
+ SWAP(BLI_mempool *, var_a##_pool_, var_b##_pool_); \
} (void)0
#define BLI_LINKSTACK_FREE(var) { \
- BLI_mempool_destroy(_##var##_pool); \
- _##var##_pool = NULL; (void)_##var##_pool; \
+ BLI_mempool_destroy(var##_pool_); \
+ var##_pool_ = NULL; (void)var##_pool_; \
var = NULL; (void)var; \
- (void)&(_##var##_type); \
+ (void)&(var##_type_); \
} (void)0
#include "BLI_linklist.h"
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 3f03c4e3845..2e01f743f9e 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -67,10 +67,11 @@ void *BLI_poptail(ListBase *listbase) ATTR_NONNULL(1);
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1);
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1);
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1);
-void BLI_sortlist(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2);
-void BLI_sortlist_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) ATTR_NONNULL(1, 3);
+void BLI_listbase_sort(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2);
+void BLI_listbase_sort_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) ATTR_NONNULL(1, 3);
void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1);
-int BLI_countlist(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+int BLI_listbase_count_ex(const struct ListBase *listbase, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1);
void BLI_listbase_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2);
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 07de074e717..daa7db8e3cf 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -42,37 +42,43 @@
#endif
#ifndef M_PI
-#define M_PI 3.14159265358979323846
+#define M_PI 3.14159265358979323846 /* pi */
#endif
#ifndef M_PI_2
-#define M_PI_2 1.57079632679489661923
+#define M_PI_2 1.57079632679489661923 /* pi/2 */
+#endif
+#ifndef M_PI_4
+#define M_PI_4 0.78539816339744830962 /* pi/4 */
#endif
#ifndef M_SQRT2
-#define M_SQRT2 1.41421356237309504880
+#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
#endif
#ifndef M_SQRT1_2
-#define M_SQRT1_2 0.70710678118654752440
+#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
#endif
#ifndef M_SQRT3
-#define M_SQRT3 1.7320508075688772
+#define M_SQRT3 1.73205080756887729352 /* sqrt(3) */
+#endif
+#ifndef M_SQRT1_3
+#define M_SQRT1_3 0.57735026918962576450 /* 1/sqrt(3) */
#endif
#ifndef M_1_PI
-#define M_1_PI 0.318309886183790671538
+#define M_1_PI 0.318309886183790671538 /* 1/pi */
#endif
#ifndef M_E
-#define M_E 2.7182818284590452354
+#define M_E 2.7182818284590452354 /* e */
#endif
#ifndef M_LOG2E
-#define M_LOG2E 1.4426950408889634074
+#define M_LOG2E 1.4426950408889634074 /* log_2 e */
#endif
#ifndef M_LOG10E
-#define M_LOG10E 0.43429448190325182765
+#define M_LOG10E 0.43429448190325182765 /* log_10 e */
#endif
#ifndef M_LN2
-#define M_LN2 0.69314718055994530942
+#define M_LN2 0.69314718055994530942 /* log_e 2 */
#endif
#ifndef M_LN10
-#define M_LN10 2.30258509299404568402
+#define M_LN10 2.30258509299404568402 /* log_e 10 */
#endif
#if defined(__GNUC__)
@@ -157,6 +163,11 @@ static const int NAN_INT = 0x7FC00000;
/******************************* Float ******************************/
+MINLINE float pow2f(float x);
+MINLINE float pow3f(float x);
+MINLINE float pow4f(float x);
+MINLINE float pow7f(float x);
+
MINLINE float sqrt3f(float f);
MINLINE double sqrt3d(double d);
@@ -186,6 +197,8 @@ MINLINE int min_iiii(int a, int b, int c, int d);
MINLINE int max_iiii(int a, int b, int c, int d);
MINLINE float signf(float f);
+MINLINE int signum_i_ex(float a, float eps);
+MINLINE int signum_i(float a);
MINLINE float power_of_2(float f);
diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h
index 5c14ac55492..55e57b14d09 100644
--- a/source/blender/blenlib/BLI_math_color.h
+++ b/source/blender/blenlib/BLI_math_color.h
@@ -89,9 +89,6 @@ MINLINE float rgb_to_luma_y(const float rgb[3]);
/**************** Profile Transformations *****************/
-void gamma_correct(float *c, float gamma);
-float rec709_to_linearrgb(float c);
-float linearrgb_to_rec709(float c);
float srgb_to_linearrgb(float c);
float linearrgb_to_srgb(float c);
@@ -141,6 +138,10 @@ void xyz_to_lab(float x, float y, float z, float *l, float *a, float *b);
MINLINE int compare_rgb_uchar(const unsigned char a[3], const unsigned char b[3], const int limit);
+MINLINE float dither_random_value(float s, float t);
+MINLINE void float_to_byte_dither_v3(unsigned char b[3], const float f[3], float dither, float s, float t);
+
+
#define rgba_char_args_set_fl(col, r, g, b, a) \
rgba_char_args_set(col, (r) * 255, (g) * 255, (b) * 255, (a) * 255)
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index ba32b29becc..4f7a3310ee6 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -52,21 +52,31 @@ float normal_quad_v3(float r[3], const float a[3], const float b[3], const float
float normal_poly_v3(float r[3], const float verts[][3], unsigned int nr);
MINLINE float area_tri_v2(const float a[2], const float b[2], const float c[2]);
+MINLINE float area_squared_tri_v2(const float a[2], const float b[2], const float c[2]);
MINLINE float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2]);
float area_tri_v3(const float a[3], const float b[3], const float c[3]);
+float area_squared_tri_v3(const float a[3], const float b[3], const float c[3]);
float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3]);
float area_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
+float area_squared_quad_v3(const float a[3], const float b[3], const float c[3], const float d[3]);
float area_poly_v3(const float verts[][3], unsigned int nr);
float area_poly_v2(const float verts[][2], unsigned int nr);
+float area_squared_poly_v3(const float verts[][3], unsigned int nr);
+float area_squared_poly_v2(const float verts[][2], unsigned int nr);
+float area_poly_signed_v2(const float verts[][2], unsigned int nr);
float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3]);
+void cross_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3]);
MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2]);
+void cross_poly_v3(float n[3], const float verts[][3], unsigned int nr);
float cross_poly_v2(const float verts[][2], unsigned int nr);
/********************************* Planes **********************************/
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3]);
-void plane_to_point_normal_v3(const float plane[4], float r_plane_co[3], float r_plane_no[3]);
+void plane_to_point_vector_v3(const float plane[4], float r_plane_co[3], float r_plane_no[3]);
+void plane_to_point_vector_v3_normalized(const float plane[4], float r_plane_co[3], float r_plane_no[3]);
+
MINLINE float plane_point_side_v3(const float plane[4], const float co[3]);
/********************************* Volume **********************************/
@@ -77,6 +87,7 @@ float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const f
bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
bool is_poly_convex_v2(const float verts[][2], unsigned int nr);
+int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
/********************************* Distance **********************************/
@@ -95,6 +106,10 @@ float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const
float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
float dist_squared_to_line_v3(const float p[3], const float l1[3], const float l2[3]);
float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3]);
+float dist_signed_squared_to_corner_v3v3v3(
+ const float p[3],
+ const float v1[3], const float v2[3], const float v3[3],
+ const float axis_ref[3]);
float closest_to_line_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
float closest_to_line_v2(float r[2], const float p[2], const float l1[2], const float l2[2]);
void closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3]);
@@ -263,6 +278,9 @@ void orthographic_m4(float mat[4][4], const float left, const float right,
void window_translate_m4(float winmat[4][4], float perspmat[4][4],
const float x, const float y);
+void planes_from_projmat(float mat[4][4], float left[4], float right[4], float top[4], float bottom[4],
+ float front[4], float back[4]);
+
int box_clip_bounds_m4(float boundbox[2][3],
const float bounds[4], float winmat[4][4]);
void box_minmax_bounds_m4(float min[3], float max[3],
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h
index 732f4b66f38..45972d03175 100644
--- a/source/blender/blenlib/BLI_math_matrix.h
+++ b/source/blender/blenlib/BLI_math_matrix.h
@@ -125,7 +125,8 @@ void mul_m3_fl(float R[3][3], float f);
void mul_m4_fl(float R[4][4], float f);
void mul_mat3_m4_fl(float R[4][4], float f);
-void negate_m3(float R[4][4]);
+void negate_m3(float R[3][3]);
+void negate_mat3_m4(float R[4][4]);
void negate_m4(float R[4][4]);
bool invert_m3_ex(float m[3][3], const float epsilon);
@@ -144,7 +145,10 @@ void mul_v4d_m4v4d(double r[4], float M[4][4], double v[4]);
/****************************** Linear Algebra *******************************/
void transpose_m3(float R[3][3]);
+void transpose_m3_m3(float R[3][3], float A[3][3]);
+void transpose_m3_m4(float R[3][3], float A[4][4]);
void transpose_m4(float R[4][4]);
+void transpose_m4_m4(float R[4][4], float A[4][4]);
int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit);
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index 905889a33d7..fbd026f7617 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -119,6 +119,11 @@ void mat4_to_axis_angle(float axis[3], float *angle, float M[4][4]);
void axis_angle_to_mat3_single(float R[3][3], const char axis, const float angle);
void angle_to_mat2(float R[2][2], const float angle);
+/****************************** Exponential Map ******************************/
+void quat_to_expmap(float expmap[3], const float q[4]);
+void quat_normalized_to_expmap(float expmap[3], const float q[4]);
+void expmap_to_quat(float r[4], const float expmap[3]);
+
/******************************** XYZ Eulers *********************************/
void eul_to_quat(float quat[4], const float eul[3]);
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 6885a5aa351..ffd80f46725 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -148,6 +148,7 @@ MINLINE void negate_v3_short(short r[3]);
MINLINE float dot_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT;
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT;
+MINLINE float dot_v3v3v3(const float p[3], const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT;
MINLINE float dot_v4v4(const float a[4], const float b[4]) ATTR_WARN_UNUSED_RESULT;
MINLINE float cross_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT;
@@ -207,6 +208,7 @@ void interp_v4_v4v4_uchar(unsigned char target[4], const unsigned char a[4], con
void mid_v3_v3v3(float r[3], const float a[3], const float b[3]);
void mid_v2_v2v2(float r[2], const float a[2], const float b[2]);
void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3]);
+void mid_v3_v3v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3]);
void mid_v3_angle_weighted(float r[3]);
@@ -289,6 +291,8 @@ MINLINE void normal_float_to_short_v3(short r[3], const float n[3]);
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3]);
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2]);
+void minmax_v3v3_v3_array(float r_min[3], float r_max[3], float (*vec_arr)[3], int nbr);
+
void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist);
void dist_ensure_v2_v2fl(float v1[2], const float v2[2], const float dist);
@@ -318,6 +322,7 @@ void interp_vn_vn(float *array_tar, const float *array_src, const float t, const
void fill_vn_i(int *array_tar, const int size, const int val);
void fill_vn_short(short *array_tar, const int size, const short val);
void fill_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val);
+void fill_vn_uchar(unsigned char *array_tar, const int size, const unsigned char val);
void fill_vn_fl(float *array_tar, const int size, const float val);
/**************************** Inline Definitions ******************************/
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 3d82480d050..d99df24aaf7 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -40,40 +40,6 @@ extern "C" {
struct ListBase;
struct direntry;
-const char *BLI_getDefaultDocumentFolder(void);
-
-const char *BLI_get_folder(int folder_id, const char *subfolder);
-const char *BLI_get_folder_create(int folder_id, const char *subfolder);
-const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder);
-const char *BLI_get_folder_version(const int id, const int ver, const bool do_check);
-
-/* folder_id */
-
-/* general, will find based on user/local/system priority */
-#define BLENDER_DATAFILES 2
-
-/* user-specific */
-#define BLENDER_USER_CONFIG 31
-#define BLENDER_USER_DATAFILES 32
-#define BLENDER_USER_SCRIPTS 33
-#define BLENDER_USER_AUTOSAVE 34
-
-/* system */
-#define BLENDER_SYSTEM_DATAFILES 52
-#define BLENDER_SYSTEM_SCRIPTS 53
-#define BLENDER_SYSTEM_PYTHON 54
-
-/* for BLI_get_folder_version only */
-#define BLENDER_RESOURCE_PATH_USER 0
-#define BLENDER_RESOURCE_PATH_LOCAL 1
-#define BLENDER_RESOURCE_PATH_SYSTEM 2
-
-#define BLENDER_STARTUP_FILE "startup.blend"
-#define BLENDER_USERPREF_FILE "userpref.blend"
-#define BLENDER_QUIT_FILE "quit.blend"
-#define BLENDER_BOOKMARK_FILE "bookmarks.txt"
-#define BLENDER_HISTORY_FILE "recent-files.txt"
-
#ifdef WIN32
#define SEP '\\'
#define ALTSEP '/'
@@ -121,7 +87,7 @@ bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch) ATTR_NONNUL
bool BLI_replace_extension(char *path, size_t maxlen, const char *ext) ATTR_NONNULL();
bool BLI_ensure_extension(char *path, size_t maxlen, const char *ext) ATTR_NONNULL();
bool BLI_ensure_filename(char *filepath, size_t maxlen, const char *filename) ATTR_NONNULL();
-void BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offs, int len);
+bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offs, int len);
bool BLI_uniquename_cb(bool (*unique_check)(void *arg, const char *name),
void *arg, const char *defname, char delim, char *name, int name_len);
void BLI_newname(char *name, int add);
@@ -142,6 +108,8 @@ void BLI_cleanup_dir(const char *relabase, char *dir) ATTR_NONNULL(2);
/* doesn't touch trailing slash */
void BLI_cleanup_path(const char *relabase, char *path) ATTR_NONNULL(2);
+void BLI_filename_make_safe(char *fname) ATTR_NONNULL(1);
+
/* go back one directory */
bool BLI_parent_dir(char *path) ATTR_NONNULL();
@@ -185,19 +153,6 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char
void BLI_char_switch(char *string, char from, char to) ATTR_NONNULL();
-/* Initialize path to program executable */
-void BLI_init_program_path(const char *argv0);
-/* Initialize path to temporary directory.
- * NOTE: On Window userdir will be set to the temporary directory! */
-void BLI_temp_dir_init(char *userdir);
-
-const char *BLI_program_path(void);
-const char *BLI_program_dir(void);
-const char *BLI_temp_dir_session(void);
-const char *BLI_temp_dir_base(void);
-void BLI_system_temporary_dir(char *dir);
-void BLI_temp_dir_session_purge(void);
-
#ifdef WITH_ICONV
void BLI_string_to_utf8(char *original, char *utf_8, const char *code);
#endif
@@ -210,6 +165,15 @@ void BLI_string_to_utf8(char *original, char *utf_8, const char *code);
# define FILE_MAX 1024
#endif
+/* Parent and current dir helpers. */
+#define FILENAME_PARENT ".."
+#define FILENAME_CURRENT "."
+
+/* Avoid calling strcmp on one or two chars! */
+#define FILENAME_IS_PARENT(_n) (((_n)[0] == '.') && ((_n)[1] == '.') && ((_n)[2] == '\0'))
+#define FILENAME_IS_CURRENT(_n) (((_n)[0] == '.') && ((_n)[1] == '\0'))
+#define FILENAME_IS_CURRPAR(_n) (((_n)[0] == '.') && (((_n)[1] == '\0') || (((_n)[1] == '.') && ((_n)[2] == '\0'))))
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_polyfill2d.h b/source/blender/blenlib/BLI_polyfill2d.h
index 5c5cea8f67d..798055f9240 100644
--- a/source/blender/blenlib/BLI_polyfill2d.h
+++ b/source/blender/blenlib/BLI_polyfill2d.h
@@ -37,4 +37,7 @@ void BLI_polyfill_calc(
const int coords_sign,
unsigned int (*r_tris)[3]);
+/* default size of polyfill arena */
+#define BLI_POLYFILL_ARENA_SIZE MEM_SIZE_OPTIMAL(1 << 14)
+
#endif /* __BLI_POLYFILL2D_H__ */
diff --git a/source/blender/blenlib/BLI_polyfill2d_beautify.h b/source/blender/blenlib/BLI_polyfill2d_beautify.h
new file mode 100644
index 00000000000..20e53b080fe
--- /dev/null
+++ b/source/blender/blenlib/BLI_polyfill2d_beautify.h
@@ -0,0 +1,42 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_POLYFILL2D_BEAUTIFY_H__
+#define __BLI_POLYFILL2D_BEAUTIFY_H__
+
+struct EdgeHash;
+struct Heap;
+struct MemArena;
+
+void BLI_polyfill_beautify(
+ const float (*coords)[2],
+ const unsigned int coords_tot,
+ unsigned int (*tris)[3],
+
+ /* structs for reuse */
+ struct MemArena *arena, struct Heap *eheap, struct EdgeHash *eh);
+
+float BLI_polyfill_beautify_quad_rotate_calc(
+ const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
+
+/* avoid realloc's when creating new structures for polyfill ngons */
+#define BLI_POLYFILL_ALLOC_NGON_RESERVE 64
+
+#endif /* __BLI_POLYFILL2D_BEAUTIFY_H__ */
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h
index 879af446469..7b84dddcb68 100644
--- a/source/blender/blenlib/BLI_rand.h
+++ b/source/blender/blenlib/BLI_rand.h
@@ -55,6 +55,9 @@ double BLI_rng_get_double(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NON
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
void BLI_rng_get_float_unit_v2(struct RNG *rng, float v[2]) ATTR_NONNULL(1, 2);
void BLI_rng_get_float_unit_v3(struct RNG *rng, float v[3]) ATTR_NONNULL(1, 2);
+void BLI_rng_get_tri_sample_float_v2(
+ struct RNG *rng, const float v1[2], const float v2[2], const float v3[2],
+ float r_pt[2]) ATTR_NONNULL();
void BLI_rng_shuffle_array(struct RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_tot) ATTR_NONNULL(1, 2);
/** Note that skipping is as slow as generating n numbers! */
diff --git a/source/blender/blenlib/BLI_smallhash.h b/source/blender/blenlib/BLI_smallhash.h
index b80044bccff..e096354e5b1 100644
--- a/source/blender/blenlib/BLI_smallhash.h
+++ b/source/blender/blenlib/BLI_smallhash.h
@@ -52,7 +52,7 @@ typedef struct SmallHash {
} SmallHash;
typedef struct {
- SmallHash *sh;
+ const SmallHash *sh;
unsigned int i;
} SmallHashIter;
@@ -61,13 +61,16 @@ void BLI_smallhash_init_ex(SmallHash *sh,
void BLI_smallhash_init(SmallHash *sh) ATTR_NONNULL(1);
void BLI_smallhash_release(SmallHash *sh) ATTR_NONNULL(1);
void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *item) ATTR_NONNULL(1);
+bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item) ATTR_NONNULL(1);
bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1);
-void *BLI_smallhash_lookup(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
-void **BLI_smallhash_lookup_p(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
-bool BLI_smallhash_haskey(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1);
-int BLI_smallhash_count(SmallHash *sh) ATTR_NONNULL(1);
+void *BLI_smallhash_lookup(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
+void **BLI_smallhash_lookup_p(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
+bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1);
+int BLI_smallhash_count(const SmallHash *sh) ATTR_NONNULL(1);
void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
-void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
+void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
+void *BLI_smallhash_iternew(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
+void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
/* void BLI_smallhash_print(SmallHash *sh); */ /* UNUSED */
#ifdef DEBUG
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index b249bc720c6..c4853e37398 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -48,6 +48,8 @@ char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) AT
char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL();
+char *BLI_strncpy_ensure_pad(char *__restrict dst, const char *__restrict src, const char pad, size_t maxncpy) ATTR_NONNULL();
+
size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -71,6 +73,8 @@ char *BLI_strcasestr(const char *s, const char *find) ATTR_WARN_UNUSED_RESULT AT
int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
int BLI_strncasecmp(const char *s1, const char *s2, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
int BLI_natstrcmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+
size_t BLI_strnlen(const char *str, const size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void BLI_timestr(double _time, char *str, size_t maxlen) ATTR_NONNULL();
@@ -81,6 +85,9 @@ int BLI_str_rstrip_float_zero(char *str, const char pad) ATTR_NONNULL();
int BLI_str_index_in_array_n(const char *__restrict str, const char **__restrict str_array, const int str_array_len) ATTR_NONNULL();
int BLI_str_index_in_array(const char *__restrict str, const char **__restrict str_array) ATTR_NONNULL();
+bool BLI_str_endswith(const char *__restrict str, const char *__restrict end) ATTR_NONNULL();
+bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, size_t length) ATTR_NONNULL();
+
size_t BLI_str_partition(const char *str, const char delim[], char **sep, char **suf) ATTR_NONNULL();
size_t BLI_str_rpartition(const char *str, const char delim[], char **sep, char **suf) ATTR_NONNULL();
size_t BLI_str_partition_ex(const char *str, const char delim[], char **sep, char **suf, const bool from_right) ATTR_NONNULL();
diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h
index 89754be25ba..3e599865416 100644
--- a/source/blender/blenlib/BLI_string_utf8.h
+++ b/source/blender/blenlib/BLI_string_utf8.h
@@ -34,6 +34,7 @@ extern "C" {
#include "BLI_compiler_attrs.h"
char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL();
+size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL();
char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL();
int BLI_utf8_invalid_byte(const char *str, int length) ATTR_NONNULL();
int BLI_utf8_invalid_strip(char *str, int length) ATTR_NONNULL();
diff --git a/source/blender/blenlib/BLI_system.h b/source/blender/blenlib/BLI_system.h
index 8cdc9e4e6c5..cb8cb6f5a0d 100644
--- a/source/blender/blenlib/BLI_system.h
+++ b/source/blender/blenlib/BLI_system.h
@@ -27,6 +27,10 @@
int BLI_cpu_support_sse2(void);
+#if defined(NDEBUG) || !defined(__BLI_UTILDEFINES_H__)
+void BLI_system_backtrace(FILE *fp);
+#endif
+
/* getpid */
#ifdef WIN32
# define BLI_SYSTEM_PID_H <process.h>
@@ -35,4 +39,3 @@ int BLI_cpu_support_sse2(void);
#endif
#endif /* __BLI_SYSTEM_H__ */
-
diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h
index 8c22a25fe14..2eaec024ce2 100644
--- a/source/blender/blenlib/BLI_task.h
+++ b/source/blender/blenlib/BLI_task.h
@@ -73,7 +73,7 @@ typedef enum TaskPriority {
} TaskPriority;
typedef struct TaskPool TaskPool;
-typedef void (*TaskRunFunction)(TaskPool *pool, void *taskdata, int threadid);
+typedef void (*TaskRunFunction)(TaskPool *__restrict pool, void *taskdata, int threadid);
TaskPool *BLI_task_pool_create(TaskScheduler *scheduler, void *userdata);
void BLI_task_pool_free(TaskPool *pool);
@@ -88,6 +88,9 @@ void BLI_task_pool_cancel(TaskPool *pool);
/* stop all worker threads */
void BLI_task_pool_stop(TaskPool *pool);
+/* set number of threads allowed to be used by this pool */
+void BLI_pool_set_num_threads(TaskPool *pool, int num_threads);
+
/* for worker threads, test if canceled */
bool BLI_task_pool_canceled(TaskPool *pool);
@@ -106,7 +109,8 @@ void BLI_task_parallel_range_ex(
int start, int stop,
void *userdata,
TaskParallelRangeFunc func,
- const int range_threshold);
+ const int range_threshold,
+ const bool use_dynamic_scheduling);
void BLI_task_parallel_range(
int start, int stop,
void *userdata,
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 736578361b3..1e8440e55e9 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -32,6 +32,10 @@
* \ingroup bli
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* avoid many includes for now */
#include "BLI_sys_types.h"
#include "BLI_compiler_compat.h"
@@ -51,7 +55,8 @@
_49_, _50_, _51_, _52_, _53_, _54_, _55_, _56_, _57_, _58_, _59_, _60_, _61_, _62_, _63_, _64_, \
count, ...) count
#define _VA_NARGS_EXPAND(args) _VA_NARGS_RETURN_COUNT args
-#define _VA_NARGS_COUNT_MAX32(...) _VA_NARGS_EXPAND((__VA_ARGS__, \
+/* 64 args max */
+#define _VA_NARGS_COUNT(...) _VA_NARGS_EXPAND((__VA_ARGS__, \
64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \
48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, \
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \
@@ -61,7 +66,7 @@
#define _VA_NARGS_OVERLOAD_MACRO(name, count) _VA_NARGS_OVERLOAD_MACRO1(name, count)
/* --- expose for re-use --- */
#define VA_NARGS_CALL_OVERLOAD(name, ...) \
- _VA_NARGS_GLUE(_VA_NARGS_OVERLOAD_MACRO(name, _VA_NARGS_COUNT_MAX32(__VA_ARGS__)), (__VA_ARGS__))
+ _VA_NARGS_GLUE(_VA_NARGS_OVERLOAD_MACRO(name, _VA_NARGS_COUNT(__VA_ARGS__)), (__VA_ARGS__))
/* useful for finding bad use of min/max */
#if 0
@@ -179,8 +184,10 @@
/* ELEM#(v, ...): is the first arg equal any others? */
/* internal helpers*/
+#define _VA_ELEM2(v, a) \
+ ((v) == (a))
#define _VA_ELEM3(v, a, b) \
- (((v) == (a)) || ((v) == (b)))
+ (_VA_ELEM2(v, a) || ((v) == (b)))
#define _VA_ELEM4(v, a, b, c) \
(_VA_ELEM3(v, a, b) || ((v) == (c)))
#define _VA_ELEM5(v, a, b, c, d) \
@@ -213,6 +220,8 @@
/* reusable ELEM macro */
#define ELEM(...) VA_NARGS_CALL_OVERLOAD(_VA_ELEM, __VA_ARGS__)
+/* no-op for expressions we don't want to instansiate, but must remian valid */
+#define EXPR_NOP(expr) (void)(0 ? ((void)(expr), 1) : 0)
/* shift around elements */
#define SHIFT3(type, a, b, c) { \
@@ -335,6 +344,60 @@
if ((a) < (b)) (a) = (b); \
} (void)0
+#define CLAMP2(vec, b, c) { \
+ CLAMP((vec)[0], b, c); \
+ CLAMP((vec)[1], b, c); \
+} (void)0
+
+#define CLAMP2_MIN(vec, b) { \
+ CLAMP_MIN((vec)[0], b); \
+ CLAMP_MIN((vec)[1], b); \
+} (void)0
+
+#define CLAMP2_MAX(vec, b) { \
+ CLAMP_MAX((vec)[0], b); \
+ CLAMP_MAX((vec)[1], b); \
+} (void)0
+
+#define CLAMP3(vec, b, c) { \
+ CLAMP((vec)[0], b, c); \
+ CLAMP((vec)[1], b, c); \
+ CLAMP((vec)[2], b, c); \
+} (void)0
+
+#define CLAMP3_MIN(vec, b) { \
+ CLAMP_MIN((vec)[0], b); \
+ CLAMP_MIN((vec)[1], b); \
+ CLAMP_MIN((vec)[2], b); \
+} (void)0
+
+#define CLAMP3_MAX(vec, b) { \
+ CLAMP_MAX((vec)[0], b); \
+ CLAMP_MAX((vec)[1], b); \
+ CLAMP_MAX((vec)[2], b); \
+} (void)0
+
+#define CLAMP4(vec, b, c) { \
+ CLAMP((vec)[0], b, c); \
+ CLAMP((vec)[1], b, c); \
+ CLAMP((vec)[2], b, c); \
+ CLAMP((vec)[3], b, c); \
+} (void)0
+
+#define CLAMP4_MIN(vec, b) { \
+ CLAMP_MIN((vec)[0], b); \
+ CLAMP_MIN((vec)[1], b); \
+ CLAMP_MIN((vec)[2], b); \
+ CLAMP_MIN((vec)[3], b); \
+} (void)0
+
+#define CLAMP4_MAX(vec, b) { \
+ CLAMP_MAX((vec)[0], b); \
+ CLAMP_MAX((vec)[1], b); \
+ CLAMP_MAX((vec)[2], b); \
+ CLAMP_MAX((vec)[3], b); \
+} (void)0
+
#define IS_EQ(a, b) ( \
CHECK_TYPE_INLINE(a, double), CHECK_TYPE_INLINE(b, double), \
((fabs((double)((a) - (b))) >= (double) FLT_EPSILON) ? false : true))
@@ -373,13 +436,59 @@
/* assuming a static array */
#if defined(__GNUC__) && !defined(__cplusplus)
-# define ARRAY_SIZE(arr) \
- ((sizeof(struct {int isnt_array : ((void *)&(arr) == &(arr)[0]);}) * 0) + \
+# define ARRAY_SIZE(arr) \
+ ((sizeof(struct {int isnt_array : ((const void *)&(arr) == &(arr)[0]);}) * 0) + \
(sizeof(arr) / sizeof(*(arr))))
#else
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*(arr)))
#endif
+/* ARRAY_SET_ITEMS#(v, ...): set indices of array 'v' */
+/* internal helpers */
+#define _VA_ARRAY_SET_ITEMS2(v, a) \
+ ((v)[0] = (a))
+#define _VA_ARRAY_SET_ITEMS3(v, a, b) \
+ _VA_ARRAY_SET_ITEMS2(v, a); ((v)[1] = (b))
+#define _VA_ARRAY_SET_ITEMS4(v, a, b, c) \
+ _VA_ARRAY_SET_ITEMS3(v, a, b); ((v)[2] = (c))
+#define _VA_ARRAY_SET_ITEMS5(v, a, b, c, d) \
+ _VA_ARRAY_SET_ITEMS4(v, a, b, c); ((v)[3] = (d))
+#define _VA_ARRAY_SET_ITEMS6(v, a, b, c, d, e) \
+ _VA_ARRAY_SET_ITEMS5(v, a, b, c, d); ((v)[4] = (e))
+#define _VA_ARRAY_SET_ITEMS7(v, a, b, c, d, e, f) \
+ _VA_ARRAY_SET_ITEMS6(v, a, b, c, d, e); ((v)[5] = (f))
+#define _VA_ARRAY_SET_ITEMS8(v, a, b, c, d, e, f, g) \
+ _VA_ARRAY_SET_ITEMS7(v, a, b, c, d, e, f); ((v)[6] = (g))
+#define _VA_ARRAY_SET_ITEMS9(v, a, b, c, d, e, f, g, h) \
+ _VA_ARRAY_SET_ITEMS8(v, a, b, c, d, e, f, g); ((v)[7] = (h))
+#define _VA_ARRAY_SET_ITEMS10(v, a, b, c, d, e, f, g, h, i) \
+ _VA_ARRAY_SET_ITEMS9(v, a, b, c, d, e, f, g, h); ((v)[8] = (i))
+#define _VA_ARRAY_SET_ITEMS11(v, a, b, c, d, e, f, g, h, i, j) \
+ _VA_ARRAY_SET_ITEMS10(v, a, b, c, d, e, f, g, h, i); ((v)[9] = (j))
+#define _VA_ARRAY_SET_ITEMS12(v, a, b, c, d, e, f, g, h, i, j, k) \
+ _VA_ARRAY_SET_ITEMS11(v, a, b, c, d, e, f, g, h, i, j); ((v)[10] = (k))
+#define _VA_ARRAY_SET_ITEMS13(v, a, b, c, d, e, f, g, h, i, j, k, l) \
+ _VA_ARRAY_SET_ITEMS12(v, a, b, c, d, e, f, g, h, i, j, k); ((v)[11] = (l))
+#define _VA_ARRAY_SET_ITEMS14(v, a, b, c, d, e, f, g, h, i, j, k, l, m) \
+ _VA_ARRAY_SET_ITEMS13(v, a, b, c, d, e, f, g, h, i, j, k, l); ((v)[12] = (m))
+#define _VA_ARRAY_SET_ITEMS15(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n) \
+ _VA_ARRAY_SET_ITEMS14(v, a, b, c, d, e, f, g, h, i, j, k, l, m); ((v)[13] = (n))
+#define _VA_ARRAY_SET_ITEMS16(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) \
+ _VA_ARRAY_SET_ITEMS15(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n); ((v)[14] = (o))
+#define _VA_ARRAY_SET_ITEMS17(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
+ _VA_ARRAY_SET_ITEMS16(v, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); ((v)[15] = (p))
+
+/* reusable ARRAY_SET_ITEMS macro */
+#define ARRAY_SET_ITEMS(...) { VA_NARGS_CALL_OVERLOAD(_VA_ARRAY_SET_ITEMS, __VA_ARGS__); } (void)0
+
+#if defined(__GNUC__) || defined(__clang__)
+#define POINTER_OFFSET(v, ofs) \
+ ((typeof(v))((char *)(v) + ofs))
+#else
+#define POINTER_OFFSET(v, ofs) \
+ ((void *)((char *)(v) + ofs))
+#endif
+
/* Like offsetof(typeof(), member), for non-gcc compilers */
#define OFFSETOF_STRUCT(_struct, _member) \
((((char *)&((_struct)->_member)) - ((char *)(_struct))) + sizeof((_struct)->_member))
@@ -414,6 +523,11 @@
/* generic strcmp macros */
+#if defined(_MSC_VER)
+# define strcasecmp _stricmp
+# define strncasecmp _strnicmp
+#endif
+
#define STREQ(a, b) (strcmp(a, b) == 0)
#define STRCASEEQ(a, b) (strcasecmp(a, b) == 0)
#define STREQLEN(a, b, n) (strncmp(a, b, n) == 0)
@@ -437,6 +551,62 @@
# define UNUSED_FUNCTION(x) UNUSED_ ## x
#endif
+/**
+ * UNUSED_VARS#(a, ...): quiet unused warnings
+ *
+ * \code{.py}
+ * for i in range(16):
+ * args = [(chr(ord('a') + (c % 26)) + (chr(ord('0') + (c // 26)))) for c in range(i + 1)]
+ * print("#define _VA_UNUSED_VARS_%d(%s) \\" % (i + 1, ", ".join(args)))
+ * print("\t((void)(%s)%s)" %
+ * (args[0], ((", _VA_UNUSED_VARS_" + str(i) + "(%s)") if i else "%s") % ", ".join((args[1:]))))
+ * \endcode
+ */
+
+#define _VA_UNUSED_VARS_1(a0) \
+ ((void)(a0))
+#define _VA_UNUSED_VARS_2(a0, b0) \
+ ((void)(a0), _VA_UNUSED_VARS_1(b0))
+#define _VA_UNUSED_VARS_3(a0, b0, c0) \
+ ((void)(a0), _VA_UNUSED_VARS_2(b0, c0))
+#define _VA_UNUSED_VARS_4(a0, b0, c0, d0) \
+ ((void)(a0), _VA_UNUSED_VARS_3(b0, c0, d0))
+#define _VA_UNUSED_VARS_5(a0, b0, c0, d0, e0) \
+ ((void)(a0), _VA_UNUSED_VARS_4(b0, c0, d0, e0))
+#define _VA_UNUSED_VARS_6(a0, b0, c0, d0, e0, f0) \
+ ((void)(a0), _VA_UNUSED_VARS_5(b0, c0, d0, e0, f0))
+#define _VA_UNUSED_VARS_7(a0, b0, c0, d0, e0, f0, g0) \
+ ((void)(a0), _VA_UNUSED_VARS_6(b0, c0, d0, e0, f0, g0))
+#define _VA_UNUSED_VARS_8(a0, b0, c0, d0, e0, f0, g0, h0) \
+ ((void)(a0), _VA_UNUSED_VARS_7(b0, c0, d0, e0, f0, g0, h0))
+#define _VA_UNUSED_VARS_9(a0, b0, c0, d0, e0, f0, g0, h0, i0) \
+ ((void)(a0), _VA_UNUSED_VARS_8(b0, c0, d0, e0, f0, g0, h0, i0))
+#define _VA_UNUSED_VARS_10(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0) \
+ ((void)(a0), _VA_UNUSED_VARS_9(b0, c0, d0, e0, f0, g0, h0, i0, j0))
+#define _VA_UNUSED_VARS_11(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0) \
+ ((void)(a0), _VA_UNUSED_VARS_10(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0))
+#define _VA_UNUSED_VARS_12(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0) \
+ ((void)(a0), _VA_UNUSED_VARS_11(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0))
+#define _VA_UNUSED_VARS_13(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0) \
+ ((void)(a0), _VA_UNUSED_VARS_12(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0))
+#define _VA_UNUSED_VARS_14(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0) \
+ ((void)(a0), _VA_UNUSED_VARS_13(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0))
+#define _VA_UNUSED_VARS_15(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0) \
+ ((void)(a0), _VA_UNUSED_VARS_14(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0))
+#define _VA_UNUSED_VARS_16(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0) \
+ ((void)(a0), _VA_UNUSED_VARS_15(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0))
+
+
+/* reusable ELEM macro */
+#define UNUSED_VARS(...) VA_NARGS_CALL_OVERLOAD(_VA_UNUSED_VARS_, __VA_ARGS__)
+
+/* for debug-only variables */
+#ifndef NDEBUG
+# define UNUSED_VARS_NDEBUG(...)
+#else
+# define UNUSED_VARS_NDEBUG UNUSED_VARS
+#endif
+
/*little macro so inline keyword works*/
#if defined(_MSC_VER)
# define BLI_INLINE static __forceinline
@@ -454,6 +624,7 @@
* for aborting need to define WITH_ASSERT_ABORT
*/
#ifndef NDEBUG
+extern void BLI_system_backtrace(FILE *fp);
# ifdef WITH_ASSERT_ABORT
# define _BLI_DUMMY_ABORT abort
# else
@@ -463,6 +634,7 @@
# define BLI_assert(a) \
(void)((!(a)) ? ( \
( \
+ BLI_system_backtrace(stderr), \
fprintf(stderr, \
"BLI_assert failed: %s:%d, %s(), at \'%s\'\n", \
__FILE__, __LINE__, __func__, STRINGIFY(a)), \
@@ -502,4 +674,8 @@
# define UNLIKELY(x) (x)
#endif
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __BLI_UTILDEFINES_H__ */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 9efa20da13e..e614a2a0663 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -29,8 +29,8 @@ set(INC
.
# ../blenkernel # dont add this back!
../makesdna
- ../../../intern/ghost
../../../intern/guardedalloc
+ ../../../intern/atomic
../../../extern/wcwidth
)
@@ -52,6 +52,8 @@ set(SRC
intern/BLI_memarena.c
intern/BLI_mempool.c
intern/DLRB_tree.c
+ intern/array_utils.c
+ intern/astar.c
intern/boxpack2d.c
intern/buffer.c
intern/callbacks.c
@@ -65,6 +67,8 @@ set(SRC
intern/freetypefont.c
intern/graph.c
intern/gsqueue.c
+ intern/hash_md5.c
+ intern/hash_mm2a.c
intern/jitter.c
intern/lasso.c
intern/listbase.c
@@ -80,10 +84,10 @@ set(SRC
intern/math_rotation.c
intern/math_vector.c
intern/math_vector_inline.c
- intern/md5.c
intern/noise.c
intern/path_util.c
intern/polyfill2d.c
+ intern/polyfill2d_beautify.c
intern/quadric.c
intern/rand.c
intern/rct.c
@@ -111,6 +115,8 @@ set(SRC
BLI_alloca.h
BLI_args.h
BLI_array.h
+ BLI_array_utils.h
+ BLI_astar.h
BLI_bitmap.h
BLI_blenlib.h
BLI_boxpack2d.h
@@ -134,6 +140,8 @@ set(SRC
BLI_ghash.h
BLI_graph.h
BLI_gsqueue.h
+ BLI_hash_md5.h
+ BLI_hash_mm2a.h
BLI_heap.h
BLI_jitter.h
BLI_kdopbvh.h
@@ -153,12 +161,12 @@ set(SRC
BLI_math_matrix.h
BLI_math_rotation.h
BLI_math_vector.h
- BLI_md5.h
BLI_memarena.h
BLI_mempool.h
BLI_noise.h
BLI_path_util.h
BLI_polyfill2d.h
+ BLI_polyfill2d_beautify.h
BLI_quadric.h
BLI_rand.h
BLI_rect.h
@@ -187,13 +195,6 @@ set(SRC
PIL_time_utildefines.h
)
-if(WITH_BINRELOC)
- list(APPEND INC_SYS
- ${BINRELOC_INCLUDE_DIRS}
- )
- add_definitions(-DWITH_BINRELOC)
-endif()
-
if(WITH_MEM_VALGRIND)
add_definitions(-DWITH_MEM_VALGRIND)
endif()
diff --git a/source/blender/blenlib/PIL_time.h b/source/blender/blenlib/PIL_time.h
index 158559fa3d9..6e347339980 100644
--- a/source/blender/blenlib/PIL_time.h
+++ b/source/blender/blenlib/PIL_time.h
@@ -37,7 +37,7 @@
extern "C" {
#endif
-extern
+extern
/** Return an indication of time, expressed as
* seconds since some fixed point. Successive calls
* are guaranteed to generate values greater than or
@@ -45,6 +45,12 @@ extern
*/
double PIL_check_seconds_timer(void);
+extern
+/**
+ * int version of #PIL_check_seconds_timer
+ */
+long int PIL_check_seconds_timer_i(void);
+
/**
* Platform-independent sleep function.
* \param ms Number of milliseconds to sleep
diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript
index b712d2032bf..8b4054e00b5 100644
--- a/source/blender/blenlib/SConscript
+++ b/source/blender/blenlib/SConscript
@@ -34,8 +34,8 @@ cflags=''
incs = [
'.',
'#/extern/wcwidth',
- '#/intern/ghost',
'#/intern/guardedalloc',
+ '#/intern/atomic',
'../makesdna',
env['BF_FREETYPE_INC'],
env['BF_ZLIB_INC'],
@@ -44,10 +44,6 @@ incs = ' '.join(incs)
defs = []
-if env['WITH_BF_BINRELOC']:
- incs += ' ../../../extern/binreloc/include'
- defs.append('WITH_BINRELOC')
-
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
incs += ' ../../../intern/utfconv'
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
index 49a3c466727..9faf6c93447 100644
--- a/source/blender/blenlib/intern/BLI_args.c
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -100,7 +100,7 @@ static bool keycmp(const void *a, const void *b)
return (BLI_strcasecmp(ka->arg, kb->arg) != 0);
}
else {
- return (strcmp(ka->arg, kb->arg) != 0);
+ return (!STREQ(ka->arg, kb->arg));
}
}
else {
diff --git a/source/blender/blenlib/intern/BLI_array.c b/source/blender/blenlib/intern/BLI_array.c
index da2eef8ab6a..01550ad1008 100644
--- a/source/blender/blenlib/intern/BLI_array.c
+++ b/source/blender/blenlib/intern/BLI_array.c
@@ -43,6 +43,7 @@
*
* little array macro library. example of usage:
*
+ * \code{.c}
* int *arr = NULL;
* BLI_array_declare(arr);
* int i;
@@ -52,6 +53,7 @@
* arr[i] = something;
* }
* BLI_array_free(arr);
+ * \endcode
*
* arrays are buffered, using double-buffering (so on each reallocation,
* the array size is doubled). supposedly this should give good Big Oh
@@ -59,13 +61,10 @@
*/
#include <string.h>
-#include <stdlib.h>
#include "BLI_array.h"
#include "BLI_sys_types.h"
-#include "BLI_utildefines.h"
-#include "BLI_alloca.h"
#include "MEM_guardedalloc.h"
@@ -100,55 +99,3 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
arr_count += num;
#endif
}
-
-void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride)
-{
- const unsigned int arr_half_stride = (arr_len / 2) * arr_stride;
- unsigned int i, i_end;
- char *arr = arr_v;
- char *buf = BLI_array_alloca(buf, arr_stride);
-
- for (i = 0, i_end = (arr_len - 1) * arr_stride;
- i < arr_half_stride;
- i += arr_stride, i_end -= arr_stride)
- {
- memcpy(buf, &arr[i], arr_stride);
- memcpy(&arr[i], &arr[i_end], arr_stride);
- memcpy(&arr[i_end], buf, arr_stride);
- }
-}
-
-void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int dir)
-{
- char *arr = arr_v;
- char *buf = BLI_array_alloca(buf, arr_stride);
-
- if (dir == -1) {
- memcpy(buf, arr, arr_stride);
- memmove(arr, arr + arr_stride, arr_stride * (arr_len - 1));
- memcpy(arr + (arr_stride * (arr_len - 1)), buf, arr_stride);
- }
- else if (dir == 1) {
- memcpy(buf, arr + (arr_stride * (arr_len - 1)), arr_stride);
- memmove(arr + arr_stride, arr, arr_stride * (arr_len - 1));
- memcpy(arr, buf, arr_stride);
- }
- else {
- BLI_assert(0);
- }
-}
-
-/**
- * \note Not efficient, use for error checks/asserts.
- */
-int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p)
-{
- const char *arr_step = (const char *)arr;
- unsigned int i;
- for (i = 0; i < arr_len; i++, arr_step += arr_stride) {
- if (memcmp(arr_step, p, arr_stride) == 0) {
- return (int)i;
- }
- }
- return -1;
-}
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 6747e5c4e7e..5360ea744a1 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -28,7 +28,8 @@
/** \file blender/blenlib/intern/BLI_ghash.c
* \ingroup bli
*
- * A general (pointer -> pointer) hash table ADT
+ * A general (pointer -> pointer) chaining hash table
+ * for 'Abstract Data Types' (known as an ADT Hash Table).
*
* \note edgehash.c is based on this, make sure they stay in sync.
*/
@@ -770,7 +771,7 @@ unsigned int BLI_ghashutil_strhash_p(const void *ptr)
}
bool BLI_ghashutil_strcmp(const void *a, const void *b)
{
- return (strcmp(a, b) != 0);
+ return (!STREQ(a, b));
}
GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second)
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index 55dee4e8677..66dfa87b7b9 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -49,7 +49,6 @@ struct Heap {
unsigned int bufsize;
MemArena *arena;
HeapNode *freenodes;
- HeapNode *nodes;
HeapNode **tree;
};
@@ -139,9 +138,9 @@ Heap *BLI_heap_new(void)
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp)
{
- unsigned int i;
-
if (ptrfreefp) {
+ unsigned int i;
+
for (i = 0; i < heap->size; i++) {
ptrfreefp(heap->tree[i]->ptr);
}
@@ -152,6 +151,21 @@ void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp)
MEM_freeN(heap);
}
+void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp)
+{
+ if (ptrfreefp) {
+ unsigned int i;
+
+ for (i = 0; i < heap->size; i++) {
+ ptrfreefp(heap->tree[i]->ptr);
+ }
+ }
+
+ heap->size = 0;
+ BLI_memarena_clear(heap->arena);
+ heap->freenodes = NULL;
+}
+
HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr)
{
HeapNode *node;
@@ -163,7 +177,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr)
if (heap->freenodes) {
node = heap->freenodes;
- heap->freenodes = (HeapNode *)(((HeapNode *)heap->freenodes)->ptr);
+ heap->freenodes = heap->freenodes->ptr;
}
else {
node = (HeapNode *)BLI_memarena_alloc(heap->arena, sizeof(*node));
@@ -206,13 +220,8 @@ void *BLI_heap_popmin(Heap *heap)
heap->tree[0]->ptr = heap->freenodes;
heap->freenodes = heap->tree[0];
- if (UNLIKELY(heap->size == 1)) {
- heap->size--;
- }
- else {
- heap_swap(heap, 0, heap->size - 1);
- heap->size--;
-
+ if (--heap->size) {
+ heap_swap(heap, 0, heap->size);
heap_down(heap, 0);
}
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index d28215ee8ed..e4504bcaab1 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -986,7 +986,7 @@ bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const
/* check if index exists */
if (index > tree->totleaf)
- return 0;
+ return false;
node = tree->nodearray + index;
@@ -1001,7 +1001,7 @@ bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const
node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */
}
- return 1;
+ return true;
}
/* call BLI_bvhtree_update_node() first for every node/point/triangle */
@@ -1468,6 +1468,42 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
}
}
+static void dfs_raycast_all(BVHRayCastData *data, BVHNode *node)
+{
+ int i;
+
+ /* ray-bv is really fast.. and simple tests revealed its worth to test it
+ * before calling the ray-primitive functions */
+ /* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
+ float dist = (data->ray.radius == 0.0f) ? fast_ray_nearest_hit(data, node) : ray_nearest_hit(data, node->bv);
+
+ if (node->totnode == 0) {
+ if (data->callback) {
+ data->hit.index = -1;
+ data->hit.dist = FLT_MAX;
+ data->callback(data->userdata, node->index, &data->ray, &data->hit);
+ }
+ else {
+ data->hit.index = node->index;
+ data->hit.dist = dist;
+ madd_v3_v3v3fl(data->hit.co, data->ray.origin, data->ray.direction, dist);
+ }
+ }
+ else {
+ /* pick loop direction to dive into the tree (based on ray direction and split axis) */
+ if (data->ray_dot_axis[node->main_axis] > 0.0f) {
+ for (i = 0; i != node->totnode; i++) {
+ dfs_raycast_all(data, node->children[i]);
+ }
+ }
+ else {
+ for (i = node->totnode - 1; i >= 0; i--) {
+ dfs_raycast_all(data, node->children[i]);
+ }
+ }
+ }
+}
+
#if 0
static void iterative_raycast(BVHRayCastData *data, BVHNode *node)
{
@@ -1573,6 +1609,48 @@ float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], cons
}
+int BLI_bvhtree_ray_cast_all(BVHTree *tree, const float co[3], const float dir[3], float radius,
+ BVHTree_RayCastCallback callback, void *userdata)
+{
+ int i;
+ BVHRayCastData data;
+ BVHNode *root = tree->nodes[tree->totleaf];
+
+ data.tree = tree;
+
+ data.callback = callback;
+ data.userdata = userdata;
+
+ copy_v3_v3(data.ray.origin, co);
+ copy_v3_v3(data.ray.direction, dir);
+ data.ray.radius = radius;
+
+ normalize_v3(data.ray.direction);
+
+ for (i = 0; i < 3; i++) {
+ data.ray_dot_axis[i] = dot_v3v3(data.ray.direction, KDOP_AXES[i]);
+ data.idot_axis[i] = 1.0f / data.ray_dot_axis[i];
+
+ if (fabsf(data.ray_dot_axis[i]) < FLT_EPSILON) {
+ data.ray_dot_axis[i] = 0.0;
+ }
+ data.index[2 * i] = data.idot_axis[i] < 0.0f ? 1 : 0;
+ data.index[2 * i + 1] = 1 - data.index[2 * i];
+ data.index[2 * i] += 2 * i;
+ data.index[2 * i + 1] += 2 * i;
+ }
+
+
+ data.hit.index = -1;
+ data.hit.dist = FLT_MAX;
+
+ if (root) {
+ dfs_raycast_all(&data, root);
+ }
+
+ return data.hit.index;
+}
+
/**
* Range Query - as request by broken :P
*
diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c
index a0b61e7945c..391f3ef7702 100644
--- a/source/blender/blenlib/intern/BLI_linklist.c
+++ b/source/blender/blenlib/intern/BLI_linklist.c
@@ -32,6 +32,8 @@
#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
#include "BLI_linklist.h"
#include "BLI_memarena.h"
#include "BLI_mempool.h"
@@ -85,6 +87,77 @@ void BLI_linklist_reverse(LinkNode **listp)
}
/**
+ * Move an item from its current position to a new one inside a single-linked list.
+ * Note *listp may be modified.
+ */
+void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index)
+{
+ LinkNode *lnk, *lnk_psrc = NULL, *lnk_pdst = NULL;
+ int i;
+
+ if (new_index == curr_index) {
+ return;
+ }
+
+ if (new_index < curr_index) {
+ for (lnk = *listp, i = 0; lnk; lnk = lnk->next, i++) {
+ if (i == new_index - 1) {
+ lnk_pdst = lnk;
+ }
+ else if (i == curr_index - 1) {
+ lnk_psrc = lnk;
+ break;
+ }
+ }
+
+ if (!(lnk_psrc && lnk_psrc->next && (!lnk_pdst || lnk_pdst->next))) {
+ /* Invalid indices, abort. */
+ return;
+ }
+
+ lnk = lnk_psrc->next;
+ lnk_psrc->next = lnk->next;
+ if (lnk_pdst) {
+ lnk->next = lnk_pdst->next;
+ lnk_pdst->next = lnk;
+ }
+ else {
+ /* destination is first element of the list... */
+ lnk->next = *listp;
+ *listp = lnk;
+ }
+ }
+ else {
+ for (lnk = *listp, i = 0; lnk; lnk = lnk->next, i++) {
+ if (i == new_index) {
+ lnk_pdst = lnk;
+ break;
+ }
+ else if (i == curr_index - 1) {
+ lnk_psrc = lnk;
+ }
+ }
+
+ if (!(lnk_pdst && (!lnk_psrc || lnk_psrc->next))) {
+ /* Invalid indices, abort. */
+ return;
+ }
+
+ if (lnk_psrc) {
+ lnk = lnk_psrc->next;
+ lnk_psrc->next = lnk->next;
+ }
+ else {
+ /* source is first element of the list... */
+ lnk = *listp;
+ *listp = lnk->next;
+ }
+ lnk->next = lnk_pdst->next;
+ lnk_pdst->next = lnk;
+ }
+}
+
+/**
* A version of prepend that takes the allocated link.
*/
void BLI_linklist_prepend_nlink(LinkNode **listp, void *ptr, LinkNode *nlink)
@@ -96,7 +169,7 @@ void BLI_linklist_prepend_nlink(LinkNode **listp, void *ptr, LinkNode *nlink)
void BLI_linklist_prepend(LinkNode **listp, void *ptr)
{
- LinkNode *nlink = MEM_mallocN(sizeof(*nlink), "nlink");
+ LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
BLI_linklist_prepend_nlink(listp, ptr, nlink);
}
@@ -135,7 +208,7 @@ void BLI_linklist_append_nlink(LinkNode **listp, void *ptr, LinkNode *nlink)
void BLI_linklist_append(LinkNode **listp, void *ptr)
{
- LinkNode *nlink = MEM_mallocN(sizeof(*nlink), "nlink");
+ LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
BLI_linklist_append_nlink(listp, ptr, nlink);
}
@@ -177,7 +250,7 @@ void *BLI_linklist_pop_pool(struct LinkNode **listp, struct BLI_mempool *mempool
void BLI_linklist_insert_after(LinkNode **listp, void *ptr)
{
- LinkNode *nlink = MEM_mallocN(sizeof(*nlink), "nlink");
+ LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
LinkNode *node = *listp;
nlink->link = ptr;
diff --git a/source/blender/blenlib/intern/array_utils.c b/source/blender/blenlib/intern/array_utils.c
new file mode 100644
index 00000000000..173effbc434
--- /dev/null
+++ b/source/blender/blenlib/intern/array_utils.c
@@ -0,0 +1,85 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenlib/intern/array_utils.c
+ * \ingroup bli
+ * \brief Generic array manipulation API.
+ */
+#include <string.h>
+#include <stdlib.h>
+
+#include "BLI_array_utils.h"
+
+#include "BLI_sys_types.h"
+#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
+
+
+void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride)
+{
+ const unsigned int arr_half_stride = (arr_len / 2) * arr_stride;
+ unsigned int i, i_end;
+ char *arr = arr_v;
+ char *buf = BLI_array_alloca(buf, arr_stride);
+
+ for (i = 0, i_end = (arr_len - 1) * arr_stride;
+ i < arr_half_stride;
+ i += arr_stride, i_end -= arr_stride)
+ {
+ memcpy(buf, &arr[i], arr_stride);
+ memcpy(&arr[i], &arr[i_end], arr_stride);
+ memcpy(&arr[i_end], buf, arr_stride);
+ }
+}
+
+void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int dir)
+{
+ char *arr = arr_v;
+ char *buf = BLI_array_alloca(buf, arr_stride);
+
+ if (dir == -1) {
+ memcpy(buf, arr, arr_stride);
+ memmove(arr, arr + arr_stride, arr_stride * (arr_len - 1));
+ memcpy(arr + (arr_stride * (arr_len - 1)), buf, arr_stride);
+ }
+ else if (dir == 1) {
+ memcpy(buf, arr + (arr_stride * (arr_len - 1)), arr_stride);
+ memmove(arr + arr_stride, arr, arr_stride * (arr_len - 1));
+ memcpy(arr, buf, arr_stride);
+ }
+ else {
+ BLI_assert(0);
+ }
+}
+
+/**
+ * \note Not efficient, use for error checks/asserts.
+ */
+int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p)
+{
+ const char *arr_step = (const char *)arr;
+ unsigned int i;
+ for (i = 0; i < arr_len; i++, arr_step += arr_stride) {
+ if (memcmp(arr_step, p, arr_stride) == 0) {
+ return (int)i;
+ }
+ }
+ return -1;
+}
diff --git a/source/blender/blenlib/intern/astar.c b/source/blender/blenlib/intern/astar.c
new file mode 100644
index 00000000000..b7b41d2497e
--- /dev/null
+++ b/source/blender/blenlib/intern/astar.c
@@ -0,0 +1,294 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Bastien Montagne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenlib/intern/astar.c
+ * \ingroup bli
+ * \brief An implementation of the A* (AStar) algorithm to solve shortest path problem.
+ *
+ * This library implements the simple A* (AStar) algorithm, an optimized version of
+ * classical dijkstra shortest path solver. The difference is that each future possible
+ * path is weighted from its 'shortest' (smallest) possible distance to destination,
+ * in addition to distance already walked. This heuristic allows more efficiency
+ * in finding optimal path.
+ *
+ * Implementation based on Wikipedia A* page [http://en.wikipedia.org/wiki/A*_search_algorithm].
+ *
+ * Note that most memory handling here is done through two different MemArena's. Those should also be used to allocate
+ * custom data needed to a specific use of A*.
+ * The first one, owned by BLI_AStarGraph, is for 'static' data that will live as long as the graph.
+ * The second one, owned by BLI_AStarSolution, is for data used during a single path solve. It will be cleared
+ * much more often than graph's one.
+ */
+
+#include <limits.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_sys_types.h"
+#include "BLI_compiler_attrs.h"
+
+#include "BLI_alloca.h"
+#include "BLI_heap.h"
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_memarena.h"
+
+#include "BLI_astar.h"
+
+/**
+ * Init a node in A* graph.
+ *
+ * \param custom_data an opaque pointer attached to this link, available e.g. to cost callback function.
+ */
+void BLI_astar_node_init(BLI_AStarGraph *as_graph, const int node_index, void *custom_data)
+{
+ as_graph->nodes[node_index].custom_data = custom_data;
+}
+
+/**
+ * Add a link between two nodes of our A* graph.
+ *
+ * \param cost the 'length' of the link (actual distance between two vertices or face centers e.g.).
+ * \param custom_data an opaque pointer attached to this link, available e.g. to cost callback function.
+ */
+void BLI_astar_node_link_add(
+ BLI_AStarGraph *as_graph, const int node1_index, const int node2_index, const float cost, void *custom_data)
+{
+ MemArena *mem = as_graph->mem;
+ BLI_AStarGNLink *link = BLI_memarena_alloc(mem, sizeof(*link));
+ LinkData *ld = BLI_memarena_alloc(mem, sizeof(*ld) * 2);
+
+ link->nodes[0] = node1_index;
+ link->nodes[1] = node2_index;
+ link->cost = cost;
+ link->custom_data = custom_data;
+
+ ld[0].data = ld[1].data = link;
+
+ BLI_addtail(&(as_graph->nodes[node1_index].neighbor_links), &ld[0]);
+ BLI_addtail(&(as_graph->nodes[node2_index].neighbor_links), &ld[1]);
+}
+
+/**
+ * \return The index of the other node of given link.
+ */
+int BLI_astar_node_link_other_node(BLI_AStarGNLink *lnk, const int idx)
+{
+ return (lnk->nodes[0] == idx) ? lnk->nodes[1] : lnk->nodes[0];
+}
+
+/**
+ * Initialize a solution data for given A* graph. Does not compute anything!
+ *
+ * \param custom_data an opaque pointer attached to this link, available e.g. to cost callback function.
+ *
+ * \note BLI_AStarSolution stores nearly all data needed during solution compute.
+ */
+void BLI_astar_solution_init(BLI_AStarGraph *as_graph, BLI_AStarSolution *as_solution, void *custom_data)
+{
+ MemArena *mem = as_solution->mem;
+ size_t node_num = (size_t)as_graph->node_num;
+
+ if (mem == NULL) {
+ mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ as_solution->mem = mem;
+ }
+ /* else memarena should be cleared */
+
+ as_solution->steps = 0;
+ as_solution->prev_nodes = BLI_memarena_alloc(mem, sizeof(*as_solution->prev_nodes) * node_num);
+ as_solution->prev_links = BLI_memarena_alloc(mem, sizeof(*as_solution->prev_links) * node_num);
+
+ as_solution->custom_data = custom_data;
+
+ as_solution->done_nodes = BLI_BITMAP_NEW_MEMARENA(mem, node_num);
+ as_solution->g_costs = BLI_memarena_alloc(mem, sizeof(*as_solution->g_costs) * node_num);
+ as_solution->g_steps = BLI_memarena_alloc(mem, sizeof(*as_solution->g_steps) * node_num);
+}
+
+/**
+ * Clear given solution's data, but does not release its memory. Avoids having to recreate/allocate
+ * a memarena in loops, e.g.
+ *
+ * \note This *has to be called* between each path solving.
+ */
+void BLI_astar_solution_clear(BLI_AStarSolution *as_solution)
+{
+ if (as_solution->mem) {
+ BLI_memarena_clear(as_solution->mem);
+ }
+
+ as_solution->steps = 0;
+ as_solution->prev_nodes = NULL;
+ as_solution->prev_links = NULL;
+
+ as_solution->custom_data = NULL;
+
+ as_solution->done_nodes = NULL;
+ as_solution->g_costs = NULL;
+ as_solution->g_steps = NULL;
+}
+
+/**
+ * Release the memory allocated for this solution.
+ */
+void BLI_astar_solution_free(BLI_AStarSolution *as_solution)
+{
+ if (as_solution->mem) {
+ BLI_memarena_free(as_solution->mem);
+ as_solution->mem = NULL;
+ }
+}
+
+/**
+ * Callback computing the current cost (distance) to next node, and the estimated overall cost to destination node
+ * (A* expects this estimation to always be less or equal than actual shortest path from next node to destination one).
+ *
+ * \param link the graph link between current node and next one.
+ * \param node_idx_curr current node index.
+ * \param node_idx_next next node index.
+ * \param node_idx_dst destination node index.
+ */
+typedef float (*astar_f_cost)(BLI_AStarGraph *as_graph, BLI_AStarSolution *as_solution, BLI_AStarGNLink *link,
+ const int node_idx_curr, const int node_idx_next, const int node_idx_dst);
+
+/**
+ * Init an A* graph. Total number of nodes must be known.
+ *
+ * Nodes might be e.g. vertices, faces, ...
+ *
+ * \param custom_data an opaque pointer attached to this link, available e.g. to cost callback function.
+ */
+void BLI_astar_graph_init(BLI_AStarGraph *as_graph, const int node_num, void *custom_data)
+{
+ MemArena *mem = as_graph->mem;
+
+ if (mem == NULL) {
+ mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ as_graph->mem = mem;
+ }
+ /* else memarena should be cleared */
+
+ as_graph->node_num = node_num;
+ as_graph->nodes = BLI_memarena_calloc(mem, sizeof(*as_graph->nodes) * (size_t)node_num);
+
+ as_graph->custom_data = custom_data;
+}
+
+void BLI_astar_graph_free(BLI_AStarGraph *as_graph)
+{
+ if (as_graph->mem) {
+ BLI_memarena_free(as_graph->mem);
+ as_graph->mem = NULL;
+ }
+}
+
+/**
+ * Solve a path in given graph, using given 'cost' callback function.
+ *
+ * \param max_steps maximum number of nodes the found path may have. Useful in performance-critical usages.
+ * If no path is found within given steps, returns false too.
+ * \return true if a path was found, false otherwise.
+ */
+bool BLI_astar_graph_solve(
+ BLI_AStarGraph *as_graph, const int node_index_src, const int node_index_dst, astar_f_cost f_cost_cb,
+ BLI_AStarSolution *r_solution, const int max_steps)
+{
+ Heap *todo_nodes;
+
+ BLI_bitmap *done_nodes = r_solution->done_nodes;
+ int *prev_nodes = r_solution->prev_nodes;
+ BLI_AStarGNLink **prev_links = r_solution->prev_links;
+ float *g_costs = r_solution->g_costs;
+ int *g_steps = r_solution->g_steps;
+
+ r_solution->steps = 0;
+ prev_nodes[node_index_src] = -1;
+ BLI_BITMAP_SET_ALL(done_nodes, false, as_graph->node_num);
+ fill_vn_fl(g_costs, as_graph->node_num, FLT_MAX);
+ g_costs[node_index_src] = 0.0f;
+ g_steps[node_index_src] = 0;
+
+ if (node_index_src == node_index_dst) {
+ return true;
+ }
+
+ todo_nodes = BLI_heap_new();
+ BLI_heap_insert(todo_nodes,
+ f_cost_cb(as_graph, r_solution, NULL, -1, node_index_src, node_index_dst),
+ SET_INT_IN_POINTER(node_index_src));
+
+ while (!BLI_heap_is_empty(todo_nodes)) {
+ const int node_curr_idx = GET_INT_FROM_POINTER(BLI_heap_popmin(todo_nodes));
+ BLI_AStarGNode *node_curr = &as_graph->nodes[node_curr_idx];
+ LinkData *ld;
+
+ if (BLI_BITMAP_TEST(done_nodes, node_curr_idx)) {
+ /* Might happen, because we always add nodes to heap when evaluating them, without ever removing them. */
+ continue;
+ }
+
+ /* If we are limited in amount of steps to find a path, skip if we reached limit. */
+ if (max_steps && g_steps[node_curr_idx] > max_steps) {
+ continue;
+ }
+
+ if (node_curr_idx == node_index_dst) {
+ /* Success! Path found... */
+ r_solution->steps = g_steps[node_curr_idx] + 1;
+
+ BLI_heap_free(todo_nodes, NULL);
+ return true;
+ }
+
+ BLI_BITMAP_ENABLE(done_nodes, node_curr_idx);
+
+ for (ld = node_curr->neighbor_links.first; ld; ld = ld->next) {
+ BLI_AStarGNLink *link = ld->data;
+ const int node_next_idx = BLI_astar_node_link_other_node(link, node_curr_idx);
+
+ if (!BLI_BITMAP_TEST(done_nodes, node_next_idx)) {
+ float g_cst = g_costs[node_curr_idx] + link->cost;
+
+ if (g_cst < g_costs[node_next_idx]) {
+ prev_nodes[node_next_idx] = node_curr_idx;
+ prev_links[node_next_idx] = link;
+ g_costs[node_next_idx] = g_cst;
+ g_steps[node_next_idx] = g_steps[node_curr_idx] + 1;
+ /* We might have this node already in heap, but since this 'instance' will be evaluated first,
+ * no problem. */
+ BLI_heap_insert(todo_nodes,
+ f_cost_cb(as_graph, r_solution, link, node_curr_idx, node_next_idx, node_index_dst),
+ SET_INT_IN_POINTER(node_next_idx));
+ }
+ }
+ }
+ }
+
+ BLI_heap_free(todo_nodes, NULL);
+ return false;
+}
diff --git a/source/blender/blenlib/intern/boxpack2d.c b/source/blender/blenlib/intern/boxpack2d.c
index 91495ce3c9c..2db52cbda60 100644
--- a/source/blender/blenlib/intern/boxpack2d.c
+++ b/source/blender/blenlib/intern/boxpack2d.c
@@ -32,6 +32,9 @@
#include "BLI_utildefines.h"
#include "BLI_boxpack2d.h" /* own include */
+#include "BLI_sort.h" /* qsort_r */
+#define qsort_r BLI_qsort_r
+
#include "BLI_strict_flags.h"
#ifdef __GNUC__
@@ -226,18 +229,20 @@ static int box_areasort(const void *p1, const void *p2)
* sorts from lower left to top right It uses the current box's width and height
* as offsets when sorting, this has the result of not placing boxes outside
* the bounds of the existing backed area where possible
- * */
-static float box_width;
-static float box_height;
-static BoxVert *vertarray;
+ */
+struct VertSortContext {
+ BoxVert *vertarray;
+ float box_width, box_height;
+};
-static int vertex_sort(const void *p1, const void *p2)
+static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p)
{
- BoxVert *v1, *v2;
+ const struct VertSortContext *vs_ctx = vs_ctx_p;
+ const BoxVert *v1, *v2;
float a1, a2;
- v1 = vertarray + ((int *)p1)[0];
- v2 = vertarray + ((int *)p2)[0];
+ v1 = &vs_ctx->vertarray[*((const unsigned int *)p1)];
+ v2 = &vs_ctx->vertarray[*((const unsigned int *)p2)];
#ifdef USE_FREE_STRIP
/* push free verts to the end so we can strip */
@@ -246,8 +251,8 @@ static int vertex_sort(const void *p1, const void *p2)
else if (UNLIKELY(v2->free == 0)) return -1;
#endif
- a1 = max_ff(v1->x + box_width, v1->y + box_height);
- a2 = max_ff(v2->x + box_width, v2->y + box_height);
+ a1 = max_ff(v1->x + vs_ctx->box_width, v1->y + vs_ctx->box_height);
+ a2 = max_ff(v2->x + vs_ctx->box_width, v2->y + vs_ctx->box_height);
#ifdef USE_PACK_BIAS
a1 += v1->bias;
@@ -285,6 +290,8 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *r_tot_x,
BoxPack *box, *box_test; /*current box and another for intersection tests*/
BoxVert *vert; /* the current vert */
+ struct VertSortContext vs_ctx;
+
if (!len) {
*r_tot_x = tot_x;
*r_tot_y = tot_y;
@@ -295,9 +302,11 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *r_tot_x,
qsort(boxarray, (size_t)len, sizeof(BoxPack), box_areasort);
/* add verts to the boxes, these are only used internally */
- vert = vertarray = MEM_mallocN((size_t)len * 4 * sizeof(BoxVert), "BoxPack Verts");
+ vert = MEM_mallocN((size_t)len * 4 * sizeof(BoxVert), "BoxPack Verts");
vertex_pack_indices = MEM_mallocN((size_t)len * 3 * sizeof(int), "BoxPack Indices");
+ vs_ctx.vertarray = vert;
+
for (box = boxarray, box_index = 0, i = 0; box_index < len; box_index++, box++) {
vert->blb = vert->brb = vert->tlb =
@@ -371,16 +380,16 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *r_tot_x,
/* Main boxpacking loop */
for (box_index = 1; box_index < len; box_index++, box++) {
- /* These static floatds are used for sorting */
- box_width = box->w;
- box_height = box->h;
+ /* These floats are used for sorting re-sorting */
+ vs_ctx.box_width = box->w;
+ vs_ctx.box_height = box->h;
- qsort(vertex_pack_indices, (size_t)verts_pack_len, sizeof(int), vertex_sort);
+ qsort_r(vertex_pack_indices, (size_t)verts_pack_len, sizeof(int), vertex_sort, &vs_ctx);
#ifdef USE_FREE_STRIP
/* strip free vertices */
i = verts_pack_len - 1;
- while ((i != 0) && vertarray[vertex_pack_indices[i]].free == 0) {
+ while ((i != 0) && vs_ctx.vertarray[vertex_pack_indices[i]].free == 0) {
i--;
}
verts_pack_len = i + 1;
@@ -391,7 +400,7 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *r_tot_x,
isect = true;
for (i = 0; i < verts_pack_len && isect; i++) {
- vert = vertarray + vertex_pack_indices[i];
+ vert = &vs_ctx.vertarray[vertex_pack_indices[i]];
/* printf("\ttesting vert %i %i %i %f %f\n", i,
* vert->free, verts_pack_len, vert->x, vert->y); */
@@ -661,5 +670,5 @@ void BLI_box_pack_2d(BoxPack *boxarray, const unsigned int len, float *r_tot_x,
box->v[0] = box->v[1] = box->v[2] = box->v[3] = NULL;
}
MEM_freeN(vertex_pack_indices);
- MEM_freeN(vertarray);
+ MEM_freeN(vs_ctx.vertarray);
}
diff --git a/source/blender/blenlib/intern/convexhull2d.c b/source/blender/blenlib/intern/convexhull2d.c
index 361e4b4eadb..5f64088f433 100644
--- a/source/blender/blenlib/intern/convexhull2d.c
+++ b/source/blender/blenlib/intern/convexhull2d.c
@@ -187,8 +187,8 @@ static int pointref_cmp_yx(const void *a_, const void *b_)
* \param points An array of 2D points.
* \param n The number of points in points.
* \param r_points An array of the convex hull vertex indices (max is n).
- * _must_ be allocated as ``n * 2`` because of how its used internally,
- * even though the final result will be no more then \a n in size.
+ * _must_ be allocated as ``n * 2`` because of how its used internally,
+ * even though the final result will be no more than \a n in size.
* \returns the number of points in r_points.
*/
int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[])
diff --git a/source/blender/blenlib/intern/dynlib.c b/source/blender/blenlib/intern/dynlib.c
index b66eda4f141..e916b01e859 100644
--- a/source/blender/blenlib/intern/dynlib.c
+++ b/source/blender/blenlib/intern/dynlib.c
@@ -43,6 +43,8 @@ struct DynamicLibrary {
#ifdef WIN32
+#define _WIN32_WINNT 0x501 /* Windows XP or newer */
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "utf_winfunc.h"
#include "utfconv.h"
diff --git a/source/blender/blenlib/intern/easing.c b/source/blender/blenlib/intern/easing.c
index 80f02d54eaa..90c8528338e 100644
--- a/source/blender/blenlib/intern/easing.c
+++ b/source/blender/blenlib/intern/easing.c
@@ -139,7 +139,7 @@ float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float
#ifdef USE_ELASTIC_BLEND
/**
- * When the amplitude is less then the change, we need to blend
+ * When the amplitude is less than the change, we need to blend
* \a f when we're close to the crossing point (int time), else we get an ugly sharp falloff.
*/
static float elastic_blend(float time, float change, float duration, float amplitude, float s, float f)
diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c
index 4ed82f8a473..82d57dad753 100644
--- a/source/blender/blenlib/intern/edgehash.c
+++ b/source/blender/blenlib/intern/edgehash.c
@@ -23,12 +23,13 @@
/** \file blender/blenlib/intern/edgehash.c
* \ingroup bli
*
- * A general (pointer -> pointer) hash table ADT
+ * An (edge -> pointer) chaining hash table.
+ * Using unordered int-pairs as keys.
*
- * \note Based on 'BLI_ghash.c', make sure these stay in sync.
+ * \note Based on 'BLI_ghash.c', which is a more generalized hash-table
+ * make sure these stay in sync.
*/
-
#include <stdlib.h>
#include <string.h>
#include <limits.h>
@@ -146,7 +147,7 @@ BLI_INLINE void edgehash_buckets_reserve(EdgeHash *eh, const unsigned int nentri
/**
* Internal lookup function.
- * Takes a hash argument to avoid calling #ghash_keyhash multiple times.
+ * Takes a hash argument to avoid calling #edgehash_keyhash multiple times.
*/
BLI_INLINE EdgeEntry *edgehash_lookup_entry_ex(EdgeHash *eh, unsigned int v0, unsigned int v1,
const unsigned int hash)
@@ -256,6 +257,35 @@ BLI_INLINE void edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1,
}
/**
+ * Remove the entry and return it, caller must free from eh->epool.
+ */
+static EdgeEntry *edgehash_remove_ex(EdgeHash *eh, unsigned int v0, unsigned int v1, EdgeHashFreeFP valfreefp,
+ unsigned int hash)
+{
+ EdgeEntry *e;
+ EdgeEntry *e_prev = NULL;
+
+ BLI_assert(v0 < v1);
+
+ for (e = eh->buckets[hash]; e; e = e->next) {
+ if (UNLIKELY(v0 == e->v0 && v1 == e->v1)) {
+ EdgeEntry *e_next = e->next;
+
+ if (valfreefp) valfreefp(e->val);
+
+ if (e_prev) e_prev->next = e_next;
+ else eh->buckets[hash] = e_next;
+
+ eh->nentries--;
+ return e;
+ }
+ e_prev = e;
+ }
+
+ return NULL;
+}
+
+/**
* Run free callbacks for freeing entries.
*/
static void edgehash_free_cb(EdgeHash *eh, EdgeHashFreeFP valfreefp)
@@ -366,6 +396,57 @@ void *BLI_edgehash_lookup_default(EdgeHash *eh, unsigned int v0, unsigned int v1
}
/**
+ * Remove \a key from \a eh, or return false if the key wasn't found.
+ *
+ * \param key The key to remove.
+ * \param valfreefp Optional callback to free the value.
+ * \return true if \a key was removed from \a eh.
+ */
+bool BLI_edgehash_remove(EdgeHash *eh, unsigned int v0, unsigned int v1, EdgeHashFreeFP valfreefp)
+{
+ unsigned int hash;
+ EdgeEntry *e;
+
+ EDGE_ORD(v0, v1); /* ensure v0 is smaller */
+ hash = edgehash_keyhash(eh, v0, v1);
+ e = edgehash_remove_ex(eh, v0, v1, valfreefp, hash);
+ if (e) {
+ BLI_mempool_free(eh->epool, e);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+/* same as above but return the value,
+ * no free value argument since it will be returned */
+/**
+ * Remove \a key from \a eh, returning the value or NULL if the key wasn't found.
+ *
+ * \param key The key to remove.
+ * \return the value of \a key int \a eh or NULL.
+ */
+void *BLI_edgehash_popkey(EdgeHash *eh, unsigned int v0, unsigned int v1)
+{
+ unsigned int hash;
+ EdgeEntry *e;
+
+ EDGE_ORD(v0, v1); /* ensure v0 is smaller */
+ hash = edgehash_keyhash(eh, v0, v1);
+ e = edgehash_remove_ex(eh, v0, v1, NULL, hash);
+ IS_EDGEHASH_ASSERT(eh);
+ if (e) {
+ void *val = e->val;
+ BLI_mempool_free(eh->epool, e);
+ return val;
+ }
+ else {
+ return NULL;
+ }
+}
+
+/**
* Return boolean true/false if edge (v0,v1) in hash.
*/
bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1)
@@ -404,6 +485,14 @@ void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP valfreefp,
BLI_mempool_clear_ex(eh->epool, nentries_reserve ? (int)nentries_reserve : -1);
}
+/**
+ * Wraps #BLI_edgehash_clear_ex with zero entries reserved.
+ */
+void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp)
+{
+ BLI_edgehash_clear_ex(eh, valfreefp, 0);
+}
+
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp)
{
BLI_assert((int)eh->nentries == BLI_mempool_count(eh->epool));
@@ -440,7 +529,7 @@ void BLI_edgehash_flag_clear(EdgeHash *eh, unsigned int flag)
/**
* Create a new EdgeHashIterator. The hash table must not be mutated
* while the iterator is in use, and the iterator will step exactly
- * BLI_edgehash_size(gh) times before becoming done.
+ * BLI_edgehash_size(eh) times before becoming done.
*/
EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh)
{
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index f6bbd3273f9..d6fe5e52b95 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -311,12 +311,12 @@ static bool delete_recursive(const char *dir)
bool err = false;
unsigned int nbr, i;
- i = nbr = BLI_dir_contents(dir, &filelist);
+ i = nbr = BLI_filelist_dir_contents(dir, &filelist);
fl = filelist;
while (i--) {
char file[8];
BLI_split_file_part(fl->path, file, sizeof(file));
- if (STREQ(file, ".") || STREQ(file, "..")) {
+ if (FILENAME_IS_CURRPAR(file)) {
/* Skip! */
}
else if (S_ISDIR(fl->type)) {
@@ -336,7 +336,7 @@ static bool delete_recursive(const char *dir)
err = true;
}
- BLI_free_filelist(filelist, nbr);
+ BLI_filelist_free(filelist, nbr, NULL);
return err;
}
@@ -584,7 +584,7 @@ static int recursive_operation(const char *startfrom, const char *startto,
for (i = 0; i < n; i++) {
const struct dirent * const dirent = dirlist[i];
- if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
+ if (FILENAME_IS_CURRPAR(dirent->d_name))
continue;
join_dirfile_alloc(&from_path, &from_alloc_len, from, dirent->d_name);
@@ -896,7 +896,7 @@ int BLI_move(const char *file, const char *to)
}
#endif
-static char *check_destination(const char *file, const char *to)
+static const char *check_destination(const char *file, const char *to)
{
struct stat st;
@@ -927,18 +927,18 @@ static char *check_destination(const char *file, const char *to)
}
}
- return (char *)to;
+ return to;
}
int BLI_copy(const char *file, const char *to)
{
- char *actual_to = check_destination(file, to);
+ const char *actual_to = check_destination(file, to);
int ret;
ret = recursive_operation(file, actual_to, copy_callback_pre, copy_single_file, NULL);
if (actual_to != to)
- MEM_freeN(actual_to);
+ MEM_freeN((void *)actual_to);
return ret;
}
diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c
index d4d87dfdbf6..81cc9fde01f 100644
--- a/source/blender/blenlib/intern/graph.c
+++ b/source/blender/blenlib/intern/graph.c
@@ -170,11 +170,11 @@ bool BLI_hasAdjacencyList(BGraph *graph)
for (node = graph->nodes.first; node; node = node->next) {
if (node->arcs == NULL) {
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
void BLI_replaceNodeInArc(BGraph *graph, BArc *arc, BNode *node_src, BNode *node_replaced)
@@ -337,7 +337,7 @@ static bool detectCycle(BNode *node, BArc *src_arc)
}
}
else {
- value = 1;
+ value = true;
}
return value;
@@ -354,7 +354,7 @@ bool BLI_isGraphCyclic(BGraph *graph)
BLI_flagNodes(graph, 0);
/* detectCycles in subgraphs */
- for (node = graph->nodes.first; node && value == 0; node = node->next) {
+ for (node = graph->nodes.first; node && value == false; node = node->next) {
/* only for nodes in subgraphs that haven't been visited yet */
if (node->flag == 0) {
value = value || detectCycle(node, NULL);
diff --git a/source/blender/blenlib/intern/md5.c b/source/blender/blenlib/intern/hash_md5.c
index 3d1a9cdb7a4..4eec38278e9 100644
--- a/source/blender/blenlib/intern/md5.c
+++ b/source/blender/blenlib/intern/hash_md5.c
@@ -22,20 +22,20 @@
* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>.
*/
-/** \file blender/blenlib/intern/md5.c
+/** \file blender/blenlib/intern/hash_md5.c
* \ingroup bli
*
* Functions to compute MD5 message digest of files or memory blocks
* according to the definition of MD5 in RFC 1321 from April 1992.
*/
-#include "BLI_md5.h" /* own include */
-
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
+#include "BLI_hash_md5.h" /* own include */
+
#if defined HAVE_LIMITS_H || defined _LIBC
# include <limits.h>
#endif
@@ -77,7 +77,8 @@
#endif
-/* Following code is low level, upon which are built up the functions 'md5_stream' and 'md5_buffer'. */
+/* Following code is low level, upon which are built up the functions
+ * 'BLI_hash_md5_stream' and 'BLI_hash_md5_buffer'. */
/* Structure to save state of computation between the single steps. */
struct md5_ctx
@@ -284,7 +285,7 @@ static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf)
* The resulting message digest number will be written into the 16 bytes beginning at 'resblock'.
* \return Non-zero if an error occurred.
*/
-int md5_stream(FILE *stream, void *resblock)
+int BLI_hash_md5_stream(FILE *stream, void *resblock)
{
#define BLOCKSIZE 4096 /* Important: must be a multiple of 64. */
struct md5_ctx ctx;
@@ -356,7 +357,7 @@ int md5_stream(FILE *stream, void *resblock)
* The result is always in little endian byte order, so that a byte-wise output yields to the wanted
* ASCII representation of the message digest.
*/
-void *md5_buffer(const char *buffer, size_t len, void *resblock)
+void *BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock)
{
struct md5_ctx ctx;
char restbuf[64 + 72];
@@ -390,7 +391,7 @@ void *md5_buffer(const char *buffer, size_t len, void *resblock)
return md5_read_ctx(&ctx, resblock);
}
-char *md5_to_hexdigest(void *resblock, char r_hex_digest[33])
+char *BLI_hash_md5_to_hexdigest(void *resblock, char r_hex_digest[33])
{
static const char hex_map[17] = "0123456789abcdef";
const unsigned char *p;
diff --git a/source/blender/blenlib/intern/hash_mm2a.c b/source/blender/blenlib/intern/hash_mm2a.c
new file mode 100644
index 00000000000..bae098ae96b
--- /dev/null
+++ b/source/blender/blenlib/intern/hash_mm2a.c
@@ -0,0 +1,107 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Copyright (C) 2014 Blender Foundation.
+ *
+ */
+
+/** \file blender/blenlib/intern/hash_mm2a.c
+ * \ingroup bli
+ *
+ * Functions to compute Murmur2A hash key.
+ *
+ * A very fast hash generating int32 result, with few collisions and good repartition.
+ *
+ * See also:
+ * reference implementation: https://smhasher.googlecode.com/svn-history/r130/trunk/MurmurHash2.cpp
+ * and http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed
+ *
+ * \warning Do not store that hash in files or such, it is not endian-agnostic, so you should only use it
+ * for temporary data.
+ */
+
+#include "BLI_hash_mm2a.h" /* own include */
+
+/* Helpers. */
+#define MM2A_M 0x5bd1e995
+
+#define MM2A_MIX(h, k) \
+{ \
+ (k) *= MM2A_M; \
+ (k) ^= (k) >> 24; \
+ (k) *= MM2A_M; \
+ (h) = ((h) * MM2A_M) ^ (k); \
+} (void)0
+
+static void mm2a_mix_tail(BLI_HashMurmur2A *mm2, const unsigned char **data, size_t *len)
+{
+ while (*len && ((*len < 4) || mm2->count)) {
+ mm2->tail |= (uint32_t)(**data) << (mm2->count * 8);
+
+ mm2->count++;
+ (*len)--;
+ (*data)++;
+
+ if (mm2->count == 4) {
+ MM2A_MIX(mm2->hash, mm2->tail);
+ mm2->tail = 0;
+ mm2->count = 0;
+ }
+ }
+}
+
+void BLI_hash_mm2a_init(BLI_HashMurmur2A *mm2, uint32_t seed)
+{
+ mm2->hash = seed;
+ mm2->tail = 0;
+ mm2->count = 0;
+ mm2->size = 0;
+}
+
+void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t len)
+{
+ mm2->size += (uint32_t)len;
+
+ mm2a_mix_tail(mm2, &data, &len);
+
+ for (; len >= 4; data += 4, len -= 4) {
+ uint32_t k = *(const uint32_t *)data;
+
+ MM2A_MIX(mm2->hash, k);
+ }
+
+ mm2a_mix_tail(mm2, &data, &len);
+}
+
+void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data)
+{
+ BLI_hash_mm2a_add(mm2, (const unsigned char *)&data, sizeof(data));
+}
+
+uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2)
+{
+ MM2A_MIX(mm2->hash, mm2->tail);
+ MM2A_MIX(mm2->hash, mm2->size);
+
+ mm2->hash ^= mm2->hash >> 13;
+ mm2->hash *= MM2A_M;
+ mm2->hash ^= mm2->hash >> 15;
+
+ return mm2->hash;
+}
diff --git a/source/blender/blenlib/intern/lasso.c b/source/blender/blenlib/intern/lasso.c
index e89f7fd795b..23704538413 100644
--- a/source/blender/blenlib/intern/lasso.c
+++ b/source/blender/blenlib/intern/lasso.c
@@ -33,7 +33,6 @@
#include "DNA_vec_types.h"
#include "BLI_math.h"
-#include "BLI_rect.h"
#include "BLI_strict_flags.h"
#include "BLI_lasso.h" /* own include */
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 6fcc5888382..d52c09790f9 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -211,7 +211,7 @@ void BLI_freelinkN(ListBase *listbase, void *vlink)
* (which should return 1 iff its first arg should come after its second arg).
* This uses insertion sort, so NOT ok for large list.
*/
-void BLI_sortlist(ListBase *listbase, int (*cmp)(const void *, const void *))
+void BLI_listbase_sort(ListBase *listbase, int (*cmp)(const void *, const void *))
{
Link *current = NULL;
Link *previous = NULL;
@@ -233,7 +233,7 @@ void BLI_sortlist(ListBase *listbase, int (*cmp)(const void *, const void *))
}
}
-void BLI_sortlist_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *))
+void BLI_listbase_sort_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *))
{
Link *current = NULL;
Link *previous = NULL;
@@ -372,22 +372,35 @@ void BLI_freelistN(ListBase *listbase)
BLI_listbase_clear(listbase);
}
+/**
+ * Returns the number of elements in \a listbase, up until (and including count_max)
+ *
+ * \note Use to avoid redundant looping.
+ */
+int BLI_listbase_count_ex(const ListBase *listbase, const int count_max)
+{
+ Link *link;
+ int count = 0;
+
+ for (link = listbase->first; link && count != count_max; link = link->next) {
+ count++;
+ }
+
+ return count;
+}
/**
* Returns the number of elements in \a listbase.
*/
-int BLI_countlist(const ListBase *listbase)
+int BLI_listbase_count(const ListBase *listbase)
{
Link *link;
int count = 0;
-
- if (listbase) {
- link = listbase->first;
- while (link) {
- count++;
- link = link->next;
- }
+
+ for (link = listbase->first; link; link = link->next) {
+ count++;
}
+
return count;
}
@@ -461,7 +474,7 @@ void *BLI_findstring(const ListBase *listbase, const char *id, const int offset)
for (link = listbase->first; link; link = link->next) {
id_iter = ((const char *)link) + offset;
- if (id[0] == id_iter[0] && strcmp(id, id_iter) == 0) {
+ if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
return link;
}
}
@@ -481,7 +494,7 @@ void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset
for (link = listbase->last; link; link = link->prev) {
id_iter = ((const char *)link) + offset;
- if (id[0] == id_iter[0] && strcmp(id, id_iter) == 0) {
+ if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
return link;
}
}
@@ -502,7 +515,7 @@ void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int off
/* exact copy of BLI_findstring(), except for this line */
id_iter = *((const char **)(((const char *)link) + offset));
- if (id[0] == id_iter[0] && strcmp(id, id_iter) == 0) {
+ if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
return link;
}
}
@@ -523,7 +536,7 @@ void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int of
/* exact copy of BLI_rfindstring(), except for this line */
id_iter = *((const char **)(((const char *)link) + offset));
- if (id[0] == id_iter[0] && strcmp(id, id_iter) == 0) {
+ if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
return link;
}
}
@@ -587,7 +600,7 @@ int BLI_findstringindex(const ListBase *listbase, const char *id, const int offs
while (link) {
id_iter = ((const char *)link) + offset;
- if (id[0] == id_iter[0] && strcmp(id, id_iter) == 0)
+ if (id[0] == id_iter[0] && STREQ(id, id_iter))
return i;
i++;
link = link->next;
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index e6217329145..f5713824296 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -44,6 +44,24 @@
# define UNLIKELY(x) (x)
#endif
+/* powf is really slow for raising to integer powers. */
+MINLINE float pow2f(float x)
+{
+ return x * x;
+}
+MINLINE float pow3f(float x)
+{
+ return pow2f(x) * x;
+}
+MINLINE float pow4f(float x)
+{
+ return pow2f(pow2f(x));
+}
+MINLINE float pow7f(float x)
+{
+ return pow2f(pow3f(x)) * x;
+}
+
MINLINE float sqrt3f(float f)
{
if (UNLIKELY(f == 0.0f)) return 0.0f;
@@ -258,5 +276,18 @@ MINLINE float signf(float f)
return (f < 0.f) ? -1.f : 1.f;
}
+MINLINE int signum_i_ex(float a, float eps)
+{
+ if (a > eps) return 1;
+ if (a < -eps) return -1;
+ else return 0;
+}
+
+MINLINE int signum_i(float a)
+{
+ if (a > 0.0f) return 1;
+ if (a < 0.0f) return -1;
+ else return 0;
+}
#endif /* __MATH_BASE_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 3ed7230b1d2..e149fdb2d26 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -429,27 +429,6 @@ void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
/* ********************************* color transforms ********************************* */
-void gamma_correct(float *c, float gamma)
-{
- *c = powf((*c), gamma);
-}
-
-float rec709_to_linearrgb(float c)
-{
- if (c < 0.081f)
- return (c < 0.0f) ? 0.0f : c * (1.0f / 4.5f);
- else
- return powf((c + 0.099f) * (1.0f / 1.099f), (1.0f / 0.45f));
-}
-
-float linearrgb_to_rec709(float c)
-{
- if (c < 0.018f)
- return (c < 0.0f) ? 0.0f : c * 4.5f;
- else
- return 1.099f * powf(c, 0.45f) - 0.099f;
-}
-
float srgb_to_linearrgb(float c)
{
if (c < 0.04045f)
diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c
index 9233749d5df..dc62d04ad55 100644
--- a/source/blender/blenlib/intern/math_color_inline.c
+++ b/source/blender/blenlib/intern/math_color_inline.c
@@ -31,6 +31,8 @@
#include "BLI_math_color.h"
#include "BLI_utildefines.h"
+#include "math.h"
+
#ifndef __MATH_COLOR_INLINE_C__
#define __MATH_COLOR_INLINE_C__
@@ -269,6 +271,24 @@ MINLINE int compare_rgb_uchar(const unsigned char col_a[3], const unsigned char
return 0;
}
+MINLINE float dither_random_value(float s, float t)
+{
+ static float vec[2] = {12.9898f, 78.233f};
+ float value;
+
+ value = sinf(s * vec[0] + t * vec[1]) * 43758.5453f;
+ return value - floorf(value);
+}
+
+MINLINE void float_to_byte_dither_v3(unsigned char b[3], const float f[3], float dither, float s, float t)
+{
+ float dither_value = dither_random_value(s, t) * 0.005f * dither;
+
+ b[0] = FTOCHAR(dither_value + f[0]);
+ b[1] = FTOCHAR(dither_value + f[1]);
+ b[2] = FTOCHAR(dither_value + f[2]);
+}
+
/**************** Alpha Transformations *****************/
MINLINE void premul_to_straight_v4_v4(float straight[4], const float premul[4])
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 015313431cb..ba1f4480659 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -50,6 +50,21 @@ void cent_quad_v3(float cent[3], const float v1[3], const float v2[3], const flo
cent[2] = 0.25f * (v1[2] + v2[2] + v3[2] + v4[2]);
}
+void cross_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
+{
+ float n1[3], n2[3];
+
+ n1[0] = v1[0] - v2[0];
+ n2[0] = v2[0] - v3[0];
+ n1[1] = v1[1] - v2[1];
+ n2[1] = v2[1] - v3[1];
+ n1[2] = v1[2] - v2[2];
+ n2[2] = v2[2] - v3[2];
+ n[0] = n1[1] * n2[2] - n1[2] * n2[1];
+ n[1] = n1[2] * n2[0] - n1[0] * n2[2];
+ n[2] = n1[0] * n2[1] - n1[1] * n2[0];
+}
+
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
{
float n1[3], n2[3];
@@ -94,58 +109,44 @@ float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const flo
*/
float normal_poly_v3(float n[3], const float verts[][3], unsigned int nr)
{
- const float *v_prev = verts[nr - 1];
- const float *v_curr = verts[0];
- unsigned int i;
-
- zero_v3(n);
-
- /* Newell's Method */
- for (i = 0; i < nr; v_prev = v_curr, v_curr = verts[++i]) {
- add_newell_cross_v3_v3v3(n, v_prev, v_curr);
- }
-
+ cross_poly_v3(n, verts, nr);
return normalize_v3(n);
}
-/* only convex Quadrilaterals */
float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
- float len, vec1[3], vec2[3], n[3];
-
- sub_v3_v3v3(vec1, v2, v1);
- sub_v3_v3v3(vec2, v4, v1);
- cross_v3_v3v3(n, vec1, vec2);
- len = len_v3(n);
-
- sub_v3_v3v3(vec1, v4, v3);
- sub_v3_v3v3(vec2, v2, v3);
- cross_v3_v3v3(n, vec1, vec2);
- len += len_v3(n);
+ const float verts[4][3] = {{UNPACK3(v1)}, {UNPACK3(v2)}, {UNPACK3(v3)}, {UNPACK3(v4)}};
+ return area_poly_v3(verts, 4);
+}
- return (len / 2.0f);
+float area_squared_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+{
+ const float verts[4][3] = {{UNPACK3(v1)}, {UNPACK3(v2)}, {UNPACK3(v3)}, {UNPACK3(v4)}};
+ return area_squared_poly_v3(verts, 4);
}
/* Triangles */
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
{
- float vec1[3], vec2[3], n[3];
-
- sub_v3_v3v3(vec1, v3, v2);
- sub_v3_v3v3(vec2, v1, v2);
- cross_v3_v3v3(n, vec1, vec2);
+ float n[3];
+ cross_tri_v3(n, v1, v2, v3);
+ return len_v3(n) * 0.5f;
+}
- return len_v3(n) / 2.0f;
+float area_squared_tri_v3(const float v1[3], const float v2[3], const float v3[3])
+{
+ float n[3];
+ cross_tri_v3(n, v1, v2, v3);
+ mul_v3_fl(n, 0.5f);
+ return len_squared_v3(n);
}
float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3])
{
- float area, vec1[3], vec2[3], n[3];
+ float area, n[3];
- sub_v3_v3v3(vec1, v3, v2);
- sub_v3_v3v3(vec2, v1, v2);
- cross_v3_v3v3(n, vec1, vec2);
- area = len_v3(n) / 2.0f;
+ cross_tri_v3(n, v1, v2, v3);
+ area = len_v3(n) * 0.5f;
/* negate area for flipped triangles */
if (dot_v3v3(n, normal) < 0.0f)
@@ -157,7 +158,17 @@ float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3]
float area_poly_v3(const float verts[][3], unsigned int nr)
{
float n[3];
- return normal_poly_v3(n, verts, nr) * 0.5f;
+ cross_poly_v3(n, verts, nr);
+ return len_v3(n) * 0.5f;
+}
+
+float area_squared_poly_v3(const float verts[][3], unsigned int nr)
+{
+ float n[3];
+
+ cross_poly_v3(n, verts, nr);
+ mul_v3_fl(n, 0.5f);
+ return len_squared_v3(n);
}
/**
@@ -185,11 +196,36 @@ float cross_poly_v2(const float verts[][2], unsigned int nr)
return cross;
}
+void cross_poly_v3(float n[3], const float verts[][3], unsigned int nr)
+{
+ const float *v_prev = verts[nr - 1];
+ const float *v_curr = verts[0];
+ unsigned int i;
+
+ zero_v3(n);
+
+ /* Newell's Method */
+ for (i = 0; i < nr; v_prev = v_curr, v_curr = verts[++i]) {
+ add_newell_cross_v3_v3v3(n, v_prev, v_curr);
+ }
+}
+
float area_poly_v2(const float verts[][2], unsigned int nr)
{
return fabsf(0.5f * cross_poly_v2(verts, nr));
}
+float area_poly_signed_v2(const float verts[][2], unsigned int nr)
+{
+ return (0.5f * cross_poly_v2(verts, nr));
+}
+
+float area_squared_poly_v2(const float verts[][2], unsigned int nr)
+{
+ float area = area_poly_signed_v2(verts, nr);
+ return area * area;
+}
+
float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3])
{
float a[3], b[3], c[3], c_len;
@@ -221,14 +257,22 @@ void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const
}
/**
- * Get a point and a normal from a plane.
+ * Get a point and a direction from a plane.
*/
-void plane_to_point_normal_v3(const float plane[4], float r_plane_co[3], float r_plane_no[3])
+void plane_to_point_vector_v3(const float plane[4], float r_plane_co[3], float r_plane_no[3])
{
- const float length = normalize_v3_v3(r_plane_no, plane);
- madd_v3_v3v3fl(r_plane_co, r_plane_no, r_plane_no, (-plane[3] / length) - 1.0f);
+ mul_v3_v3fl(r_plane_co, plane, (-plane[3] / len_squared_v3(plane)));
+ copy_v3_v3(r_plane_no, plane);
}
+/**
+ * version of #plane_to_point_vector_v3 that gets a unit length vector.
+ */
+void plane_to_point_vector_v3_normalized(const float plane[4], float r_plane_co[3], float r_plane_no[3])
+{
+ const float length = normalize_v3_v3(r_plane_no, plane);
+ mul_v3_v3fl(r_plane_co, r_plane_no, (-plane[3] / length));
+}
/********************************* Volume **********************************/
@@ -441,6 +485,77 @@ float dist_to_line_v3(const float v1[3], const float l1[3], const float l2[3])
return sqrtf(dist_squared_to_line_v3(v1, l1, l2));
}
+/**
+ * Check if \a p is inside the 2x planes defined by ``(v1, v2, v3)``
+ * where the 3x points define 2x planes.
+ *
+ * \param axis_ref used when v1,v2,v3 form a line and to check if the corner is concave/convex.
+ *
+ * \note the distance from \a v1 & \a v3 to \a v2 doesnt matter
+ * (it just defines the planes).
+ *
+ * \return the lowest squared distance to eithe of the planes.
+ * where ``(return < 0.0)`` is outside.
+ *
+ * <pre>
+ * v1
+ * +
+ * /
+ * x - out / x - inside
+ * /
+ * +----+
+ * v2 v3
+ * x - also outside
+ * </pre>
+ */
+float dist_signed_squared_to_corner_v3v3v3(
+ const float p[3],
+ const float v1[3], const float v2[3], const float v3[3],
+ const float axis_ref[3])
+{
+ float dir_a[3], dir_b[3];
+ float plane_a[4], plane_b[4];
+ float dist_a, dist_b;
+ float axis[3];
+ bool flip = false;
+
+ sub_v3_v3v3(dir_a, v1, v2);
+ sub_v3_v3v3(dir_b, v3, v2);
+
+ cross_v3_v3v3(axis, dir_a, dir_b);
+
+ if ((len_squared_v3(axis) < FLT_EPSILON)) {
+ copy_v3_v3(axis, axis_ref);
+ }
+ else if (dot_v3v3(axis, axis_ref) < 0.0f) {
+ /* concave */
+ flip = true;
+ negate_v3(axis);
+ }
+
+ cross_v3_v3v3(plane_a, dir_a, axis);
+ cross_v3_v3v3(plane_b, axis, dir_b);
+
+#if 0
+ plane_from_point_normal_v3(plane_a, center, l1);
+ plane_from_point_normal_v3(plane_b, center, l2);
+#else
+ /* do inline */
+ plane_a[3] = -dot_v3v3(plane_a, v2);
+ plane_b[3] = -dot_v3v3(plane_b, v2);
+#endif
+
+ dist_a = dist_signed_squared_to_plane_v3(p, plane_a);
+ dist_b = dist_signed_squared_to_plane_v3(p, plane_b);
+
+ if (flip) {
+ return min_ff(dist_a, dist_b);
+ }
+ else {
+ return max_ff(dist_a, dist_b);
+ }
+}
+
/* Adapted from "Real-Time Collision Detection" by Christer Ericson,
* published by Morgan Kaufmann Publishers, copyright 2005 Elsevier Inc.
*
@@ -912,12 +1027,12 @@ bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[
if (line_point_side_v2(v1, v2, pt) >= 0.0f) {
if (line_point_side_v2(v2, v3, pt) >= 0.0f) {
if (line_point_side_v2(v3, v1, pt) >= 0.0f) {
- return 1;
+ return true;
}
}
}
- return 0;
+ return false;
}
int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
@@ -983,28 +1098,28 @@ bool isect_line_tri_v3(const float p1[3], const float p2[3],
cross_v3_v3v3(p, d, e2);
a = dot_v3v3(e1, p);
- if (a == 0.0f) return 0;
+ if (a == 0.0f) return false;
f = 1.0f / a;
sub_v3_v3v3(s, p1, v0);
u = f * dot_v3v3(s, p);
- if ((u < 0.0f) || (u > 1.0f)) return 0;
+ if ((u < 0.0f) || (u > 1.0f)) return false;
cross_v3_v3v3(q, s, e1);
v = f * dot_v3v3(d, q);
- if ((v < 0.0f) || ((u + v) > 1.0f)) return 0;
+ if ((v < 0.0f) || ((u + v) > 1.0f)) return false;
*r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return 0;
+ if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return false;
if (r_uv) {
r_uv[0] = u;
r_uv[1] = v;
}
- return 1;
+ return true;
}
/* like isect_line_tri_v3, but allows epsilon tolerance around triangle */
@@ -1022,28 +1137,28 @@ bool isect_line_tri_epsilon_v3(const float p1[3], const float p2[3],
cross_v3_v3v3(p, d, e2);
a = dot_v3v3(e1, p);
- if (a == 0.0f) return 0;
+ if (a == 0.0f) return false;
f = 1.0f / a;
sub_v3_v3v3(s, p1, v0);
u = f * dot_v3v3(s, p);
- if ((u < -epsilon) || (u > 1.0f + epsilon)) return 0;
+ if ((u < -epsilon) || (u > 1.0f + epsilon)) return false;
cross_v3_v3v3(q, s, e1);
v = f * dot_v3v3(d, q);
- if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return 0;
+ if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return false;
*r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return 0;
+ if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return false;
if (r_uv) {
r_uv[0] = u;
r_uv[1] = v;
}
- return 1;
+ return true;
}
/* moved from effect.c
@@ -1064,28 +1179,28 @@ bool isect_ray_tri_v3(const float p1[3], const float d[3],
a = dot_v3v3(e1, p);
/* note: these values were 0.000001 in 2.4x but for projection snapping on
* a human head (1BU == 1m), subsurf level 2, this gave many errors - campbell */
- if ((a > -0.00000001f) && (a < 0.00000001f)) return 0;
+ if ((a > -0.00000001f) && (a < 0.00000001f)) return false;
f = 1.0f / a;
sub_v3_v3v3(s, p1, v0);
u = f * dot_v3v3(s, p);
- if ((u < 0.0f) || (u > 1.0f)) return 0;
+ if ((u < 0.0f) || (u > 1.0f)) return false;
cross_v3_v3v3(q, s, e1);
v = f * dot_v3v3(d, q);
- if ((v < 0.0f) || ((u + v) > 1.0f)) return 0;
+ if ((v < 0.0f) || ((u + v) > 1.0f)) return false;
*r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f)) return 0;
+ if ((*r_lambda < 0.0f)) return false;
if (r_uv) {
r_uv[0] = u;
r_uv[1] = v;
}
- return 1;
+ return true;
}
/**
@@ -1107,7 +1222,7 @@ bool isect_ray_plane_v3(const float p1[3], const float d[3],
a = dot_v3v3(e1, p);
/* note: these values were 0.000001 in 2.4x but for projection snapping on
* a human head (1BU == 1m), subsurf level 2, this gave many errors - campbell */
- if ((a > -0.00000001f) && (a < 0.00000001f)) return 0;
+ if ((a > -0.00000001f) && (a < 0.00000001f)) return false;
f = 1.0f / a;
sub_v3_v3v3(s, p1, v0);
@@ -1119,9 +1234,9 @@ bool isect_ray_plane_v3(const float p1[3], const float d[3],
/* v = f * dot_v3v3(d, q); */ /*UNUSED*/
*r_lambda = f * dot_v3v3(e2, q);
- if (clip && (*r_lambda < 0.0f)) return 0;
+ if (clip && (*r_lambda < 0.0f)) return false;
- return 1;
+ return true;
}
bool isect_ray_tri_epsilon_v3(const float p1[3], const float d[3],
@@ -1142,22 +1257,22 @@ bool isect_ray_tri_epsilon_v3(const float p1[3], const float d[3],
sub_v3_v3v3(s, p1, v0);
u = f * dot_v3v3(s, p);
- if ((u < -epsilon) || (u > 1.0f + epsilon)) return 0;
+ if ((u < -epsilon) || (u > 1.0f + epsilon)) return false;
cross_v3_v3v3(q, s, e1);
v = f * dot_v3v3(d, q);
- if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return 0;
+ if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return false;
*r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f)) return 0;
+ if ((*r_lambda < 0.0f)) return false;
if (uv) {
uv[0] = u;
uv[1] = v;
}
- return 1;
+ return true;
}
bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3],
@@ -1173,14 +1288,14 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3],
cross_v3_v3v3(p, d, e2);
a = dot_v3v3(e1, p);
- if ((a > -0.000001f) && (a < 0.000001f)) return 0;
+ if ((a > -0.000001f) && (a < 0.000001f)) return false;
f = 1.0f / a;
sub_v3_v3v3(s, p1, v0);
cross_v3_v3v3(q, s, e1);
*r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f)) return 0;
+ if ((*r_lambda < 0.0f)) return false;
u = f * dot_v3v3(s, p);
v = f * dot_v3v3(d, q);
@@ -1204,7 +1319,7 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3],
mul_v3_fl(e2, dv);
if (len_squared_v3(e1) + len_squared_v3(e2) > threshold * threshold) {
- return 0;
+ return false;
}
if (r_uv) {
@@ -1212,7 +1327,7 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3],
r_uv[1] = v;
}
- return 1;
+ return true;
}
/**
@@ -1363,7 +1478,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const fl
if (t0 > t1)
SWAP(float, t0, t1);
- if (t0 > 1.0f || t1 < 0.0f) return 0;
+ if (t0 > 1.0f || t1 < 0.0f) return false;
/* clamp to [0, 1] */
CLAMP(t0, 0.0f, 1.0f);
@@ -1542,7 +1657,7 @@ bool isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3
if ((f > -0.000001f) && (f < 0.000001f)) return false;
v = (p[a2] * e1[a1] - p[a1] * e1[a2]) / f;
- if ((v < 0.0f) || (v > 1.0f)) return 0;
+ if ((v < 0.0f) || (v > 1.0f)) return false;
f = e1[a1];
if ((f > -0.000001f) && (f < 0.000001f)) {
@@ -1553,7 +1668,7 @@ bool isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3
else
u = (-p[a1] - v * e2[a1]) / f;
- if ((u < 0.0f) || ((u + v) > 1.0f)) return 0;
+ if ((u < 0.0f) || ((u + v) > 1.0f)) return false;
*r_lambda = (p[a0] + u * e1[a0] + v * e2[a0]) / (p2[a0] - p1[a0]);
@@ -1840,7 +1955,7 @@ float line_plane_factor_v3(const float plane_co[3], const float plane_no[3],
return (dot != 0.0f) ? -dot_v3v3(plane_no, h) / dot : 0.0f;
}
-/** Ensure the distance between these points is no greater then 'dist'.
+/** Ensure the distance between these points is no greater than 'dist'.
* If it is, scale then both into the center.
*/
void limit_dist_v3(float v1[3], float v2[3], const float dist)
@@ -2350,15 +2465,15 @@ bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[
}
/**
- * \note: using #area_tri_signed_v2 means locations outside the triangle are correctly weighted
+ * \note: using #cross_tri_v2 means locations outside the triangle are correctly weighted
*/
void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
{
float wtot;
- w[0] = area_tri_signed_v2(v2, v3, co);
- w[1] = area_tri_signed_v2(v3, v1, co);
- w[2] = area_tri_signed_v2(v1, v2, co);
+ w[0] = cross_tri_v2(v2, v3, co);
+ w[1] = cross_tri_v2(v3, v1, co);
+ w[2] = cross_tri_v2(v1, v2, co);
wtot = w[0] + w[1] + w[2];
if (wtot != 0.0f) {
@@ -2377,9 +2492,9 @@ void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const fl
{
float wtot;
- w[0] = area_tri_signed_v2(v2, v3, co) / v1[3];
- w[1] = area_tri_signed_v2(v3, v1, co) / v2[3];
- w[2] = area_tri_signed_v2(v1, v2, co) / v3[3];
+ w[0] = cross_tri_v2(v2, v3, co) / v1[3];
+ w[1] = cross_tri_v2(v3, v1, co) / v2[3];
+ w[2] = cross_tri_v2(v1, v2, co) / v3[3];
wtot = w[0] + w[1] + w[2];
if (wtot != 0.0f) {
@@ -2602,38 +2717,55 @@ int interp_sparse_array(float *array, const int list_size, const float skipval)
return 1;
}
+/** \name interp_weights_poly_v2, v3
+ * \{ */
+
+#define IS_POINT_IX (1 << 0)
+#define IS_SEGMENT_IX (1 << 1)
+
+#define DIR_V3_SET(d_len, va, vb) { \
+ sub_v3_v3v3((d_len)->dir, va, vb); \
+ (d_len)->len = len_v3((d_len)->dir); \
+} (void)0
+
+#define DIR_V2_SET(d_len, va, vb) { \
+ sub_v2_v2v2((d_len)->dir, va, vb); \
+ (d_len)->len = len_v2((d_len)->dir); \
+} (void)0
+
+struct Float3_Len {
+ float dir[3], len;
+};
+
+struct Float2_Len {
+ float dir[2], len;
+};
+
/* Mean value weights - smooth interpolation weights for polygons with
* more than 3 vertices */
-static float mean_value_half_tan_v3(const float v1[3], const float v2[3], const float v3[3])
+static float mean_value_half_tan_v3(const struct Float3_Len *d_curr, const struct Float3_Len *d_next)
{
- float d2[3], d3[3], cross[3], area;
-
- sub_v3_v3v3(d2, v2, v1);
- sub_v3_v3v3(d3, v3, v1);
- cross_v3_v3v3(cross, d2, d3);
-
+ float cross[3], area;
+ cross_v3_v3v3(cross, d_curr->dir, d_next->dir);
area = len_v3(cross);
if (LIKELY(area != 0.0f)) {
- const float dot = dot_v3v3(d2, d3);
- const float len = len_v3(d2) * len_v3(d3);
+ const float dot = dot_v3v3(d_curr->dir, d_next->dir);
+ const float len = d_curr->len * d_next->len;
return (len - dot) / area;
}
else {
return 0.0f;
}
}
-static float mean_value_half_tan_v2(const float v1[2], const float v2[2], const float v3[2])
-{
- float d2[2], d3[2], area;
-
- sub_v2_v2v2(d2, v2, v1);
- sub_v2_v2v2(d3, v3, v1);
+static float mean_value_half_tan_v2(const struct Float2_Len *d_curr, const struct Float2_Len *d_next)
+{
+ float area;
/* different from the 3d version but still correct */
- area = cross_v2v2(d2, d3);
+ area = cross_v2v2(d_curr->dir, d_next->dir);
if (LIKELY(area != 0.0f)) {
- const float dot = dot_v2v2(d2, d3);
- const float len = len_v2(d2) * len_v2(d3);
+ const float dot = dot_v2v2(d_curr->dir, d_next->dir);
+ const float len = d_curr->len * d_next->len;
return (len - dot) / area;
}
else {
@@ -2649,30 +2781,34 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
float ht_prev, ht; /* half tangents */
float totweight = 0.0f;
int i = 0;
- bool vert_interp = false;
- bool edge_interp = false;
+ char ix_flag = 0;
+ struct Float3_Len d_curr, d_next;
v_curr = v[0];
v_next = v[1];
- ht_prev = mean_value_half_tan_v3(co, v[n - 1], v_curr);
+ DIR_V3_SET(&d_curr, v[n - 1], co);
+ DIR_V3_SET(&d_next, v_curr, co);
+ ht_prev = mean_value_half_tan_v3(&d_curr, &d_next);
while (i < n) {
- const float len_sq = len_squared_v3v3(co, v_curr);
-
/* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
* to borders of face. In that case, do simple linear interpolation between the two edge vertices */
- if (len_sq < eps_sq) {
- vert_interp = true;
+
+ /* 'd_next.len' is infact 'd_curr.len', just avoid copy to begin with */
+ if (UNLIKELY(d_next.len < eps)) {
+ ix_flag = IS_POINT_IX;
break;
}
- else if (dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq) {
- edge_interp = true;
+ else if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) {
+ ix_flag = IS_SEGMENT_IX;
break;
}
- ht = mean_value_half_tan_v3(co, v_curr, v_next);
- w[i] = (ht_prev + ht) / sqrtf(len_sq);
+ d_curr = d_next;
+ DIR_V3_SET(&d_next, v_next, co);
+ ht = mean_value_half_tan_v3(&d_curr, &d_next);
+ w[i] = (ht_prev + ht) / d_curr.len;
totweight += w[i];
/* step */
@@ -2683,22 +2819,21 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
ht_prev = ht;
}
- if (vert_interp) {
+ if (ix_flag) {
const int i_curr = i;
- for (i = 0; i < n; i++)
- w[i] = 0.0;
- w[i_curr] = 1.0f;
- }
- else if (edge_interp) {
- const int i_curr = i;
- float len_curr = len_v3v3(co, v_curr);
- float len_next = len_v3v3(co, v_next);
- float edge_len = len_curr + len_next;
- for (i = 0; i < n; i++)
- w[i] = 0.0;
+ for (i = 0; i < n; i++) {
+ w[i] = 0.0f;
+ }
- w[i_curr] = len_next / edge_len;
- w[(i_curr + 1) % n] = len_curr / edge_len;
+ if (ix_flag & IS_POINT_IX) {
+ w[i_curr] = 1.0f;
+ }
+ else {
+ float fac = line_point_factor_v3(co, v_curr, v_next);
+ CLAMP(fac, 0.0f, 1.0f);
+ w[i_curr] = 1.0f - fac;
+ w[(i_curr + 1) % n] = fac;
+ }
}
else {
if (totweight != 0.0f) {
@@ -2718,30 +2853,34 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
float ht_prev, ht; /* half tangents */
float totweight = 0.0f;
int i = 0;
- bool vert_interp = false;
- bool edge_interp = false;
+ char ix_flag = 0;
+ struct Float2_Len d_curr, d_next;
v_curr = v[0];
v_next = v[1];
- ht_prev = mean_value_half_tan_v2(co, v[n - 1], v_curr);
+ DIR_V2_SET(&d_curr, v[n - 1], co);
+ DIR_V2_SET(&d_next, v_curr, co);
+ ht_prev = mean_value_half_tan_v2(&d_curr, &d_next);
while (i < n) {
- const float len_sq = len_squared_v2v2(co, v_curr);
-
/* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
* to borders of face. In that case, do simple linear interpolation between the two edge vertices */
- if (len_sq < eps_sq) {
- vert_interp = true;
+
+ /* 'd_next.len' is infact 'd_curr.len', just avoid copy to begin with */
+ if (UNLIKELY(d_next.len < eps)) {
+ ix_flag = IS_POINT_IX;
break;
}
- else if (dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq) {
- edge_interp = true;
+ else if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) {
+ ix_flag = IS_SEGMENT_IX;
break;
}
- ht = mean_value_half_tan_v2(co, v_curr, v_next);
- w[i] = (ht_prev + ht) / sqrtf(len_sq);
+ d_curr = d_next;
+ DIR_V2_SET(&d_next, v_next, co);
+ ht = mean_value_half_tan_v2(&d_curr, &d_next);
+ w[i] = (ht_prev + ht) / d_curr.len;
totweight += w[i];
/* step */
@@ -2752,22 +2891,21 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
ht_prev = ht;
}
- if (vert_interp) {
+ if (ix_flag) {
const int i_curr = i;
- for (i = 0; i < n; i++)
- w[i] = 0.0;
- w[i_curr] = 1.0f;
- }
- else if (edge_interp) {
- const int i_curr = i;
- float len_curr = len_v2v2(co, v_curr);
- float len_next = len_v2v2(co, v_next);
- float edge_len = len_curr + len_next;
- for (i = 0; i < n; i++)
- w[i] = 0.0;
+ for (i = 0; i < n; i++) {
+ w[i] = 0.0f;
+ }
- w[i_curr] = len_next / edge_len;
- w[(i_curr + 1) % n] = len_curr / edge_len;
+ if (ix_flag & IS_POINT_IX) {
+ w[i_curr] = 1.0f;
+ }
+ else {
+ float fac = line_point_factor_v2(co, v_curr, v_next);
+ CLAMP(fac, 0.0f, 1.0f);
+ w[i_curr] = 1.0f - fac;
+ w[(i_curr + 1) % n] = fac;
+ }
}
else {
if (totweight != 0.0f) {
@@ -2778,6 +2916,15 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
}
}
+#undef IS_POINT_IX
+#undef IS_SEGMENT_IX
+
+#undef DIR_V3_SET
+#undef DIR_V2_SET
+
+/** \} */
+
+
/* (x1, v1)(t1=0)------(x2, v2)(t2=1), 0<t<1 --> (x, v)(t) */
void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3], const float x2[3], const float v2[3], const float t)
{
@@ -3057,6 +3204,59 @@ void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x
}
}
+/**
+ * Frustum planes extraction from a projection matrix (homogeneous 4d vector representations of planes).
+ *
+ * plane parameters can be NULL if you do not need them.
+ */
+void planes_from_projmat(float mat[4][4], float left[4], float right[4], float top[4], float bottom[4],
+ float near[4], float far[4])
+{
+ /* References:
+ *
+ * https://fgiesen.wordpress.com/2012/08/31/frustum-planes-from-the-projection-matrix/
+ * http://www8.cs.umu.se/kurser/5DV051/HT12/lab/plane_extraction.pdf
+ */
+
+ int i;
+
+ if (left) {
+ for (i = 4; i--; ) {
+ left[i] = mat[i][3] + mat[i][0];
+ }
+ }
+
+ if (right) {
+ for (i = 4; i--; ) {
+ right[i] = mat[i][3] - mat[i][0];
+ }
+ }
+
+ if (bottom) {
+ for (i = 4; i--; ) {
+ bottom[i] = mat[i][3] + mat[i][1];
+ }
+ }
+
+ if (top) {
+ for (i = 4; i--; ) {
+ top[i] = mat[i][3] - mat[i][1];
+ }
+ }
+
+ if (near) {
+ for (i = 4; i--; ) {
+ near[i] = mat[i][3] + mat[i][2];
+ }
+ }
+
+ if (far) {
+ for (i = 4; i--; ) {
+ far[i] = mat[i][3] - mat[i][2];
+ }
+ }
+}
+
static void i_multmatrix(float icand[4][4], float Vm[4][4])
{
int row, col;
@@ -4016,3 +4216,31 @@ bool is_poly_convex_v2(const float verts[][2], unsigned int nr)
return true;
}
+
+/**
+ * Check if either of the diagonals along this quad create flipped triangles
+ * (normals pointing away from eachother).
+ * - (1 << 0): (v1-v3) is flipped.
+ * - (1 << 1): (v2-v4) is flipped.
+ */
+int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+{
+ float d_12[3], d_23[3], d_34[3], d_41[3];
+ float cross_a[3], cross_b[3];
+ int ret = 0;
+
+ sub_v3_v3v3(d_12, v1, v2);
+ sub_v3_v3v3(d_23, v2, v3);
+ sub_v3_v3v3(d_34, v3, v4);
+ sub_v3_v3v3(d_41, v4, v1);
+
+ cross_v3_v3v3(cross_a, d_12, d_23);
+ cross_v3_v3v3(cross_b, d_34, d_41);
+ ret |= ((dot_v3v3(cross_a, cross_b) < 0.0f) << 0);
+
+ cross_v3_v3v3(cross_a, d_23, d_34);
+ cross_v3_v3v3(cross_b, d_41, d_12);
+ ret |= ((dot_v3v3(cross_a, cross_b) < 0.0f) << 1);
+
+ return ret;
+}
diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c
index 5a64ed63ecf..44b17681540 100644
--- a/source/blender/blenlib/intern/math_geom_inline.c
+++ b/source/blender/blenlib/intern/math_geom_inline.c
@@ -54,6 +54,12 @@ MINLINE float area_tri_v2(const float v1[2], const float v2[2], const float v3[2
return fabsf(area_tri_signed_v2(v1, v2, v3));
}
+MINLINE float area_squared_tri_v2(const float v1[2], const float v2[2], const float v3[2])
+{
+ float area = area_tri_signed_v2(v1, v2, v3);
+ return area * area;
+}
+
/****************************** Spherical Harmonics **************************/
MINLINE void zero_sh(float r[9])
diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c
index 4feb954a31a..67850463fe2 100644
--- a/source/blender/blenlib/intern/math_interp.c
+++ b/source/blender/blenlib/intern/math_interp.c
@@ -111,10 +111,12 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer, const fl
/* sample area entirely outside image? */
if (ceil(u) < 0 || floor(u) > width - 1 || ceil(v) < 0 || floor(v) > height - 1) {
- if (float_output)
- float_output[0] = float_output[1] = float_output[2] = float_output[3] = 0.0f;
- if (byte_output)
- byte_output[0] = byte_output[1] = byte_output[2] = byte_output[3] = 0;
+ if (float_output) {
+ fill_vn_fl(float_output, components, 0.0f);
+ }
+ if (byte_output) {
+ fill_vn_uchar(byte_output, components, 0);
+ }
return;
}
@@ -279,7 +281,7 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const f
/* sample area entirely outside image? */
if (x2 < 0 || x1 > width - 1 || y2 < 0 || y1 > height - 1) {
- float_output[0] = float_output[1] = float_output[2] = float_output[3] = 0.0f;
+ fill_vn_fl(float_output, components, 0.0f);
return;
}
@@ -321,7 +323,7 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const f
/* sample area entirely outside image? */
if (x2 < 0 || x1 > width - 1 || y2 < 0 || y1 > height - 1) {
- byte_output[0] = byte_output[1] = byte_output[2] = byte_output[3] = 0;
+ fill_vn_uchar(byte_output, components, 0);
return;
}
@@ -467,7 +469,7 @@ void BLI_ewa_filter(const int width, const int height,
/* scaling dxt/dyt by full resolution can cause overflow because of huge A/B/C and esp. F values,
* scaling by aspect ratio alone does the opposite, so try something in between instead... */
const float ff2 = (float)width, ff = sqrtf(ff2), q = (float)height / ff;
- const float Ux = du[0] * ff, Vx = dv[0] * q, Uy = du[1] * ff, Vy = dv[1] * q;
+ const float Ux = du[0] * ff, Vx = du[1] * q, Uy = dv[0] * ff, Vy = dv[1] * q;
float A = Vx * Vx + Vy * Vy;
float B = -2.0f * (Ux * Vx + Uy * Vy);
float C = Ux * Ux + Uy * Uy;
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index af42af88582..1b4bbafdb04 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -639,7 +639,16 @@ void mul_mat3_m4_fl(float m[4][4], float f)
m[i][j] *= f;
}
-void negate_m3(float m[4][4])
+void negate_m3(float m[3][3])
+{
+ int i, j;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ m[i][j] *= -1.0f;
+}
+
+void negate_mat3_m4(float m[4][4])
{
int i, j;
@@ -839,9 +848,10 @@ bool invert_m4_m4(float inverse[4][4], float mat[4][4])
}
}
- temp = tempmat[i][i];
- if (temp == 0)
- return 0; /* No non-zero pivot */
+ if (UNLIKELY(tempmat[i][i] == 0.0f)) {
+ return false; /* No non-zero pivot */
+ }
+ temp = (double)tempmat[i][i];
for (k = 0; k < 4; k++) {
tempmat[i][k] = (float)((double)tempmat[i][k] / temp);
inverse[i][k] = (float)((double)inverse[i][k] / temp);
@@ -856,7 +866,7 @@ bool invert_m4_m4(float inverse[4][4], float mat[4][4])
}
}
}
- return 1;
+ return true;
}
/****************************** Linear Algebra *******************************/
@@ -876,6 +886,37 @@ void transpose_m3(float mat[3][3])
mat[2][1] = t;
}
+void transpose_m3_m3(float rmat[3][3], float mat[3][3])
+{
+ BLI_assert(rmat != mat);
+
+ rmat[0][0] = mat[0][0];
+ rmat[0][1] = mat[1][0];
+ rmat[0][2] = mat[2][0];
+ rmat[1][0] = mat[0][1];
+ rmat[1][1] = mat[1][1];
+ rmat[1][2] = mat[2][1];
+ rmat[2][0] = mat[0][2];
+ rmat[2][1] = mat[1][2];
+ rmat[2][2] = mat[2][2];
+}
+
+/* seems obscure but in-fact a common operation */
+void transpose_m3_m4(float rmat[3][3], float mat[4][4])
+{
+ BLI_assert(&rmat[0][0] != &mat[0][0]);
+
+ rmat[0][0] = mat[0][0];
+ rmat[0][1] = mat[1][0];
+ rmat[0][2] = mat[2][0];
+ rmat[1][0] = mat[0][1];
+ rmat[1][1] = mat[1][1];
+ rmat[1][2] = mat[2][1];
+ rmat[2][0] = mat[0][2];
+ rmat[2][1] = mat[1][2];
+ rmat[2][2] = mat[2][2];
+}
+
void transpose_m4(float mat[4][4])
{
float t;
@@ -902,6 +943,28 @@ void transpose_m4(float mat[4][4])
mat[3][2] = t;
}
+void transpose_m4_m4(float rmat[4][4], float mat[4][4])
+{
+ BLI_assert(rmat != mat);
+
+ rmat[0][0] = mat[0][0];
+ rmat[0][1] = mat[1][0];
+ rmat[0][2] = mat[2][0];
+ rmat[0][3] = mat[3][0];
+ rmat[1][0] = mat[0][1];
+ rmat[1][1] = mat[1][1];
+ rmat[1][2] = mat[2][1];
+ rmat[1][3] = mat[3][1];
+ rmat[2][0] = mat[0][2];
+ rmat[2][1] = mat[1][2];
+ rmat[2][2] = mat[2][2];
+ rmat[2][3] = mat[3][2];
+ rmat[3][0] = mat[0][3];
+ rmat[3][1] = mat[1][3];
+ rmat[3][2] = mat[2][3];
+ rmat[3][3] = mat[3][3];
+}
+
int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit)
{
if (compare_v4v4(mat1[0], mat2[0], limit))
@@ -1087,11 +1150,11 @@ bool is_orthogonal_m3(float m[3][3])
for (i = 0; i < 3; i++) {
for (j = 0; j < i; j++) {
if (fabsf(dot_v3v3(m[i], m[j])) > 1.5f * FLT_EPSILON)
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
bool is_orthogonal_m4(float m[4][4])
@@ -1101,12 +1164,12 @@ bool is_orthogonal_m4(float m[4][4])
for (i = 0; i < 4; i++) {
for (j = 0; j < i; j++) {
if (fabsf(dot_v4v4(m[i], m[j])) > 1.5f * FLT_EPSILON)
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
bool is_orthonormal_m3(float m[3][3])
@@ -1116,12 +1179,12 @@ bool is_orthonormal_m3(float m[3][3])
for (i = 0; i < 3; i++)
if (fabsf(dot_v3v3(m[i], m[i]) - 1) > 1.5f * FLT_EPSILON)
- return 0;
+ return false;
- return 1;
+ return true;
}
- return 0;
+ return false;
}
bool is_orthonormal_m4(float m[4][4])
@@ -1131,12 +1194,12 @@ bool is_orthonormal_m4(float m[4][4])
for (i = 0; i < 4; i++)
if (fabsf(dot_v4v4(m[i], m[i]) - 1) > 1.5f * FLT_EPSILON)
- return 0;
+ return false;
- return 1;
+ return true;
}
- return 0;
+ return false;
}
bool is_uniform_scaled_m3(float m[3][3])
@@ -1145,8 +1208,7 @@ bool is_uniform_scaled_m3(float m[3][3])
float t[3][3];
float l1, l2, l3, l4, l5, l6;
- copy_m3_m3(t, m);
- transpose_m3(t);
+ transpose_m3_m3(t, m);
l1 = len_squared_v3(m[0]);
l2 = len_squared_v3(m[1]);
@@ -1387,7 +1449,7 @@ float mat3_to_scale(float mat[3][3])
{
/* unit length vector */
float unit_vec[3];
- copy_v3_fl(unit_vec, (float)(1.0 / M_SQRT3));
+ copy_v3_fl(unit_vec, (float)M_SQRT1_3);
mul_m3_v3(mat, unit_vec);
return len_v3(unit_vec);
}
@@ -1396,7 +1458,7 @@ float mat4_to_scale(float mat[4][4])
{
/* unit length vector */
float unit_vec[3];
- copy_v3_fl(unit_vec, (float)(1.0 / M_SQRT3));
+ copy_v3_fl(unit_vec, (float)M_SQRT1_3);
mul_mat3_m4_v3(mat, unit_vec);
return len_v3(unit_vec);
}
@@ -1413,9 +1475,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
/* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */
normalize_m3_m3(mat3_n, mat3);
if (is_negative_m3(mat3)) {
- negate_v3(mat3_n[0]);
- negate_v3(mat3_n[1]);
- negate_v3(mat3_n[2]);
+ negate_m3(mat3_n);
}
/* rotation */
@@ -1425,11 +1485,19 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
/* scale */
/* note: mat4_to_size(ob->size, mat) fails for negative scale */
invert_m3_m3(imat3_n, mat3_n);
+
+ /* better not edit mat3 */
+#if 0
mul_m3_m3m3(mat3, imat3_n, mat3);
size[0] = mat3[0][0];
size[1] = mat3[1][1];
size[2] = mat3[2][2];
+#else
+ size[0] = dot_m3_v3_row_x(imat3_n, mat3[0]);
+ size[1] = dot_m3_v3_row_y(imat3_n, mat3[1]);
+ size[2] = dot_m3_v3_row_z(imat3_n, mat3[2]);
+#endif
}
void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4])
@@ -1454,9 +1522,7 @@ void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4])
/* so scale doesn't interfere with rotation [#24291] */
/* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */
if (is_negative_m3(mat3)) {
- negate_v3(mat3_n[0]);
- negate_v3(mat3_n[1]);
- negate_v3(mat3_n[2]);
+ negate_m3(mat3_n);
}
mat3_to_quat(quat, mat3_n);
@@ -2183,14 +2249,14 @@ void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4])
}
}
-void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon)
+void pseudoinverse_m4_m4(float Ainv[4][4], float A_[4][4], float epsilon)
{
/* compute moon-penrose pseudo inverse of matrix, singular values
* below epsilon are ignored for stability (truncated SVD) */
- float V[4][4], W[4], Wm[4][4], U[4][4];
+ float A[4][4], V[4][4], W[4], Wm[4][4], U[4][4];
int i;
- transpose_m4(A);
+ transpose_m4_m4(A, A_);
svd_m4(V, W, U, A);
transpose_m4(U);
transpose_m4(V);
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 9a6515daf68..3d5d47bc2e0 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -1016,6 +1016,40 @@ void angle_to_mat2(float mat[2][2], const float angle)
mat[1][1] = angle_cos;
}
+/****************************** Exponential Map ******************************/
+
+void quat_normalized_to_expmap(float expmap[3], const float q[4])
+{
+ float angle;
+ BLI_ASSERT_UNIT_QUAT(q);
+
+ /* Obtain axis/angle representation. */
+ quat_to_axis_angle(expmap, &angle, q);
+
+ /* Convert to exponential map. */
+ mul_v3_fl(expmap, angle);
+}
+
+void quat_to_expmap(float expmap[3], const float q[4])
+{
+ float q_no[4];
+ normalize_qt_qt(q_no, q);
+ quat_normalized_to_expmap(expmap, q_no);
+}
+
+void expmap_to_quat(float r[4], const float expmap[3])
+{
+ float axis[3];
+ float angle;
+
+ /* Obtain axis/angle representation. */
+ angle = normalize_v3_v3(axis, expmap);
+ angle = angle_wrap_rad(angle);
+
+ /* Convert to quaternion. */
+ axis_angle_to_quat(r, axis, angle);
+}
+
/******************************** XYZ Eulers *********************************/
/* XYZ order */
@@ -1867,7 +1901,7 @@ float angle_wrap_deg(float angle)
/* returns an angle compatible with angle_compat */
float angle_compat_rad(float angle, float angle_compat)
{
- return angle + (floorf(((angle_compat - angle) / (float)M_PI) + 0.5f)) * (float)M_PI;
+ return angle_compat + angle_wrap_rad(angle - angle_compat);
}
/* axis conversion */
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 887ec7d4d2c..814180bba24 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -252,6 +252,13 @@ void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float
v[2] = (v1[2] + v2[2] + v3[2]) / 3.0f;
}
+void mid_v3_v3v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+{
+ v[0] = (v1[0] + v2[0] + v3[0] + v4[0]) / 4.0f;
+ v[1] = (v1[1] + v2[1] + v3[1] + v4[1]) / 4.0f;
+ v[2] = (v1[2] + v2[2] + v3[2] + v4[2]) / 4.0f;
+}
+
/**
* Specialized function for calculating normals.
* fastpath for:
@@ -757,6 +764,13 @@ void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
if (max[1] < vec[1]) max[1] = vec[1];
}
+void minmax_v3v3_v3_array(float r_min[3], float r_max[3], float (*vec_arr)[3], int nbr)
+{
+ while (nbr--) {
+ minmax_v3v3_v3(r_min, r_max, *vec_arr++);
+ }
+}
+
/** ensure \a v1 is \a dist from \a v2 */
void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist)
{
@@ -1033,6 +1047,15 @@ void fill_vn_ushort(unsigned short *array_tar, const int size, const unsigned sh
}
}
+void fill_vn_uchar(unsigned char *array_tar, const int size, const unsigned char val)
+{
+ unsigned char *tar = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = val;
+ }
+}
+
void fill_vn_fl(float *array_tar, const int size, const float val)
{
float *tar = array_tar + (size - 1);
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index da9d5bd3f49..6b6a3113e0b 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -621,6 +621,18 @@ MINLINE float dot_v3v3(const float a[3], const float b[3])
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
+MINLINE float dot_v3v3v3(const float p[3], const float a[3], const float b[3])
+{
+ float vec1[3], vec2[3];
+
+ sub_v3_v3v3(vec1, a, p);
+ sub_v3_v3v3(vec2, b, p);
+ if (is_zero_v3(vec1) || is_zero_v3(vec2)) {
+ return 0.0f;
+ }
+ return dot_v3v3(vec1, vec2);
+}
+
MINLINE float dot_v4v4(const float a[4], const float b[4])
{
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index f002ea54b32..5febf720b30 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -278,8 +278,8 @@ static float npfade(float t)
static float grad(int hash_val, float x, float y, float z)
{
int h = hash_val & 15; /* CONVERT LO 4 BITS OF HASH CODE */
- float u = h < 8 ? x : y, /* INTO 12 GRADIENT DIRECTIONS. */
- v = h < 4 ? y : h == 12 || h == 14 ? x : z;
+ float u = h < 8 ? x : y; /* INTO 12 GRADIENT DIRECTIONS. */
+ float v = h < 4 ? y : h == 12 || h == 14 ? x : z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index d5af980e373..72739018399 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -45,12 +45,6 @@
#include "BLI_string_utf8.h"
#include "BLI_fnmatch.h"
-#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */
-
-#include "GHOST_Path-api.h"
-
-#include "MEM_guardedalloc.h"
-
#ifdef WIN32
# include "utf_winfunc.h"
# include "utfconv.h"
@@ -62,21 +56,12 @@
# include <windows.h>
# include <shlobj.h>
# include "BLI_winstuff.h"
-#else /* non windows */
-# ifdef WITH_BINRELOC
-# include "binreloc.h"
-# endif
-# include <unistd.h> /* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */
+# include "MEM_guardedalloc.h"
#endif /* WIN32 */
/* local */
#define UNIQUE_NAME_MAX 128
-static char bprogname[FILE_MAX]; /* full path to program executable */
-static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */
-static char btempdir_base[FILE_MAX]; /* persistent temporary directory */
-static char btempdir_session[FILE_MAX] = ""; /* volatile temporary directory */
-
/* implementation */
/**
@@ -243,7 +228,8 @@ bool BLI_uniquename_cb(bool (*unique_check)(void *arg, const char *name),
int number;
int len = BLI_split_name_num(left, &number, name, delim);
do {
- const int numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number);
+ /* add 1 to account for \0 */
+ const int numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number) + 1;
/* highly unlikely the string only has enough room for the number
* but support anyway */
@@ -253,9 +239,8 @@ bool BLI_uniquename_cb(bool (*unique_check)(void *arg, const char *name),
}
else {
char *tempname_buf;
- tempname[0] = '\0';
- tempname_buf = BLI_strncat_utf8(tempname, left, name_len - numlen);
- memcpy(tempname_buf, numstr, numlen + 1);
+ tempname_buf = tempname + BLI_strncpy_utf8_rlen(tempname, left, name_len - numlen);
+ memcpy(tempname_buf, numstr, numlen);
}
} while (unique_check(arg, tempname));
@@ -305,7 +290,7 @@ static bool uniquename_unique_check(void *arg, const char *name)
/**
* Ensures that the specified block has a unique name within the containing list,
- * incrementing its numeric suffix as necessary.
+ * incrementing its numeric suffix as necessary. Returns true if name had to be adjusted.
*
* \param list List containing the block
* \param vlink The block to check the name for
@@ -314,7 +299,7 @@ static bool uniquename_unique_check(void *arg, const char *name)
* \param name_offs Offset of name within block structure
* \param name_len Maximum length of name area
*/
-void BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim, int name_offs, int name_len)
+bool BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim, int name_offs, int name_len)
{
struct {ListBase *lb; void *vlink; int name_offs; } data;
data.lb = list;
@@ -325,9 +310,9 @@ void BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim
/* See if we are given an empty string */
if (ELEM(NULL, vlink, defname))
- return;
+ return false;
- BLI_uniquename_cb(uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
+ return BLI_uniquename_cb(uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
}
static int BLI_path_unc_prefix_len(const char *path); /* defined below in same file */
@@ -361,7 +346,7 @@ void BLI_cleanup_path(const char *relabase, char *path)
/* Note
* memmove(start, eind, strlen(eind) + 1);
* is the same as
- * strcpy( start, eind );
+ * strcpy(start, eind);
* except strcpy should not be used because there is overlap,
* so use memmove's slightly more obscure syntax - Campbell
*/
@@ -443,6 +428,23 @@ void BLI_cleanup_file(const char *relabase, char *path)
BLI_del_slash(path);
}
+
+/**
+ * Make given name safe to be used in paths.
+ *
+ * For now, simply replaces reserved chars (as listed in
+ * http://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words )
+ * by underscores ('_').
+ */
+void BLI_filename_make_safe(char *fname)
+{
+ const char *invalid = "/\\?%*:|\"<>. ";
+
+ for (; *fname && (fname = strpbrk(fname, invalid)); fname++) {
+ *fname = '_';
+ }
+}
+
/**
* Does path begin with the special "//" prefix that Blender uses to indicate
* a path relative to the .blend file.
@@ -954,8 +956,6 @@ bool BLI_path_abs(char *path, const char *basepath)
BLI_strncpy(path, tmp, FILE_MAX);
}
- BLI_cleanup_path(NULL, path);
-
#ifdef WIN32
/* skip first two chars, which in case of
* absolute path will be drive:/blabla and
@@ -965,7 +965,10 @@ bool BLI_path_abs(char *path, const char *basepath)
*/
BLI_char_switch(path + 2, '/', '\\');
#endif
-
+
+ /* ensure this is after correcting for path switch */
+ BLI_cleanup_path(NULL, path);
+
return wasrelative;
}
@@ -1038,446 +1041,6 @@ void BLI_getlastdir(const char *dir, char *last, const size_t maxlen)
}
}
-/* This is now only used to really get the user's default document folder */
-/* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used
- * as default location to save documents */
-const char *BLI_getDefaultDocumentFolder(void)
-{
-#ifndef WIN32
- const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR");
-
- if (xdg_documents_dir)
- return xdg_documents_dir;
-
- return getenv("HOME");
-#else /* Windows */
- static char documentfolder[MAXPATHLEN];
- HRESULT hResult;
-
- /* Check for %HOME% env var */
- if (uput_getenv("HOME", documentfolder, MAXPATHLEN)) {
- if (BLI_is_dir(documentfolder)) return documentfolder;
- }
-
- /* add user profile support for WIN 2K / NT.
- * This is %APPDATA%, which translates to either
- * %USERPROFILE%\Application Data or since Vista
- * to %USERPROFILE%\AppData\Roaming
- */
- hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder);
-
- if (hResult == S_OK) {
- if (BLI_is_dir(documentfolder)) return documentfolder;
- }
-
- return NULL;
-#endif /* WIN32 */
-}
-
-/* NEW stuff, to be cleaned up when fully migrated */
-/* ************************************************************* */
-/* ************************************************************* */
-
-// #define PATH_DEBUG
-
-/* returns a formatted representation of the specified version number. Non-reentrant! */
-static char *blender_version_decimal(const int ver)
-{
- static char version_str[5];
- sprintf(version_str, "%d.%02d", ver / 100, ver % 100);
- return version_str;
-}
-
-/**
- * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath,
- * returning true if result points to a directory.
- */
-static bool test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name)
-{
- char tmppath[FILE_MAX];
-
- if (path_sep) BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep);
- else BLI_strncpy(tmppath, path_base, sizeof(tmppath));
-
- /* rare cases folder_name is omitted (when looking for ~/.blender/2.xx dir only) */
- if (folder_name)
- BLI_make_file_string("/", targetpath, tmppath, folder_name);
- else
- BLI_strncpy(targetpath, tmppath, sizeof(tmppath));
- /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile)
- * if folder_name is specified but not otherwise? */
-
- if (BLI_is_dir(targetpath)) {
-#ifdef PATH_DEBUG
- printf("\t%s found: %s\n", __func__, targetpath);
-#endif
- return true;
- }
- else {
-#ifdef PATH_DEBUG
- printf("\t%s missing: %s\n", __func__, targetpath);
-#endif
- //targetpath[0] = '\0';
- return false;
- }
-}
-
-/**
- * Puts the value of the specified environment variable into *path if it exists
- * and points at a directory. Returns true if this was done.
- */
-static bool test_env_path(char *path, const char *envvar)
-{
- const char *env = envvar ? getenv(envvar) : NULL;
- if (!env) return false;
-
- if (BLI_is_dir(env)) {
- BLI_strncpy(path, env, FILE_MAX);
-#ifdef PATH_DEBUG
- printf("\t%s env %s found: %s\n", __func__, envvar, env);
-#endif
- return true;
- }
- else {
- path[0] = '\0';
-#ifdef PATH_DEBUG
- printf("\t%s env %s missing: %s\n", __func__, envvar, env);
-#endif
- return false;
- }
-}
-
-/**
- * Constructs in \a targetpath the name of a directory relative to a version-specific
- * subdirectory in the parent directory of the Blender executable.
- *
- * \param targetpath String to return path
- * \param folder_name Optional folder name within version-specific directory
- * \param subfolder_name Optional subfolder name within folder_name
- * \param ver To construct name of version-specific directory within bprogdir
- * \return true if such a directory exists.
- */
-static bool get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver)
-{
- char relfolder[FILE_MAX];
-
-#ifdef PATH_DEBUG
- printf("%s...\n", __func__);
-#endif
-
- if (folder_name) {
- if (subfolder_name) {
- BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name);
- }
- else {
- BLI_strncpy(relfolder, folder_name, sizeof(relfolder));
- }
- }
- else {
- relfolder[0] = '\0';
- }
-
- /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */
-#ifdef __APPLE__
- static char osx_resourses[FILE_MAX]; /* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */
- sprintf(osx_resourses, "%s../Resources", bprogdir);
- return test_path(targetpath, osx_resourses, blender_version_decimal(ver), relfolder);
-#else
- return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder);
-#endif
-}
-
-/**
- * Is this an install with user files kept together with the Blender executable and its
- * installation files.
- */
-static bool is_portable_install(void)
-{
- /* detect portable install by the existence of config folder */
- const int ver = BLENDER_VERSION;
- char path[FILE_MAX];
-
- return get_path_local(path, "config", NULL, ver);
-}
-
-/**
- * Returns the path of a folder within the user-files area.
- *
- *
- * \param targetpath String to return path
- * \param folder_name default name of folder within user area
- * \param subfolder_name optional name of subfolder within folder
- * \param envvar name of environment variable which, if defined, overrides folder_name
- * \param ver Blender version, used to construct a subdirectory name
- * \return true if it was able to construct such a path.
- */
-static bool get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
-{
- char user_path[FILE_MAX];
- const char *user_base_path;
-
- /* for portable install, user path is always local */
- if (is_portable_install())
- return get_path_local(targetpath, folder_name, subfolder_name, ver);
-
- user_path[0] = '\0';
-
- if (test_env_path(user_path, envvar)) {
- if (subfolder_name) {
- return test_path(targetpath, user_path, NULL, subfolder_name);
- }
- else {
- BLI_strncpy(targetpath, user_path, FILE_MAX);
- return true;
- }
- }
-
- user_base_path = (const char *)GHOST_getUserDir(ver, blender_version_decimal(ver));
- if (user_base_path)
- BLI_strncpy(user_path, user_base_path, FILE_MAX);
-
- if (!user_path[0])
- return false;
-
-#ifdef PATH_DEBUG
- printf("%s: %s\n", __func__, user_path);
-#endif
-
- if (subfolder_name) {
- return test_path(targetpath, user_path, folder_name, subfolder_name);
- }
- else {
- return test_path(targetpath, user_path, NULL, folder_name);
- }
-}
-
-/**
- * Returns the path of a folder within the Blender installation directory.
- *
- * \param targetpath String to return path
- * \param folder_name default name of folder within installation area
- * \param subfolder_name optional name of subfolder within folder
- * \param envvar name of environment variable which, if defined, overrides folder_name
- * \param ver Blender version, used to construct a subdirectory name
- * \return true if it was able to construct such a path.
- */
-static bool get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
-{
- char system_path[FILE_MAX];
- const char *system_base_path;
- char cwd[FILE_MAX];
- char relfolder[FILE_MAX];
-
- if (folder_name) {
- if (subfolder_name) {
- BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name);
- }
- else {
- BLI_strncpy(relfolder, folder_name, sizeof(relfolder));
- }
- }
- else {
- relfolder[0] = '\0';
- }
-
- /* first allow developer only overrides to the system path
- * these are only used when running blender from source */
-
- /* try CWD/release/folder_name */
- if (BLI_current_working_dir(cwd, sizeof(cwd))) {
- if (test_path(targetpath, cwd, "release", relfolder)) {
- return true;
- }
- }
-
- /* try EXECUTABLE_DIR/release/folder_name */
- if (test_path(targetpath, bprogdir, "release", relfolder))
- return true;
-
- /* end developer overrides */
-
-
-
- system_path[0] = '\0';
-
- if (test_env_path(system_path, envvar)) {
- if (subfolder_name) {
- return test_path(targetpath, system_path, NULL, subfolder_name);
- }
- else {
- BLI_strncpy(targetpath, system_path, FILE_MAX);
- return true;
- }
- }
-
- system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver));
- if (system_base_path)
- BLI_strncpy(system_path, system_base_path, FILE_MAX);
-
- if (!system_path[0])
- return false;
-
-#ifdef PATH_DEBUG
- printf("%s: %s\n", __func__, system_path);
-#endif
-
- if (subfolder_name) {
- /* try $BLENDERPATH/folder_name/subfolder_name */
- return test_path(targetpath, system_path, folder_name, subfolder_name);
- }
- else {
- /* try $BLENDERPATH/folder_name */
- return test_path(targetpath, system_path, NULL, folder_name);
- }
-}
-
-/* get a folder out of the 'folder_id' presets for paths */
-/* returns the path if found, NULL string if not */
-const char *BLI_get_folder(int folder_id, const char *subfolder)
-{
- const int ver = BLENDER_VERSION;
- static char path[FILE_MAX] = "";
-
- switch (folder_id) {
- case BLENDER_DATAFILES: /* general case */
- if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
- if (get_path_local(path, "datafiles", subfolder, ver)) break;
- if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break;
- return NULL;
-
- case BLENDER_USER_DATAFILES:
- if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
- return NULL;
-
- case BLENDER_SYSTEM_DATAFILES:
- if (get_path_local(path, "datafiles", subfolder, ver)) break;
- if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break;
- return NULL;
-
- case BLENDER_USER_AUTOSAVE:
- if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
- return NULL;
-
- case BLENDER_USER_CONFIG:
- if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver)) break;
- return NULL;
-
- case BLENDER_USER_SCRIPTS:
- if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver)) break;
- return NULL;
-
- case BLENDER_SYSTEM_SCRIPTS:
- if (get_path_local(path, "scripts", subfolder, ver)) break;
- if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS", ver)) break;
- return NULL;
-
- case BLENDER_SYSTEM_PYTHON:
- if (get_path_local(path, "python", subfolder, ver)) break;
- if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break;
- return NULL;
-
- default:
- BLI_assert(0);
- break;
- }
-
- return path;
-}
-
-/**
- * Returns the path to a folder in the user area without checking that it actually exists first.
- */
-const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
-{
- const int ver = BLENDER_VERSION;
- static char path[FILE_MAX] = "";
-
- switch (folder_id) {
- case BLENDER_USER_DATAFILES:
- get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver);
- break;
- case BLENDER_USER_CONFIG:
- get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver);
- break;
- case BLENDER_USER_AUTOSAVE:
- get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE", ver);
- break;
- case BLENDER_USER_SCRIPTS:
- get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver);
- break;
- default:
- BLI_assert(0);
- break;
- }
-
- if ('\0' == path[0]) {
- return NULL;
- }
- return path;
-}
-
-/**
- * Returns the path to a folder in the user area, creating it if it doesn't exist.
- */
-const char *BLI_get_folder_create(int folder_id, const char *subfolder)
-{
- const char *path;
-
- /* only for user folders */
- if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE))
- return NULL;
-
- path = BLI_get_folder(folder_id, subfolder);
-
- if (!path) {
- path = BLI_get_user_folder_notest(folder_id, subfolder);
- if (path) BLI_dir_create_recursive(path);
- }
-
- return path;
-}
-
-/**
- * Returns the path of the top-level version-specific local, user or system directory.
- * If do_check, then the result will be NULL if the directory doesn't exist.
- */
-const char *BLI_get_folder_version(const int id, const int ver, const bool do_check)
-{
- static char path[FILE_MAX] = "";
- bool ok;
- switch (id) {
- case BLENDER_RESOURCE_PATH_USER:
- ok = get_path_user(path, NULL, NULL, NULL, ver);
- break;
- case BLENDER_RESOURCE_PATH_LOCAL:
- ok = get_path_local(path, NULL, NULL, ver);
- break;
- case BLENDER_RESOURCE_PATH_SYSTEM:
- ok = get_path_system(path, NULL, NULL, NULL, ver);
- break;
- default:
- path[0] = '\0'; /* in case do_check is false */
- ok = false;
- BLI_assert(!"incorrect ID");
- break;
- }
-
- if (!ok && do_check) {
- return NULL;
- }
-
- return path;
-}
-
-/* End new stuff */
-/* ************************************************************* */
-/* ************************************************************* */
-
-
-
-#ifdef PATH_DEBUG
-# undef PATH_DEBUG
-#endif
/**
* Sets the specified environment variable to the specified value,
@@ -1541,18 +1104,22 @@ void BLI_char_switch(char *string, char from, char to)
}
/**
- * Strips off nonexistent subdirectories from the end of *dir, leaving the path of
- * the lowest-level directory that does exist.
+ * Strips off nonexistent (or non-accessible) subdirectories from the end of *dir, leaving the path of
+ * the lowest-level directory that does exist and we can read.
*/
void BLI_make_exist(char *dir)
{
int a;
+ char par_path[PATH_MAX + 3];
BLI_char_switch(dir, ALTSEP, SEP);
a = strlen(dir);
- while (!BLI_is_dir(dir)) {
+ for (BLI_join_dirfile(par_path, sizeof(par_path), dir, FILENAME_PARENT);
+ !(BLI_is_dir(dir) && BLI_exists(par_path));
+ BLI_join_dirfile(par_path, sizeof(par_path), dir, FILENAME_PARENT))
+ {
a--;
while (dir[a] != SEP) {
a--;
@@ -1580,7 +1147,7 @@ void BLI_make_existing_file(const char *name)
char di[FILE_MAX];
BLI_split_dir_part(name, di, sizeof(di));
- /* make if if the dir doesn't exist */
+ /* make if the dir doesn't exist */
BLI_dir_create_recursive(di);
}
@@ -1707,11 +1274,10 @@ bool BLI_testextensie_n(const char *str, ...)
while ((ext = (const char *) va_arg(args, void *))) {
if (testextensie_ex(str, str_len, ext, strlen(ext))) {
ret = true;
- goto finally;
+ break;
}
}
-finally:
va_end(args);
return ret;
@@ -1803,9 +1369,7 @@ bool BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
ssize_t a;
/* first check the extension is already there */
- if ( (ext_len <= path_len) &&
- (strcmp(path + (path_len - ext_len), ext) == 0))
- {
+ if ((ext_len <= path_len) && (STREQ(path + (path_len - ext_len), ext))) {
return true;
}
@@ -2153,310 +1717,6 @@ void BLI_path_native_slash(char *path)
#endif
}
-/**
- * Tries appending each of the semicolon-separated extensions in the PATHEXT
- * environment variable (Windows-only) onto *name in turn until such a file is found.
- * Returns success/failure.
- */
-static int add_win32_extension(char *name)
-{
- int retval = 0;
- int type;
-
- type = BLI_exists(name);
- if ((type == 0) || S_ISDIR(type)) {
-#ifdef _WIN32
- char filename[FILE_MAX];
- char ext[FILE_MAX];
- const char *extensions = getenv("PATHEXT");
- if (extensions) {
- char *temp;
- do {
- strcpy(filename, name);
- temp = strstr(extensions, ";");
- if (temp) {
- strncpy(ext, extensions, temp - extensions);
- ext[temp - extensions] = 0;
- extensions = temp + 1;
- strcat(filename, ext);
- }
- else {
- strcat(filename, extensions);
- }
-
- type = BLI_exists(filename);
- if (type && (!S_ISDIR(type))) {
- retval = 1;
- strcpy(name, filename);
- break;
- }
- } while (temp);
- }
-#endif
- }
- else {
- retval = 1;
- }
-
- return (retval);
-}
-
-/**
- * Checks if name is a fully qualified filename to an executable.
- * If not it searches $PATH for the file. On Windows it also
- * adds the correct extension (.com .exe etc) from
- * $PATHEXT if necessary. Also on Windows it translates
- * the name to its 8.3 version to prevent problems with
- * spaces and stuff. Final result is returned in fullname.
- *
- * \param fullname The full path and full name of the executable
- * (must be FILE_MAX minimum)
- * \param name The name of the executable (usually argv[0]) to be checked
- */
-static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name)
-{
- char filename[FILE_MAX];
- const char *path = NULL, *temp;
-
-#ifdef _WIN32
- const char *separator = ";";
-#else
- const char *separator = ":";
-#endif
-
-
-#ifdef WITH_BINRELOC
- /* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */
- path = br_find_exe(NULL);
- if (path) {
- BLI_strncpy(fullname, path, maxlen);
- free((void *)path);
- return;
- }
-#endif
-
-#ifdef _WIN32
- wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath");
- if (GetModuleFileNameW(0, fullname_16, maxlen)) {
- conv_utf_16_to_8(fullname_16, fullname, maxlen);
- if (!BLI_exists(fullname)) {
- printf("path can't be found: \"%.*s\"\n", (int)maxlen, fullname);
- MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK);
- }
- MEM_freeN(fullname_16);
- return;
- }
-
- MEM_freeN(fullname_16);
-#endif
-
- /* unix and non linux */
- if (name && name[0]) {
-
- BLI_strncpy(fullname, name, maxlen);
- if (name[0] == '.') {
- char wdir[FILE_MAX] = "";
- BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */
-
- // not needed but avoids annoying /./ in name
- if (name[1] == SEP)
- BLI_join_dirfile(fullname, maxlen, wdir, name + 2);
- else
- BLI_join_dirfile(fullname, maxlen, wdir, name);
-
- add_win32_extension(fullname); /* XXX, doesnt respect length */
- }
- else if (BLI_last_slash(name)) {
- // full path
- BLI_strncpy(fullname, name, maxlen);
- add_win32_extension(fullname);
- }
- else {
- // search for binary in $PATH
- path = getenv("PATH");
- if (path) {
- do {
- temp = strstr(path, separator);
- if (temp) {
- strncpy(filename, path, temp - path);
- filename[temp - path] = 0;
- path = temp + 1;
- }
- else {
- strncpy(filename, path, sizeof(filename));
- }
- BLI_path_append(fullname, maxlen, name);
- if (add_win32_extension(filename)) {
- BLI_strncpy(fullname, filename, maxlen);
- break;
- }
- } while (temp);
- }
- }
-#if defined(DEBUG)
- if (strcmp(name, fullname)) {
- printf("guessing '%s' == '%s'\n", name, fullname);
- }
-#endif
- }
-}
-
-void BLI_init_program_path(const char *argv0)
-{
- bli_where_am_i(bprogname, sizeof(bprogname), argv0);
- BLI_split_dir_part(bprogname, bprogdir, sizeof(bprogdir));
-}
-
-/**
- * Path to executable
- */
-const char *BLI_program_path(void)
-{
- return bprogname;
-}
-
-/**
- * Path to directory of executable
- */
-const char *BLI_program_dir(void)
-{
- return bprogdir;
-}
-
-/**
- * Gets the temp directory when blender first runs.
- * If the default path is not found, use try $TEMP
- *
- * Also make sure the temp dir has a trailing slash
- *
- * \param fullname The full path to the temporary temp directory
- * \param basename The full path to the persistent temp directory (may be NULL)
- * \param maxlen The size of the fullname buffer
- * \param userdir Directory specified in user preferences
- */
-static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir)
-{
- /* Clear existing temp dir, if needed. */
- BLI_temp_dir_session_purge();
-
- fullname[0] = '\0';
- if (basename) {
- basename[0] = '\0';
- }
-
- if (userdir && BLI_is_dir(userdir)) {
- BLI_strncpy(fullname, userdir, maxlen);
- }
-
-
-#ifdef WIN32
- if (fullname[0] == '\0') {
- const char *tmp = getenv("TEMP"); /* Windows */
- if (tmp && BLI_is_dir(tmp)) {
- BLI_strncpy(fullname, tmp, maxlen);
- }
- }
-#else
- /* Other OS's - Try TMP and TMPDIR */
- if (fullname[0] == '\0') {
- const char *tmp = getenv("TMP");
- if (tmp && BLI_is_dir(tmp)) {
- BLI_strncpy(fullname, tmp, maxlen);
- }
- }
-
- if (fullname[0] == '\0') {
- const char *tmp = getenv("TMPDIR");
- if (tmp && BLI_is_dir(tmp)) {
- BLI_strncpy(fullname, tmp, maxlen);
- }
- }
-#endif
-
- if (fullname[0] == '\0') {
- BLI_strncpy(fullname, "/tmp/", maxlen);
- }
- else {
- /* add a trailing slash if needed */
- BLI_add_slash(fullname);
-#ifdef WIN32
- if (userdir && userdir != fullname) {
- BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */
- }
-#endif
- }
-
- /* Now that we have a valid temp dir, add system-generated unique sub-dir. */
- if (basename) {
- /* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */
- char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX");
- const size_t ln = strlen(tmp_name) + 1;
- if (ln <= maxlen) {
-#ifdef WIN32
- if (_mktemp_s(tmp_name, ln) == 0) {
- BLI_dir_create_recursive(tmp_name);
- }
-#else
- mkdtemp(tmp_name);
-#endif
- }
- if (BLI_is_dir(tmp_name)) {
- BLI_strncpy(basename, fullname, maxlen);
- BLI_strncpy(fullname, tmp_name, maxlen);
- BLI_add_slash(fullname);
- }
- else {
- printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname);
- }
-
- MEM_freeN(tmp_name);
- }
-}
-
-/**
- * Sets btempdir_base to userdir if specified and is a valid directory, otherwise
- * chooses a suitable OS-specific temporary directory.
- * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base.
- */
-void BLI_temp_dir_init(char *userdir)
-{
- BLI_where_is_temp(btempdir_session, btempdir_base, FILE_MAX, userdir);
-;
-}
-
-/**
- * Path to temporary directory (with trailing slash)
- */
-const char *BLI_temp_dir_session(void)
-{
- return btempdir_session[0] ? btempdir_session : BLI_temp_dir_base();
-}
-
-/**
- * Path to persistent temporary directory (with trailing slash)
- */
-const char *BLI_temp_dir_base(void)
-{
- return btempdir_base;
-}
-
-/**
- * Path to the system temporary directory (with trailing slash)
- */
-void BLI_system_temporary_dir(char *dir)
-{
- BLI_where_is_temp(dir, NULL, FILE_MAX, NULL);
-}
-
-/**
- * Delete content of this instance's temp dir.
- */
-void BLI_temp_dir_session_purge(void)
-{
- if (btempdir_session[0] && BLI_is_dir(btempdir_session)) {
- BLI_delete(btempdir_session, true, true);
- }
-}
#ifdef WITH_ICONV
diff --git a/source/blender/blenlib/intern/polyfill2d.c b/source/blender/blenlib/intern/polyfill2d.c
index 16cf7ff960b..3aadbe5f1df 100644
--- a/source/blender/blenlib/intern/polyfill2d.c
+++ b/source/blender/blenlib/intern/polyfill2d.c
@@ -165,7 +165,7 @@ static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip);
static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip);
-BLI_INLINE eSign signum_i(float a)
+BLI_INLINE eSign signum_enum(float a)
{
if (UNLIKELY(a == 0.0f))
return 0;
@@ -191,7 +191,7 @@ BLI_INLINE float area_tri_signed_v2_alt_2x(const float v1[2], const float v2[2],
static eSign span_tri_v2_sign(const float v1[2], const float v2[2], const float v3[2])
{
- return signum_i(area_tri_signed_v2_alt_2x(v3, v2, v1));
+ return signum_enum(area_tri_signed_v2_alt_2x(v3, v2, v1));
}
diff --git a/source/blender/blenlib/intern/polyfill2d_beautify.c b/source/blender/blenlib/intern/polyfill2d_beautify.c
new file mode 100644
index 00000000000..ba71f52b530
--- /dev/null
+++ b/source/blender/blenlib/intern/polyfill2d_beautify.c
@@ -0,0 +1,493 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenlib/intern/polyfill2d_beautify.c
+ * \ingroup bli
+ *
+ * This function is to improve the tessellation resulting from polyfill2d,
+ * creating optimal topology.
+ *
+ * The functionality here matches #BM_mesh_beautify_fill,
+ * but its far simpler to perform this operation in 2d,
+ * on a simple polygon representation where we _know_:
+ *
+ * - The polygon is primitive with no holes with a continuous boundary.
+ * - Tris have consistent winding.
+ * - 2d (saves some hassles projecting face pairs on an axis for every edge-rotation)
+ * also saves us having to store all previous edge-states (see #EdRotState in bmesh_beautify.c)
+ *
+ * \note
+ *
+ * No globals - keep threadsafe.
+ */
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "BLI_memarena.h"
+#include "BLI_edgehash.h"
+#include "BLI_heap.h"
+
+#include "BLI_polyfill2d_beautify.h" /* own include */
+
+#include "BLI_strict_flags.h"
+
+struct PolyEdge {
+ /** ordered vert indices (smaller first) */
+ unsigned int verts[2];
+ /** ordered face indices (depends on winding compared to the edge verts)
+ * - (verts[0], verts[1]) == faces[0]
+ * - (verts[1], verts[0]) == faces[1]
+ */
+ unsigned int faces[2];
+ /**
+ * The face-index which isn't used by either of the edges verts [0 - 2].
+ * could be calculated each time, but cleaner to store for reuse.
+ */
+ unsigned int faces_other_v[2];
+};
+
+
+#ifndef NDEBUG
+/**
+ * Only to check for error-cases.
+ */
+static void polyfill_validate_tri(unsigned int (*tris)[3], unsigned int tri_index, EdgeHash *ehash)
+{
+ const unsigned int *tri = tris[tri_index];
+ int j_curr;
+
+ BLI_assert(!ELEM(tri[0], tri[1], tri[2]) &&
+ !ELEM(tri[1], tri[0], tri[2]) &&
+ !ELEM(tri[2], tri[0], tri[1]));
+
+ for (j_curr = 0; j_curr < 3; j_curr++) {
+ struct PolyEdge *e;
+ unsigned int e_v1 = tri[(j_curr ) ];
+ unsigned int e_v2 = tri[(j_curr + 1) % 3];
+ e = BLI_edgehash_lookup(ehash, e_v1, e_v2);
+ if (e) {
+ if (e->faces[0] == tri_index) {
+ BLI_assert(e->verts[0] == e_v1);
+ BLI_assert(e->verts[1] == e_v2);
+ }
+ else if (e->faces[1] == tri_index) {
+ BLI_assert(e->verts[0] == e_v2);
+ BLI_assert(e->verts[1] == e_v1);
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ BLI_assert(e->faces[0] != e->faces[1]);
+ BLI_assert(ELEM(e_v1, UNPACK3(tri)));
+ BLI_assert(ELEM(e_v2, UNPACK3(tri)));
+ BLI_assert(ELEM(e_v1, UNPACK2(e->verts)));
+ BLI_assert(ELEM(e_v2, UNPACK2(e->verts)));
+ BLI_assert(e_v1 != tris[e->faces[0]][e->faces_other_v[0]]);
+ BLI_assert(e_v1 != tris[e->faces[1]][e->faces_other_v[1]]);
+ BLI_assert(e_v2 != tris[e->faces[0]][e->faces_other_v[0]]);
+ BLI_assert(e_v2 != tris[e->faces[1]][e->faces_other_v[1]]);
+
+ BLI_assert(ELEM(tri_index, UNPACK2(e->faces)));
+ }
+ }
+}
+#endif
+
+BLI_INLINE bool is_boundary_edge(unsigned int i_a, unsigned int i_b, const unsigned int coord_last)
+{
+ BLI_assert(i_a < i_b);
+ return ((i_a + 1 == i_b) || UNLIKELY((i_a == 0) && (i_b == coord_last)));
+}
+/**
+ * Assuming we have 2 triangles sharing an edge (2 - 4),
+ * check if the edge running from (1 - 3) gives better results.
+ *
+ * \return (negative number means the edge can be rotated, lager == better).
+ */
+float BLI_polyfill_beautify_quad_rotate_calc(
+ const float v1[2], const float v2[2], const float v3[2], const float v4[2])
+{
+ /* not a loop (only to be able to break out) */
+ do {
+ bool is_zero_a, is_zero_b;
+
+ const float area_2x_234 = cross_tri_v2(v2, v3, v4);
+ const float area_2x_241 = cross_tri_v2(v2, v4, v1);
+
+ const float area_2x_123 = cross_tri_v2(v1, v2, v3);
+ const float area_2x_134 = cross_tri_v2(v1, v3, v4);
+
+ {
+ BLI_assert((ELEM(v1, v2, v3, v4) == false) &&
+ (ELEM(v2, v1, v3, v4) == false) &&
+ (ELEM(v3, v1, v2, v4) == false) &&
+ (ELEM(v4, v1, v2, v3) == false));
+
+ is_zero_a = (fabsf(area_2x_234) <= FLT_EPSILON);
+ is_zero_b = (fabsf(area_2x_241) <= FLT_EPSILON);
+
+ if (is_zero_a && is_zero_b) {
+ break;
+ }
+ }
+
+ /* one of the tri's was degenerate, check we're not rotating
+ * into a different degenerate shape or flipping the face */
+ if ((fabsf(area_2x_123) <= FLT_EPSILON) || (fabsf(area_2x_134) <= FLT_EPSILON)) {
+ /* one of the new rotations is degenerate */
+ break;
+ }
+
+ if ((area_2x_123 >= 0.0f) != (area_2x_134 >= 0.0f)) {
+ /* rotation would cause flipping */
+ break;
+ }
+
+ {
+ /* testing rule: the area divided by the perimeter,
+ * check if (1-3) beats the existing (2-4) edge rotation */
+ float area_a, area_b;
+ float prim_a, prim_b;
+ float fac_24, fac_13;
+
+ float len_12, len_23, len_34, len_41, len_24, len_13;
+
+ /* edges around the quad */
+ len_12 = len_v2v2(v1, v2);
+ len_23 = len_v2v2(v2, v3);
+ len_34 = len_v2v2(v3, v4);
+ len_41 = len_v2v2(v4, v1);
+ /* edges crossing the quad interior */
+ len_13 = len_v2v2(v1, v3);
+ len_24 = len_v2v2(v2, v4);
+
+ /* note, area is in fact (area * 2),
+ * but in this case its OK, since we're comparing ratios */
+
+ /* edge (2-4), current state */
+ area_a = fabsf(area_2x_234);
+ area_b = fabsf(area_2x_241);
+ prim_a = len_23 + len_34 + len_24;
+ prim_b = len_41 + len_12 + len_24;
+ fac_24 = (area_a / prim_a) + (area_b / prim_b);
+
+ /* edge (1-3), new state */
+ area_a = fabsf(area_2x_123);
+ area_b = fabsf(area_2x_134);
+ prim_a = len_12 + len_23 + len_13;
+ prim_b = len_34 + len_41 + len_13;
+ fac_13 = (area_a / prim_a) + (area_b / prim_b);
+
+ /* negative number if (1-3) is an improved state */
+ return fac_24 - fac_13;
+ }
+ } while (false);
+
+ return FLT_MAX;
+}
+
+static float polyedge_rotate_beauty_calc(
+ const float (*coords)[2],
+ const unsigned int (*tris)[3],
+ const struct PolyEdge *e)
+{
+ const float *v1, *v2, *v3, *v4;
+
+ v1 = coords[tris[e->faces[0]][e->faces_other_v[0]]];
+ v3 = coords[tris[e->faces[1]][e->faces_other_v[1]]];
+ v2 = coords[e->verts[0]];
+ v4 = coords[e->verts[1]];
+
+ return BLI_polyfill_beautify_quad_rotate_calc(v1, v2, v3, v4);
+}
+
+static void polyedge_beauty_cost_update_single(
+ const float (*coords)[2],
+ const unsigned int (*tris)[3],
+ const struct PolyEdge *edges,
+ struct PolyEdge *e,
+ Heap *eheap, HeapNode **eheap_table)
+{
+ const unsigned int i = (unsigned int)(e - edges);
+
+ if (eheap_table[i]) {
+ BLI_heap_remove(eheap, eheap_table[i]);
+ eheap_table[i] = NULL;
+ }
+
+ {
+ /* recalculate edge */
+ const float cost = polyedge_rotate_beauty_calc(coords, tris, e);
+ /* We can get cases where both choices generate very small negative costs, which leads to infinite loop.
+ * Anyway, costs above that are not worth recomputing, maybe we could even optimize it to a smaller limit?
+ * See T43578. */
+ if (cost < -FLT_EPSILON) {
+ eheap_table[i] = BLI_heap_insert(eheap, cost, e);
+ }
+ else {
+ eheap_table[i] = NULL;
+ }
+ }
+}
+
+static void polyedge_beauty_cost_update(
+ const float (*coords)[2],
+ const unsigned int (*tris)[3],
+ const struct PolyEdge *edges,
+ struct PolyEdge *e,
+ Heap *eheap, HeapNode **eheap_table,
+ EdgeHash *ehash)
+{
+ const unsigned int *tri_0 = tris[e->faces[0]];
+ const unsigned int *tri_1 = tris[e->faces[1]];
+ unsigned int i;
+
+ struct PolyEdge *e_arr[4] = {
+ BLI_edgehash_lookup(ehash,
+ tri_0[(e->faces_other_v[0] ) % 3],
+ tri_0[(e->faces_other_v[0] + 1) % 3]),
+ BLI_edgehash_lookup(ehash,
+ tri_0[(e->faces_other_v[0] + 2) % 3],
+ tri_0[(e->faces_other_v[0] ) % 3]),
+ BLI_edgehash_lookup(ehash,
+ tri_1[(e->faces_other_v[1] ) % 3],
+ tri_1[(e->faces_other_v[1] + 1) % 3]),
+ BLI_edgehash_lookup(ehash,
+ tri_1[(e->faces_other_v[1] + 2) % 3],
+ tri_1[(e->faces_other_v[1] ) % 3]),
+ };
+
+
+ for (i = 0; i < 4; i++) {
+ if (e_arr[i]) {
+ BLI_assert(!(ELEM(e_arr[i]->faces[0], UNPACK2(e->faces)) &&
+ ELEM(e_arr[i]->faces[1], UNPACK2(e->faces))));
+
+ polyedge_beauty_cost_update_single(
+ coords, tris, edges,
+ e_arr[i],
+ eheap, eheap_table);
+ }
+ }
+}
+
+static void polyedge_rotate(
+ unsigned int (*tris)[3],
+ struct PolyEdge *e,
+ EdgeHash *ehash)
+{
+ unsigned int e_v1_new = tris[e->faces[0]][e->faces_other_v[0]];
+ unsigned int e_v2_new = tris[e->faces[1]][e->faces_other_v[1]];
+
+#ifndef NDEBUG
+ polyfill_validate_tri(tris, e->faces[0], ehash);
+ polyfill_validate_tri(tris, e->faces[1], ehash);
+#endif
+
+ BLI_assert(e_v1_new != e_v2_new);
+ BLI_assert(!ELEM(e_v2_new, UNPACK3(tris[e->faces[0]])));
+ BLI_assert(!ELEM(e_v1_new, UNPACK3(tris[e->faces[1]])));
+
+ tris[e->faces[0]][(e->faces_other_v[0] + 1) % 3] = e_v2_new;
+ tris[e->faces[1]][(e->faces_other_v[1] + 1) % 3] = e_v1_new;
+
+ e->faces_other_v[0] = (e->faces_other_v[0] + 2) % 3;
+ e->faces_other_v[1] = (e->faces_other_v[1] + 2) % 3;
+
+ BLI_assert((tris[e->faces[0]][e->faces_other_v[0]] != e_v1_new) &&
+ (tris[e->faces[0]][e->faces_other_v[0]] != e_v2_new));
+ BLI_assert((tris[e->faces[1]][e->faces_other_v[1]] != e_v1_new) &&
+ (tris[e->faces[1]][e->faces_other_v[1]] != e_v2_new));
+
+ BLI_edgehash_remove(ehash, e->verts[0], e->verts[1], NULL);
+ BLI_edgehash_insert(ehash, e_v1_new, e_v2_new, e);
+
+ if (e_v1_new < e_v2_new) {
+ e->verts[0] = e_v1_new;
+ e->verts[1] = e_v2_new;
+ }
+ else {
+ /* maintain winding info */
+ e->verts[0] = e_v2_new;
+ e->verts[1] = e_v1_new;
+
+ SWAP(unsigned int, e->faces[0], e->faces[1]);
+ SWAP(unsigned int, e->faces_other_v[0], e->faces_other_v[1]);
+ }
+
+ /* update adjacent data */
+ {
+ unsigned int e_side = 0;
+
+ for (e_side = 0; e_side < 2; e_side++) {
+ /* 't_other' which we need to swap out is always the same edge-order */
+ const unsigned int t_other = (((e->faces_other_v[e_side]) + 2)) % 3;
+ unsigned int t_index = e->faces[e_side];
+ unsigned int t_index_other = e->faces[!e_side];
+ unsigned int *tri = tris[t_index];
+
+ struct PolyEdge *e_other;
+ unsigned int e_v1 = tri[(t_other ) ];
+ unsigned int e_v2 = tri[(t_other + 1) % 3];
+
+ e_other = BLI_edgehash_lookup(ehash, e_v1, e_v2);
+ if (e_other) {
+ BLI_assert(t_index != e_other->faces[0] && t_index != e_other->faces[1]);
+ if (t_index_other == e_other->faces[0]) {
+ e_other->faces[0] = t_index;
+ e_other->faces_other_v[0] = (t_other + 2) % 3;
+ BLI_assert(!ELEM(tri[e_other->faces_other_v[0]], e_v1, e_v2));
+ }
+ else if (t_index_other == e_other->faces[1]) {
+ e_other->faces[1] = t_index;
+ e_other->faces_other_v[1] = (t_other + 2) % 3;
+ BLI_assert(!ELEM(tri[e_other->faces_other_v[1]], e_v1, e_v2));
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ }
+ }
+
+#ifndef NDEBUG
+ polyfill_validate_tri(tris, e->faces[0], ehash);
+ polyfill_validate_tri(tris, e->faces[1], ehash);
+#endif
+
+ BLI_assert(!ELEM(tris[e->faces[0]][e->faces_other_v[0]], UNPACK2(e->verts)));
+ BLI_assert(!ELEM(tris[e->faces[1]][e->faces_other_v[1]], UNPACK2(e->verts)));
+}
+
+/**
+ * The intention is that this calculates the output of #BLI_polyfill_calc
+ *
+ *
+ * \note assumes the \a coords form a boundary,
+ * so any edges running along contiguous (wrapped) indices,
+ * are ignored since the edges wont share 2 faces.
+ */
+void BLI_polyfill_beautify(
+ const float (*coords)[2],
+ const unsigned int coords_tot,
+ unsigned int (*tris)[3],
+
+ /* structs for reuse */
+ MemArena *arena, Heap *eheap, EdgeHash *ehash)
+{
+ const unsigned int coord_last = coords_tot - 1;
+ const unsigned int tris_tot = coords_tot - 2;
+ /* internal edges only (between 2 tris) */
+ const unsigned int edges_tot = tris_tot - 1;
+ unsigned int edges_tot_used = 0;
+ unsigned int i;
+
+ HeapNode **eheap_table;
+
+ struct PolyEdge *edges = BLI_memarena_alloc(arena, edges_tot * sizeof(*edges));
+
+ BLI_assert(BLI_heap_size(eheap) == 0);
+ BLI_assert(BLI_edgehash_size(ehash) == 0);
+
+ /* first build edges */
+ for (i = 0; i < tris_tot; i++) {
+ unsigned int j_prev, j_curr, j_next;
+ j_prev = 2;
+ j_next = 1;
+ for (j_curr = 0; j_curr < 3; j_next = j_prev, j_prev = j_curr++) {
+ int e_index;
+
+ unsigned int e_pair[2] = {
+ tris[i][j_prev],
+ tris[i][j_curr],
+ };
+
+ if (e_pair[0] > e_pair[1]) {
+ SWAP(unsigned int, e_pair[0], e_pair[1]);
+ e_index = 1;
+ }
+ else {
+ e_index = 0;
+ }
+
+ if (!is_boundary_edge(e_pair[0], e_pair[1], coord_last)) {
+ struct PolyEdge *e = BLI_edgehash_lookup(ehash, e_pair[0], e_pair[1]);
+ if (e == NULL) {
+ e = &edges[edges_tot_used++];
+ BLI_edgehash_insert(ehash, e_pair[0], e_pair[1], e);
+ memcpy(e->verts, e_pair, sizeof(e->verts));
+#ifndef NDEBUG
+ e->faces[!e_index] = (unsigned int)-1;
+#endif
+ }
+ else {
+
+ /* ensure each edge only ever has 2x users */
+#ifndef NDEBUG
+ BLI_assert(e->faces[e_index] == (unsigned int)-1);
+ BLI_assert((e->verts[0] == e_pair[0]) &&
+ (e->verts[1] == e_pair[1]));
+#endif
+ }
+
+ e->faces[e_index] = i;
+ e->faces_other_v[e_index] = j_next;
+ }
+ }
+ }
+
+ /* now perform iterative rotations */
+ eheap_table = BLI_memarena_alloc(arena, sizeof(HeapNode *) * (size_t)edges_tot);
+
+ // for (i = 0; i < tris_tot; i++) { polyfill_validate_tri(tris, i, eh); }
+
+ /* build heap */
+ for (i = 0; i < edges_tot; i++) {
+ struct PolyEdge *e = &edges[i];
+ const float cost = polyedge_rotate_beauty_calc(coords, (const unsigned int (*)[3])tris, e);
+ if (cost < 0.0f) {
+ eheap_table[i] = BLI_heap_insert(eheap, cost, e);
+ }
+ else {
+ eheap_table[i] = NULL;
+ }
+ }
+
+ while (BLI_heap_is_empty(eheap) == false) {
+ struct PolyEdge *e = BLI_heap_popmin(eheap);
+ i = (unsigned int)(e - edges);
+ eheap_table[i] = NULL;
+
+ polyedge_rotate(tris, e, ehash);
+
+ /* recalculate faces connected on the heap */
+ polyedge_beauty_cost_update(
+ coords, (const unsigned int (*)[3])tris, edges,
+ e,
+ eheap, eheap_table, ehash);
+ }
+
+ BLI_heap_clear(eheap, NULL);
+ BLI_edgehash_clear_ex(ehash, NULL, BLI_POLYFILL_ALLOC_NGON_RESERVE);
+
+ /* MEM_freeN(eheap_table); */ /* arena */
+}
diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c
index 59ccf381f29..a03b236b5c6 100644
--- a/source/blender/blenlib/intern/rand.c
+++ b/source/blender/blenlib/intern/rand.c
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
+#include <time.h>
#include "MEM_guardedalloc.h"
@@ -144,6 +145,31 @@ void BLI_rng_get_float_unit_v3(RNG *rng, float v[3])
}
}
+/**
+ * Generate a random point inside given tri.
+ */
+void BLI_rng_get_tri_sample_float_v2(
+ RNG *rng, const float v1[2], const float v2[2], const float v3[2],
+ float r_pt[2])
+{
+ float u = BLI_rng_get_float(rng);
+ float v = BLI_rng_get_float(rng);
+
+ float side_u[2], side_v[2];
+
+ if ((u + v) > 1.0f) {
+ u = 1.0f - u;
+ v = 1.0f - v;
+ }
+
+ sub_v2_v2v2(side_u, v2, v1);
+ sub_v2_v2v2(side_v, v3, v1);
+
+ copy_v2_v2(r_pt, v1);
+ madd_v2_v2fl(r_pt, side_u, u);
+ madd_v2_v2fl(r_pt, side_v, v);
+}
+
void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_tot)
{
const size_t elem_size = (unsigned int)elem_size_i;
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index cf0d8cff870..8a96daeeb91 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -173,13 +173,13 @@ static bool boundisect(PolyFill *pf2, PolyFill *pf1)
/* has pf2 been touched (intersected) by pf1 ? with bounding box */
/* test first if polys exist */
- if (pf1->edges == 0 || pf2->edges == 0) return 0;
+ if (pf1->edges == 0 || pf2->edges == 0) return false;
- if (pf2->max_xy[0] < pf1->min_xy[0]) return 0;
- if (pf2->max_xy[1] < pf1->min_xy[1]) return 0;
+ if (pf2->max_xy[0] < pf1->min_xy[0]) return false;
+ if (pf2->max_xy[1] < pf1->min_xy[1]) return false;
- if (pf2->min_xy[0] > pf1->max_xy[0]) return 0;
- if (pf2->min_xy[1] > pf1->max_xy[1]) return 0;
+ if (pf2->min_xy[0] > pf1->max_xy[0]) return false;
+ if (pf2->min_xy[1] > pf1->max_xy[1]) return false;
/* join */
if (pf2->max_xy[0] < pf1->max_xy[0]) pf2->max_xy[0] = pf1->max_xy[0];
@@ -188,7 +188,7 @@ static bool boundisect(PolyFill *pf2, PolyFill *pf1)
if (pf2->min_xy[0] > pf1->min_xy[0]) pf2->min_xy[0] = pf1->min_xy[0];
if (pf2->min_xy[1] > pf1->min_xy[1]) pf2->min_xy[1] = pf1->min_xy[1];
- return 1;
+ return true;
}
@@ -225,13 +225,13 @@ static bool testedgeside(const float v1[2], const float v2[2], const float v3[2]
(v1[1] - v2[1]) * (v1[0] - v3[0]);
if (inp < 0.0f) {
- return 0;
+ return false;
}
else if (inp == 0.0f) {
- if (v1[0] == v3[0] && v1[1] == v3[1]) return 0;
- if (v2[0] == v3[0] && v2[1] == v3[1]) return 0;
+ if (v1[0] == v3[0] && v1[1] == v3[1]) return false;
+ if (v2[0] == v3[0] && v2[1] == v3[1]) return false;
}
- return 1;
+ return true;
}
static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
@@ -261,7 +261,7 @@ static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
for (ed = sc->edge_first; ed; ed = ed->next) {
if (ed->v2 == eed->v2) {
- return 0;
+ return false;
}
fac = ed->v2->xy[1] - y;
@@ -279,7 +279,7 @@ static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
if (ed) BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed, eed);
else BLI_addtail((ListBase *)&(sc->edge_first), eed);
- return 1;
+ return true;
}
@@ -341,10 +341,10 @@ static bool boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve)
maxy = eed->v1->xy[1];
}
if (eve->xy[1] >= miny && eve->xy[1] <= maxy) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
@@ -807,7 +807,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
#if 0
if (flag & BLI_SCANFILL_CALC_QUADTRI_FASTPATH) {
- const int totverts = BLI_countlist(&sf_ctx->fillvertbase);
+ const int totverts = BLI_listbase_count(&sf_ctx->fillvertbase);
if (totverts == 3) {
eve = sf_ctx->fillvertbase.first;
diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c
index 9fc1db1f1e4..a606ac41aa1 100644
--- a/source/blender/blenlib/intern/scanfill_utils.c
+++ b/source/blender/blenlib/intern/scanfill_utils.c
@@ -76,7 +76,7 @@ typedef struct ScanFillIsect {
#if 0
-void BKE_scanfill_obj_dump(ScanFillContext *sf_ctx)
+void BLI_scanfill_obj_dump(ScanFillContext *sf_ctx)
{
FILE *f = fopen("test.obj", "w");
unsigned int i = 1;
@@ -96,7 +96,7 @@ void BKE_scanfill_obj_dump(ScanFillContext *sf_ctx)
#endif
#if 0
-void BKE_scanfill_view3d_dump(ScanFillContext *sf_ctx)
+void BLI_scanfill_view3d_dump(ScanFillContext *sf_ctx)
{
ScanFillEdge *eed;
@@ -136,8 +136,8 @@ static int edge_isect_ls_sort_cb(void *thunk, const void *def_a_ptr, const void
{
const float *co = thunk;
- const ScanFillIsect *i_a = ((LinkData *)def_a_ptr)->data;
- const ScanFillIsect *i_b = ((LinkData *)def_b_ptr)->data;
+ const ScanFillIsect *i_a = ((const LinkData *)def_a_ptr)->data;
+ const ScanFillIsect *i_b = ((const LinkData *)def_b_ptr)->data;
const float a = len_squared_v2v2(co, i_a->co);
const float b = len_squared_v2v2(co, i_b->co);
@@ -265,7 +265,7 @@ static bool scanfill_preprocess_self_isect(
}
if (BLI_listbase_is_single(e_ls) == false) {
- BLI_sortlist_r(e_ls, eed->v2->co, edge_isect_ls_sort_cb);
+ BLI_listbase_sort_r(e_ls, eed->v2->co, edge_isect_ls_sort_cb);
}
/* move original edge to filledgebase and add replacement
@@ -508,8 +508,8 @@ bool BLI_scanfill_calc_self_isect(
sf_ctx->poly_nr = SF_POLY_UNSET;
#if 0
- BKE_scanfill_view3d_dump(sf_ctx);
- BKE_scanfill_obj_dump(sf_ctx);
+ BLI_scanfill_view3d_dump(sf_ctx);
+ BLI_scanfill_obj_dump(sf_ctx);
#endif
return changed;
diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c
index 0cf9f69b9ae..ba336ab6c4b 100644
--- a/source/blender/blenlib/intern/smallhash.c
+++ b/source/blender/blenlib/intern/smallhash.c
@@ -118,7 +118,7 @@ BLI_INLINE void smallhash_buckets_reserve(SmallHash *sh, const unsigned int nent
}
}
-BLI_INLINE SmallHashEntry *smallhash_lookup(SmallHash *sh, const uintptr_t key)
+BLI_INLINE SmallHashEntry *smallhash_lookup(const SmallHash *sh, const uintptr_t key)
{
SmallHashEntry *e;
unsigned int h = smallhash_key(key);
@@ -246,6 +246,26 @@ void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *val)
e->val = val;
}
+/**
+ * Inserts a new value to a key that may already be in ghash.
+ *
+ * Avoids #BLI_smallhash_remove, #BLI_smallhash_insert calls (double lookups)
+ *
+ * \returns true if a new key has been added.
+ */
+bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item)
+{
+ SmallHashEntry *e = smallhash_lookup(sh, key);
+ if (e) {
+ e->val = item;
+ return false;
+ }
+ else {
+ BLI_smallhash_insert(sh, key, item);
+ return true;
+ }
+}
+
#ifdef USE_REMOVE
bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key)
{
@@ -264,33 +284,33 @@ bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key)
}
#endif
-void *BLI_smallhash_lookup(SmallHash *sh, uintptr_t key)
+void *BLI_smallhash_lookup(const SmallHash *sh, uintptr_t key)
{
SmallHashEntry *e = smallhash_lookup(sh, key);
return e ? e->val : NULL;
}
-void **BLI_smallhash_lookup_p(SmallHash *sh, uintptr_t key)
+void **BLI_smallhash_lookup_p(const SmallHash *sh, uintptr_t key)
{
SmallHashEntry *e = smallhash_lookup(sh, key);
return e ? &e->val : NULL;
}
-bool BLI_smallhash_haskey(SmallHash *sh, uintptr_t key)
+bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key)
{
SmallHashEntry *e = smallhash_lookup(sh, key);
return (e != NULL);
}
-int BLI_smallhash_count(SmallHash *sh)
+int BLI_smallhash_count(const SmallHash *sh)
{
return (int)sh->nentries;
}
-void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key)
+BLI_INLINE SmallHashEntry *smallhash_iternext(SmallHashIter *iter, uintptr_t *key)
{
while (iter->i < iter->sh->nbuckets) {
if (smallhash_val_is_used(iter->sh->buckets[iter->i].val)) {
@@ -298,7 +318,7 @@ void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key)
*key = iter->sh->buckets[iter->i].key;
}
- return iter->sh->buckets[iter->i++].val;
+ return &iter->sh->buckets[iter->i++];
}
iter->i++;
@@ -307,7 +327,21 @@ void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key)
return NULL;
}
-void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key)
+void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key)
+{
+ SmallHashEntry *e = smallhash_iternext(iter, key);
+
+ return e ? e->val : NULL;
+}
+
+void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key)
+{
+ SmallHashEntry *e = smallhash_iternext(iter, key);
+
+ return e ? &e->val : NULL;
+}
+
+void *BLI_smallhash_iternew(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key)
{
iter->sh = sh;
iter->i = 0;
@@ -315,6 +349,15 @@ void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key)
return BLI_smallhash_iternext(iter, key);
}
+void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key)
+{
+ iter->sh = sh;
+ iter->i = 0;
+
+ return BLI_smallhash_iternext_p(iter, key);
+}
+
+
/** \name Debugging & Introspection
* \{ */
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index f3ecc799e1e..46c5a11949c 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -135,10 +135,10 @@ static int bli_compare(struct direntry *entry1, struct direntry *entry2)
/* OK, now we know their S_IFMT fields are the same, go on to a name comparison */
/* make sure "." and ".." are always first */
- if (strcmp(entry1->relname, ".") == 0) return (-1);
- if (strcmp(entry2->relname, ".") == 0) return (1);
- if (strcmp(entry1->relname, "..") == 0) return (-1);
- if (strcmp(entry2->relname, "..") == 0) return (1);
+ if (FILENAME_IS_CURRENT(entry1->relname)) return (-1);
+ if (FILENAME_IS_CURRENT(entry2->relname)) return (1);
+ if (FILENAME_IS_PARENT(entry1->relname)) return (-1);
+ if (FILENAME_IS_PARENT(entry2->relname)) return (1);
return (BLI_natstrcmp(entry1->relname, entry2->relname));
}
@@ -219,7 +219,6 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
DIR *dir;
if ((dir = opendir(dirname)) != NULL) {
-
const struct dirent *fname;
while ((fname = readdir(dir)) != NULL) {
struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
@@ -231,20 +230,19 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
}
if (newnum) {
-
if (dir_ctx->files) {
- void * const tmp = realloc(dir_ctx->files, (dir_ctx->nrfiles + newnum) * sizeof(struct direntry));
+ void * const tmp = MEM_reallocN(dir_ctx->files, (dir_ctx->nrfiles + newnum) * sizeof(struct direntry));
if (tmp) {
dir_ctx->files = (struct direntry *)tmp;
}
else { /* realloc fail */
- free(dir_ctx->files);
+ MEM_freeN(dir_ctx->files);
dir_ctx->files = NULL;
}
}
if (dir_ctx->files == NULL)
- dir_ctx->files = (struct direntry *)malloc(newnum * sizeof(struct direntry));
+ dir_ctx->files = (struct direntry *)MEM_mallocN(newnum * sizeof(struct direntry), __func__);
if (dir_ctx->files) {
struct dirlink * dlink = (struct dirlink *) dirbase.first;
@@ -255,8 +253,9 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
file->relname = dlink->name;
file->path = BLI_strdupcat(dirname, dlink->name);
BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name);
- BLI_stat(fullname, &file->s);
- file->type = file->s.st_mode;
+ if (BLI_stat(fullname, &file->s) != -1) {
+ file->type = file->s.st_mode;
+ }
file->flags = 0;
dir_ctx->nrfiles++;
file++;
@@ -280,7 +279,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
closedir(dir);
}
else {
- printf("%s non-existant directory\n", dirname);
+ printf("%s non-existent directory\n", dirname);
}
}
@@ -385,9 +384,11 @@ static void bli_adddirstrings(struct BuildDirCtx *dir_ctx)
/**
* Scans the contents of the directory named *dirname, and allocates and fills in an
- * array of entries describing them in *filelist. The length of the array is the function result.
+ * array of entries describing them in *filelist.
+ *
+ * \return The length of filelist array.
*/
-unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist)
+unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **filelist)
{
struct BuildDirCtx dir_ctx;
@@ -403,18 +404,51 @@ unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist)
else {
// keep blender happy. Blender stores this in a variable
// where 0 has special meaning.....
- *filelist = malloc(sizeof(struct direntry));
+ *filelist = MEM_mallocN(sizeof(**filelist), __func__);
}
return dir_ctx.nrfiles;
}
-/* frees storage for an array of direntries, including the array itself. */
-void BLI_free_filelist(struct direntry *filelist, unsigned int nrentries)
+/**
+ * Deep-duplicate of an array of direntries, including the array itself.
+ *
+ * \param dup_poin If given, called for each non-NULL direntry->poin. Otherwise, pointer is always simply copied over.
+ */
+void BLI_filelist_duplicate(
+ struct direntry **dest_filelist, struct direntry *src_filelist, unsigned int nrentries,
+ void *(*dup_poin)(void *))
+{
+ unsigned int i;
+
+ *dest_filelist = MEM_mallocN(sizeof(**dest_filelist) * (size_t)(nrentries), __func__);
+ for (i = 0; i < nrentries; ++i) {
+ struct direntry * const src = &src_filelist[i];
+ struct direntry *dest = &(*dest_filelist)[i];
+ *dest = *src;
+ if (dest->image) {
+ dest->image = IMB_dupImBuf(src->image);
+ }
+ if (dest->relname) {
+ dest->relname = MEM_dupallocN(src->relname);
+ }
+ if (dest->path) {
+ dest->path = MEM_dupallocN(src->path);
+ }
+ if (dest->poin && dup_poin) {
+ dest->poin = dup_poin(src->poin);
+ }
+ }
+}
+
+/**
+ * frees storage for an array of direntries, including the array itself.
+ */
+void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries, void (*free_poin)(void *))
{
unsigned int i;
for (i = 0; i < nrentries; ++i) {
- struct direntry * const entry = filelist + i;
+ struct direntry *entry = filelist + i;
if (entry->image) {
IMB_freeImBuf(entry->image);
}
@@ -422,10 +456,13 @@ void BLI_free_filelist(struct direntry *filelist, unsigned int nrentries)
MEM_freeN(entry->relname);
if (entry->path)
MEM_freeN(entry->path);
- /* entry->poin assumed not to point to anything needing freeing here */
+ if (entry->poin && free_poin)
+ free_poin(entry->poin);
}
- free(filelist);
+ if (filelist != NULL) {
+ MEM_freeN(filelist);
+ }
}
@@ -495,6 +532,7 @@ int BLI_exists(const char *name)
if (res == -1) return(0);
#else
struct stat st;
+ BLI_assert(name);
if (stat(name, &st)) return(0);
#endif
return(st.st_mode);
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index eeafc1a9e8f..cc5a90dbc39 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -126,6 +126,54 @@ char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t
}
/**
+ * Like BLI_strncpy but ensures dst is always padded by given char, on both sides (unless src is empty).
+ *
+ * \param dst Destination for copy
+ * \param src Source string to copy
+ * \param pad the char to use for padding
+ * \param maxncpy Maximum number of characters to copy (generally the size of dst)
+ * \retval Returns dst
+ */
+char *BLI_strncpy_ensure_pad(char *__restrict dst, const char *__restrict src, const char pad, size_t maxncpy)
+{
+ BLI_assert(maxncpy != 0);
+
+#ifdef DEBUG_STRSIZE
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
+#endif
+
+ if (src[0] == '\0') {
+ dst[0] = '\0';
+ }
+ else {
+ /* Add heading/trailing wildcards if needed. */
+ size_t idx = 0;
+ size_t srclen;
+
+ if (src[idx] != pad) {
+ dst[idx++] = pad;
+ maxncpy--;
+ }
+ maxncpy--; /* trailing '\0' */
+
+ srclen = BLI_strnlen(src, maxncpy);
+ if ((src[srclen - 1] != pad) && (srclen == maxncpy)) {
+ srclen--;
+ }
+
+ memcpy(&dst[idx], src, srclen);
+ idx += srclen;
+
+ if (dst[idx - 1] != pad) {
+ dst[idx++] = pad;
+ }
+ dst[idx] = '\0';
+ }
+
+ return dst;
+}
+
+/**
* Like strncpy but ensures dst is always
* '\0' terminated.
*
@@ -566,6 +614,50 @@ int BLI_natstrcmp(const char *s1, const char *s2)
return strcmp(s1, s2);
}
+/**
+ * Like strcmp, but will ignore any heading/trailing pad char for comparison.
+ * So e.g. if pad is '*', '*world' and 'world*' will compare equal.
+ */
+int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad)
+{
+ size_t str1_len, str2_len;
+
+ while (*str1 == pad) {
+ str1++;
+ }
+ while (*str2 == pad) {
+ str2++;
+ }
+
+ str1_len = strlen(str1);
+ str2_len = strlen(str2);
+
+ while (str1_len && (str1[str1_len - 1] == pad)) {
+ str1_len--;
+ }
+ while (str2_len && (str2[str2_len - 1] == pad)) {
+ str2_len--;
+ }
+
+ if (str1_len == str2_len) {
+ return strncmp(str1, str2, str2_len);
+ }
+ else if (str1_len > str2_len) {
+ int ret = strncmp(str1, str2, str2_len);
+ if (ret == 0) {
+ ret = 1;
+ }
+ return ret;
+ }
+ else {
+ int ret = strncmp(str1, str2, str1_len);
+ if (ret == 0) {
+ ret = -1;
+ }
+ return ret;
+ }
+}
+
void BLI_timestr(double _time, char *str, size_t maxlen)
{
/* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
@@ -681,6 +773,35 @@ int BLI_str_index_in_array(const char *__restrict str, const char **__restrict s
return -1;
}
+bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, size_t slength)
+{
+ size_t elength = strlen(end);
+
+ if (elength < slength) {
+ const char *iter = &str[slength - elength];
+ while (*iter) {
+ if (*iter++ != *end++) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Find if a string ends with another string.
+ *
+ * \param str The string to search within.
+ * \param end The string we look for at the end.
+ * \return If str ends with end.
+ */
+bool BLI_str_endswith(const char *__restrict str, const char *end)
+{
+ const size_t slength = strlen(str);
+ return BLI_strn_endswith(str, end, slength);
+}
+
/**
* Find the first char matching one of the chars in \a delim, from left.
*
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index 9697fcf09e9..67ff532cb6f 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -69,11 +69,11 @@ static const char trailingBytesForUTF8[256] = {
int BLI_utf8_invalid_byte(const char *str, int length)
{
- const unsigned char *p, *pend = (unsigned char *)str + length;
+ const unsigned char *p, *pend = (const unsigned char *)str + length;
unsigned char c;
int ab;
- for (p = (unsigned char *)str; p < pend; p++) {
+ for (p = (const unsigned char *)str; p < pend; p++) {
c = *p;
if (c < 128)
continue;
@@ -130,7 +130,7 @@ int BLI_utf8_invalid_byte(const char *str, int length)
utf8_error:
- return (int)((char *)p - (char *)str) - 1;
+ return (int)((const char *)p - (const char *)str) - 1;
}
int BLI_utf8_invalid_strip(char *str, int length)
@@ -209,6 +209,22 @@ char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t
return r_dst;
}
+size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, size_t maxncpy)
+{
+ char *r_dst = dst;
+
+ BLI_assert(maxncpy != 0);
+
+#ifdef DEBUG_STRSIZE
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
+#endif
+
+ /* note: currently we don't attempt to deal with invalid utf8 chars */
+ BLI_STR_UTF8_CPY(dst, src, maxncpy);
+
+ return (size_t)(dst - r_dst);
+}
+
char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy)
{
while (*dst && maxncpy > 0) {
@@ -233,6 +249,7 @@ char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxncpy)
{
const size_t maxlen = maxncpy - 1;
+ const int64_t maxlen_secured = (int64_t)maxlen - 6; /* 6 is max utf8 length of an unicode char. */
size_t len = 0;
BLI_assert(maxncpy != 0);
@@ -241,10 +258,23 @@ size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict
memset(dst, 0xff, sizeof(*dst) * maxncpy);
#endif
- while (*src && len < maxlen) { /* XXX can still run over the buffer because utf8 size isn't known :| */
+ while (*src && len <= maxlen_secured) {
len += BLI_str_utf8_from_unicode((unsigned int)*src++, dst + len);
}
+ /* We have to be more careful for the last six bytes, to avoid buffer overflow in case utf8-encoded char
+ * would be too long for our dst buffer. */
+ while (*src) {
+ char t[6];
+ size_t l = BLI_str_utf8_from_unicode((unsigned int)*src++, t);
+ BLI_assert(l <= 6);
+ if (len + l > maxlen) {
+ break;
+ }
+ memcpy(dst + len, t, l);
+ len += l;
+ }
+
dst[len] = '\0';
return len;
diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c
index e6389bc68f3..b6b0f14a4e2 100644
--- a/source/blender/blenlib/intern/system.c
+++ b/source/blender/blenlib/intern/system.c
@@ -22,9 +22,21 @@
* \ingroup bli
*/
+#include <stdio.h>
+#include <stdlib.h>
#include "BLI_system.h"
+#include "MEM_guardedalloc.h"
+
+/* for backtrace */
+#if defined(__linux__) || defined(__APPLE__)
+# include <execinfo.h>
+#elif defined(WIN32)
+# include <windows.h>
+# include <DbgHelp.h>
+#endif
+
int BLI_cpu_support_sse2(void)
{
#if defined(__x86_64__) || defined(_M_X64)
@@ -57,3 +69,71 @@ int BLI_cpu_support_sse2(void)
#endif
}
+/**
+ * Write a backtrace into a file for systems which support it.
+ */
+void BLI_system_backtrace(FILE *fp)
+{
+ /* ------------- */
+ /* Linux / Apple */
+#if defined(__linux__) || defined(__APPLE__)
+
+#define SIZE 100
+ void *buffer[SIZE];
+ int nptrs;
+ char **strings;
+ int i;
+
+ /* include a backtrace for good measure */
+ nptrs = backtrace(buffer, SIZE);
+ strings = backtrace_symbols(buffer, nptrs);
+ for (i = 0; i < nptrs; i++) {
+ fputs(strings[i], fp);
+ fputc('\n', fp);
+ }
+
+ free(strings);
+#undef SIZE
+
+ /* -------- */
+ /* Windows */
+#elif defined(_MSC_VER)
+
+ (void)fp;
+#if defined WIN32
+#define MAXSYMBOL 256
+#define SIZE 100
+ unsigned short i;
+ void *stack[SIZE];
+ unsigned short nframes;
+ SYMBOL_INFO *symbolinfo;
+ HANDLE process;
+
+ process = GetCurrentProcess();
+
+ SymInitialize(process, NULL, TRUE);
+
+ nframes = CaptureStackBackTrace(0, SIZE, stack, NULL);
+ symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof(char), "crash Symbol table");
+ symbolinfo->MaxNameLen = MAXSYMBOL - 1;
+ symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO);
+
+ for (i = 0; i < nframes; i++) {
+ SymFromAddr(process, (DWORD64)(stack[i]), 0, symbolinfo);
+
+ fprintf(fp, "%u: %s - 0x%0X\n", nframes - i - 1, symbolinfo->Name, symbolinfo->Address);
+ }
+
+ MEM_freeN(symbolinfo);
+#undef MAXSYMBOL
+#undef SIZE
+#endif
+
+ /* ------------------ */
+ /* non msvc/osx/linux */
+#else
+ (void)fp;
+#endif
+
+}
+/* end BLI_system_backtrace */
diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c
index 07c67f001f9..d187a8d1968 100644
--- a/source/blender/blenlib/intern/task.c
+++ b/source/blender/blenlib/intern/task.c
@@ -29,9 +29,12 @@
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
+#include "BLI_math.h"
#include "BLI_task.h"
#include "BLI_threads.h"
+#include "atomic_ops.h"
+
/* Types */
typedef struct Task {
@@ -48,6 +51,8 @@ struct TaskPool {
volatile size_t num;
volatile size_t done;
+ size_t num_threads;
+ size_t currently_running_tasks;
ThreadMutex num_mutex;
ThreadCondition num_cond;
@@ -83,6 +88,7 @@ static void task_pool_num_decrease(TaskPool *pool, size_t done)
BLI_assert(pool->num >= done);
pool->num -= done;
+ atomic_sub_z(&pool->currently_running_tasks, done);
pool->done += done;
if (pool->num == 0)
@@ -103,19 +109,37 @@ static void task_pool_num_increase(TaskPool *pool)
static bool task_scheduler_thread_wait_pop(TaskScheduler *scheduler, Task **task)
{
+ bool found_task = false;
BLI_mutex_lock(&scheduler->queue_mutex);
while (!scheduler->queue.first && !scheduler->do_exit)
BLI_condition_wait(&scheduler->queue_cond, &scheduler->queue_mutex);
- if (!scheduler->queue.first) {
- BLI_mutex_unlock(&scheduler->queue_mutex);
- BLI_assert(scheduler->do_exit);
- return false;
- }
-
- *task = scheduler->queue.first;
- BLI_remlink(&scheduler->queue, *task);
+ do {
+ Task *current_task;
+ if (!scheduler->queue.first) {
+ BLI_mutex_unlock(&scheduler->queue_mutex);
+ BLI_assert(scheduler->do_exit);
+ return false;
+ }
+ for (current_task = scheduler->queue.first;
+ current_task != NULL;
+ current_task = current_task->next)
+ {
+ TaskPool *pool = current_task->pool;
+ if (pool->num_threads == 0 ||
+ pool->currently_running_tasks < pool->num_threads)
+ {
+ *task = current_task;
+ found_task = true;
+ atomic_add_z(&pool->currently_running_tasks, 1);
+ BLI_remlink(&scheduler->queue, *task);
+ break;
+ }
+ }
+ if (!found_task)
+ BLI_condition_wait(&scheduler->queue_cond, &scheduler->queue_mutex);
+ } while (!found_task);
BLI_mutex_unlock(&scheduler->queue_mutex);
@@ -287,6 +311,8 @@ TaskPool *BLI_task_pool_create(TaskScheduler *scheduler, void *userdata)
pool->scheduler = scheduler;
pool->num = 0;
+ pool->num_threads = 0;
+ pool->currently_running_tasks = 0;
pool->do_cancel = false;
BLI_mutex_init(&pool->num_mutex);
@@ -350,12 +376,16 @@ void BLI_task_pool_work_and_wait(TaskPool *pool)
/* find task from this pool. if we get a task from another pool,
* we can get into deadlock */
- for (task = scheduler->queue.first; task; task = task->next) {
- if (task->pool == pool) {
- work_task = task;
- found_task = true;
- BLI_remlink(&scheduler->queue, task);
- break;
+ if (pool->num_threads == 0 ||
+ pool->currently_running_tasks < pool->num_threads)
+ {
+ for (task = scheduler->queue.first; task; task = task->next) {
+ if (task->pool == pool) {
+ work_task = task;
+ found_task = true;
+ BLI_remlink(&scheduler->queue, task);
+ break;
+ }
}
}
@@ -364,6 +394,7 @@ void BLI_task_pool_work_and_wait(TaskPool *pool)
/* if found task, do it, otherwise wait until other tasks are done */
if (found_task) {
/* run task */
+ atomic_add_z(&pool->currently_running_tasks, 1);
work_task->run(pool, work_task->taskdata, 0);
/* delete task */
@@ -386,6 +417,12 @@ void BLI_task_pool_work_and_wait(TaskPool *pool)
BLI_mutex_unlock(&pool->num_mutex);
}
+void BLI_pool_set_num_threads(TaskPool *pool, int num_threads)
+{
+ /* NOTE: Don't try to modify threads while tasks are running! */
+ pool->num_threads = num_threads;
+}
+
void BLI_task_pool_cancel(TaskPool *pool)
{
pool->do_cancel = true;
@@ -452,18 +489,21 @@ typedef struct ParallelRangeState {
TaskParallelRangeFunc func;
int iter;
+ int chunk_size;
SpinLock lock;
} ParallelRangeState;
BLI_INLINE bool parallel_range_next_iter_get(
- ParallelRangeState *state,
- int *iter)
+ ParallelRangeState * __restrict state,
+ int * __restrict iter, int * __restrict count)
{
bool result = false;
if (state->iter < state->stop) {
BLI_spin_lock(&state->lock);
if (state->iter < state->stop) {
- *iter = state->iter++;
+ *count = min_ii(state->chunk_size, state->stop - state->iter);
+ *iter = state->iter;
+ state->iter += *count;
result = true;
}
BLI_spin_unlock(&state->lock);
@@ -472,14 +512,17 @@ BLI_INLINE bool parallel_range_next_iter_get(
}
static void parallel_range_func(
- TaskPool *pool,
+ TaskPool * __restrict pool,
void *UNUSED(taskdata),
int UNUSED(threadid))
{
- ParallelRangeState *state = BLI_task_pool_userdata(pool);
- int iter;
- while (parallel_range_next_iter_get(state, &iter)) {
- state->func(state->userdata, iter);
+ ParallelRangeState * __restrict state = BLI_task_pool_userdata(pool);
+ int iter, count;
+ while (parallel_range_next_iter_get(state, &iter, &count)) {
+ int i;
+ for (i = 0; i < count; ++i) {
+ state->func(state->userdata, iter + i);
+ }
}
}
@@ -487,12 +530,13 @@ void BLI_task_parallel_range_ex(
int start, int stop,
void *userdata,
TaskParallelRangeFunc func,
- const int range_threshold)
+ const int range_threshold,
+ const bool use_dynamic_scheduling)
{
TaskScheduler *task_scheduler;
TaskPool *task_pool;
ParallelRangeState state;
- int i;
+ int i, num_threads, num_tasks;
BLI_assert(start < stop);
@@ -506,21 +550,30 @@ void BLI_task_parallel_range_ex(
return;
}
- BLI_spin_init(&state.lock);
- state.start = start;
- state.stop = stop;
- state.userdata = userdata;
- state.func = func;
- state.iter = start;
-
task_scheduler = BLI_task_scheduler_get();
task_pool = BLI_task_pool_create(task_scheduler, &state);
+ num_threads = BLI_task_scheduler_num_threads(task_scheduler);
/* The idea here is to prevent creating task for each of the loop iterations
* and instead have tasks which are evenly distributed across CPU cores and
* pull next iter to be crunched using the queue.
*/
- for (i = 0; i < 2 * BLI_task_scheduler_num_threads(task_scheduler); i++) {
+ num_tasks = num_threads * 2;
+
+ BLI_spin_init(&state.lock);
+ state.start = start;
+ state.stop = stop;
+ state.userdata = userdata;
+ state.func = func;
+ state.iter = start;
+ if (use_dynamic_scheduling) {
+ state.chunk_size = 32;
+ }
+ else {
+ state.chunk_size = (stop - start) / (num_tasks);
+ }
+
+ for (i = 0; i < num_tasks; i++) {
BLI_task_pool_push(task_pool,
parallel_range_func,
NULL, false,
@@ -538,5 +591,5 @@ void BLI_task_parallel_range(
void *userdata,
TaskParallelRangeFunc func)
{
- BLI_task_parallel_range_ex(start, stop, userdata, func, 64);
+ BLI_task_parallel_range_ex(start, stop, userdata, func, 64, false);
}
diff --git a/source/blender/blenlib/intern/time.c b/source/blender/blenlib/intern/time.c
index 078fc2c295b..a0fb78cd193 100644
--- a/source/blender/blenlib/intern/time.c
+++ b/source/blender/blenlib/intern/time.c
@@ -33,6 +33,9 @@
#include "PIL_time.h"
#ifdef WIN32
+
+#define _WIN32_WINNT 0x501 /* Windows XP or newer */
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
double PIL_check_seconds_timer(void)
@@ -70,6 +73,11 @@ double PIL_check_seconds_timer(void)
}
}
+long int PIL_check_seconds_timer_i(void)
+{
+ return (long int)PIL_check_seconds_timer();
+}
+
void PIL_sleep_ms(int ms)
{
Sleep(ms);
@@ -90,6 +98,16 @@ double PIL_check_seconds_timer(void)
return ((double) tv.tv_sec + tv.tv_usec / 1000000.0);
}
+long int PIL_check_seconds_timer_i(void)
+{
+ struct timeval tv;
+ struct timezone tz;
+
+ gettimeofday(&tv, &tz);
+
+ return tv.tv_sec;
+}
+
void PIL_sleep_ms(int ms)
{
if (ms >= 1000) {
diff --git a/source/blender/blenlib/intern/winstuff_dir.c b/source/blender/blenlib/intern/winstuff_dir.c
index 3d669a869f9..b20da9ce959 100644
--- a/source/blender/blenlib/intern/winstuff_dir.c
+++ b/source/blender/blenlib/intern/winstuff_dir.c
@@ -45,11 +45,11 @@
#include "utfconv.h"
/* Note: MinGW (FREE_WINDOWS) has opendir() and _wopendir(), and only the
-* latter accepts a path name of wchar_t type. Rather than messing up with
-* extra #ifdef's here and there, Blender's own implementations of opendir()
-* and related functions are used to properly support paths with non-ASCII
-* characters. (kjym3)
-*/
+ * latter accepts a path name of wchar_t type. Rather than messing up with
+ * extra #ifdef's here and there, Blender's own implementations of opendir()
+ * and related functions are used to properly support paths with non-ASCII
+ * characters. (kjym3)
+ */
DIR *opendir(const char *path)
{
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 4b7b9cecb17..419d8c0f137 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -37,7 +37,6 @@ extern "C" {
#endif
struct bScreen;
-struct direntry;
struct LinkNode;
struct Main;
struct MemFile;
@@ -61,9 +60,7 @@ typedef struct BlendFileData {
struct Main *main;
struct UserDef *user;
- int winpos;
int fileflags;
- int displaymode;
int globalf;
char filename[1024]; /* 1024 = FILE_MAX */
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index d9bcfc2e8f9..95440158277 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -308,6 +308,9 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil
/* makes lookup of existing video clips in old main */
blo_make_movieclip_pointer_map(fd, oldmain);
+
+ /* make lookups of existing sound data in old main */
+ blo_make_sound_pointer_map(fd, oldmain);
/* removed packed data from this trick - it's internal data that needs saves */
@@ -318,7 +321,10 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil
/* ensures relinked movie clips are not freed */
blo_end_movieclip_pointer_map(fd, oldmain);
-
+
+ /* ensures relinked sounds are not freed */
+ blo_end_sound_pointer_map(fd, oldmain);
+
/* move libraries from old main to new main */
if (bfd && mainlist.first != mainlist.last) {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index d99500dae92..6b4d45a85dc 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -113,6 +113,7 @@
#include "BKE_armature.h"
#include "BKE_brush.h"
+#include "BKE_cloth.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_curve.h"
@@ -141,13 +142,9 @@
#include "BKE_treehash.h"
#include "BKE_sound.h"
-#include "IMB_imbuf.h" // for proxy / timecode versioning stuff
#include "NOD_common.h"
#include "NOD_socket.h"
-#include "NOD_composite.h"
-#include "NOD_shader.h"
-#include "NOD_texture.h"
#include "BLO_readfile.h"
#include "BLO_undofile.h"
@@ -157,7 +154,6 @@
#include "readfile.h"
-#include "PIL_time.h"
#include <errno.h>
@@ -210,6 +206,9 @@
* - initialize FileGlobal and copy pointers to Global
*/
+/* use GHash for BHead name-based lookups (speeds up linking) */
+#define USE_GHASH_BHEAD
+
/***/
typedef struct OldNew {
@@ -229,6 +228,8 @@ typedef struct OldNewMap {
static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static void direct_link_modifiers(FileData *fd, ListBase *lb);
static void convert_tface_mt(FileData *fd, Main *main);
+static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
+static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
/* this function ensures that reports are printed,
* in the case of libraray linking errors this is important!
@@ -295,15 +296,9 @@ static void oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int n
if (oldaddr==NULL || newaddr==NULL) return;
- if (onm->nentries == onm->entriessize) {
- int osize = onm->entriessize;
- OldNew *oentries = onm->entries;
-
+ if (UNLIKELY(onm->nentries == onm->entriessize)) {
onm->entriessize *= 2;
- onm->entries = MEM_mallocN(sizeof(*onm->entries)*onm->entriessize, "OldNewMap.entries");
-
- memcpy(onm->entries, oentries, sizeof(*oentries)*osize);
- MEM_freeN(oentries);
+ onm->entries = MEM_reallocN(onm->entries, sizeof(*onm->entries) * onm->entriessize);
}
entry = &onm->entries[onm->nentries++];
@@ -512,6 +507,44 @@ static void read_file_version(FileData *fd, Main *main)
}
}
+#ifdef USE_GHASH_BHEAD
+static void read_file_bhead_idname_map_create(FileData *fd)
+{
+ BHead *bhead;
+
+ /* dummy values */
+ bool is_link = false;
+ int code_prev = ENDB;
+ unsigned int reserve = 0;
+
+ for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
+ if (code_prev != bhead->code) {
+ code_prev = bhead->code;
+ is_link = BKE_idcode_is_valid(code_prev) ? BKE_idcode_is_linkable(code_prev) : false;
+ }
+
+ if (is_link) {
+ reserve += 1;
+ }
+ }
+
+ BLI_assert(fd->bhead_idname_hash == NULL);
+
+ fd->bhead_idname_hash = BLI_ghash_str_new_ex(__func__, reserve);
+
+ for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
+ if (code_prev != bhead->code) {
+ code_prev = bhead->code;
+ is_link = BKE_idcode_is_valid(code_prev) ? BKE_idcode_is_linkable(code_prev) : false;
+ }
+
+ if (is_link) {
+ BLI_ghash_insert(fd->bhead_idname_hash, (void *)bhead_id_name(fd, bhead), bhead);
+ }
+ }
+}
+#endif
+
static Main *blo_find_main(FileData *fd, const char *filepath, const char *relabase)
{
@@ -740,7 +773,7 @@ BHead *blo_firstbhead(FileData *fd)
BHead *blo_prevbhead(FileData *UNUSED(fd), BHead *thisblock)
{
- BHeadN *bheadn = (BHeadN *) (((char *) thisblock) - offsetof(BHeadN, bhead));
+ BHeadN *bheadn = (BHeadN *)POINTER_OFFSET(thisblock, -offsetof(BHeadN, bhead));
BHeadN *prev = bheadn->prev;
return (prev) ? &prev->bhead : NULL;
@@ -754,7 +787,7 @@ BHead *blo_nextbhead(FileData *fd, BHead *thisblock)
if (thisblock) {
/* bhead is actually a sub part of BHeadN
* We calculate the BHeadN pointer from the BHead pointer below */
- new_bhead = (BHeadN *) (((char *) thisblock) - offsetof(BHeadN, bhead));
+ new_bhead = (BHeadN *)POINTER_OFFSET(thisblock, -offsetof(BHeadN, bhead));
/* get the next BHeadN. If it doesn't exist we read in the next one */
new_bhead = new_bhead->next;
@@ -781,7 +814,7 @@ static void decode_blender_header(FileData *fd)
readsize = fd->read(fd, header, sizeof(header));
if (readsize == sizeof(header)) {
- if (strncmp(header, "BLENDER", 7) == 0) {
+ if (STREQLEN(header, "BLENDER", 7)) {
int remove_this_endian_test = 1;
fd->flags |= FD_FLAGS_FILE_OK;
@@ -924,7 +957,7 @@ static int fd_read_from_memfile(FileData *filedata, void *buffer, unsigned int s
if (chunkoffset+readsize > chunk->size)
readsize= chunk->size-chunkoffset;
- memcpy((char *)buffer + totread, chunk->buf + chunkoffset, readsize);
+ memcpy(POINTER_OFFSET(buffer, totread), chunk->buf + chunkoffset, readsize);
totread += readsize;
filedata->seek += readsize;
seek += readsize;
@@ -1128,6 +1161,8 @@ void blo_freefiledata(FileData *fd)
oldnewmap_free(fd->imamap);
if (fd->movieclipmap)
oldnewmap_free(fd->movieclipmap);
+ if (fd->soundmap)
+ oldnewmap_free(fd->soundmap);
if (fd->packedmap)
oldnewmap_free(fd->packedmap);
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
@@ -1135,6 +1170,12 @@ void blo_freefiledata(FileData *fd)
if (fd->bheadmap)
MEM_freeN(fd->bheadmap);
+#ifdef USE_GHASH_BHEAD
+ if (fd->bhead_idname_hash) {
+ BLI_ghash_free(fd->bhead_idname_hash, NULL, NULL);
+ }
+#endif
+
MEM_freeN(fd);
}
}
@@ -1155,6 +1196,9 @@ bool BLO_is_a_library(const char *path, char *dir, char *group)
int len;
char *fd;
+ /* if path leads to a directory we can be sure we're not in a library */
+ if (BLI_is_dir(path)) return 0;
+
strcpy(dir, path);
len = strlen(dir);
if (len < 7) return 0;
@@ -1181,7 +1225,7 @@ bool BLO_is_a_library(const char *path, char *dir, char *group)
/* now we know that we are in a blend file and it is safe to
* assume that gp actually points to a group */
- if (strcmp("Screen", gp) != 0)
+ if (!STREQ("Screen", gp))
BLI_strncpy(group, gp, BLO_GROUP_MAX);
}
return 1;
@@ -1218,6 +1262,13 @@ static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie
return NULL;
}
+static void *newsoundadr(FileData *fd, void *adr) /* used to restore sound data after undo */
+{
+ if (fd->soundmap && adr)
+ return oldnewmap_lookup_and_inc(fd->soundmap, adr, true);
+ return NULL;
+}
+
static void *newpackedadr(FileData *fd, void *adr) /* used to restore packed data after undo */
{
if (fd->packedmap && adr)
@@ -1434,6 +1485,37 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain)
}
}
+void blo_make_sound_pointer_map(FileData *fd, Main *oldmain)
+{
+ bSound *sound = oldmain->sound.first;
+
+ fd->soundmap = oldnewmap_new();
+
+ for (; sound; sound = sound->id.next) {
+ if (sound->waveform)
+ oldnewmap_insert(fd->soundmap, sound->waveform, sound->waveform, 0);
+ }
+}
+
+/* set old main sound caches to zero if it has been restored */
+/* this works because freeing old main only happens after this call */
+void blo_end_sound_pointer_map(FileData *fd, Main *oldmain)
+{
+ OldNew *entry = fd->soundmap->entries;
+ bSound *sound = oldmain->sound.first;
+ int i;
+
+ /* used entries were restored, so we put them to zero */
+ for (i = 0; i < fd->soundmap->nentries; i++, entry++) {
+ if (entry->nr > 0)
+ entry->newp = NULL;
+ }
+
+ for (; sound; sound = sound->id.next) {
+ sound->waveform = newsoundadr(fd, sound->waveform);
+ }
+}
+
/* XXX disabled this feature - packed files also belong in temp saves and quit.blend, to make restore work */
static void insert_packedmap(FileData *fd, PackedFile *pf)
@@ -3085,14 +3167,14 @@ static void lib_link_key(FileData *fd, Main *main)
static void switch_endian_keyblock(Key *key, KeyBlock *kb)
{
int elemsize, a, b;
- const char *data, *poin, *cp;
+ char *data;
elemsize = key->elemsize;
data = kb->data;
for (a = 0; a < kb->totelem; a++) {
- cp = key->elemstr;
- poin = data;
+ const char *cp = key->elemstr;
+ char *poin = data;
while (cp[0]) { /* cp[0] == amount */
switch (cp[1]) { /* cp[1] = type */
@@ -3217,6 +3299,7 @@ static void direct_link_world(FileData *fd, World *wrld)
}
wrld->preview = direct_link_preview_image(fd, wrld->preview);
+ BLI_listbase_clear(&wrld->gpumaterial);
}
@@ -3727,25 +3810,26 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
BoidRule *rule;
for (; state; state=state->next) {
rule = state->rules.first;
- for (; rule; rule=rule->next)
- switch (rule->type) {
- case eBoidRuleType_Goal:
- case eBoidRuleType_Avoid:
- {
- BoidRuleGoalAvoid *brga = (BoidRuleGoalAvoid*)rule;
- brga->ob = newlibadr(fd, part->id.lib, brga->ob);
- break;
- }
- case eBoidRuleType_FollowLeader:
- {
- BoidRuleFollowLeader *brfl = (BoidRuleFollowLeader*)rule;
- brfl->ob = newlibadr(fd, part->id.lib, brfl->ob);
- break;
+ for (; rule; rule=rule->next) {
+ switch (rule->type) {
+ case eBoidRuleType_Goal:
+ case eBoidRuleType_Avoid:
+ {
+ BoidRuleGoalAvoid *brga = (BoidRuleGoalAvoid*)rule;
+ brga->ob = newlibadr(fd, part->id.lib, brga->ob);
+ break;
+ }
+ case eBoidRuleType_FollowLeader:
+ {
+ BoidRuleFollowLeader *brfl = (BoidRuleFollowLeader*)rule;
+ brfl->ob = newlibadr(fd, part->id.lib, brfl->ob);
+ break;
+ }
}
}
}
}
-
+
for (a = 0; a < MAX_MTEX; a++) {
mtex= part->mtex[a];
if (mtex) {
@@ -3776,6 +3860,13 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
direct_link_partdeflect(part->pd);
direct_link_partdeflect(part->pd2);
+ part->clumpcurve = newdataadr(fd, part->clumpcurve);
+ if (part->clumpcurve)
+ direct_link_curvemapping(fd, part->clumpcurve);
+ part->roughcurve = newdataadr(fd, part->roughcurve);
+ if (part->roughcurve)
+ direct_link_curvemapping(fd, part->roughcurve);
+
part->effector_weights = newdataadr(fd, part->effector_weights);
if (!part->effector_weights)
part->effector_weights = BKE_add_effector_weights(part->eff_group);
@@ -3892,6 +3983,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
if (psys->clmd) {
psys->clmd = newdataadr(fd, psys->clmd);
psys->clmd->clothObject = NULL;
+ psys->clmd->hairdata = NULL;
psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms);
psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms);
@@ -3903,6 +3995,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
}
psys->hair_in_dm = psys->hair_out_dm = NULL;
+ psys->clmd->solver_result = NULL;
psys->clmd->point_cache = psys->pointcache;
}
@@ -4462,11 +4555,11 @@ static void lib_link_object(FileData *fd, Main *main)
}
else if (act->type == ACT_ACTION) {
bActionActuator *aa = act->data;
- aa->act= newlibadr(fd, ob->id.lib, aa->act);
+ aa->act= newlibadr_us(fd, ob->id.lib, aa->act);
}
else if (act->type == ACT_SHAPEACTION) {
bActionActuator *aa = act->data;
- aa->act= newlibadr(fd, ob->id.lib, aa->act);
+ aa->act= newlibadr_us(fd, ob->id.lib, aa->act);
}
else if (act->type == ACT_PROPERTY) {
bPropertyActuator *pa = act->data;
@@ -4497,7 +4590,7 @@ static void lib_link_object(FileData *fd, Main *main)
steeringa->target = newlibadr(fd, ob->id.lib, steeringa->target);
steeringa->navmesh = newlibadr(fd, ob->id.lib, steeringa->navmesh);
}
- else if(act->type == ACT_MOUSE) {
+ else if (act->type == ACT_MOUSE) {
/* bMouseActuator *moa= act->data; */
}
}
@@ -4617,6 +4710,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
ClothModifierData *clmd = (ClothModifierData *)md;
clmd->clothObject = NULL;
+ clmd->hairdata = NULL;
clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
@@ -4635,6 +4729,8 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL);
}
}
+
+ clmd->solver_result = NULL;
}
else if (md->type == eModifierType_Fluidsim) {
FluidsimModifierData *fluidmd = (FluidsimModifierData *)md;
@@ -4785,6 +4881,11 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
BLI_endian_switch_int32_array(hmd->indexar, hmd->totindex);
}
+
+ hmd->curfalloff = newdataadr(fd, hmd->curfalloff);
+ if (hmd->curfalloff) {
+ direct_link_curvemapping(fd, hmd->curfalloff);
+ }
}
else if (md->type == eModifierType_ParticleSystem) {
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
@@ -4871,9 +4972,14 @@ static void direct_link_object(FileData *fd, Object *ob)
/* loading saved files with editmode enabled works, but for undo we like
* to stay in object mode during undo presses so keep editmode disabled.
*
- * Also when linking in a file don't allow editmode: [#34776] */
+ * Also when linking in a file don't allow edit and pose modes.
+ * See [#34776, #42780] for more information.
+ */
if (fd->memfile || (ob->id.flag & (LIB_EXTERN | LIB_INDIRECT))) {
ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT);
+ if (!fd->memfile) {
+ ob->mode &= ~OB_MODE_POSE;
+ }
}
ob->adt = newdataadr(fd, ob->adt);
@@ -5121,6 +5227,36 @@ static void lib_link_sequence_modifiers(FileData *fd, Scene *scene, ListBase *lb
}
}
+/* check for cyclic set-scene,
+ * libs can cause this case which is normally prevented, see (T#####) */
+#define USE_SETSCENE_CHECK
+
+#ifdef USE_SETSCENE_CHECK
+/**
+ * A version of #BKE_scene_validate_setscene with special checks for linked libs.
+ */
+static bool scene_validate_setscene__liblink(Scene *sce, const int totscene)
+{
+ Scene *sce_iter;
+ int a;
+
+ if (sce->set == NULL) return 1;
+
+ for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) {
+ if (sce_iter->id.flag & LIB_NEED_LINK) {
+ return 1;
+ }
+
+ if (a > totscene) {
+ sce->set = NULL;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+#endif
+
static void lib_link_scene(FileData *fd, Main *main)
{
Scene *sce;
@@ -5130,6 +5266,11 @@ static void lib_link_scene(FileData *fd, Main *main)
TimeMarker *marker;
FreestyleModuleConfig *fmc;
FreestyleLineSet *fls;
+
+#ifdef USE_SETSCENE_CHECK
+ bool need_check_set = false;
+ int totscene = 0;
+#endif
for (sce = main->scene.first; sce; sce = sce->id.next) {
if (sce->id.flag & LIB_NEED_LINK) {
@@ -5169,6 +5310,8 @@ static void lib_link_scene(FileData *fd, Main *main)
sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template);
+ sce->toolsettings->particle.shape_object = newlibadr(fd, sce->id.lib, sce->toolsettings->particle.shape_object);
+
for (base = sce->base.first; base; base = next) {
next = base->next;
@@ -5275,12 +5418,45 @@ static void lib_link_scene(FileData *fd, Main *main)
/* Motion Tracking */
sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip);
-
- sce->id.flag -= LIB_NEED_LINK;
+
+#ifdef USE_SETSCENE_CHECK
+ if (sce->set != NULL) {
+ /* link flag for scenes with set would be reset later,
+ * so this way we only check cyclic for newly linked scenes.
+ */
+ need_check_set = true;
+ }
+ else {
+ /* postpone un-setting the flag until we've checked the set-scene */
+ sce->id.flag &= ~LIB_NEED_LINK;
+ }
+#else
+ sce->id.flag &= ~LIB_NEED_LINK;
+#endif
+ }
+
+#ifdef USE_SETSCENE_CHECK
+ totscene++;
+#endif
+ }
+
+#ifdef USE_SETSCENE_CHECK
+ if (need_check_set) {
+ for (sce = main->scene.first; sce; sce = sce->id.next) {
+ if (sce->id.flag & LIB_NEED_LINK) {
+ sce->id.flag &= ~LIB_NEED_LINK;
+ if (!scene_validate_setscene__liblink(sce, totscene)) {
+ printf("Found cyclic background scene when linking %s\n", sce->id.name + 2);
+ }
+ }
}
}
+#endif
}
+#undef USE_SETSCENE_CHECK
+
+
static void link_recurs_seq(FileData *fd, ListBase *lb)
{
Sequence *seq;
@@ -5293,12 +5469,26 @@ static void link_recurs_seq(FileData *fd, ListBase *lb)
}
}
-static void direct_link_paint(FileData *fd, Paint **paint)
+static void direct_link_paint(FileData *fd, Paint *p)
+{
+ if (p->num_input_samples < 1)
+ p->num_input_samples = 1;
+
+ p->cavity_curve = newdataadr(fd, p->cavity_curve);
+ if (p->cavity_curve)
+ direct_link_curvemapping(fd, p->cavity_curve);
+ else
+ BKE_paint_cavity_curve_preset(p, CURVE_PRESET_LINE);
+}
+
+static void direct_link_paint_helper(FileData *fd, Paint **paint)
{
/* TODO. is this needed */
(*paint) = newdataadr(fd, (*paint));
- if (*paint && (*paint)->num_input_samples < 1)
- (*paint)->num_input_samples = 1;
+
+ if (*paint) {
+ direct_link_paint(fd, *paint);
+ }
}
static void direct_link_sequence_modifiers(FileData *fd, ListBase *lb)
@@ -5364,11 +5554,13 @@ static void direct_link_scene(FileData *fd, Scene *sce)
sce->toolsettings= newdataadr(fd, sce->toolsettings);
if (sce->toolsettings) {
- direct_link_paint(fd, (Paint**)&sce->toolsettings->sculpt);
- direct_link_paint(fd, (Paint**)&sce->toolsettings->vpaint);
- direct_link_paint(fd, (Paint**)&sce->toolsettings->wpaint);
- direct_link_paint(fd, (Paint**)&sce->toolsettings->uvsculpt);
+ direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->sculpt);
+ direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->vpaint);
+ direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->wpaint);
+ direct_link_paint_helper(fd, (Paint**)&sce->toolsettings->uvsculpt);
+ direct_link_paint(fd, &sce->toolsettings->imapaint.paint);
+
sce->toolsettings->imapaint.paintcursor = NULL;
sce->toolsettings->particle.paintcursor = NULL;
sce->toolsettings->particle.scene = NULL;
@@ -5386,7 +5578,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
}
if (sce->ed) {
- ListBase *old_seqbasep = &((Editing *)sce->ed)->seqbase;
+ ListBase *old_seqbasep = &sce->ed->seqbase;
ed = sce->ed = newdataadr(fd, sce->ed);
@@ -5400,6 +5592,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
seq->seq1= newdataadr(fd, seq->seq1);
seq->seq2= newdataadr(fd, seq->seq2);
seq->seq3= newdataadr(fd, seq->seq3);
+
/* a patch: after introduction of effects with 3 input strips */
if (seq->seq3 == NULL) seq->seq3 = seq->seq2;
@@ -5457,7 +5650,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
/* link metastack, slight abuse of structs here, have to restore pointer to internal part in struct */
{
Sequence temp;
- char *poin;
+ void *poin;
intptr_t offset;
offset = ((intptr_t)&(temp.seqbase)) - ((intptr_t)&temp);
@@ -5467,12 +5660,11 @@ static void direct_link_scene(FileData *fd, Scene *sce)
ed->seqbasep = &ed->seqbase;
}
else {
- poin = (char *)ed->seqbasep;
- poin -= offset;
+ poin = POINTER_OFFSET(ed->seqbasep, -offset);
poin = newdataadr(fd, poin);
if (poin)
- ed->seqbasep = (ListBase *)(poin+offset);
+ ed->seqbasep = (ListBase *)POINTER_OFFSET(poin, offset);
else
ed->seqbasep = &ed->seqbase;
}
@@ -5485,11 +5677,10 @@ static void direct_link_scene(FileData *fd, Scene *sce)
if (ms->oldbasep == old_seqbasep)
ms->oldbasep= &ed->seqbase;
else {
- poin = (char *)ms->oldbasep;
- poin -= offset;
+ poin = POINTER_OFFSET(ms->oldbasep, -offset);
poin = newdataadr(fd, poin);
if (poin)
- ms->oldbasep = (ListBase *)(poin+offset);
+ ms->oldbasep = (ListBase *)POINTER_OFFSET(poin, offset);
else
ms->oldbasep = &ed->seqbase;
}
@@ -5569,6 +5760,9 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->eventstate = NULL;
win->curswin = NULL;
win->tweak = NULL;
+#ifdef WIN32
+ win->ime_data = NULL;
+#endif
BLI_listbase_clear(&win->queue);
BLI_listbase_clear(&win->handlers);
@@ -5624,6 +5818,21 @@ static void lib_link_windowmanager(FileData *fd, Main *main)
/* ****************** READ GREASE PENCIL ***************** */
+/* relink's grease pencil data's refs */
+static void lib_link_gpencil(FileData *fd, Main *main)
+{
+ bGPdata *gpd;
+
+ for (gpd = main->gpencil.first; gpd; gpd = gpd->id.next) {
+ if (gpd->id.flag & LIB_NEED_LINK) {
+ gpd->id.flag -= LIB_NEED_LINK;
+
+ if (gpd->adt)
+ lib_link_animdata(fd, &gpd->id, gpd->adt);
+ }
+ }
+}
+
/* relinks grease-pencil data - used for direct_link and old file linkage */
static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
{
@@ -5635,6 +5844,10 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
if (gpd == NULL)
return;
+ /* relink animdata */
+ gpd->adt = newdataadr(fd, gpd->adt);
+ direct_link_animdata(fd, gpd->adt);
+
/* relink layers */
link_list(fd, &gpd->layers);
@@ -5667,6 +5880,12 @@ static void lib_link_screen(FileData *fd, Main *main)
if (sc->id.flag & LIB_NEED_LINK) {
sc->id.us = 1;
sc->scene = newlibadr(fd, sc->id.lib, sc->scene);
+
+ /* this should not happen, but apparently it does somehow. Until we figure out the cause,
+ * just assign first available scene */
+ if (!sc->scene)
+ sc->scene = main->scene.first;
+
sc->animtimer = NULL; /* saved in rare cases */
for (sa = sc->areabase.first; sa; sa = sa->next) {
@@ -5858,7 +6077,7 @@ typedef enum ePointerUserMode {
static bool restore_pointer(ID *id, ID *newid, ePointerUserMode user)
{
- if (strcmp(newid->name + 2, id->name + 2) == 0) {
+ if (STREQ(newid->name + 2, id->name + 2)) {
if (newid->lib == id->lib) {
if (user == USER_ONE) {
if (newid->us == 0) {
@@ -6247,6 +6466,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
rv3d->render_engine = NULL;
rv3d->sms = NULL;
rv3d->smooth_timer = NULL;
+ rv3d->compositor = NULL;
}
}
}
@@ -6354,7 +6574,7 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
/* add local view3d too */
else if (sa->spacetype == SPACE_VIEW3D)
blo_do_versions_view3d_split_250(sa->spacedata.first, &sa->regionbase);
-
+
/* incase we set above */
sa->butspacetype = sa->spacetype;
@@ -6401,6 +6621,11 @@ static bool direct_link_screen(FileData *fd, bScreen *sc)
/* render can be quite heavy, set to solid on load */
if (v3d->drawtype == OB_RENDER)
v3d->drawtype = OB_SOLID;
+
+ if (v3d->fx_settings.dof)
+ v3d->fx_settings.dof = newdataadr(fd, v3d->fx_settings.dof);
+ if (v3d->fx_settings.ssao)
+ v3d->fx_settings.ssao = newdataadr(fd, v3d->fx_settings.ssao);
blo_do_versions_view3d_split_250(v3d, &sl->regionbase);
}
@@ -6705,14 +6930,27 @@ static void direct_link_sound(FileData *fd, bSound *sound)
{
sound->handle = NULL;
sound->playback_handle = NULL;
- sound->waveform = NULL;
- // versioning stuff, if there was a cache, then we enable caching:
+ /* versioning stuff, if there was a cache, then we enable caching: */
if (sound->cache) {
sound->flags |= SOUND_FLAGS_CACHING;
sound->cache = NULL;
}
+ if (fd->soundmap) {
+ sound->waveform = newsoundadr(fd, sound->waveform);
+ }
+ else {
+ sound->waveform = NULL;
+ }
+
+ if (sound->spinlock) {
+ sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
+ BLI_spin_init(sound->spinlock);
+ }
+ /* clear waveform loading flag */
+ sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+
sound->packedfile = direct_link_packedfile(fd, sound->packedfile);
sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile);
}
@@ -7424,9 +7662,7 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
bfd->main->build_commit_timestamp = fg->build_commit_timestamp;
BLI_strncpy(bfd->main->build_hash, fg->build_hash, sizeof(bfd->main->build_hash));
- bfd->winpos = fg->winpos;
bfd->fileflags = fg->fileflags;
- bfd->displaymode = fg->displaymode;
bfd->globalf = fg->globalf;
BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename));
@@ -7594,6 +7830,7 @@ static void lib_link_all(FileData *fd, Main *main)
lib_link_movieclip(fd, main);
lib_link_mask(fd, main);
lib_link_linestyle(fd, main);
+ lib_link_gpencil(fd, main);
lib_link_mesh(fd, main); /* as last: tpage images with users at zero */
@@ -7841,9 +8078,48 @@ static BHead *find_bhead(FileData *fd, void *old)
return NULL;
}
-char *bhead_id_name(FileData *fd, BHead *bhead)
+static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name)
+{
+#ifdef USE_GHASH_BHEAD
+
+ char idname_full[MAX_ID_NAME];
+
+ *((short *)idname_full) = idcode;
+ BLI_strncpy(idname_full + 2, name, sizeof(idname_full) - 2);
+
+ return BLI_ghash_lookup(fd->bhead_idname_hash, idname_full);
+
+#else
+ BHead *bhead;
+
+ for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
+ if (bhead->code == idcode) {
+ const char *idname_test = bhead_id_name(fd, bhead);
+ if (STREQ(idname_test + 2, name)) {
+ return bhead;
+ }
+ }
+ else if (bhead->code == ENDB) {
+ break;
+ }
+ }
+
+ return NULL;
+#endif
+}
+
+static BHead *find_bhead_from_idname(FileData *fd, const char *idname)
{
- return ((char *)(bhead+1)) + fd->id_name_offs;
+#ifdef USE_GHASH_BHEAD
+ return BLI_ghash_lookup(fd->bhead_idname_hash, idname);
+#else
+ return find_bhead_from_code_name(fd, GS(idname), idname + 2);
+#endif
+}
+
+const char *bhead_id_name(const FileData *fd, const BHead *bhead)
+{
+ return (const char *)POINTER_OFFSET(bhead, sizeof(*bhead) + fd->id_name_offs);
}
static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead)
@@ -8699,6 +8975,12 @@ static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *li
}
}
+static void expand_gpencil(FileData *fd, Main *mainvar, bGPdata *gpd)
+{
+ if (gpd->adt)
+ expand_animdata(fd, mainvar, gpd->adt);
+}
+
void BLO_main_expander(void (*expand_doit_func)(void *, Main *, void *))
{
expand_doit = expand_doit_func;
@@ -8793,6 +9075,9 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
case ID_LS:
expand_linestyle(fd, mainvar, (FreestyleLineStyle *)id);
break;
+ case ID_GD:
+ expand_gpencil(fd, mainvar, (bGPdata *)id);
+ break;
}
do_it = true;
@@ -8841,7 +9126,7 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const
do_it = true;
}
else if (idcode==ID_GR) {
- if (ob->id.us == 1 && is_link == false && ob->id.lib == lib) {
+ if ((is_link == false) && (ob->id.lib == lib)) {
if ((ob->flag & OB_FROMGROUP) && object_in_any_scene(mainvar, ob)==0) {
do_it = true;
}
@@ -8850,7 +9135,7 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const
else {
/* when appending, make sure any indirectly loaded objects
* get a base else they cant be accessed at all [#27437] */
- if (ob->id.us==1 && is_link == false && ob->id.lib == lib) {
+ if ((is_link == false) && (ob->id.lib == lib)) {
/* we may be appending from a scene where we already
* have a linked object which is not in any scene [#27616] */
if ((ob->id.flag & LIB_PRE_EXISTING)==0) {
@@ -8870,7 +9155,9 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const
base->lay = ob->lay;
base->object = ob;
base->flag = ob->flag;
- ob->id.us = 1;
+
+ CLAMP_MIN(ob->id.us, 0);
+ ob->id.us += 1;
ob->id.flag -= LIB_INDIRECT;
ob->id.flag |= LIB_EXTERN;
@@ -8918,50 +9205,40 @@ static void give_base_to_groups(Main *mainvar, Scene *scene)
* but it may already have already been appended/linked */
static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, const short idcode)
{
- BHead *bhead;
- ID *id = NULL;
- int found = 0;
+ BHead *bhead = find_bhead_from_code_name(fd, idcode, idname);
+ ID *id;
- for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
- if (bhead->code == idcode) {
- const char *idname_test= bhead_id_name(fd, bhead);
-
- if (strcmp(idname_test + 2, idname) == 0) {
- found = 1;
- id = is_yet_read(fd, mainl, bhead);
- if (id == NULL) {
- /* not read yet */
- read_libblock(fd, mainl, bhead, LIB_TESTEXT, &id);
-
- if (id) {
- /* sort by name in list */
- ListBase *lb = which_libbase(mainl, idcode);
- id_sort_by_name(lb, id);
- }
- }
- else {
- /* already linked */
- if (G.debug)
- printf("append: already linked\n");
- oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
- if (id->flag & LIB_INDIRECT) {
- id->flag -= LIB_INDIRECT;
- id->flag |= LIB_EXTERN;
- }
- }
-
- break;
+ if (bhead) {
+ id = is_yet_read(fd, mainl, bhead);
+ if (id == NULL) {
+ /* not read yet */
+ read_libblock(fd, mainl, bhead, LIB_TESTEXT, &id);
+
+ if (id) {
+ /* sort by name in list */
+ ListBase *lb = which_libbase(mainl, idcode);
+ id_sort_by_name(lb, id);
}
}
- else if (bhead->code == ENDB) {
- break;
+ else {
+ /* already linked */
+ if (G.debug)
+ printf("append: already linked\n");
+ oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code);
+ if (id->flag & LIB_INDIRECT) {
+ id->flag -= LIB_INDIRECT;
+ id->flag |= LIB_EXTERN;
+ }
}
}
+ else {
+ id = NULL;
+ }
/* if we found the id but the id is NULL, this is really bad */
- BLI_assert((found != 0) == (id != NULL));
+ BLI_assert((bhead != NULL) == (id != NULL));
- return (found) ? id : NULL;
+ return id;
}
/* simple reader for copy/paste buffers */
@@ -9042,22 +9319,13 @@ ID *BLO_library_append_named_part_ex(const bContext *C, Main *mainl, BlendHandle
static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **r_id)
{
- BHead *bhead;
-
- for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
- if (bhead->code == GS(id->name)) {
-
- if (strcmp(id->name, bhead_id_name(fd, bhead))==0) {
- id->flag &= ~LIB_READ;
- id->flag |= LIB_NEED_EXPAND;
-// printf("read lib block %s\n", id->name);
- read_libblock(fd, mainvar, bhead, id->flag, r_id);
-
- break;
- }
- }
- else if (bhead->code==ENDB)
- break;
+ BHead *bhead = find_bhead_from_idname(fd, id->name);
+
+ if (bhead) {
+ id->flag &= ~LIB_READ;
+ id->flag |= LIB_NEED_EXPAND;
+ // printf("read lib block %s\n", id->name);
+ read_libblock(fd, mainvar, bhead, id->flag, r_id);
}
}
@@ -9081,6 +9349,9 @@ static Main *library_append_begin(Main *mainvar, FileData **fd, const char *file
/* needed for do_version */
mainl->versionfile = (*fd)->fileversion;
read_file_version(*fd, mainl);
+#ifdef USE_GHASH_BHEAD
+ read_file_bhead_idname_map_create(*fd);
+#endif
return mainl;
}
@@ -9287,6 +9558,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
/* subversion */
read_file_version(fd, mainptr);
+#ifdef USE_GHASH_BHEAD
+ read_file_bhead_idname_map_create(fd);
+#endif
+
}
else {
mainptr->curlib->filedata = NULL;
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index d56f58d1b37..51a68926455 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -88,10 +88,14 @@ typedef struct FileData {
struct OldNewMap *libmap;
struct OldNewMap *imamap;
struct OldNewMap *movieclipmap;
+ struct OldNewMap *soundmap;
struct OldNewMap *packedmap;
struct BHeadSort *bheadmap;
int tot_bheadmap;
+
+ /* see: USE_GHASH_BHEAD */
+ struct GHash *bhead_idname_hash;
ListBase *mainlist;
@@ -133,6 +137,8 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain);
void blo_end_image_pointer_map(FileData *fd, Main *oldmain);
void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain);
void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain);
+void blo_make_sound_pointer_map(FileData *fd, Main *oldmain);
+void blo_end_sound_pointer_map(FileData *fd, Main *oldmain);
void blo_make_packed_pointer_map(FileData *fd, Main *oldmain);
void blo_end_packed_pointer_map(FileData *fd, Main *oldmain);
void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd);
@@ -143,7 +149,7 @@ BHead *blo_firstbhead(FileData *fd);
BHead *blo_nextbhead(FileData *fd, BHead *thisblock);
BHead *blo_prevbhead(FileData *fd, BHead *thisblock);
-char *bhead_id_name(FileData *fd, BHead *bhead);
+const char *bhead_id_name(const FileData *fd, const BHead *bhead);
/* do versions stuff */
diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c
index d6fd2f92443..ec496e1c866 100644
--- a/source/blender/blenloader/intern/runtime.c
+++ b/source/blender/blenloader/intern/runtime.c
@@ -51,7 +51,6 @@
#include "BLO_readfile.h"
#include "BLO_runtime.h"
-#include "BKE_blender.h"
#include "BKE_report.h"
/* Runtime reading */
diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.c
index 12f4a295a34..f70d889828f 100644
--- a/source/blender/blenloader/intern/undofile.c
+++ b/source/blender/blenloader/intern/undofile.c
@@ -40,7 +40,6 @@
#include "DNA_listBase.h"
#include "BLI_blenlib.h"
-#include "BLI_linklist.h"
#include "BLO_undofile.h"
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 40b756a3f7c..4125451ead9 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -25,11 +25,10 @@
* \ingroup blenloader
*/
-#include "zlib.h"
-
#ifndef WIN32
# include <unistd.h> /* for read close */
#else
+# include <zlib.h> /* odd include order-issue */
# include <io.h> // for open close read
# include "winsock2.h"
# include "BLI_winstuff.h"
@@ -90,14 +89,9 @@
#include "NOD_socket.h"
#include "BLO_readfile.h"
-#include "BLO_undofile.h"
-
-#include "RE_engine.h"
#include "readfile.h"
-#include "PIL_time.h"
-
#include <errno.h>
/* 2.50 patch */
@@ -329,7 +323,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
SpaceNla *snla = (SpaceNla *)sl;
memcpy(&ar->v2d, &snla->v2d, sizeof(View2D));
- ar->v2d.tot.ymin = (float)(-sa->winy)/3.0f;
+ ar->v2d.tot.ymin = (float)(-sa->winy) / 3.0f;
ar->v2d.tot.ymax = 0.0f;
ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
@@ -344,8 +338,8 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
/* we totally reinit the view for the Action Editor, as some old instances had some weird cruft set */
ar->v2d.tot.xmin = -20.0f;
- ar->v2d.tot.ymin = (float)(-sa->winy)/3.0f;
- ar->v2d.tot.xmax = (float)((sa->winx > 120)? (sa->winx) : 120);
+ ar->v2d.tot.ymin = (float)(-sa->winy) / 3.0f;
+ ar->v2d.tot.xmax = (float)((sa->winx > 120) ? (sa->winx) : 120);
ar->v2d.tot.ymax = 0.0f;
ar->v2d.cur = ar->v2d.tot;
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index 7c6b6ec7249..10526a191d2 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -25,8 +25,6 @@
* \ingroup blenloader
*/
-#include "zlib.h"
-
#include "BLI_utildefines.h"
/* allow readfile to use deprecated functionality */
@@ -1885,7 +1883,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
SEQ_END
if (scene->r.bake_samples == 0)
- scene->r.bake_samples = 256;
+ scene->r.bake_samples = 256;
if (scene->world) {
World *world = blo_do_versions_newlibadr(fd, scene->id.lib, scene->world);
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index bd1b5f2c269..ab5c8ace430 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -35,6 +35,7 @@
#define DNA_DEPRECATED_ALLOW
#include "DNA_brush_types.h"
+#include "DNA_camera_types.h"
#include "DNA_cloth_types.h"
#include "DNA_constraint_types.h"
#include "DNA_sdna_types.h"
@@ -49,19 +50,20 @@
#include "DNA_genfile.h"
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-
#include "BKE_main.h"
+#include "BKE_modifier.h"
#include "BKE_node.h"
+#include "BKE_screen.h"
#include "BLI_math.h"
+#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLO_readfile.h"
#include "readfile.h"
+#include "MEM_guardedalloc.h"
static void do_version_constraints_radians_degrees_270_1(ListBase *lb)
{
@@ -310,7 +312,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
{
Scene *scene;
for (scene = main->scene.first; scene; scene = scene->id.next) {
- int num_layers = BLI_countlist(&scene->r.layers);
+ int num_layers = BLI_listbase_count(&scene->r.layers);
scene->r.actlay = min_ff(scene->r.actlay, num_layers - 1);
}
}
@@ -403,7 +405,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
-
+
if (!MAIN_VERSION_ATLEAST(main, 272, 1)) {
Brush *br;
for (br = main->brush.first; br; br = br->id.next) {
@@ -412,27 +414,245 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- if (!DNA_struct_elem_find(fd->filesdna, "Image", "float", "gen_color")) {
- Image *image;
- for (image = main->image.first; image != NULL; image = image->id.next) {
- image->gen_color[3] = 1.0f;
+ if (!MAIN_VERSION_ATLEAST(main, 272, 2)) {
+ if (!DNA_struct_elem_find(fd->filesdna, "Image", "float", "gen_color")) {
+ Image *image;
+ for (image = main->image.first; image != NULL; image = image->id.next) {
+ image->gen_color[3] = 1.0f;
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "bStretchToConstraint", "float", "bulge_min")) {
+ Object *ob;
+
+ /* Update Transform constraint (again :|). */
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ do_version_constraints_stretch_to_limits(&ob->constraints);
+
+ if (ob->pose) {
+ /* Bones constraints! */
+ bPoseChannel *pchan;
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ do_version_constraints_stretch_to_limits(&pchan->constraints);
+ }
+ }
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 273, 1)) {
+#define BRUSH_RAKE (1 << 7)
+#define BRUSH_RANDOM_ROTATION (1 << 25)
+
+ Brush *br;
+
+ for (br = main->brush.first; br; br = br->id.next) {
+ if (br->flag & BRUSH_RAKE) {
+ br->mtex.brush_angle_mode |= MTEX_ANGLE_RAKE;
+ br->mask_mtex.brush_angle_mode |= MTEX_ANGLE_RAKE;
+ }
+ else if (br->flag & BRUSH_RANDOM_ROTATION) {
+ br->mtex.brush_angle_mode |= MTEX_ANGLE_RANDOM;
+ br->mask_mtex.brush_angle_mode |= MTEX_ANGLE_RANDOM;
+ }
+ br->mtex.random_angle = 2.0 * M_PI;
+ br->mask_mtex.random_angle = 2.0 * M_PI;
+ }
+
+#undef BRUSH_RAKE
+#undef BRUSH_RANDOM_ROTATION
+ }
+
+ /* Customizable Safe Areas */
+ if (!MAIN_VERSION_ATLEAST(main, 273, 2)) {
+ if (!DNA_struct_elem_find(fd->filesdna, "Scene", "DisplaySafeAreas", "safe_areas")) {
+ Scene *scene;
+
+ for (scene = main->scene.first; scene; scene = scene->id.next) {
+ copy_v2_fl2(scene->safe_areas.title, 3.5f / 100.0f, 3.5f / 100.0f);
+ copy_v2_fl2(scene->safe_areas.action, 10.0f / 100.0f, 5.0f / 100.0f);
+ copy_v2_fl2(scene->safe_areas.title_center, 17.5f / 100.0f, 5.0f / 100.0f);
+ copy_v2_fl2(scene->safe_areas.action_center, 15.0f / 100.0f, 5.0f / 100.0f);
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 273, 3)) {
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ if (part->clumpcurve)
+ part->child_flag |= PART_CHILD_USE_CLUMP_CURVE;
+ if (part->roughcurve)
+ part->child_flag |= PART_CHILD_USE_ROUGH_CURVE;
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 273, 6)) {
+ if (!DNA_struct_elem_find(fd->filesdna, "ClothSimSettings", "float", "bending_damping")) {
+ Object *ob;
+ ModifierData *md;
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ for (md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Cloth) {
+ ClothModifierData *clmd = (ClothModifierData *)md;
+ clmd->sim_parms->bending_damping = 0.5f;
+ }
+ else if (md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md;
+ if (pmd->psys->clmd) {
+ pmd->psys->clmd->sim_parms->bending_damping = 0.5f;
+ }
+ }
+ }
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "ParticleSettings", "float", "clump_noise_size")) {
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ part->clump_noise_size = 1.0f;
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "ParticleSettings", "int", "kink_extra_steps")) {
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ part->kink_extra_steps = 4;
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "MTex", "float", "kinkampfac")) {
+ ParticleSettings *part;
+ for (part = main->particle.first; part; part = part->id.next) {
+ int a;
+ for (a = 0; a < MAX_MTEX; a++) {
+ MTex *mtex = part->mtex[a];
+ if (mtex) {
+ mtex->kinkampfac = 1.0f;
+ }
+ }
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "HookModifierData", "char", "flag")) {
+ Object *ob;
+
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ ModifierData *md;
+ for (md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Hook) {
+ HookModifierData *hmd = (HookModifierData *)md;
+ hmd->falloff_type = eHook_Falloff_InvSquare;
+ }
+ }
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "NodePlaneTrackDeformData", "char", "flag")) {
+ FOREACH_NODETREE(main, ntree, id) {
+ if (ntree->type == NTREE_COMPOSIT) {
+ bNode *node;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (ELEM(node->type, CMP_NODE_PLANETRACKDEFORM)) {
+ NodePlaneTrackDeformData *data = node->storage;
+ data->flag = 0;
+ data->motion_blur_samples = 16;
+ data->motion_blur_shutter = 0.5f;
+ }
+ }
+ }
+ }
+ FOREACH_NODETREE_END
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "Camera", "GPUDOFSettings", "gpu_dof")) {
+ Camera *ca;
+ for (ca = main->camera.first; ca; ca = ca->id.next) {
+ ca->gpu_dof.fstop = 128.0f;
+ ca->gpu_dof.focal_length = 1.0f;
+ ca->gpu_dof.focus_distance = 1.0f;
+ ca->gpu_dof.sensor = 1.0f;
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 273, 7)) {
+ bScreen *scr;
+ ScrArea *sa;
+ SpaceLink *sl;
+ ARegion *ar;
+
+ for (scr = main->screen.first; scr; scr = scr->id.next) {
+ /* Remove old deprecated region from filebrowsers */
+ for (sa = scr->areabase.first; sa; sa = sa->next) {
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_FILE) {
+ for (ar = sl->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_CHANNELS) {
+ break;
+ }
+ }
+
+ if (ar) {
+ /* Free old deprecated 'channel' region... */
+ BKE_area_region_free(NULL, ar);
+ BLI_freelinkN(&sl->regionbase, ar);
+ }
+ }
+ }
+ }
}
}
- if (!DNA_struct_elem_find(fd->filesdna, "bStretchToConstraint", "float", "bulge_min")) {
+ if (!MAIN_VERSION_ATLEAST(main, 273, 8)) {
Object *ob;
+ for (ob = main->object.first; ob != NULL; ob = ob->id.next) {
+ ModifierData *md;
+ for (md = ob->modifiers.last; md != NULL; md = md->prev) {
+ if (modifier_unique_name(&ob->modifiers, md)) {
+ printf("Warning: Object '%s' had several modifiers with the "
+ "same name, renamed one of them to '%s'.\n",
+ ob->id.name + 2, md->name);
+ }
+ }
+ }
- /* Update Transform constraint (again :|). */
- for (ob = main->object.first; ob; ob = ob->id.next) {
- do_version_constraints_stretch_to_limits(&ob->constraints);
+ if (!DNA_struct_elem_find(fd->filesdna, "bSteeringActuator", "float", "acceleration")) {
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ bActuator *act;
+ for (act = ob->actuators.first; act; act = act->next) {
+ if (act->type == ACT_STEERING) {
+ bSteeringActuator *sact = act->data;
+ sact->acceleration = 1000.f;
+ }
+ }
+ }
+ }
+ }
- if (ob->pose) {
- /* Bones constraints! */
- bPoseChannel *pchan;
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- do_version_constraints_stretch_to_limits(&pchan->constraints);
+ if (!MAIN_VERSION_ATLEAST(main, 273, 9)) {
+ bScreen *scr;
+ ScrArea *sa;
+ SpaceLink *sl;
+ ARegion *ar;
+
+ /* Make sure sequencer preview area limits zoom */
+ for (scr = main->screen.first; scr; scr = scr->id.next) {
+ for (sa = scr->areabase.first; sa; sa = sa->next) {
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_SEQ) {
+ for (ar = sl->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_PREVIEW) {
+ ar->v2d.keepzoom |= V2D_LIMITZOOM;
+ ar->v2d.minzoom = 0.001f;
+ ar->v2d.maxzoom = 1000.0f;
+ break;
+ }
+ }
+ }
}
}
}
}
+
}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 1afcac313a2..4c7b011097b 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -138,15 +138,37 @@ void BLO_update_defaults_startup_blend(Main *bmain)
{
Brush *br;
- br = BKE_brush_add(bmain, "Fill");
- br->imagepaint_tool = PAINT_TOOL_FILL;
- br->ob_mode = OB_MODE_TEXTURE_PAINT;
+
+ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Fill");
+ if (!br) {
+ br = BKE_brush_add(bmain, "Fill");
+ br->imagepaint_tool = PAINT_TOOL_FILL;
+ br->ob_mode = OB_MODE_TEXTURE_PAINT;
+ }
br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Mask");
if (br) {
br->imagepaint_tool = PAINT_TOOL_MASK;
br->ob_mode |= OB_MODE_TEXTURE_PAINT;
}
+
+ /* remove polish brush (flatten/contrast does the same) */
+ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Polish");
+ if (br) {
+ BKE_libblock_free(bmain, br);
+ }
+
+ /* remove brush brush (huh?) from some modes (draw brushes do the same) */
+ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Brush");
+ if (br) {
+ BKE_libblock_free(bmain, br);
+ }
+
+ /* remove draw brush from texpaint (draw brushes do the same) */
+ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Draw");
+ if (br) {
+ br->ob_mode &= ~OB_MODE_TEXTURE_PAINT;
+ }
}
}
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 557cc147f19..5dae6fbc464 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -30,13 +30,12 @@
*/
-#include "zlib.h"
-
#include <limits.h>
#ifndef WIN32
# include <unistd.h> // for read close
#else
+# include <zlib.h> /* odd include order-issue */
# include <io.h> // for open close read
# include "winsock2.h"
# include "BLI_winstuff.h"
@@ -94,14 +93,9 @@
#include "BKE_scene.h"
#include "BKE_sequencer.h"
-#include "IMB_imbuf.h" // for proxy / timecode versioning stuff
-
#include "NOD_socket.h"
#include "BLO_readfile.h"
-#include "BLO_undofile.h"
-
-#include "RE_engine.h"
#include "readfile.h"
@@ -521,6 +515,40 @@ static void do_version_free_effects_245(ListBase *lb)
}
}
+static void do_version_constraints_245(ListBase *lb)
+{
+ bConstraint *con;
+ bConstraintTarget *ct;
+
+ for (con = lb->first; con; con = con->next) {
+ if (con->type == CONSTRAINT_TYPE_PYTHON) {
+ bPythonConstraint *data = (bPythonConstraint *)con->data;
+ if (data->tar) {
+ /* version patching needs to be done */
+ ct = MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
+
+ ct->tar = data->tar;
+ BLI_strncpy(ct->subtarget, data->subtarget, sizeof(ct->subtarget));
+ ct->space = con->tarspace;
+
+ BLI_addtail(&data->targets, ct);
+ data->tarnum++;
+
+ /* clear old targets to avoid problems */
+ data->tar = NULL;
+ data->subtarget[0] = '\0';
+ }
+ }
+ else if (con->type == CONSTRAINT_TYPE_LOCLIKE) {
+ bLocateLikeConstraint *data = (bLocateLikeConstraint *)con->data;
+
+ /* new headtail functionality makes Bone-Tip function obsolete */
+ if (data->flag & LOCLIKE_TIP)
+ con->headtail = 1.0f;
+ }
+ }
+}
+
PartEff *blo_do_version_give_parteff_245(Object *ob)
{
PartEff *paf;
@@ -1271,7 +1299,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
Object *ob;
for (vf = main->vfont.first; vf; vf = vf->id.next) {
- if (strcmp(vf->name + strlen(vf->name)-6, ".Bfont") == 0) {
+ if (STREQ(vf->name + strlen(vf->name)-6, ".Bfont")) {
strcpy(vf->name, FO_BUILTIN_NAME);
}
}
@@ -2155,8 +2183,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
cam->flag |= CAM_SHOWPASSEPARTOUT;
/* make sure old cameras have title safe on */
- if (!(cam->flag & CAM_SHOWTITLESAFE))
- cam->flag |= CAM_SHOWTITLESAFE;
+ if (!(cam->flag & CAM_SHOW_SAFE_MARGINS))
+ cam->flag |= CAM_SHOW_SAFE_MARGINS;
/* set an appropriate camera passepartout alpha */
if (!(cam->passepartalpha))
@@ -2286,7 +2314,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
if (main->versionfile == 241) {
Image *ima;
for (ima = main->image.first; ima; ima = ima->id.next)
- if (strcmp(ima->name, "Compositor") == 0) {
+ if (STREQ(ima->name, "Compositor")) {
strcpy(ima->id.name + 2, "Viewer Node");
strcpy(ima->name, "Viewer Node");
}
@@ -2474,11 +2502,11 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
ima->gen_x = 256; ima->gen_y = 256;
ima->gen_type = 1;
- if (0 == strncmp(ima->id.name + 2, "Viewer Node", sizeof(ima->id.name) - 2)) {
+ if (STREQLEN(ima->id.name + 2, "Viewer Node", sizeof(ima->id.name) - 2)) {
ima->source = IMA_SRC_VIEWER;
ima->type = IMA_TYPE_COMPOSITE;
}
- if (0 == strncmp(ima->id.name + 2, "Render Result", sizeof(ima->id.name) - 2)) {
+ if (STREQLEN(ima->id.name + 2, "Render Result", sizeof(ima->id.name) - 2)) {
ima->source = IMA_SRC_VIEWER;
ima->type = IMA_TYPE_R_RESULT;
}
@@ -2957,69 +2985,14 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
if ((main->versionfile < 245) || (main->versionfile == 245 && main->subversionfile < 7)) {
Object *ob;
bPoseChannel *pchan;
- bConstraint *con;
- bConstraintTarget *ct;
for (ob = main->object.first; ob; ob = ob->id.next) {
if (ob->pose) {
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- for (con = pchan->constraints.first; con; con = con->next) {
- if (con->type == CONSTRAINT_TYPE_PYTHON) {
- bPythonConstraint *data = (bPythonConstraint *)con->data;
- if (data->tar) {
- /* version patching needs to be done */
- ct = MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
-
- ct->tar = data->tar;
- BLI_strncpy(ct->subtarget, data->subtarget, sizeof(ct->subtarget));
- ct->space = con->tarspace;
-
- BLI_addtail(&data->targets, ct);
- data->tarnum++;
-
- /* clear old targets to avoid problems */
- data->tar = NULL;
- data->subtarget[0] = '\0';
- }
- }
- else if (con->type == CONSTRAINT_TYPE_LOCLIKE) {
- bLocateLikeConstraint *data = (bLocateLikeConstraint *)con->data;
-
- /* new headtail functionality makes Bone-Tip function obsolete */
- if (data->flag & LOCLIKE_TIP)
- con->headtail = 1.0f;
- }
- }
- }
- }
-
- for (con = ob->constraints.first; con; con = con->next) {
- if (con->type == CONSTRAINT_TYPE_PYTHON) {
- bPythonConstraint *data = (bPythonConstraint *)con->data;
- if (data->tar) {
- /* version patching needs to be done */
- ct = MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
-
- ct->tar = data->tar;
- BLI_strncpy(ct->subtarget, data->subtarget, sizeof(ct->subtarget));
- ct->space = con->tarspace;
-
- BLI_addtail(&data->targets, ct);
- data->tarnum++;
-
- /* clear old targets to avoid problems */
- data->tar = NULL;
- data->subtarget[0] = '\0';
- }
- }
- else if (con->type == CONSTRAINT_TYPE_LOCLIKE) {
- bLocateLikeConstraint *data = (bLocateLikeConstraint *)con->data;
-
- /* new headtail functionality makes Bone-Tip function obsolete */
- if (data->flag & LOCLIKE_TIP)
- con->headtail = 1.0f;
+ do_version_constraints_245(&pchan->constraints);
}
}
+ do_version_constraints_245(&ob->constraints);
if (ob->soft && ob->soft->keys) {
SoftBody *sb = ob->soft;
@@ -3085,7 +3058,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
BLI_addtail(&ob->particlesystem, psys);
md = modifier_new(eModifierType_ParticleSystem);
- BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
+ BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", BLI_listbase_count(&ob->particlesystem));
psmd = (ParticleSystemModifierData*) md;
psmd->psys = psys;
BLI_addtail(&ob->modifiers, md);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 59f12657703..1156d3f30f0 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -79,9 +79,8 @@
#include <string.h>
#include <stdlib.h>
-#include "zlib.h"
-
#ifdef WIN32
+# include <zlib.h> /* odd include order-issue */
# include "winsock2.h"
# include <io.h>
# include "BLI_winstuff.h"
@@ -163,11 +162,9 @@
#include "BKE_mesh.h"
#ifdef USE_NODE_COMPAT_CUSTOMNODES
-#include "NOD_common.h"
#include "NOD_socket.h" /* for sock->default_value data */
#endif
-#include "RNA_access.h"
#include "BLO_writefile.h"
#include "BLO_readfile.h"
@@ -912,16 +909,39 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree)
write_node_socket_interface(wd, ntree, sock);
}
-static void current_screen_compat(Main *mainvar, bScreen **screen)
+/**
+ * Take care using 'use_active_win', since we wont want the currently active window
+ * to change which scene renders (currently only used for undo).
+ */
+static void current_screen_compat(Main *mainvar, bScreen **r_screen, bool use_active_win)
{
wmWindowManager *wm;
- wmWindow *window;
+ wmWindow *window = NULL;
/* find a global current screen in the first open window, to have
* a reasonable default for reading in older versions */
wm = mainvar->wm.first;
- window = (wm) ? wm->windows.first : NULL;
- *screen = (window) ? window->screen : NULL;
+
+ if (wm) {
+ if (use_active_win) {
+ /* write the active window into the file, needed for multi-window undo T43424 */
+ for (window = wm->windows.first; window; window = window->next) {
+ if (window->active) {
+ break;
+ }
+ }
+
+ /* fallback */
+ if (window == NULL) {
+ window = wm->windows.first;
+ }
+ }
+ else {
+ window = wm->windows.first;
+ }
+ }
+
+ *r_screen = (window) ? window->screen : NULL;
}
typedef struct RenderInfo {
@@ -940,7 +960,7 @@ static void write_renderinfo(WriteData *wd, Main *mainvar)
RenderInfo data;
/* XXX in future, handle multiple windows with multiple screens? */
- current_screen_compat(mainvar, &curscreen);
+ current_screen_compat(mainvar, &curscreen, false);
if (curscreen) curscene = curscreen->scene;
for (sce= mainvar->scene.first; sce; sce= sce->id.next) {
@@ -1111,6 +1131,11 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
writestruct(wd, DATA, "PartDeflect", 1, part->pd2);
writestruct(wd, DATA, "EffectorWeights", 1, part->effector_weights);
+ if (part->clumpcurve)
+ write_curvemapping(wd, part->clumpcurve);
+ if (part->roughcurve)
+ write_curvemapping(wd, part->roughcurve);
+
dw = part->dupliweights.first;
for (; dw; dw=dw->next) {
/* update indices */
@@ -1451,7 +1476,7 @@ static void write_pose(WriteData *wd, bPose *pose)
/* write IK param */
if (pose->ikparam) {
- const char *structname = (char *)BKE_pose_ikparam_get_name(pose);
+ const char *structname = BKE_pose_ikparam_get_name(pose);
if (structname)
writestruct(wd, DATA, structname, 1, pose->ikparam);
}
@@ -1483,6 +1508,10 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
if (md->type==eModifierType_Hook) {
HookModifierData *hmd = (HookModifierData*) md;
+ if (hmd->curfalloff) {
+ write_curvemapping(wd, hmd->curfalloff);
+ }
+
writedata(wd, DATA, sizeof(int)*hmd->totindex, hmd->indexar);
}
else if (md->type==eModifierType_Cloth) {
@@ -2060,7 +2089,8 @@ static void write_lattices(WriteData *wd, ListBase *idbase)
static void write_previews(WriteData *wd, PreviewImage *prv)
{
- if (prv) {
+ /* Never write previews in undo steps! */
+ if (prv && !wd->current) {
short w = prv->w[1];
short h = prv->h[1];
unsigned int *rect = prv->rect[1];
@@ -2286,6 +2316,12 @@ static void write_view_settings(WriteData *wd, ColorManagedViewSettings *view_se
}
}
+static void write_paint(WriteData *wd, Paint *p)
+{
+ if (p->cavity_curve)
+ write_curvemapping(wd, p->cavity_curve);
+}
+
static void write_scenes(WriteData *wd, ListBase *scebase)
{
Scene *sce;
@@ -2321,18 +2357,22 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
writestruct(wd, DATA, "ToolSettings", 1, tos);
if (tos->vpaint) {
writestruct(wd, DATA, "VPaint", 1, tos->vpaint);
+ write_paint (wd, &tos->vpaint->paint);
}
if (tos->wpaint) {
writestruct(wd, DATA, "VPaint", 1, tos->wpaint);
+ write_paint (wd, &tos->wpaint->paint);
}
if (tos->sculpt) {
writestruct(wd, DATA, "Sculpt", 1, tos->sculpt);
+ write_paint (wd, &tos->sculpt->paint);
}
if (tos->uvsculpt) {
writestruct(wd, DATA, "UvSculpt", 1, tos->uvsculpt);
+ write_paint (wd, &tos->uvsculpt->paint);
}
- // write_paint(wd, &tos->imapaint.paint);
+ write_paint(wd, &tos->imapaint.paint);
ed= sce->ed;
if (ed) {
@@ -2468,6 +2508,8 @@ static void write_gpencils(WriteData *wd, ListBase *lb)
/* write gpd data block to file */
writestruct(wd, ID_GD, "bGPdata", 1, gpd);
+ if (gpd->adt) write_animdata(wd, gpd->adt);
+
/* write grease-pencil layers to file */
writelist(wd, DATA, "bGPDlayer", &gpd->layers);
for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
@@ -2640,6 +2682,11 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
for (bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next)
writestruct(wd, DATA, "BGpic", 1, bgpic);
if (v3d->localvd) writestruct(wd, DATA, "View3D", 1, v3d->localvd);
+
+ if (v3d->fx_settings.ssao)
+ writestruct(wd, DATA, "GPUSSAOSettings", 1, v3d->fx_settings.ssao);
+ if (v3d->fx_settings.dof)
+ writestruct(wd, DATA, "GPUDOFSettings", 1, v3d->fx_settings.dof);
}
else if (sl->spacetype==SPACE_IPO) {
SpaceIpo *sipo= (SpaceIpo *)sl;
@@ -2727,6 +2774,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
else if (sl->spacetype==SPACE_CLIP) {
writestruct(wd, DATA, "SpaceClip", 1, sl);
}
+ else if (sl->spacetype == SPACE_INFO) {
+ writestruct(wd, DATA, "SpaceInfo", 1, sl);
+ }
sl= sl->next;
}
@@ -3037,7 +3087,7 @@ static void write_brushes(WriteData *wd, ListBase *idbase)
if (brush->curve)
write_curvemapping(wd, brush->curve);
- if (brush->curve)
+ if (brush->gradient)
writestruct(wd, DATA, "ColorBand", 1, brush->gradient);
}
}
@@ -3428,22 +3478,21 @@ static void write_linestyles(WriteData *wd, ListBase *idbase)
* - for undofile, curscene needs to be saved */
static void write_global(WriteData *wd, int fileflags, Main *mainvar)
{
+ const bool is_undo = (wd->current != NULL);
FileGlobal fg;
bScreen *screen;
char subvstr[8];
/* prevent mem checkers from complaining */
- fg.pads= 0;
+ memset(fg.pad, 0, sizeof(fg.pad));
memset(fg.filename, 0, sizeof(fg.filename));
memset(fg.build_hash, 0, sizeof(fg.build_hash));
- current_screen_compat(mainvar, &screen);
+ current_screen_compat(mainvar, &screen, is_undo);
/* XXX still remap G */
fg.curscreen= screen;
fg.curscene= screen ? screen->scene : NULL;
- fg.displaymode= G.displaymode;
- fg.winpos= G.winpos;
/* prevent to save this, is not good convention, and feature with concerns... */
fg.fileflags= (fileflags & ~G_FILE_FLAGS_RUNTIME);
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index 50d3ac30ddc..80adb595ac9 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -43,6 +43,7 @@ set(SRC
operators/bmo_bisect_plane.c
operators/bmo_bridge.c
operators/bmo_connect.c
+ operators/bmo_connect_concave.c
operators/bmo_connect_nonplanar.c
operators/bmo_connect_pair.c
operators/bmo_create.c
@@ -74,6 +75,8 @@ set(SRC
operators/bmo_utils.c
operators/bmo_wireframe.c
+ intern/bmesh_callback_generic.c
+ intern/bmesh_callback_generic.h
intern/bmesh_construct.c
intern/bmesh_construct.h
intern/bmesh_core.c
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index 4efc6aa16f8..87b1818fa5d 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -243,6 +243,7 @@ extern "C" {
#include "intern/bmesh_error.h"
#include "intern/bmesh_core.h"
+#include "intern/bmesh_callback_generic.h"
#include "intern/bmesh_construct.h"
#include "intern/bmesh_delete.h"
#include "intern/bmesh_edgeloop.h"
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 39359b97a4e..120ff4997dc 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -256,6 +256,12 @@ enum {
#define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
#define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE)
+#define BM_CHECK_TYPE_ELEM(ele) \
+ CHECK_TYPE_ANY(ele, void *, BMFace *, BMEdge *, BMVert *, BMLoop *, BMElem *, BMElemF *, BMHeader *)
+
+#define BM_CHECK_TYPE_ELEM_ASSIGN(ele) \
+ (BM_CHECK_TYPE_ELEM(ele), CHECK_TYPE_NONCONST(ele)), ele
+
/* BMHeader->hflag (char) */
enum {
BM_ELEM_SELECT = (1 << 0),
diff --git a/source/blender/bmesh/intern/bmesh_callback_generic.c b/source/blender/bmesh/intern/bmesh_callback_generic.c
new file mode 100644
index 00000000000..913255bfb33
--- /dev/null
+++ b/source/blender/bmesh/intern/bmesh_callback_generic.c
@@ -0,0 +1,60 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/intern/bmesh_callback_generic.c
+ * \ingroup bmesh
+ *
+ * BM element callback functions.
+ */
+
+#include "BLI_utildefines.h"
+
+#include "bmesh.h"
+
+#include "intern/bmesh_callback_generic.h"
+
+bool BM_elem_cb_check_hflag_ex(BMElem *ele, void *user_data)
+{
+ const unsigned int hflag_pair = GET_INT_FROM_POINTER(user_data);
+ const char hflag_p = (hflag_pair & 0xff);
+ const char hflag_n = (hflag_pair >> 8);
+
+ return ((BM_elem_flag_test(ele, hflag_p) != 0) &&
+ (BM_elem_flag_test(ele, hflag_n) == 0));
+}
+
+bool BM_elem_cb_check_hflag_enabled(BMElem *ele, void *user_data)
+{
+ const char hflag = GET_INT_FROM_POINTER(user_data);
+
+ return (BM_elem_flag_test(ele, hflag) != 0);
+}
+
+bool BM_elem_cb_check_hflag_disabled(BMElem *ele, void *user_data)
+{
+ const char hflag = GET_INT_FROM_POINTER(user_data);
+
+ return (BM_elem_flag_test(ele, hflag) == 0);
+}
+
+bool BM_elem_cb_check_elem_not_equal(BMElem *ele, void *user_data)
+{
+ return (ele != user_data);
+}
diff --git a/source/blender/bmesh/intern/bmesh_callback_generic.h b/source/blender/bmesh/intern/bmesh_callback_generic.h
new file mode 100644
index 00000000000..3cae01d417f
--- /dev/null
+++ b/source/blender/bmesh/intern/bmesh_callback_generic.h
@@ -0,0 +1,45 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BMESH_CALLBACK_GENERIC_H__
+#define __BMESH_CALLBACK_GENERIC_H__
+
+/** \file blender/bmesh/intern/bmesh_callback_generic.h
+ * \ingroup bmesh
+ */
+
+bool BM_elem_cb_check_hflag_enabled(BMElem *, void *user_data);
+bool BM_elem_cb_check_hflag_disabled(BMElem *, void *user_data);
+bool BM_elem_cb_check_hflag_ex(BMElem *, void *user_data);
+bool BM_elem_cb_check_elem_not_equal(BMElem *ele, void *user_data);
+
+#define BM_elem_cb_check_hflag_ex_simple(type, hflag_p, hflag_n) \
+ (bool (*)(type, void *))BM_elem_cb_check_hflag_ex, \
+ SET_UINT_IN_POINTER(((hflag_p) | (hflag_n << 8)))
+
+#define BM_elem_cb_check_hflag_enabled_simple(type, hflag_p) \
+ (bool (*)(type, void *))BM_elem_cb_check_hflag_enabled, \
+ SET_UINT_IN_POINTER((hflag_p))
+
+#define BM_elem_cb_check_hflag_disabled_simple(type, hflag_n) \
+ (bool (*)(type, void *))BM_elem_cb_check_hflag_disabled, \
+ SET_UINT_IN_POINTER(hflag_n)
+
+#endif /* __BMESH_CALLBACK_GENERIC_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index eb7b9f78ef4..9e0807710fc 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -493,17 +493,17 @@ int bmesh_elem_check(void *element, const char htype)
int err = 0;
if (!element)
- return 1;
+ return (1 << 0);
if (head->htype != htype)
- return 2;
+ return (1 << 1);
switch (htype) {
case BM_VERT:
{
BMVert *v = element;
if (v->e && v->e->head.htype != BM_EDGE) {
- err |= 4;
+ err |= (1 << 2);
}
break;
}
@@ -511,20 +511,20 @@ int bmesh_elem_check(void *element, const char htype)
{
BMEdge *e = element;
if (e->l && e->l->head.htype != BM_LOOP)
- err |= 8;
+ err |= (1 << 3);
if (e->l && e->l->f->head.htype != BM_FACE)
- err |= 16;
+ err |= (1 << 4);
if (e->v1_disk_link.prev == NULL ||
e->v2_disk_link.prev == NULL ||
e->v1_disk_link.next == NULL ||
e->v2_disk_link.next == NULL)
{
- err |= 32;
+ err |= (1 << 5);
}
if (e->l && (e->l->radial_next == NULL || e->l->radial_prev == NULL))
- err |= 64;
+ err |= (1 << 6);
if (e->l && e->l->f->len <= 0)
- err |= 128;
+ err |= (1 << 7);
break;
}
case BM_LOOP:
@@ -533,14 +533,14 @@ int bmesh_elem_check(void *element, const char htype)
int i;
if (l->f->head.htype != BM_FACE)
- err |= 256;
+ err |= (1 << 8);
if (l->e->head.htype != BM_EDGE)
- err |= 512;
+ err |= (1 << 9);
if (l->v->head.htype != BM_VERT)
- err |= 1024;
+ err |= (1 << 10);
if (!BM_vert_in_edge(l->e, l->v)) {
fprintf(stderr, "%s: fatal bmesh error (vert not in edge)! (bmesh internal error)\n", __func__);
- err |= 2048;
+ err |= (1 << 11);
}
if (l->radial_next == NULL || l->radial_prev == NULL)
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c
index e83a1d5b00a..aa1f511e8d7 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.c
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.c
@@ -662,7 +662,7 @@ void BM_edgeloop_flip(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
void BM_edgeloop_expand(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store, int el_store_len)
{
- /* first double until we are more then half as big */
+ /* first double until we are more than half as big */
while ((el_store->len * 2) < el_store_len) {
LinkData *node_curr = el_store->verts.first;
while (node_curr) {
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index a32f28169f6..f745972293e 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -40,39 +40,43 @@
#include "BKE_customdata.h"
#include "BKE_multires.h"
+#include "BLI_memarena.h"
+#include "BLI_linklist.h"
#include "bmesh.h"
#include "intern/bmesh_private.h"
/* edge and vertex share, currently theres no need to have different logic */
-static void bm_data_interp_from_elem(CustomData *data_layer, BMElem *ele1, BMElem *ele2, BMElem *ele_dst, const float fac)
+static void bm_data_interp_from_elem(
+ CustomData *data_layer, const BMElem *ele_src_1, const BMElem *ele_src_2,
+ BMElem *ele_dst, const float fac)
{
- if (ele1->head.data && ele2->head.data) {
+ if (ele_src_1->head.data && ele_src_2->head.data) {
/* first see if we can avoid interpolation */
if (fac <= 0.0f) {
- if (ele1 == ele_dst) {
+ if (ele_src_1 == ele_dst) {
/* do nothing */
}
else {
CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
- CustomData_bmesh_copy_data(data_layer, data_layer, ele1->head.data, &ele_dst->head.data);
+ CustomData_bmesh_copy_data(data_layer, data_layer, ele_src_1->head.data, &ele_dst->head.data);
}
}
else if (fac >= 1.0f) {
- if (ele2 == ele_dst) {
+ if (ele_src_2 == ele_dst) {
/* do nothing */
}
else {
CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
- CustomData_bmesh_copy_data(data_layer, data_layer, ele2->head.data, &ele_dst->head.data);
+ CustomData_bmesh_copy_data(data_layer, data_layer, ele_src_2->head.data, &ele_dst->head.data);
}
}
else {
- void *src[2];
+ const void *src[2];
float w[2];
- src[0] = ele1->head.data;
- src[1] = ele2->head.data;
+ src[0] = ele_src_1->head.data;
+ src[1] = ele_src_2->head.data;
w[0] = 1.0f - fac;
w[1] = fac;
CustomData_bmesh_interp(data_layer, src, w, NULL, 2, ele_dst->head.data);
@@ -83,25 +87,25 @@ static void bm_data_interp_from_elem(CustomData *data_layer, BMElem *ele1, BMEle
/**
* \brief Data, Interp From Verts
*
- * Interpolates per-vertex data from two sources to a target.
+ * Interpolates per-vertex data from two sources to \a v_dst
*
* \note This is an exact match to #BM_data_interp_from_edges
*/
-void BM_data_interp_from_verts(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, const float fac)
+void BM_data_interp_from_verts(BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v_dst, const float fac)
{
- bm_data_interp_from_elem(&bm->vdata, (BMElem *)v1, (BMElem *)v2, (BMElem *)v, fac);
+ bm_data_interp_from_elem(&bm->vdata, (const BMElem *)v_src_1, (const BMElem *)v_src_2, (BMElem *)v_dst, fac);
}
/**
* \brief Data, Interp From Edges
*
- * Interpolates per-edge data from two sources to a target.
+ * Interpolates per-edge data from two sources to \a e_dst.
*
* \note This is an exact match to #BM_data_interp_from_verts
*/
-void BM_data_interp_from_edges(BMesh *bm, BMEdge *e1, BMEdge *e2, BMEdge *e, const float fac)
+void BM_data_interp_from_edges(BMesh *bm, const BMEdge *e_src_1, const BMEdge *e_src_2, BMEdge *e_dst, const float fac)
{
- bm_data_interp_from_elem(&bm->edata, (BMElem *)e1, (BMElem *)e2, (BMElem *)e, fac);
+ bm_data_interp_from_elem(&bm->edata, (const BMElem *)e_src_1, (const BMElem *)e_src_2, (BMElem *)e_dst, fac);
}
/**
@@ -118,26 +122,26 @@ static void UNUSED_FUNCTION(BM_Data_Vert_Average)(BMesh *UNUSED(bm), BMFace *UNU
/**
* \brief Data Face-Vert Edge Interp
*
- * Walks around the faces of an edge and interpolates the per-face-edge
- * data between two sources to a target.
+ * Walks around the faces of \a e and interpolates
+ * the loop data between two sources.
*/
-void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BMVert *v, BMEdge *e1, const float fac)
+void BM_data_interp_face_vert_edge(
+ BMesh *bm, const BMVert *v_src_1, const BMVert *UNUSED(v_src_2), BMVert *v, BMEdge *e, const float fac)
{
- void *src[2];
float w[2];
BMLoop *l_v1 = NULL, *l_v = NULL, *l_v2 = NULL;
BMLoop *l_iter = NULL;
- if (!e1->l) {
+ if (!e->l) {
return;
}
w[1] = 1.0f - fac;
w[0] = fac;
- l_iter = e1->l;
+ l_iter = e->l;
do {
- if (l_iter->v == v1) {
+ if (l_iter->v == v_src_1) {
l_v1 = l_iter;
l_v = l_v1->next;
l_v2 = l_v->next;
@@ -148,14 +152,17 @@ void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BM
l_v2 = l_iter->prev;
}
- if (!l_v1 || !l_v2)
+ if (!l_v1 || !l_v2) {
return;
-
- src[0] = l_v1->head.data;
- src[1] = l_v2->head.data;
+ }
+ else {
+ const void *src[2];
+ src[0] = l_v1->head.data;
+ src[1] = l_v2->head.data;
- CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_v->head.data);
- } while ((l_iter = l_iter->radial_next) != e1->l);
+ CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_v->head.data);
+ }
+ } while ((l_iter = l_iter->radial_next) != e->l);
}
/**
@@ -166,56 +173,57 @@ void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BM
*
* \note Only handles loop customdata. multires is handled.
*/
-void BM_face_interp_from_face_ex(BMesh *bm, BMFace *target, BMFace *source, const bool do_vertex,
- void **blocks_l, void **blocks_v, float (*cos_2d)[2], float axis_mat[3][3])
+void BM_face_interp_from_face_ex(
+ BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex,
+ const void **blocks_l, const void **blocks_v, float (*cos_2d)[2], float axis_mat[3][3])
{
BMLoop *l_iter;
BMLoop *l_first;
- float *w = BLI_array_alloca(w, source->len);
+ float *w = BLI_array_alloca(w, f_src->len);
float co[2];
int i;
- if (source != target)
- BM_elem_attrs_copy(bm, bm, source, target);
+ if (f_src != f_dst)
+ BM_elem_attrs_copy(bm, bm, f_src, f_dst);
/* interpolate */
i = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(target);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst);
do {
mul_v2_m3v3(co, axis_mat, l_iter->v->co);
- interp_weights_poly_v2(w, cos_2d, source->len, co);
- CustomData_bmesh_interp(&bm->ldata, blocks_l, w, NULL, source->len, l_iter->head.data);
+ interp_weights_poly_v2(w, cos_2d, f_src->len, co);
+ CustomData_bmesh_interp(&bm->ldata, blocks_l, w, NULL, f_src->len, l_iter->head.data);
if (do_vertex) {
- CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, source->len, l_iter->v->head.data);
+ CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, f_src->len, l_iter->v->head.data);
}
} while (i++, (l_iter = l_iter->next) != l_first);
}
-void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source, const bool do_vertex)
+void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex)
{
BMLoop *l_iter;
BMLoop *l_first;
- void **blocks_l = BLI_array_alloca(blocks_l, source->len);
- void **blocks_v = do_vertex ? BLI_array_alloca(blocks_v, source->len) : NULL;
- float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len);
+ const void **blocks_l = BLI_array_alloca(blocks_l, f_src->len);
+ const void **blocks_v = do_vertex ? BLI_array_alloca(blocks_v, f_src->len) : NULL;
+ float (*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
int i;
/* convert the 3d coords into 2d for projection */
- BLI_assert(BM_face_is_normal_valid(source));
- axis_dominant_v3_to_m3(axis_mat, source->no);
+ BLI_assert(BM_face_is_normal_valid(f_src));
+ axis_dominant_v3_to_m3(axis_mat, f_src->no);
i = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(source);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
do {
mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
blocks_l[i] = l_iter->head.data;
if (do_vertex) blocks_v[i] = l_iter->v->head.data;
} while (i++, (l_iter = l_iter->next) != l_first);
- BM_face_interp_from_face_ex(bm, target, source, do_vertex,
+ BM_face_interp_from_face_ex(bm, f_dst, f_src, do_vertex,
blocks_l, blocks_v, cos_2d, axis_mat);
}
@@ -425,7 +433,7 @@ static void bm_loop_flip_disp(const float source_axis_x[3], const float source_a
disp[1] = (mat[0][0] * b[1] - b[0] * mat[1][0]) / d;
}
-static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *l_dst, BMFace *f_src)
+static void bm_loop_interp_mdisps(BMesh *bm, BMLoop *l_dst, const BMFace *f_src)
{
const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
MDisps *md_dst;
@@ -609,36 +617,37 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
}
/**
- * project the multires grid in target onto source's set of multires grids
+ * project the multires grid in target onto f_src's set of multires grids
*/
-void BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source)
+void BM_loop_interp_multires(BMesh *bm, BMLoop *l_dst, const BMFace *f_src)
{
- bm_loop_interp_mdisps(bm, target, source);
+ bm_loop_interp_mdisps(bm, l_dst, f_src);
}
/**
- * projects a single loop, target, onto source for customdata interpolation. multires is handled.
+ * projects a single loop, target, onto f_src for customdata interpolation. multires is handled.
* if do_vertex is true, target's vert data will also get interpolated.
*/
-void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
- const bool do_vertex, const bool do_multires)
+void BM_loop_interp_from_face(
+ BMesh *bm, BMLoop *l_dst, const BMFace *f_src,
+ const bool do_vertex, const bool do_multires)
{
BMLoop *l_iter;
BMLoop *l_first;
- void **vblocks = do_vertex ? BLI_array_alloca(vblocks, source->len) : NULL;
- void **blocks = BLI_array_alloca(blocks, source->len);
- float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len);
- float *w = BLI_array_alloca(w, source->len);
+ const void **vblocks = do_vertex ? BLI_array_alloca(vblocks, f_src->len) : NULL;
+ const void **blocks = BLI_array_alloca(blocks, f_src->len);
+ float (*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
+ float *w = BLI_array_alloca(w, f_src->len);
float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
float co[2];
int i;
/* convert the 3d coords into 2d for projection */
- BLI_assert(BM_face_is_normal_valid(source));
- axis_dominant_v3_to_m3(axis_mat, source->no);
+ BLI_assert(BM_face_is_normal_valid(f_src));
+ axis_dominant_v3_to_m3(axis_mat, f_src->no);
i = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(source);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
do {
mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
blocks[i] = l_iter->head.data;
@@ -648,48 +657,48 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
}
} while (i++, (l_iter = l_iter->next) != l_first);
- mul_v2_m3v3(co, axis_mat, target->v->co);
+ mul_v2_m3v3(co, axis_mat, l_dst->v->co);
/* interpolate */
- interp_weights_poly_v2(w, cos_2d, source->len, co);
- CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data);
+ interp_weights_poly_v2(w, cos_2d, f_src->len, co);
+ CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, f_src->len, l_dst->head.data);
if (do_vertex) {
- CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, source->len, target->v->head.data);
+ CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, f_src->len, l_dst->v->head.data);
}
if (do_multires) {
- bm_loop_interp_mdisps(bm, target, source);
+ bm_loop_interp_mdisps(bm, l_dst, f_src);
}
}
-void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source)
+void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src)
{
BMLoop *l_iter;
BMLoop *l_first;
- void **blocks = BLI_array_alloca(blocks, source->len);
- float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len);
- float *w = BLI_array_alloca(w, source->len);
+ const void **blocks = BLI_array_alloca(blocks, f_src->len);
+ float (*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
+ float *w = BLI_array_alloca(w, f_src->len);
float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
float co[2];
int i;
/* convert the 3d coords into 2d for projection */
- BLI_assert(BM_face_is_normal_valid(source));
- axis_dominant_v3_to_m3(axis_mat, source->no);
+ BLI_assert(BM_face_is_normal_valid(f_src));
+ axis_dominant_v3_to_m3(axis_mat, f_src->no);
i = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(source);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
do {
mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
blocks[i] = l_iter->v->head.data;
} while (i++, (l_iter = l_iter->next) != l_first);
- mul_v2_m3v3(co, axis_mat, v->co);
+ mul_v2_m3v3(co, axis_mat, v_dst->co);
/* interpolate */
- interp_weights_poly_v2(w, cos_2d, source->len, co);
- CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, source->len, v->head.data);
+ interp_weights_poly_v2(w, cos_2d, f_src->len, co);
+ CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, f_src->len, v_dst->head.data);
}
static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
@@ -812,6 +821,7 @@ void BM_data_layer_free(BMesh *bm, CustomData *data, int type)
has_layer = CustomData_free_layer_active(data, type, 0);
/* assert because its expensive to realloc - better not do if layer isnt present */
BLI_assert(has_layer != false);
+ UNUSED_VARS_NDEBUG(has_layer);
update_data_blocks(bm, &olddata, data);
if (olddata.layers) MEM_freeN(olddata.layers);
@@ -831,7 +841,8 @@ void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n)
has_layer = CustomData_free_layer(data, type, 0, CustomData_get_layer_index_n(data, type, n));
/* assert because its expensive to realloc - better not do if layer isnt present */
BLI_assert(has_layer != false);
-
+ UNUSED_VARS_NDEBUG(has_layer);
+
update_data_blocks(bm, &olddata, data);
if (olddata.layers) MEM_freeN(olddata.layers);
}
@@ -893,3 +904,249 @@ void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float
float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
if (f) *f = val;
}
+
+/** \name Loop interpolation functions: BM_vert_loop_groups_data_layer_***
+ *
+ * Handling loop custom-data such as UV's, while keeping contiguous fans is rather tedious.
+ * Especially when a verts loops can have multiple CustomData layers,
+ * and each layer can have multiple (different) contiguous fans.
+ * Said differently, a single vertices loops may span multiple UV islands.
+ *
+ * These functions snapshot vertices loops, storing each contiguous fan in its own group.
+ * The caller can manipulate the loops, then re-combine the CustomData values.
+ *
+ * While these functions don't explicitly handle multiple layers at once,
+ * the caller can simply store its own list.
+ *
+ * \note Currently they are averaged back together (weighted by loop angle)
+ * but we could copy add other methods to re-combine CustomData-Loop-Fans.
+ *
+ * \{ */
+
+struct LoopWalkCtx {
+ /* same for all groups */
+ int type;
+ int cd_layer_offset;
+ const float *loop_weights;
+ MemArena *arena;
+
+ /* --- Per loop fan vars --- */
+
+ /* reference for this contiguous fan */
+ const void *data_ref;
+ int data_len;
+
+ /* accumulate 'LoopGroupCD.weight' to make unit length */
+ float weight_accum;
+
+ /* both arrays the size of the 'BM_vert_face_count(v)'
+ * each contiguous fan gets a slide of these arrays */
+ void **data_array;
+ int *data_index_array;
+ float *weight_array;
+};
+
+/* Store vars to pass into 'CustomData_bmesh_interp' */
+struct LoopGroupCD {
+ /* direct customdata pointer array */
+ void **data;
+ /* weights (aligned with 'data') */
+ float *data_weights;
+ /* index-in-face */
+ int *data_index;
+ /* number of loops in the fan */
+ int data_len;
+};
+
+static void bm_loop_walk_add(struct LoopWalkCtx *lwc, BMLoop *l)
+{
+ const int i = BM_elem_index_get(l);
+ const float w = lwc->loop_weights[i];
+ BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG);
+ lwc->data_array[lwc->data_len] = BM_ELEM_CD_GET_VOID_P(l, lwc->cd_layer_offset);
+ lwc->data_index_array[lwc->data_len] = i;
+ lwc->weight_array[lwc->data_len] = w;
+ lwc->weight_accum += w;
+
+ lwc->data_len += 1;
+}
+
+/**
+ * called recursively, keep stack-usage minimal.
+ *
+ * \note called for fan matching so we're pretty much safe not to break the stack
+ */
+static void bm_loop_walk_data(struct LoopWalkCtx *lwc, BMLoop *l_walk)
+{
+ int i;
+
+ BLI_assert(CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_walk, lwc->cd_layer_offset)));
+ BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG) == false);
+
+ bm_loop_walk_add(lwc, l_walk);
+
+ /* recurse around this loop-fan (in both directions) */
+ for (i = 0; i < 2; i++) {
+ BMLoop *l_other = ((i == 0) ? l_walk : l_walk->prev)->radial_next;
+ if (l_other->radial_next != l_other) {
+ if (l_other->v != l_walk->v) {
+ l_other = l_other->next;
+ }
+ BLI_assert(l_other->v == l_walk->v);
+ if (!BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) {
+ if (CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_other, lwc->cd_layer_offset))) {
+ bm_loop_walk_data(lwc, l_other);
+ }
+ }
+ }
+ }
+}
+
+LinkNode *BM_vert_loop_groups_data_layer_create(
+ BMesh *bm, BMVert *v, const int layer_n, const float *loop_weights, MemArena *arena)
+{
+ struct LoopWalkCtx lwc;
+ LinkNode *groups = NULL;
+ BMLoop *l;
+ BMIter liter;
+ int loop_num;
+
+
+ lwc.type = bm->ldata.layers[layer_n].type;
+ lwc.cd_layer_offset = bm->ldata.layers[layer_n].offset;
+ lwc.loop_weights = loop_weights;
+ lwc.arena = arena;
+
+ loop_num = 0;
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG);
+ BM_elem_index_set(l, loop_num); /* set_dirty! */
+ loop_num++;
+ }
+ bm->elem_index_dirty |= BM_LOOP;
+
+ lwc.data_len = 0;
+ lwc.data_array = BLI_memarena_alloc(lwc.arena, sizeof(void *) * loop_num);
+ lwc.data_index_array = BLI_memarena_alloc(lwc.arena, sizeof(int) * loop_num);
+ lwc.weight_array = BLI_memarena_alloc(lwc.arena, sizeof(float) * loop_num);
+
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ if (!BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) {
+ struct LoopGroupCD *lf = BLI_memarena_alloc(lwc.arena, sizeof(*lf));
+ int len_prev = lwc.data_len;
+
+ lwc.data_ref = BM_ELEM_CD_GET_VOID_P(l, lwc.cd_layer_offset);
+
+ /* assign len-last */
+ lf->data = &lwc.data_array[lwc.data_len];
+ lf->data_index = &lwc.data_index_array[lwc.data_len];
+ lf->data_weights = &lwc.weight_array[lwc.data_len];
+ lwc.weight_accum = 0.0f;
+
+ /* new group */
+ bm_loop_walk_data(&lwc, l);
+ lf->data_len = lwc.data_len - len_prev;
+
+ if (LIKELY(lwc.weight_accum != 0.0f)) {
+ mul_vn_fl(lf->data_weights, lf->data_len, 1.0f / lwc.weight_accum);
+ }
+ else {
+ fill_vn_fl(lf->data_weights, lf->data_len, 1.0f / (float)lf->data_len);
+ }
+
+ BLI_linklist_prepend_arena(&groups, lf, lwc.arena);
+ }
+ }
+
+ BLI_assert(lwc.data_len == loop_num);
+
+ return groups;
+}
+
+static void bm_vert_loop_groups_data_layer_merge__single(
+ BMesh *bm, void *lf_p, int layer_n,
+ void *data_tmp)
+{
+ struct LoopGroupCD *lf = lf_p;
+ const int type = bm->ldata.layers[layer_n].type;
+ int i;
+ const float *data_weights;
+
+ data_weights = lf->data_weights;
+
+ CustomData_bmesh_interp_n(
+ &bm->ldata, (const void **)lf->data,
+ data_weights, NULL, lf->data_len, data_tmp, layer_n);
+
+ for (i = 0; i < lf->data_len; i++) {
+ CustomData_copy_elements(type, data_tmp, lf->data[i], 1);
+ }
+}
+
+static void bm_vert_loop_groups_data_layer_merge_weights__single(
+ BMesh *bm, void *lf_p, const int layer_n, void *data_tmp,
+ const float *loop_weights)
+{
+ struct LoopGroupCD *lf = lf_p;
+ const int type = bm->ldata.layers[layer_n].type;
+ int i;
+ const float *data_weights;
+
+ /* re-weight */
+ float *temp_weights = BLI_array_alloca(temp_weights, lf->data_len);
+ float weight_accum = 0.0f;
+
+ for (i = 0; i < lf->data_len; i++) {
+ float w = loop_weights[lf->data_index[i]] * lf->data_weights[i];
+ temp_weights[i] = w;
+ weight_accum += w;
+ }
+
+ if (LIKELY(weight_accum != 0.0f)) {
+ mul_vn_fl(temp_weights, lf->data_len, 1.0f / weight_accum);
+ data_weights = temp_weights;
+ }
+ else {
+ data_weights = lf->data_weights;
+ }
+
+ CustomData_bmesh_interp_n(
+ &bm->ldata, (const void **)lf->data,
+ data_weights, NULL, lf->data_len, data_tmp, layer_n);
+
+ for (i = 0; i < lf->data_len; i++) {
+ CustomData_copy_elements(type, data_tmp, lf->data[i], 1);
+ }
+}
+
+/**
+ * Take existing custom data and merge each fan's data.
+ */
+void BM_vert_loop_groups_data_layer_merge(BMesh *bm, LinkNode *groups, const int layer_n)
+{
+ const int type = bm->ldata.layers[layer_n].type;
+ const int size = CustomData_sizeof(type);
+ void *data_tmp = alloca(size);
+
+ do {
+ bm_vert_loop_groups_data_layer_merge__single(bm, groups->link, layer_n, data_tmp);
+ } while ((groups = groups->next));
+}
+
+/**
+ * A version of #BM_vert_loop_groups_data_layer_merge
+ * that takes an array of loop-weights (aligned with #BM_LOOPS_OF_VERT iterator)
+ */
+void BM_vert_loop_groups_data_layer_merge_weights(
+ BMesh *bm, LinkNode *groups, const int layer_n, const float *loop_weights)
+{
+ const int type = bm->ldata.layers[layer_n].type;
+ const int size = CustomData_sizeof(type);
+ void *data_tmp = alloca(size);
+
+ do {
+ bm_vert_loop_groups_data_layer_merge_weights__single(bm, groups->link, layer_n, data_tmp, loop_weights);
+ } while ((groups = groups->next));
+}
+
+/** \} */
diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h
index c605ad31ae7..969e92f37db 100644
--- a/source/blender/bmesh/intern/bmesh_interp.h
+++ b/source/blender/bmesh/intern/bmesh_interp.h
@@ -27,12 +27,15 @@
* \ingroup bmesh
*/
-void BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source);
-void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source);
+struct LinkNode;
+struct MemArena;
-void BM_data_interp_from_verts(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, const float fac);
-void BM_data_interp_from_edges(BMesh *bm, BMEdge *e1, BMEdge *e2, BMEdge *e, const float fac);
-void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, BMEdge *e1, const float fac);
+void BM_loop_interp_multires(BMesh *bm, BMLoop *l_dst, const BMFace *f_src);
+void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src);
+
+void BM_data_interp_from_verts(BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v_dst, const float fac);
+void BM_data_interp_from_edges(BMesh *bm, const BMEdge *e_src_1, const BMEdge *e_src_2, BMEdge *e_dst, const float fac);
+void BM_data_interp_face_vert_edge(BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v, BMEdge *e, const float fac);
void BM_data_layer_add(BMesh *bm, CustomData *data, int type);
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name);
void BM_data_layer_free(BMesh *bm, CustomData *data, int type);
@@ -42,12 +45,26 @@ void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int d
float BM_elem_float_data_get(CustomData *cd, void *element, int type);
void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val);
-void BM_face_interp_from_face_ex(BMesh *bm, BMFace *target, BMFace *source, const bool do_vertex,
- void **blocks, void **blocks_v, float (*cos_2d)[2], float axis_mat[3][3]);
-void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source, const bool do_vertex);
-void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
- const bool do_vertex, const bool do_multires);
+void BM_face_interp_from_face_ex(
+ BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex,
+ const void **blocks, const void **blocks_v,
+ float (*cos_2d)[2], float axis_mat[3][3]);
+void BM_face_interp_from_face(
+ BMesh *bm, BMFace *f_dst, const BMFace *f_src,
+ const bool do_vertex);
+void BM_loop_interp_from_face(
+ BMesh *bm, BMLoop *l_dst, const BMFace *f_src,
+ const bool do_vertex, const bool do_multires);
void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f);
+struct LinkNode *BM_vert_loop_groups_data_layer_create(
+ BMesh *bm, BMVert *v, const int layer_n,
+ const float *loop_weights, struct MemArena *arena);
+void BM_vert_loop_groups_data_layer_merge(
+ BMesh *bm, struct LinkNode *groups, const int layer_n);
+void BM_vert_loop_groups_data_layer_merge_weights(
+ BMesh *bm, struct LinkNode *groups, const int layer_n,
+ const float *loop_weights);
+
#endif /* __BMESH_INTERP_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c
index 476878ad38c..4dc27d75a55 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.c
+++ b/source/blender/bmesh/intern/bmesh_iterators.c
@@ -56,7 +56,7 @@ const char bm_iter_itype_htype_map[BM_ITYPE_MAX] = {
/**
* Utility function.
*/
-int BM_iter_mesh_count(BMesh *bm, const char itype)
+int BM_iter_mesh_count(const char itype, BMesh *bm)
{
int count;
diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h
index 44be7072e71..49e511bdcb5 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.h
+++ b/source/blender/bmesh/intern/bmesh_iterators.h
@@ -84,30 +84,40 @@ typedef enum BMIterType {
extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX];
#define BM_ITER_MESH(ele, iter, bm, itype) \
- for (ele = BM_iter_new(iter, bm, itype, NULL); ele; ele = BM_iter_step(iter))
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
+ ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar) \
- for (ele = BM_iter_new(iter, bm, itype, NULL), indexvar = 0; ele; ele = BM_iter_step(iter), (indexvar)++)
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL), indexvar = 0; \
+ ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++)
/* a version of BM_ITER_MESH which keeps the next item in storage
* so we can delete the current item, see bug [#36923] */
#ifdef DEBUG
# define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \
- for (ele = BM_iter_new(iter, bm, itype, NULL); \
- ele ? ((void)((iter)->count = BM_iter_mesh_count(bm, itype)), \
- (void)(ele_next = BM_iter_step(iter)), 1) : 0; \
- ele = ele_next)
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
+ ele ? ((void)((iter)->count = BM_iter_mesh_count(itype, bm)), \
+ (void)(ele_next = BM_iter_step(iter)), 1) : 0; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = ele_next)
#else
# define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \
- for (ele = BM_iter_new(iter, bm, itype, NULL); ele ? ((ele_next = BM_iter_step(iter)), 1) : 0; ele = ele_next)
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
+ ele ? ((BM_CHECK_TYPE_ELEM_ASSIGN(ele_next) = BM_iter_step(iter)), 1) : 0; \
+ ele = ele_next)
#endif
#define BM_ITER_ELEM(ele, iter, data, itype) \
- for (ele = BM_iter_new(iter, NULL, itype, data); ele; ele = BM_iter_step(iter))
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data); \
+ ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
#define BM_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar) \
- for (ele = BM_iter_new(iter, NULL, itype, data), indexvar = 0; ele; ele = BM_iter_step(iter), (indexvar)++)
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data), indexvar = 0; \
+ ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++)
/* iterator type structs */
struct BMIter__elem_of_mesh {
@@ -185,7 +195,6 @@ typedef struct BMIter {
char itype;
} BMIter;
-int BM_iter_mesh_count(BMesh *bm, const char itype);
void *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index) ATTR_WARN_UNUSED_RESULT;
int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len);
void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len,
@@ -196,9 +205,9 @@ void *BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *sl
int *r_len,
/* optional args to avoid an alloc (normally stack array) */
void **stack_array, int stack_array_size);
-
int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value);
int BMO_iter_elem_count_flag(BMesh *bm, const char itype, void *data, const short oflag, const bool value);
+int BM_iter_mesh_count(const char itype, BMesh *bm);
int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value);
/* private for bmesh_iterators_inline.c */
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 709a174731f..158c2aa4263 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -582,7 +582,7 @@ void BM_log_free(BMLog *log)
/* Get the number of log entries */
int BM_log_length(const BMLog *log)
{
- return BLI_countlist(&log->entries);
+ return BLI_listbase_count(&log->entries);
}
/* Apply a consistent ordering to BMesh vertices */
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index ee35d8cd1d2..8aa64906019 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -41,6 +41,7 @@
#include "BLI_listbase.h"
#include "bmesh.h"
+#include "bmesh_structure.h"
static void recount_totsels(BMesh *bm)
{
@@ -69,6 +70,69 @@ static void recount_totsels(BMesh *bm)
}
}
+/** \name BMesh helper functions for selection flushing.
+ * \{ */
+
+static bool bm_vert_is_edge_select_any_other(BMVert *v, BMEdge *e_first)
+{
+ BMEdge *e_iter = e_first;
+
+ /* start by stepping over the current edge */
+ while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first) {
+ if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+#if 0
+static bool bm_vert_is_edge_select_any(BMVert *v)
+{
+ if (v->e) {
+ BMEdge *e_iter, *e_first;
+ e_iter = e_first = v->e;
+ do {
+ if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT)) {
+ return true;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return false;
+}
+#endif
+
+static bool bm_edge_is_face_select_any_other(BMLoop *l_first)
+{
+ BMLoop *l_iter = l_first;
+
+ /* start by stepping over the current face */
+ while ((l_iter = l_iter->radial_next) != l_first) {
+ if (BM_elem_flag_test(l_iter->f, BM_ELEM_SELECT)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+#if 0
+static bool bm_edge_is_face_select_any(BMEdge *e)
+{
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ if (BM_elem_flag_test(l_iter->f, BM_ELEM_SELECT)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ return false;
+}
+#endif
+
+/** \} */
+
/**
* \brief Select Mode Clean
*
@@ -341,8 +405,8 @@ void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select)
if (select) {
if (!BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- bm->totvertsel += 1;
BM_elem_flag_enable(v, BM_ELEM_SELECT);
+ bm->totvertsel += 1;
}
}
else {
@@ -367,39 +431,27 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
}
if (select) {
- if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) bm->totedgesel += 1;
-
- BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ bm->totedgesel += 1;
+ }
BM_vert_select_set(bm, e->v1, true);
BM_vert_select_set(bm, e->v2, true);
}
else {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) bm->totedgesel -= 1;
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ bm->totedgesel -= 1;
+ }
if ((bm->selectmode & SCE_SELECT_VERTEX) == 0) {
- BMIter iter;
- BMVert *verts[2] = {e->v1, e->v2};
- BMEdge *e2;
int i;
/* check if the vert is used by a selected edge */
for (i = 0; i < 2; i++) {
- bool deselect = true;
-
- for (e2 = BM_iter_new(&iter, bm, BM_EDGES_OF_VERT, verts[i]); e2; e2 = BM_iter_step(&iter)) {
- if (e2 == e) {
- continue;
- }
-
- if (BM_elem_flag_test(e2, BM_ELEM_SELECT)) {
- deselect = false;
- break;
- }
- }
-
- if (deselect) {
- BM_vert_select_set(bm, verts[i], false);
+ BMVert *v = *((&e->v1) + i);
+ if (bm_vert_is_edge_select_any_other(v, e) == false) {
+ BM_vert_select_set(bm, v, false);
}
}
}
@@ -430,10 +482,10 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
if (select) {
if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- bm->totfacesel++;
+ BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ bm->totfacesel += 1;
}
- BM_elem_flag_enable(f, BM_ELEM_SELECT);
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
BM_vert_select_set(bm, l_iter->v, true);
@@ -441,42 +493,80 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
} while ((l_iter = l_iter->next) != l_first);
}
else {
- BMIter liter;
- BMLoop *l;
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) bm->totfacesel -= 1;
- BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ bm->totfacesel -= 1;
+ }
/* flush down to edges */
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- BMIter fiter;
- BMFace *f2;
- BM_ITER_ELEM (f2, &fiter, l->e, BM_FACES_OF_EDGE) {
- if (BM_elem_flag_test(f2, BM_ELEM_SELECT))
- break;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ /* vertex flushing is handled below */
+ if (bm_edge_is_face_select_any_other(l_iter) == false) {
+ BM_edge_select_set_noflush(bm, l_iter->e, false);
}
+ } while ((l_iter = l_iter->next) != l_first);
- if (!f2) {
- BM_edge_select_set(bm, l->e, false);
+ /* flush down to verts */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (bm_vert_is_edge_select_any_other(l_iter->v, l_iter->e) == false) {
+ BM_vert_select_set(bm, l_iter->v, false);
}
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+}
+
+/** \name Non flushing versions element selection.
+ * \{ */
+
+void BM_edge_select_set_noflush(BMesh *bm, BMEdge *e, const bool select)
+{
+ BLI_assert(e->head.htype == BM_EDGE);
+
+ if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ return;
+ }
+
+ if (select) {
+ if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ bm->totedgesel += 1;
}
+ }
+ else {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ bm->totedgesel -= 1;
+ }
+ }
+}
- /* flush down to verts */
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- BMIter eiter;
- BMEdge *e;
- BM_ITER_ELEM (e, &eiter, l->v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT))
- break;
- }
+void BM_face_select_set_noflush(BMesh *bm, BMFace *f, const bool select)
+{
+ BLI_assert(f->head.htype == BM_FACE);
- if (!e) {
- BM_vert_select_set(bm, l->v, false);
- }
+ if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ return;
+ }
+
+ if (select) {
+ if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ bm->totfacesel += 1;
+ }
+ }
+ else {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ bm->totfacesel -= 1;
}
}
}
+/** \} */
+
/**
* Select Mode Set
*
diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h
index 9e0c0923164..15f972c6435 100644
--- a/source/blender/bmesh/intern/bmesh_marking.h
+++ b/source/blender/bmesh/intern/bmesh_marking.h
@@ -59,6 +59,10 @@ void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select);
void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select);
void BM_face_select_set(BMesh *bm, BMFace *f, const bool select);
+/* lower level functions which don't do flushing */
+void BM_edge_select_set_noflush(BMesh *bm, BMEdge *e, const bool select);
+void BM_face_select_set_noflush(BMesh *bm, BMFace *e, const bool select);
+
void BM_mesh_select_mode_clean_ex(BMesh *bm, const short selectmode);
void BM_mesh_select_mode_clean(BMesh *bm);
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index b16ea42304a..9a2869b64ef 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -34,10 +34,12 @@
#include "BLI_linklist_stack.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_stack.h"
#include "BLI_utildefines.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_editmesh.h"
+#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "intern/bmesh_private.h"
@@ -438,7 +440,8 @@ void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (*
static void bm_mesh_edges_sharp_tag(BMesh *bm, const float (*vnos)[3], const float (*fnos)[3], float split_angle,
float (*r_lnos)[3])
{
- BMIter eiter;
+ BMIter eiter, viter;
+ BMVert *v;
BMEdge *e;
int i;
@@ -450,15 +453,18 @@ static void bm_mesh_edges_sharp_tag(BMesh *bm, const float (*vnos)[3], const flo
{
char htype = BM_LOOP;
- if (vnos) {
- htype |= BM_VERT;
- }
if (fnos) {
htype |= BM_FACE;
}
BM_mesh_elem_index_ensure(bm, htype);
}
+ /* Clear all vertices' tags (means they are all smooth for now). */
+ BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
+ BM_elem_index_set(v, i); /* set_inline */
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+ }
+
/* This first loop checks which edges are actually smooth, and pre-populate lnos with vnos (as if they were
* all smooth).
*/
@@ -481,13 +487,13 @@ static void bm_mesh_edges_sharp_tag(BMesh *bm, const float (*vnos)[3], const flo
* If the angle between both its polys' normals is below split_angle value,
* and it is tagged as such,
* and both its faces are smooth,
- * and both its faces have compatible (non-flipped) normals, i.e. both loops on the same edge do not share
- * the same vertex.
+ * and both its faces have compatible (non-flipped) normals,
+ * i.e. both loops on the same edge do not share the same vertex.
*/
if (is_angle_smooth &&
- BM_elem_flag_test_bool(e, BM_ELEM_SMOOTH) &&
- BM_elem_flag_test_bool(l_a->f, BM_ELEM_SMOOTH) &&
- BM_elem_flag_test_bool(l_b->f, BM_ELEM_SMOOTH) &&
+ BM_elem_flag_test(e, BM_ELEM_SMOOTH) &&
+ BM_elem_flag_test(l_a->f, BM_ELEM_SMOOTH) &&
+ BM_elem_flag_test(l_b->f, BM_ELEM_SMOOTH) &&
l_a->v != l_b->v)
{
const float *no;
@@ -499,20 +505,40 @@ static void bm_mesh_edges_sharp_tag(BMesh *bm, const float (*vnos)[3], const flo
no = vnos ? vnos[BM_elem_index_get(l_b->v)] : l_b->v->no;
copy_v3_v3(r_lnos[BM_elem_index_get(l_b)], no);
}
+ else {
+ /* Sharp edge, tag its verts as such. */
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+ }
+ }
+ else {
+ /* Sharp edge, tag its verts as such. */
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
}
}
- bm->elem_index_dirty &= ~BM_EDGE;
+ bm->elem_index_dirty &= ~(BM_EDGE | BM_VERT);
}
-/* BMesh version of BKE_mesh_normals_loop_split() in mesh_evaluate.c */
-static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const float (*fnos)[3], float (*r_lnos)[3])
+/* BMesh version of BKE_mesh_normals_loop_split() in mesh_evaluate.c
+ * Will use first clnors_data array, and fallback to cd_loop_clnors_offset (use NULL and -1 to not use clnors). */
+static void bm_mesh_loops_calc_normals(
+ BMesh *bm, const float (*vcos)[3], const float (*fnos)[3], float (*r_lnos)[3],
+ MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset)
{
BMIter fiter;
BMFace *f_curr;
+ const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
+
+ MLoopNorSpaceArray _lnors_spacearr = {NULL};
/* Temp normal stack. */
BLI_SMALLSTACK_DECLARE(normal, float *);
+ /* Temp clnors stack. */
+ BLI_SMALLSTACK_DECLARE(clnors, short *);
+ /* Temp edge vectors stack, only used when computing lnor spacearr. */
+ BLI_Stack *edge_vectors = NULL;
{
char htype = BM_LOOP;
@@ -525,6 +551,15 @@ static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const
BM_mesh_elem_index_ensure(bm, htype);
}
+ if (!r_lnors_spacearr && has_clnors) {
+ /* We need to compute lnor spacearr if some custom lnor data are given to us! */
+ r_lnors_spacearr = &_lnors_spacearr;
+ }
+ if (r_lnors_spacearr) {
+ BKE_lnor_spacearr_init(r_lnors_spacearr, bm->totloop);
+ edge_vectors = BLI_stack_new(sizeof(float[3]), __func__);
+ }
+
/* We now know edges that can be smoothed (they are tagged), and edges that will be hard (they aren't).
* Now, time to generate the normals.
*/
@@ -533,8 +568,10 @@ static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const
l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
do {
- if (BM_elem_flag_test_bool(l_curr->e, BM_ELEM_TAG)) {
- /* A smooth edge.
+ if (BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) &&
+ (!r_lnors_spacearr || BM_elem_flag_test(l_curr->v, BM_ELEM_TAG)))
+ {
+ /* A smooth edge, and we are not generating lnors_spacearr, or the related vertex is sharp.
* We skip it because it is either:
* - in the middle of a 'smooth fan' already computed (or that will be as soon as we hit
* one of its ends, i.e. one of its two sharp edges), or...
@@ -542,12 +579,45 @@ static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const
* are just fine!
*/
}
- else if (!BM_elem_flag_test_bool(l_curr->prev->e, BM_ELEM_TAG)) {
+ else if (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) &&
+ !BM_elem_flag_test(l_curr->prev->e, BM_ELEM_TAG))
+ {
/* Simple case (both edges around that vertex are sharp in related polygon),
* this vertex just takes its poly normal.
*/
+ const int l_curr_index = BM_elem_index_get(l_curr);
const float *no = fnos ? fnos[BM_elem_index_get(f_curr)] : f_curr->no;
- copy_v3_v3(r_lnos[BM_elem_index_get(l_curr)], no);
+ copy_v3_v3(r_lnos[l_curr_index], no);
+
+ /* If needed, generate this (simple!) lnor space. */
+ if (r_lnors_spacearr) {
+ float vec_curr[3], vec_prev[3];
+ MLoopNorSpace *lnor_space = BKE_lnor_space_create(r_lnors_spacearr);
+
+ {
+ const BMVert *v_pivot = l_curr->v;
+ const float *co_pivot = vcos ? vcos[BM_elem_index_get(v_pivot)] : v_pivot->co;
+ const BMVert *v_1 = BM_edge_other_vert(l_curr->e, v_pivot);
+ const float *co_1 = vcos ? vcos[BM_elem_index_get(v_1)] : v_1->co;
+ const BMVert *v_2 = BM_edge_other_vert(l_curr->prev->e, v_pivot);
+ const float *co_2 = vcos ? vcos[BM_elem_index_get(v_2)] : v_2->co;
+
+ sub_v3_v3v3(vec_curr, co_1, co_pivot);
+ normalize_v3(vec_curr);
+ sub_v3_v3v3(vec_prev, co_2, co_pivot);
+ normalize_v3(vec_prev);
+ }
+
+ BKE_lnor_space_define(lnor_space, r_lnos[l_curr_index], vec_curr, vec_prev, NULL);
+ /* We know there is only one loop in this space, no need to create a linklist in this case... */
+ BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, l_curr_index, false);
+
+ if (has_clnors) {
+ short (*clnor)[2] = clnors_data ? &clnors_data[l_curr_index] :
+ BM_ELEM_CD_GET_VOID_P(l_curr, cd_loop_clnors_offset);
+ BKE_lnor_space_custom_data_to_normal(lnor_space, *clnor, r_lnos[l_curr_index]);
+ }
+ }
}
/* We *do not need* to check/tag loops as already computed!
* Due to the fact a loop only links to one of its two edges, a same fan *will never be walked more than
@@ -567,13 +637,26 @@ static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const
*/
BMVert *v_pivot = l_curr->v;
BMEdge *e_next;
+ const BMEdge *e_org = l_curr->e;
BMLoop *lfan_pivot, *lfan_pivot_next;
+ int lfan_pivot_index;
float lnor[3] = {0.0f, 0.0f, 0.0f};
- float vec_curr[3], vec_next[3];
+ float vec_curr[3], vec_next[3], vec_org[3];
+
+ /* We validate clnors data on the fly - cheapest way to do! */
+ int clnors_avg[2] = {0, 0};
+ short (*clnor_ref)[2] = NULL;
+ int clnors_nbr = 0;
+ bool clnors_invalid = false;
const float *co_pivot = vcos ? vcos[BM_elem_index_get(v_pivot)] : v_pivot->co;
+ MLoopNorSpace *lnor_space = r_lnors_spacearr ? BKE_lnor_space_create(r_lnors_spacearr) : NULL;
+
+ BLI_assert((edge_vectors == NULL) || BLI_stack_is_empty(edge_vectors));
+
lfan_pivot = l_curr;
+ lfan_pivot_index = BM_elem_index_get(lfan_pivot);
e_next = lfan_pivot->e; /* Current edge here, actually! */
/* Only need to compute previous edge's vector once, then we can just reuse old current one! */
@@ -581,8 +664,13 @@ static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const
const BMVert *v_2 = BM_edge_other_vert(e_next, v_pivot);
const float *co_2 = vcos ? vcos[BM_elem_index_get(v_2)] : v_2->co;
- sub_v3_v3v3(vec_curr, co_2, co_pivot);
- normalize_v3(vec_curr);
+ sub_v3_v3v3(vec_org, co_2, co_pivot);
+ normalize_v3(vec_org);
+ copy_v3_v3(vec_curr, vec_org);
+
+ if (r_lnors_spacearr) {
+ BLI_stack_push(edge_vectors, vec_org);
+ }
}
while (true) {
@@ -617,12 +705,38 @@ static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const
const float *no = fnos ? fnos[BM_elem_index_get(f)] : f->no;
/* Accumulate */
madd_v3_v3fl(lnor, no, fac);
+
+ if (has_clnors) {
+ /* Accumulate all clnors, if they are not all equal we have to fix that! */
+ short (*clnor)[2] = clnors_data ? &clnors_data[lfan_pivot_index] :
+ BM_ELEM_CD_GET_VOID_P(lfan_pivot, cd_loop_clnors_offset);
+ if (clnors_nbr) {
+ clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
+ }
+ else {
+ clnor_ref = clnor;
+ }
+ clnors_avg[0] += (*clnor)[0];
+ clnors_avg[1] += (*clnor)[1];
+ clnors_nbr++;
+ /* We store here a pointer to all custom lnors processed. */
+ BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor);
+ }
}
/* We store here a pointer to all loop-normals processed. */
- BLI_SMALLSTACK_PUSH(normal, (float *)r_lnos[BM_elem_index_get(lfan_pivot)]);
+ BLI_SMALLSTACK_PUSH(normal, (float *)r_lnos[lfan_pivot_index]);
+
+ if (r_lnors_spacearr) {
+ /* Assign current lnor space to current 'vertex' loop. */
+ BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, lfan_pivot_index, true);
+ if (e_next != e_org) {
+ /* We store here all edges-normalized vectors processed. */
+ BLI_stack_push(edge_vectors, vec_next);
+ }
+ }
- if (!BM_elem_flag_test_bool(e_next, BM_ELEM_TAG)) {
+ if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) {
/* Next edge is sharp, we have finished with this fan of faces around this vert! */
break;
}
@@ -631,23 +745,105 @@ static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const
copy_v3_v3(vec_curr, vec_next);
/* Next pivot loop to current one. */
lfan_pivot = lfan_pivot_next;
+ lfan_pivot_index = BM_elem_index_get(lfan_pivot);
}
- /* In case we get a zero normal here, just use vertex normal already set! */
- if (LIKELY(normalize_v3(lnor) != 0.0f)) {
- /* Copy back the final computed normal into all related loop-normals. */
- float *nor;
- while ((nor = BLI_SMALLSTACK_POP(normal))) {
- copy_v3_v3(nor, lnor);
+ {
+ float lnor_len = normalize_v3(lnor);
+
+ /* If we are generating lnor spacearr, we can now define the one for this fan. */
+ if (r_lnors_spacearr) {
+ if (UNLIKELY(lnor_len == 0.0f)) {
+ /* Use vertex normal as fallback! */
+ copy_v3_v3(lnor, r_lnos[lfan_pivot_index]);
+ lnor_len = 1.0f;
+ }
+
+ BKE_lnor_space_define(lnor_space, lnor, vec_org, vec_next, edge_vectors);
+
+ if (has_clnors) {
+ if (clnors_invalid) {
+ short *clnor;
+
+ clnors_avg[0] /= clnors_nbr;
+ clnors_avg[1] /= clnors_nbr;
+ /* Fix/update all clnors of this fan with computed average value. */
+ printf("Invalid clnors in this fan!\n");
+ while ((clnor = BLI_SMALLSTACK_POP(clnors))) {
+ //print_v2("org clnor", clnor);
+ clnor[0] = (short)clnors_avg[0];
+ clnor[1] = (short)clnors_avg[1];
+ }
+ //print_v2("new clnors", clnors_avg);
+ }
+ else {
+ /* We still have to consume the stack! */
+ while (BLI_SMALLSTACK_POP(clnors));
+ }
+ BKE_lnor_space_custom_data_to_normal(lnor_space, *clnor_ref, lnor);
+ }
+ }
+
+ /* In case we get a zero normal here, just use vertex normal already set! */
+ if (LIKELY(lnor_len != 0.0f)) {
+ /* Copy back the final computed normal into all related loop-normals. */
+ float *nor;
+
+ while ((nor = BLI_SMALLSTACK_POP(normal))) {
+ copy_v3_v3(nor, lnor);
+ }
+ }
+ else {
+ /* We still have to consume the stack! */
+ while (BLI_SMALLSTACK_POP(normal));
}
}
- else {
- /* We still have to clear the stack! */
- while (BLI_SMALLSTACK_POP(normal));
+
+ /* Tag related vertex as sharp, to avoid fanning around it again (in case it was a smooth one). */
+ if (r_lnors_spacearr) {
+ BM_elem_flag_enable(l_curr->v, BM_ELEM_TAG);
}
}
} while ((l_curr = l_curr->next) != l_first);
}
+
+ if (r_lnors_spacearr) {
+ BLI_stack_free(edge_vectors);
+ if (r_lnors_spacearr == &_lnors_spacearr) {
+ BKE_lnor_spacearr_free(r_lnors_spacearr);
+ }
+ }
+}
+
+static void bm_mesh_loops_calc_normals_no_autosmooth(
+ BMesh *bm, const float (*vnos)[3], const float (*fnos)[3], float (*r_lnos)[3])
+{
+ BMIter fiter;
+ BMFace *f_curr;
+
+ {
+ char htype = BM_LOOP;
+ if (vnos) {
+ htype |= BM_VERT;
+ }
+ if (fnos) {
+ htype |= BM_FACE;
+ }
+ BM_mesh_elem_index_ensure(bm, htype);
+ }
+
+ BM_ITER_MESH (f_curr, &fiter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l_curr, *l_first;
+ const bool is_face_flat = !BM_elem_flag_test(f_curr, BM_ELEM_SMOOTH);
+
+ l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
+ do {
+ const float *no = is_face_flat ? (fnos ? fnos[BM_elem_index_get(f_curr)] : f_curr->no) :
+ (vnos ? vnos[BM_elem_index_get(l_curr->v)] : l_curr->v->no);
+ copy_v3_v3(r_lnos[BM_elem_index_get(l_curr)], no);
+
+ } while ((l_curr = l_curr->next) != l_first);
+ }
}
#if 0 /* Unused currently */
@@ -657,13 +853,24 @@ static void bm_mesh_loops_calc_normals(BMesh *bm, const float (*vcos)[3], const
* Updates the loop normals of a mesh. Assumes vertex and face normals are valid (else call BM_mesh_normals_update()
* first)!
*/
-void BM_mesh_loop_normals_update(BMesh *bm, const float split_angle, float (*r_lnos)[3])
+void BM_mesh_loop_normals_update(
+ BMesh *bm, const bool use_split_normals, const float split_angle, float (*r_lnos)[3],
+ MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset)
{
- /* Tag smooth edges and set lnos from vnos when they might be completely smooth... */
- bm_mesh_edges_sharp_tag(bm, NULL, NULL, split_angle, r_lnos);
+ const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
+
+ if (use_split_normals) {
+ /* Tag smooth edges and set lnos from vnos when they might be completely smooth...
+ * When using custom loop normals, disable the angle feature! */
+ bm_mesh_edges_sharp_tag(bm, NULL, NULL, has_clnors ? (float)M_PI : split_angle, r_lnos);
- /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
- bm_mesh_loops_calc_normals(bm, NULL, NULL, r_lnos);
+ /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
+ bm_mesh_loops_calc_normals(bm, NULL, NULL, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset);
+ }
+ else {
+ BLI_assert(!r_lnors_spacearr);
+ bm_mesh_loops_calc_normals_no_autosmooth(bm, NULL, NULL, r_lnos);
+ }
}
#endif
@@ -673,14 +880,25 @@ void BM_mesh_loop_normals_update(BMesh *bm, const float split_angle, float (*r_l
* Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
* Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry (splitting edges).
*/
-void BM_loops_calc_normal_vcos(BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*fnos)[3],
- const float split_angle, float (*r_lnos)[3])
+void BM_loops_calc_normal_vcos(
+ BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*fnos)[3],
+ const bool use_split_normals, const float split_angle, float (*r_lnos)[3],
+ MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset)
{
- /* Tag smooth edges and set lnos from vnos when they might be completely smooth... */
- bm_mesh_edges_sharp_tag(bm, vnos, fnos, split_angle, r_lnos);
+ const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
+
+ if (use_split_normals) {
+ /* Tag smooth edges and set lnos from vnos when they might be completely smooth...
+ * When using custom loop normals, disable the angle feature! */
+ bm_mesh_edges_sharp_tag(bm, vnos, fnos, has_clnors ? (float)M_PI : split_angle, r_lnos);
- /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
- bm_mesh_loops_calc_normals(bm, vcos, fnos, r_lnos);
+ /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
+ bm_mesh_loops_calc_normals(bm, vcos, fnos, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset);
+ }
+ else {
+ BLI_assert(!r_lnors_spacearr);
+ bm_mesh_loops_calc_normals_no_autosmooth(bm, vnos, fnos, r_lnos);
+ }
}
static void UNUSED_FUNCTION(bm_mdisps_space_set)(Object *ob, BMesh *bm, int from, int to)
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 22e50502aee..bac5da8347e 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -28,6 +28,7 @@
*/
struct BMAllocTemplate;
+struct MLoopNorSpaceArray;
void BM_mesh_elem_toolflags_ensure(BMesh *bm);
void BM_mesh_elem_toolflags_clear(BMesh *bm);
@@ -39,8 +40,10 @@ void BM_mesh_clear(BMesh *bm);
void BM_mesh_normals_update(BMesh *bm);
void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (*vcos)[3], float (*vnos)[3]);
-void BM_loops_calc_normal_vcos(BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*pnos)[3],
- const float split_angle, float (*r_lnos)[3]);
+void BM_loops_calc_normal_vcos(
+ BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*pnos)[3],
+ const bool use_split_normals, const float split_angle, float (*r_lnos)[3],
+ struct MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset);
void bmesh_edit_begin(BMesh *bm, const BMOpTypeFlag type_flag);
void bmesh_edit_end(BMesh *bm, const BMOpTypeFlag type_flag);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 05f3ff5b60b..3630bb78b8a 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -788,7 +788,7 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
{
BMEditSelection *selected;
- me->totselect = BLI_countlist(&(bm->selected));
+ me->totselect = BLI_listbase_count(&(bm->selected));
if (me->mselect) MEM_freeN(me->mselect);
@@ -850,15 +850,7 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
* bmesh and the mesh are out of sync */
(oldverts != NULL)) /* not used here, but 'oldverts' is used later for applying 'ofs' */
{
- bool act_is_basis = false;
-
- /* find if this key is a basis for any others */
- for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
- if (bm->shapenr - 1 == currkey->relative) {
- act_is_basis = true;
- break;
- }
- }
+ const bool act_is_basis = BKE_keyblock_is_basis(me->key, bm->shapenr - 1);
/* active key is a base */
if (act_is_basis && (cd_shape_keyindex_offset != -1)) {
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 72d25413f09..7b3f64dc5cd 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -902,7 +902,9 @@ bool BM_face_split_edgenet(
if (l_first == NULL) {
mul_v2_m3v3(co, axis_mat, v->co);
interp_weights_poly_v2(w, cos_2d, f->len, co);
- CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, f->len, l_iter->head.data);
+ CustomData_bmesh_interp(
+ &bm->ldata, (const void **)blocks,
+ w, NULL, f->len, l_iter->head.data);
l_first = l_iter;
}
else {
@@ -1010,7 +1012,7 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float
l_iter = e_kill->l;
do {
if (l_iter->v == tv && l_iter->next->v == v_kill) {
- void *src[2];
+ const void *src[2];
BMLoop *tvloop = l_iter;
BMLoop *kvloop = l_iter->next;
@@ -1149,7 +1151,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
* </pre>
*
* \param e The edge to split.
- * \param v One of the vertices in \a e and defines the the "from" end of the splitting operation,
+ * \param v One of the vertices in \a e and defines the "from" end of the splitting operation,
* the new vertex will be \a fac of the way from \a v to the other end.
* \param r_e The newly created edge.
* \return The new vertex.
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index aba805cccd7..d0679b9919a 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -173,8 +173,9 @@ static BMOpDefine bmo_region_extend_def = {
"region_extend",
/* slots_in */
{{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
- {"use_constrict", BMO_OP_SLOT_BOOL}, /* find boundary inside the regions, not outside. */
+ {"use_contract", BMO_OP_SLOT_BOOL}, /* find boundary inside the regions, not outside. */
{"use_faces", BMO_OP_SLOT_BOOL}, /* extend from faces instead of edges */
+ {"use_face_step", BMO_OP_SLOT_BOOL}, /* step over connected faces */
{{'\0'}},
},
/* slots_out */
@@ -932,6 +933,28 @@ static BMOpDefine bmo_connect_verts_def = {
};
/*
+ * Connect Verts to form Convex Faces.
+ *
+ * Ensures all faces are convex **faces**.
+ */
+static BMOpDefine bmo_connect_verts_concave_def = {
+ "connect_verts_concave",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ bmo_connect_verts_concave_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
+};
+
+/*
* Connect Verts Across non Planer Faces.
*
* Split faces by connecting edges along non planer **faces**.
@@ -1949,6 +1972,7 @@ const BMOpDefine *bmo_opdefines[] = {
&bmo_collapse_def,
&bmo_collapse_uvs_def,
&bmo_connect_verts_def,
+ &bmo_connect_verts_concave_def,
&bmo_connect_verts_nonplanar_def,
&bmo_connect_vert_pair_def,
&bmo_contextual_create_def,
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index 287aafc8f9f..d966d882c67 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -395,6 +395,8 @@ void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag);
+void BMO_slot_buffer_from_array(BMOperator *op, BMOpSlot *slot, BMHeader **ele_buffer, int ele_buffer_len);
+
void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele);
void *BMO_slot_buffer_get_single(BMOpSlot *slot);
@@ -477,7 +479,9 @@ int BMO_iter_map_value_int(BMOIter *iter);
bool BMO_iter_map_value_bool(BMOIter *iter);
#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag) \
- for (ele = BMO_iter_new(iter, slot_args, slot_name, restrict_flag); ele; ele = BMO_iter_step(iter))
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_new(iter, slot_args, slot_name, restrict_flag); \
+ ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_step(iter))
/******************* Inlined Functions********************/
typedef void (*opexec)(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index b041c010c22..ba154b04838 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -900,6 +900,21 @@ void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele)
*slot->data.buf = ele;
}
+void BMO_slot_buffer_from_array(BMOperator *op, BMOpSlot *slot, BMHeader **ele_buffer, int ele_buffer_len)
+{
+ BMO_ASSERT_SLOT_IN_OP(slot, op);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(slot->len == 0 || slot->len == ele_buffer_len);
+
+ if (slot->data.buf == NULL) {
+ slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(*slot->data.buf) * ele_buffer_len);
+ }
+
+ slot->len = ele_buffer_len;
+ memcpy(slot->data.buf, ele_buffer, ele_buffer_len * sizeof(*slot->data.buf));
+}
+
+
void *BMO_slot_buffer_get_single(BMOpSlot *slot)
{
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
@@ -1636,6 +1651,7 @@ static int BMO_opcode_from_opname_check(const char *opname)
*
* **Element Buffer** (#BMO_OP_SLOT_ELEMENT_BUF)
* - `e` - single element vert/edge/face (use with #BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE).
+ * - `eb` - elem buffer, take an array and a length.
* - `av` - all verts
* - `ae` - all edges
* - `af` - all faces
@@ -1756,12 +1772,23 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
state = true;
break;
}
- case 'e': /* single vert/edge/face */
+ case 'e':
{
- BMHeader *ele = va_arg(vlist, void *);
BMOpSlot *slot = BMO_slot_get(op->slots_in, slot_name);
- BMO_slot_buffer_from_single(op, slot, ele);
+ if (NEXT_CHAR(fmt) == 'b') {
+ BMHeader **ele_buffer = va_arg(vlist, void *);
+ int ele_buffer_len = va_arg(vlist, int);
+
+ BMO_slot_buffer_from_array(op, slot, ele_buffer, ele_buffer_len);
+ fmt++;
+ }
+ else {
+ /* single vert/edge/face */
+ BMHeader *ele = va_arg(vlist, void *);
+
+ BMO_slot_buffer_from_single(op, slot, ele);
+ }
state = true;
break;
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index b3d97947cab..f39fe29b596 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -33,10 +33,10 @@
/*quad innervert values*/
enum {
- SUBD_INNERVERT,
- SUBD_PATH,
- SUBD_FAN,
- SUBD_STRAIGHT_CUT
+ SUBD_CORNER_INNERVERT,
+ SUBD_CORNER_PATH,
+ SUBD_CORNER_FAN,
+ SUBD_CORNER_STRAIGHT_CUT
};
/* aligned with PROP_SMOOTH and friends */
@@ -82,6 +82,7 @@ enum {
SIMFACE_PERIMETER,
SIMFACE_NORMAL,
SIMFACE_COPLANAR,
+ SIMFACE_SMOOTH,
#ifdef WITH_FREESTYLE
SIMFACE_FREESTYLE
#endif
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index 9c1b7085835..979f7d2640a 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -41,6 +41,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op);
void bmo_collapse_exec(BMesh *bm, BMOperator *op);
void bmo_collapse_uvs_exec(BMesh *bm, BMOperator *op);
void bmo_connect_verts_exec(BMesh *bm, BMOperator *op);
+void bmo_connect_verts_concave_exec(BMesh *bm, BMOperator *op);
void bmo_connect_verts_nonplanar_exec(BMesh *bm, BMOperator *op);
void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op);
void bmo_contextual_create_exec(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index a8e1acd9c71..bc06ba2c9b1 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -37,6 +37,7 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_polyfill2d.h"
+#include "BLI_polyfill2d_beautify.h"
#include "bmesh.h"
#include "bmesh_tools.h"
@@ -213,9 +214,6 @@ float BM_face_calc_area(BMFace *f)
if (f->len == 3) {
area = area_tri_v3(verts[0], verts[1], verts[2]);
}
- else if (f->len == 4) {
- area = area_quad_v3(verts[0], verts[1], verts[2], verts[3]);
- }
else {
area = area_poly_v3((const float (*)[3])verts, f->len);
}
@@ -422,6 +420,43 @@ void BM_edge_normals_update(BMEdge *e)
BM_vert_normal_update(e->v2);
}
+bool BM_vert_normal_update_ex(BMVert *v, const char hflag, float r_no[3])
+{
+ /* TODO, we can normalize each edge only once, then compare with previous edge */
+
+ BMIter liter;
+ BMLoop *l;
+ int len = 0;
+
+ zero_v3(r_no);
+
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ if (BM_elem_flag_test(l->f, hflag)) {
+ float vec1[3], vec2[3], fac;
+
+ /* Same calculation used in BM_mesh_normals_update */
+ sub_v3_v3v3(vec1, l->v->co, l->prev->v->co);
+ sub_v3_v3v3(vec2, l->next->v->co, l->v->co);
+ normalize_v3(vec1);
+ normalize_v3(vec2);
+
+ fac = saacos(-dot_v3v3(vec1, vec2));
+
+ madd_v3_v3fl(r_no, l->f->no, fac);
+
+ len++;
+ }
+ }
+
+ if (len) {
+ normalize_v3(r_no);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
/**
* update a vert normal (but not the faces incident on it)
*/
@@ -431,12 +466,13 @@ void BM_vert_normal_update(BMVert *v)
BMIter liter;
BMLoop *l;
- float vec1[3], vec2[3], fac;
int len = 0;
zero_v3(v->no);
BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ float vec1[3], vec2[3], fac;
+
/* Same calculation used in BM_mesh_normals_update */
sub_v3_v3v3(vec1, l->v->co, l->prev->v->co);
sub_v3_v3v3(vec2, l->next->v->co, l->v->co);
@@ -704,20 +740,24 @@ bool BM_face_point_inside_test(BMFace *f, const float co[3])
*
* \note use_tag tags new flags and edges.
*/
-void BM_face_triangulate(BMesh *bm, BMFace *f,
- BMFace **r_faces_new,
- int *r_faces_new_tot,
- MemArena *sf_arena,
- const int quad_method,
- const int ngon_method,
- const bool use_tag)
+void BM_face_triangulate(
+ BMesh *bm, BMFace *f,
+ BMFace **r_faces_new,
+ int *r_faces_new_tot,
+ BMEdge **r_edges_new,
+ int *r_edges_new_tot,
+ const int quad_method,
+ const int ngon_method,
+ const bool use_tag,
+ MemArena *pf_arena,
+
+ /* use for MOD_TRIANGULATE_NGON_BEAUTY only! */
+ struct Heap *pf_heap, struct EdgeHash *pf_ehash)
{
BMLoop *l_iter, *l_first, *l_new;
BMFace *f_new;
- int orig_f_len = f->len;
int nf_i = 0;
- BMEdge **edge_array;
- int edge_array_len;
+ int ne_i = 0;
bool use_beauty = (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY);
BLI_assert(BM_face_is_normal_valid(f));
@@ -743,38 +783,39 @@ void BM_face_triangulate(BMesh *bm, BMFace *f,
break;
}
case MOD_TRIANGULATE_QUAD_SHORTEDGE:
- {
- BMLoop *l_v3, *l_v4;
- float d1, d2;
-
- l_v1 = l_first;
- l_v2 = l_first->next->next;
- l_v3 = l_first->next;
- l_v4 = l_first->prev;
-
- d1 = len_squared_v3v3(l_v1->v->co, l_v2->v->co);
- d2 = len_squared_v3v3(l_v3->v->co, l_v4->v->co);
-
- if (d2 < d1) {
- l_v1 = l_v3;
- l_v2 = l_v4;
- }
- break;
- }
case MOD_TRIANGULATE_QUAD_BEAUTY:
default:
{
BMLoop *l_v3, *l_v4;
- float cost;
+ bool split_24;
l_v1 = l_first->next;
l_v2 = l_first->next->next;
l_v3 = l_first->prev;
l_v4 = l_first;
- cost = BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0);
+ if (quad_method == MOD_TRIANGULATE_QUAD_SHORTEDGE) {
+ float d1, d2;
+ d1 = len_squared_v3v3(l_v4->v->co, l_v2->v->co);
+ d2 = len_squared_v3v3(l_v1->v->co, l_v3->v->co);
+ split_24 = ((d2 - d1) > 0.0f);
+ }
+ else {
+ /* first check if the quad is concave on either diagonal */
+ const int flip_flag = is_quad_flip_v3(l_v1->v->co, l_v2->v->co, l_v3->v->co, l_v4->v->co);
+ if (UNLIKELY(flip_flag & (1 << 0))) {
+ split_24 = true;
+ }
+ else if (UNLIKELY(flip_flag & (1 << 1))) {
+ split_24 = false;
+ }
+ else {
+ split_24 = (BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) > 0.0f);
+ }
+ }
- if (cost < 0.0f) {
+ /* named confusingly, l_v1 is in fact the second vertex */
+ if (split_24) {
l_v1 = l_v4;
//l_v2 = l_v2;
}
@@ -797,6 +838,9 @@ void BM_face_triangulate(BMesh *bm, BMFace *f,
if (r_faces_new) {
r_faces_new[nf_i++] = f_new;
}
+ if (r_edges_new) {
+ r_edges_new[ne_i++] = l_new->e;
+ }
}
else if (f->len > 4) {
@@ -816,11 +860,12 @@ void BM_face_triangulate(BMesh *bm, BMFace *f,
}
BLI_polyfill_calc_arena((const float (*)[2])projverts, f->len, -1, tris,
- sf_arena);
+ pf_arena);
if (use_beauty) {
- edge_array = BLI_array_alloca(edge_array, orig_f_len - 3);
- edge_array_len = 0;
+ BLI_polyfill_beautify(
+ (const float (*)[2])projverts, f->len, tris,
+ pf_arena, pf_heap, pf_ehash);
}
/* loop over calculated triangles and create new geometry */
@@ -856,8 +901,7 @@ void BM_face_triangulate(BMesh *bm, BMFace *f,
}
}
- /* we know any edge that we create and _isnt_ */
- if (use_beauty || use_tag) {
+ if (use_tag || r_edges_new) {
/* new faces loops */
l_iter = l_first = l_new;
do {
@@ -867,14 +911,11 @@ void BM_face_triangulate(BMesh *bm, BMFace *f,
bool is_new_edge = (l_iter == l_iter->radial_next);
if (is_new_edge) {
- if (use_beauty) {
- edge_array[edge_array_len] = e;
- edge_array_len++;
- }
-
if (use_tag) {
BM_elem_flag_enable(e, BM_ELEM_TAG);
-
+ }
+ if (r_edges_new) {
+ r_edges_new[ne_i++] = e;
}
}
/* note, never disable tag's */
@@ -882,83 +923,22 @@ void BM_face_triangulate(BMesh *bm, BMFace *f,
}
}
- if ((!use_beauty) || (!r_faces_new)) {
+ {
/* we can't delete the real face, because some of the callers expect it to remain valid.
* so swap data and delete the last created tri */
bmesh_face_swap_data(f, f_new);
BM_face_kill(bm, f_new);
}
-
- if (use_beauty) {
- BLI_assert(edge_array_len <= orig_f_len - 3);
-
- BM_mesh_beautify_fill(bm, edge_array, edge_array_len, 0, 0, 0, 0);
-
- if (r_faces_new) {
- /* beautify deletes and creates new faces
- * we need to re-populate the r_faces_new array
- * with the new faces
- */
- int i;
-
-
-#define FACE_USED_TEST(f) (BM_elem_index_get(f) == -2)
-#define FACE_USED_SET(f) BM_elem_index_set(f, -2)
-
- nf_i = 0;
- for (i = 0; i < edge_array_len; i++) {
- BMFace *f_a, *f_b;
- BMEdge *e = edge_array[i];
-#ifndef NDEBUG
- const bool ok = BM_edge_face_pair(e, &f_a, &f_b);
- BLI_assert(ok);
-#else
- BM_edge_face_pair(e, &f_a, &f_b);
-#endif
-
- if (FACE_USED_TEST(f_a) == false) {
- FACE_USED_SET(f_a); /* set_dirty */
-
- if (nf_i < edge_array_len) {
- r_faces_new[nf_i++] = f_a;
- }
- else {
- f_new = f_a;
- break;
- }
- }
-
- if (FACE_USED_TEST(f_b) == false) {
- FACE_USED_SET(f_b); /* set_dirty */
-
- if (nf_i < edge_array_len) {
- r_faces_new[nf_i++] = f_b;
- }
- else {
- f_new = f_b;
- break;
- }
- }
- }
-
-#undef FACE_USED_TEST
-#undef FACE_USED_SET
-
- /* nf_i doesn't include the last face */
- BLI_assert(nf_i <= orig_f_len - 3);
-
- /* we can't delete the real face, because some of the callers expect it to remain valid.
- * so swap data and delete the last created tri */
- bmesh_face_swap_data(f, f_new);
- BM_face_kill(bm, f_new);
- }
- }
}
bm->elem_index_dirty |= BM_FACE;
if (r_faces_new_tot) {
*r_faces_new_tot = nf_i;
}
+
+ if (r_edges_new_tot) {
+ *r_edges_new_tot = ne_i;
+ }
}
/**
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index 91e649edb16..9980b59a298 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -27,6 +27,9 @@
* \ingroup bmesh
*/
+struct EdgeHash;
+struct Heap;
+
#include "BLI_compiler_attrs.h"
void BM_bmesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot);
@@ -49,18 +52,24 @@ void BM_face_normal_update(BMFace *f) ATTR_NONNULL();
void BM_edge_normals_update(BMEdge *e) ATTR_NONNULL();
+bool BM_vert_normal_update_ex(BMVert *v, const char hflag, float r_no[3]);
void BM_vert_normal_update(BMVert *v) ATTR_NONNULL();
void BM_vert_normal_update_all(BMVert *v) ATTR_NONNULL();
void BM_face_normal_flip(BMesh *bm, BMFace *f) ATTR_NONNULL();
bool BM_face_point_inside_test(BMFace *f, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void BM_face_triangulate(BMesh *bm, BMFace *f,
- BMFace **r_faces_new,
- int *r_faces_new_tot,
- struct MemArena *sf_arena,
- const int quad_method, const int ngon_method,
- const bool use_tag) ATTR_NONNULL(1, 2);
+void BM_face_triangulate(
+ BMesh *bm, BMFace *f,
+ BMFace **r_faces_new,
+ int *r_faces_new_tot,
+ BMEdge **r_edges_new,
+ int *r_edges_new_tot,
+ const int quad_method, const int ngon_method,
+ const bool use_tag,
+ struct MemArena *pf_arena,
+ struct Heap *pf_heap, struct EdgeHash *pf_ehash
+ ) ATTR_NONNULL(1, 2);
void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL();
void BM_face_splits_check_optimal(BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL();
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 40e0356e14c..c3be768aa09 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -193,7 +193,7 @@ bool BM_vert_pair_share_face_check(
BMFace *f;
BM_ITER_ELEM (f, &iter, v_a, BM_FACES_OF_VERT) {
- if (BM_vert_in_face(f, v_b)) {
+ if (BM_vert_in_face(v_b, f)) {
return true;
}
}
@@ -202,6 +202,26 @@ bool BM_vert_pair_share_face_check(
return false;
}
+bool BM_vert_pair_share_face_check_cb(
+ BMVert *v_a, BMVert *v_b,
+ bool (*test_fn)(BMFace *, void *user_data), void *user_data)
+{
+ if (v_a->e && v_b->e) {
+ BMIter iter;
+ BMFace *f;
+
+ BM_ITER_ELEM (f, &iter, v_a, BM_FACES_OF_VERT) {
+ if (test_fn(f, user_data)) {
+ if (BM_vert_in_face(v_b, f)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
/**
* Given 2 verts, find the smallest face they share and give back both loops.
*/
@@ -250,6 +270,37 @@ static float bm_face_calc_split_dot(BMLoop *l_a, BMLoop *l_b)
}
/**
+ * Check if a point is inside the corner defined by a loop
+ * (within the 2 planes defined by the loops corner & face normal).
+ *
+ * \return signed, squared distance to the loops planes, less than 0.0 when outside.
+ */
+float BM_loop_point_side_of_loop_test(const BMLoop *l, const float co[3])
+{
+ const float *axis = l->f->no;
+ return dist_signed_squared_to_corner_v3v3v3(co, l->prev->v->co, l->v->co, l->next->v->co, axis);
+}
+
+/**
+ * Check if a point is inside the edge defined by a loop
+ * (within the plane defined by the loops edge & face normal).
+ *
+ * \return signed, squared distablce to the edge plane, less than 0.0 when outside.
+ */
+float BM_loop_point_side_of_edge_test(const BMLoop *l, const float co[3])
+{
+ const float *axis = l->f->no;
+ float dir[3];
+ float plane[4];
+
+ sub_v3_v3v3(dir, l->next->v->co, l->v->co);
+ cross_v3_v3v3(plane, axis, dir);
+
+ plane[3] = -dot_v3v3(plane, l->v->co);
+ return dist_signed_squared_to_plane_v3(co, plane);
+}
+
+/**
* Given 2 verts, find a face they share that has the lowest angle across these verts and give back both loops.
*
* This can be better then #BM_vert_pair_share_face_by_len because concave splits are ranked lowest.
@@ -325,7 +376,7 @@ BMLoop *BM_vert_find_first_loop(BMVert *v)
/**
* Returns true if the vertex is used in a given face.
*/
-bool BM_vert_in_face(BMFace *f, BMVert *v)
+bool BM_vert_in_face(BMVert *v, BMFace *f)
{
BMLoop *l_iter, *l_first;
@@ -353,7 +404,7 @@ bool BM_vert_in_face(BMFace *f, BMVert *v)
* Compares the number of vertices in an array
* that appear in a given face
*/
-int BM_verts_in_face_count(BMFace *f, BMVert **varr, int len)
+int BM_verts_in_face_count(BMVert **varr, int len, BMFace *f)
{
BMLoop *l_iter, *l_first;
@@ -397,7 +448,7 @@ int BM_verts_in_face_count(BMFace *f, BMVert **varr, int len)
/**
* Return true if all verts are in the face.
*/
-bool BM_verts_in_face(BMFace *f, BMVert **varr, int len)
+bool BM_verts_in_face(BMVert **varr, int len, BMFace *f)
{
BMLoop *l_iter, *l_first;
@@ -448,7 +499,7 @@ bool BM_verts_in_face(BMFace *f, BMVert **varr, int len)
}
/**
- * Returns whether or not a given edge is is part of a given face.
+ * Returns whether or not a given edge is part of a given face.
*/
bool BM_edge_in_face(BMEdge *e, BMFace *f)
{
@@ -613,7 +664,7 @@ BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e_first)
/**
* Returns edge length
*/
-float BM_edge_calc_length(BMEdge *e)
+float BM_edge_calc_length(const BMEdge *e)
{
return len_v3v3(e->v1->co, e->v2->co);
}
@@ -621,7 +672,7 @@ float BM_edge_calc_length(BMEdge *e)
/**
* Returns edge length squared (for comparisons)
*/
-float BM_edge_calc_length_squared(BMEdge *e)
+float BM_edge_calc_length_squared(const BMEdge *e)
{
return len_squared_v3v3(e->v1->co, e->v2->co);
}
@@ -681,9 +732,9 @@ bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
/**
* Fast alternative to ``(BM_vert_edge_count(v) == 2)``
*/
-bool BM_vert_is_edge_pair(BMVert *v)
+bool BM_vert_is_edge_pair(const BMVert *v)
{
- BMEdge *e = v->e;
+ const BMEdge *e = v->e;
if (e) {
const BMDiskLink *dl = bmesh_disk_edge_link_from_vert(e, v);
return (dl->next == dl->prev);
@@ -694,17 +745,17 @@ bool BM_vert_is_edge_pair(BMVert *v)
/**
* Returns the number of edges around this vertex.
*/
-int BM_vert_edge_count(BMVert *v)
+int BM_vert_edge_count(const BMVert *v)
{
return bmesh_disk_count(v);
}
-int BM_vert_edge_count_nonwire(BMVert *v)
+int BM_vert_edge_count_nonwire(const BMVert *v)
{
int count = 0;
BMIter eiter;
BMEdge *edge;
- BM_ITER_ELEM (edge, &eiter, v, BM_EDGES_OF_VERT) {
+ BM_ITER_ELEM (edge, &eiter, (BMVert *)v, BM_EDGES_OF_VERT) {
if (edge->l) {
count++;
}
@@ -714,7 +765,7 @@ int BM_vert_edge_count_nonwire(BMVert *v)
/**
* Returns the number of faces around this edge
*/
-int BM_edge_face_count(BMEdge *e)
+int BM_edge_face_count(const BMEdge *e)
{
int count = 0;
@@ -736,7 +787,7 @@ int BM_edge_face_count(BMEdge *e)
* Returns the number of faces around this vert
* length matches #BM_LOOPS_OF_VERT iterator
*/
-int BM_vert_face_count(BMVert *v)
+int BM_vert_face_count(const BMVert *v)
{
return bmesh_disk_facevert_count(v);
}
@@ -1305,7 +1356,7 @@ void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_ta
*
* \returns the angle in radians
*/
-float BM_vert_calc_edge_angle(BMVert *v)
+float BM_vert_calc_edge_angle_ex(BMVert *v, const float fallback)
{
BMEdge *e1, *e2;
@@ -1323,10 +1374,15 @@ float BM_vert_calc_edge_angle(BMVert *v)
return (float)M_PI - angle_v3v3v3(v1->co, v->co, v2->co);
}
else {
- return DEG2RADF(90.0f);
+ return fallback;
}
}
+float BM_vert_calc_edge_angle(BMVert *v)
+{
+ return BM_vert_calc_edge_angle_ex(v, DEG2RADF(90.0f));
+}
+
/**
* \note this isn't optimal to run on an array of verts,
* see 'solidify_add_thickness' for a function which runs on an array.
@@ -1353,7 +1409,7 @@ float BM_vert_calc_shell_factor(BMVert *v)
}
/* alternate version of #BM_vert_calc_shell_factor which only
* uses 'hflag' faces, but falls back to all if none found. */
-float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag)
+float BM_vert_calc_shell_factor_ex(BMVert *v, const float no[3], const char hflag)
{
BMIter iter;
BMLoop *l;
@@ -1364,7 +1420,7 @@ float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag)
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
if (BM_elem_flag_test(l->f, hflag)) { /* <-- main difference to BM_vert_calc_shell_factor! */
const float face_angle = BM_loop_calc_face_angle(l);
- accum_shell += shell_v3v3_normalized_to_dist(v->no, l->f->no) * face_angle;
+ accum_shell += shell_v3v3_normalized_to_dist(no, l->f->no) * face_angle;
accum_angle += face_angle;
tot_sel++;
}
@@ -1552,7 +1608,7 @@ bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface)
#if 0
BM_ITER_ELEM (f, &viter, v_search, BM_FACES_OF_VERT) {
if (f->len == len) {
- if (BM_verts_in_face(f, varr, len)) {
+ if (BM_verts_in_face(varr, len, f)) {
if (r_existface) {
*r_existface = f;
}
@@ -1777,7 +1833,7 @@ bool BM_face_exists_multi_edge(BMEdge **earr, int len)
*
* \note The face may contain other verts \b not in \a varr.
*
- * \note Its possible there are more then one overlapping faces,
+ * \note Its possible there are more than one overlapping faces,
* in this case the first one found will be assigned to \a r_f_overlap.
*
* \param varr Array of unordered verts.
@@ -1810,7 +1866,7 @@ bool BM_face_exists_overlap(BMVert **varr, const int len, BMFace **r_f_overlap)
for (i = 0; i < len; i++) {
BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
if (BM_ELEM_API_FLAG_TEST(f, _FLAG_OVERLAP) == 0) {
- if (len <= BM_verts_in_face_count(f, varr, len)) {
+ if (len <= BM_verts_in_face_count(varr, len, f)) {
if (r_f_overlap)
*r_f_overlap = f;
@@ -2128,6 +2184,7 @@ int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
}
BLI_assert(ok == true);
+ UNUSED_VARS_NDEBUG(ok);
/* manage arrays */
if (group_index_len == group_curr) {
@@ -2282,6 +2339,7 @@ int BM_mesh_calc_edge_groups(BMesh *bm, int *r_groups_array, int (**r_group_inde
}
BLI_assert(ok == true);
+ UNUSED_VARS_NDEBUG(ok);
/* manage arrays */
if (group_index_len == group_curr) {
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index 0d47633dc73..4ee5588ba0b 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -27,9 +27,9 @@
* \ingroup bmesh
*/
-bool BM_vert_in_face(BMFace *f, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_verts_in_face_count(BMFace *f, BMVert **varr, int len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_verts_in_face(BMFace *f, BMVert **varr, int len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_in_face(BMVert *v, BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_verts_in_face_count(BMVert **varr, int len, BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_verts_in_face(BMVert **varr, int len, BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
bool BM_edge_in_face(BMEdge *e, BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BLI_INLINE bool BM_edge_in_loop(const BMEdge *e, const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -37,8 +37,8 @@ BLI_INLINE bool BM_edge_in_loop(const BMEdge *e, const BMLoop *l) ATTR_WARN_U
BLI_INLINE bool BM_vert_in_edge(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BLI_INLINE bool BM_verts_in_edge(const BMVert *v1, const BMVert *v2, const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_edge_calc_length(BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_edge_calc_length_squared(BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_edge_calc_length(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_edge_calc_length_squared(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
bool BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb) ATTR_NONNULL();
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb) ATTR_NONNULL();
BLI_INLINE BMVert *BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -52,6 +52,9 @@ BMLoop *BM_vert_find_first_loop(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(
bool BM_vert_pair_share_face_check(
BMVert *v_a, BMVert *v_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_pair_share_face_check_cb(
+ BMVert *v_a, BMVert *v_b,
+ bool (*test_fn)(BMFace *f, void *user_data), void *user_data) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3);
BMFace *BM_vert_pair_share_face_by_len(
BMVert *v_a, BMVert *v_b,
BMLoop **r_l_a, BMLoop **r_l_b,
@@ -61,13 +64,13 @@ BMFace *BM_vert_pair_share_face_by_angle(
BMLoop **r_l_a, BMLoop **r_l_b,
const bool allow_adjacent) ATTR_NONNULL();
-int BM_vert_edge_count_nonwire(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_vert_edge_count(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_edge_face_count(BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_vert_face_count(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_vert_edge_count_nonwire(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_vert_edge_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_edge_face_count(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_vert_face_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_vert_is_edge_pair(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_is_edge_pair(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
bool BM_vert_is_wire(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -80,6 +83,8 @@ bool BM_edge_is_convex(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(
bool BM_loop_is_convex(const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_loop_point_side_of_loop_test(const BMLoop *l, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_loop_point_side_of_edge_test(const BMLoop *l, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
float BM_loop_calc_face_angle(BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void BM_loop_calc_face_normal(BMLoop *l, float r_normal[3]) ATTR_NONNULL();
@@ -93,8 +98,9 @@ float BM_edge_calc_face_angle_signed(const BMEdge *e) ATTR_WARN_UNUSED_RESULT
void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3]) ATTR_NONNULL();
float BM_vert_calc_edge_angle(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_vert_calc_edge_angle_ex(BMVert *v, const float fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
float BM_vert_calc_shell_factor(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_vert_calc_shell_factor_ex(BMVert *v, const float no[3], const char hflag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
float BM_vert_calc_mean_tagged_edge_length(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *BM_face_find_shortest_loop(BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
diff --git a/source/blender/bmesh/intern/bmesh_queries_inline.h b/source/blender/bmesh/intern/bmesh_queries_inline.h
index 6162af46837..1ca56beb746 100644
--- a/source/blender/bmesh/intern/bmesh_queries_inline.h
+++ b/source/blender/bmesh/intern/bmesh_queries_inline.h
@@ -36,7 +36,7 @@ BLI_INLINE bool BM_vert_in_edge(const BMEdge *e, const BMVert *v)
}
/**
- * Returns whether or not a given edge is is part of a given loop.
+ * Returns whether or not a given edge is part of a given loop.
*/
BLI_INLINE bool BM_edge_in_loop(const BMEdge *e, const BMLoop *l)
{
diff --git a/source/blender/bmesh/intern/bmesh_walkers.c b/source/blender/bmesh/intern/bmesh_walkers.c
index 6a5efbe70ac..20b56632099 100644
--- a/source/blender/bmesh/intern/bmesh_walkers.c
+++ b/source/blender/bmesh/intern/bmesh_walkers.c
@@ -180,7 +180,7 @@ void *BMW_walk(BMWalker *walker)
* \brief Current Walker State
*
* Returns the first state from the walker state
- * worklist. This state is the the next in the
+ * worklist. This state is the next in the
* worklist for processing.
*/
void *BMW_current_state(BMWalker *walker)
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index 406dd412d6d..b7bf80b0e3f 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -33,7 +33,6 @@
#include "BKE_customdata.h"
#include "bmesh.h"
-#include "intern/bmesh_private.h"
#include "intern/bmesh_walkers_private.h"
/* pop into stack memory (common operation) */
@@ -738,7 +737,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker)
(owalk.is_single == false && vert_edge_tot > 2) ||
/* initial edge was a boundary, so is this edge and vertex is only apart of this face
- * this lets us walk over the the boundary of an ngon which is handy */
+ * this lets us walk over the boundary of an ngon which is handy */
(owalk.is_single == true && vert_edge_tot == 2 && BM_edge_is_boundary(e)))
{
/* find next boundary edge in the fan */
diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c
index e4417477e76..6002dcf2c0d 100644
--- a/source/blender/bmesh/operators/bmo_bridge.c
+++ b/source/blender/bmesh/operators/bmo_bridge.c
@@ -180,20 +180,42 @@ static void bridge_loop_pair(BMesh *bm,
/* normalizing isn't strictly needed but without we may get very large values */
float no[3];
+ float dir_a_orig[3], dir_b_orig[3];
float dir_a[3], dir_b[3];
+ const float *test_a, *test_b;
- sub_v3_v3v3(dir_a,
+ sub_v3_v3v3(dir_a_orig,
((BMVert *)(((LinkData *)lb_a->first)->data))->co,
((BMVert *)(((LinkData *)lb_a->last)->data))->co);
- sub_v3_v3v3(dir_b,
+ sub_v3_v3v3(dir_b_orig,
((BMVert *)(((LinkData *)lb_b->first)->data))->co,
((BMVert *)(((LinkData *)lb_b->last)->data))->co);
/* make the directions point out from the normals, 'no' is used as a temp var */
- cross_v3_v3v3(no, dir_a, el_dir); cross_v3_v3v3(dir_a, no, el_dir);
- cross_v3_v3v3(no, dir_b, el_dir); cross_v3_v3v3(dir_b, no, el_dir);
+ cross_v3_v3v3(no, dir_a_orig, el_dir); cross_v3_v3v3(dir_a, no, el_dir);
+ cross_v3_v3v3(no, dir_b_orig, el_dir); cross_v3_v3v3(dir_b, no, el_dir);
- if (dot_v3v3(dir_a, dir_b) < 0.0f) {
+ if (LIKELY(!is_zero_v3(dir_a) && !is_zero_v3(dir_b))) {
+ test_a = dir_a;
+ test_b = dir_b;
+ }
+ else {
+ /**
+ * This is a corner case:
+ *
+ * <pre>
+ * (loop a) (loop b)
+ * +--------+ +--------+
+ * </pre>
+ *
+ * When loops are aligned to the direction between the loops values of 'dir_a/b' is degenerate,
+ * in this case compare the original directions (before they were corrected by 'el_dir'), see: T43013
+ */
+ test_a = dir_a_orig;
+ test_b = dir_b_orig;
+ }
+
+ if (dot_v3v3(test_a, test_b) < 0.0f) {
BM_edgeloop_flip(bm, el_store_b);
}
diff --git a/source/blender/bmesh/operators/bmo_connect_concave.c b/source/blender/bmesh/operators/bmo_connect_concave.c
new file mode 100644
index 00000000000..a00f65bd10f
--- /dev/null
+++ b/source/blender/bmesh/operators/bmo_connect_concave.c
@@ -0,0 +1,219 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/operators/bmo_connect_concave.c
+ * \ingroup bmesh
+ *
+ * Connect vertices so all resulting faces are convex.
+ *
+ * Implementation:
+ *
+ * - triangulate all concave face (tagging convex verts),
+ * - rotate edges (beautify) so edges will connect nearby verts.
+ * - sort long edges (longest first),
+ * put any edges between 2 convex verts last since they often split convex regions.
+ * - merge the sorted edges as long as they don't create convex ngons.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_alloca.h"
+#include "BLI_memarena.h"
+#include "BLI_heap.h"
+#include "BLI_polyfill2d.h"
+#include "BLI_polyfill2d_beautify.h"
+#include "BLI_edgehash.h"
+
+#include "bmesh.h"
+
+#include "intern/bmesh_operators_private.h" /* own include */
+
+#define EDGE_OUT (1 << 0)
+#define FACE_OUT (1 << 1)
+
+static int bm_edge_length_cmp(const void *a_, const void *b_)
+{
+ const BMEdge *e_a = *(const void **)a_;
+ const BMEdge *e_b = *(const void **)b_;
+
+ int e_a_concave = ((BM_elem_flag_test(e_a->v1, BM_ELEM_TAG)) && (BM_elem_flag_test(e_a->v2, BM_ELEM_TAG)));
+ int e_b_concave = ((BM_elem_flag_test(e_b->v1, BM_ELEM_TAG)) && (BM_elem_flag_test(e_b->v2, BM_ELEM_TAG)));
+
+ /* merge edges between concave edges last since these
+ * are most likely to remain and be the main dividers */
+ if (e_a_concave < e_b_concave) return -1;
+ else if (e_a_concave > e_b_concave) return 1;
+ else {
+ /* otherwise shortest edges last */
+ const float e_a_len = BM_edge_calc_length_squared(e_a);
+ const float e_b_len = BM_edge_calc_length_squared(e_b);
+ if (e_a_len < e_b_len) return 1;
+ else if (e_a_len > e_b_len) return -1;
+ else return 0;
+ }
+}
+
+static bool bm_face_split_by_concave(
+ BMesh *bm, BMFace *f_base, const float eps,
+
+ MemArena *pf_arena,
+ struct Heap *pf_heap, struct EdgeHash *pf_ehash)
+{
+ const int f_base_len = f_base->len;
+ int faces_array_tot = f_base->len - 3;
+ int edges_array_tot = f_base->len - 3;
+ BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot);
+ BMEdge **edges_array = BLI_array_alloca(edges_array, edges_array_tot);
+ const int quad_method = 0, ngon_method = 0; /* beauty */
+
+ float normal[3];
+ BLI_assert(f_base->len > 3);
+
+ copy_v3_v3(normal, f_base->no);
+
+ BM_face_triangulate(
+ bm, f_base,
+ faces_array, &faces_array_tot,
+ edges_array, &edges_array_tot,
+ quad_method, ngon_method, false,
+ pf_arena,
+ pf_heap, pf_ehash);
+
+ BLI_assert(edges_array_tot <= f_base_len - 3);
+
+ if (faces_array_tot) {
+ int i;
+ for (i = 0; i < faces_array_tot; i++) {
+ BMFace *f = faces_array[i];
+ BMO_elem_flag_enable(bm, f, FACE_OUT);
+ }
+ }
+ BMO_elem_flag_enable(bm, f_base, FACE_OUT);
+
+ if (edges_array_tot) {
+ int i;
+
+ qsort(edges_array, edges_array_tot, sizeof(*edges_array), bm_edge_length_cmp);
+
+ for (i = 0; i < edges_array_tot; i++) {
+ BMLoop *l_pair[2];
+ BMEdge *e = edges_array[i];
+ BMO_elem_flag_enable(bm, e, EDGE_OUT);
+
+ if (BM_edge_is_contiguous(e) &&
+ BM_edge_loop_pair(e, &l_pair[0], &l_pair[1]))
+ {
+ bool ok = true;
+ int j;
+ for (j = 0; j < 2; j++) {
+ BMLoop *l = l_pair[j];
+
+ /* check that merging the edge (on this side)
+ * wouldn't result in a convex face-loop.
+ *
+ * This is the (l->next, l->prev) we would have once joined.
+ */
+ float cross[3];
+ cross_tri_v3(
+ cross,
+ l->v->co,
+ l->radial_next->next->next->v->co,
+ l->prev->v->co
+ );
+
+ if (dot_v3v3(cross, normal) <= eps) {
+ ok = false;
+ break;
+ }
+ }
+
+ if (ok) {
+ BMFace *f_new, *f_pair[2] = {l_pair[0]->f, l_pair[1]->f};
+ f_new = BM_faces_join(bm, f_pair, 2, true);
+ if (f_new) {
+ BMO_elem_flag_enable(bm, f_new, FACE_OUT);
+ }
+ }
+ }
+ }
+ }
+
+ BLI_heap_clear(pf_heap, NULL);
+ BLI_edgehash_clear_ex(pf_ehash, NULL, BLI_POLYFILL_ALLOC_NGON_RESERVE);
+
+ return true;
+}
+
+static bool bm_face_convex_tag_verts(BMFace *f)
+{
+ bool is_concave = false;
+ if (f->len > 3) {
+ const BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_loop_is_convex(l_iter) == false) {
+ is_concave = true;
+ BM_elem_flag_enable(l_iter->v, BM_ELEM_TAG);
+ }
+ else {
+ BM_elem_flag_disable(l_iter->v, BM_ELEM_TAG);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ return is_concave;
+}
+
+void bmo_connect_verts_concave_exec(BMesh *bm, BMOperator *op)
+{
+ BMOIter siter;
+ BMFace *f;
+ bool changed = false;
+
+ MemArena *pf_arena;
+ Heap *pf_heap;
+ EdgeHash *pf_ehash;
+
+ pf_arena = BLI_memarena_new(BLI_POLYFILL_ARENA_SIZE, __func__);
+ pf_heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE);
+ pf_ehash = BLI_edgehash_new_ex(__func__, BLI_POLYFILL_ALLOC_NGON_RESERVE);
+
+ BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
+ if (f->len > 3 && bm_face_convex_tag_verts(f)) {
+ if (bm_face_split_by_concave(
+ bm, f, FLT_EPSILON,
+ pf_arena, pf_heap, pf_ehash))
+ {
+ changed = true;
+ }
+ }
+ }
+
+ if (changed) {
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_OUT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT);
+ }
+
+ BLI_memarena_free(pf_arena);
+ BLI_heap_free(pf_heap, NULL);
+ BLI_edgehash_free(pf_ehash, NULL);
+}
diff --git a/source/blender/bmesh/operators/bmo_connect_nonplanar.c b/source/blender/bmesh/operators/bmo_connect_nonplanar.c
index 6859ce2060c..c9ce2c5f6b8 100644
--- a/source/blender/bmesh/operators/bmo_connect_nonplanar.c
+++ b/source/blender/bmesh/operators/bmo_connect_nonplanar.c
@@ -153,23 +153,11 @@ void bmo_connect_verts_nonplanar_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMFace *f;
- int totface = 0, totloop = 0;
+ bool changed = false;
BLI_LINKSTACK_DECLARE(fstack, BMFace *);
const float angle_limit = BMO_slot_float_get(op->slots_in, "angle_limit");
-
- BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
- if (f->len > 3) {
- totface += 1;
- totloop += f->len;
- }
- }
-
- if (totface == 0) {
- return;
- }
-
BLI_LINKSTACK_INIT(fstack);
BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
@@ -188,11 +176,14 @@ void bmo_connect_verts_nonplanar_exec(BMesh *bm, BMOperator *op)
BLI_LINKSTACK_PUSH(fstack, f_pair[j]);
}
}
+ changed = true;
}
}
BLI_LINKSTACK_FREE(fstack);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_OUT);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT);
+ if (changed) {
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_OUT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT);
+ }
}
diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c
index a0acf6ed2c5..fbc128b375f 100644
--- a/source/blender/bmesh/operators/bmo_connect_pair.c
+++ b/source/blender/bmesh/operators/bmo_connect_pair.c
@@ -82,7 +82,7 @@ typedef struct PathContext {
typedef struct PathLink {
struct PathLink *next;
BMElem *ele; /* edge or vert */
- BMElem *ele_from; /* edge or face we game from (not 'next->ele') */
+ BMElem *ele_from; /* edge or face we came from (not 'next->ele') */
} PathLink;
typedef struct PathLinkState {
@@ -96,6 +96,62 @@ typedef struct PathLinkState {
float co_prev[3];
} PathLinkState;
+/**
+ \name Min Dist Dir Util
+
+ * Simply getting the closest intersecting vert/edge is _not_ good enough. see T43792
+ * we need to get the closest in both directions since the absolute closest may be a dead-end.
+ *
+ * Logic is simple:
+ *
+ * - first intersection, store the direction.
+ * - successive intersections will update the first distance if its aligned with the first hit.
+ * otherwise update the opposite distance.
+ * - caller stores best outcome in both directions.
+ *
+ * \{ */
+
+typedef struct MinDistDir {
+ /* distance in both directions (FLT_MAX == uninitialized) */
+ float dist_min[2];
+ /* direction of the first intersection found */
+ float dir[3];
+} MinDistDir;
+
+#define MIN_DIST_DIR_INIT {{FLT_MAX, FLT_MAX}}
+
+static int min_dist_dir_test(MinDistDir *mddir, const float dist_dir[3], const float dist_sq)
+{
+
+ if (mddir->dist_min[0] == FLT_MAX) {
+ return 0;
+ }
+ else {
+ if (dot_v3v3(dist_dir, mddir->dir) > 0.0f) {
+ if (dist_sq < mddir->dist_min[0]) {
+ return 0;
+ }
+ }
+ else {
+ if (dist_sq < mddir->dist_min[1]) {
+ return 1;
+ }
+ }
+ }
+
+ return -1;
+}
+
+static void min_dist_dir_update(MinDistDir *dist, const float dist_dir[3])
+{
+ if (dist->dist_min[0] == FLT_MAX) {
+ copy_v3_v3(dist->dir, dist_dir);
+ }
+}
+
+/** \} */
+
+
static int state_isect_co_pair(const PathContext *pc,
const float co_a[3], const float co_b[3])
{
@@ -141,9 +197,9 @@ static void state_calc_co_pair(const PathContext *pc,
/**
* Ideally we wouldn't need this and for most cases we don't.
- * But when a face has vertices that are on the boundary more then once this becomes tricky.
+ * But when a face has vertices that are on the boundary more than once this becomes tricky.
*/
-static bool state_link_find(PathLinkState *state, BMElem *ele)
+static bool state_link_find(const PathLinkState *state, BMElem *ele)
{
PathLink *link = state->link_last;
BLI_assert(ELEM(ele->head.htype, BM_VERT, BM_EDGE, BM_FACE));
@@ -230,23 +286,51 @@ static PathLinkState *state_dupe_add(
static PathLinkState *state_step__face_edges(
PathContext *pc,
PathLinkState *state, const PathLinkState *state_orig,
- BMLoop *l_iter, BMLoop *l_last)
+ BMLoop *l_iter, BMLoop *l_last,
+ MinDistDir *mddir)
{
+
+ BMLoop *l_iter_best[2] = {NULL, NULL};
+ int i;
+
do {
if (state_isect_co_pair(pc, l_iter->v->co, l_iter->next->v->co)) {
- BMElem *ele_next = (BMElem *)l_iter->e;
- BMElem *ele_next_from = (BMElem *)l_iter->f;
+ float dist_test;
+ float co_isect[3];
+ float dist_dir[3];
+ int index;
- if (FACE_WALK_TEST((BMFace *)ele_next_from) &&
- (state_link_find(state, ele_next) == false))
- {
- if (state_orig->link_last != state->link_last) {
- state = state_dupe_add(pc, state, state_orig);
+ state_calc_co_pair(pc, l_iter->v->co, l_iter->next->v->co, co_isect);
+
+ sub_v3_v3v3(dist_dir, co_isect, state_orig->co_prev);
+ dist_test = len_squared_v3(dist_dir);
+ if ((index = min_dist_dir_test(mddir, dist_dir, dist_test)) != -1) {
+ BMElem *ele_next = (BMElem *)l_iter->e;
+ BMElem *ele_next_from = (BMElem *)l_iter->f;
+
+ if (FACE_WALK_TEST((BMFace *)ele_next_from) &&
+ (state_link_find(state_orig, ele_next) == false))
+ {
+ min_dist_dir_update(mddir, dist_dir);
+ mddir->dist_min[index] = dist_test;
+ l_iter_best[index] = l_iter;
}
- state_link_add(pc, state, ele_next, ele_next_from);
}
}
} while ((l_iter = l_iter->next) != l_last);
+
+ for (i = 0; i < 2; i++) {
+ if ((l_iter = l_iter_best[i])) {
+ BMElem *ele_next = (BMElem *)l_iter->e;
+ BMElem *ele_next_from = (BMElem *)l_iter->f;
+
+ if (state_orig->link_last != state->link_last) {
+ state = state_dupe_add(pc, state, state_orig);
+ }
+ state_link_add(pc, state, ele_next, ele_next_from);
+ }
+ }
+
return state;
}
@@ -254,23 +338,48 @@ static PathLinkState *state_step__face_edges(
static PathLinkState *state_step__face_verts(
PathContext *pc,
PathLinkState *state, const PathLinkState *state_orig,
- BMLoop *l_iter, BMLoop *l_last)
+ BMLoop *l_iter, BMLoop *l_last,
+ MinDistDir *mddir)
{
+ BMLoop *l_iter_best[2] = {NULL, NULL};
+ int i;
+
do {
if (state_isect_co_exact(pc, l_iter->v->co)) {
+ float dist_test;
+ const float *co_isect = l_iter->v->co;
+ float dist_dir[3];
+ int index;
+
+ sub_v3_v3v3(dist_dir, co_isect, state_orig->co_prev);
+ dist_test = len_squared_v3(dist_dir);
+ if ((index = min_dist_dir_test(mddir, dist_dir, dist_test)) != -1) {
+ BMElem *ele_next = (BMElem *)l_iter->v;
+ BMElem *ele_next_from = (BMElem *)l_iter->f;
+
+ if (FACE_WALK_TEST((BMFace *)ele_next_from) &&
+ (state_link_find(state_orig, ele_next) == false))
+ {
+ min_dist_dir_update(mddir, dist_dir);
+ mddir->dist_min[index] = dist_test;
+ l_iter_best[index] = l_iter;
+ }
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_last);
+
+ for (i = 0; i < 2; i++) {
+ if ((l_iter = l_iter_best[i])) {
BMElem *ele_next = (BMElem *)l_iter->v;
BMElem *ele_next_from = (BMElem *)l_iter->f;
- if (FACE_WALK_TEST((BMFace *)ele_next_from) &&
- state_link_find(state, ele_next) == false)
- {
- if (state_orig->link_last != state->link_last) {
- state = state_dupe_add(pc, state, state_orig);
- }
- state_link_add(pc, state, ele_next, ele_next_from);
+ if (state_orig->link_last != state->link_last) {
+ state = state_dupe_add(pc, state, state_orig);
}
+ state_link_add(pc, state, ele_next, ele_next_from);
}
- } while ((l_iter = l_iter->next) != l_last);
+ }
+
return state;
}
@@ -290,20 +399,12 @@ static bool state_step(PathContext *pc, PathLinkState *state)
if ((l_start->f != ele_from) &&
FACE_WALK_TEST(l_start->f))
{
+ MinDistDir mddir = MIN_DIST_DIR_INIT;
/* very similar to block below */
- if (BM_vert_in_face(l_start->f, pc->v_b)) {
- if (state_orig.link_last != state->link_last) {
- state = state_dupe_add(pc, state, &state_orig);
- }
-
- state_link_add(pc, state, (BMElem *)pc->v_b, (BMElem *)l_start->f);
- }
- else {
- state = state_step__face_edges(pc, state, &state_orig,
- l_start->next, l_start);
- state = state_step__face_verts(pc, state, &state_orig,
- l_start->next->next, l_start);
- }
+ state = state_step__face_edges(pc, state, &state_orig,
+ l_start->next, l_start, &mddir);
+ state = state_step__face_verts(pc, state, &state_orig,
+ l_start->next->next, l_start, &mddir);
}
}
}
@@ -319,24 +420,14 @@ static bool state_step(PathContext *pc, PathLinkState *state)
if ((l_start->f != ele_from) &&
FACE_WALK_TEST(l_start->f))
{
+ MinDistDir mddir = MIN_DIST_DIR_INIT;
/* very similar to block above */
- if (BM_vert_in_face(l_start->f, pc->v_b)) {
- BMElem *ele_next = (BMElem *)pc->v_b;
- BMElem *ele_next_from = (BMElem *)l_start->f;
-
- if (state_orig.link_last != state->link_last) {
- state = state_dupe_add(pc, state, &state_orig);
- }
- state_link_add(pc, state, ele_next, ele_next_from);
- }
- else {
- state = state_step__face_edges(pc, state, &state_orig,
- l_start->next, l_start->prev);
- if (l_start->f->len > 3) {
- /* adjacent verts are handled in state_step__vert_edges */
- state = state_step__face_verts(pc, state, &state_orig,
- l_start->next->next, l_start->prev);
- }
+ state = state_step__face_edges(pc, state, &state_orig,
+ l_start->next, l_start->prev, &mddir);
+ if (l_start->f->len > 3) {
+ /* adjacent verts are handled in state_step__vert_edges */
+ state = state_step__face_verts(pc, state, &state_orig,
+ l_start->next->next, l_start->prev, &mddir);
}
}
}
@@ -351,31 +442,19 @@ static bool state_step(PathContext *pc, PathLinkState *state)
if (((BMElem *)e != ele_from) &&
VERT_WALK_TEST(v_other))
{
- if (v_other == pc->v_b) {
- BMElem *ele_next = (BMElem *)pc->v_b;
+ if (state_isect_co_exact(pc, v_other->co)) {
+ BMElem *ele_next = (BMElem *)v_other;
BMElem *ele_next_from = (BMElem *)e;
-
- if (state_orig.link_last != state->link_last) {
- state = state_dupe_add(pc, state, &state_orig);
- }
- state_link_add(pc, state, ele_next, ele_next_from);
- }
- else {
- if (state_isect_co_exact(pc, v_other->co)) {
- BMElem *ele_next = (BMElem *)v_other;
- BMElem *ele_next_from = (BMElem *)e;
- if (state_link_find(state, ele_next) == false) {
- if (state_orig.link_last != state->link_last) {
- state = state_dupe_add(pc, state, &state_orig);
- }
- state_link_add(pc, state, ele_next, ele_next_from);
+ if (state_link_find(state, ele_next) == false) {
+ if (state_orig.link_last != state->link_last) {
+ state = state_dupe_add(pc, state, &state_orig);
}
+ state_link_add(pc, state, ele_next, ele_next_from);
}
}
}
}
}
-
}
else {
BLI_assert(0);
@@ -459,11 +538,19 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
#endif
/* get third axis */
+ normalize_v3(basis_dir);
+ normalize_v3(basis_nor);
cross_v3_v3v3(basis_tmp, basis_dir, basis_nor);
+ if (UNLIKELY(normalize_v3(basis_tmp) < FLT_EPSILON)) {
+ ortho_v3_v3(basis_nor, basis_dir);
+ normalize_v3(basis_nor);
+ cross_v3_v3v3(basis_tmp, basis_dir, basis_nor);
+ normalize_v3(basis_tmp);
+ }
- normalize_v3_v3(pc.matrix[0], basis_tmp);
- normalize_v3_v3(pc.matrix[1], basis_dir);
- normalize_v3_v3(pc.matrix[2], basis_nor);
+ copy_v3_v3(pc.matrix[0], basis_tmp);
+ copy_v3_v3(pc.matrix[1], basis_dir);
+ copy_v3_v3(pc.matrix[2], basis_nor);
invert_m3(pc.matrix);
pc.axis_sep = dot_m3_v3_row_x(pc.matrix, pc.v_a->co);
@@ -482,6 +569,9 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
while (pc.state_lb.first) {
PathLinkState *state, *state_next;
found_all = true;
+#ifdef DEBUG_PRINT
+ printf("\n%s: stepping %d\n", __func__, BLI_listbase_count(&pc.state_lb));
+#endif
for (state = pc.state_lb.first; state; state = state_next) {
state_next = state->next;
if (state->link_last->ele == (BMElem *)pc.v_b) {
@@ -562,12 +652,10 @@ void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op)
#if 1
if (found_all) {
- /* leave 'check_degenerate' off, if a user tries to cut with 2 verts,
- * always connect even when resulting faces are degenerate [#39418] */
BMOperator op_sub;
BMO_op_initf(bm, &op_sub, 0,
- "connect_verts verts=%fv faces_exclude=%s",
- VERT_OUT, op, "faces_exclude");
+ "connect_verts verts=%fv faces_exclude=%s check_degenerate=%b",
+ VERT_OUT, op, "faces_exclude", true);
BMO_op_exec(bm, &op_sub);
BMO_slot_copy(&op_sub, slots_out, "edges.out",
op, slots_out, "edges.out");
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index dd814fa8bfb..1c054e89e39 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -39,7 +39,7 @@
/* This is what runs when pressing the F key
* doing the best thing here isn't always easy create vs dissolve, its nice to support
- * but it it _really_ gives issues we might have to not call dissolve. - campbell
+ * but it _really_ gives issues we might have to not call dissolve. - campbell
*/
void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
{
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 8cd9ee14bcb..ecb41363761 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -475,7 +475,7 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op)
{
BMOpSlot *einput = BMO_slot_get(op->slots_in, "edges");
BMOpSlot *vinput = BMO_slot_get(op->slots_in, "verts");
- const float angle_max = (float)M_PI / 2.0f;
+ const float angle_max = M_PI_2;
const float angle_limit = min_ff(angle_max, BMO_slot_float_get(op->slots_in, "angle_limit"));
const bool do_dissolve_boundaries = BMO_slot_bool_get(op->slots_in, "use_dissolve_boundaries");
const BMO_Delimit delimit = BMO_slot_int_get(op->slots_in, "delimit");
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index cd5592f08c9..a5a6480c187 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -109,7 +109,7 @@ static BMEdge *bmo_edge_copy(BMOperator *op,
/* add to new/old edge map if necassary */
if (rlen < 2) {
- /* not sure what non-manifold cases of greater then three
+ /* not sure what non-manifold cases of greater than three
* radial should do. */
BMO_slot_map_elem_insert(op, slot_boundarymap_out, e_src, e_dst);
}
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 88b53b63abb..aa92c3054cd 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -608,10 +608,10 @@ static void calc_solidify_normals(BMesh *bm)
}
else {
/* only one face attached to that edge */
- /* an edge without another attached- the weight on this is
- * undefined, M_PI / 2 is 90d in radians and that seems good enough */
+ /* an edge without another attached- the weight on this is undefined,
+ * M_PI_2 is 90d in radians and that seems good enough */
copy_v3_v3(edge_normal, f1->no);
- mul_v3_fl(edge_normal, M_PI / 2);
+ mul_v3_fl(edge_normal, M_PI_2);
}
add_v3_v3(e->v1->no, edge_normal);
diff --git a/source/blender/bmesh/operators/bmo_fill_grid.c b/source/blender/bmesh/operators/bmo_fill_grid.c
index 40f6937245b..dd954adcd55 100644
--- a/source/blender/bmesh/operators/bmo_fill_grid.c
+++ b/source/blender/bmesh/operators/bmo_fill_grid.c
@@ -159,7 +159,7 @@ static void bm_loop_pair_test_copy(BMLoop *l_pair_a[2], BMLoop *l_pair_b[2])
*/
static void bm_loop_interp_from_grid_boundary_4(BMesh *bm, BMLoop *l, BMLoop *l_bound[4], const float w[4])
{
- void *l_cdata[4] = {
+ const void *l_cdata[4] = {
l_bound[0]->head.data,
l_bound[1]->head.data,
l_bound[2]->head.data,
@@ -170,8 +170,7 @@ static void bm_loop_interp_from_grid_boundary_4(BMesh *bm, BMLoop *l, BMLoop *l_
static void bm_loop_interp_from_grid_boundary_2(BMesh *bm, BMLoop *l, BMLoop *l_bound[2], const float t)
{
-
- void *l_cdata[2] = {
+ const void *l_cdata[2] = {
l_bound[0]->head.data,
l_bound[1]->head.data};
@@ -346,7 +345,7 @@ static void bm_grid_fill_array(BMesh *bm, BMVert **v_grid, const unsigned int xt
if (use_vert_interp) {
const float *w = weight_table[XY(x, y)];
- void *v_cdata[4] = {
+ const void *v_cdata[4] = {
v_grid[XY(x, 0)]->head.data,
v_grid[XY(0, y)]->head.data,
v_grid[XY(x, ytot - 1)]->head.data,
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index 26a4dbe1e1d..fb99c9777d0 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -285,8 +285,8 @@ static void hull_remove_overlapping(BMesh *bm, GSet *hull_triangles,
/* Note: can't change ghash while iterating, so mark
* with 'skip' flag rather than deleting triangles */
- if (BM_vert_in_face(f, t->v[1]) &&
- BM_vert_in_face(f, t->v[2]) && f_on_hull)
+ if (BM_vert_in_face(t->v[1], f) &&
+ BM_vert_in_face(t->v[2], f) && f_on_hull)
{
t->skip = true;
BMO_elem_flag_disable(bm, f, HULL_FLAG_INTERIOR_ELE);
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index b7914e84c50..27e140eb990 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -390,8 +390,10 @@ static void bmo_face_inset_individual(
if (use_interpolate) {
- BM_face_interp_from_face_ex(bm, iface->f, iface->f, true,
- iface->blocks_l, iface->blocks_v, iface->cos_2d, iface->axis_mat);
+ BM_face_interp_from_face_ex(
+ bm, iface->f, iface->f, true,
+ (const void **)iface->blocks_l, (const void **)iface->blocks_v,
+ iface->cos_2d, iface->axis_mat);
/* build rim faces */
l_iter = l_first;
@@ -993,8 +995,10 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
for (i = 0; i < iface_array_len; i++) {
if (iface_array[i]) {
InterpFace *iface = iface_array[i];
- BM_face_interp_from_face_ex(bm, iface->f, iface->f, true,
- iface->blocks_l, iface->blocks_v, iface->cos_2d, iface->axis_mat);
+ BM_face_interp_from_face_ex(
+ bm, iface->f, iface->f, true,
+ (const void **)iface->blocks_l, (const void **)iface->blocks_v,
+ iface->cos_2d, iface->axis_mat);
}
}
}
diff --git a/source/blender/bmesh/operators/bmo_normals.c b/source/blender/bmesh/operators/bmo_normals.c
index d0f08871400..f62e445ca18 100644
--- a/source/blender/bmesh/operators/bmo_normals.c
+++ b/source/blender/bmesh/operators/bmo_normals.c
@@ -47,39 +47,79 @@ static bool bmo_recalc_normal_edge_filter_cb(BMElem *ele, void *UNUSED(user_data
}
/**
- * Given an array of faces, recalculate their normals.
- * this functions assumes all faces in the array are connected by edges.
+ * This uses a more comprehensive test to see if the furthest face from the center
+ * is pointing towards the center or not.
*
- * \param bm
- * \param faces Array of connected faces.
- * \param faces_len Length of \a faces
- * \param oflag Flag to check before doing the actual face flipping.
+ * A simple test could just check the dot product of the faces-normal and the direction from the center,
+ * however this can fail for faces which make a sharp spike. eg:
+ *
+ * <pre>
+ * +
+ * |\ <- face
+ * + +
+ * \ \
+ * \ \
+ * \ +--------------+
+ * \ |
+ * \ center -> + |
+ * \ |
+ * +------------+
+ * </pre>
+ *
+ * In the example above, the a\ face can point towards the \a center
+ * which would end up flipping the normals inwards.
+ *
+ * To take these spikes into account, use the normals of the faces edges.
*/
-static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int faces_len, const short oflag)
+#define USE_FACE_EDGE_NORMAL_TEST
+
+/**
+ * The center of the entire island is't necessarily well placed,
+ *
+ * This re-calculated a center relative to this face.
+ */
+#ifdef USE_FACE_EDGE_NORMAL_TEST
+# define USE_FACE_LOCAL_CENTER_TEST
+#endif
+
+/**
+ * \return a face index in \a faces and set \a r_is_flip if the face is flipped away from the center.
+ */
+static int recalc_face_normals_find_index(BMesh *bm, BMFace **faces, const int faces_len, bool *r_is_flip)
{
+ float cent_area_accum = 0.0f;
+ float f_len_best_sq;
+
float cent[3], tvec[3];
- float (*faces_center)[3] = MEM_mallocN(sizeof(*faces_center) * faces_len, __func__);
const float cent_fac = 1.0f / (float)faces_len;
- int i, f_start_index;
- const short oflag_flip = oflag | FACE_FLIP;
- float f_len_best_sq;
- BMFace *f;
+ float (*faces_center)[3] = MEM_mallocN(sizeof(*faces_center) * faces_len, __func__);
+ float *faces_area = MEM_mallocN(sizeof(*faces_area) * faces_len, __func__);
+ bool is_flip = false;
+ int f_start_index;
+ int i;
- BLI_LINKSTACK_DECLARE(fstack, BMFace *);
+ UNUSED_VARS_NDEBUG(bm);
zero_v3(cent);
/* first calculate the center */
for (i = 0; i < faces_len; i++) {
float *f_cent = faces_center[i];
+ const float f_area = BM_face_calc_area(faces[i]);
BM_face_calc_center_mean_weighted(faces[i], f_cent);
- madd_v3_v3fl(cent, f_cent, cent_fac);
+ madd_v3_v3fl(cent, f_cent, cent_fac * f_area);
+ cent_area_accum += f_area;
+ faces_area[i] = f_area;
BLI_assert(BMO_elem_flag_test(bm, faces[i], FACE_TEMP) == 0);
BLI_assert(BM_face_is_normal_valid(faces[i]));
}
+ if (cent_area_accum != 0.0f) {
+ mul_v3_fl(cent, 1.0f / cent_area_accum);
+ }
+
f_len_best_sq = -FLT_MAX;
/* used in degenerate cases only */
f_start_index = 0;
@@ -87,19 +127,104 @@ static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int f
for (i = 0; i < faces_len; i++) {
float f_len_test_sq;
- if ((f_len_test_sq = len_squared_v3v3(faces_center[i], cent)) > f_len_best_sq) {
- f_len_best_sq = f_len_test_sq;
- f_start_index = i;
+ if (faces_area[i] > FLT_EPSILON) {
+ if ((f_len_test_sq = len_squared_v3v3(faces_center[i], cent)) > f_len_best_sq) {
+ f_len_best_sq = f_len_test_sq;
+ f_start_index = i;
+ }
}
}
- /* make sure the starting face has the correct winding */
- sub_v3_v3v3(tvec, faces_center[f_start_index], cent);
- if (dot_v3v3(tvec, faces[f_start_index]->no) < 0.0f) {
- BMO_elem_flag_enable(bm, faces[f_start_index], FACE_FLIP);
+#ifdef USE_FACE_EDGE_NORMAL_TEST
+ {
+ BMFace *f_test = faces[f_start_index];
+ BMLoop *l_iter, *l_first;
+ float e_len_best_sq = -FLT_MAX;
+ BMLoop *l_other_best = NULL;
+ float no_edge[3];
+ const float *no_best;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_test);
+ do {
+ if (BM_edge_is_manifold(l_iter->e) &&
+ bmo_recalc_normal_edge_filter_cb((BMElem *)l_iter->e, NULL))
+ {
+ BMLoop *l_other = l_iter->radial_next;
+
+ if (len_squared_v3v3(l_iter->v->co, l_iter->next->v->co) > FLT_EPSILON) {
+ float e_len_test_sq;
+ float e_cent[3];
+ mid_v3_v3v3(e_cent, l_iter->v->co, l_iter->next->v->co);
+ e_len_test_sq = len_squared_v3v3(cent, e_cent);
+ if (e_len_test_sq > e_len_best_sq) {
+ l_other_best = l_other;
+ e_len_best_sq = e_len_test_sq;
+ }
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ /* furthest edge on furthest face */
+ if (l_other_best) {
+ float e_cent[3];
+
+#ifdef USE_FACE_LOCAL_CENTER_TEST
+ {
+ float f_cent_other[3];
+ BM_face_calc_center_mean_weighted(l_other_best->f, f_cent_other);
+ mid_v3_v3v3(cent, f_cent_other, faces_center[f_start_index]);
+ }
+#endif
+ mid_v3_v3v3(e_cent, l_other_best->e->v1->co, l_other_best->e->v2->co);
+ sub_v3_v3v3(tvec, e_cent, cent);
+
+ madd_v3_v3v3fl(no_edge, f_test->no, l_other_best->f->no, BM_edge_is_contiguous(l_other_best->e) ? 1 : -1);
+ no_best = no_edge;
+ }
+ else {
+ sub_v3_v3v3(tvec, faces_center[f_start_index], cent);
+ no_best = f_test->no;
+ }
+
+ is_flip = (dot_v3v3(tvec, no_best) < 0.0f);
}
+#else
+ sub_v3_v3v3(tvec, faces_center[f_start_index], cent);
+ is_flip = (dot_v3v3(tvec, faces[f_start_index]->no) < 0.0f);
+#endif
+ /* make sure the starting face has the correct winding */
MEM_freeN(faces_center);
+ MEM_freeN(faces_area);
+
+ *r_is_flip = is_flip;
+ return f_start_index;
+}
+
+/**
+ * Given an array of faces, recalculate their normals.
+ * this functions assumes all faces in the array are connected by edges.
+ *
+ * \param bm
+ * \param faces Array of connected faces.
+ * \param faces_len Length of \a faces
+ * \param oflag Flag to check before doing the actual face flipping.
+ */
+static void bmo_recalc_face_normals_array(BMesh *bm, BMFace **faces, const int faces_len, const short oflag)
+{
+ int i, f_start_index;
+ const short oflag_flip = oflag | FACE_FLIP;
+ bool is_flip;
+
+ BMFace *f;
+
+ BLI_LINKSTACK_DECLARE(fstack, BMFace *);
+
+ f_start_index = recalc_face_normals_find_index(bm, faces, faces_len, &is_flip);
+
+ if (is_flip) {
+ BMO_elem_flag_enable(bm, faces[f_start_index], FACE_FLIP);
+ }
/* now that we've found our starting face, make all connected faces
* have the same winding. this is done recursively, using a manual
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index e69dcca6342..2108a2c0589 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -662,78 +662,46 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
{
- BMVert *v1, *v2, *v3, *v4, *v5, *v6, *v7, *v8;
- float vec[3], mat[4][4], off = BMO_slot_float_get(op->slots_in, "size") / 2.0f;
+ BMVert *verts[8];
+ float mat[4][4];
+ float off = BMO_slot_float_get(op->slots_in, "size") / 2.0f;
+ int i, x, y, z;
+ const char faces[6][4] = {
+ {1, 3, 2, 0},
+ {3, 7, 6, 2},
+ {7, 5, 4, 6},
+ {5, 1, 0, 4},
+ {0, 2, 6, 4},
+ {5, 7, 3, 1},
+ };
BMO_slot_mat4_get(op->slots_in, "matrix", mat);
if (!off) off = 0.5f;
+ i = 0;
- vec[0] = -off;
- vec[1] = -off;
- vec[2] = -off;
- mul_m4_v3(mat, vec);
- v1 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
- BMO_elem_flag_enable(bm, v1, VERT_MARK);
-
- vec[0] = -off;
- vec[1] = off;
- vec[2] = -off;
- mul_m4_v3(mat, vec);
- v2 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
- BMO_elem_flag_enable(bm, v2, VERT_MARK);
-
- vec[0] = off;
- vec[1] = off;
- vec[2] = -off;
- mul_m4_v3(mat, vec);
- v3 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
- BMO_elem_flag_enable(bm, v3, VERT_MARK);
-
- vec[0] = off;
- vec[1] = -off;
- vec[2] = -off;
- mul_m4_v3(mat, vec);
- v4 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
- BMO_elem_flag_enable(bm, v4, VERT_MARK);
-
- vec[0] = -off;
- vec[1] = -off;
- vec[2] = off;
- mul_m4_v3(mat, vec);
- v5 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
- BMO_elem_flag_enable(bm, v5, VERT_MARK);
-
- vec[0] = -off;
- vec[1] = off;
- vec[2] = off;
- mul_m4_v3(mat, vec);
- v6 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
- BMO_elem_flag_enable(bm, v6, VERT_MARK);
-
- vec[0] = off;
- vec[1] = off;
- vec[2] = off;
- mul_m4_v3(mat, vec);
- v7 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
- BMO_elem_flag_enable(bm, v7, VERT_MARK);
-
- vec[0] = off;
- vec[1] = -off;
- vec[2] = off;
- mul_m4_v3(mat, vec);
- v8 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
- BMO_elem_flag_enable(bm, v8, VERT_MARK);
-
- /* the four sides */
- BM_face_create_quad_tri(bm, v5, v6, v2, v1, NULL, BM_CREATE_NOP);
- BM_face_create_quad_tri(bm, v6, v7, v3, v2, NULL, BM_CREATE_NOP);
- BM_face_create_quad_tri(bm, v7, v8, v4, v3, NULL, BM_CREATE_NOP);
- BM_face_create_quad_tri(bm, v8, v5, v1, v4, NULL, BM_CREATE_NOP);
-
- /* top/bottom */
- BM_face_create_quad_tri(bm, v1, v2, v3, v4, NULL, BM_CREATE_NOP);
- BM_face_create_quad_tri(bm, v8, v7, v6, v5, NULL, BM_CREATE_NOP);
+ for (x = -1; x < 2; x += 2) {
+ for (y = -1; y < 2; y += 2) {
+ for (z = -1; z < 2; z += 2) {
+ float vec[3] = {(float)x * off, (float)y * off, (float)z * off};
+ mul_m4_v3(mat, vec);
+ verts[i] = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
+ BMO_elem_flag_enable(bm, verts[i], VERT_MARK);
+ i++;
+ }
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(faces); i++) {
+ BMVert *quad[4] = {
+ verts[faces[i][0]],
+ verts[faces[i][1]],
+ verts[faces[i][2]],
+ verts[faces[i][3]],
+ };
+
+ BM_face_create_verts(bm, quad, 4, NULL, BM_CREATE_NOP, true);
+ }
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index 75f9feef413..871bee64c19 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -238,7 +238,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
static int vergaverco(const void *e1, const void *e2)
{
- const BMVert *v1 = *(void **)e1, *v2 = *(void **)e2;
+ const BMVert *v1 = *(const void **)e1, *v2 = *(const void **)e2;
float x1 = v1->co[0] + v1->co[1] + v1->co[2];
float x2 = v2->co[0] + v2->co[1] + v2->co[2];
@@ -529,7 +529,7 @@ static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op,
const float dist = BMO_slot_float_get(op->slots_in, "dist");
const float dist_sq = dist * dist;
- const float dist3 = (M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */
+ const float dist3 = ((float)M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */
/* Test whether keep_verts arg exists and is non-empty */
if (BMO_slot_exists(op->slots_in, "keep_verts")) {
diff --git a/source/blender/bmesh/operators/bmo_similar.c b/source/blender/bmesh/operators/bmo_similar.c
index f779828a00d..5f8438919df 100644
--- a/source/blender/bmesh/operators/bmo_similar.c
+++ b/source/blender/bmesh/operators/bmo_similar.c
@@ -115,7 +115,7 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
num_total = BM_mesh_elem_count(bm, BM_FACE);
/*
- * The first thing to do is to iterate through all the the selected items and mark them since
+ * The first thing to do is to iterate through all the selected items and mark them since
* they will be in the selection anyway.
* This will increase performance, (especially when the number of originally selected faces is high)
* so the overall complexity will be less than $O(mn)$ where is the total number of selected faces,
@@ -245,6 +245,13 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
cont = false;
}
break;
+
+ case SIMFACE_SMOOTH:
+ if (BM_elem_flag_test(fm, BM_ELEM_SMOOTH) == BM_elem_flag_test(fs, BM_ELEM_SMOOTH)) {
+ BMO_elem_flag_enable(bm, fm, FACE_MARK);
+ cont = false;
+ }
+ break;
#ifdef WITH_FREESTYLE
case SIMFACE_FREESTYLE:
if (CustomData_has_layer(&bm->pdata, CD_FREESTYLE_FACE)) {
@@ -405,10 +412,10 @@ void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
/* compute the angle between the two edges */
angle = angle_normalized_v3v3(e_ext[i].dir, e_ext[indices[idx]].dir);
- if (angle > (float)(M_PI / 2.0)) /* use the smallest angle between the edges */
+ if (angle > (float)M_PI_2) /* use the smallest angle between the edges */
angle = fabsf(angle - (float)M_PI);
- if (angle / (float)(M_PI / 2.0) <= thresh) {
+ if (angle / (float)M_PI_2 <= thresh) {
BMO_elem_flag_enable(bm, e, EDGE_MARK);
cont = false;
}
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 0d9ce4b2731..003c27671a5 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -319,13 +319,9 @@ static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, const SubDParams *par
for (i = 0; i < numcuts; i++) {
v = subdivideedgenum(bm, eed, &e_tmp, i, params->numcuts, params, &e_new, vsta, vend);
- BMO_elem_flag_enable(bm, v, SUBD_SPLIT);
- BMO_elem_flag_enable(bm, eed, SUBD_SPLIT);
- BMO_elem_flag_enable(bm, e_new, SUBD_SPLIT);
-
- BMO_elem_flag_enable(bm, v, ELE_SPLIT);
- BMO_elem_flag_enable(bm, eed, ELE_SPLIT);
- BMO_elem_flag_enable(bm, e_new, SUBD_SPLIT);
+ BMO_elem_flag_enable(bm, v, SUBD_SPLIT | ELE_SPLIT);
+ BMO_elem_flag_enable(bm, eed, SUBD_SPLIT | ELE_SPLIT);
+ BMO_elem_flag_enable(bm, e_new, SUBD_SPLIT | ELE_SPLIT);
BM_CHECK_ELEMENT(v);
if (v->e) BM_CHECK_ELEMENT(v->e);
@@ -802,13 +798,13 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
patterns[1] = NULL;
/* straight cut is patterns[1] == NULL */
switch (cornertype) {
- case SUBD_PATH:
+ case SUBD_CORNER_PATH:
patterns[1] = &quad_2edge_path;
break;
- case SUBD_INNERVERT:
+ case SUBD_CORNER_INNERVERT:
patterns[1] = &quad_2edge_innervert;
break;
- case SUBD_FAN:
+ case SUBD_CORNER_FAN:
patterns[1] = &quad_2edge_fan;
break;
}
@@ -1082,7 +1078,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BMIter other_fiter;
BM_ITER_ELEM (other_loop, &other_fiter, loops[a]->v, BM_LOOPS_OF_VERT) {
if (other_loop->f != face) {
- if (BM_vert_in_face(other_loop->f, loops[b]->v)) {
+ if (BM_vert_in_face(loops[b]->v, other_loop->f)) {
/* we assume that these verts are not making an edge in the face */
BLI_assert(other_loop->prev->v != loops[a]->v);
BLI_assert(other_loop->next->v != loops[a]->v);
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index 986583cc21b..cb9ba5e361c 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -75,6 +75,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
GHash *sf_vert_map;
float normal[3];
const int scanfill_flag = BLI_SCANFILL_CALC_HOLES | BLI_SCANFILL_CALC_POLYS | BLI_SCANFILL_CALC_LOOSE;
+ unsigned int nors_tot;
bool calc_winding = false;
sf_vert_map = BLI_ghash_ptr_new_ex(__func__, BMO_slot_buffer_count(op->slots_in, "edges"));
@@ -103,6 +104,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
/* sf_edge = */ BLI_scanfill_edge_add(&sf_ctx, UNPACK2(sf_verts));
/* sf_edge->tmp.p = e; */ /* UNUSED */
}
+ nors_tot = BLI_ghash_size(sf_vert_map);
BLI_ghash_free(sf_vert_map, NULL, NULL);
@@ -111,7 +113,6 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
* Since we don't know winding, just accumulate */
ScanFillVert *sf_vert;
struct SortNormal *nors;
- const unsigned int nors_tot = BLI_ghash_size(sf_vert_map);
unsigned int i;
bool is_degenerate = true;
@@ -182,7 +183,11 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
calc_winding = false;
}
- normalize_v3(normal);
+ /* in this case we almost certainly have degenerate geometry,
+ * better set a fallback value as a last resort */
+ if (UNLIKELY(normalize_v3(normal) == 0.0f)) {
+ normal[2] = 1.0f;
+ }
BLI_scanfill_calc_ex(&sf_ctx, scanfill_flag, normal);
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index a06d40c8c0f..da1991a187d 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -177,42 +177,108 @@ void bmo_rotate_edges_exec(BMesh *bm, BMOperator *op)
#define SEL_FLAG 1
#define SEL_ORIG 2
-static void bmo_region_extend_extend(BMesh *bm, BMOperator *op, const bool use_faces)
+static void bmo_face_flag_set_flush(BMesh *bm, BMFace *f, const short oflag, const bool value)
+{
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ BMO_elem_flag_set(bm, f, oflag, value);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BMO_elem_flag_set(bm, l_iter->e, oflag, value);
+ BMO_elem_flag_set(bm, l_iter->v, oflag, value);
+ } while ((l_iter = l_iter->next) != l_first);
+}
+
+
+static void bmo_region_extend_expand(
+ BMesh *bm, BMOperator *op,
+ const bool use_faces, const bool use_faces_step)
{
- BMVert *v;
- BMEdge *e;
- BMIter eiter;
BMOIter siter;
if (!use_faces) {
+ BMVert *v;
+
BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
- BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN))
- if (!BMO_elem_flag_test(bm, e, SEL_ORIG))
+ bool found = false;
+
+ {
+ BMIter eiter;
+ BMEdge *e;
+
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, e, SEL_ORIG)) {
+ found = true;
break;
+ }
+ }
}
- if (e) {
- BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- BMO_elem_flag_enable(bm, e, SEL_FLAG);
- BMO_elem_flag_enable(bm, BM_edge_other_vert(e, v), SEL_FLAG);
+ if (found) {
+ if (!use_faces_step) {
+ BMIter eiter;
+ BMEdge *e;
+
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, e, SEL_FLAG)) {
+ BMO_elem_flag_enable(bm, e, SEL_FLAG);
+ BMO_elem_flag_enable(bm, BM_edge_other_vert(e, v), SEL_FLAG);
+ }
+ }
+ }
+ else {
+ BMIter fiter;
+ BMFace *f;
+
+ BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, f, SEL_FLAG)) {
+ bmo_face_flag_set_flush(bm, f, SEL_FLAG, true);
+ }
+ }
+
+ /* handle wire edges (when stepping over faces) */
+ {
+ BMIter eiter;
+ BMEdge *e;
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (BM_edge_is_wire(e)) {
+ if (!BMO_elem_flag_test(bm, e, SEL_FLAG)) {
+ BMO_elem_flag_enable(bm, e, SEL_FLAG);
+ BMO_elem_flag_enable(bm, BM_edge_other_vert(e, v), SEL_FLAG);
+ }
+ }
+ }
}
}
}
}
}
else {
- BMIter liter, fiter;
- BMFace *f, *f2;
- BMLoop *l;
+ BMFace *f;
BMO_ITER (f, &siter, op->slots_in, "geom", BM_FACE) {
+ BMIter liter;
+ BMLoop *l;
+
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- BM_ITER_ELEM (f2, &fiter, l->e, BM_FACES_OF_EDGE) {
- if (!BM_elem_flag_test(f2, BM_ELEM_HIDDEN)) {
- if (!BMO_elem_flag_test(bm, f2, SEL_ORIG)) {
- BMO_elem_flag_enable(bm, f2, SEL_FLAG);
+ if (!use_faces_step) {
+ BMIter fiter;
+ BMFace *f_other;
+
+ BM_ITER_ELEM (f_other, &fiter, l->e, BM_FACES_OF_EDGE) {
+ if (!BMO_elem_flag_test(bm, f_other, SEL_ORIG | SEL_FLAG)) {
+ BMO_elem_flag_enable(bm, f_other, SEL_FLAG);
+ }
+ }
+ }
+ else {
+ BMIter fiter;
+ BMFace *f_other;
+
+ BM_ITER_ELEM (f_other, &fiter, l->v, BM_FACES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, f_other, SEL_ORIG | SEL_FLAG)) {
+ BMO_elem_flag_enable(bm, f_other, SEL_FLAG);
}
}
}
@@ -221,43 +287,94 @@ static void bmo_region_extend_extend(BMesh *bm, BMOperator *op, const bool use_f
}
}
-static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, const bool use_faces)
+static void bmo_region_extend_contract(
+ BMesh *bm, BMOperator *op,
+ const bool use_faces, const bool use_faces_step)
{
- BMVert *v;
- BMEdge *e;
- BMIter eiter;
BMOIter siter;
if (!use_faces) {
+ BMVert *v;
+
BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
- BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN))
- if (!BMO_elem_flag_test(bm, e, SEL_ORIG))
+ bool found = false;
+
+ if (!use_faces_step) {
+ BMIter eiter;
+ BMEdge *e;
+
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, e, SEL_ORIG)) {
+ found = true;
break;
+ }
+ }
}
+ else {
+ BMIter fiter;
+ BMFace *f;
- if (e) {
- BMO_elem_flag_enable(bm, v, SEL_FLAG);
+ BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, f, SEL_ORIG)) {
+ found = true;
+ break;
+ }
+ }
- BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- BMO_elem_flag_enable(bm, e, SEL_FLAG);
+ /* handle wire edges (when stepping over faces) */
+ if (!found) {
+ BMIter eiter;
+ BMEdge *e;
+
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (BM_edge_is_wire(e)) {
+ if (!BMO_elem_flag_test(bm, e, SEL_ORIG)) {
+ found = true;
+ break;
+ }
+ }
}
}
+ }
+
+ if (found) {
+ BMIter eiter;
+ BMEdge *e;
+
+ BMO_elem_flag_enable(bm, v, SEL_FLAG);
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ BMO_elem_flag_enable(bm, e, SEL_FLAG);
+ }
}
}
}
else {
- BMIter liter, fiter;
- BMFace *f, *f2;
- BMLoop *l;
+ BMFace *f;
BMO_ITER (f, &siter, op->slots_in, "geom", BM_FACE) {
+ BMIter liter;
+ BMLoop *l;
+
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- BM_ITER_ELEM (f2, &fiter, l->e, BM_FACES_OF_EDGE) {
- if (!BM_elem_flag_test(f2, BM_ELEM_HIDDEN)) {
- if (!BMO_elem_flag_test(bm, f2, SEL_ORIG)) {
+
+ if (!use_faces_step) {
+ BMIter fiter;
+ BMFace *f_other;
+
+ BM_ITER_ELEM (f_other, &fiter, l->e, BM_FACES_OF_EDGE) {
+ if (!BMO_elem_flag_test(bm, f_other, SEL_ORIG)) {
+ BMO_elem_flag_enable(bm, f, SEL_FLAG);
+ break;
+ }
+ }
+ }
+ else {
+ BMIter fiter;
+ BMFace *f_other;
+
+ BM_ITER_ELEM (f_other, &fiter, l->v, BM_FACES_OF_VERT) {
+ if (!BMO_elem_flag_test(bm, f_other, SEL_ORIG)) {
BMO_elem_flag_enable(bm, f, SEL_FLAG);
break;
}
@@ -271,14 +388,17 @@ static void bmo_region_extend_constrict(BMesh *bm, BMOperator *op, const bool us
void bmo_region_extend_exec(BMesh *bm, BMOperator *op)
{
const bool use_faces = BMO_slot_bool_get(op->slots_in, "use_faces");
- const bool constrict = BMO_slot_bool_get(op->slots_in, "use_constrict");
+ const bool use_face_step = BMO_slot_bool_get(op->slots_in, "use_face_step");
+ const bool constrict = BMO_slot_bool_get(op->slots_in, "use_contract");
BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL_NOLOOP, SEL_ORIG);
- if (constrict)
- bmo_region_extend_constrict(bm, op, use_faces);
- else
- bmo_region_extend_extend(bm, op, use_faces);
+ if (constrict) {
+ bmo_region_extend_contract(bm, op, use_faces, use_face_step);
+ }
+ else {
+ bmo_region_extend_expand(bm, op, use_faces, use_face_step);
+ }
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, SEL_FLAG);
}
diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c
index 62409fc3987..ac81dde93c0 100644
--- a/source/blender/bmesh/operators/bmo_wireframe.c
+++ b/source/blender/bmesh/operators/bmo_wireframe.c
@@ -26,8 +26,6 @@
* Creates a solid wireframe from connected faces.
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_material_types.h"
#include "BLI_sys_types.h"
diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c
index 6639e767e77..990a2108bd7 100644
--- a/source/blender/bmesh/tools/bmesh_beautify.c
+++ b/source/blender/bmesh/tools/bmesh_beautify.c
@@ -37,6 +37,7 @@
#include "BLI_math.h"
#include "BLI_heap.h"
+#include "BLI_polyfill2d_beautify.h"
#include "MEM_guardedalloc.h"
@@ -96,7 +97,7 @@ static GSet *erot_gset_new(void)
static void erot_state_ex(const BMEdge *e, int v_index[2], int f_index[2])
{
- BLI_assert(BM_edge_is_manifold((BMEdge *)e));
+ BLI_assert(BM_edge_is_manifold(e));
BLI_assert(BM_vert_in_edge(e, e->l->prev->v) == false);
BLI_assert(BM_vert_in_edge(e, e->l->radial_next->prev->v) == false);
@@ -125,22 +126,22 @@ static void erot_state_alternate(const BMEdge *e, EdRotState *e_state)
/* -------------------------------------------------------------------- */
/* Calculate the improvement of rotating the edge */
-/**
- * \return a negative value means the edge can be rotated.
- */
static float bm_edge_calc_rotate_beauty__area(
const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
/* not a loop (only to be able to break out) */
do {
float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2];
- bool is_zero_a, is_zero_b;
/* first get the 2d values */
{
+ const float eps = 1e-5;
float no_a[3], no_b[3];
float no[3];
float axis_mat[3][3];
+ float no_scale;
+ cross_tri_v3(no_a, v2, v3, v4);
+ cross_tri_v3(no_b, v2, v4, v1);
// printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
BLI_assert((ELEM(v1, v2, v3, v4) == false) &&
@@ -148,97 +149,40 @@ static float bm_edge_calc_rotate_beauty__area(
(ELEM(v3, v1, v2, v4) == false) &&
(ELEM(v4, v1, v2, v3) == false));
- is_zero_a = (normal_tri_v3(no_a, v2, v3, v4) <= FLT_EPSILON);
- is_zero_b = (normal_tri_v3(no_b, v2, v4, v1) <= FLT_EPSILON);
-
- if (LIKELY(is_zero_a == false && is_zero_b == false)) {
- add_v3_v3v3(no, no_a, no_b);
- if (UNLIKELY(normalize_v3(no) <= FLT_EPSILON)) {
- break;
- }
- }
- else if (is_zero_a == false) {
- copy_v3_v3(no, no_a);
- }
- else if (is_zero_b == false) {
- copy_v3_v3(no, no_b);
- }
- else {
- /* both zero area, no useful normal can be calculated */
+ add_v3_v3v3(no, no_a, no_b);
+ if (UNLIKELY((no_scale = normalize_v3(no)) <= FLT_EPSILON)) {
break;
}
- // { float a = angle_normalized_v3v3(no_a, no_b); printf("~ %.7f\n", a); fflush(stdout);}
-
axis_dominant_v3_to_m3(axis_mat, no);
mul_v2_m3v3(v1_xy, axis_mat, v1);
mul_v2_m3v3(v2_xy, axis_mat, v2);
mul_v2_m3v3(v3_xy, axis_mat, v3);
mul_v2_m3v3(v4_xy, axis_mat, v4);
- }
-
- // printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
-
- if (is_zero_a == false && is_zero_b == false) {
- /* both tri's are valid, check we make a concave quad */
- if (!is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) {
- break;
- }
- }
- else {
- /* one of the tri's was degenerate, chech we're not rotating
- * into a different degenerate shape or flipping the face */
- float area_a, area_b;
-
- area_a = area_tri_signed_v2(v1_xy, v2_xy, v3_xy);
- area_b = area_tri_signed_v2(v1_xy, v3_xy, v4_xy);
-
- if ((fabsf(area_a) <= FLT_EPSILON) || (fabsf(area_b) <= FLT_EPSILON)) {
- /* one of the new rotations is degenerate */
- break;
- }
- if ((area_a >= 0.0f) != (area_b >= 0.0f)) {
- /* rotation would cause flipping */
+ /**
+ * Check if input faces are already flipped.
+ * Logic for 'signum_i' addition is:
+ *
+ * Accept:
+ * - (1, 1) or (-1, -1): same side (common case).
+ * - (-1/1, 0): one degenerate, OK since we may rotate into a valid state.
+ *
+ * Ignore:
+ * - (-1, 1): opposite winding, ignore.
+ * - ( 0, 0): both degenerate, ignore.
+ *
+ * \note The cross product is divided by 'no_scale'
+ * so the rotation calculation is scale independent.
+ */
+ if (!(signum_i_ex(cross_tri_v2(v2_xy, v3_xy, v4_xy) / no_scale, eps) +
+ signum_i_ex(cross_tri_v2(v2_xy, v4_xy, v1_xy) / no_scale, eps)))
+ {
break;
}
}
- {
- /* testing rule: the area divided by the perimeter,
- * check if (1-3) beats the existing (2-4) edge rotation */
- float area_a, area_b;
- float prim_a, prim_b;
- float fac_24, fac_13;
-
- float len_12, len_23, len_34, len_41, len_24, len_13;
-
- /* edges around the quad */
- len_12 = len_v2v2(v1_xy, v2_xy);
- len_23 = len_v2v2(v2_xy, v3_xy);
- len_34 = len_v2v2(v3_xy, v4_xy);
- len_41 = len_v2v2(v4_xy, v1_xy);
- /* edges crossing the quad interior */
- len_13 = len_v2v2(v1_xy, v3_xy);
- len_24 = len_v2v2(v2_xy, v4_xy);
-
- /* edge (2-4), current state */
- area_a = area_tri_v2(v2_xy, v3_xy, v4_xy);
- area_b = area_tri_v2(v2_xy, v4_xy, v1_xy);
- prim_a = len_23 + len_34 + len_24;
- prim_b = len_24 + len_41 + len_12;
- fac_24 = (area_a / prim_a) + (area_b / prim_b);
-
- /* edge (1-3), new state */
- area_a = area_tri_v2(v1_xy, v2_xy, v3_xy);
- area_b = area_tri_v2(v1_xy, v3_xy, v4_xy);
- prim_a = len_12 + len_23 + len_13;
- prim_b = len_34 + len_41 + len_13;
- fac_13 = (area_a / prim_a) + (area_b / prim_b);
-
- /* negative number if (1-3) is an improved state */
- return fac_24 - fac_13;
- }
+ return BLI_polyfill_beautify_quad_rotate_calc(v1_xy, v2_xy, v3_xy, v4_xy);
} while (false);
return FLT_MAX;
@@ -272,6 +216,12 @@ static float bm_edge_calc_rotate_beauty__angle(
return FLT_MAX;
}
+/**
+ * Assuming we have 2 triangles sharing an edge (2 - 4),
+ * check if the edge running from (1 - 3) gives better results.
+ *
+ * \return (negative number means the edge can be rotated, lager == better).
+ */
float BM_verts_calc_rotate_beauty(
const BMVert *v1, const BMVert *v2, const BMVert *v3, const BMVert *v4,
const short flag, const short method)
@@ -400,9 +350,10 @@ static void bm_edge_update_beauty_cost(BMEdge *e, Heap *eheap, HeapNode **eheap_
/**
* \note This function sets the edge indices to invalid values.
*/
-void BM_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_len,
- const short flag, const short method,
- const short oflag_edge, const short oflag_face)
+void BM_mesh_beautify_fill(
+ BMesh *bm, BMEdge **edge_array, const int edge_array_len,
+ const short flag, const short method,
+ const short oflag_edge, const short oflag_face)
{
Heap *eheap; /* edge heap */
HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */
diff --git a/source/blender/bmesh/tools/bmesh_beautify.h b/source/blender/bmesh/tools/bmesh_beautify.h
index 7cc17008b50..0d6aa23b81d 100644
--- a/source/blender/bmesh/tools/bmesh_beautify.h
+++ b/source/blender/bmesh/tools/bmesh_beautify.h
@@ -31,12 +31,14 @@ enum {
VERT_RESTRICT_TAG = (1 << 0),
};
-void BM_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_len,
- const short flag, const short method,
- const short oflag_edge, const short oflag_face);
+void BM_mesh_beautify_fill(
+ BMesh *bm, BMEdge **edge_array, const int edge_array_len,
+ const short flag, const short method,
+ const short oflag_edge, const short oflag_face);
-float BM_verts_calc_rotate_beauty(const BMVert *v1, const BMVert *v2,
- const BMVert *v3, const BMVert *v4,
- const short flag, const short method);
+float BM_verts_calc_rotate_beauty(
+ const BMVert *v1, const BMVert *v2,
+ const BMVert *v3, const BMVert *v4,
+ const short flag, const short method);
#endif /* __BMESH_BEAUTIFY_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 34317866b39..2ef93618e2a 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -525,23 +525,28 @@ static void bev_merge_uvs(BMesh *bm, BMVert *v)
BMLoop *l;
float uv[2];
int n;
- int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ int num_of_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
+ int i;
- if (cd_loop_uv_offset == -1)
- return;
+ for (i = 0; i < num_of_uv_layers; i++) {
+ int cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, i);
- n = 0;
- zero_v2(uv);
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- add_v2_v2(uv, luv->uv);
- n++;
- }
- if (n > 1) {
- mul_v2_fl(uv, 1.0f / (float)n);
+ if (cd_loop_uv_offset == -1)
+ return;
+
+ n = 0;
+ zero_v2(uv);
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- copy_v2_v2(luv->uv, uv);
+ add_v2_v2(uv, luv->uv);
+ n++;
+ }
+ if (n > 1) {
+ mul_v2_fl(uv, 1.0f / (float)n);
+ BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ copy_v2_v2(luv->uv, uv);
+ }
}
}
}
@@ -787,7 +792,7 @@ static void offset_on_edge_between(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2,
* be on emid if that does a better job of keeping offsets at the user spec.
* Viewed from the vertex normal side, the CCW order of the edges is e1, emid, e2.
* The offset lines may not meet exactly: the lines may be angled so that they can't meet.
- * In that case, pick the the offset_on_edge_between. */
+ * In that case, pick the offset_on_edge_between. */
static void offset_in_two_planes(BevelParams *bp, EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid,
BMVert *v, float meetco[3])
{
@@ -1387,7 +1392,7 @@ static void set_bound_vert_seams(BevVert *bv)
}
/* Make a circular list of BoundVerts for bv, each of which has the coordinates
- * of a vertex on the the boundary of the beveled vertex bv->v.
+ * of a vertex on the boundary of the beveled vertex bv->v.
* This may adjust some EdgeHalf widths, and there might have to be
* a subsequent pass to make the widths as consistent as possible.
* The first time through, construct will be true and we are making the BoundVerts
@@ -1474,7 +1479,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
return;
}
- lastd = bp->vertex_only ? bv->offset : e->offset_l;
+ lastd = e->offset_l;
do {
if (e->is_bev) {
/* handle only left side of beveled edge e here: next iteration should do right side */
@@ -1557,9 +1562,10 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
/* None of e->prev, e, e->next are beveled.
* could either leave alone or add slide points to make
* one polygon around bv->v. For now, we choose latter.
+ * For vertex bevel, we use e->offset_l as slide distance.
* Could slide to make an even bevel plane but for now will
* just use last distance a meet point moved from bv->v. */
- slide_dist(e, bv->v, lastd, co);
+ slide_dist(e, bv->v, bp->vertex_only ? e->offset_l : lastd, co);
if (construct) {
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = v->elast = e;
@@ -2229,7 +2235,6 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp)
BoundVert *bndv;
int i, j, k, ns2;
float co[3], coc[3];
- float w;
if (r == PRO_SQUARE_R)
return make_cube_corner_straight(mem_arena, nseg);
@@ -2262,10 +2267,8 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp)
bndv = bndv->next;
}
/* center vertex */
- w = (float)(1.0 / M_SQRT3);
- co[0] = w;
- co[1] = w;
- co[2] = w;
+ copy_v3_fl(co, M_SQRT1_3);
+
if (nseg > 2) {
if (r > 1.5f)
mul_v3_fl(co, 1.4f);
@@ -2712,23 +2715,60 @@ static void bevel_build_quadstrip(BevelParams *bp, BMesh *bm, BevVert *bv)
}
}
-/* Special case: there is no vmesh pattern because this has only two boundary verts,
- * and there are no faces in the original mesh at the original vertex.
- * Since there will be no rebuilt face to make the edge between the boundary verts,
+/* Special case: vertex bevel with only two boundary verts.
+ * Want to make a curved edge if seg > 0.
+ * If there are no faces in the original mesh at the original vertex,
+ * there will be no rebuilt face to make the edge between the boundary verts,
* we have to make it here. */
-static void bevel_build_one_wire(BMesh *bm, BevVert *bv)
+static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv)
{
VMesh *vm = bv->vmesh;
BMVert *v1, *v2;
BMEdge *e_eg;
+ Profile *pro;
+ float co[3];
+ BoundVert *bndv;
+ int ns, k;
- BLI_assert(vm->count == 2);
+ BLI_assert(vm->count == 2 && bp->vertex_only);
v1 = mesh_vert(vm, 0, 0, 0)->v;
v2 = mesh_vert(vm, 1, 0, 0)->v;
- e_eg = bv->edges[0].e;
- BLI_assert(v1 != NULL && v2 != NULL && e_eg != NULL);
- BM_edge_create(bm, v1, v2, e_eg, BM_CREATE_NO_DOUBLE);
+
+ ns = vm->seg;
+ if (ns > 1) {
+ /* Set up profile parameters */
+ bndv = vm->boundstart;
+ pro = &bndv->profile;
+ pro->super_r = bp->pro_super_r;
+ copy_v3_v3(pro->coa, v1->co);
+ copy_v3_v3(pro->cob, v2->co);
+ copy_v3_v3(pro->midco, bv->v->co);
+ /* don't use projection */
+ zero_v3(pro->plane_co);
+ zero_v3(pro->plane_no);
+ zero_v3(pro->proj_dir);
+ calculate_profile(bp, bndv);
+ for (k = 1; k < ns; k++) {
+ get_profile_point(bp, pro, k, ns, co);
+ copy_v3_v3(mesh_vert(vm, 0, 0, k)->co, co);
+ create_mesh_bmvert(bm, vm, 0, 0, k, bv->v);
+ }
+ copy_v3_v3(mesh_vert(vm, 0, 0, ns)->co, v2->co);
+ for (k = 1; k < ns; k++)
+ copy_mesh_vert(vm, 1, 0, ns - k, 0, 0, k);
+ }
+
+ if (BM_vert_face_count(bv->v) == 0) {
+ e_eg = bv->edges[0].e;
+ BLI_assert(e_eg != NULL);
+ for (k = 0; k < ns; k++) {
+ v1 = mesh_vert(vm, 0, 0, k)->v;
+ v2 = mesh_vert(vm, 0, 0, k + 1)->v;
+ BLI_assert(v1 != NULL && v2 != NULL);
+ BM_edge_create(bm, v1, v2, e_eg, BM_CREATE_NO_DOUBLE);
+ }
+ }
}
/* Given that the boundary is built, now make the actual BMVerts
@@ -2814,8 +2854,8 @@ static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
switch (vm->mesh_kind) {
case M_NONE:
- if (n == 2 && BM_vert_face_count(bv->v) == 0)
- bevel_build_one_wire(bm, bv);
+ if (n == 2 && bp->vertex_only)
+ bevel_vert_two_edges(bp, bm, bv);
break;
case M_POLY:
bevel_build_poly(bp, bm, bv);
@@ -2898,8 +2938,9 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
nwire++;
/* If edge beveling, exclude wire edges from edges array.
* Mark this edge as "chosen" so loop below won't choose it. */
- if (!bp->vertex_only)
+ if (!bp->vertex_only) {
BM_BEVEL_EDGE_TAG_ENABLE(bme);
+ }
}
}
if (!first_bme)
@@ -3081,6 +3122,18 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
e->offset_r_spec *= weight;
}
}
+ else if (bp->vertex_only) {
+ /* Weight has already been applied to bv->offset, if present.
+ * Transfer to e->offset_[lr]_spec and treat percent as special case */
+ if (bp->offset_type == BEVEL_AMT_PERCENT) {
+ v2 = BM_edge_other_vert(e->e, bv->v);
+ e->offset_l_spec = BM_edge_calc_length(e->e) * bv->offset / 100.0f;
+ }
+ else {
+ e->offset_l_spec = bv->offset;
+ }
+ e->offset_r_spec = e->offset_l_spec;
+ }
else {
e->offset_l_spec = e->offset_r_spec = 0.0f;
}
@@ -3159,7 +3212,7 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
BLI_array_append(vv_fix, bmv);
}
}
- else if (vm->mesh_kind == M_ADJ && vm->seg > 1 && !e->is_bev && !eprev->is_bev) {
+ else if ((vm->mesh_kind == M_ADJ || bp->vertex_only) && vm->seg > 1 && !e->is_bev && !eprev->is_bev) {
BLI_assert(v->prev == vend);
i = vend->index;
for (k = vm->seg - 1; k > 0; k--) {
diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c
index 463304f27f7..e6e33c905da 100644
--- a/source/blender/bmesh/tools/bmesh_bisect_plane.c
+++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c
@@ -112,7 +112,7 @@ static int bm_vert_sortval_cb(const void *v_a_v, const void *v_b_v)
static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], const short oflag_center)
{
- /* unlikely more then 2 verts are needed */
+ /* unlikely more than 2 verts are needed */
const unsigned int f_len_orig = (unsigned int)f->len;
BMVert **vert_split_arr = BLI_array_alloca(vert_split_arr, f_len_orig);
STACK_DECLARE(vert_split_arr);
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index ef1783cc693..811a144fc39 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -519,13 +519,17 @@ static void bm_edge_collapse_loop_customdata(BMesh *bm, BMLoop *l, BMVert *v_cle
if (CustomData_layer_has_math(&bm->ldata, i)) {
const int offset = bm->ldata.layers[i].offset;
const int type = bm->ldata.layers[i].type;
- void *cd_src[2] = {(char *)src[0] + offset,
- (char *)src[1] + offset};
- void *cd_iter = (char *)l_iter->head.data + offset;
+ const void *cd_src[2] = {
+ POINTER_OFFSET(src[0], offset),
+ POINTER_OFFSET(src[1], offset),
+ };
+ void *cd_iter = POINTER_OFFSET(l_iter->head.data, offset);
/* detect seams */
if (CustomData_data_equals(type, cd_src[0], cd_iter)) {
- CustomData_bmesh_interp_n(&bm->ldata, cd_src, w, NULL, 2, l_iter->head.data, i);
+ CustomData_bmesh_interp_n(
+ &bm->ldata, cd_src, w, NULL, ARRAY_SIZE(cd_src),
+ POINTER_OFFSET(l_iter->head.data, offset), i);
#ifdef USE_SEAM
is_seam = false;
#endif
@@ -719,6 +723,7 @@ static bool bm_edge_collapse(BMesh *bm, BMEdge *e_clear, BMVert *v_clear, int r_
BLI_assert(ok == true);
BLI_assert(l_a->f->len == 3);
BLI_assert(l_b->f->len == 3);
+ UNUSED_VARS_NDEBUG(ok);
/* keep 'v_clear' 0th */
if (BM_vert_in_edge(l_a->prev->e, v_clear)) {
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index 4d87c3e3551..064dbd7405b 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -45,7 +45,9 @@
#include "BLI_linklist_stack.h"
#include "BLI_stackdefines.h"
-#include "BLI_array.h"
+#ifndef NDEBUG
+# include "BLI_array_utils.h"
+#endif
#include "BLI_kdopbvh.h"
@@ -541,7 +543,7 @@ static void bm_isect_tri_tri(
if (((1 << i_b_e0) | (1 << i_b_e1)) & b_mask)
continue;
fac = line_point_factor_v3(fv_a[i_a]->co, fv_b[i_b_e0]->co, fv_b[i_b_e1]->co);
- if ((fac > 0.0f - s->epsilon.eps) && (fac < 1.0 + s->epsilon.eps)) {
+ if ((fac > 0.0f - s->epsilon.eps) && (fac < 1.0f + s->epsilon.eps)) {
float ix[3];
interp_v3_v3v3(ix, fv_b[i_b_e0]->co, fv_b[i_b_e1]->co, fac);
if (len_squared_v3v3(ix, fv_a[i_a]->co) <= s->epsilon.eps2x_sq) {
@@ -579,7 +581,7 @@ static void bm_isect_tri_tri(
if (((1 << i_a_e0) | (1 << i_a_e1)) & a_mask)
continue;
fac = line_point_factor_v3(fv_b[i_b]->co, fv_a[i_a_e0]->co, fv_a[i_a_e1]->co);
- if ((fac > 0.0 - s->epsilon.eps) && (fac < 1.0 + s->epsilon.eps)) {
+ if ((fac > 0.0f - s->epsilon.eps) && (fac < 1.0f + s->epsilon.eps)) {
float ix[3];
interp_v3_v3v3(ix, fv_a[i_a_e0]->co, fv_a[i_a_e1]->co, fac);
if (len_squared_v3v3(ix, fv_b[i_b]->co) <= s->epsilon.eps2x_sq) {
@@ -857,7 +859,7 @@ bool BM_mesh_intersect(
{UNPACK3(looptris[i][2]->v->co)},
};
- BLI_bvhtree_insert(tree_a, i, (float *)t_cos, 3);
+ BLI_bvhtree_insert(tree_a, i, (const float *)t_cos, 3);
}
}
BLI_bvhtree_balance(tree_a);
@@ -874,7 +876,7 @@ bool BM_mesh_intersect(
{UNPACK3(looptris[i][2]->v->co)},
};
- BLI_bvhtree_insert(tree_b, i, (float *)t_cos, 3);
+ BLI_bvhtree_insert(tree_b, i, (const float *)t_cos, 3);
}
}
BLI_bvhtree_balance(tree_b);
diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c
index 060d0dd969b..8ae3507a738 100644
--- a/source/blender/bmesh/tools/bmesh_path.c
+++ b/source/blender/bmesh/tools/bmesh_path.c
@@ -95,7 +95,7 @@ static void verttag_add_adjacent(Heap *heap, BMVert *v_a, BMVert **verts_prev, f
LinkNode *BM_mesh_calc_path_vert(
BMesh *bm, BMVert *v_src, BMVert *v_dst, const bool use_length,
- void *user_data, bool (*test_fn)(BMVert *, void *user_data))
+ bool (*test_fn)(BMVert *, void *user_data), void *user_data)
{
LinkNode *path = NULL;
/* BM_ELEM_TAG flag is used to store visited edges */
@@ -221,7 +221,7 @@ static void edgetag_add_adjacent(Heap *heap, BMEdge *e1, BMEdge **edges_prev, fl
LinkNode *BM_mesh_calc_path_edge(
BMesh *bm, BMEdge *e_src, BMEdge *e_dst, const bool use_length,
- void *user_data, bool (*filter_fn)(BMEdge *, void *user_data))
+ bool (*filter_fn)(BMEdge *, void *user_data), void *user_data)
{
LinkNode *path = NULL;
/* BM_ELEM_TAG flag is used to store visited edges */
@@ -347,7 +347,7 @@ static void facetag_add_adjacent(Heap *heap, BMFace *f_a, BMFace **faces_prev, f
LinkNode *BM_mesh_calc_path_face(
BMesh *bm, BMFace *f_src, BMFace *f_dst, const bool use_length,
- void *user_data, bool (*test_fn)(BMFace *, void *user_data))
+ bool (*test_fn)(BMFace *, void *user_data), void *user_data)
{
LinkNode *path = NULL;
/* BM_ELEM_TAG flag is used to store visited edges */
diff --git a/source/blender/bmesh/tools/bmesh_path.h b/source/blender/bmesh/tools/bmesh_path.h
index a13290b875e..c39e08e83ef 100644
--- a/source/blender/bmesh/tools/bmesh_path.h
+++ b/source/blender/bmesh/tools/bmesh_path.h
@@ -29,14 +29,17 @@
struct LinkNode *BM_mesh_calc_path_vert(
BMesh *bm, BMVert *v_src, BMVert *v_dst, const bool use_length,
- void *user_data, bool (*filter_fn)(BMVert *, void *));
+ bool (*filter_fn)(BMVert *, void *), void *user_data)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3, 5);
struct LinkNode *BM_mesh_calc_path_edge(
BMesh *bm, BMEdge *e_src, BMEdge *e_dst, const bool use_length,
- void *user_data, bool (*filter_fn)(BMEdge *, void *));
+ bool (*filter_fn)(BMEdge *, void *), void *user_data)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3, 5);
struct LinkNode *BM_mesh_calc_path_face(
BMesh *bm, BMFace *f_src, BMFace *f_dst, const bool use_length,
- void *user_data, bool (*test_fn)(BMFace *, void *));
+ bool (*test_fn)(BMFace *, void *), void *user_data)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3, 5);
#endif /* __BMESH_PATH_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c
index 050d5ae4808..bb7000e5534 100644
--- a/source/blender/bmesh/tools/bmesh_region_match.c
+++ b/source/blender/bmesh/tools/bmesh_region_match.c
@@ -656,7 +656,7 @@ static bool bm_uuidwalk_facestep_begin(
bool ok = false;
BLI_assert(BLI_ghash_size(uuidwalk->cache.faces_from_uuid) == 0);
- BLI_assert(BLI_countlist(&fstep->items) == 0);
+ BLI_assert(BLI_listbase_is_empty(&fstep->items));
f_link_prev_p = &fstep->faces;
for (f_link = fstep->faces; f_link; f_link = f_link_next) {
@@ -695,7 +695,7 @@ static bool bm_uuidwalk_facestep_begin(
BLI_ghash_clear(uuidwalk->cache.faces_from_uuid, NULL, NULL);
- BLI_sortlist(&fstep->items, facestep_sort);
+ BLI_listbase_sort(&fstep->items, facestep_sort);
return ok;
}
@@ -781,7 +781,7 @@ static BMFace **bm_mesh_region_match_pair(
UUIDFaceStep *fstep_src = w_src->faces_step.first;
UUIDFaceStep *fstep_dst = w_dst->faces_step.first;
- BLI_assert(BLI_countlist(&w_src->faces_step) == BLI_countlist(&w_dst->faces_step));
+ BLI_assert(BLI_listbase_count(&w_src->faces_step) == BLI_listbase_count(&w_dst->faces_step));
while (fstep_src) {
@@ -874,7 +874,7 @@ static BMFace **bm_mesh_region_match_pair(
const unsigned int faces_result_len = (unsigned int)BLI_ghash_size(w_dst->faces_uuid);
unsigned int i;
- faces_result = MEM_mallocN(sizeof(faces_result) * (faces_result_len + 1), __func__);
+ faces_result = MEM_mallocN(sizeof(*faces_result) * (faces_result_len + 1), __func__);
GHASH_ITER_INDEX (gh_iter, w_dst->faces_uuid, i) {
BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
faces_result[i] = f;
diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c
index 446c03a543f..404776a0769 100644
--- a/source/blender/bmesh/tools/bmesh_triangulate.c
+++ b/source/blender/bmesh/tools/bmesh_triangulate.c
@@ -27,13 +27,20 @@
*
*/
+#include "DNA_modifier_types.h" /* for MOD_TRIANGULATE_NGON_BEAUTY only */
+
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_alloca.h"
#include "BLI_memarena.h"
#include "BLI_listbase.h"
-#include "BLI_scanfill.h"
+#include "BLI_heap.h"
+#include "BLI_edgehash.h"
+
+/* only for defines */
+#include "BLI_polyfill2d.h"
+#include "BLI_polyfill2d_beautify.h"
#include "bmesh.h"
@@ -42,16 +49,27 @@
/**
* a version of #BM_face_triangulate that maps to #BMOpSlot
*/
-static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_arena,
- const int quad_method, const int ngon_method,
- const bool use_tag,
- BMOperator *op, BMOpSlot *slot_facemap_out)
+static void bm_face_triangulate_mapping(
+ BMesh *bm, BMFace *face,
+ const int quad_method, const int ngon_method,
+ const bool use_tag,
+ BMOperator *op, BMOpSlot *slot_facemap_out,
+
+ MemArena *pf_arena,
+ /* use for MOD_TRIANGULATE_NGON_BEAUTY only! */
+ struct Heap *pf_heap, struct EdgeHash *pf_ehash)
{
int faces_array_tot = face->len - 3;
BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot);
BLI_assert(face->len > 3);
- BM_face_triangulate(bm, face, faces_array, &faces_array_tot, sf_arena, quad_method, ngon_method, use_tag);
+ BM_face_triangulate(
+ bm, face,
+ faces_array, &faces_array_tot,
+ NULL, NULL,
+ quad_method, ngon_method, use_tag,
+ pf_arena,
+ pf_heap, pf_ehash);
if (faces_array_tot) {
int i;
@@ -63,22 +81,39 @@ static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, MemArena *sf_ar
}
-void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only,
- BMOperator *op, BMOpSlot *slot_facemap_out)
+void BM_mesh_triangulate(
+ BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only,
+ BMOperator *op, BMOpSlot *slot_facemap_out)
{
BMIter iter;
BMFace *face;
- MemArena *sf_arena;
+ MemArena *pf_arena;
+ Heap *pf_heap;
+ EdgeHash *pf_ehash;
- sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__);
+ pf_arena = BLI_memarena_new(BLI_POLYFILL_ARENA_SIZE, __func__);
+
+ if (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY) {
+ pf_heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE);
+ pf_ehash = BLI_edgehash_new_ex(__func__, BLI_POLYFILL_ALLOC_NGON_RESERVE);
+ }
+ else {
+ pf_heap = NULL;
+ pf_ehash = NULL;
+ }
if (slot_facemap_out) {
/* same as below but call: bm_face_triangulate_mapping() */
BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
if (face->len > 3) {
if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) {
- bm_face_triangulate_mapping(bm, face, sf_arena, quad_method, ngon_method, tag_only,
- op, slot_facemap_out);
+ bm_face_triangulate_mapping(
+ bm, face, quad_method,
+ ngon_method, tag_only,
+ op, slot_facemap_out,
+
+ pf_arena,
+ pf_heap, pf_ehash);
}
}
}
@@ -87,11 +122,22 @@ void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method
BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
if (face->len > 3) {
if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) {
- BM_face_triangulate(bm, face, NULL, NULL, sf_arena, quad_method, ngon_method, tag_only);
+ BM_face_triangulate(
+ bm, face,
+ NULL, NULL,
+ NULL, NULL,
+ quad_method, ngon_method, tag_only,
+ pf_arena,
+ pf_heap, pf_ehash);
}
}
}
}
- BLI_memarena_free(sf_arena);
+ BLI_memarena_free(pf_arena);
+
+ if (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY) {
+ BLI_heap_free(pf_heap, NULL);
+ BLI_edgehash_free(pf_ehash, NULL);
+ }
}
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index f2c057d32d8..de4e29a7d48 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -24,8 +24,6 @@
#include "AnimationExporter.h"
#include "MaterialExporter.h"
-Global G;
-
template<class Functor>
void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
{
@@ -76,9 +74,9 @@ void AnimationExporter::operator()(Object *ob)
else
transformName = extract_transform_name(fcu->rna_path);
- if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) ||
- (!strcmp(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL) ||
- (!strcmp(transformName, "rotation_quaternion")))
+ if ((STREQ(transformName, "location") || STREQ(transformName, "scale")) ||
+ (STREQ(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL) ||
+ (STREQ(transformName, "rotation_quaternion")))
{
dae_animation(ob, fcu, transformName, false);
}
@@ -98,8 +96,8 @@ void AnimationExporter::operator()(Object *ob)
while (fcu) {
transformName = extract_transform_name(fcu->rna_path);
- if ((!strcmp(transformName, "color")) || (!strcmp(transformName, "spot_size")) ||
- (!strcmp(transformName, "spot_blend")) || (!strcmp(transformName, "distance")))
+ if ((STREQ(transformName, "color")) || (STREQ(transformName, "spot_size")) ||
+ (STREQ(transformName, "spot_blend")) || (STREQ(transformName, "distance")))
{
dae_animation(ob, fcu, transformName, true);
}
@@ -113,10 +111,10 @@ void AnimationExporter::operator()(Object *ob)
while (fcu) {
transformName = extract_transform_name(fcu->rna_path);
- if ((!strcmp(transformName, "lens")) ||
- (!strcmp(transformName, "ortho_scale")) ||
- (!strcmp(transformName, "clip_end")) ||
- (!strcmp(transformName, "clip_start")))
+ if ((STREQ(transformName, "lens")) ||
+ (STREQ(transformName, "ortho_scale")) ||
+ (STREQ(transformName, "clip_end")) ||
+ (STREQ(transformName, "clip_start")))
{
dae_animation(ob, fcu, transformName, true);
}
@@ -134,9 +132,9 @@ void AnimationExporter::operator()(Object *ob)
while (fcu) {
transformName = extract_transform_name(fcu->rna_path);
- if ((!strcmp(transformName, "specular_hardness")) || (!strcmp(transformName, "specular_color")) ||
- (!strcmp(transformName, "diffuse_color")) || (!strcmp(transformName, "alpha")) ||
- (!strcmp(transformName, "ior")))
+ if ((STREQ(transformName, "specular_hardness")) || (STREQ(transformName, "specular_color")) ||
+ (STREQ(transformName, "diffuse_color")) || (STREQ(transformName, "alpha")) ||
+ (STREQ(transformName, "ior")))
{
dae_animation(ob, fcu, transformName, true, ma);
}
@@ -225,7 +223,7 @@ float *AnimationExporter::get_eul_source_for_quat(Object *ob)
while (fcu) {
char *transformName = extract_transform_name(fcu->rna_path);
- if (!strcmp(transformName, "rotation_quaternion") ) {
+ if (STREQ(transformName, "rotation_quaternion") ) {
for (int i = 0; i < fcu->totvert; i++) {
*(quat + (i * 4) + fcu->array_index) = fcu->bezt[i].vec[1][1];
}
@@ -278,17 +276,17 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
bool has_tangents = false;
bool quatRotation = false;
- if (!strcmp(transformName, "rotation_quaternion") ) {
+ if (STREQ(transformName, "rotation_quaternion") ) {
fprintf(stderr, "quaternion rotation curves are not supported. rotation curve will not be exported\n");
quatRotation = true;
return;
}
//axis names for colors
- else if (!strcmp(transformName, "color") ||
- !strcmp(transformName, "specular_color") ||
- !strcmp(transformName, "diffuse_color") ||
- !strcmp(transformName, "alpha"))
+ else if (STREQ(transformName, "color") ||
+ STREQ(transformName, "specular_color") ||
+ STREQ(transformName, "diffuse_color") ||
+ STREQ(transformName, "alpha"))
{
const char *axis_names[] = {"R", "G", "B"};
if (fcu->array_index < 3)
@@ -296,10 +294,10 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
}
//axis names for transforms
- else if (!strcmp(transformName, "location") ||
- !strcmp(transformName, "scale") ||
- !strcmp(transformName, "rotation_euler") ||
- !strcmp(transformName, "rotation_quaternion"))
+ else if (STREQ(transformName, "location") ||
+ STREQ(transformName, "scale") ||
+ STREQ(transformName, "rotation_euler") ||
+ STREQ(transformName, "rotation_quaternion"))
{
const char *axis_names[] = {"X", "Y", "Z"};
if (fcu->array_index < 3)
@@ -357,7 +355,7 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
MEM_freeN(eul);
MEM_freeN(eul_axis);
}
- else if (!strcmp(transformName, "lens") && (ob->type == OB_CAMERA)) {
+ else if (STREQ(transformName, "lens") && (ob->type == OB_CAMERA)) {
output_id = create_lens_source_from_fcurve((Camera *) ob->data, COLLADASW::InputSemantic::OUTPUT, fcu, anim_id);
}
else {
@@ -763,7 +761,7 @@ std::string AnimationExporter::create_source_from_fcurve(COLLADASW::InputSemanti
{
std::string source_id = anim_id + get_semantic_suffix(semantic);
- //bool is_angle = !strcmp(fcu->rna_path, "rotation");
+ //bool is_angle = STREQ(fcu->rna_path, "rotation");
bool is_angle = false;
if (strstr(fcu->rna_path, "rotation") || strstr(fcu->rna_path,"spot_size")) is_angle = true;
@@ -1103,13 +1101,13 @@ std::string AnimationExporter::get_light_param_sid(char *rna_path, int tm_type,
if (rna_path) {
char *name = extract_transform_name(rna_path);
- if (!strcmp(name, "color"))
+ if (STREQ(name, "color"))
tm_type = 1;
- else if (!strcmp(name, "spot_size"))
+ else if (STREQ(name, "spot_size"))
tm_type = 2;
- else if (!strcmp(name, "spot_blend"))
+ else if (STREQ(name, "spot_blend"))
tm_type = 3;
- else if (!strcmp(name, "distance"))
+ else if (STREQ(name, "distance"))
tm_type = 4;
else
tm_type = -1;
@@ -1151,13 +1149,13 @@ std::string AnimationExporter::get_camera_param_sid(char *rna_path, int tm_type,
if (rna_path) {
char *name = extract_transform_name(rna_path);
- if (!strcmp(name, "lens"))
+ if (STREQ(name, "lens"))
tm_type = 0;
- else if (!strcmp(name, "ortho_scale"))
+ else if (STREQ(name, "ortho_scale"))
tm_type = 1;
- else if (!strcmp(name, "clip_end"))
+ else if (STREQ(name, "clip_end"))
tm_type = 2;
- else if (!strcmp(name, "clip_start"))
+ else if (STREQ(name, "clip_start"))
tm_type = 3;
else
@@ -1203,23 +1201,23 @@ std::string AnimationExporter::get_transform_sid(char *rna_path, int tm_type, co
if (rna_path) {
char *name = extract_transform_name(rna_path);
- if (!strcmp(name, "rotation_euler"))
+ if (STREQ(name, "rotation_euler"))
tm_type = 0;
- else if (!strcmp(name, "rotation_quaternion"))
+ else if (STREQ(name, "rotation_quaternion"))
tm_type = 1;
- else if (!strcmp(name, "scale"))
+ else if (STREQ(name, "scale"))
tm_type = 2;
- else if (!strcmp(name, "location"))
+ else if (STREQ(name, "location"))
tm_type = 3;
- else if (!strcmp(name, "specular_hardness"))
+ else if (STREQ(name, "specular_hardness"))
tm_type = 4;
- else if (!strcmp(name, "specular_color"))
+ else if (STREQ(name, "specular_color"))
tm_type = 5;
- else if (!strcmp(name, "diffuse_color"))
+ else if (STREQ(name, "diffuse_color"))
tm_type = 6;
- else if (!strcmp(name, "alpha"))
+ else if (STREQ(name, "alpha"))
tm_type = 7;
- else if (!strcmp(name, "ior"))
+ else if (STREQ(name, "ior"))
tm_type = 8;
else
@@ -1311,7 +1309,7 @@ void AnimationExporter::enable_fcurves(bAction *act, char *bone_name)
for (fcu = (FCurve *)act->curves.first; fcu; fcu = fcu->next) {
if (bone_name) {
- if (!strncmp(fcu->rna_path, prefix, strlen(prefix)))
+ if (STREQLEN(fcu->rna_path, prefix, strlen(prefix)))
fcu->flag &= ~FCURVE_DISABLED;
else
fcu->flag |= FCURVE_DISABLED;
@@ -1378,11 +1376,11 @@ void AnimationExporter::find_frames(Object *ob, std::vector<float> &fra, const c
FCurve *fcu = (FCurve *)ob->adt->action->curves.first;
for (; fcu; fcu = fcu->next) {
- if (prefix && strncmp(prefix, fcu->rna_path, strlen(prefix)))
+ if (prefix && !STREQLEN(prefix, fcu->rna_path, strlen(prefix)))
continue;
char *name = extract_transform_name(fcu->rna_path);
- if (!strcmp(name, tm_name)) {
+ if (STREQ(name, tm_name)) {
for (unsigned 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())
diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h
index 5e7338aef61..6f675ed6a39 100644
--- a/source/blender/collada/AnimationExporter.h
+++ b/source/blender/collada/AnimationExporter.h
@@ -51,7 +51,6 @@ extern "C"
#include "BKE_object.h"
#include "BKE_constraint.h"
#include "BIK_api.h"
-#include "BKE_global.h"
#include "ED_object.h"
}
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index 6e2d337a32e..7e937e42787 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -649,7 +649,7 @@ void AnimationImporter:: Assign_float_animations(const COLLADAFW::UniqueId& list
for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
FCurve *fcu = *iter;
/* All anim_types whose values are to be converted from Degree to Radians can be ORed here */
- if (strcmp("spot_size", anim_type)==0) {
+ if (STREQ("spot_size", anim_type)) {
/* NOTE: Do NOT convert if imported file was made by blender <= 2.69.10
* Reason: old blender versions stored spot_size in radians (was a bug)
*/
diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp
index 2e92cd9c147..36ab85b9b5b 100644
--- a/source/blender/collada/ArmatureExporter.cpp
+++ b/source/blender/collada/ArmatureExporter.cpp
@@ -168,7 +168,7 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce,
node.setNodeSid(node_sid);
#if 0
- if (BLI_listbase_is_empty(&bone->childbase) || BLI_countlist(&(bone->childbase)) >= 2) {
+ if (BLI_listbase_is_empty(&bone->childbase) || BLI_listbase_count_ex(&bone->childbase, 2) == 2) {
add_blender_leaf_bone( bone, ob_arm, node);
}
else {
@@ -181,7 +181,7 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce,
std::list<Object *>::iterator i = child_objects.begin();
while (i != child_objects.end()) {
- if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) {
+ if ((*i)->partype == PARBONE && STREQ((*i)->parsubstr, bone->name)) {
float backup_parinv[4][4];
copy_m4_m4(backup_parinv, (*i)->parentinv);
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index e2c36df564a..c2ee6170470 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -37,6 +37,7 @@
#include "BKE_object.h"
#include "BKE_armature.h"
#include "BLI_string.h"
+#include "BLI_listbase.h"
#include "ED_armature.h"
#include "ArmatureImporter.h"
@@ -49,7 +50,22 @@ static const char *bc_get_joint_name(T *node)
return id.size() ? id.c_str() : node->getOriginalId().c_str();
}
-ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce) :
+static EditBone *get_edit_bone(bArmature * armature, char *name) {
+ EditBone *eBone;
+
+ for (eBone = (EditBone *)armature->edbo->first; eBone; eBone = eBone->next) {
+ if (STREQ(name, eBone->name))
+ return eBone;
+ }
+
+ return NULL;
+
+}
+
+
+
+ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce, const ImportSettings *import_settings) :
+ import_settings(import_settings),
unit_converter(conv),
TransformReader(conv),
scene(sce),
@@ -57,6 +73,15 @@ ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh,
mesh_importer(mesh) {
}
+void ArmatureImporter::clear_extended_boneset()
+{
+ for (std::map<std::string, BoneExtended *>::iterator it = extended_bones.begin(); it != extended_bones.end(); ++it) {
+ if (it->second != NULL)
+ delete it->second;
+ }
+ extended_bones.clear();
+}
+
ArmatureImporter::~ArmatureImporter()
{
// free skin controller data if we forget to do this earlier
@@ -64,6 +89,7 @@ ArmatureImporter::~ArmatureImporter()
for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
it->second.free();
}
+ clear_extended_boneset();
}
#if 0
@@ -83,16 +109,17 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node);
}
#endif
-void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
+int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[4][4], bArmature *arm)
{
float mat[4][4];
float joint_inv_bind_mat[4][4];
+ int chain_length = 0;
//Checking if bone is already made.
std::vector<COLLADAFW::Node *>::iterator it;
it = std::find(finished_joints.begin(), finished_joints.end(), node);
- if (it != finished_joints.end()) return;
+ if (it != finished_joints.end()) return chain_length;
// JointData* jd = get_joint_data(node);
@@ -143,96 +170,156 @@ void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBo
// set tail, don't set it to head because 0-length bones are not allowed
add_v3_v3v3(bone->tail, bone->head, vec);
- // set parent tail
+ /* find smallest bone length in armature (used later for leaf bone length) */
if (parent) {
- // XXX increase this to prevent "very" small bones?
- const float epsilon = 0.000001f;
-
- // derive leaf bone length
+ /* guess reasonable leaf bone length */
float length = len_v3v3(parent->head, bone->head);
- if ((length < leaf_bone_length || totbone == 0) && length > epsilon) {
+ if ((length < leaf_bone_length || totbone == 0) && length > MINIMUM_BONE_LENGTH) {
leaf_bone_length = length;
}
-
- if (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;
-
-
- // treat zero-sized bone like a leaf bone
- if (length <= epsilon) {
- add_leaf_bone(parent_mat, parent, node);
- }
- }
-
}
COLLADAFW::NodePointerArray& children = node->getChildNodes();
+
+ BoneExtended &be = add_bone_extended(bone, node);
+ be.set_leaf_bone(true);
+
for (unsigned int i = 0; i < children.getCount(); i++) {
- create_bone(skin, children[i], bone, children.getCount(), mat, arm);
+ int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm);
+ if (cl > chain_length)
+ chain_length = cl;
}
- // in second case it's not a leaf bone, but we handle it the same way
- if (!children.getCount() || children.getCount() > 1) {
- add_leaf_bone(mat, bone, node);
- }
bone->length = len_v3v3(bone->head, bone->tail);
joint_by_uid[node->getUniqueId()] = node;
finished_joints.push_back(node);
+
+ be.set_chain_length(chain_length + 1);
+
+ return chain_length + 1;
}
-void ArmatureImporter::add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node *node)
+/**
+ * Collada only knows Joints, hence bones at the end of a bone chain
+ * don't have a defined length. This function guesses reasonable
+ * tail locations for the affected bones (nodes which don't have any connected child)
+ * Hint: The extended_bones set gets populated in ArmatureImporter::create_bone
+**/
+void ArmatureImporter::fix_leaf_bones(bArmature *armature, Bone *bone)
{
- LeafBone leaf;
+ /* armature has no bones */
+ if (bone == NULL)
+ return;
- leaf.bone = bone;
- copy_m4_m4(leaf.mat, mat);
- BLI_strncpy(leaf.name, bone->name, sizeof(leaf.name));
-
- TagsMap::iterator etit;
- ExtraTags *et = 0;
- etit = uid_tags_map.find(node->getUniqueId().toAscii());
- if (etit != uid_tags_map.end()) {
- et = etit->second;
- //else return;
+ BoneExtended *be = extended_bones[bone->name];
+ if (be != NULL && be->is_leaf_bone() ) {
+ /* Collada only knows Joints, Here we guess a reasonable leaf bone length */
+ float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0 : leaf_bone_length;
+
+ EditBone *ebone = get_edit_bone(armature, bone->name);
+ float vec[3];
+
+ if (this->import_settings->fix_orientation) {
+ if (ebone->parent != NULL) {
+ EditBone *parent = ebone->parent;
+ sub_v3_v3v3(vec, ebone->head, parent->tail);
+ if (len_squared_v3(vec) < MINIMUM_BONE_LENGTH)
+ {
+ sub_v3_v3v3(vec, parent->tail, parent->head);
+ }
+ }
+ else {
+ vec[2] = 0.1f;
+ sub_v3_v3v3(vec, ebone->tail, ebone->head);
+ }
+ }
+ else {
+ sub_v3_v3v3(vec, ebone->tail, ebone->head);
+ }
- float x, y, z;
- et->setData("tip_x", &x);
- et->setData("tip_y", &y);
- et->setData("tip_z", &z);
- float vec[3] = {x, y, z};
- copy_v3_v3(leaf.bone->tail, leaf.bone->head);
- add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
- }
- else {
- leaf_bones.push_back(leaf);
+ normalize_v3_v3(vec, vec);
+ mul_v3_fl(vec, leaf_length);
+ add_v3_v3v3(ebone->tail, ebone->head, vec);
}
-}
-void ArmatureImporter::fix_leaf_bones( )
-{
- // Collada only knows Joints, Here we guess a reasonable
- // leaf bone length
- float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0:leaf_bone_length;
+ for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
+ fix_leaf_bones(armature, child);
+ }
- // just setting tail for leaf bones here
- std::vector<LeafBone>::iterator it;
- for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
+}
- LeafBone& leaf = *it;
- // pointing up
- float vec[3] = {0.0f, 0.0f, 0.1f};
-
- sub_v3_v3v3(vec, leaf.bone->tail , leaf.bone->head);
- mul_v3_fl(vec, leaf_length);
- add_v3_v3v3(leaf.bone->tail, leaf.bone->head , vec);
+void ArmatureImporter::connect_bone_chains(bArmature *armature, Bone *parentbone, int clip)
+{
+ BoneExtended *dominant_child = NULL;
+ int maxlen = 0;
+ Bone *child = (Bone *)parentbone->childbase.first;
+ if (child && (import_settings->find_chains || child->next==NULL) )
+ {
+ for (; child; child = child->next) {
+ BoneExtended *be = extended_bones[child->name];
+ if (be != NULL) {
+ if (be->get_chain_length() <= clip) {
+ if (be->get_chain_length() > maxlen) {
+ dominant_child = be;
+ maxlen = be->get_chain_length();
+ }
+ else if (be->get_chain_length() == maxlen) {
+ dominant_child = NULL;
+ }
+ }
+ }
+ }
+ }
+ BoneExtended *pbe = extended_bones[parentbone->name];
+ if (dominant_child != NULL) {
+ /* Found a valid chain. Now connect current bone with that chain.*/
+ EditBone *pebone = get_edit_bone(armature, parentbone->name);
+ EditBone *cebone = get_edit_bone(armature, dominant_child->get_name());
+ if (pebone && !(cebone->flag & BONE_CONNECTED)) {
+
+ float vec[3];
+ sub_v3_v3v3(vec, cebone->head, pebone->head);
+
+ /*
+ * It is possible that the child's head is located on the parents head.
+ * When this happens, then moving the parent's tail to the child's head
+ * would result in a zero sized bone and Blender would silently remove the bone.
+ * So we move the tail only when the resulting bone has a minimum length:
+ */
+
+ if (len_squared_v3(vec) > MINIMUM_BONE_LENGTH)
+ {
+ pebone->tail[0] = cebone->head[0];
+ pebone->tail[1] = cebone->head[1];
+ pebone->tail[2] = cebone->head[2];
+
+ if (pbe && pbe->get_chain_length() >= this->import_settings->min_chain_length) {
+ cebone->flag |= BONE_CONNECTED;
+ printf("Connecting chain: parent %s --> %s (child)\n", pebone->name, cebone->name);
+ pbe->set_leaf_bone(false);
+ }
+ }
+ }
+ for (Bone *child = (Bone *)parentbone->childbase.first; child; child = child->next) {
+ ArmatureImporter::connect_bone_chains(armature, child, UNLIMITED_CHAIN_MAX);
+ }
+ }
+ else if (maxlen>1 && maxlen > this->import_settings->min_chain_length) {
+ /* Try again with smaller chain length */
+ ArmatureImporter::connect_bone_chains(armature, parentbone, maxlen - 1);
}
+ else {
+ /* can't connect this Bone. Proceed with children ... */
+ if (pbe) pbe->set_leaf_bone(true);
+ for (Bone *child = (Bone *)parentbone->childbase.first; child; child = child->next) {
+ ArmatureImporter::connect_bone_chains(armature, child, UNLIMITED_CHAIN_MAX);
+ }
+ }
+
}
#if 0
@@ -351,21 +438,26 @@ void ArmatureImporter::create_armature_bones( )
continue;
}
+ clear_extended_boneset();
+
ED_armature_to_edit(armature);
create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature);
- //leaf bone tails are derived from the matrix, so no need of this.
- fix_leaf_bones();
+ /* exit armature edit mode to populate the Armature object */
+ ED_armature_from_edit(armature);
+ ED_armature_edit_free(armature);
+
+ /* and step back to edit mode to fix the leaf nodes */
+ ED_armature_to_edit(armature);
+
+ connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
+ fix_leaf_bones(armature, (Bone *)armature->bonebase.first);
// exit armature edit mode
unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm;
ED_armature_from_edit(armature);
-
- //This serves no purpose, as pose is automatically reset later, in BKE_where_is_bone()
- //set_pose(ob_arm, *ri, NULL, NULL);
-
ED_armature_edit_free(armature);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
}
@@ -459,9 +551,11 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
}
// enter armature edit mode
- ED_armature_to_edit((bArmature *)ob_arm->data);
+ bArmature * armature = (bArmature *)ob_arm->data;
+ ED_armature_to_edit(armature);
+
+ clear_extended_boneset();
- leaf_bones.clear();
totbone = 0;
// bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row
leaf_bone_length = FLT_MAX;
@@ -480,20 +574,27 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
// since root_joints may contain joints for multiple controllers, we need to filter
if (skin.uses_joint_or_descendant(*ri)) {
- create_bone(&skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature *)ob_arm->data);
+ create_bone(&skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, armature);
if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent())
skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]);
}
}
- fix_leaf_bones();
+ /* exit armature edit mode to populate the Armature object */
+ ED_armature_from_edit(armature);
+ ED_armature_edit_free(armature);
+
+ /* and step back to edit mode to fix the leaf nodes */
+ ED_armature_to_edit(armature);
+
+ connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
+ fix_leaf_bones(armature, (Bone *)armature->bonebase.first);
// exit armature edit mode
- ED_armature_from_edit((bArmature *)ob_arm->data);
- ED_armature_edit_free((bArmature *)ob_arm->data);
+ ED_armature_from_edit(armature);
+ ED_armature_edit_free(armature);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
-
}
void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4])
@@ -538,10 +639,11 @@ void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, con
}
-
-// root - if this joint is the top joint in hierarchy, if a joint
-// is a child of a node (not joint), root should be true since
-// this is where we build armature bones from
+/**
+ * root - if this joint is the top joint in hierarchy, if a joint
+ * is a child of a node (not joint), root should be true since
+ * this is where we build armature bones from
+ **/
void ArmatureImporter::add_root_joint(COLLADAFW::Node *node, Object *parent)
{
root_joints.push_back(node);
@@ -702,7 +804,7 @@ void ArmatureImporter::make_shape_keys()
//insert basis key
kb = BKE_keyblock_add_ctime(key, "Basis", false);
- BKE_key_convert_from_mesh(source_me, kb);
+ BKE_keyblock_convert_from_mesh(source_me, kb);
//insert other shape keys
for (int i = 0 ; i < morphTargetIds.getCount() ; i++ ) {
@@ -716,7 +818,7 @@ void ArmatureImporter::make_shape_keys()
std::string morph_name = *this->mesh_importer->get_geometry_name(me->id.name);
kb = BKE_keyblock_add_ctime(key, morph_name.c_str(), false);
- BKE_key_convert_from_mesh(me, kb);
+ BKE_keyblock_convert_from_mesh(me, kb);
//apply weights
weight = morphWeights.getFloatValues()->getData()[i];
@@ -785,3 +887,71 @@ bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint)
return found;
}
+
+
+/**
+ * BoneExtended is a helper class needed for the Bone chain finder
+ * See ArmatureImporter::fix_leaf_bones()
+ * and ArmatureImporter::connect_bone_chains()
+ **/
+
+BoneExtended::BoneExtended(EditBone *aBone)
+{
+ this->set_name(aBone->name);
+ this->chain_length = 0;
+ this->is_leaf = false;
+}
+
+char *BoneExtended::get_name()
+{
+ return name;
+}
+
+void BoneExtended::set_name(char *aName)
+{
+ BLI_strncpy(name, aName, MAXBONENAME);
+}
+
+int BoneExtended::get_chain_length()
+{
+ return chain_length;
+}
+
+void BoneExtended::set_chain_length(const int aLength)
+{
+ chain_length = aLength;
+}
+
+
+void BoneExtended::set_leaf_bone(bool state)
+{
+ is_leaf = state;
+}
+
+bool BoneExtended::is_leaf_bone()
+{
+ return is_leaf;
+}
+
+BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node)
+{
+
+ TagsMap::iterator etit;
+ ExtraTags *et = 0;
+ etit = uid_tags_map.find(node->getUniqueId().toAscii());
+ if (etit != uid_tags_map.end()) {
+ float x, y, z;
+
+ et = etit->second;
+ et->setData("tip_x", &x);
+ et->setData("tip_y", &y);
+ et->setData("tip_z", &z);
+ float vec[3] = { x, y, z };
+ copy_v3_v3(bone->tail, bone->head);
+ add_v3_v3v3(bone->tail, bone->head, vec);
+ }
+
+ BoneExtended *be = new BoneExtended(bone);
+ extended_bones[bone->name] = be;
+ return *be;
+}
diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h
index beeac85cc4d..732fda80ff1 100644
--- a/source/blender/collada/ArmatureImporter.h
+++ b/source/blender/collada/ArmatureImporter.h
@@ -54,23 +54,41 @@ extern "C" {
#include "collada_internal.h"
#include "collada_utils.h"
+#include "ImportSettings.h"
+
+#define UNLIMITED_CHAIN_MAX INT_MAX
+#define MINIMUM_BONE_LENGTH 0.000001f
+
+class BoneExtended {
+
+private:
+ char name[MAXBONENAME];
+ int chain_length;
+ bool is_leaf;
+
+public:
+
+ BoneExtended(EditBone *aBone);
+ char *get_name();
+ int get_chain_length();
+
+ void set_name(char *aName);
+ void set_chain_length(const int aLength);
+ void set_leaf_bone(bool state);
+ bool is_leaf_bone();
+};
class ArmatureImporter : private TransformReader
{
private:
Scene *scene;
UnitConverter *unit_converter;
+ const ImportSettings *import_settings;
// std::map<int, JointData> joint_index_to_joint_info_map;
// std::map<COLLADAFW::UniqueId, int> joint_id_to_joint_index_map;
- struct LeafBone {
- // COLLADAFW::Node *node;
- EditBone *bone;
- char name[32];
- float mat[4][4]; // bone matrix, derived from inv_bind_mat
- };
- std::vector<LeafBone> leaf_bones;
+ std::map<std::string, BoneExtended *> extended_bones;
// int bone_direction_row; // XXX not used
float leaf_bone_length;
int totbone;
@@ -106,13 +124,15 @@ private:
JointData *get_joint_data(COLLADAFW::Node *node);
#endif
- void create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
+ int create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[4][4], bArmature *arm);
- void add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node * node);
+ BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node);
+ void clear_extended_boneset();
+
+ void fix_leaf_bones(bArmature *armature, Bone *bone);
+ void connect_bone_chains(bArmature *armature, Bone *bone, const int max_chain_length);
- void fix_leaf_bones();
-
void set_pose( Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]);
@@ -137,7 +157,7 @@ private:
TagsMap uid_tags_map;
public:
- ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce);
+ ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce, const ImportSettings *import_settings);
~ArmatureImporter();
void add_root_joint(COLLADAFW::Node *node, Object *parent);
diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp
index bc1c4172f46..16c3f68bca4 100644
--- a/source/blender/collada/ControllerExporter.cpp
+++ b/source/blender/collada/ControllerExporter.cpp
@@ -473,7 +473,7 @@ static float get_property(Bone *bone, const char *key, float def)
if (bone->prop) {
IDProperty *property = IDP_GetPropertyFromGroup(bone->prop, key);
if (property) {
- switch(property->type) {
+ switch (property->type) {
case IDP_INT:
result = (float)(IDP_Int(property));
break;
@@ -556,7 +556,7 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, ListBas
COLLADASW::FloatSourceF source(mSW);
source.setId(source_id);
source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(totjoint); //BLI_countlist(defbase));
+ source.setAccessorCount(totjoint); //BLI_listbase_count(defbase));
source.setAccessorStride(16);
source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4);
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 8101e579098..462b7b6f200 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -104,7 +104,7 @@ DocumentImporter::DocumentImporter(bContext *C, const ImportSettings *import_set
import_settings(import_settings),
mImportStage(General),
mContext(C),
- armature_importer(&unit_converter, &mesh_importer, CTX_data_scene(C)),
+ armature_importer(&unit_converter, &mesh_importer, CTX_data_scene(C), import_settings),
mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)),
anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C))
{
@@ -157,9 +157,6 @@ bool DocumentImporter::import()
delete ehandler;
- //XXX No longer needed (geometries are now created as bmesh)
- //mesh_importer.bmeshConversion();
-
return true;
}
diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp
index 3c35618a4cd..13dc1eda580 100644
--- a/source/blender/collada/EffectExporter.cpp
+++ b/source/blender/collada/EffectExporter.cpp
@@ -133,7 +133,7 @@ void EffectsExporter::writeTextures(COLLADASW::EffectProfile &ep,
if (!ima) return;
// color
- if (t->mapto & (MAP_COL | MAP_COLSPEC)) {
+ if (t->mapto & MAP_COL) {
ep.setDiffuse(createTexture(ima, uvname, sampler), false, "diffuse");
}
// ambient
@@ -141,7 +141,7 @@ void EffectsExporter::writeTextures(COLLADASW::EffectProfile &ep,
ep.setAmbient(createTexture(ima, uvname, sampler), false, "ambient");
}
// specular
- if (t->mapto & MAP_SPEC) {
+ if (t->mapto & (MAP_SPEC | MAP_COLSPEC)) {
ep.setSpecular(createTexture(ima, uvname, sampler), false, "specular");
}
// emission
@@ -263,7 +263,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
COLLADASW::Sampler samplers[MAX_MTEX];
//COLLADASW::Surface surfaces[MAX_MTEX];
//void *samp_surf[MAX_MTEX][2];
- void *samp_surf[MAX_MTEX][1];
+ void *samp_surf[MAX_MTEX];
// image to index to samp_surf map
// samp_surf[index] stores 2 pointers, sampler and surface
@@ -302,7 +302,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
//surfaces[a] = surface;
// store pointers so they can be used later when we create <texture>s
- samp_surf[b][0] = &samplers[a];
+ samp_surf[b] = &samplers[a];
//samp_surf[b][1] = &surfaces[a];
im_samp_map[key] = b;
@@ -349,7 +349,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
sampler.setImageId(key);
samplers[a] = sampler;
- samp_surf[b][0] = &samplers[a];
+ samp_surf[b] = &samplers[a];
im_samp_map[key] = b;
b++;
a++;
@@ -380,19 +380,19 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
key = translate_id(key);
int i = im_samp_map[key];
std::string uvname = strlen(t->uvname) ? t->uvname : active_uv;
- COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0];
+ COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i];
writeTextures(ep, key, sampler, t, ima, uvname);
}
std::set<Image *>::iterator uv_t_iter;
int idx;
for (idx = 0, uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++, idx++ ) {
- if(active_uv_layer>-1 && idx==active_uv_layer) {
+ if (active_uv_layer>-1 && idx==active_uv_layer) {
Image *ima = *uv_t_iter;
std::string key(id_name(ima));
key = translate_id(key);
int i = im_samp_map[key];
- COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0];
+ COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i];
ep.setDiffuse(createTexture(ima, active_uv, sampler), false, "diffuse");
}
}
diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp
index 7ac138ac807..b271604f839 100644
--- a/source/blender/collada/ErrorHandler.cpp
+++ b/source/blender/collada/ErrorHandler.cpp
@@ -34,6 +34,8 @@
#include <string.h>
+#include "BLI_utildefines.h"
+
//--------------------------------------------------------------------
ErrorHandler::ErrorHandler() : mError(false)
{
@@ -47,7 +49,7 @@ ErrorHandler::~ErrorHandler()
//--------------------------------------------------------------------
bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
{
- mError = true;
+ bool isError = true;
if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) {
COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *) error;
@@ -55,15 +57,15 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
// Workaround to avoid wrong error
if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED) {
- if (strcmp(parserError.getElement(), "effect") == 0) {
- mError = false;
+ if (STREQ(parserError.getElement(), "effect")) {
+ isError = false;
}
}
if (parserError.getErrorType() == GeneratedSaxParser::ParserError::ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) {
- if (!((strcmp(parserError.getElement(), "extra") == 0) &&
- (strcmp(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract") == 0)))
+ if (!(STREQ(parserError.getElement(), "extra") &&
+ STREQ(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract")))
{
- mError = false;
+ isError = false;
}
}
@@ -75,11 +77,21 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
}
else if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXFWL) {
COLLADASaxFWL::SaxFWLError *saxFWLError = (COLLADASaxFWL::SaxFWLError *) error;
+ /*
+ * Accept non critical errors as warnings (i.e. texture not found)
+ * This makes the importer more gracefull, so it now imports what makes sense.
+ */
+ if (saxFWLError->getSeverity() == COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL) {
+ isError = false;
+ }
+
std::cout << "Sax FWL Error: " << saxFWLError->getErrorMessage() << std::endl;
}
else {
std::cout << "opencollada error: " << error->getFullErrorMessage() << std::endl;
}
- return false;
+ mError |= isError;
+
+ return false; // let OpenCollada decide when to abort
}
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index 1bf245c39e0..28cee05ec4b 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -159,7 +159,7 @@ void GeometryExporter::operator()(Object *ob)
//skip the basis
kb = kb->next;
for (; kb; kb = kb->next) {
- BKE_key_convert_to_mesh(kb, me);
+ BKE_keyblock_convert_to_mesh(kb, me);
export_key_mesh(ob, me, kb);
}
}
diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp
index 55fe2034869..a5c1493208b 100644
--- a/source/blender/collada/ImageExporter.cpp
+++ b/source/blender/collada/ImageExporter.cpp
@@ -67,7 +67,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
return;
}
- bool is_dirty = imbuf->userflags & IB_BITMAPDIRTY;
+ bool is_dirty = (imbuf->userflags & IB_BITMAPDIRTY) != 0;
ImageFormatData imageFormat;
BKE_imbuf_to_image_format(&imageFormat, imbuf);
@@ -89,7 +89,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
// make absolute destination path
BLI_strncpy(export_file, name.c_str(), sizeof(export_file));
- BKE_add_image_extension(export_file, &imageFormat);
+ BKE_image_path_ensure_ext_from_imformat(export_file, &imageFormat);
BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file);
diff --git a/source/blender/collada/ImportSettings.cpp b/source/blender/collada/ImportSettings.cpp
index 74607787f25..9483aa1ac76 100644
--- a/source/blender/collada/ImportSettings.cpp
+++ b/source/blender/collada/ImportSettings.cpp
@@ -20,7 +20,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/collada/ExportSettings.cpp
+/** \file blender/collada/ImportSettings.cpp
* \ingroup collada
*/
diff --git a/source/blender/collada/ImportSettings.h b/source/blender/collada/ImportSettings.h
index 3f3a9fb354e..783f58e6bff 100644
--- a/source/blender/collada/ImportSettings.h
+++ b/source/blender/collada/ImportSettings.h
@@ -20,7 +20,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file ExportSettings.h
+/** \file ImportSettings.h
* \ingroup collada
*/
@@ -32,7 +32,9 @@
struct ImportSettings {
public:
bool import_units;
-
+ bool find_chains;
+ bool fix_orientation;
+ int min_chain_length;
char *filepath;
};
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index a4bf1d28366..2adbdd27cdf 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -185,7 +185,7 @@ void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
{
COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
- if (values->empty()) return;
+ if (values->empty() || values->getCount() <= (v_index * stride + 2)) return; // xxx need to create an eror instead
mloopcol->r = FTOCHAR((*values)[v_index * stride]);
mloopcol->g = FTOCHAR((*values)[v_index * stride + 1]);
@@ -196,7 +196,7 @@ void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
{
COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
- if (values->empty()) return;
+ if (values->empty() || values->getCount() <= (v_index * stride + 2)) return; // xxx need to create an eror instead
mloopcol->r = FTOCHAR((*values)[v_index * stride]);
mloopcol->g = FTOCHAR((*values)[v_index * stride + 1]);
@@ -225,11 +225,9 @@ void MeshImporter::set_poly_indices(MPoly *mpoly, MLoop *mloop, int loop_index,
void MeshImporter::set_vcol(MLoopCol *mlc, VCOLDataWrapper &vob, int loop_index, COLLADAFW::IndexList &index_list, int count)
{
- COLLADAFW::UIntValuesArray& indices =index_list.getIndices();
int index;
- for(index = 0; index < count; index++,mlc++)
- {
- int v_index = indices[index+loop_index];
+ for (index = 0; index < count; index++, mlc++) {
+ int v_index = index_list.getIndex(index + loop_index);
vob.get_vcol(v_index,mlc);
}
}
@@ -628,6 +626,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
unsigned int *position_indices = mp->getPositionIndices().getData();
unsigned int *normal_indices = mp->getNormalIndices().getData();
+
bool mp_has_normals = primitive_has_useable_normals(mp);
bool mp_has_faces = primitive_has_faces(mp);
@@ -708,16 +707,21 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
mpoly->flag |= ME_SMOOTH;
}
- for(unsigned int vcolor_index = 0 ; vcolor_index < index_list_array_vcolor.getCount();vcolor_index++)
- {
- COLLADAFW::IndexList& index_list = *index_list_array_vcolor[vcolor_index];
- COLLADAFW::String colname = extract_vcolname(index_list.getName());
- MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_named(&me->ldata, CD_MLOOPCOL, colname.c_str());
- if (mloopcol == NULL) {
- fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to VCOLOR [#%s].\n", me->id.name, index_list.getName().c_str() );
- }
- else {
- set_vcol(mloopcol+loop_index, vcol, start_index, *index_list_array_vcolor[vcolor_index], vcount);
+
+ if (mp->hasColorIndices()) {
+ int vcolor_count = index_list_array_vcolor.getCount();
+
+ for (unsigned int vcolor_index = 0; vcolor_index < vcolor_count; vcolor_index++) {
+
+ COLLADAFW::IndexList& color_index_list = *mp->getColorIndices(vcolor_index);
+ COLLADAFW::String colname = extract_vcolname(color_index_list.getName());
+ MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_named(&me->ldata, CD_MLOOPCOL, colname.c_str());
+ if (mloopcol == NULL) {
+ fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to VCOLOR [#%s].\n", me->id.name, color_index_list.getName().c_str());
+ }
+ else {
+ set_vcol(mloopcol + loop_index, vcol, start_index, color_index_list, vcount);
+ }
}
}
@@ -810,22 +814,6 @@ bool MeshImporter::is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& n
return true;
}
-
-void MeshImporter::bmeshConversion()
-{
- for (std::map<COLLADAFW::UniqueId, Mesh *>::iterator m = uid_mesh_map.begin();
- m != uid_mesh_map.end(); ++m)
- {
- if ((*m).second) {
- Mesh *me = (*m).second;
- BKE_mesh_tessface_clear(me);
- BKE_mesh_calc_normals(me);
- //BKE_mesh_validate(me, 1);
- }
- }
-}
-
-
Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid)
{
if (uid_object_map.find(geom_uid) != uid_object_map.end())
@@ -1063,7 +1051,7 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
// set texture face
if (color_texture &&
strlen((color_texture)->uvname) &&
- strcmp(layername, color_texture->uvname) != 0) {
+ !STREQ(layername, color_texture->uvname)) {
texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
color_texture->uvname);
strcpy(layername, color_texture->uvname);
@@ -1197,7 +1185,12 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
read_vertices(mesh, me);
read_polys(mesh, me);
- BKE_mesh_calc_edges(me, false, false);
+
+ // must validate before calculating edges
+ BKE_mesh_calc_normals(me);
+ BKE_mesh_validate(me, false, false);
+ // validation does this
+ // BKE_mesh_calc_edges(me, false, false);
// read_lines() must be called after the face edges have been generated.
// Oterwise the loose edges will be silently deleted again.
diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h
index 9fc1d777f62..9d5fefb83f2 100644
--- a/source/blender/collada/MeshImporter.h
+++ b/source/blender/collada/MeshImporter.h
@@ -161,8 +161,6 @@ public:
MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce);
- void bmeshConversion();
-
virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid);
virtual Mesh *get_mesh_by_geom_uid(const COLLADAFW::UniqueId& geom_uid);
diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp
index 75928f9d189..71875d6274a 100644
--- a/source/blender/collada/SkinInfo.cpp
+++ b/source/blender/collada/SkinInfo.cpp
@@ -38,13 +38,16 @@
#include "BLI_math.h"
#include "BLI_compiler_attrs.h"
-#include "BKE_object.h"
#include "DNA_armature_types.h"
#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
+
+#include "BKE_action.h"
+#include "BKE_object.h"
+#include "BKE_object_deform.h"
+
#include "ED_mesh.h"
#include "ED_object.h"
-#include "BKE_action.h"
#include "SkinInfo.h"
#include "collada_utils.h"
@@ -263,7 +266,7 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::Unique
name = bc_get_joint_name(joint_by_uid[(*it).joint_uid]);
}
- ED_vgroup_add_name(ob, (char *)name);
+ BKE_object_defgroup_add_name(ob, name);
}
// <vcount> - number of joints per vertex - joints_per_vertex
diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp
index 595787b44ac..e205608a365 100644
--- a/source/blender/collada/TransformWriter.cpp
+++ b/source/blender/collada/TransformWriter.cpp
@@ -102,7 +102,7 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob, B
double d_obmat[4][4];
float f_obmat[4][4];
- /* Export the local Matrix (relative to the object parent) */
+ /* Export the local Matrix (relative to the object parent, be it an object, bone or vertex(-tices)) */
BKE_object_matrix_local_get(ob, f_obmat);
converter.mat4_to_dae_double(d_obmat, f_obmat);
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index ffbbb8623ac..f1d5f1a208a 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -44,13 +44,18 @@ extern "C"
int collada_import(bContext *C,
const char *filepath,
- int import_units)
+ int import_units,
+ int find_chains,
+ int fix_orientation,
+ int min_chain_length)
{
ImportSettings import_settings;
- import_settings.filepath = (char *)filepath;
-
- import_settings.import_units = import_units != 0;
+ import_settings.filepath = (char *)filepath;
+ import_settings.import_units = import_units != 0;
+ import_settings.find_chains = find_chains != 0;
+ import_settings.fix_orientation = fix_orientation != 0;
+ import_settings.min_chain_length = min_chain_length;
DocumentImporter imp(C, &import_settings);
if (imp.import()) return 1;
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index 524c704cdee..6819a62fdf0 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -55,7 +55,10 @@ struct Scene;
*/
int collada_import(struct bContext *C,
const char *filepath,
- int import_units);
+ int import_units,
+ int find_chains,
+ int fix_orientation,
+ int min_chain_length);
int collada_export(struct Scene *sce,
const char *filepath,
diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp
index 567ee22b3d6..38855013ee1 100644
--- a/source/blender/collada/collada_internal.cpp
+++ b/source/blender/collada/collada_internal.cpp
@@ -94,8 +94,7 @@ void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::
void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4])
{
- copy_m4_m4(out, in);
- transpose_m4(out);
+ transpose_m4_m4(out, in);
}
void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4])
@@ -188,73 +187,77 @@ void TransformBase::decompose(float mat[4][4], float *loc, float eul[3], float q
* must obviously be removed too, otherwise they would be heavily misinterpreted.
*/
const unsigned char translate_start_name_map[256] = {
- 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 76, 77, 78, 79, 80,
- 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 95, 95, 95, 95, 95, 95,
- 97, 98, 99, 100, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 112,
- 113, 114, 115, 116, 117, 118, 119, 120,
- 121, 122, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 192,
- 193, 194, 195, 196, 197, 198, 199, 200,
- 201, 202, 203, 204, 205, 206, 207, 208,
- 209, 210, 211, 212, 213, 214, 95, 216,
- 217, 218, 219, 220, 221, 222, 223, 224,
- 225, 226, 227, 228, 229, 230, 231, 232,
- 233, 234, 235, 236, 237, 238, 239, 240,
- 241, 242, 243, 244, 245, 246, 95, 248,
- 249, 250, 251, 252, 253, 254, 255
+
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 95, 95, 95, 95, 95,
+ 95, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 95, 95, 95, 95, 95,
+
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215,
+ 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250, 251, 252, 253, 254, 255
};
const unsigned char translate_name_map[256] = {
- 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 45, 95, 95, 48,
- 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 95, 95, 95, 95, 95, 95, 95,
- 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 76, 77, 78, 79, 80,
- 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 95, 95, 95, 95, 95, 95,
- 97, 98, 99, 100, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 112,
- 113, 114, 115, 116, 117, 118, 119, 120,
- 121, 122, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 183, 95,
- 95, 95, 95, 95, 95, 95, 95, 192,
- 193, 194, 195, 196, 197, 198, 199, 200,
- 201, 202, 203, 204, 205, 206, 207, 208,
- 209, 210, 211, 212, 213, 214, 95, 216,
- 217, 218, 219, 220, 221, 222, 223, 224,
- 225, 226, 227, 228, 229, 230, 231, 232,
- 233, 234, 235, 236, 237, 238, 239, 240,
- 241, 242, 243, 244, 245, 246, 95, 248,
- 249, 250, 251, 252, 253, 254, 255
+
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 95, 95, 95,
+ 95, 95, 95, 95, 95, 45, 95, 95,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 95, 95, 95, 95, 95, 95,
+ 95, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 95, 95, 95, 95, 95,
+ 95, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 95, 95, 95, 95, 95,
+
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215,
+ 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250, 251, 252, 253, 254, 255
};
typedef std::map< std::string, std::vector<std::string> > map_string_list;
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index d91689ff496..f15efa89ea6 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -164,8 +164,7 @@ Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh
}
tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here
- DM_to_mesh(dm, tmpmesh, ob, CD_MASK_MESH);
- dm->release(dm);
+ DM_to_mesh(dm, tmpmesh, ob, CD_MASK_MESH, true);
if (triangulate) {
bc_triangulate_mesh(tmpmesh);
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index 4bcdd4d9e34..048c974423f 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -90,8 +90,6 @@ set(SRC
intern/COM_OpenCLDevice.h
intern/COM_CompositorContext.cpp
intern/COM_CompositorContext.h
- intern/COM_ChannelInfo.cpp
- intern/COM_ChannelInfo.h
intern/COM_SingleThreadedOperation.cpp
intern/COM_SingleThreadedOperation.h
intern/COM_Debug.cpp
diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h
index b60fffc6a22..9936914d3d8 100644
--- a/source/blender/compositor/COM_defines.h
+++ b/source/blender/compositor/COM_defines.h
@@ -105,7 +105,9 @@ typedef enum OrderOfChunks {
#define COM_RULE_OF_THIRDS_DIVIDER 100.0f
-#define COM_NUMBER_OF_CHANNELS 4
+#define COM_NUM_CHANNELS_VALUE 1
+#define COM_NUM_CHANNELS_VECTOR 3
+#define COM_NUM_CHANNELS_COLOR 4
#define COM_BLUR_BOKEH_PIXELS 512
diff --git a/source/blender/compositor/intern/COM_ChannelInfo.h b/source/blender/compositor/intern/COM_ChannelInfo.h
deleted file mode 100644
index ec78e7e1cb1..00000000000
--- a/source/blender/compositor/intern/COM_ChannelInfo.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor:
- * Jeroen Bakker
- * Monique Dewanchand
- */
-
-#ifndef _COM_ChannelInfo_h
-#define _COM_ChannelInfo_h
-
-#include <vector>
-#include "BKE_text.h"
-#include <string>
-#include "DNA_node_types.h"
-#include "BLI_rect.h"
-
-using namespace std;
-
-/**
- * @brief List of possible channel types
- * @ingroup Model
- */
-typedef enum ChannelType {
- COM_CT_ColorComponent /** @brief this channel is contains color information. Specific used is determined by channelnumber, and in the future color space */,
- COM_CT_Alpha /** @brief this channel is contains transparency value */,
- COM_CT_Value /** @brief this channel is contains a value */,
- COM_CT_X /** @brief this channel is contains a X value */,
- COM_CT_Y /** @brief this channel is contains a Y value */,
- COM_CT_Z /** @brief this channel is contains a Z value */,
- COM_CT_W /** @brief this channel is contains a W value */,
- COM_CT_UNUSED /** @brief this channel is unused */
-} ChannelType;
-
-/**
- * @brief ChannelInfo holds information about a channel.
- *
- * Channels are transported from node to node via a NodeLink.
- * ChannelInfo holds specific setting of these channels in order that the to-node of the link
- * Can handle specific logic per channel setting.
- *
- * @note currently this is not used, but a future place to implement color spacing and other things.
- * @ingroup Model
- */
-class ChannelInfo {
-private:
- /**
- * @brief the channel number, in the link. [0-3]
- */
- int m_number;
-
- /**
- * @brief type of channel
- */
- ChannelType m_type;
-
- /**
- * @brieg Is this value in this channel premultiplied with its alpha
- * @note only valid if type = ColorComponent;
- */
- bool m_premultiplied;
-
-// /**
-// * Color space of this value.
-// * only valid when type = ColorComponent;
-// */
-// string colorspacename;
-
-public:
- /**
- * @brief creates a new ChannelInfo and set default values
- */
- ChannelInfo();
-
- /**
- * @brief set the index of this channel in the NodeLink
- */
- void setNumber(const int number) { this->m_number = number; }
-
- /**
- * @brief get the index of this channel in the NodeLink
- */
- const int getNumber() const { return this->m_number; }
-
- /**
- * @brief set the type of channel
- */
- void setType(const ChannelType type) { this->m_type = type; }
-
- /**
- * @brief get the type of channel
- */
- const ChannelType getType() const { return this->m_type; }
-
- /**
- * @brief set the premultiplicatioin of this channel
- */
- void setPremultiplied(const bool premultiplied) { this->m_premultiplied = premultiplied; }
-
- /**
- * @brief is this channel premultiplied
- */
- const bool isPremultiplied() const { return this->m_premultiplied; }
-};
-
-
-#endif
diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h
index a398ae937a3..3fbafa0a029 100644
--- a/source/blender/compositor/intern/COM_CompositorContext.h
+++ b/source/blender/compositor/intern/COM_CompositorContext.h
@@ -185,7 +185,7 @@ public:
void setFastCalculation(bool fastCalculation) {this->m_fastCalculation = fastCalculation;}
bool isFastCalculation() const { return this->m_fastCalculation; }
- bool isGroupnodeBufferEnabled() const { return this->getbNodeTree()->flag & NTREE_COM_GROUPNODE_BUFFER; }
+ bool isGroupnodeBufferEnabled() const { return (this->getbNodeTree()->flag & NTREE_COM_GROUPNODE_BUFFER) != 0; }
};
diff --git a/source/blender/compositor/intern/COM_Debug.cpp b/source/blender/compositor/intern/COM_Debug.cpp
index 470f8fd2ef7..ffaa4cc45a8 100644
--- a/source/blender/compositor/intern/COM_Debug.cpp
+++ b/source/blender/compositor/intern/COM_Debug.cpp
@@ -32,6 +32,7 @@ extern "C" {
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "DNA_node_types.h"
+#include "BKE_appdir.h"
#include "BKE_node.h"
}
@@ -398,7 +399,7 @@ void DebugInfo::graphviz(const ExecutionSystem *system)
char filename[FILE_MAX];
BLI_snprintf(basename, sizeof(basename), "compositor_%d.dot", m_file_index);
- BLI_join_dirfile(filename, sizeof(filename), BLI_temp_dir_session(), basename);
+ BLI_join_dirfile(filename, sizeof(filename), BKE_tempdir_session(), basename);
++m_file_index;
FILE *fp = BLI_fopen(filename, "wb");
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp
index 7c08188db90..0667271f4b1 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp
@@ -137,11 +137,15 @@ void ExecutionSystem::execute()
}
unsigned int index;
+ // First allocale all write buffer
for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index];
- operation->setbNodeTree(this->m_context.getbNodeTree());
- operation->initExecution();
+ if (operation->isWriteBufferOperation()) {
+ operation->setbNodeTree(this->m_context.getbNodeTree());
+ operation->initExecution();
+ }
}
+ // Connect read buffers to their write buffers
for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index];
if (operation->isReadBufferOperation()) {
@@ -149,6 +153,14 @@ void ExecutionSystem::execute()
readOperation->updateMemoryBuffer();
}
}
+ // initialize other operations
+ for (index = 0; index < this->m_operations.size(); index++) {
+ NodeOperation *operation = this->m_operations[index];
+ if (!operation->isWriteBufferOperation()) {
+ operation->setbNodeTree(this->m_context.getbNodeTree());
+ operation->initExecution();
+ }
+ }
for (index = 0; index < this->m_groups.size(); index++) {
ExecutionGroup *executionGroup = this->m_groups[index];
executionGroup->setChunksize(this->m_context.getChunksize());
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp
index c59ecced93c..9e6e5a423f9 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp
@@ -27,6 +27,19 @@
using std::min;
using std::max;
+static unsigned int determine_num_channels(DataType datatype)
+{
+ switch (datatype) {
+ case COM_DT_VALUE:
+ return COM_NUM_CHANNELS_VALUE;
+ case COM_DT_VECTOR:
+ return COM_NUM_CHANNELS_VECTOR;
+ case COM_DT_COLOR:
+ default:
+ return COM_NUM_CHANNELS_COLOR;
+ }
+}
+
unsigned int MemoryBuffer::determineBufferSize()
{
return getWidth() * getHeight();
@@ -34,61 +47,62 @@ unsigned int MemoryBuffer::determineBufferSize()
int MemoryBuffer::getWidth() const
{
- return this->m_rect.xmax - this->m_rect.xmin;
+ return this->m_width;
}
int MemoryBuffer::getHeight() const
{
- return this->m_rect.ymax - this->m_rect.ymin;
+ return this->m_height;
}
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect)
{
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
+ this->m_width = BLI_rcti_size_x(&this->m_rect);
+ this->m_height = BLI_rcti_size_y(&this->m_rect);
this->m_memoryProxy = memoryProxy;
this->m_chunkNumber = chunkNumber;
- this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, 16, "COM_MemoryBuffer");
+ this->m_num_channels = determine_num_channels(memoryProxy->getDataType());
+ this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer");
this->m_state = COM_MB_ALLOCATED;
- this->m_datatype = COM_DT_COLOR;
- this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
+ this->m_datatype = memoryProxy->getDataType();;
}
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect)
{
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
+ this->m_width = BLI_rcti_size_x(&this->m_rect);
+ this->m_height = BLI_rcti_size_y(&this->m_rect);
this->m_memoryProxy = memoryProxy;
this->m_chunkNumber = -1;
- this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, 16, "COM_MemoryBuffer");
+ this->m_num_channels = determine_num_channels(memoryProxy->getDataType());
+ this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer");
this->m_state = COM_MB_TEMPORARILY;
- this->m_datatype = COM_DT_COLOR;
- this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
+ this->m_datatype = memoryProxy->getDataType();
+}
+MemoryBuffer::MemoryBuffer(DataType dataType, rcti *rect)
+{
+ BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
+ this->m_width = BLI_rcti_size_x(&this->m_rect);
+ this->m_height = BLI_rcti_size_y(&this->m_rect);
+ this->m_height = this->m_rect.ymax - this->m_rect.ymin;
+ this->m_memoryProxy = NULL;
+ this->m_chunkNumber = -1;
+ this->m_num_channels = determine_num_channels(dataType);
+ this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer");
+ this->m_state = COM_MB_TEMPORARILY;
+ this->m_datatype = dataType;
}
MemoryBuffer *MemoryBuffer::duplicate()
{
MemoryBuffer *result = new MemoryBuffer(this->m_memoryProxy, &this->m_rect);
- memcpy(result->m_buffer, this->m_buffer, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float));
+ memcpy(result->m_buffer, this->m_buffer, this->determineBufferSize() * this->m_num_channels * sizeof(float));
return result;
}
void MemoryBuffer::clear()
{
- memset(this->m_buffer, 0, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float));
+ memset(this->m_buffer, 0, this->determineBufferSize() * this->m_num_channels * sizeof(float));
}
-float *MemoryBuffer::convertToValueBuffer()
-{
- const unsigned int size = this->determineBufferSize();
- unsigned int i;
-
- float *result = (float *)MEM_mallocN(sizeof(float) * size, __func__);
-
- const float *fp_src = this->m_buffer;
- float *fp_dst = result;
-
- for (i = 0; i < size; i++, fp_dst++, fp_src += COM_NUMBER_OF_CHANNELS) {
- *fp_dst = *fp_src;
- }
-
- return result;
-}
float MemoryBuffer::getMaximumValue()
{
@@ -98,7 +112,7 @@ float MemoryBuffer::getMaximumValue()
const float *fp_src = this->m_buffer;
- for (i = 0; i < size; i++, fp_src += COM_NUMBER_OF_CHANNELS) {
+ for (i = 0; i < size; i++, fp_src += this->m_num_channels) {
float value = *fp_src;
if (value > result) {
result = value;
@@ -116,7 +130,7 @@ float MemoryBuffer::getMaximumValue(rcti *rect)
BLI_rcti_isect(rect, &this->m_rect, &rect_clamp);
if (!BLI_rcti_is_empty(&rect_clamp)) {
- MemoryBuffer *temp = new MemoryBuffer(NULL, &rect_clamp);
+ MemoryBuffer *temp = new MemoryBuffer(this->m_datatype, &rect_clamp);
temp->copyContentFrom(this);
float result = temp->getMaximumValue();
delete temp;
@@ -152,9 +166,9 @@ void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer)
for (otherY = minY; otherY < maxY; otherY++) {
- otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_chunkWidth + minX - otherBuffer->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
- offset = ((otherY - this->m_rect.ymin) * this->m_chunkWidth + minX - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
- memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * COM_NUMBER_OF_CHANNELS * sizeof(float));
+ otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_width + minX - otherBuffer->m_rect.xmin) * this->m_num_channels;
+ offset = ((otherY - this->m_rect.ymin) * this->m_width + minX - this->m_rect.xmin) * this->m_num_channels;
+ memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * this->m_num_channels * sizeof(float));
}
}
@@ -163,9 +177,8 @@ void MemoryBuffer::writePixel(int x, int y, const float color[4])
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax)
{
- const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
- copy_v4_v4(&this->m_buffer[offset], color);
- }
+ const int offset = (this->m_width * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * this->m_num_channels;
+ memcpy(&this->m_buffer[offset], color, sizeof(float)*this->m_num_channels); }
}
void MemoryBuffer::addPixel(int x, int y, const float color[4])
@@ -173,8 +186,12 @@ void MemoryBuffer::addPixel(int x, int y, const float color[4])
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax)
{
- const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
- add_v4_v4(&this->m_buffer[offset], color);
+ const int offset = (this->m_width * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * this->m_num_channels;
+ float *dst = &this->m_buffer[offset];
+ const float *src = color;
+ for (int i = 0; i < this->m_num_channels ; i++, dst++, src++) {
+ *dst += *src;
+ }
}
}
@@ -208,8 +225,9 @@ static void read_ewa_pixel_sampled(void *userdata, int x, int y, float result[4]
}
}
-void MemoryBuffer::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler)
+void MemoryBuffer::readEWA(float *result, const float uv[2], const float derivatives[2][2], PixelSampler sampler)
{
+ BLI_assert(this->m_datatype == COM_DT_COLOR);
ReadEWAData data;
data.buffer = this;
data.sampler = sampler;
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h
index d6ef9cd673e..0b5fc21e69e 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.h
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.h
@@ -83,11 +83,6 @@ private:
unsigned int m_chunkNumber;
/**
- * @brief width of the chunk
- */
- unsigned int m_chunkWidth;
-
- /**
* @brief state of the buffer
*/
MemoryBufferState m_state;
@@ -97,6 +92,15 @@ private:
*/
float *m_buffer;
+ /**
+ * @brief the number of channels of a single value in the buffer.
+ * For value buffers this is 1, vector 3 and color 4
+ */
+ unsigned int m_num_channels;
+
+ int m_width;
+ int m_height;
+
public:
/**
* @brief construct new MemoryBuffer for a chunk
@@ -107,7 +111,12 @@ public:
* @brief construct new temporarily MemoryBuffer for an area
*/
MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect);
-
+
+ /**
+ * @brief construct new temporarily MemoryBuffer for an area
+ */
+ MemoryBuffer(DataType datatype, rcti *rect);
+
/**
* @brief destructor
*/
@@ -117,7 +126,9 @@ public:
* @brief read the ChunkNumber of this MemoryBuffer
*/
unsigned int getChunkNumber() { return this->m_chunkNumber; }
-
+
+ unsigned int get_num_channels() { return this->m_num_channels; }
+
/**
* @brief get the data of this MemoryBuffer
* @note buffer should already be available in memory
@@ -134,8 +145,8 @@ public:
inline void wrap_pixel(int &x, int &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y)
{
- int w = m_rect.xmax - m_rect.xmin;
- int h = m_rect.ymax - m_rect.ymin;
+ int w = this->m_width;
+ int h = this->m_height;
x = x - m_rect.xmin;
y = y - m_rect.ymin;
@@ -164,7 +175,39 @@ public:
}
}
- inline void read(float result[4], int x, int y,
+ inline void wrap_pixel(float &x, float &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y)
+ {
+ float w = (float)this->m_width;
+ float h = (float)this->m_height;
+ x = x - m_rect.xmin;
+ y = y - m_rect.ymin;
+
+ switch (extend_x) {
+ case COM_MB_CLIP:
+ break;
+ case COM_MB_EXTEND:
+ if (x < 0) x = 0.0f;
+ if (x >= w) x = w;
+ break;
+ case COM_MB_REPEAT:
+ x = fmodf(x, w);
+ break;
+ }
+
+ switch (extend_y) {
+ case COM_MB_CLIP:
+ break;
+ case COM_MB_EXTEND:
+ if (y < 0) y = 0.0f;
+ if (y >= h) y = h;
+ break;
+ case COM_MB_REPEAT:
+ y = fmodf(y, h);
+ break;
+ }
+ }
+
+ inline void read(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP)
{
@@ -172,81 +215,54 @@ public:
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
if (clip_x || clip_y) {
/* clip result outside rect is zero */
- zero_v4(result);
+ memset(result, 0, this->m_num_channels * sizeof(float));
}
else {
- wrap_pixel(x, y, extend_x, extend_y);
- const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS;
- copy_v4_v4(result, &this->m_buffer[offset]);
+ int u = x;
+ int v = y;
+ this->wrap_pixel(u, v, extend_x, extend_y);
+ const int offset = (this->m_width * y + x) * this->m_num_channels;
+ float *buffer = &this->m_buffer[offset];
+ memcpy(result, buffer, sizeof(float) * this->m_num_channels);
}
}
- inline void readNoCheck(float result[4], int x, int y,
+ inline void readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP)
{
- wrap_pixel(x, y, extend_x, extend_y);
- const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS;
+ int u = x;
+ int v = y;
- BLI_assert(offset >= 0);
- BLI_assert(offset < this->determineBufferSize() * COM_NUMBER_OF_CHANNELS);
- BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
- !(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
+ this->wrap_pixel(u, v, extend_x, extend_y);
+ const int offset = (this->m_width * v + u) * this->m_num_channels;
+ BLI_assert(offset >= 0);
+ BLI_assert(offset < this->determineBufferSize() * this->m_num_channels);
+ BLI_assert(!(extend_x == COM_MB_CLIP && (u < m_rect.xmin || u >= m_rect.xmax)) &&
+ !(extend_y == COM_MB_CLIP && (v < m_rect.ymin || v >= m_rect.ymax)));
#if 0
/* always true */
BLI_assert((int)(MEM_allocN_len(this->m_buffer) / sizeof(*this->m_buffer)) ==
(int)(this->determineBufferSize() * COM_NUMBER_OF_CHANNELS));
#endif
-
- copy_v4_v4(result, &this->m_buffer[offset]);
+ float *buffer = &this->m_buffer[offset];
+ memcpy(result, buffer, sizeof(float) * this->m_num_channels);
}
void writePixel(int x, int y, const float color[4]);
void addPixel(int x, int y, const float color[4]);
- inline void readBilinear(float result[4], float x, float y,
+ inline void readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP)
{
- int x1 = floor(x);
- int y1 = floor(y);
- int x2 = x1 + 1;
- int y2 = y1 + 1;
- wrap_pixel(x1, y1, extend_x, extend_y);
- wrap_pixel(x2, y2, extend_x, extend_y);
-
- float valuex = x - x1;
- float valuey = y - y1;
- float mvaluex = 1.0f - valuex;
- float mvaluey = 1.0f - valuey;
-
- float color1[4];
- float color2[4];
- float color3[4];
- float color4[4];
-
- read(color1, x1, y1);
- read(color2, x1, y2);
- read(color3, x2, y1);
- read(color4, x2, y2);
-
- color1[0] = color1[0] * mvaluey + color2[0] * valuey;
- color1[1] = color1[1] * mvaluey + color2[1] * valuey;
- color1[2] = color1[2] * mvaluey + color2[2] * valuey;
- color1[3] = color1[3] * mvaluey + color2[3] * valuey;
-
- color3[0] = color3[0] * mvaluey + color4[0] * valuey;
- color3[1] = color3[1] * mvaluey + color4[1] * valuey;
- color3[2] = color3[2] * mvaluey + color4[2] * valuey;
- color3[3] = color3[3] * mvaluey + color4[3] * valuey;
-
- result[0] = color1[0] * mvaluex + color3[0] * valuex;
- result[1] = color1[1] * mvaluex + color3[1] * valuex;
- result[2] = color1[2] * mvaluex + color3[2] * valuex;
- result[3] = color1[3] * mvaluex + color3[3] * valuex;
+ float u = x;
+ float v = y;
+ this->wrap_pixel(u, v, extend_x, extend_y);
+ BLI_bilinear_interpolation_fl(this->m_buffer, result, this->m_width, this->m_height, this->m_num_channels, u, v);
}
- void readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler);
+ void readEWA(float *result, const float uv[2], const float derivatives[2][2], PixelSampler sampler);
/**
* @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk)
@@ -284,7 +300,6 @@ public:
MemoryBuffer *duplicate();
- float *convertToValueBuffer();
float getMaximumValue();
float getMaximumValue(rcti *rect);
private:
diff --git a/source/blender/compositor/intern/COM_MemoryProxy.cpp b/source/blender/compositor/intern/COM_MemoryProxy.cpp
index 90ca0baea06..1df3e59db62 100644
--- a/source/blender/compositor/intern/COM_MemoryProxy.cpp
+++ b/source/blender/compositor/intern/COM_MemoryProxy.cpp
@@ -23,10 +23,11 @@
#include "COM_MemoryProxy.h"
-MemoryProxy::MemoryProxy()
+MemoryProxy::MemoryProxy(DataType datatype)
{
this->m_writeBufferOperation = NULL;
this->m_executor = NULL;
+ this->m_datatype = datatype;
}
void MemoryProxy::allocate(unsigned int width, unsigned int height)
diff --git a/source/blender/compositor/intern/COM_MemoryProxy.h b/source/blender/compositor/intern/COM_MemoryProxy.h
index 233b035a2d7..b332852088b 100644
--- a/source/blender/compositor/intern/COM_MemoryProxy.h
+++ b/source/blender/compositor/intern/COM_MemoryProxy.h
@@ -63,8 +63,13 @@ private:
*/
MemoryBuffer *m_buffer;
+ /**
+ * @brief datatype of this MemoryProxy
+ */
+ DataType m_datatype;
+
public:
- MemoryProxy();
+ MemoryProxy(DataType type);
/**
* @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk.
@@ -104,6 +109,8 @@ public:
*/
inline MemoryBuffer *getBuffer() { return this->m_buffer; }
+ inline DataType getDataType() { return this->m_datatype; }
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryProxy")
#endif
diff --git a/source/blender/compositor/intern/COM_NodeGraph.cpp b/source/blender/compositor/intern/COM_NodeGraph.cpp
index 2dcf419d81b..c5096a6b352 100644
--- a/source/blender/compositor/intern/COM_NodeGraph.cpp
+++ b/source/blender/compositor/intern/COM_NodeGraph.cpp
@@ -179,6 +179,8 @@ void NodeGraph::add_bNodeLink(const NodeRange &node_range, bNodeLink *b_nodelink
/// @note: ignore invalid links
if (!(b_nodelink->flag & NODE_LINK_VALID))
return;
+ if ((b_nodelink->fromsock->flag & SOCK_UNAVAIL) || (b_nodelink->tosock->flag & SOCK_UNAVAIL))
+ return;
/* Note: a DNA input socket can have multiple NodeInput in the compositor tree! (proxies)
* The output then gets linked to each one of them.
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp b/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp
index fb5bc8fcd9b..74c05c3e62e 100644
--- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp
@@ -476,7 +476,7 @@ void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOpera
/* check of other end already has write operation, otherwise add a new one */
WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output);
if (!writeoperation) {
- writeoperation = new WriteBufferOperation();
+ writeoperation = new WriteBufferOperation(output->getDataType());
writeoperation->setbNodeTree(m_context->getbNodeTree());
addOperation(writeoperation);
@@ -486,7 +486,7 @@ void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOpera
}
/* add readbuffer op for the input */
- ReadBufferOperation *readoperation = new ReadBufferOperation();
+ ReadBufferOperation *readoperation = new ReadBufferOperation(output->getDataType());
readoperation->setMemoryProxy(writeoperation->getMemoryProxy());
this->addOperation(readoperation);
@@ -519,7 +519,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOper
/* if no write buffer operation exists yet, create a new one */
if (!writeOperation) {
- writeOperation = new WriteBufferOperation();
+ writeOperation = new WriteBufferOperation(operation->getOutputSocket()->getDataType());
writeOperation->setbNodeTree(m_context->getbNodeTree());
addOperation(writeOperation);
@@ -534,7 +534,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOper
if (&target->getOperation() == writeOperation)
continue; /* skip existing write op links */
- ReadBufferOperation *readoperation = new ReadBufferOperation();
+ ReadBufferOperation *readoperation = new ReadBufferOperation(operation->getOutputSocket()->getDataType());
readoperation->setMemoryProxy(writeOperation->getMemoryProxy());
addOperation(readoperation);
diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp
index c5b663d2aef..1b7acc9daf6 100644
--- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp
+++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp
@@ -24,6 +24,18 @@
#include "COM_WorkScheduler.h"
typedef enum COM_VendorID {NVIDIA = 0x10DE, AMD = 0x1002} COM_VendorID;
+const cl_image_format IMAGE_FORMAT_COLOR = {
+ CL_RGBA,
+ CL_FLOAT
+};
+const cl_image_format IMAGE_FORMAT_VECTOR = {
+ CL_RGB,
+ CL_FLOAT
+};
+const cl_image_format IMAGE_FORMAT_VALUE = {
+ CL_R,
+ CL_FLOAT
+};
OpenCLDevice::OpenCLDevice(cl_context context, cl_device_id device, cl_program program, cl_int vendorId)
{
@@ -72,6 +84,23 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader);
}
+const cl_image_format* OpenCLDevice::determineImageFormat(MemoryBuffer *memoryBuffer)
+{
+ const cl_image_format *imageFormat;
+ int num_channels = memoryBuffer->get_num_channels();
+ if (num_channels == 1) {
+ imageFormat = &IMAGE_FORMAT_VALUE;
+ }
+ else if (num_channels == 3) {
+ imageFormat = &IMAGE_FORMAT_VECTOR;
+ }
+ else {
+ imageFormat = &IMAGE_FORMAT_COLOR;
+ }
+
+ return imageFormat;
+}
+
cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex,
list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers,
ReadBufferOperation *reader)
@@ -80,12 +109,9 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers);
- const cl_image_format imageFormat = {
- CL_RGBA,
- CL_FLOAT
- };
+ const cl_image_format *imageFormat = determineImageFormat(result);
- cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, result->getWidth(),
+ cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, imageFormat, result->getWidth(),
result->getHeight(), 0, result->getBuffer(), &error);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
@@ -154,7 +180,7 @@ void OpenCLDevice::COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemo
bool breaked = false;
for (offsety = 0; offsety < height && (!breaked); offsety += localSize) {
- offset.y = offsety;
+ offset.s[1] = offsety;
if (offsety + localSize < height) {
size[1] = localSize;
}
@@ -169,7 +195,7 @@ void OpenCLDevice::COM_clEnqueueRange(cl_kernel kernel, MemoryBuffer *outputMemo
else {
size[0] = width - offsetx;
}
- offset.x = offsetx;
+ offset.s[0] = offsetx;
error = clSetKernelArg(kernel, offsetIndex, sizeof(cl_int2), &offset);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.h b/source/blender/compositor/intern/COM_OpenCLDevice.h
index 94df2f2b44c..a513954ee0d 100644
--- a/source/blender/compositor/intern/COM_OpenCLDevice.h
+++ b/source/blender/compositor/intern/COM_OpenCLDevice.h
@@ -94,6 +94,12 @@ public:
*/
void execute(WorkPackage *work);
+ /**
+ * @brief determine an image format
+ * @param memorybuffer
+ */
+ static const cl_image_format *determineImageFormat(MemoryBuffer *memoryBuffer);
+
cl_context getContext() { return this->m_context; }
cl_command_queue getQueue() { return this->m_queue; }
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index e1016731c7f..673920ef84a 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -111,7 +111,9 @@ static void **g_highlightedNodesRead;
}
#endif /* COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE */
#else
+# if COM_CURRENT_THREADING_MODEL != COM_TM_NOTHREAD
#define HIGHLIGHT(wp) {}
+# endif
#endif
void COM_startReadHighlights()
@@ -196,7 +198,7 @@ void WorkScheduler::schedule(ExecutionGroup *group, int chunkNumber)
BLI_thread_queue_push(g_cpuqueue, package);
}
#else
- BLI_thread_queue_push(cpuqueue, package);
+ BLI_thread_queue_push(g_cpuqueue, package);
#endif
#endif
}
diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp
index 636660bc96c..7ab05e438ec 100644
--- a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp
+++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp
@@ -62,8 +62,13 @@ void BokehBlurNode::convertToOperations(NodeConverter &converter, const Composit
converter.addOperation(operation);
converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
- converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
- converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(3));
+
+ // NOTE: on the bokeh blur operation the sockets are switched.
+ // for this reason the next two lines are correct.
+ // Fix for T43771
+ converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(3));
+ converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(2));
+
converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
if (!connectedSizeSocket) {
diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cpp b/source/blender/compositor/nodes/COM_CompositorNode.cpp
index 3d79eb693ea..933b8d0282b 100644
--- a/source/blender/compositor/nodes/COM_CompositorNode.cpp
+++ b/source/blender/compositor/nodes/COM_CompositorNode.cpp
@@ -34,7 +34,7 @@ void CompositorNode::convertToOperations(NodeConverter &converter, const Composi
bNode *editorNode = this->getbNode();
bool is_active = (editorNode->flag & NODE_DO_OUTPUT_RECALC) ||
context.isRendering();
- bool ignore_alpha = editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA;
+ bool ignore_alpha = (editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA) != 0;
NodeInput *imageSocket = this->getInputSocket(0);
NodeInput *alphaSocket = this->getInputSocket(1);
diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp
index e105f530eb2..cb7ccfaedf9 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.cpp
+++ b/source/blender/compositor/nodes/COM_ImageNode.cpp
@@ -32,6 +32,7 @@
#include "COM_SetValueOperation.h"
#include "COM_SetVectorOperation.h"
#include "COM_SetColorOperation.h"
+#include "COM_SeparateColorNode.h"
ImageNode::ImageNode(bNode *editorNode) : Node(editorNode)
{
@@ -78,7 +79,7 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
int numberOfOutputs = this->getNumberOfOutputSockets();
bool outputStraightAlpha = (editorNode->custom1 & CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT) != 0;
BKE_image_user_frame_calc(imageuser, context.getFramenumber(), 0);
-
+ NodeOperation *combined_operation = NULL;
/* force a load, we assume iuser index will be set OK anyway */
if (image && image->type == IMA_TYPE_MULTILAYER) {
bool is_multilayer_ok = false;
@@ -105,33 +106,48 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
#endif
int passindex;
RenderPass *rpass;
- for (rpass = (RenderPass *)rl->passes.first, passindex = 0; rpass; rpass = rpass->next, ++passindex)
- if (STREQ(rpass->name, bnodeSocket->identifier))
- break;
- if (rpass) {
- imageuser->pass = passindex;
- switch (rpass->channels) {
- case 1:
- operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_VALUE);
- break;
- /* using image operations for both 3 and 4 channels (RGB and RGBA respectively) */
- /* XXX any way to detect actual vector images? */
- case 3:
- operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_VECTOR);
- break;
- case 4:
- operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_COLOR);
- break;
- default:
- /* dummy operation is added below */
+ if (STREQ(bnodeSocket->identifier, "Alpha")) {
+ BLI_assert(combined_operation != NULL);
+ NodeOutput *outputSocket = this->getOutputSocket(index);
+ SeparateChannelOperation *separate_operation;
+ separate_operation = new SeparateChannelOperation();
+ separate_operation->setChannel(3);
+ converter.addOperation(separate_operation);
+ converter.addLink(combined_operation->getOutputSocket(), separate_operation->getInputSocket(0));
+ converter.mapOutputSocket(outputSocket, separate_operation->getOutputSocket());
+ operation = separate_operation;
+ }
+ else {
+ for (rpass = (RenderPass *)rl->passes.first, passindex = 0; rpass; rpass = rpass->next, ++passindex)
+ if (STREQ(rpass->name, bnodeSocket->identifier))
break;
- }
-
- if (index == 0 && operation) {
- converter.addPreview(operation->getOutputSocket());
+ if (rpass) {
+ imageuser->pass = passindex;
+ switch (rpass->channels) {
+ case 1:
+ operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_VALUE);
+ break;
+ /* using image operations for both 3 and 4 channels (RGB and RGBA respectively) */
+ /* XXX any way to detect actual vector images? */
+ case 3:
+ operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_VECTOR);
+ break;
+ case 4:
+ operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_COLOR);
+ break;
+ default:
+ /* dummy operation is added below */
+ break;
+ }
+ if (index == 0 && operation) {
+ converter.addPreview(operation->getOutputSocket());
+ }
+ if (STREQ(rpass->chan_id, "RGBA")) {
+ combined_operation = operation;
+ }
}
}
-
+
/* incase we can't load the layer */
if (operation == NULL)
converter.setInvalidOutput(getOutputSocket(index));
diff --git a/source/blender/compositor/nodes/COM_MathNode.cpp b/source/blender/compositor/nodes/COM_MathNode.cpp
index ef7046b8165..4cd6964ed3b 100644
--- a/source/blender/compositor/nodes/COM_MathNode.cpp
+++ b/source/blender/compositor/nodes/COM_MathNode.cpp
@@ -29,61 +29,61 @@ void MathNode::convertToOperations(NodeConverter &converter, const CompositorCon
MathBaseOperation *operation = NULL;
switch (this->getbNode()->custom1) {
- case 0: /* Add */
+ case NODE_MATH_ADD:
operation = new MathAddOperation();
break;
- case 1: /* Subtract */
+ case NODE_MATH_SUB:
operation = new MathSubtractOperation();
break;
- case 2: /* Multiply */
+ case NODE_MATH_MUL:
operation = new MathMultiplyOperation();
break;
- case 3: /* Divide */
+ case NODE_MATH_DIVIDE:
operation = new MathDivideOperation();
break;
- case 4: /* Sine */
+ case NODE_MATH_SIN:
operation = new MathSineOperation();
break;
- case 5: /* Cosine */
+ case NODE_MATH_COS:
operation = new MathCosineOperation();
break;
- case 6: /* Tangent */
+ case NODE_MATH_TAN:
operation = new MathTangentOperation();
break;
- case 7: /* Arc-Sine */
+ case NODE_MATH_ASIN:
operation = new MathArcSineOperation();
break;
- case 8: /* Arc-Cosine */
+ case NODE_MATH_ACOS:
operation = new MathArcCosineOperation();
break;
- case 9: /* Arc-Tangent */
+ case NODE_MATH_ATAN:
operation = new MathArcTangentOperation();
break;
- case 10: /* Power */
+ case NODE_MATH_POW:
operation = new MathPowerOperation();
break;
- case 11: /* Logarithm */
+ case NODE_MATH_LOG:
operation = new MathLogarithmOperation();
break;
- case 12: /* Minimum */
+ case NODE_MATH_MIN:
operation = new MathMinimumOperation();
break;
- case 13: /* Maximum */
+ case NODE_MATH_MAX:
operation = new MathMaximumOperation();
break;
- case 14: /* Round */
+ case NODE_MATH_ROUND:
operation = new MathRoundOperation();
break;
- case 15: /* Less Than */
+ case NODE_MATH_LESS:
operation = new MathLessThanOperation();
break;
- case 16: /* Greater Than */
+ case NODE_MATH_GREATER:
operation = new MathGreaterThanOperation();
break;
- case 17: /* Modulo */
+ case NODE_MATH_MOD:
operation = new MathModuloOperation();
break;
- case 18: /* Absolute Value */
+ case NODE_MATH_ABS:
operation = new MathAbsoluteOperation();
break;
}
diff --git a/source/blender/compositor/nodes/COM_MixNode.cpp b/source/blender/compositor/nodes/COM_MixNode.cpp
index b12dfc02ed7..89010d0e861 100644
--- a/source/blender/compositor/nodes/COM_MixNode.cpp
+++ b/source/blender/compositor/nodes/COM_MixNode.cpp
@@ -41,8 +41,8 @@ void MixNode::convertToOperations(NodeConverter &converter, const CompositorCont
NodeInput *color2Socket = this->getInputSocket(2);
NodeOutput *outputSocket = this->getOutputSocket(0);
bNode *editorNode = this->getbNode();
- bool useAlphaPremultiply = this->getbNode()->custom2 & 1;
- bool useClamp = this->getbNode()->custom2 & 2;
+ bool useAlphaPremultiply = (this->getbNode()->custom2 & 1) != 0;
+ bool useClamp = (this->getbNode()->custom2 & 2) != 0;
MixBaseOperation *convertProg;
switch (editorNode->custom1) {
diff --git a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
index 9b69bc5a46e..379b9f193e8 100644
--- a/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
+++ b/source/blender/compositor/nodes/COM_PlaneTrackDeformNode.cpp
@@ -54,6 +54,10 @@ void PlaneTrackDeformNode::convertToOperations(NodeConverter &converter, const C
warp_image_operation->setTrackingObject(data->tracking_object);
warp_image_operation->setPlaneTrackName(data->plane_track_name);
warp_image_operation->setFramenumber(frame_number);
+ if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
+ warp_image_operation->setMotionBlurSamples(data->motion_blur_samples);
+ warp_image_operation->setMotionBlurShutter(data->motion_blur_shutter);
+ }
converter.addOperation(warp_image_operation);
converter.mapInputSocket(input_image, warp_image_operation->getInputSocket(0));
@@ -64,6 +68,10 @@ void PlaneTrackDeformNode::convertToOperations(NodeConverter &converter, const C
plane_mask_operation->setTrackingObject(data->tracking_object);
plane_mask_operation->setPlaneTrackName(data->plane_track_name);
plane_mask_operation->setFramenumber(frame_number);
+ if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
+ plane_mask_operation->setMotionBlurSamples(data->motion_blur_samples);
+ plane_mask_operation->setMotionBlurShutter(data->motion_blur_shutter);
+ }
converter.addOperation(plane_mask_operation);
converter.mapOutputSocket(output_plane, plane_mask_operation->getOutputSocket());
diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp
index 48c8acfc6a1..17b00af16d8 100644
--- a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp
+++ b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp
@@ -73,8 +73,9 @@ void SocketBufferNode::convertToOperations(NodeConverter &converter, const Compo
NodeOutput *output = this->getOutputSocket(0);
NodeInput *input = this->getInputSocket(0);
- WriteBufferOperation *writeOperation = new WriteBufferOperation();
- ReadBufferOperation *readOperation = new ReadBufferOperation();
+ DataType datatype = output->getDataType();
+ WriteBufferOperation *writeOperation = new WriteBufferOperation(datatype);
+ ReadBufferOperation *readOperation = new ReadBufferOperation(datatype);
readOperation->setMemoryProxy(writeOperation->getMemoryProxy());
converter.addOperation(writeOperation);
converter.addOperation(readOperation);
diff --git a/source/blender/compositor/nodes/COM_TextureNode.cpp b/source/blender/compositor/nodes/COM_TextureNode.cpp
index 2ac027ca326..b80ca2fcdbd 100644
--- a/source/blender/compositor/nodes/COM_TextureNode.cpp
+++ b/source/blender/compositor/nodes/COM_TextureNode.cpp
@@ -35,7 +35,7 @@ void TextureNode::convertToOperations(NodeConverter &converter, const Compositor
Tex *texture = (Tex *)editorNode->id;
TextureOperation *operation = new TextureOperation();
const ColorManagedDisplaySettings *displaySettings = context.getDisplaySettings();
- bool sceneColorManage = strcmp(displaySettings->display_device, "None") != 0;
+ bool sceneColorManage = !STREQ(displaySettings->display_device, "None");
operation->setTexture(texture);
operation->setRenderData(context.getRenderData());
operation->setSceneColorManage(sceneColorManage);
diff --git a/source/blender/compositor/nodes/COM_TranslateNode.cpp b/source/blender/compositor/nodes/COM_TranslateNode.cpp
index 990cbe19be2..04dc1d435d3 100644
--- a/source/blender/compositor/nodes/COM_TranslateNode.cpp
+++ b/source/blender/compositor/nodes/COM_TranslateNode.cpp
@@ -57,8 +57,8 @@ void TranslateNode::convertToOperations(NodeConverter &converter, const Composit
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
if (data->wrap_axis) {
- WriteBufferOperation *writeOperation = new WriteBufferOperation();
- WrapOperation *wrapOperation = new WrapOperation();
+ WriteBufferOperation *writeOperation = new WriteBufferOperation(COM_DT_COLOR);
+ WrapOperation *wrapOperation = new WrapOperation(COM_DT_COLOR);
wrapOperation->setMemoryProxy(writeOperation->getMemoryProxy());
wrapOperation->setWrapping(data->wrap_axis);
diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp
index 07aa960c4d9..ff0b8fb1706 100644
--- a/source/blender/compositor/nodes/COM_ViewerNode.cpp
+++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp
@@ -35,7 +35,7 @@ void ViewerNode::convertToOperations(NodeConverter &converter, const CompositorC
{
bNode *editorNode = this->getbNode();
bool do_output = (editorNode->flag & NODE_DO_OUTPUT_RECALC || context.isRendering()) && (editorNode->flag & NODE_DO_OUTPUT);
- bool ignore_alpha = editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA;
+ bool ignore_alpha = (editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA) != 0;
NodeInput *imageSocket = this->getInputSocket(0);
NodeInput *alphaSocket = this->getInputSocket(1);
diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp
index 995c61589cc..b25e2281467 100644
--- a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp
+++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp
@@ -95,7 +95,7 @@ void *AntiAliasOperation::initializeTileData(rcti *rect)
float *input = tile->getBuffer();
char *valuebuffer = (char *)MEM_mallocN(sizeof(char) * size, __func__);
for (int i = 0; i < size; i++) {
- float in = input[i * COM_NUMBER_OF_CHANNELS];
+ float in = input[i];
valuebuffer[i] = FTOCHAR(in);
}
antialias_tagbuf(tile->getWidth(), tile->getHeight(), valuebuffer);
diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp
index f5bca5371e6..22f6fc33a0d 100644
--- a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp
@@ -110,11 +110,11 @@ void BokehBlurOperation::executePixel(float output[4], int x, int y, void *data)
int step = getStep();
- int offsetadd = getOffsetAdd();
+ int offsetadd = getOffsetAdd() * COM_NUM_CHANNELS_COLOR;
float m = this->m_bokehDimension / pixelSize;
for (int ny = miny; ny < maxy; ny += step) {
- int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
+ int bufferindex = ((minx - bufferstartx) * COM_NUM_CHANNELS_COLOR) + ((ny - bufferstarty) * COM_NUM_CHANNELS_COLOR * bufferwidth);
for (int nx = minx; nx < maxx; nx += step) {
float u = this->m_bokehMidX - (nx - x) * m;
float v = this->m_bokehMidY - (ny - y) * m;
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp
index ef331a50dfd..e3438bcbd15 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.cpp
+++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp
@@ -138,7 +138,7 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y2 = rect->ymax;
int offset = (y1 * this->getWidth() + x1);
int add = (this->getWidth() - (x2 - x1));
- int offset4 = offset * COM_NUMBER_OF_CHANNELS;
+ int offset4 = offset * COM_NUM_CHANNELS_COLOR;
int x;
int y;
bool breaked = false;
@@ -196,14 +196,14 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
this->m_depthInput->readSampled(color, input_x, input_y, COM_PS_NEAREST);
zbuffer[offset] = color[0];
- offset4 += COM_NUMBER_OF_CHANNELS;
+ offset4 += COM_NUM_CHANNELS_COLOR;
offset++;
if (isBreaked()) {
breaked = true;
}
}
offset += add;
- offset4 += add * COM_NUMBER_OF_CHANNELS;
+ offset4 += add * COM_NUM_CHANNELS_COLOR;
}
}
diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp
index ea1443598a9..fa9a957f83c 100644
--- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp
+++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp
@@ -60,7 +60,7 @@ void ConvertDepthToRadiusOperation::initExecution()
this->m_inputOperation = this->getInputSocketReader(0);
float focalDistance = determineFocalDistance();
- if (focalDistance == 0.0f) focalDistance = 1e10f; /* if the dof is 0.0 then set it be be far away */
+ if (focalDistance == 0.0f) focalDistance = 1e10f; /* if the dof is 0.0 then set it to be far away */
this->m_inverseFocalDistance = 1.0f / focalDistance;
this->m_aspect = (this->getWidth() > this->getHeight()) ? (this->getHeight() / (float)this->getWidth()) : (this->getWidth() / (float)this->getHeight());
this->m_aperture = 0.5f * (this->m_cam_lens / (this->m_aspect * cam_sensor)) / this->m_fStop;
diff --git a/source/blender/compositor/operations/COM_ConvertOperation.cpp b/source/blender/compositor/operations/COM_ConvertOperation.cpp
index 6b3e4067b18..977586acb60 100644
--- a/source/blender/compositor/operations/COM_ConvertOperation.cpp
+++ b/source/blender/compositor/operations/COM_ConvertOperation.cpp
@@ -49,9 +49,9 @@ ConvertValueToColorOperation::ConvertValueToColorOperation() : ConvertBaseOperat
void ConvertValueToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- float inputValue[4];
- this->m_inputOperation->readSampled(inputValue, x, y, sampler);
- output[0] = output[1] = output[2] = inputValue[0];
+ float value;
+ this->m_inputOperation->readSampled(&value, x, y, sampler);
+ output[0] = output[1] = output[2] = value;
output[3] = 1.0f;
}
@@ -98,8 +98,9 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation() : ConvertBaseOper
void ConvertColorToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- this->m_inputOperation->readSampled(output, x, y, sampler);
-}
+ float color[4];
+ this->m_inputOperation->readSampled(color, x, y, sampler);
+ copy_v3_v3(output, color);}
/* ******** Value to Vector ******** */
@@ -112,12 +113,9 @@ ConvertValueToVectorOperation::ConvertValueToVectorOperation() : ConvertBaseOper
void ConvertValueToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- float input[4];
- this->m_inputOperation->readSampled(input, x, y, sampler);
- output[0] = input[0];
- output[1] = input[0];
- output[2] = input[0];
- output[3] = 0.0f;
+ float value;
+ this->m_inputOperation->readSampled(&value, x, y, sampler);
+ output[0] = output[1] = output[2] = value;
}
@@ -292,6 +290,9 @@ void ConvertHSVToRGBOperation::executePixelSampled(float output[4], float x, flo
float inputColor[4];
this->m_inputOperation->readSampled(inputColor, x, y, sampler);
hsv_to_rgb_v(inputColor, output);
+ output[0] = max_ff(output[0], 0.0f);
+ output[1] = max_ff(output[1], 0.0f);
+ output[2] = max_ff(output[2], 0.0f);
output[3] = inputColor[3];
}
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
index cbf4ce693d9..6d15ef3395b 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
@@ -82,18 +82,18 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
const int bufferWidth = BLI_rcti_size_x(rect);
int offset;
- this->m_inputProgram->read(inputValue, x, y, NULL);
+ inputBuffer->read(inputValue, x, y);
if (inputValue[0] > sw) {
for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y;
- offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4;
+ offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
for (int xi = minx; xi < maxx; xi++) {
if (buffer[offset] < sw) {
const float dx = xi - x;
const float dis = dx * dx + dy * dy;
mindist = min(mindist, dis);
}
- offset += 4;
+ offset ++;
}
}
pixelvalue = -sqrtf(mindist);
@@ -101,15 +101,14 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
else {
for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y;
- offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4;
+ offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
for (int xi = minx; xi < maxx; xi++) {
if (buffer[offset] > sw) {
const float dx = xi - x;
const float dis = dx * dx + dy * dy;
mindist = min(mindist, dis);
}
- offset += 4;
-
+ offset ++;
}
}
pixelvalue = sqrtf(mindist);
@@ -206,14 +205,14 @@ void DilateDistanceOperation::executePixel(float output[4], int x, int y, void *
for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y;
- offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4;
+ offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
for (int xi = minx; xi < maxx; xi++) {
const float dx = xi - x;
const float dis = dx * dx + dy * dy;
if (dis <= mindist) {
value = max(buffer[offset], value);
}
- offset += 4;
+ offset ++;
}
}
output[0] = value;
@@ -280,14 +279,14 @@ void ErodeDistanceOperation::executePixel(float output[4], int x, int y, void *d
for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y;
- offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4;
+ offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
for (int xi = minx; xi < maxx; xi++) {
const float dx = xi - x;
const float dis = dx * dx + dy * dy;
if (dis <= mindist) {
value = min(buffer[offset], value);
}
- offset += 4;
+ offset ++;
}
}
output[0] = value;
@@ -383,7 +382,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect)
buf[x] = -FLT_MAX;
}
for (x = xmin; x < xmax; ++x) {
- buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)];
+ buf[x - rect->xmin + window - 1] = buffer[(y * width + x)];
}
for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
@@ -510,7 +509,7 @@ void *ErodeStepOperation::initializeTileData(rcti *rect)
buf[x] = FLT_MAX;
}
for (x = xmin; x < xmax; ++x) {
- buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)];
+ buf[x - rect->xmin + window - 1] = buffer[(y * width + x)];
}
for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
index 5006720f091..234a61a4c41 100644
--- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
+++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
@@ -1270,11 +1270,9 @@ void *DoubleEdgeMaskOperation::initializeTileData(rcti *rect)
MemoryBuffer *innerMask = (MemoryBuffer *)this->m_inputInnerMask->initializeTileData(rect);
MemoryBuffer *outerMask = (MemoryBuffer *)this->m_inputOuterMask->initializeTileData(rect);
float *data = (float *)MEM_mallocN(sizeof(float) * this->getWidth() * this->getHeight(), __func__);
- float *imask = innerMask->convertToValueBuffer();
- float *omask = outerMask->convertToValueBuffer();
+ float *imask = innerMask->getBuffer();
+ float *omask = outerMask->getBuffer();
doDoubleEdgeMask(imask, omask, data);
- MEM_freeN(imask);
- MEM_freeN(omask);
this->m_cachedInstance = data;
}
unlockMutex();
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
index 705a8c07381..08f520e4271 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
@@ -92,16 +92,16 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
this->m_sy = this->m_data.sizey * this->m_size / 2.0f;
if ((this->m_sx == this->m_sy) && (this->m_sx > 0.f)) {
- for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
+ for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sx, c, 3);
}
else {
if (this->m_sx > 0.0f) {
- for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
+ for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sx, c, 1);
}
if (this->m_sy > 0.0f) {
- for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
+ for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sy, c, 2);
}
}
@@ -120,6 +120,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign
unsigned int x, y, sz;
unsigned int i;
float *buffer = src->getBuffer();
+ const unsigned int num_channels = src->get_num_channels();
// <0.5 not valid, though can have a possibly useful sort of sharpening effect
if (sigma < 0.5f) return;
@@ -198,31 +199,31 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign
int offset;
for (y = 0; y < src_height; ++y) {
const int yx = y * src_width;
- offset = yx * COM_NUMBER_OF_CHANNELS + chan;
+ offset = yx * num_channels + chan;
for (x = 0; x < src_width; ++x) {
X[x] = buffer[offset];
- offset += COM_NUMBER_OF_CHANNELS;
+ offset += num_channels;
}
YVV(src_width);
- offset = yx * COM_NUMBER_OF_CHANNELS + chan;
+ offset = yx * num_channels + chan;
for (x = 0; x < src_width; ++x) {
buffer[offset] = Y[x];
- offset += COM_NUMBER_OF_CHANNELS;
+ offset += num_channels;
}
}
}
if (xy & 2) { // V
int offset;
- const int add = src_width * COM_NUMBER_OF_CHANNELS;
+ const int add = src_width * num_channels;
for (x = 0; x < src_width; ++x) {
- offset = x * COM_NUMBER_OF_CHANNELS + chan;
+ offset = x * num_channels + chan;
for (y = 0; y < src_height; ++y) {
X[y] = buffer[offset];
offset += add;
}
YVV(src_height);
- offset = x * COM_NUMBER_OF_CHANNELS + chan;
+ offset = x * num_channels + chan;
for (y = 0; y < src_height; ++y) {
buffer[offset] = Y[y];
offset += add;
@@ -298,7 +299,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
if (this->m_overlay == FAST_GAUSS_OVERLAY_MIN) {
float *src = newBuf->getBuffer();
float *dst = copy->getBuffer();
- for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUMBER_OF_CHANNELS, dst += COM_NUMBER_OF_CHANNELS) {
+ for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUM_CHANNELS_VALUE, dst += COM_NUM_CHANNELS_VALUE) {
if (*src < *dst) {
*dst = *src;
}
@@ -307,7 +308,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
else if (this->m_overlay == FAST_GAUSS_OVERLAY_MAX) {
float *src = newBuf->getBuffer();
float *dst = copy->getBuffer();
- for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUMBER_OF_CHANNELS, dst += COM_NUMBER_OF_CHANNELS) {
+ for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUM_CHANNELS_VALUE, dst += COM_NUM_CHANNELS_VALUE) {
if (*src > *dst) {
*dst = *src;
}
diff --git a/source/blender/compositor/operations/COM_FlipOperation.cpp b/source/blender/compositor/operations/COM_FlipOperation.cpp
index 3de2ae9dabc..7ff7d694fa8 100644
--- a/source/blender/compositor/operations/COM_FlipOperation.cpp
+++ b/source/blender/compositor/operations/COM_FlipOperation.cpp
@@ -44,8 +44,8 @@ void FlipOperation::deinitExecution()
void FlipOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- float nx = this->m_flipX ? this->getWidth() - 1 - x : x;
- float ny = this->m_flipY ? this->getHeight() - 1 - y : y;
+ float nx = this->m_flipX ? ((int)this->getWidth() - 1) - x : x;
+ float ny = this->m_flipY ? ((int)this->getHeight() - 1) - y : y;
this->m_inputOperation->readSampled(output, nx, ny, sampler);
}
@@ -55,16 +55,18 @@ bool FlipOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOper
rcti newInput;
if (this->m_flipX) {
- newInput.xmax = (this->getWidth() - 1 - input->xmin) + 1;
- newInput.xmin = (this->getWidth() - 1 - input->xmax) - 1;
+ const int w = (int)this->getWidth() - 1;
+ newInput.xmax = (w - input->xmin) + 1;
+ newInput.xmin = (w - input->xmax) - 1;
}
else {
newInput.xmin = input->xmin;
newInput.xmax = input->xmax;
}
if (this->m_flipY) {
- newInput.ymax = (this->getHeight() - 1 - input->ymin) + 1;
- newInput.ymin = (this->getHeight() - 1 - input->ymax) - 1;
+ const int h = (int)this->getHeight() - 1;
+ newInput.ymax = (h - input->ymin) + 1;
+ newInput.ymin = (h - input->ymax) - 1;
}
else {
newInput.ymin = input->ymin;
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
index c78347e7b1c..dde57ab640f 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
@@ -102,15 +102,14 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo
/* *** this is the main part which is different to 'GaussianXBlurOperation' *** */
int step = getStep();
- int offsetadd = getOffsetAdd();
- int bufferindex = ((xmin - bufferstartx) * 4) + ((ymin - bufferstarty) * 4 * bufferwidth);
+ int bufferindex = ((xmin - bufferstartx)) + ((ymin - bufferstarty) * bufferwidth);
/* gauss */
float alpha_accum = 0.0f;
float multiplier_accum = 0.0f;
/* dilate */
- float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
+ float value_max = finv_test(buffer[(x) + (y * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
float distfacinv_max = 1.0f; /* 0 to 1 */
for (int nx = xmin; nx < xmax; nx += step) {
@@ -134,7 +133,7 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo
distfacinv_max = multiplier;
}
}
- bufferindex += offsetadd;
+ bufferindex += step;
}
/* blend between the max value and gauss blue - gives nice feather */
diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
index ab97c8b0d13..bb5b3c044af 100644
--- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
@@ -108,11 +108,11 @@ void GaussianAlphaYBlurOperation::executePixel(float output[4], int x, int y, vo
float multiplier_accum = 0.0f;
/* dilate */
- float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
+ float value_max = finv_test(buffer[(x) + (y * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
float distfacinv_max = 1.0f; /* 0 to 1 */
for (int ny = ymin; ny < ymax; ny += step) {
- int bufferindex = ((xmin - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth);
+ int bufferindex = ((xmin - bufferstartx)) + ((ny - bufferstarty) * bufferwidth);
const int index = (ny - y) + this->m_filtersize;
float value = finv_test(buffer[bufferindex], do_invert);
diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
index 441b623b589..dbad51c4329 100644
--- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
@@ -296,7 +296,7 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
int minyr = y - refrady < 0 ? -y : -refrady;
int maxyr = y + refrady > imgy ? imgy - y : refrady;
- float *srcd = buffer + COM_NUMBER_OF_CHANNELS * ( (y + minyr) * imgx + x + minxr);
+ float *srcd = buffer + COM_NUM_CHANNELS_COLOR * ( (y + minyr) * imgx + x + minxr);
gausstabx = m_maintabs[refradx - 1];
gausstabcentx = gausstabx + refradx;
@@ -304,9 +304,9 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
gausstabcenty = gausstaby + refrady;
sum = gval = rval = bval = aval = 0.0f;
- for (i = minyr; i < maxyr; i++, srcd += COM_NUMBER_OF_CHANNELS * imgx) {
+ for (i = minyr; i < maxyr; i++, srcd += COM_NUM_CHANNELS_COLOR * imgx) {
src = srcd;
- for (j = minxr; j < maxxr; j++, src += COM_NUMBER_OF_CHANNELS) {
+ for (j = minxr; j < maxxr; j++, src += COM_NUM_CHANNELS_COLOR) {
val = gausstabcenty[i] * gausstabcentx[j];
sum += val;
diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp
index 99c745d7fb0..98919f1b161 100644
--- a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp
@@ -49,7 +49,7 @@ MemoryBuffer *GlareBaseOperation::createMemoryBuffer(rcti *rect2)
rect.ymin = 0;
rect.xmax = getWidth();
rect.ymax = getHeight();
- MemoryBuffer *result = new MemoryBuffer(NULL, &rect);
+ MemoryBuffer *result = new MemoryBuffer(COM_DT_COLOR, &rect);
float *data = result->getBuffer();
this->generateGlare(data, tile, this->m_settings);
return result;
diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
index 99a7c5b64c4..04993b08ddf 100644
--- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
@@ -259,8 +259,8 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
float *kernelBuffer = in2->getBuffer();
float *imageBuffer = in1->getBuffer();
- MemoryBuffer *rdst = new MemoryBuffer(NULL, in1->getRect());
- memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
+ MemoryBuffer *rdst = new MemoryBuffer(COM_DT_COLOR, in1->getRect());
+ memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float));
// convolution result width & height
w2 = 2 * kernelWidth - 1;
@@ -276,7 +276,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
// normalize convolutor
wt[0] = wt[1] = wt[2] = 0.f;
for (y = 0; y < kernelHeight; y++) {
- colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS];
+ colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUM_CHANNELS_COLOR];
for (x = 0; x < kernelWidth; x++)
add_v3_v3(wt, colp[x]);
}
@@ -284,7 +284,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
if (wt[1] != 0.f) wt[1] = 1.f / wt[1];
if (wt[2] != 0.f) wt[2] = 1.f / wt[2];
for (y = 0; y < kernelHeight; y++) {
- colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS];
+ colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUM_CHANNELS_COLOR];
for (x = 0; x < kernelWidth; x++)
mul_v3_v3(colp[x], wt);
}
@@ -313,7 +313,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
// in2, channel ch -> data1
for (y = 0; y < kernelHeight; y++) {
fp = &data1ch[y * w2];
- colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS];
+ colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUM_CHANNELS_COLOR];
for (x = 0; x < kernelWidth; x++)
fp[x] = colp[x][ch];
}
@@ -325,7 +325,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
int yy = ybl * ybsz + y;
if (yy >= imageHeight) continue;
fp = &data2[y * w2];
- colp = (fRGB *)&imageBuffer[yy * imageWidth * COM_NUMBER_OF_CHANNELS];
+ colp = (fRGB *)&imageBuffer[yy * imageWidth * COM_NUM_CHANNELS_COLOR];
for (x = 0; x < xbsz; x++) {
int xx = xbl * xbsz + x;
if (xx >= imageWidth) continue;
@@ -349,7 +349,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
const int yy = ybl * ybsz + y - hh;
if ((yy < 0) || (yy >= imageHeight)) continue;
fp = &data2[y * w2];
- colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NUMBER_OF_CHANNELS];
+ colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NUM_CHANNELS_COLOR];
for (x = 0; x < (int)w2; x++) {
const int xx = xbl * xbsz + x - hw;
if ((xx < 0) || (xx >= imageWidth)) continue;
@@ -364,7 +364,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
MEM_freeN(data2);
MEM_freeN(data1);
- memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NUMBER_OF_CHANNELS);
+ memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NUM_CHANNELS_COLOR);
delete(rdst);
}
@@ -381,7 +381,7 @@ void GlareFogGlowOperation::generateGlare(float *data, MemoryBuffer *inputTile,
// make the convolution kernel
rcti kernelRect;
BLI_rcti_init(&kernelRect, 0, sz, 0, sz);
- ckrn = new MemoryBuffer(NULL, &kernelRect);
+ ckrn = new MemoryBuffer(COM_DT_COLOR, &kernelRect);
scale = 0.25f * sqrtf((float)(sz * sz));
diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp
index 8854be52ded..69b5bd7d6bf 100644
--- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp
@@ -97,7 +97,7 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No
}
- memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
+ memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float));
for (n = 1; n < settings->iter && (!breaked); n++) {
for (y = 0; y < gbuf->getHeight() && (!breaked); y++) {
v = ((float)y + 0.5f) / (float)gbuf->getHeight();
@@ -117,9 +117,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No
}
if (isBreaked()) breaked = true;
}
- memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
+ memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth() * tbuf1->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float));
}
- memcpy(data, gbuf->getBuffer(), gbuf->getWidth() * gbuf->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
+ memcpy(data, gbuf->getBuffer(), gbuf->getWidth() * gbuf->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float));
delete gbuf;
delete tbuf1;
diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp
index 5644ff30ef3..deeb5094bd0 100644
--- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp
@@ -36,7 +36,7 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile,
bool breaked = false;
MemoryBuffer *tsrc = inputTile->duplicate();
- MemoryBuffer *tdst = new MemoryBuffer(NULL, inputTile->getRect());
+ MemoryBuffer *tdst = new MemoryBuffer(COM_DT_COLOR, inputTile->getRect());
tdst->clear();
memset(data, 0, size4 * sizeof(float));
diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cpp b/source/blender/compositor/operations/COM_InpaintOperation.cpp
index b64c98be0c7..18611c051d3 100644
--- a/source/blender/compositor/operations/COM_InpaintOperation.cpp
+++ b/source/blender/compositor/operations/COM_InpaintOperation.cpp
@@ -83,8 +83,8 @@ float *InpaintSimpleOperation::get_pixel(int x, int y)
ASSERT_XY_RANGE(x, y);
return &this->m_cached_buffer[
- y * width * COM_NUMBER_OF_CHANNELS +
- x * COM_NUMBER_OF_CHANNELS];
+ y * width * COM_NUM_CHANNELS_COLOR +
+ x * COM_NUM_CHANNELS_COLOR];
}
int InpaintSimpleOperation::mdist(int x, int y)
diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp
index ddc09ecb483..72c7512cb23 100644
--- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp
@@ -58,7 +58,7 @@ void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data
const int start = max(0, x - this->m_size + 1),
end = min(bufferWidth, x + this->m_size);
for (int cx = start; cx < end; ++cx) {
- int bufferIndex = (y * bufferWidth + cx) * 4;
+ int bufferIndex = (y * bufferWidth + cx);
average += buffer[bufferIndex];
count++;
}
@@ -67,7 +67,7 @@ void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data
const int start = max(0, y - this->m_size + 1),
end = min(inputBuffer->getHeight(), y + this->m_size);
for (int cy = start; cy < end; ++cy) {
- int bufferIndex = (cy * bufferWidth + x) * 4;
+ int bufferIndex = (cy * bufferWidth + x);
average += buffer[bufferIndex];
count++;
}
diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp
index d9eb7b588a8..d4ba94f240f 100644
--- a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp
+++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp
@@ -62,7 +62,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data
int bufferWidth = inputBuffer->getWidth();
int bufferHeight = inputBuffer->getHeight();
- float value = buffer[(y * bufferWidth + x) * 4];
+ float value = buffer[(y * bufferWidth + x)];
bool ok = false;
int start_x = max_ff(0, x - delta + 1),
@@ -83,7 +83,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data
continue;
}
- int bufferIndex = (cy * bufferWidth + cx) * 4;
+ int bufferIndex = (cy * bufferWidth + cx);
float currentValue = buffer[bufferIndex];
if (fabsf(currentValue - value) < tolerance) {
diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp
index 6bf730253e7..bb8fe825c68 100644
--- a/source/blender/compositor/operations/COM_MapUVOperation.cpp
+++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp
@@ -83,11 +83,11 @@ bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_
return false;
}
else {
- float col[4];
- m_inputUVProgram->readSampled(col, x, y, COM_PS_BILINEAR);
- r_u = col[0] * m_inputColorProgram->getWidth();
- r_v = col[1] * m_inputColorProgram->getHeight();
- r_alpha = col[2];
+ float vector[3];
+ m_inputUVProgram->readSampled(vector, x, y, COM_PS_BILINEAR);
+ r_u = vector[0] * m_inputColorProgram->getWidth();
+ r_v = vector[1] * m_inputColorProgram->getHeight();
+ r_alpha = vector[2];
return true;
}
}
diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp
index 9a184ae1216..133b6d520eb 100644
--- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp
+++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp
@@ -124,9 +124,7 @@ MovieClipAlphaOperation::MovieClipAlphaOperation() : MovieClipBaseOperation()
void MovieClipAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- MovieClipBaseOperation::executePixelSampled(output, x, y, sampler);
- output[0] = output[3];
- output[1] = 0.0f;
- output[2] = 0.0f;
- output[3] = 0.0f;
+ float result[4];
+ MovieClipBaseOperation::executePixelSampled(result, x, y, sampler);
+ output[0] = result[3];
}
diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cpp b/source/blender/compositor/operations/COM_NormalizeOperation.cpp
index f81b50e6836..e0b5893ffbb 100644
--- a/source/blender/compositor/operations/COM_NormalizeOperation.cpp
+++ b/source/blender/compositor/operations/COM_NormalizeOperation.cpp
@@ -104,7 +104,7 @@ void *NormalizeOperation::initializeTileData(rcti *rect)
if ((value < minv) && (value >= -BLENDER_ZMAX)) {
minv = value;
}
- bc += 4;
+ bc ++;
}
minmult->x = minv;
diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl
index 1b965eb8659..cbd05cbec17 100644
--- a/source/blender/compositor/operations/COM_OpenCLKernels.cl
+++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl
@@ -80,10 +80,10 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima
}
//KERNEL --- DEFOCUS /VARIABLESIZEBOKEHBLUR ---
-__kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2d_t bokehImage,
- __read_only image2d_t inputSize,
- __write_only image2d_t output, int2 offsetInput, int2 offsetOutput,
- int step, int maxBlurScalar, float threshold, float scalar, int2 dimension, int2 offset)
+__kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2d_t bokehImage,
+ __read_only image2d_t inputSize,
+ __write_only image2d_t output, int2 offsetInput, int2 offsetOutput,
+ int step, int maxBlurScalar, float threshold, float scalar, int2 dimension, int2 offset)
{
float4 color = {1.0f, 0.0f, 0.0f, 1.0f};
int2 coords = {get_global_id(0), get_global_id(1)};
@@ -212,8 +212,8 @@ __kernel void erodeKernel(__read_only image2d_t inputImage, __write_only image2
// KERNEL --- DIRECTIONAL BLUR ---
__kernel void directionalBlurKernel(__read_only image2d_t inputImage, __write_only image2d_t output,
- int2 offsetOutput, int iterations, float scale, float rotation, float2 translate,
- float2 center, int2 offset)
+ int2 offsetOutput, int iterations, float scale, float rotation, float2 translate,
+ float2 center, int2 offset)
{
int2 coords = {get_global_id(0), get_global_id(1)};
coords += offset;
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index 92e8f309ea1..2f92351c00d 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -140,8 +140,9 @@ void OutputSingleLayerOperation::deinitExecution()
IMB_colormanagement_imbuf_for_write(ibuf, true, false, m_viewSettings, m_displaySettings,
this->m_format);
- BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra,
- this->m_format, (this->m_rd->scemode & R_EXTENSION) != 0, true);
+ BKE_image_path_from_imformat(
+ filename, this->m_path, bmain->name, this->m_rd->cfra,
+ this->m_format, (this->m_rd->scemode & R_EXTENSION) != 0, true);
if (0 == BKE_imbuf_write(ibuf, filename, this->m_format))
printf("Cannot save Node File Output to %s\n", filename);
@@ -211,8 +212,9 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
char filename[FILE_MAX];
void *exrhandle = IMB_exr_get_handle();
- BKE_makepicstring_from_type(filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
- (this->m_rd->scemode & R_EXTENSION) != 0, true);
+ BKE_image_path_from_imtype(
+ filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
+ (this->m_rd->scemode & R_EXTENSION) != 0, true);
BLI_make_existing_file(filename);
for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
index fe272000b6e..fb8730c9fa0 100644
--- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
@@ -135,7 +135,7 @@ void *PlaneCornerPinMaskOperation::initializeTileData(rcti *rect)
getInputSocketReader(3) };
float corners[4][2];
readCornersFromSockets(rect, readers, corners);
- calculateCorners(corners, true);
+ calculateCorners(corners, true, 0);
m_corners_ready = true;
}
@@ -194,8 +194,7 @@ void *PlaneCornerPinWarpImageOperation::initializeTileData(rcti *rect)
getInputSocketReader(4) };
float corners[4][2];
readCornersFromSockets(rect, readers, corners);
- calculateCorners(corners, true);
- calculatePerspectiveMatrix();
+ calculateCorners(corners, true, 0);
m_corners_ready = true;
}
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
index c507b4cfa98..8133f392ac6 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp
@@ -56,36 +56,38 @@ PlaneDistortWarpImageOperation::PlaneDistortWarpImageOperation() :
this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE);
this->addOutputSocket(COM_DT_COLOR);
this->m_pixelReader = NULL;
+ this->m_motion_blur_samples = 1;
+ this->m_motion_blur_shutter = 0.5f;
this->setComplex(true);
}
-void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2], bool normalized)
+void PlaneDistortWarpImageOperation::calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample)
{
+ BLI_assert(sample < this->m_motion_blur_samples);
+ const int width = this->m_pixelReader->getWidth();
+ const int height = this->m_pixelReader->getHeight();
+ float frame_corners[4][2] = {{0.0f, 0.0f},
+ {(float) width, 0.0f},
+ {(float) width, (float) height},
+ {0.0f, (float) height}};
+ MotionSample *sample_data = &this->m_samples[sample];
if (normalized) {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
- this->m_frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
+ sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
+ sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
}
}
else {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0];
- this->m_frameSpaceCorners[i][1] = corners[i][1];
+ sample_data->frameSpaceCorners[i][0] = corners[i][0];
+ sample_data->frameSpaceCorners[i][1] = corners[i][1];
}
}
-}
-
-void PlaneDistortWarpImageOperation::calculatePerspectiveMatrix()
-{
- const int width = this->m_pixelReader->getWidth();
- const int height = this->m_pixelReader->getHeight();
- float frame_corners[4][2] = {{0.0f, 0.0f},
- {(float) width, 0.0f},
- {(float) width, (float) height},
- {0.0f, (float) height}};
- BKE_tracking_homography_between_two_quads(this->m_frameSpaceCorners,
+ BKE_tracking_homography_between_two_quads(sample_data->frameSpaceCorners,
frame_corners,
- this->m_perspectiveMatrix);
+ sample_data->perspectiveMatrix);
}
void PlaneDistortWarpImageOperation::initExecution()
@@ -100,35 +102,47 @@ void PlaneDistortWarpImageOperation::deinitExecution()
void PlaneDistortWarpImageOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- float xy[2] = {x, y};
float uv[2];
float deriv[2][2];
-
- pixelTransform(xy, uv, deriv);
-
- m_pixelReader->readFiltered(output, uv[0], uv[1], deriv[0], deriv[1], COM_PS_BILINEAR);
-}
-
-void PlaneDistortWarpImageOperation::pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2])
-{
- warpCoord(xy[0], xy[1], m_perspectiveMatrix, r_uv, r_deriv);
+ if (this->m_motion_blur_samples == 1) {
+ warpCoord(x, y, this->m_samples[0].perspectiveMatrix, uv, deriv);
+ m_pixelReader->readFiltered(output,
+ uv[0], uv[1],
+ deriv[0], deriv[1],
+ COM_PS_BILINEAR);
+ }
+ else {
+ zero_v4(output);
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ float color[4];
+ warpCoord(x, y, this->m_samples[sample].perspectiveMatrix, uv, deriv);
+ m_pixelReader->readFiltered(color,
+ uv[0], uv[1],
+ deriv[0], deriv[1],
+ COM_PS_BILINEAR);
+ add_v4_v4(output, color);
+ }
+ mul_v4_fl(output, 1.0f / (float)this->m_motion_blur_samples);
+ }
}
bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
{
- float UVs[4][2];
- float deriv[2][2];
-
- /* TODO(sergey): figure out proper way to do this. */
- warpCoord(input->xmin - 2, input->ymin - 2, this->m_perspectiveMatrix, UVs[0], deriv);
- warpCoord(input->xmax + 2, input->ymin - 2, this->m_perspectiveMatrix, UVs[1], deriv);
- warpCoord(input->xmax + 2, input->ymax + 2, this->m_perspectiveMatrix, UVs[2], deriv);
- warpCoord(input->xmin - 2, input->ymax + 2, this->m_perspectiveMatrix, UVs[3], deriv);
-
float min[2], max[2];
INIT_MINMAX2(min, max);
- for (int i = 0; i < 4; i++) {
- minmax_v2v2_v2(min, max, UVs[i]);
+
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ float UVs[4][2];
+ float deriv[2][2];
+ MotionSample *sample_data = &this->m_samples[sample];
+ /* TODO(sergey): figure out proper way to do this. */
+ warpCoord(input->xmin - 2, input->ymin - 2, sample_data->perspectiveMatrix, UVs[0], deriv);
+ warpCoord(input->xmax + 2, input->ymin - 2, sample_data->perspectiveMatrix, UVs[1], deriv);
+ warpCoord(input->xmax + 2, input->ymax + 2, sample_data->perspectiveMatrix, UVs[2], deriv);
+ warpCoord(input->xmin - 2, input->ymax + 2, sample_data->perspectiveMatrix, UVs[3], deriv);
+ for (int i = 0; i < 4; i++) {
+ minmax_v2v2_v2(min, max, UVs[i]);
+ }
}
rcti newInput;
@@ -151,20 +165,26 @@ PlaneDistortMaskOperation::PlaneDistortMaskOperation() :
/* Currently hardcoded to 8 samples. */
m_osa = 8;
+ this->m_motion_blur_samples = 1;
+ this->m_motion_blur_shutter = 0.5f;
}
-void PlaneDistortMaskOperation::calculateCorners(const float corners[4][2], bool normalized)
+void PlaneDistortMaskOperation::calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample)
{
+ BLI_assert(sample < this->m_motion_blur_samples);
+ MotionSample *sample_data = &this->m_samples[sample];
if (normalized) {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
- this->m_frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
+ sample_data->frameSpaceCorners[i][0] = corners[i][0] * this->getWidth();
+ sample_data->frameSpaceCorners[i][1] = corners[i][1] * this->getHeight();
}
}
else {
for (int i = 0; i < 4; i++) {
- this->m_frameSpaceCorners[i][0] = corners[i][0];
- this->m_frameSpaceCorners[i][1] = corners[i][1];
+ sample_data->frameSpaceCorners[i][0] = corners[i][0];
+ sample_data->frameSpaceCorners[i][1] = corners[i][1];
}
}
}
@@ -177,18 +197,44 @@ void PlaneDistortMaskOperation::initExecution()
void PlaneDistortMaskOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
float point[2];
-
int inside_counter = 0;
- for (int sample = 0; sample < this->m_osa; sample++) {
- point[0] = x + this->m_jitter[sample][0];
- point[1] = y + this->m_jitter[sample][1];
-
- if (isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[1], this->m_frameSpaceCorners[2]) ||
- isect_point_tri_v2(point, this->m_frameSpaceCorners[0], this->m_frameSpaceCorners[2], this->m_frameSpaceCorners[3]))
+ if (this->m_motion_blur_samples == 1) {
+ MotionSample *sample_data = &this->m_samples[0];
+ for (int sample = 0; sample < this->m_osa; sample++) {
+ point[0] = x + this->m_jitter[sample][0];
+ point[1] = y + this->m_jitter[sample][1];
+ if (isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[1],
+ sample_data->frameSpaceCorners[2]) ||
+ isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[2],
+ sample_data->frameSpaceCorners[3]))
+ {
+ inside_counter++;
+ }
+ }
+ output[0] = (float)inside_counter / this->m_osa;
+ }
+ else {
+ for (int motion_sample = 0;
+ motion_sample < this->m_motion_blur_samples;
+ ++motion_sample)
{
- inside_counter++;
+ MotionSample *sample_data = &this->m_samples[motion_sample];
+ for (int osa_sample = 0; osa_sample < this->m_osa; ++osa_sample) {
+ point[0] = x + this->m_jitter[osa_sample][0];
+ point[1] = y + this->m_jitter[osa_sample][1];
+ if (isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[1],
+ sample_data->frameSpaceCorners[2]) ||
+ isect_point_tri_v2(point, sample_data->frameSpaceCorners[0],
+ sample_data->frameSpaceCorners[2],
+ sample_data->frameSpaceCorners[3]))
+ {
+ inside_counter++;
+ }
+ }
}
+ output[0] = (float)inside_counter / (this->m_osa * this->m_motion_blur_samples);
}
-
- output[0] = (float) inside_counter / this->m_osa;
}
diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
index ee2874c6b46..fc5dd1ff7d8 100644
--- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.h
@@ -33,43 +33,72 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
+#define PLANE_DISTORT_MAX_SAMPLES 64
class PlaneDistortWarpImageOperation : public NodeOperation {
protected:
+ struct MotionSample {
+ float frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
+ float perspectiveMatrix[3][3];
+ };
SocketReader *m_pixelReader;
- float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
- float m_perspectiveMatrix[3][3];
+ MotionSample m_samples[PLANE_DISTORT_MAX_SAMPLES];
+ int m_motion_blur_samples;
+ float m_motion_blur_shutter;
public:
PlaneDistortWarpImageOperation();
- void calculateCorners(const float corners[4][2], bool normalized);
- void calculatePerspectiveMatrix();
+ void calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample);
void initExecution();
void deinitExecution();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
- void pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2]);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
+ void setMotionBlurSamples(int samples) {
+ BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES);
+ this->m_motion_blur_samples = samples;
+ }
+ void setMotionBlurShutter(float shutter) {
+ this->m_motion_blur_shutter = shutter;
+ }
};
class PlaneDistortMaskOperation : public NodeOperation {
protected:
+ struct MotionSample {
+ float frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
+ };
int m_osa;
+ MotionSample m_samples[PLANE_DISTORT_MAX_SAMPLES];
float m_jitter[32][2];
- float m_frameSpaceCorners[4][2]; /* Corners coordinates in pixel space. */
+ int m_motion_blur_samples;
+ float m_motion_blur_shutter;
public:
PlaneDistortMaskOperation();
-
- void calculateCorners(const float corners[4][2], bool normalized);
-
+
+ void calculateCorners(const float corners[4][2],
+ bool normalized,
+ int sample);
+
void initExecution();
-
+
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+
+ void setMotionBlurSamples(int samples) {
+ BLI_assert(samples <= PLANE_DISTORT_MAX_SAMPLES);
+ this->m_motion_blur_samples = samples;
+ }
+ void setMotionBlurShutter(float shutter) {
+ this->m_motion_blur_shutter = shutter;
+ }
};
#endif
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
index fec39cbfde0..03205130a74 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
@@ -46,31 +46,27 @@ PlaneTrackCommon::PlaneTrackCommon()
this->m_planeTrackName[0] = '\0';
}
-void PlaneTrackCommon::readCornersFromTrack(float corners[4][2])
+void PlaneTrackCommon::readCornersFromTrack(float corners[4][2], float frame)
{
MovieTracking *tracking;
MovieTrackingObject *object;
if (!this->m_movieClip)
return;
-
+
tracking = &this->m_movieClip->tracking;
-
+
object = BKE_tracking_object_get_named(tracking, this->m_trackingObjectName);
if (object) {
MovieTrackingPlaneTrack *plane_track;
-
plane_track = BKE_tracking_plane_track_get_named(tracking, object, this->m_planeTrackName);
-
if (plane_track) {
- MovieTrackingPlaneMarker *plane_marker;
- int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber);
-
- plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr);
- copy_v2_v2(corners[0], plane_marker->corners[0]);
- copy_v2_v2(corners[1], plane_marker->corners[1]);
- copy_v2_v2(corners[2], plane_marker->corners[2]);
- copy_v2_v2(corners[3], plane_marker->corners[3]);
+ float clip_framenr =
+ BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip,
+ frame);
+ BKE_tracking_plane_marker_get_subframe_corners(plane_track,
+ clip_framenr,
+ corners);
}
}
}
@@ -79,14 +75,12 @@ void PlaneTrackCommon::determineResolution(unsigned int resolution[2], unsigned
{
resolution[0] = 0;
resolution[1] = 0;
-
+
if (this->m_movieClip) {
int width, height;
MovieClipUser user = {0};
-
BKE_movieclip_user_set_frame(&user, this->m_framenumber);
BKE_movieclip_get_size(this->m_movieClip, &user, &width, &height);
-
resolution[0] = width;
resolution[1] = height;
}
@@ -98,10 +92,21 @@ void PlaneTrackCommon::determineResolution(unsigned int resolution[2], unsigned
void PlaneTrackMaskOperation::initExecution()
{
PlaneDistortMaskOperation::initExecution();
-
float corners[4][2];
- readCornersFromTrack(corners);
- calculateCorners(corners, true);
+ if (this->m_motion_blur_samples == 1) {
+ readCornersFromTrack(corners, this->m_framenumber);
+ calculateCorners(corners, true, 0);
+ }
+ else {
+ const float frame = (float)this->m_framenumber - this->m_motion_blur_shutter;
+ const float frame_step = (this->m_motion_blur_shutter * 2.0f) / this->m_motion_blur_samples;
+ float frame_iter = frame;
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ readCornersFromTrack(corners, frame_iter);
+ calculateCorners(corners, true, sample);
+ frame_iter += frame_step;
+ }
+ }
}
/* ******** PlaneTrackWarpImageOperation ******** */
@@ -109,9 +114,20 @@ void PlaneTrackMaskOperation::initExecution()
void PlaneTrackWarpImageOperation::initExecution()
{
PlaneDistortWarpImageOperation::initExecution();
-
+ /* TODO(sergey): De-duplicate with mask operation. */
float corners[4][2];
- readCornersFromTrack(corners);
- calculateCorners(corners, true);
- calculatePerspectiveMatrix();
+ if (this->m_motion_blur_samples == 1) {
+ readCornersFromTrack(corners, this->m_framenumber);
+ calculateCorners(corners, true, 0);
+ }
+ else {
+ const float frame = (float)this->m_framenumber - this->m_motion_blur_shutter;
+ const float frame_step = (this->m_motion_blur_shutter * 2.0f) / this->m_motion_blur_samples;
+ float frame_iter = frame;
+ for (int sample = 0; sample < this->m_motion_blur_samples; ++sample) {
+ readCornersFromTrack(corners, frame_iter);
+ calculateCorners(corners, true, sample);
+ frame_iter += frame_step;
+ }
+ }
}
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
index 3c5dd783542..41761493e12 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.h
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.h
@@ -43,7 +43,7 @@ protected:
/* note: this class is not an operation itself (to prevent virtual inheritance issues)
* implementation classes must make wrappers to use these methods, see below.
*/
- void readCornersFromTrack(float corners[4][2]);
+ void readCornersFromTrack(float corners[4][2], float frame);
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
public:
@@ -68,7 +68,7 @@ public:
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
{
PlaneTrackCommon::determineResolution(resolution, preferredResolution);
-
+
unsigned int temp[2];
NodeOperation::determineResolution(temp, resolution);
}
@@ -81,13 +81,12 @@ public:
PlaneDistortWarpImageOperation(),
PlaneTrackCommon()
{}
-
+
void initExecution();
-
+
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
{
PlaneTrackCommon::determineResolution(resolution, preferredResolution);
-
unsigned int temp[2];
NodeOperation::determineResolution(temp, resolution);
}
diff --git a/source/blender/compositor/operations/COM_QualityStepHelper.cpp b/source/blender/compositor/operations/COM_QualityStepHelper.cpp
index d99d6f28eff..4d9c15f9747 100644
--- a/source/blender/compositor/operations/COM_QualityStepHelper.cpp
+++ b/source/blender/compositor/operations/COM_QualityStepHelper.cpp
@@ -37,15 +37,15 @@ void QualityStepHelper::initExecution(QualityHelper helper)
case COM_QUALITY_HIGH:
default:
this->m_step = 1;
- this->m_offsetadd = 4;
+ this->m_offsetadd = 1;
break;
case COM_QUALITY_MEDIUM:
this->m_step = 2;
- this->m_offsetadd = 8;
+ this->m_offsetadd = 2;
break;
case COM_QUALITY_LOW:
this->m_step = 3;
- this->m_offsetadd = 12;
+ this->m_offsetadd = 3;
break;
}
break;
diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp
index 47d5fc6bcca..ad4084a7092 100644
--- a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp
+++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp
@@ -24,9 +24,9 @@
#include "COM_WriteBufferOperation.h"
#include "COM_defines.h"
-ReadBufferOperation::ReadBufferOperation() : NodeOperation()
+ReadBufferOperation::ReadBufferOperation(DataType datatype) : NodeOperation()
{
- this->addOutputSocket(COM_DT_COLOR);
+ this->addOutputSocket(datatype);
this->m_single_value = false;
this->m_offset = 0;
this->m_buffer = NULL;
@@ -58,11 +58,19 @@ void ReadBufferOperation::executePixelSampled(float output[4], float x, float y,
/* write buffer has a single value stored at (0,0) */
m_buffer->read(output, 0, 0);
}
- else if (sampler == COM_PS_NEAREST) {
- m_buffer->read(output, x, y);
- }
else {
- m_buffer->readBilinear(output, x, y);
+ switch (sampler) {
+ case COM_PS_NEAREST:
+ m_buffer->read(output, x, y);
+ break;
+ case COM_PS_BILINEAR:
+ default:
+ m_buffer->readBilinear(output, x, y);
+ break;
+ case COM_PS_BICUBIC:
+ m_buffer->readBilinear(output, x, y);
+ break;
+ }
}
}
diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.h b/source/blender/compositor/operations/COM_ReadBufferOperation.h
index 569920d51ef..7e5bc55a8ca 100644
--- a/source/blender/compositor/operations/COM_ReadBufferOperation.h
+++ b/source/blender/compositor/operations/COM_ReadBufferOperation.h
@@ -25,6 +25,7 @@
#include "COM_NodeOperation.h"
#include "COM_MemoryProxy.h"
+#include "COM_MemoryBuffer.h"
class ReadBufferOperation : public NodeOperation {
private:
@@ -33,7 +34,7 @@ private:
unsigned int m_offset;
MemoryBuffer *m_buffer;
public:
- ReadBufferOperation();
+ ReadBufferOperation(DataType datetype);
void setMemoryProxy(MemoryProxy *memoryProxy) { this->m_memoryProxy = memoryProxy; }
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cpp b/source/blender/compositor/operations/COM_RenderLayersProg.cpp
index 06f4f6d77cf..409fa68bacf 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.cpp
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.cpp
@@ -111,15 +111,6 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
BLI_bicubic_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
break;
}
-
- if (this->m_elementsize == 1) {
- output[1] = 0.0f;
- output[2] = 0.0f;
- output[3] = 0.0f;
- }
- else if (this->m_elementsize == 3) {
- output[3] = 1.0f;
- }
}
void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
@@ -144,8 +135,39 @@ void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y
int iy = y - dy;
#endif
+#ifndef NDEBUG
+ {
+ const DataType data_type = this->getOutputSocket()->getDataType();
+ int actual_element_size = this->m_elementsize;
+ int expected_element_size;
+ if (data_type == COM_DT_VALUE) {
+ expected_element_size = 1;
+ }
+ else if (data_type == COM_DT_VECTOR) {
+ expected_element_size = 3;
+ }
+ else if (data_type == COM_DT_COLOR) {
+ expected_element_size = 4;
+ }
+ else {
+ BLI_assert(!"Something horribly wrong just happened");
+ }
+ BLI_assert(expected_element_size == actual_element_size);
+ }
+#endif
+
if (this->m_inputBuffer == NULL) {
- zero_v4(output);
+ int elemsize = this->m_elementsize;
+ if (elemsize == 1) {
+ output[0] = 0.0f;
+ }
+ else if (elemsize == 3) {
+ zero_v3(output);
+ }
+ else {
+ BLI_assert(elemsize == 4);
+ zero_v4(output);
+ }
}
else {
doInterpolation(output, x, y, sampler);
@@ -192,6 +214,19 @@ RenderLayersAOOperation::RenderLayersAOOperation() : RenderLayersBaseProg(SCE_PA
this->addOutputSocket(COM_DT_COLOR);
}
+
+void RenderLayersAOOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+{
+ float *inputBuffer = this->getInputBuffer();
+ if (inputBuffer == NULL) {
+ zero_v3(output);
+ }
+ else {
+ doInterpolation(output, x, y, sampler);
+ }
+ output[3] = 1.0f;
+}
+
/* ******** Render Layers Alpha Operation ******** */
RenderLayersAlphaProg::RenderLayersAlphaProg() : RenderLayersBaseProg(SCE_PASS_COMBINED, 4)
@@ -204,15 +239,12 @@ void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float
float *inputBuffer = this->getInputBuffer();
if (inputBuffer == NULL) {
- zero_v4(output);
+ output[0] = 0.0f;
}
else {
float temp[4];
doInterpolation(temp, x, y, sampler);
output[0] = temp[3];
- output[1] = 0.0f;
- output[2] = 0.0f;
- output[3] = 0.0f;
}
}
@@ -227,7 +259,7 @@ RenderLayersColorOperation::RenderLayersColorOperation() : RenderLayersBaseProg(
RenderLayersCyclesOperation::RenderLayersCyclesOperation(int pass) : RenderLayersBaseProg(pass, 3)
{
- this->addOutputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_VECTOR);
}
/* ******** Render Layers Depth Operation ******** */
@@ -245,16 +277,10 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float
if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
output[0] = 0.0f;
- output[1] = 0.0f;
- output[2] = 0.0f;
- output[3] = 0.0f;
}
else {
unsigned int offset = (iy * this->getWidth() + ix);
output[0] = inputBuffer[offset];
- output[1] = 0.0f;
- output[2] = 0.0f;
- output[3] = 0.0f;
}
}
@@ -262,21 +288,21 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float
RenderLayersDiffuseOperation::RenderLayersDiffuseOperation() : RenderLayersBaseProg(SCE_PASS_DIFFUSE, 3)
{
- this->addOutputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_VECTOR);
}
/* ******** Render Layers Emit Operation ******** */
RenderLayersEmitOperation::RenderLayersEmitOperation() : RenderLayersBaseProg(SCE_PASS_EMIT, 3)
{
- this->addOutputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_VECTOR);
}
/* ******** Render Layers Environment Operation ******** */
RenderLayersEnvironmentOperation::RenderLayersEnvironmentOperation() : RenderLayersBaseProg(SCE_PASS_ENVIRONMENT, 3)
{
- this->addOutputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_VECTOR);
}
/* ******** Render Layers Image Operation ******** */
@@ -290,7 +316,7 @@ RenderLayersColorProg::RenderLayersColorProg() : RenderLayersBaseProg(SCE_PASS_C
RenderLayersIndirectOperation::RenderLayersIndirectOperation() : RenderLayersBaseProg(SCE_PASS_INDIRECT, 3)
{
- this->addOutputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_VECTOR);
}
/* ******** Render Layers Material Index Operation ******** */
@@ -325,28 +351,28 @@ RenderLayersObjectIndexOperation::RenderLayersObjectIndexOperation() : RenderLay
RenderLayersReflectionOperation::RenderLayersReflectionOperation() : RenderLayersBaseProg(SCE_PASS_REFLECT, 3)
{
- this->addOutputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_VECTOR);
}
/* ******** Render Layers Refraction Operation ******** */
RenderLayersRefractionOperation::RenderLayersRefractionOperation() : RenderLayersBaseProg(SCE_PASS_REFRACT, 3)
{
- this->addOutputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_VECTOR);
}
/* ******** Render Layers Shadow Operation ******** */
RenderLayersShadowOperation::RenderLayersShadowOperation() : RenderLayersBaseProg(SCE_PASS_SHADOW, 3)
{
- this->addOutputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_VECTOR);
}
/* ******** Render Layers Specular Operation ******** */
RenderLayersSpecularOperation::RenderLayersSpecularOperation() : RenderLayersBaseProg(SCE_PASS_SPEC, 3)
{
- this->addOutputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_VECTOR);
}
/* ******** Render Layers Speed Operation ******** */
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h
index 554e27eb579..f73d9de3e27 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.h
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.h
@@ -105,6 +105,7 @@ public:
class RenderLayersAOOperation : public RenderLayersBaseProg {
public:
RenderLayersAOOperation();
+ void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
class RenderLayersAlphaProg : public RenderLayersBaseProg {
diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.cpp b/source/blender/compositor/operations/COM_SetVectorOperation.cpp
index 17212d78e15..769eaf1d2ed 100644
--- a/source/blender/compositor/operations/COM_SetVectorOperation.cpp
+++ b/source/blender/compositor/operations/COM_SetVectorOperation.cpp
@@ -33,7 +33,6 @@ void SetVectorOperation::executePixelSampled(float output[4], float x, float y,
output[0] = this->m_x;
output[1] = this->m_y;
output[2] = this->m_z;
- output[3] = this->m_w;
}
void SetVectorOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
index bcef652a8b5..0ca687ea162 100644
--- a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
+++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
@@ -50,34 +50,52 @@ void SunBeamsOperation::initExecution()
* For a target point (x,y) the sector should be chosen such that
* ``u >= v >= 0``
* This removes the need to handle all sorts of special cases.
+ *
+ * Template parameters:
+ * fxu : buffer increment in x for sector u+1
+ * fxv : buffer increment in x for sector v+1
+ * fyu : buffer increment in y for sector u+1
+ * fyv : buffer increment in y for sector v+1
*/
-template <int fxx, int fxy, int fyx, int fyy>
+template <int fxu, int fxv, int fyu, int fyv>
struct BufferLineAccumulator {
/* utility functions implementing the matrix transform to/from sector space */
-
- static inline void buffer_to_sector(int x, int y, int &u, int &v)
+
+ static inline void buffer_to_sector(const float source[2], int x, int y, int &u, int &v)
{
- u = x * fxx + y * fyx;
- v = x * fxy + y * fyy;
+ int x0 = (int)source[0];
+ int y0 = (int)source[1];
+ x -= x0;
+ y -= y0;
+ u = x * fxu + y * fyu;
+ v = x * fxv + y * fyv;
}
- static inline void buffer_to_sector(float x, float y, float &u, float &v)
+ static inline void buffer_to_sector(const float source[2], float x, float y, float &u, float &v)
{
- u = x * fxx + y * fyx;
- v = x * fxy + y * fyy;
+ int x0 = (int)source[0];
+ int y0 = (int)source[1];
+ x -= (float)x0;
+ y -= (float)y0;
+ u = x * fxu + y * fyu;
+ v = x * fxv + y * fyv;
}
- static inline void sector_to_buffer(int u, int v, int &x, int &y)
+ static inline void sector_to_buffer(const float source[2], int u, int v, int &x, int &y)
{
- x = u * fxx + v * fxy;
- y = u * fyx + v * fyy;
+ int x0 = (int)source[0];
+ int y0 = (int)source[1];
+ x = x0 + u * fxu + v * fxv;
+ y = y0 + u * fyu + v * fyv;
}
- static inline void sector_to_buffer(float u, float v, float &x, float &y)
+ static inline void sector_to_buffer(const float source[2], float u, float v, float &x, float &y)
{
- x = u * fxx + v * fxy;
- y = u * fyx + v * fyy;
+ int x0 = (int)source[0];
+ int y0 = (int)source[1];
+ x = (float)x0 + u * fxu + v * fxv;
+ y = (float)y0 + u * fyu + v * fyv;
}
/**
@@ -91,12 +109,12 @@ struct BufferLineAccumulator {
* \param num Total steps in the loop
* \param v, dv Vertical offset in sector space, for line offset perpendicular to the loop axis
*/
- static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float pt_ofs[2],
+ static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float co[2],
float dist_min, float dist_max,
int &x, int &y, int &num, float &v, float &dv, float &falloff_factor)
{
float pu, pv;
- buffer_to_sector(pt_ofs[0], pt_ofs[1], pu, pv);
+ buffer_to_sector(source, co[0], co[1], pu, pv);
/* line angle */
float tan_phi = pv / pu;
@@ -113,13 +131,11 @@ struct BufferLineAccumulator {
int end = (int)ceilf(umin);
num = end - start;
- sector_to_buffer(end, (int)ceilf(v), x, y);
- x += (int)source[0];
- y += (int)source[1];
+ sector_to_buffer(source, end, (int)ceilf(v), x, y);
falloff_factor = dist_max > dist_min ? dr / (float)(dist_max - dist_min) : 0.0f;
- float *iter = input->getBuffer() + COM_NUMBER_OF_CHANNELS * (x + input->getWidth() * y);
+ float *iter = input->getBuffer() + COM_NUM_CHANNELS_COLOR * (x + input->getWidth() * y);
return iter;
}
@@ -130,7 +146,7 @@ struct BufferLineAccumulator {
* The loop runs backwards(!) over the primary sector space axis u, i.e. increasing distance to pt.
* After each step it decrements v by dv < 1, adding a buffer shift when necessary.
*/
- static void eval(MemoryBuffer *input, float output[4], const float pt_ofs[2], const float source[2],
+ static void eval(MemoryBuffer *input, float output[4], const float co[2], const float source[2],
float dist_min, float dist_max)
{
rcti rect = *input->getRect();
@@ -139,14 +155,16 @@ struct BufferLineAccumulator {
float v, dv;
float falloff_factor;
float border[4];
-
- if ((int)pt_ofs[0] == 0 && (int)pt_ofs[1] == 0) {
- copy_v4_v4(output, input->getBuffer() + COM_NUMBER_OF_CHANNELS * ((int)source[0] + input->getWidth() * (int)source[1]));
+
+ zero_v4(output);
+
+ if ((int)(co[0] - source[0]) == 0 && (int)(co[1] - source[1]) == 0) {
+ copy_v4_v4(output, input->getBuffer() + COM_NUM_CHANNELS_COLOR * ((int)source[0] + input->getWidth() * (int)source[1]));
return;
}
/* initialise the iteration variables */
- float *buffer = init_buffer_iterator(input, source, pt_ofs, dist_min, dist_max, x, y, num, v, dv, falloff_factor);
+ float *buffer = init_buffer_iterator(input, source, co, dist_min, dist_max, x, y, num, v, dv, falloff_factor);
zero_v3(border);
border[3] = 1.0f;
@@ -178,18 +196,18 @@ struct BufferLineAccumulator {
*/
/* decrement u */
- x -= fxx;
- y -= fyx;
- buffer -= (fxx + fyx * buffer_width) * COM_NUMBER_OF_CHANNELS;
+ x -= fxu;
+ y -= fyu;
+ buffer -= (fxu + fyu * buffer_width) * COM_NUM_CHANNELS_COLOR;
/* decrement v (in steps of dv < 1) */
v_local -= dv;
if (v_local < 0.0f) {
v_local += 1.0f;
- x -= fxy;
- y -= fyy;
- buffer -= (fxy + fyy * buffer_width) * COM_NUMBER_OF_CHANNELS;
+ x -= fxv;
+ y -= fyv;
+ buffer -= (fxv + fyv * buffer_width) * COM_NUM_CHANNELS_COLOR;
}
}
@@ -233,21 +251,21 @@ static void accumulate_line(MemoryBuffer *input, float output[4], const float co
if (pt_ofs[0] > 0.0f) {
if (pt_ofs[1] > 0.0f) {
/* 2 */
- BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, co, source, dist_min, dist_max);
}
else {
/* 7 */
- BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, co, source, dist_min, dist_max);
}
}
else {
if (pt_ofs[1] > 0.0f) {
/* 3 */
- BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, co, source, dist_min, dist_max);
}
else {
/* 6 */
- BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, co, source, dist_min, dist_max);
}
}
}
@@ -255,21 +273,21 @@ static void accumulate_line(MemoryBuffer *input, float output[4], const float co
if (pt_ofs[0] > 0.0f) {
if (pt_ofs[1] > 0.0f) {
/* 1 */
- BufferLineAccumulator< 1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ BufferLineAccumulator< 1, 0, 0, 1>::eval(input, output, co, source, dist_min, dist_max);
}
else {
/* 8 */
- BufferLineAccumulator< 1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ BufferLineAccumulator< 1, 0, 0, -1>::eval(input, output, co, source, dist_min, dist_max);
}
}
else {
if (pt_ofs[1] > 0.0f) {
/* 4 */
- BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, co, source, dist_min, dist_max);
}
else {
/* 5 */
- BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, co, source, dist_min, dist_max);
}
}
}
diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp
index ede767cbff7..1b0485afb8d 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.cpp
+++ b/source/blender/compositor/operations/COM_TextureOperation.cpp
@@ -77,12 +77,9 @@ void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsig
void TextureAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- TextureBaseOperation::executePixelSampled(output, x, y, sampler);
- output[0] = output[3];
- output[1] = 0.0f;
- output[2] = 0.0f;
- output[3] = 0.0f;
-}
+ float color[4];
+ TextureBaseOperation::executePixelSampled(color, x, y, sampler);
+ output[0] = color[3];}
void TextureBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
@@ -103,7 +100,7 @@ void TextureBaseOperation::executePixelSampled(float output[4], float x, float y
vec[1] = textureSize[1] * (v + textureOffset[1]);
vec[2] = textureSize[2] * textureOffset[2];
- retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres, m_pool, m_sceneColorManage);
+ retval = multitex_ext(this->m_texture, vec, NULL, NULL, 0, &texres, m_pool, m_sceneColorManage, false);
if (texres.talpha)
output[3] = texres.ta;
@@ -124,18 +121,23 @@ MemoryBuffer *TextureBaseOperation::createMemoryBuffer(rcti *rect2)
{
int height = getHeight();
int width = getWidth();
+ DataType datatype = this->getOutputSocket()->getDataType();
+ int add = 4;
+ if (datatype == COM_DT_VALUE) {
+ add = 1;
+ }
rcti rect;
rect.xmin = 0;
rect.ymin = 0;
rect.xmax = width;
rect.ymax = height;
- MemoryBuffer *result = new MemoryBuffer(NULL, &rect);
+ MemoryBuffer *result = new MemoryBuffer(datatype, &rect);
float *data = result->getBuffer();
for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++, data += 4) {
+ for (int x = 0; x < width; x++, data += add) {
this->executePixelSampled(data, x, y, COM_PS_NEAREST);
}
}
diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp
index 4b81001fdab..6e4caeef613 100644
--- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp
@@ -137,30 +137,33 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
copy_v4_fl(multiplier_accum, 1.0f);
float size_center = tempSize[0] * scalar;
- const int addXStep = QualityStepHelper::getStep() * COM_NUMBER_OF_CHANNELS;
-
+ const int addXStepValue = QualityStepHelper::getStep();
+ const int addYStepValue = addXStepValue;
+ const int addXStepColor = addXStepValue * COM_NUM_CHANNELS_COLOR;
+
if (size_center > this->m_threshold) {
- for (int ny = miny; ny < maxy; ny += QualityStepHelper::getStep()) {
+ for (int ny = miny; ny < maxy; ny += addYStepValue) {
float dy = ny - y;
- int offsetNy = ny * inputSizeBuffer->getWidth() * COM_NUMBER_OF_CHANNELS;
- int offsetNxNy = offsetNy + (minx * COM_NUMBER_OF_CHANNELS);
- for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) {
+ int offsetValueNy = ny * inputSizeBuffer->getWidth();
+ int offsetValueNxNy = offsetValueNy + (minx);
+ int offsetColorNxNy = offsetValueNxNy * COM_NUM_CHANNELS_COLOR;
+ for (int nx = minx; nx < maxx; nx += addXStepValue) {
if (nx != x || ny != y) {
- float size = min(inputSizeFloatBuffer[offsetNxNy] * scalar, size_center);
+ float size = min(inputSizeFloatBuffer[offsetValueNxNy] * scalar, size_center);
if (size > this->m_threshold) {
float dx = nx - x;
if (size > fabsf(dx) && size > fabsf(dy)) {
float uv[2] = {
- (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1),
- (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1)};
- inputBokehBuffer->readNoCheck(bokeh, uv[0], uv[1]);
- madd_v4_v4v4(color_accum, bokeh, &inputProgramFloatBuffer[offsetNxNy]);
+ (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1),
+ (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1)};
+ inputBokehBuffer->read(bokeh, uv[0], uv[1]);
+ madd_v4_v4v4(color_accum, bokeh, &inputProgramFloatBuffer[offsetColorNxNy]);
add_v4_v4(multiplier_accum, bokeh);
}
}
}
- offsetNxNy += addXStep;
- }
+ offsetColorNxNy += addXStepColor;
+ offsetValueNxNy += addXStepValue; }
}
}
@@ -197,8 +200,8 @@ void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice *device,
const float max_dim = max(m_width, m_height);
cl_float scalar = this->m_do_size_scale ? (max_dim / 100.0f) : 1.0f;
- maxBlur = (cl_int)sizeMemoryBuffer->getMaximumValue() * scalar;
- maxBlur = min(maxBlur, this->m_maxBlur);
+ maxBlur = (cl_int)min_ff(sizeMemoryBuffer->getMaximumValue() * scalar,
+ (float)this->m_maxBlur);
device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 0, -1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram);
device->COM_clAttachMemoryBufferToKernelParameter(defocusKernel, 1, -1, clMemToCleanUp, inputMemoryBuffers, this->m_inputBokehProgram);
diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
index f5890157440..8dc06ef07d7 100644
--- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
@@ -57,7 +57,7 @@ void VectorBlurOperation::initExecution()
void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data)
{
float *buffer = (float *) data;
- int index = (y * this->getWidth() + x) * COM_NUMBER_OF_CHANNELS;
+ int index = (y * this->getWidth() + x) * COM_NUM_CHANNELS_COLOR;
copy_v4_v4(output, &buffer[index]);
}
@@ -108,14 +108,12 @@ bool VectorBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuff
void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputImage, MemoryBuffer *inputSpeed, MemoryBuffer *inputZ)
{
- float *zbuf = inputZ->convertToValueBuffer();
NodeBlurData blurdata;
blurdata.samples = this->m_settings->samples / QualityStepHelper::getStep();
blurdata.maxspeed = this->m_settings->maxspeed;
blurdata.minspeed = this->m_settings->minspeed;
blurdata.curved = this->m_settings->curved;
blurdata.fac = this->m_settings->fac;
- RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), zbuf);
- MEM_freeN((void *)zbuf);
+ RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), inputZ->getBuffer());
return;
}
diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp
index fedc8c6db7d..dfdc54012a8 100644
--- a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp
+++ b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp
@@ -51,7 +51,6 @@ void VectorCurveOperation::executePixelSampled(float output[4], float x, float y
this->m_inputProgram->readSampled(input, x, y, sampler);
curvemapping_evaluate_premulRGBF(this->m_curveMapping, output, input);
- output[3] = input[3];
}
void VectorCurveOperation::deinitExecution()
diff --git a/source/blender/compositor/operations/COM_WrapOperation.cpp b/source/blender/compositor/operations/COM_WrapOperation.cpp
index c30361d1df8..7fbef453a13 100644
--- a/source/blender/compositor/operations/COM_WrapOperation.cpp
+++ b/source/blender/compositor/operations/COM_WrapOperation.cpp
@@ -23,7 +23,7 @@
#include "COM_WrapOperation.h"
-WrapOperation::WrapOperation() : ReadBufferOperation()
+WrapOperation::WrapOperation(DataType datatype) : ReadBufferOperation(datatype)
{
this->m_wrappingType = CMP_NODE_WRAP_NONE;
}
diff --git a/source/blender/compositor/operations/COM_WrapOperation.h b/source/blender/compositor/operations/COM_WrapOperation.h
index 33ea1280564..92c93565691 100644
--- a/source/blender/compositor/operations/COM_WrapOperation.h
+++ b/source/blender/compositor/operations/COM_WrapOperation.h
@@ -29,7 +29,7 @@ class WrapOperation : public ReadBufferOperation {
private:
int m_wrappingType;
public:
- WrapOperation();
+ WrapOperation(DataType datetype);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp
index 832864b399d..fccff2a33bf 100644
--- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp
+++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp
@@ -25,10 +25,10 @@
#include <stdio.h>
#include "COM_OpenCLDevice.h"
-WriteBufferOperation::WriteBufferOperation() : NodeOperation()
+WriteBufferOperation::WriteBufferOperation(DataType datatype) : NodeOperation()
{
- this->addInputSocket(COM_DT_COLOR);
- this->m_memoryProxy = new MemoryProxy();
+ this->addInputSocket(datatype);
+ this->m_memoryProxy = new MemoryProxy(datatype);
this->m_memoryProxy->setWriteBufferOperation(this);
this->m_memoryProxy->setExecutor(NULL);
}
@@ -61,6 +61,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
{
MemoryBuffer *memoryBuffer = this->m_memoryProxy->getBuffer();
float *buffer = memoryBuffer->getBuffer();
+ const int num_channels = memoryBuffer->get_num_channels();
if (this->m_input->isComplex()) {
void *data = this->m_input->initializeTileData(rect);
int x1 = rect->xmin;
@@ -71,10 +72,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y;
bool breaked = false;
for (y = y1; y < y2 && (!breaked); y++) {
- int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS;
+ int offset4 = (y * memoryBuffer->getWidth() + x1) * num_channels;
for (x = x1; x < x2; x++) {
this->m_input->read(&(buffer[offset4]), x, y, data);
- offset4 += COM_NUMBER_OF_CHANNELS;
+ offset4 += num_channels;
}
if (isBreaked()) {
breaked = true;
@@ -96,10 +97,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y;
bool breaked = false;
for (y = y1; y < y2 && (!breaked); y++) {
- int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS;
+ int offset4 = (y * memoryBuffer->getWidth() + x1) * num_channels;
for (x = x1; x < x2; x++) {
this->m_input->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST);
- offset4 += COM_NUMBER_OF_CHANNELS;
+ offset4 += num_channels;
}
if (isBreaked()) {
breaked = true;
@@ -126,12 +127,9 @@ void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect,
const unsigned int outputBufferWidth = outputBuffer->getWidth();
const unsigned int outputBufferHeight = outputBuffer->getHeight();
- const cl_image_format imageFormat = {
- CL_RGBA,
- CL_FLOAT
- };
+ const cl_image_format *imageFormat = device->determineImageFormat(outputBuffer);
- cl_mem clOutputBuffer = clCreateImage2D(device->getContext(), CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, &imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error);
+ cl_mem clOutputBuffer = clCreateImage2D(device->getContext(), CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
// STEP 2
diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.h b/source/blender/compositor/operations/COM_WriteBufferOperation.h
index 96466df979c..9220cb179c6 100644
--- a/source/blender/compositor/operations/COM_WriteBufferOperation.h
+++ b/source/blender/compositor/operations/COM_WriteBufferOperation.h
@@ -35,7 +35,7 @@ class WriteBufferOperation : public NodeOperation {
bool m_single_value; /* single value stored in buffer */
NodeOperation *m_input;
public:
- WriteBufferOperation();
+ WriteBufferOperation(DataType datatype);
~WriteBufferOperation();
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
diff --git a/source/blender/datatoc/datatoc_icon.c b/source/blender/datatoc/datatoc_icon.c
index 7df9269a4a8..92048f32a28 100644
--- a/source/blender/datatoc/datatoc_icon.c
+++ b/source/blender/datatoc/datatoc_icon.c
@@ -166,7 +166,8 @@ static bool write_png(const char *name, const unsigned int *pixels,
/* set the individual row-pointers to point at the correct offsets */
for (i = 0; i < height; i++) {
row_pointers[height - 1 - i] = (png_bytep)
- (((unsigned char *)pixels) + (i * width) * bytesperpixel * sizeof(unsigned char));
+ (((const unsigned char *)pixels) +
+ (i * width) * bytesperpixel * sizeof(unsigned char));
}
/* write out the entire image data in one call */
diff --git a/source/blender/datatoc/datatoc_icon.py b/source/blender/datatoc/datatoc_icon.py
index 930d588f859..16092431195 100755
--- a/source/blender/datatoc/datatoc_icon.py
+++ b/source/blender/datatoc/datatoc_icon.py
@@ -113,6 +113,17 @@ def icondir_to_png(path_src, file_dst):
files = [os.path.join(path_src, f) for f in os.listdir(path_src) if f.endswith(".dat")]
+ # First check if we need to bother.
+ if os.path.exists(file_dst):
+ dst_time = os.path.getmtime(file_dst)
+ has_newer = False
+ for f in files:
+ if os.path.getmtime(f) > dst_time:
+ has_newer = True
+ break
+ if not has_newer:
+ return
+
with open(files[0], 'rb') as f_src:
(icon_w, icon_h,
orig_x, orig_y,
diff --git a/source/blender/datatoc/datatoc_icon_split.py b/source/blender/datatoc/datatoc_icon_split.py
index 55f0a5c5f6a..aae907ec340 100755
--- a/source/blender/datatoc/datatoc_icon_split.py
+++ b/source/blender/datatoc/datatoc_icon_split.py
@@ -63,7 +63,7 @@ def image_from_file(filepath):
try:
import bpy
- except:
+ except ImportError:
bpy = None
if bpy is not None:
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 7d8e278f0cf..37c40052275 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -61,6 +61,7 @@
#include "RNA_access.h"
+#include "BKE_animsys.h"
#include "BKE_curve.h"
#include "BKE_key.h"
#include "BKE_nla.h"
@@ -120,8 +121,8 @@ static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, floa
glColor3fv(color);
/* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
- uiSetRoundBox((expanded) ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
- uiDrawBox(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
+ UI_draw_roundbox_corner_set((expanded) ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
+ UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
}
@@ -420,8 +421,8 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi
* - top and bottom
* - special hack: make the top a bit higher, since we are first...
*/
- uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
- uiDrawBox(GL_POLYGON, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
}
/* name for summary entries */
@@ -800,8 +801,8 @@ static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc
glColor3fv(color);
/* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
- uiSetRoundBox(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
- uiDrawBox(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
+ UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
+ UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8);
}
/* name for group entries */
@@ -2365,6 +2366,83 @@ static bAnimChannelType ACF_DSSPK =
acf_dsspk_setting_ptr /* pointer for setting */
};
+/* GPencil Expander ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dsgpencil_icon(bAnimListElem *UNUSED(ale))
+{
+ return ICON_GREASEPENCIL;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid */
+static int acf_dsgpencil_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+{
+ /* clear extra return data first */
+ *neg = false;
+
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GP_DATA_EXPAND;
+
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
+
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
+
+ default: /* unsupported */
+ return 0;
+ }
+}
+
+/* get pointer to the setting */
+static void *acf_dsgpencil_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+{
+ bGPdata *gpd = (bGPdata *)ale->data;
+
+ /* clear extra return data first */
+ *type = 0;
+
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(gpd->flag, type);
+
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (gpd->adt)
+ return GET_ACF_FLAG_PTR(gpd->adt->flag, type);
+ return NULL;
+
+ default: /* unsupported */
+ return NULL;
+ }
+}
+
+/* grease pencil expander type define */
+static bAnimChannelType ACF_DSGPENCIL =
+{
+ "GPencil DS Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dsgpencil_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsgpencil_setting_flag, /* flag for setting */
+ acf_dsgpencil_setting_ptr /* pointer for setting */
+};
+
/* ShapeKey Entry ------------------------------------------- */
/* name for ShapeKey */
@@ -3010,12 +3088,12 @@ static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float y
/* only on top left corner, to show that this channel sits on top of the preceding ones
* while still linking into the action line strip to the right
*/
- uiSetRoundBox(UI_CNR_TOP_LEFT);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT);
/* draw slightly shifted up vertically to look like it has more separation from other channels,
* but we then need to slightly shorten it so that it doesn't look like it overlaps
*/
- uiDrawBox(GL_POLYGON, offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8);
}
/* name for nla action entries */
@@ -3162,6 +3240,7 @@ static void ANIM_init_channel_typeinfo_data(void)
animchannelTypeInfo[type++] = &ACF_DSLAT; /* Lattice Channel */
animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */
animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */
+ animchannelTypeInfo[type++] = &ACF_DSGPENCIL; /* GreasePencil Channel */
animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */
@@ -3407,6 +3486,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
/* step 4) draw special toggles .................................
* - in Graph Editor, checkboxes for visibility in curves area
* - in NLA Editor, glowing dots for solo/not solo...
+ * - in Grease Pencil mode, color swatches for layer color
*/
if (ac->sl) {
if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
@@ -3431,11 +3511,16 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
/* just skip - drawn as widget now */
offset += ICON_WIDTH;
}
+ else if (ale->type == ANIMTYPE_GPLAYER) {
+ /* just skip - drawn as a widget */
+ offset += ICON_WIDTH;
+ }
}
/* step 5) draw name ............................................... */
/* TODO: when renaming, we might not want to draw this, especially if name happens to be longer than channel */
if (acf->name) {
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
/* set text color */
@@ -3449,7 +3534,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
acf->name(ale, name);
offset += 3;
- UI_DrawString(offset, ytext, name);
+ UI_fontstyle_draw_simple(fstyle, offset, ytext, name);
/* draw red underline if channel is disabled */
if ((ale->type == ANIMTYPE_FCURVE) && (ale->flag & FCURVE_DISABLED)) {
@@ -3601,22 +3686,11 @@ static void achannel_nlatrack_solo_widget_cb(bContext *C, void *adt_poin, void *
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL);
}
-/* callback for rename widgets - clear rename-in-progress */
-static void achannel_setting_rename_done_cb(bContext *C, void *ads_poin, void *UNUSED(arg2))
-{
- bDopeSheet *ads = (bDopeSheet *)ads_poin;
-
- /* reset rename index so that edit box disappears now that editing is done */
- ads->renameIndex = 0;
-
- /* send notifiers */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL);
-}
-
/* callback for widget sliders - insert keyframes */
static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poin)
{
ID *id = (ID *)id_poin;
+ AnimData *adt = BKE_animdata_from_id(id);
FCurve *fcu = (FCurve *)fcu_poin;
ReportList *reports = CTX_wm_reports(C);
@@ -3627,9 +3701,8 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
bool done = false;
float cfra;
- /* get current frame */
- // NOTE: this will do for now...
- cfra = (float)CFRA;
+ /* get current frame and apply NLA-mapping to it (if applicable) */
+ cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
/* get flags for keyframing */
flag = ANIM_get_keyframing_flags(scene, 1);
@@ -3666,9 +3739,8 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
bool done = false;
float cfra;
- /* get current frame */
- // NOTE: this will do for now...
- cfra = (float)CFRA;
+ /* get current frame and apply NLA-mapping to it (if applicable) */
+ cfra = BKE_nla_tweakedit_remap(key->adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
/* get flags for keyframing */
flag = ANIM_get_keyframing_flags(scene, 1);
@@ -3788,9 +3860,9 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann
/* type of button */
if (negflag)
- butType = ICONTOGN;
+ butType = UI_BTYPE_ICON_TOGGLE_N;
else
- butType = ICONTOG;
+ butType = UI_BTYPE_ICON_TOGGLE;
/* draw button for setting */
if (ptr && flag) {
@@ -3819,18 +3891,18 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann
case ACHANNEL_SETTING_PROTECT: /* General - protection flags */
case ACHANNEL_SETTING_MUTE: /* General - muting flags */
case ACHANNEL_SETTING_PINNED: /* NLA Actions - 'map/nomap' */
- uiButSetNFunc(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting));
+ UI_but_funcN_set(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), SET_INT_IN_POINTER(setting));
break;
/* settings needing special attention */
case ACHANNEL_SETTING_SOLO: /* NLA Tracks - Solo toggle */
- uiButSetFunc(but, achannel_nlatrack_solo_widget_cb, ale->adt, ale->data);
+ UI_but_func_set(but, achannel_nlatrack_solo_widget_cb, ale->adt, ale->data);
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);
+ UI_but_func_set(but, achannel_setting_widget_cb, NULL, NULL);
break;
}
}
@@ -3838,7 +3910,7 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann
}
/* Draw UI widgets the given channel */
-void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale, uiBlock *block, float yminc, float ymaxc, size_t channel_index)
+void ANIM_channel_draw_widgets(const bContext *C, bAnimContext *ac, bAnimListElem *ale, uiBlock *block, float yminc, float ymaxc, size_t channel_index)
{
bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
View2D *v2d = &ac->ar->v2d;
@@ -3861,7 +3933,7 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
ymid = y - 0.5f * ICON_WIDTH;
/* no button backdrop behind icons */
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
/* step 1) draw expand widget ....................................... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
@@ -3878,6 +3950,7 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
/* step 3) draw special toggles .................................
* - in Graph Editor, checkboxes for visibility in curves area
* - in NLA Editor, glowing dots for solo/not solo...
+ * - in Grease Pencil mode, color swatches for layer color
*/
if (ac->sl) {
if ((ac->spacetype == SPACE_IPO) && acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
@@ -3890,6 +3963,31 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_SOLO);
offset += ICON_WIDTH;
}
+ else if (ale->type == ANIMTYPE_GPLAYER) {
+ /* color swatch for layer color */
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ PointerRNA ptr;
+ float w = ICON_WIDTH / 2.0f;
+
+ RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, &ptr);
+
+ UI_block_align_begin(block);
+
+ UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_stroke_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
+ uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset, yminc, w, ICON_WIDTH,
+ &ptr, "color", -1,
+ 0, 0, 0, 0, gpl->info);
+
+ UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_fill_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
+ uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset + w, yminc, w, ICON_WIDTH,
+ &ptr, "fill_color", -1,
+ 0, 0, 0, 0, gpl->info);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ UI_block_align_end(block);
+
+ offset += ICON_WIDTH;
+ }
}
/* step 4) draw text - check if renaming widget is in use... */
@@ -3908,14 +4006,20 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
if (acf->name_prop(ale, &ptr, &prop)) {
uiBut *but;
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
- but = uiDefButR(block, TEX, 1, "", offset + 3, yminc, RENAME_TEXT_WIDTH, channel_height,
+ but = uiDefButR(block, UI_BTYPE_TEXT, 1, "", offset + 3, yminc, RENAME_TEXT_WIDTH, channel_height,
&ptr, RNA_property_identifier(prop), -1, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, achannel_setting_rename_done_cb, ac->ads, NULL);
- uiButActiveOnly(C, ac->ar, block, but);
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ /* copy what outliner does here, see outliner_buttons */
+ if (UI_but_active_only(C, ac->ar, block, but) == false) {
+ ac->ads->renameIndex = 0;
+
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL);
+ }
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
}
}
}
@@ -3972,16 +4076,16 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
uiBut *but;
PointerRNA *opptr_b;
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
offset += UI_UNIT_X;
- but = uiDefIconButO(block, BUT, "NLA_OT_action_pushdown", WM_OP_INVOKE_DEFAULT, ICON_NLA_PUSHDOWN,
+ but = uiDefIconButO(block, UI_BTYPE_BUT, "NLA_OT_action_pushdown", WM_OP_INVOKE_DEFAULT, ICON_NLA_PUSHDOWN,
(int)v2d->cur.xmax - offset, ymid, UI_UNIT_X, UI_UNIT_X, NULL);
- opptr_b = uiButGetOperatorPtrRNA(but);
+ opptr_b = UI_but_operator_ptr_get(but);
RNA_int_set(opptr_b, "channel_index", channel_index);
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
}
}
@@ -3999,7 +4103,7 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
offset += SLIDER_WIDTH;
/* need backdrop behind sliders... */
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
if (ale->id) { /* Slider using RNA Access -------------------- */
PointerRNA id_ptr, ptr;
@@ -4037,9 +4141,9 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
/* assign keyframing function according to slider type */
if (ale->type == ANIMTYPE_SHAPEKEY)
- uiButSetFunc(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data);
+ UI_but_func_set(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data);
else
- uiButSetFunc(but, achannel_setting_slider_cb, ale->id, ale->data);
+ UI_but_func_set(but, achannel_setting_slider_cb, ale->id, ale->data);
}
/* free the path if necessary */
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index b6ab0407711..d8ad6506186 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -129,6 +129,7 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
case ANIMTYPE_DSLAT:
case ANIMTYPE_DSLINESTYLE:
case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
{
/* need to verify that this data is valid for now */
if (ale->adt) {
@@ -136,6 +137,13 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
}
break;
}
+ case ANIMTYPE_GPLAYER:
+ {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ ACHANNEL_SET_FLAG(gpl, ACHANNEL_SETFLAG_CLEAR, GP_LAYER_ACTIVE);
+ break;
+ }
}
}
@@ -176,6 +184,7 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
case ANIMTYPE_DSSPK:
case ANIMTYPE_DSNTREE:
case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSGPENCIL:
{
/* need to verify that this data is valid for now */
if (ale && ale->adt) {
@@ -184,8 +193,14 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
break;
}
- /* unhandled currently, but may be interesting */
case ANIMTYPE_GPLAYER:
+ {
+ bGPDlayer *gpl = (bGPDlayer *)channel_data;
+ gpl->flag |= GP_LAYER_ACTIVE;
+ break;
+ }
+
+ /* unhandled currently, but may be interesting */
case ANIMTYPE_MASKLAYER:
case ANIMTYPE_SHAPEKEY:
case ANIMTYPE_NLAACTION:
@@ -268,6 +283,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
case ANIMTYPE_DSLAT:
case ANIMTYPE_DSLINESTYLE:
case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
{
if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
sel = ACHANNEL_SETFLAG_CLEAR;
@@ -361,6 +377,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
case ANIMTYPE_DSLAT:
case ANIMTYPE_DSLINESTYLE:
case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
{
/* need to verify that this data is valid for now */
if (ale->adt) {
@@ -843,6 +860,13 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
is_sel = SEL_NLT(nlt);
break;
}
+ case ANIMTYPE_GPLAYER:
+ {
+ bGPDlayer *gpl = (bGPDlayer *)channel;
+
+ is_sel = SEL_GPL(gpl);
+ break;
+ }
default:
printf("rearrange_animchannel_add_to_islands(): don't know how to handle channels of type %d\n", type);
return;
@@ -1167,6 +1191,47 @@ static void rearrange_action_channels(bAnimContext *ac, bAction *act, eRearrange
/* ------------------- */
+static void rearrange_gpencil_channels(bAnimContext *ac, eRearrangeAnimChan_Mode mode)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get rearranging function */
+ AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+
+ if (rearrange_func == NULL)
+ return;
+
+ /* get Grease Pencil datablocks */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ ListBase anim_data_visible = {NULL, NULL};
+ bGPdata *gpd = ale->data;
+
+ /* only consider layers if this datablock is open */
+ BLI_assert(ale->type == ANIMTYPE_GPDATABLOCK);
+ if ((gpd->flag & GP_DATA_EXPAND) == 0)
+ continue;
+
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GPLAYER);
+
+ /* rearrange datablock's layers */
+ rearrange_animchannel_islands(&gpd->layers, rearrange_func, mode, ANIMTYPE_GPLAYER, &anim_data_visible);
+
+ /* free visible layers data */
+ BLI_freelistN(&anim_data_visible);
+ }
+
+ /* free GPD channel data */
+ ANIM_animdata_freelist(&anim_data);
+}
+
+/* ------------------- */
+
static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
@@ -1182,7 +1247,7 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
/* method to move channels depends on the editor */
if (ac.datatype == ANIMCONT_GPENCIL) {
/* Grease Pencil channels */
- printf("Grease Pencil not supported for moving yet\n");
+ rearrange_gpencil_channels(&ac, mode);
}
else if (ac.datatype == ANIMCONT_MASK) {
/* Grease Pencil channels */
@@ -1585,175 +1650,6 @@ static void ANIM_OT_channels_delete(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ******************** Set Channel Visibility Operator *********************** */
-/* NOTE: this operator is only valid in the Graph Editor channels region */
-
-static int animchannels_visibility_set_exec(bContext *C, wmOperator *UNUSED(op))
-{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- ListBase all_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get list of all channels that selection may need to be flushed to
- * - hierarchy mustn't affect what we have access to here...
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
-
- /* hide all channels not selected
- * - hierarchy matters if we're doing this from the channels region
- * since we only want to apply this to channels we can "see",
- * and have these affect their relatives
- * - but for Graph Editor, this gets used also from main region
- * where hierarchy doesn't apply, as for [#21276]
- */
- if ((ac.spacetype == SPACE_IPO) && (ac.regiontype != RGN_TYPE_CHANNELS)) {
- /* graph editor (case 2) */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_UNSEL | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- }
- else {
- /* standard case */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_UNSEL | ANIMFILTER_NODUPLIS);
- }
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* clear setting first */
- ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR);
-
- /* now also flush selection status as appropriate
- * NOTE: in some cases, this may result in repeat flushing being performed
- */
- ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, 0);
- }
-
- ANIM_animdata_freelist(&anim_data);
-
- /* make all the selected channels visible */
- filter = (ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */
- /* TODO: find out why this is the case, and fix that */
- if (ale->type == ANIMTYPE_OBJECT)
- continue;
-
- /* enable the setting */
- ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
-
- /* now, also flush selection status up/down as appropriate */
- ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, 1);
- }
-
- ANIM_animdata_freelist(&anim_data);
- BLI_freelistN(&all_data);
-
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-static void ANIM_OT_channels_visibility_set(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Set Visibility";
- ot->idname = "ANIM_OT_channels_visibility_set";
- ot->description = "Make only the selected animation channels visible in the Graph Editor";
-
- /* api callbacks */
- ot->exec = animchannels_visibility_set_exec;
- ot->poll = ED_operator_graphedit_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
-
-/* ******************** Toggle Channel Visibility Operator *********************** */
-/* NOTE: this operator is only valid in the Graph Editor channels region */
-
-static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *UNUSED(op))
-{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- ListBase all_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- short vis = ACHANNEL_SETFLAG_ADD;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get list of all channels that selection may need to be flushed to
- * - hierarchy mustn't affect what we have access to here...
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
-
- /* filter data
- * - restrict this to only applying on settings we can get to in the list
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* See if we should be making showing all selected or hiding */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* set the setting in the appropriate way (if available) */
- if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE)) {
- vis = ACHANNEL_SETFLAG_CLEAR;
- break;
- }
- }
-
- /* Now set the flags */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */
- /* TODO: find out why this is the case, and fix that */
- if (ale->type == ANIMTYPE_OBJECT)
- continue;
-
- /* change the setting */
- ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, vis);
-
- /* now, also flush selection status up/down as appropriate */
- ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, (vis == ACHANNEL_SETFLAG_ADD));
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
- BLI_freelistN(&all_data);
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-static void ANIM_OT_channels_visibility_toggle(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Toggle Visibility";
- ot->idname = "ANIM_OT_channels_visibility_toggle";
- ot->description = "Toggle visibility in Graph Editor of all selected animation channels";
-
- /* api callbacks */
- ot->exec = animchannels_visibility_toggle_exec;
- ot->poll = ED_operator_graphedit_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
/* ********************** Set Flags Operator *********************** */
/* defines for setting animation-channel flags */
@@ -2334,7 +2230,7 @@ static int animchannels_deselectall_exec(bContext *C, wmOperator *op)
/* 'standard' behavior - check if selected, then apply relevant selection */
if (RNA_boolean_get(op->ptr, "invert"))
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_TOGGLE);
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_INVERT);
else
ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_ADD);
@@ -2736,6 +2632,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
case ANIMTYPE_DSLAT:
case ANIMTYPE_DSLINESTYLE:
case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
{
/* sanity checking... */
if (ale->adt) {
@@ -2897,7 +2794,13 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
gpl->flag |= GP_LAYER_SELECT;
}
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
+ /* change active layer, if this is selected (since we must always have an active layer) */
+ if (gpl->flag & GP_LAYER_SELECT) {
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, gpl, ANIMTYPE_GPLAYER);
+ }
+
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); /* Grease Pencil updates */
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED); /* Animation Ediotrs updates */
break;
}
case ANIMTYPE_MASKDATABLOCK:
@@ -3042,9 +2945,6 @@ void ED_operatortypes_animchannels(void)
WM_operatortype_append(ANIM_OT_channels_expand);
WM_operatortype_append(ANIM_OT_channels_collapse);
- WM_operatortype_append(ANIM_OT_channels_visibility_toggle);
- WM_operatortype_append(ANIM_OT_channels_visibility_set);
-
WM_operatortype_append(ANIM_OT_channels_fcurves_enable);
WM_operatortype_append(ANIM_OT_channels_clean_empty);
@@ -3110,10 +3010,6 @@ void ED_keymap_animchannels(wmKeyConfig *keyconf)
/* grouping */
WM_keymap_add_item(keymap, "ANIM_OT_channels_group", GKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ANIM_OT_channels_ungroup", GKEY, KM_PRESS, KM_ALT, 0);
-
- /* Graph Editor only */
- WM_keymap_add_item(keymap, "ANIM_OT_channels_visibility_set", VKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "ANIM_OT_channels_visibility_toggle", VKEY, KM_PRESS, KM_SHIFT, 0);
}
/* ************************************************************************** */
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index f3b47b168e9..eb57907c9ec 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -92,7 +92,7 @@ void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale)
RNA_property_update_main(G.main, scene, &ptr, prop);
}
else {
- /* in other case we do standard depsgaph update, ideally
+ /* in other case we do standard depsgraph update, ideally
* we'd be calling property update functions here too ... */
DAG_id_tag_update(id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); // XXX or do we want something more restrictive?
}
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 9c3f310a417..0e052279796 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -41,7 +41,6 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_nla.h"
-#include "BKE_object.h"
#include "ED_anim_api.h"
#include "ED_keyframes_edit.h"
@@ -60,9 +59,10 @@
/* Draw current frame number in a little green box beside the current frame indicator */
static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const bool time)
{
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
float xscale, yscale, x, y;
char numstr[32] = " t"; /* t is the character to start replacing from */
- short slen;
+ int slen;
/* because the frame number text is subject to the same scaling as the contents of the view */
UI_view2d_scale_get(v2d, &xscale, &yscale);
@@ -79,7 +79,8 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const
else {
BLI_timecode_string_from_time_simple(&numstr[4], sizeof(numstr) - 4, 1, cfra);
}
- slen = (short)UI_GetStringWidth(numstr) - 1;
+
+ slen = UI_fontstyle_string_width(fstyle, numstr) - 1;
/* get starting coordinates for drawing */
x = cfra * xscale;
@@ -91,7 +92,7 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, const float cfra, const
/* draw current frame number - black text */
UI_ThemeColor(TH_TEXT);
- UI_DrawString(x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr);
+ UI_fontstyle_draw_simple(fstyle, x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr);
/* restore view transform */
glScalef(xscale, 1.0, 1.0);
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index dad25eb04af..d6daa64a9f2 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -216,7 +216,7 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction)
/* Get data being edited in Graph Editor (depending on current 'mode') */
static bool graphedit_get_context(bAnimContext *ac, SpaceIpo *sipo)
{
- /* init dopesheet data if non-existant (i.e. for old files) */
+ /* init dopesheet data if non-existent (i.e. for old files) */
if (sipo->ads == NULL) {
sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
sipo->ads->source = (ID *)ac->scene;
@@ -267,7 +267,7 @@ static bool graphedit_get_context(bAnimContext *ac, SpaceIpo *sipo)
/* Get data being edited in Graph Editor (depending on current 'mode') */
static bool nlaedit_get_context(bAnimContext *ac, SpaceNla *snla)
{
- /* init dopesheet data if non-existant (i.e. for old files) */
+ /* init dopesheet data if non-existent (i.e. for old files) */
if (snla->ads == NULL)
snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
ac->ads = snla->ads;
@@ -771,6 +771,21 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
ale->adt = BKE_animdata_from_id(data);
break;
}
+ case ANIMTYPE_DSGPENCIL:
+ {
+ bGPdata *gpd = (bGPdata *)data;
+ AnimData *adt = gpd->adt;
+
+ /* NOTE: we just reuse the same expand filter for this case */
+ ale->flag = EXPANDED_GPD(gpd);
+
+ // XXX: currently, this is only used for access to its animation data
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
case ANIMTYPE_GROUP:
{
bActionGroup *agrp = (bActionGroup *)data;
@@ -1255,7 +1270,7 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDop
first = adt->nla_tracks.last;
}
else {
- /* first track to include will the the first one (as per normal) */
+ /* first track to include will the first one (as per normal) */
first = adt->nla_tracks.first;
}
@@ -1413,27 +1428,77 @@ static size_t animdata_filter_gpencil(ListBase *anim_data, void *UNUSED(data), i
/* only show if gpd is used by something... */
if (ID_REAL_USERS(gpd) < 1)
continue;
+
+ /* When asked from "AnimData" blocks (i.e. the top-level containers for normal animation),
+ * for convenience, this will return GP Datablocks instead. This may cause issues down
+ * the track, but for now, this will do...
+ */
+ if (filter_mode & ANIMFILTER_ANIMDATA) {
+ /* just add GPD as a channel - this will add everything needed */
+ ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL);
+ }
+ else {
+ /* add gpencil animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
+ {
+ tmp_items += animdata_filter_gpencil_data(&tmp_data, gpd, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
- /* add gpencil animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
- {
- tmp_items += animdata_filter_gpencil_data(&tmp_data, gpd, filter_mode);
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* add gpd as channel too (if for drawing, and it has layers) */
+ ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL);
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
}
- END_ANIMFILTER_SUBCHANNELS;
+ }
+
+ /* return the number of items added to the list */
+ return items;
+}
+
+/* Helper for Grease Pencil data integrated with main DopeSheet */
+static size_t animdata_filter_ds_gpencil(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bGPdata *gpd, int filter_mode)
+{
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add relevant animation channels for Grease Pencil */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
+ {
+ /* add animation channels */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, &gpd->id, filter_mode);
- /* did we find anything? */
- if (tmp_items) {
- /* include data-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* add gpd as channel too (if for drawing, and it has layers) */
- ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL);
+ /* add Grease Pencil layers */
+ // TODO: do these need a separate expander?
+ // XXX: what order should these go in?
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ // XXX: active check here needs checking
+ if (ANIMCHANNEL_ACTIVEOK(gpd)) {
+ ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_DSGPENCIL, gpd);
}
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
}
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
}
/* return the number of items added to the list */
@@ -1699,6 +1764,12 @@ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data,
mtex = (MTex **)(&wo->mtex);
break;
}
+ case ID_PA:
+ {
+ ParticleSettings *part = (ParticleSettings *)owner_id;
+ mtex = (MTex **)(&part->mtex);
+ break;
+ }
default:
{
/* invalid/unsupported option */
@@ -1910,8 +1981,12 @@ static size_t animdata_filter_ds_particles(bAnimContext *ac, ListBase *anim_data
/* add particle-system's animation data to temp collection */
BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_PART_OBJD(psys->part))
{
- /* material's animation data */
+ /* particle system's animation data */
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)psys->part, filter_mode);
+
+ /* textures */
+ if (!(ads->filterflag & ADS_FILTER_NOTEX))
+ tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)psys->part, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
@@ -2215,6 +2290,11 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data
if ((ob->particlesystem.first) && !(ads->filterflag & ADS_FILTER_NOPART)) {
tmp_items += animdata_filter_ds_particles(ac, &tmp_data, ads, ob, filter_mode);
}
+
+ /* grease pencil */
+ if ((ob->gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) {
+ tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->gpd, filter_mode);
+ }
}
END_ANIMFILTER_SUBCHANNELS;
@@ -2257,7 +2337,7 @@ static size_t animdata_filter_ds_world(bAnimContext *ac, ListBase *anim_data, bD
/* textures for world */
if (!(ads->filterflag & ADS_FILTER_NOTEX))
- items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)wo, filter_mode);
+ tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)wo, filter_mode);
/* nodes */
if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE))
@@ -2349,6 +2429,7 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_SCEC(sce))
{
bNodeTree *ntree = sce->nodetree;
+ bGPdata *gpd = sce->gpd;
World *wo = sce->world;
/* Action, Drivers, or NLA for Scene */
@@ -2371,6 +2452,11 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d
tmp_items += animdata_filter_ds_linestyle(ac, &tmp_data, ads, sce, filter_mode);
}
+ /* grease pencil */
+ if ((gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) {
+ tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, gpd, filter_mode);
+ }
+
/* TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here */
}
END_ANIMFILTER_SUBCHANNELS;
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 7cd47fab83a..140b7e0b117 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -316,19 +316,14 @@ void debug_markers_print_list(ListBase *markers)
/* ************* Marker Drawing ************ */
/* function to draw markers */
-static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
+static void draw_marker(
+ View2D *v2d, const uiFontStyle *fstyle, TimeMarker *marker, int cfra, int flag,
+ /* avoid re-calculating each time */
+ const float ypixels, const float xscale, const float yscale)
{
- float xpos, ypixels, xscale, yscale;
- int icon_id = 0;
-
- xpos = marker->frame;
-
- /* no time correction for framelen! space is drawn with old values */
- ypixels = BLI_rcti_size_y(&v2d->mask);
- UI_view2d_scale_get(v2d, &xscale, &yscale);
-
- glScalef(1.0f / xscale, 1.0f, 1.0f);
-
+ const float xpos = marker->frame * xscale;
+ int icon_id;
+
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -347,8 +342,8 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
glColor4ub(0, 0, 0, 96);
glBegin(GL_LINES);
- glVertex2f((xpos * xscale) + 0.5f, 12.0f);
- glVertex2f((xpos * xscale) + 0.5f, (v2d->cur.ymax + 12.0f) * yscale);
+ glVertex2f(xpos + 0.5f, 12.0f);
+ glVertex2f(xpos + 0.5f, (v2d->cur.ymax + 12.0f) * yscale);
glEnd();
setlinestyle(0);
@@ -365,7 +360,7 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
ICON_MARKER;
}
- UI_icon_draw(xpos * xscale - 0.45f * UI_DPI_ICON_SIZE, UI_DPI_ICON_SIZE, icon_id);
+ UI_icon_draw(xpos - 0.45f * UI_DPI_ICON_SIZE, UI_DPI_ICON_SIZE, icon_id);
glDisable(GL_BLEND);
@@ -378,19 +373,19 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
if (marker->flag & SELECT) {
UI_ThemeColor(TH_TEXT_HI);
- x = xpos * xscale + 4.0f * UI_DPI_FAC;
+ x = xpos + 4.0f * UI_DPI_FAC;
y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC;
y = max_ii(y, min_y);
}
else {
UI_ThemeColor(TH_TEXT);
if ((marker->frame <= cfra) && (marker->frame + 5 > cfra)) {
- x = xpos * xscale + 8.0f * UI_DPI_FAC;
+ x = xpos + 8.0f * UI_DPI_FAC;
y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC;
y = max_ii(y, min_y);
}
else {
- x = xpos * xscale + 8.0f * UI_DPI_FAC;
+ x = xpos + 8.0f * UI_DPI_FAC;
y = 17.0f * UI_DPI_FAC;
}
}
@@ -404,39 +399,71 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
}
#endif
- UI_DrawString(x, y, marker->name);
+ UI_fontstyle_draw_simple(fstyle, x, y, marker->name);
}
-
- glScalef(xscale, 1.0f, 1.0f);
}
/* Draw Scene-Markers in time window */
-void draw_markers_time(const bContext *C, int flag)
+void ED_markers_draw(const bContext *C, int flag)
{
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
ListBase *markers = ED_context_get_markers(C);
View2D *v2d;
TimeMarker *marker;
Scene *scene;
+ int select_pass;
+ int v2d_clip_range_x[2];
+ float font_width_max;
- if (markers == NULL)
+ /* cache values */
+ float ypixels, xscale, yscale;
+
+ if (markers == NULL || BLI_listbase_is_empty(markers)) {
return;
+ }
scene = CTX_data_scene(C);
v2d = UI_view2d_fromcontext(C);
- /* unselected markers are drawn at the first time */
- for (marker = markers->first; marker; marker = marker->next) {
- if ((marker->flag & SELECT) == 0) {
- draw_marker(v2d, marker, scene->r.cfra, flag);
- }
+ if (flag & DRAW_MARKERS_MARGIN) {
+ const unsigned char shade[4] = {0, 0, 0, 16};
+ glColor4ubv(shade);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glRectf(v2d->cur.xmin, 0, v2d->cur.xmax, UI_MARKER_MARGIN_Y);
+
+ glDisable(GL_BLEND);
}
-
- /* selected markers are drawn later */
- for (marker = markers->first; marker; marker = marker->next) {
- if (marker->flag & SELECT) {
- draw_marker(v2d, marker, scene->r.cfra, flag);
+
+ /* no time correction for framelen! space is drawn with old values */
+ ypixels = BLI_rcti_size_y(&v2d->mask);
+ UI_view2d_scale_get(v2d, &xscale, &yscale);
+ glScalef(1.0f / xscale, 1.0f, 1.0f);
+
+ /* x-bounds with offset for text (adjust for long string, avoid checking string width) */
+ font_width_max = (10 * UI_DPI_FAC) / xscale;
+ v2d_clip_range_x[0] = v2d->cur.xmin - (sizeof(marker->name) * font_width_max);
+ v2d_clip_range_x[1] = v2d->cur.xmax + font_width_max;
+
+ /* loop [unselected, selected] */
+ for (select_pass = 0; select_pass <= SELECT; select_pass += SELECT) {
+ /* unselected markers are drawn at the first time */
+ for (marker = markers->first; marker; marker = marker->next) {
+ if ((marker->flag & SELECT) == select_pass) {
+ /* bounds check */
+ if ((marker->frame >= v2d_clip_range_x[0]) &&
+ (marker->frame <= v2d_clip_range_x[1]))
+ {
+ draw_marker(v2d, fstyle, marker, scene->r.cfra, flag,
+ ypixels, xscale, yscale);
+ }
+ }
}
}
+
+ glScalef(xscale, 1.0f, 1.0f);
}
/* ************************ Marker Wrappers API ********************* */
@@ -503,8 +530,9 @@ static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, const wm
/* return status modifications - for now, make this spacetype dependent as above */
if (sa->spacetype != SPACE_TIME) {
/* unless successful, must add "pass-through" to let normal operator's have a chance at tackling this event */
- if (retval != OPERATOR_FINISHED)
+ if ((retval & (OPERATOR_FINISHED | OPERATOR_INTERFACE)) == 0) {
retval |= OPERATOR_PASS_THROUGH;
+ }
}
return retval;
@@ -1029,7 +1057,7 @@ static void select_timeline_marker_frame(ListBase *markers, int frame, bool exte
}
BLI_LISTBASE_CIRCULAR_FORWARD_BEGIN (markers, marker, marker_first) {
- /* this way a not-extend select will allways give 1 selected marker */
+ /* this way a not-extend select will always give 1 selected marker */
if (marker->frame == frame) {
marker->flag ^= SELECT;
break;
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 0f202003dd8..cbcbc8743f1 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -41,6 +41,7 @@
#include "DNA_scene_types.h"
#include "BKE_context.h"
+#include "BKE_sequencer.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_sound.h"
@@ -55,6 +56,7 @@
#include "ED_anim_api.h"
#include "ED_screen.h"
+#include "ED_sequencer.h"
#include "anim_intern.h"
@@ -92,9 +94,15 @@ static void change_frame_apply(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
-
+ int frame = RNA_int_get(op->ptr, "frame");
+ bool do_snap = RNA_boolean_get(op->ptr, "snap");
+
+ if (do_snap && CTX_wm_space_seq(C)) {
+ frame = BKE_sequencer_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false);
+ }
+
/* set the new frame number */
- CFRA = RNA_int_get(op->ptr, "frame");
+ CFRA = frame;
FRAMENUMBER_MIN_CLAMP(CFRA);
SUBFRA = 0.0f;
@@ -136,6 +144,25 @@ static int frame_from_event(bContext *C, const wmEvent *event)
return frame;
}
+static void change_frame_seq_preview_begin(bContext *C, const wmEvent *event)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ if (sa && sa->spacetype == SPACE_SEQ) {
+ SpaceSeq *sseq = sa->spacedata.first;
+ if (ED_space_sequencer_check_show_strip(sseq)) {
+ ED_sequencer_special_preview_set(C, event->mval);
+ }
+ }
+}
+static void change_frame_seq_preview_end(bContext *C)
+{
+ if (ED_sequencer_special_preview_get() != NULL) {
+ Scene *scene = CTX_data_scene(C);
+ ED_sequencer_special_preview_clear();
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ }
+}
+
/* Modal Operator init */
static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -144,7 +171,9 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event
* click-dragging over a range (modal scrubbing).
*/
RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
-
+
+ change_frame_seq_preview_begin(C, event);
+
change_frame_apply(C, op);
/* add temp handler */
@@ -153,14 +182,21 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event
return OPERATOR_RUNNING_MODAL;
}
+static void change_frame_cancel(bContext *C, wmOperator *UNUSED(op))
+{
+ change_frame_seq_preview_end(C);
+}
+
/* Modal event handling of frame changing */
static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
+ int ret = OPERATOR_RUNNING_MODAL;
/* execute the events */
switch (event->type) {
case ESCKEY:
- return OPERATOR_FINISHED;
-
+ ret = OPERATOR_FINISHED;
+ break;
+
case MOUSEMOVE:
RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
change_frame_apply(C, op);
@@ -173,15 +209,31 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
* the modal op) doesn't work for some reason
*/
if (event->val == KM_RELEASE)
- return OPERATOR_FINISHED;
+ ret = OPERATOR_FINISHED;
+ break;
+
+ case LEFTCTRLKEY:
+ case RIGHTCTRLKEY:
+ if (event->val == KM_RELEASE) {
+ RNA_boolean_set(op->ptr, "snap", false);
+ }
+ else if (event->val == KM_PRESS) {
+ RNA_boolean_set(op->ptr, "snap", true);
+ }
break;
}
- return OPERATOR_RUNNING_MODAL;
+ if (ret != OPERATOR_RUNNING_MODAL) {
+ change_frame_seq_preview_end(C);
+ }
+
+ return ret;
}
static void ANIM_OT_change_frame(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Change Frame";
ot->idname = "ANIM_OT_change_frame";
@@ -190,6 +242,7 @@ static void ANIM_OT_change_frame(wmOperatorType *ot)
/* api callbacks */
ot->exec = change_frame_exec;
ot->invoke = change_frame_invoke;
+ ot->cancel = change_frame_cancel;
ot->modal = change_frame_modal;
ot->poll = change_frame_poll;
@@ -198,6 +251,8 @@ static void ANIM_OT_change_frame(wmOperatorType *ot)
/* rna */
ot->prop = RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
+ prop = RNA_def_boolean(ot->srna, "snap", false, "Snap", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ****************** set preview range operator ****************************/
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 296a52e7f20..67ba82f1858 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -39,18 +39,12 @@
#include "BLI_utildefines.h"
#include "DNA_anim_types.h"
-#include "DNA_object_types.h"
-#include "DNA_material_types.h"
#include "DNA_texture_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
#include "BKE_animsys.h"
#include "BKE_fcurve.h"
#include "BKE_context.h"
#include "BKE_report.h"
-#include "BKE_material.h"
-#include "BKE_texture.h"
#include "ED_keyframing.h"
@@ -437,7 +431,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
const bool all = RNA_boolean_get(op->ptr, "all");
/* try to create driver using property retrieved from UI */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
if (all)
index = -1;
@@ -455,7 +449,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
if (success) {
/* send updates */
- uiContextAnimUpdate(C);
+ UI_context_update_anim_flag(C);
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
}
@@ -492,7 +486,7 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
const bool all = RNA_boolean_get(op->ptr, "all");
/* try to find driver using property retrieved from UI */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
if (all)
index = -1;
@@ -500,13 +494,16 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
if (ptr.id.data && ptr.data && prop) {
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
- success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
- MEM_freeN(path);
+ if (path) {
+ success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
+
+ MEM_freeN(path);
+ }
}
if (success) {
/* send updates */
- uiContextAnimUpdate(C);
+ UI_context_update_anim_flag(C);
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
}
@@ -542,7 +539,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
int index;
/* try to create driver using property retrieved from UI */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
@@ -551,7 +548,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
/* only copy the driver for the button that this was involved for */
success = ANIM_copy_driver(op->reports, ptr.id.data, path, index, 0);
- uiContextAnimUpdate(C);
+ UI_context_update_anim_flag(C);
MEM_freeN(path);
}
@@ -586,7 +583,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
int index;
/* try to create driver using property retrieved from UI */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
@@ -595,7 +592,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
/* only copy the driver for the button that this was involved for */
success = ANIM_paste_driver(op->reports, ptr.id.data, path, index, 0);
- uiContextAnimUpdate(C);
+ UI_context_update_anim_flag(C);
MEM_freeN(path);
}
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index 7ce33e01747..bcdad1c93ad 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -119,17 +119,18 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
/* basic settings (backdrop + mode selector + some padding) */
/* col = uiLayoutColumn(layout, true); */ /* UNUSED */
block = uiLayoutGetBlock(layout);
- uiBlockBeginAlign(block);
- but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
+ UI_block_align_begin(block);
+ but = uiDefButR(block, UI_BTYPE_MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL);
+ UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
- uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL);
- uiBlockEndAlign(block);
+ uiDefButR(block, UI_BTYPE_TOGGLE, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL);
+ UI_block_align_end(block);
/* now add settings for individual modes */
switch (data->mode) {
case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
{
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
float *cp = NULL;
char xval[32];
unsigned int i;
@@ -138,20 +139,21 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
/* draw polynomial order selector */
row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
- but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0.5f * UI_UNIT_X, 0, bwidth, UI_UNIT_Y,
+ but = uiDefButI(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0.5f * UI_UNIT_X, 0, bwidth, UI_UNIT_Y,
&data->poly_order, 1, 100, 0, 0,
TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
- uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
+ UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
/* calculate maximum width of label for "x^n" labels */
if (data->arraysize > 2) {
BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize);
- maxXWidth = UI_GetStringWidth(xval) + 0.5 * UI_UNIT_X; /* XXX: UI_GetStringWidth is not accurate */
+ /* XXX: UI_fontstyle_string_width is not accurate */
+ maxXWidth = UI_fontstyle_string_width(fstyle, xval) + 0.5 * UI_UNIT_X;
}
else {
/* basic size (just "x") */
- maxXWidth = UI_GetStringWidth("x") + 0.5 * UI_UNIT_X;
+ maxXWidth = UI_fontstyle_string_width(fstyle, "x") + 0.5 * UI_UNIT_X;
}
/* draw controls for each coefficient and a + sign at end of row */
@@ -162,12 +164,12 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
for (i = 0; (i < data->arraysize) && (cp); i++, cp++) {
/* To align with first line... */
if (i)
- uiDefBut(block, LABEL, 1, " ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
else
- uiDefBut(block, LABEL, 1, "y =", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, "y =", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* coefficient */
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth / 2, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
+ uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth / 2, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
10, 3, TIP_("Coefficient for polynomial"));
/* 'x' param (and '+' if necessary) */
@@ -177,10 +179,10 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
BLI_strncpy(xval, "x", sizeof(xval));
else
BLI_snprintf(xval, sizeof(xval), "x^%u", i);
- uiDefBut(block, LABEL, 1, xval, 0, 0, maxXWidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x"));
+ uiDefBut(block, UI_BTYPE_LABEL, 1, xval, 0, 0, maxXWidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x"));
if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) {
- uiDefBut(block, LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* next coefficient on a new row */
row = uiLayoutRow(layout, true);
@@ -188,7 +190,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
}
else {
/* For alignment in UI! */
- uiDefBut(block, LABEL, 1, " ", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
}
break;
@@ -202,10 +204,10 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
/* draw polynomial order selector */
row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
- but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0, 0, width - 1.5 * UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefButI(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0, 0, width - 1.5 * UI_UNIT_X, UI_UNIT_Y,
&data->poly_order, 1, 100, 0, 0,
TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
- uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
+ UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
/* draw controls for each pair of coefficients */
@@ -216,31 +218,31 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
for (i = 0; (i < data->poly_order) && (cp); i++, cp += 2) {
/* To align with first line */
if (i)
- uiDefBut(block, LABEL, 1, " ", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
else
- uiDefBut(block, LABEL, 1, "y =", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, "y =", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* opening bracket */
- uiDefBut(block, LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* coefficients */
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
+ uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
10, 3, TIP_("Coefficient of x"));
- uiDefBut(block, LABEL, 1, "x +", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, "x +", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp + 1, -UI_FLT_MAX, UI_FLT_MAX,
+ uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp + 1, -UI_FLT_MAX, UI_FLT_MAX,
10, 3, TIP_("Second coefficient"));
/* closing bracket and multiplication sign */
if ( (i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2) ) {
- uiDefBut(block, LABEL, 1, ") \xc3\x97", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, ") \xc3\x97", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* set up new row for the next pair of coefficients */
row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
}
else
- uiDefBut(block, LABEL, 1, ") ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, ") ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
break;
}
@@ -439,11 +441,11 @@ static void draw_modifier__envelope(uiLayout *layout, ID *id, FModifier *fcm, sh
row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
- uiDefBut(block, LABEL, 1, IFACE_("Control Points:"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 1, IFACE_("Control Points:"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- but = uiDefBut(block, BUT, B_FMODIFIER_REDRAW, IFACE_("Add Point"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefBut(block, UI_BTYPE_BUT, B_FMODIFIER_REDRAW, IFACE_("Add Point"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Add a new control-point to the envelope on the current frame"));
- uiButSetFunc(but, fmod_envelope_addpoint_cb, env, NULL);
+ UI_but_func_set(but, fmod_envelope_addpoint_cb, env, NULL);
/* control points list */
for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
@@ -451,20 +453,20 @@ static void draw_modifier__envelope(uiLayout *layout, ID *id, FModifier *fcm, sh
row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
- uiBlockBeginAlign(block);
- but = uiDefButF(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Fra:"), 0, 0, 4.5 * UI_UNIT_X, UI_UNIT_Y,
+ UI_block_align_begin(block);
+ but = uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Fra:"), 0, 0, 4.5 * UI_UNIT_X, UI_UNIT_Y,
&fed->time, -MAXFRAMEF, MAXFRAMEF, 10, 1, TIP_("Frame that envelope point occurs"));
- uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
+ UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Min:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y,
+ uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Min:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y,
&fed->min, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, TIP_("Minimum bound of envelope at this point"));
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Max:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y,
+ uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Max:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y,
&fed->max, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, TIP_("Maximum bound of envelope at this point"));
- but = uiDefIconBut(block, BUT, B_FMODIFIER_REDRAW, ICON_X, 0, 0, 0.9 * UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefIconBut(block, UI_BTYPE_BUT, B_FMODIFIER_REDRAW, ICON_X, 0, 0, 0.9 * UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete envelope control point"));
- uiButSetFunc(but, fmod_envelope_deletepoint_cb, env, SET_INT_IN_POINTER(i));
- uiBlockBeginAlign(block);
+ UI_but_func_set(but, fmod_envelope_deletepoint_cb, env, SET_INT_IN_POINTER(i));
+ UI_block_align_begin(block);
}
}
@@ -575,7 +577,7 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *id, ListBase *modifier
sub = uiLayoutRow(row, true);
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
/* expand */
uiItemR(sub, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
@@ -597,14 +599,14 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *id, ListBase *modifier
/* 'mute' button */
uiItemR(sub, &ptr, "mute", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
/* delete button */
- but = uiDefIconBut(block, BUT, B_REDR, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefIconBut(block, UI_BTYPE_BUT, B_REDR, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete F-Curve Modifier"));
- uiButSetFunc(but, delete_fmodifier_cb, modifiers, fcm);
+ UI_but_func_set(but, delete_fmodifier_cb, modifiers, fcm);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
/* when modifier is expanded, draw settings */
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index c5e54cc1c7c..d2dbe961b42 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -39,7 +39,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_dlrbTree.h"
#include "BLI_utildefines.h"
@@ -155,6 +154,7 @@ static DLRBT_Node *nalloc_ak_gpframe(void *data)
/* store settings based on state of BezTriple */
ak->cfra = gpf->framenum;
ak->sel = (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0;
+ ak->key_type = gpf->key_type;
/* set 'modified', since this is used to identify long keyframes */
ak->modified = 1;
@@ -171,6 +171,10 @@ static void nupdate_ak_gpframe(void *node, void *data)
/* set selection status and 'touched' status */
if (gpf->flag & GP_FRAME_SELECT) ak->sel = SELECT;
ak->modified += 1;
+
+ /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
+ if (gpf->key_type == BEZT_KEYTYPE_KEYFRAME)
+ ak->key_type = BEZT_KEYTYPE_KEYFRAME;
}
/* ......... */
@@ -732,6 +736,21 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos)
BLI_dlrbTree_free(&blocks);
}
+void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos)
+{
+ DLRBT_Tree keys;
+
+ BLI_dlrbTree_init(&keys);
+
+ gpencil_to_keylist(ads, gpd, &keys);
+
+ BLI_dlrbTree_linkedlist_sync(&keys);
+
+ draw_keylist(v2d, &keys, NULL, ypos, 0);
+
+ BLI_dlrbTree_free(&keys);
+}
+
void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos)
{
DLRBT_Tree keys;
@@ -924,6 +943,20 @@ void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, DLRBT_Tree
}
+void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys)
+{
+ bGPDlayer *gpl;
+
+ if (gpd && keys) {
+ /* for now, just aggregate out all the frames, but only for visible layers */
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if ((gpl->flag & GP_LAYER_HIDE) == 0) {
+ gpl_to_keylist(ads, gpl, keys);
+ }
+ }
+ }
+}
+
void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys)
{
bGPDframe *gpf;
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 7f612de14b7..ee1bfdff0bd 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -41,9 +41,7 @@
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
-#include "DNA_node_types.h"
#include "DNA_scene_types.h"
-#include "DNA_space_types.h"
#include "BKE_fcurve.h"
@@ -548,6 +546,44 @@ static short ok_bezier_region_lasso(KeyframeEditData *ked, BezTriple *bezt)
return 0;
}
+/**
+ * only called from #ok_bezier_region_circle
+ */
+static bool bezier_region_circle_test(
+ const struct KeyframeEdit_CircleData *data_circle,
+ const float xy[2])
+{
+ if (BLI_rctf_isect_pt_v(data_circle->rectf_scaled, xy)) {
+ float xy_view[2];
+
+ BLI_rctf_transform_pt_v(data_circle->rectf_view, data_circle->rectf_scaled, xy_view, xy);
+
+ xy_view[0] = xy_view[0] - data_circle->mval[0];
+ xy_view[1] = xy_view[1] - data_circle->mval[1];
+ return len_squared_v2(xy_view) < data_circle->radius_squared;
+ }
+
+ return false;
+}
+
+
+static short ok_bezier_region_circle(KeyframeEditData *ked, BezTriple *bezt)
+{
+ /* rect is stored in data property (it's of type rectf, but may not be set) */
+ if (ked->data) {
+ short ok = 0;
+
+#define KEY_CHECK_OK(_index) bezier_region_circle_test(ked->data, bezt->vec[_index])
+ KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
+#undef KEY_CHECK_OK
+
+ /* return ok flags */
+ return ok;
+ }
+ else
+ return 0;
+}
+
KeyframeEditFunc ANIM_editkeyframes_ok(short mode)
{
@@ -567,6 +603,8 @@ KeyframeEditFunc ANIM_editkeyframes_ok(short mode)
return ok_bezier_region;
case BEZT_OK_REGION_LASSO: /* only if the point falls within KeyframeEdit_LassoData defined data */
return ok_bezier_region_lasso;
+ case BEZT_OK_REGION_CIRCLE: /* only if the point falls within KeyframeEdit_LassoData defined data */
+ return ok_bezier_region_circle;
default: /* nothing was ok */
return NULL;
}
@@ -747,7 +785,8 @@ static short mirror_bezier_cframe(KeyframeEditData *ked, BezTriple *bezt)
static short mirror_bezier_yaxis(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
if (bezt->f2 & SELECT) {
- mirror_bezier_yaxis_ex(bezt, 0.0f);
+ /* Yes, names are inverted, we are mirroring accross y axis, hence along x axis... */
+ mirror_bezier_xaxis_ex(bezt, 0.0f);
}
return 0;
@@ -756,7 +795,8 @@ static short mirror_bezier_yaxis(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
static short mirror_bezier_xaxis(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
if (bezt->f2 & SELECT) {
- mirror_bezier_xaxis_ex(bezt, 0.0f);
+ /* Yes, names are inverted, we are mirroring accross x axis, hence along y axis... */
+ mirror_bezier_yaxis_ex(bezt, 0.0f);
}
return 0;
@@ -776,7 +816,7 @@ static short mirror_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
{
/* value to mirror over is stored in the custom data -> first float value slot */
if (bezt->f2 & SELECT) {
- mirror_bezier_xaxis_ex(bezt, ked->f1);
+ mirror_bezier_yaxis_ex(bezt, ked->f1);
}
return 0;
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 56165c36efa..932a00d1687 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -43,13 +43,14 @@
#include "DNA_scene_types.h"
+#include "BKE_action.h"
#include "BKE_fcurve.h"
#include "BKE_report.h"
#include "BKE_library.h"
#include "BKE_global.h"
+#include "BKE_deform.h"
#include "RNA_access.h"
-#include "RNA_enum_types.h"
#include "ED_anim_api.h"
#include "ED_keyframing.h"
@@ -478,6 +479,7 @@ typedef struct tAnimCopybufItem {
BezTriple *bezt; /* keyframes in buffer */
short id_type; /* Result of GS(id->name)*/
+ bool is_bone; /* special flag for armature bones */
} tAnimCopybufItem;
@@ -541,6 +543,31 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
aci->grp = fcu->grp;
aci->rna_path = MEM_dupallocN(fcu->rna_path);
aci->array_index = fcu->array_index;
+
+ /* detect if this is a bone. We do that here rather than during pasting because ID pointers will get invalidated if we undo.
+ * storing the relevant information here helps avoiding crashes if we undo-repaste */
+ if ((aci->id_type == ID_OB) && (((Object *)aci->id)->type == OB_ARMATURE) && aci->rna_path) {
+ Object *ob = (Object *)aci->id;
+ char *str_start;
+
+ if ((str_start = strstr(aci->rna_path, "pose.bones["))) {
+ bPoseChannel *pchan;
+ int length = 0;
+ char *str_end;
+
+ str_start += 12;
+ str_end = strchr(str_start, '\"');
+ length = str_end - str_start;
+ str_start[length] = 0;
+ pchan = BKE_pose_channel_find_name(ob->pose, str_start);
+ str_start[length] = '\"';
+
+ if (pchan) {
+ aci->is_bone = true;
+ }
+ }
+ }
+
BLI_addtail(&animcopybuf, aci);
/* add selected keyframes to buffer */
@@ -588,19 +615,65 @@ short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
return 0;
}
+static void flip_names(tAnimCopybufItem *aci, char **name)
+{
+ if (aci->is_bone) {
+ char *str_start;
+ if ((str_start = strstr(aci->rna_path, "pose.bones["))) {
+ /* ninja coding, try to change the name */
+ char bname_new[MAX_VGROUP_NAME];
+ char *str_iter, *str_end;
+ int length, prefix_l, postfix_l;
+
+ str_start += 12;
+ prefix_l = str_start - aci->rna_path;
+
+ str_end = strchr(str_start, '\"');
+
+ length = str_end - str_start;
+ postfix_l = strlen(str_end);
+
+ /* more ninja stuff, temporary substitute with NULL terminator */
+ str_start[length] = 0;
+ BKE_deform_flip_side_name(bname_new, str_start, false);
+ str_start[length] = '\"';
+
+ str_iter = *name = MEM_mallocN(sizeof(char) * (prefix_l + postfix_l + length + 1), "flipped_path");
+
+ BLI_strncpy(str_iter, aci->rna_path, prefix_l + 1);
+ str_iter += prefix_l;
+ BLI_strncpy(str_iter, bname_new, length + 1);
+ str_iter += length;
+ BLI_strncpy(str_iter, str_end, postfix_l + 1);
+ str_iter[postfix_l] = '\0';
+ }
+ }
+}
+
/* ------------------- */
/* most strict method: exact matches only */
-static tAnimCopybufItem *pastebuf_match_path_full(FCurve *fcu, const short from_single, const short to_simple)
+static tAnimCopybufItem *pastebuf_match_path_full(FCurve *fcu, const short from_single, const short to_simple, bool flip)
{
tAnimCopybufItem *aci;
for (aci = animcopybuf.first; aci; aci = aci->next) {
- /* check that paths exist */
if (to_simple || (aci->rna_path && fcu->rna_path)) {
- if (to_simple || (strcmp(aci->rna_path, fcu->rna_path) == 0)) {
- if ((from_single) || (aci->array_index == fcu->array_index))
+ if (!to_simple && flip && aci->is_bone && fcu->rna_path) {
+ if ((from_single) || (aci->array_index == fcu->array_index)) {
+ char *name = NULL;
+ flip_names(aci, &name);
+ if (STREQ(name, fcu->rna_path)) {
+ MEM_freeN(name);
+ break;
+ }
+ MEM_freeN(name);
+ }
+ }
+ else if (to_simple || STREQ(aci->rna_path, fcu->rna_path)) {
+ if ((from_single) || (aci->array_index == fcu->array_index)) {
break;
+ }
}
}
}
@@ -638,7 +711,7 @@ static tAnimCopybufItem *pastebuf_match_path_property(FCurve *fcu, const short f
int len_path = strlen(fcu->rna_path);
if (len_id <= len_path) {
/* note, paths which end with "] will fail with this test - Animated ID Props */
- if (strcmp(identifier, fcu->rna_path + (len_path - len_id)) == 0) {
+ if (STREQ(identifier, fcu->rna_path + (len_path - len_id))) {
if ((from_single) || (aci->array_index == fcu->array_index))
break;
}
@@ -671,8 +744,30 @@ static tAnimCopybufItem *pastebuf_match_index_only(FCurve *fcu, const short from
/* ................ */
+static void do_curve_mirror_flippping(tAnimCopybufItem *aci, BezTriple *bezt)
+{
+ if (aci->is_bone) {
+ const size_t slength = strlen(aci->rna_path);
+ bool flip = false;
+ if (BLI_strn_endswith(aci->rna_path, "location", slength) && aci->array_index == 0)
+ flip = true;
+ else if (BLI_strn_endswith(aci->rna_path, "rotation_quaternion", slength) && ELEM(aci->array_index, 2, 3))
+ flip = true;
+ else if (BLI_strn_endswith(aci->rna_path, "rotation_euler", slength) && ELEM(aci->array_index, 1, 2))
+ flip = true;
+ else if (BLI_strn_endswith(aci->rna_path, "rotation_axis_angle", slength) && ELEM(aci->array_index, 2, 3))
+ flip = true;
+
+ if (flip) {
+ bezt->vec[0][1] = -bezt->vec[0][1];
+ bezt->vec[1][1] = -bezt->vec[1][1];
+ bezt->vec[2][1] = -bezt->vec[2][1];
+ }
+ }
+}
+
/* helper for paste_animedit_keys() - performs the actual pasting */
-static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float offset, const eKeyMergeMode merge_mode)
+static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float offset, const eKeyMergeMode merge_mode, bool flip)
{
BezTriple *bezt;
int i;
@@ -724,9 +819,12 @@ static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float
}
}
- /* just start pasting, with the the first keyframe on the current frame, and so on */
+ /* just start pasting, with the first keyframe on the current frame, and so on */
for (i = 0, bezt = aci->bezt; i < aci->totvert; i++, bezt++) {
/* temporarily apply offset to src beztriple while copying */
+ if (flip)
+ do_curve_mirror_flippping(aci, bezt);
+
bezt->vec[0][0] += offset;
bezt->vec[1][0] += offset;
bezt->vec[2][0] += offset;
@@ -734,12 +832,16 @@ static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float
/* insert the keyframe
* NOTE: we do not want to inherit handles from existing keyframes in this case!
*/
- insert_bezt_fcurve(fcu, bezt, INSERTKEY_OVERWRITE_FULL);
+ insert_bezt_fcurve(fcu, bezt, INSERTKEY_OVERWRITE_FULL);
+
/* un-apply offset from src beztriple after copying */
bezt->vec[0][0] -= offset;
bezt->vec[1][0] -= offset;
bezt->vec[2][0] -= offset;
+
+ if (flip)
+ do_curve_mirror_flippping(aci, bezt);
}
/* recalculate F-Curve's handles? */
@@ -769,7 +871,7 @@ EnumPropertyItem keyframe_paste_merge_items[] = {
* \return Status code is whether the method FAILED to do anything
*/
short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data,
- const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode)
+ const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
{
bAnimListElem *ale;
@@ -817,7 +919,7 @@ short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data,
fcu = (FCurve *)ale->data; /* destination F-Curve */
aci = animcopybuf.first;
- paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode);
+ paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, false);
}
else {
/* from selected channels
@@ -840,7 +942,7 @@ short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data,
switch (pass) {
case 0:
/* most strict, must be exact path match data_path & index */
- aci = pastebuf_match_path_full(fcu, from_single, to_simple);
+ aci = pastebuf_match_path_full(fcu, from_single, to_simple, flip);
break;
case 1:
@@ -857,7 +959,7 @@ short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data,
/* copy the relevant data from the matching buffer curve */
if (aci) {
totmatch++;
- paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode);
+ paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
}
ale->update |= ANIM_UPDATE_DEFAULT;
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 4c2d90179a7..7e2ce4cd3f1 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -658,7 +658,7 @@ static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
/* validate data */
if (ELEM(NULL, ptr, ptr->data, prop))
- return 0;
+ return false;
/* get first constraint and determine type of keyframe constraints to check for
* - constraints can be on either Objects or PoseChannels, so we only check if the
@@ -880,7 +880,7 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *pr
/* no F-Curve to add keyframe to? */
if (fcu == NULL) {
BKE_report(reports, RPT_ERROR, "No F-Curve to add keyframes to");
- return 0;
+ return false;
}
/* F-Curve not editable? */
if (fcurve_is_keyframable(fcu) == 0) {
@@ -888,13 +888,13 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *pr
"F-Curve with path '%s[%d]' cannot be keyframed, ensure that it is not locked or sampled, "
"and try removing F-Modifiers",
fcu->rna_path, fcu->array_index);
- return 0;
+ return false;
}
/* if no property given yet, try to validate from F-Curve info */
if ((ptr.id.data == NULL) && (ptr.data == NULL)) {
BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from");
- return 0;
+ return false;
}
if (prop == NULL) {
PointerRNA tmp_ptr;
@@ -907,7 +907,7 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *pr
BKE_reportf(reports, RPT_ERROR,
"Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
idname, fcu->rna_path);
- return 0;
+ return false;
}
else {
/* property found, so overwrite 'ptr' to make later code easier */
@@ -956,18 +956,18 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *pr
/* only return success if keyframe added */
if (insert_mode)
- return 1;
+ return true;
}
else {
/* just insert keyframe */
insert_vert_fcurve(fcu, cfra, curval, flag);
/* return success */
- return 1;
+ return true;
}
/* failed */
- return 0;
+ return false;
}
/* Main Keyframing API call:
@@ -1284,10 +1284,10 @@ static int modify_key_op_poll(bContext *C)
/* if no area or active scene */
if (ELEM(NULL, sa, scene))
- return 0;
+ return false;
/* should be fine */
- return 1;
+ return true;
}
/* Insert Key Operator ------------------------ */
@@ -1402,12 +1402,12 @@ static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UN
uiLayout *layout;
/* call the menu, which will call this operator again, hence the canceled */
- pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiItemsEnumO(layout, "ANIM_OT_keyframe_insert_menu", "type");
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
else {
/* just call the exec() on the active keyingset */
@@ -1704,7 +1704,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
flag = ANIM_get_keyframing_flags(scene, 1);
/* try to insert keyframe using property retrieved from UI */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
if ((ptr.id.data && ptr.data && prop) && RNA_property_animateable(&ptr, prop)) {
path = RNA_path_from_ID_to_property(&ptr, prop);
@@ -1751,7 +1751,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
if (success) {
/* send updates */
- uiContextAnimUpdate(C);
+ UI_context_update_anim_flag(C);
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
@@ -1792,7 +1792,7 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
const bool all = RNA_boolean_get(op->ptr, "all");
/* try to insert keyframe using property retrieved from UI */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop) {
path = RNA_path_from_ID_to_property(&ptr, prop);
@@ -1822,7 +1822,7 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
if (success) {
/* send updates */
- uiContextAnimUpdate(C);
+ UI_context_update_anim_flag(C);
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
@@ -1862,7 +1862,7 @@ static int clear_key_button_exec(bContext *C, wmOperator *op)
const bool all = RNA_boolean_get(op->ptr, "all");
/* try to insert keyframe using property retrieved from UI */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop) {
path = RNA_path_from_ID_to_property(&ptr, prop);
@@ -1892,7 +1892,7 @@ static int clear_key_button_exec(bContext *C, wmOperator *op)
if (success) {
/* send updates */
- uiContextAnimUpdate(C);
+ UI_context_update_anim_flag(C);
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
@@ -1922,17 +1922,17 @@ void ANIM_OT_keyframe_clear_button(wmOperatorType *ot)
/* ******************************************* */
/* AUTO KEYFRAME */
-int autokeyframe_cfra_can_key(Scene *scene, ID *id)
+bool autokeyframe_cfra_can_key(Scene *scene, ID *id)
{
float cfra = (float)CFRA; // XXX for now, this will do
/* only filter if auto-key mode requires this */
if (IS_AUTOKEY_ON(scene) == 0)
- return 0;
+ return false;
if (IS_AUTOKEY_MODE(scene, NORMAL)) {
/* can insert anytime we like... */
- return 1;
+ return true;
}
else { /* REPLACE */
/* for whole block - only key if there's a keyframe on that frame already
@@ -1952,7 +1952,7 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter)
{
/* quick sanity check */
if (ELEM(NULL, fcu, fcu->bezt))
- return 0;
+ return false;
/* we either include all regardless of muting, or only non-muted */
if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED) == 0) {
@@ -1965,11 +1965,11 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter)
if (replace) {
/* sanity check: 'i' may in rare cases exceed arraylen */
if ((i >= 0) && (i < fcu->totvert))
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
/* Checks whether an Action has a keyframe for a given frame
@@ -1981,11 +1981,11 @@ static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
/* can only find if there is data */
if (act == NULL)
- return 0;
+ return false;
/* if only check non-muted, check if muted */
if ((filter & ANIMFILTER_KEYS_MUTED) || (act->flag & ACT_MUTED))
- return 0;
+ return false;
/* loop over F-Curves, using binary-search to try to find matches
* - this assumes that keyframes are only beztriples
@@ -1994,12 +1994,12 @@ static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
/* only check if there are keyframes (currently only of type BezTriple) */
if (fcu->bezt && fcu->totvert) {
if (fcurve_frame_has_keyframe(fcu, frame, filter))
- return 1;
+ return true;
}
}
/* nothing found */
- return 0;
+ return false;
}
/* Checks whether an Object has a keyframe for a given frame */
@@ -2007,12 +2007,18 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
{
/* error checking */
if (ob == NULL)
- return 0;
+ return false;
/* check own animation data - specifically, the action it contains */
if ((ob->adt) && (ob->adt->action)) {
- if (action_frame_has_keyframe(ob->adt->action, frame, filter))
- return 1;
+ /* T41525 - When the active action is a NLA strip being edited,
+ * we need to correct the frame number to "look inside" the
+ * remapped action
+ */
+ float ob_frame = BKE_nla_tweakedit_remap(ob->adt, frame, NLATIME_CONVERT_UNMAP);
+
+ if (action_frame_has_keyframe(ob->adt->action, ob_frame, filter))
+ return true;
}
/* try shapekey keyframes (if available, and allowed by filter) */
@@ -2025,7 +2031,7 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
/* 1. test for relative (with keyframes) */
if (id_frame_has_keyframe((ID *)key, frame, filter))
- return 1;
+ return true;
/* 2. test for time */
/* TODO... yet to be implemented (this feature may evolve before then anyway) */
@@ -2039,7 +2045,7 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
/* we only retrieve the active material... */
if (id_frame_has_keyframe((ID *)ma, frame, filter))
- return 1;
+ return true;
}
else {
int a;
@@ -2049,13 +2055,13 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
Material *ma = give_current_material(ob, a + 1);
if (id_frame_has_keyframe((ID *)ma, frame, filter))
- return 1;
+ return true;
}
}
}
/* nothing found */
- return 0;
+ return false;
}
/* --------------- API ------------------- */
@@ -2065,7 +2071,7 @@ bool id_frame_has_keyframe(ID *id, float frame, short filter)
{
/* sanity checks */
if (id == NULL)
- return 0;
+ return false;
/* perform special checks for 'macro' types */
switch (GS(id->name)) {
@@ -2089,7 +2095,7 @@ bool id_frame_has_keyframe(ID *id, float frame, short filter)
/* no keyframe found */
- return 0;
+ return false;
}
/* ************************************************** */
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index ad2db0d9c66..4b9a629183e 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -127,7 +127,7 @@ static int add_default_keyingset_exec(bContext *C, wmOperator *UNUSED(op))
/* call the API func, and set the active keyingset index */
BKE_keyingset_add(&scene->keyingsets, NULL, NULL, flag, keyingflag);
- scene->active_keyingset = BLI_countlist(&scene->keyingsets);
+ scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
/* send notifiers */
WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
@@ -216,7 +216,7 @@ static int add_empty_ks_path_exec(bContext *C, wmOperator *op)
/* don't use the API method for this, since that checks on values... */
ksp = MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty");
BLI_addtail(&ks->paths, ksp);
- ks->active_path = BLI_countlist(&ks->paths);
+ ks->active_path = BLI_listbase_count(&ks->paths);
ksp->groupmode = KSP_GROUP_KSNAME; // XXX?
ksp->idtype = ID_OB;
@@ -316,7 +316,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op)
/* call the API func, and set the active keyingset index */
ks = BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", "Button Keying Set", flag, keyingflag);
- scene->active_keyingset = BLI_countlist(&scene->keyingsets);
+ scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
}
else if (scene->active_keyingset < 0) {
BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set");
@@ -327,7 +327,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op)
}
/* try to add to keyingset using property retrieved from UI */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
/* check if property is able to be added */
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
@@ -347,7 +347,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op)
/* add path to this setting */
BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
- ks->active_path = BLI_countlist(&ks->paths);
+ ks->active_path = BLI_listbase_count(&ks->paths);
success = 1;
/* free the temp path created */
@@ -413,7 +413,7 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
}
/* try to add to keyingset using property retrieved from UI */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop) {
path = RNA_path_from_ID_to_property(&ptr, prop);
@@ -472,12 +472,12 @@ static int keyingset_active_menu_invoke(bContext *C, wmOperator *op, const wmEve
uiLayout *layout;
/* call the menu, which will call this operator again, hence the canceled */
- pup = uiPupMenuBegin(C, op->type->name, ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiItemsEnumO(layout, "ANIM_OT_keying_set_active_set", "type");
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
static int keyingset_active_menu_exec(bContext *C, wmOperator *op)
@@ -556,7 +556,7 @@ KeyingSet *ANIM_builtin_keyingset_get_named(KeyingSet *prevKS, const char name[]
/* loop over KeyingSets checking names */
for (ks = first; ks; ks = ks->next) {
- if (strcmp(name, ks->idname) == 0)
+ if (STREQ(name, ks->idname))
return ks;
}
@@ -603,7 +603,7 @@ void ANIM_keyingset_info_unregister(Main *bmain, KeyingSetInfo *ksi)
ksn = ks->next;
/* remove if matching typeinfo name */
- if (strcmp(ks->typeinfo, ksi->idname) == 0) {
+ if (STREQ(ks->typeinfo, ksi->idname)) {
Scene *scene;
BKE_keyingset_free(ks);
BLI_remlink(&builtin_keyingsets, ks);
@@ -914,6 +914,37 @@ short ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
return 0;
}
+/* Determine which keying flags apply based on the override flags */
+static short keyingset_apply_keying_flags(const short base_flags, const short overrides, const short own_flags)
+{
+ short result = 0;
+
+ /* The logic for whether a keying flag applies is as follows:
+ * - If the flag in question is set in "overrides", that means that the
+ * status of that flag in "own_flags" is used
+ * - If however the flag isn't set, then its value in "base_flags" is used
+ * instead (i.e. no override)
+ */
+#define APPLY_KEYINGFLAG_OVERRIDE(kflag) \
+ if (overrides & kflag) { \
+ result |= (own_flags & kflag); \
+ } \
+ else { \
+ result |= (base_flags & kflag); \
+ }
+
+ /* Apply the flags one by one...
+ * (See rna_def_common_keying_flags() for the supported flags)
+ */
+ APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_NEEDED)
+ APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_MATRIX)
+ APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_XYZ2RGB)
+
+#undef APPLY_KEYINGFLAG_OVERRIDE
+
+ return result;
+}
+
/* Given a KeyingSet and context info (if required), modify keyframes for the channels specified
* by the KeyingSet. This takes into account many of the different combinations of using KeyingSets.
* Returns the number of channels that keyframes were added to
@@ -923,7 +954,8 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
Scene *scene = CTX_data_scene(C);
ReportList *reports = CTX_wm_reports(C);
KS_Path *ksp;
- int kflag = 0, success = 0;
+ const short base_kflags = ANIM_get_keyframing_flags(scene, 1);
+ short kflag = 0, success = 0;
const char *groupname = NULL;
/* sanity checks */
@@ -932,11 +964,8 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
/* get flags to use */
if (mode == MODIFYKEY_MODE_INSERT) {
- /* use KeyingSet's flags as base */
- kflag = ks->keyingflag;
-
- /* supplement with info from the context */
- kflag |= ANIM_get_keyframing_flags(scene, 1);
+ /* use context settings as base */
+ kflag = keyingset_apply_keying_flags(base_kflags, ks->keyingoverride, ks->keyingflag);
}
else if (mode == MODIFYKEY_MODE_DELETE)
kflag = 0;
@@ -962,8 +991,8 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
continue;
}
- /* since keying settings can be defined on the paths too, extend the path before using it */
- kflag2 = (kflag | ksp->keyingflag);
+ /* since keying settings can be defined on the paths too, apply the settings for this path first */
+ kflag2 = keyingset_apply_keying_flags(kflag, ksp->keyingoverride, ksp->keyingflag);
/* get pointer to name of group to add channels to */
if (ksp->groupmode == KSP_GROUP_NONE)
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index eba1bc4d78d..22aaeccc4a8 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -270,7 +270,7 @@ static EditBone *get_named_editbone(ListBase *edbo, const char *name)
if (name) {
for (eBone = edbo->first; eBone; eBone = eBone->next) {
- if (!strcmp(name, eBone->name))
+ if (STREQ(name, eBone->name))
return eBone;
}
}
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index 8bcee52baab..88c52989c07 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -38,6 +38,8 @@
#include "MEM_guardedalloc.h"
+#include "BLF_translation.h"
+
#include "BLI_blenlib.h"
#include "BLI_math.h"
@@ -236,28 +238,49 @@ float ED_rollBoneToVector(EditBone *bone, const float align_axis[3], const bool
return roll;
}
-
+/* note, ranges arithmatic is used below */
typedef enum eCalcRollTypes {
- CALC_ROLL_X = 0,
- CALC_ROLL_Y = 1,
- CALC_ROLL_Z = 2,
-
- CALC_ROLL_TAN_X = 3,
- CALC_ROLL_TAN_Z = 4,
-
- CALC_ROLL_ACTIVE = 5,
- CALC_ROLL_VIEW = 6,
- CALC_ROLL_CURSOR = 7,
+ /* pos */
+ CALC_ROLL_POS_X = 0,
+ CALC_ROLL_POS_Y,
+ CALC_ROLL_POS_Z,
+
+ CALC_ROLL_TAN_POS_X,
+ CALC_ROLL_TAN_POS_Z,
+
+ /* neg */
+ CALC_ROLL_NEG_X,
+ CALC_ROLL_NEG_Y,
+ CALC_ROLL_NEG_Z,
+
+ CALC_ROLL_TAN_NEG_X,
+ CALC_ROLL_TAN_NEG_Z,
+
+ /* no sign */
+ CALC_ROLL_ACTIVE,
+ CALC_ROLL_VIEW,
+ CALC_ROLL_CURSOR,
} eCalcRollTypes;
static EnumPropertyItem prop_calc_roll_types[] = {
- {CALC_ROLL_TAN_X, "X", 0, "Local X Tangent", ""},
- {CALC_ROLL_TAN_Z, "Z", 0, "Local Z Tangent", ""},
+ {0, "", 0, N_("Positive"), ""},
+ {CALC_ROLL_TAN_POS_X, "POS_X", 0, "Local +X Tangent", ""},
+ {CALC_ROLL_TAN_POS_Z, "POS_Z", 0, "Local +Z Tangent", ""},
+
+ {CALC_ROLL_POS_X, "GLOBAL_POS_X", 0, "Global +X Axis", ""},
+ {CALC_ROLL_POS_Y, "GLOBAL_POS_Y", 0, "Global +Y Axis", ""},
+ {CALC_ROLL_POS_Z, "GLOBAL_POS_Z", 0, "Global +Z Axis", ""},
- {CALC_ROLL_X, "GLOBAL_X", 0, "Global X Axis", ""},
- {CALC_ROLL_Y, "GLOBAL_Y", 0, "Global Y Axis", ""},
- {CALC_ROLL_Z, "GLOBAL_Z", 0, "Global Z Axis", ""},
+ {0, "", 0, N_("Negative"), ""},
+ {CALC_ROLL_TAN_NEG_X, "NEG_X", 0, "Local -X Tangent", ""},
+ {CALC_ROLL_TAN_NEG_Z, "NEG_Z", 0, "Local -Z Tangent", ""},
+
+ {CALC_ROLL_NEG_X, "GLOBAL_NEG_X", 0, "Global -X Axis", ""},
+ {CALC_ROLL_NEG_Y, "GLOBAL_NEG_Y", 0, "Global -Y Axis", ""},
+ {CALC_ROLL_NEG_Z, "GLOBAL_NEG_Z", 0, "Global -Z Axis", ""},
+
+ {0, "", 0, N_("Other"), ""},
{CALC_ROLL_ACTIVE, "ACTIVE", 0, "Active Bone", ""},
{CALC_ROLL_VIEW, "VIEW", 0, "View Axis", ""},
{CALC_ROLL_CURSOR, "CURSOR", 0, "Cursor", ""},
@@ -268,15 +291,22 @@ static EnumPropertyItem prop_calc_roll_types[] = {
static int armature_calc_roll_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_edit_object(C);
- const short type = RNA_enum_get(op->ptr, "type");
+ eCalcRollTypes type = RNA_enum_get(op->ptr, "type");
const bool axis_only = RNA_boolean_get(op->ptr, "axis_only");
- const bool axis_flip = RNA_boolean_get(op->ptr, "axis_flip");
+ /* axis_flip when matching the active bone never makes sense */
+ bool axis_flip = ((type >= CALC_ROLL_ACTIVE) ? RNA_boolean_get(op->ptr, "axis_flip") :
+ (type >= CALC_ROLL_TAN_NEG_X) ? true : false);
float imat[3][3];
bArmature *arm = ob->data;
EditBone *ebone;
+ if ((type >= CALC_ROLL_NEG_X) && (type <= CALC_ROLL_TAN_NEG_Z)) {
+ type -= (CALC_ROLL_ACTIVE - CALC_ROLL_NEG_X);
+ axis_flip = true;
+ }
+
copy_m3_m4(imat, ob->obmat);
invert_m3(imat);
@@ -302,7 +332,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
}
}
}
- else if (ELEM(type, CALC_ROLL_TAN_X, CALC_ROLL_TAN_Z)) {
+ else if (ELEM(type, CALC_ROLL_TAN_POS_X, CALC_ROLL_TAN_POS_Z)) {
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
if (ebone->parent) {
bool is_edit = (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone));
@@ -323,7 +353,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
sub_v3_v3v3(dir_b, ebone_other->head, ebone_other->tail);
normalize_v3(dir_b);
- if (type == CALC_ROLL_TAN_Z) {
+ if (type == CALC_ROLL_TAN_POS_Z) {
cross_v3_v3v3(vec, dir_a, dir_b);
}
else {
@@ -374,7 +404,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
copy_v3_v3(vec, mat[2]);
}
else { /* Axis */
- assert(type >= 0 && type <= 5);
+ assert(type <= 5);
if (type < 3) vec[type] = 1.0f;
else vec[type - 2] = -1.0f;
mul_m3_v3(imat, vec);
@@ -423,7 +453,7 @@ void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_calc_roll_types, CALC_ROLL_TAN_X, "Type", "");
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_calc_roll_types, CALC_ROLL_TAN_POS_X, "Type", "");
RNA_def_boolean(ot->srna, "axis_flip", 0, "Flip Axis", "Negate the alignment axis");
RNA_def_boolean(ot->srna, "axis_only", 0, "Shortest Rotation", "Ignore the axis direction, use the shortest rotation to align");
}
@@ -569,7 +599,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
* 2) between the two joints (order is dependent on active-bone/hierarchy)
* 3+) error (a smarter method involving finding chains needs to be worked out
*/
- count = BLI_countlist(&points);
+ count = BLI_listbase_count(&points);
if (count == 0) {
BKE_report(op->reports, RPT_ERROR, "No joints selected");
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 6d616384b9a..2c64c9aa345 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -215,7 +215,7 @@ void POSE_OT_propagate(struct wmOperatorType *ot);
*/
EditBone *make_boneList(struct ListBase *edbo, struct ListBase *bones, struct EditBone *parent, struct Bone *actBone);
-void BIF_sk_selectStroke(struct bContext *C, const int mval[2], short extend);
+bool BIF_sk_selectStroke(struct bContext *C, const int mval[2], const bool extend);
/* duplicate method */
void preEditBoneDuplicate(struct ListBase *editbones);
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index 9afc45955bd..a8b5f888597 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -141,7 +141,7 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
char oldname[MAXBONENAME];
/* names better differ! */
- if (strncmp(oldnamep, newnamep, MAXBONENAME)) {
+ if (!STREQLEN(oldnamep, newnamep, MAXBONENAME)) {
/* we alter newname string... so make copy */
BLI_strncpy(newname, newnamep, MAXBONENAME);
@@ -219,7 +219,7 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
if (ob->parent && (ob->parent->data == arm)) {
if (ob->partype == PARBONE) {
/* bone name in object */
- if (!strcmp(ob->parsubstr, oldname))
+ if (STREQ(ob->parsubstr, oldname))
BLI_strncpy(ob->parsubstr, newname, MAXBONENAME);
}
}
@@ -267,6 +267,7 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
/* Fix all animdata that may refer to this bone - we can't just do the ones attached to objects, since
* other ID-blocks may have drivers referring to this bone [#29822]
*/
+ // XXX: the ID here is for armatures, but most bone drivers are actually on the object instead...
{
BKE_all_animdata_fix_paths_rename(&arm->id, "pose.bones", oldname, newname);
@@ -284,7 +285,7 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
if (sl->spacetype == SPACE_VIEW3D) {
View3D *v3d = (View3D *)sl;
if (v3d->ob_centre && v3d->ob_centre->data == arm) {
- if (!strcmp(v3d->ob_centre_bone, oldname)) {
+ if (STREQ(v3d->ob_centre_bone, oldname)) {
BLI_strncpy(v3d->ob_centre_bone, newname, MAXBONENAME);
}
}
diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index b7e38546ca2..c80953d6737 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -28,8 +28,6 @@
* \ingroup edarmature
*/
-#include "BLI_math.h"
-
#include "RNA_access.h"
#include "WM_api.h"
@@ -368,7 +366,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "POSE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "POSE_OT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "POSE_OT_select_mirror", FKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_select_mirror", FKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
WM_keymap_add_item(keymap, "POSE_OT_constraint_add_with_targets", CKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_item(keymap, "POSE_OT_constraints_clear", CKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index 75fa4a5433f..53989dd783c 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -29,20 +29,26 @@
* \ingroup edarmature
*/
+#include "MEM_guardedalloc.h"
+
+#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLF_translation.h"
#include "BKE_action.h"
+#include "BKE_animsys.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -98,33 +104,122 @@ static void joined_armature_fix_links_constraints(
/* action constraint? (pose constraints only) */
if (con->type == CONSTRAINT_TYPE_ACTION) {
- bActionConstraint *data = con->data; // XXX old animation system
- bAction *act;
- bActionChannel *achan;
+ bActionConstraint *data = con->data;
if (data->act) {
- act = data->act;
+ BKE_action_fix_paths_rename(&tarArm->id, data->act, "pose.bones[",
+ pchan->name, curbone->name, 0, 0, false);
+ }
+ }
+
+ }
+}
+
+/* userdata for joined_armature_fix_animdata_cb() */
+typedef struct tJoinArmature_AdtFixData {
+ Object *srcArm;
+ Object *tarArm;
+
+ GHash *names_map;
+} tJoinArmature_AdtFixData;
- for (achan = act->chanbase.first; achan; achan = achan->next) {
- if (STREQ(achan->name, pchan->name)) {
- BLI_strncpy(achan->name, curbone->name, sizeof(achan->name));
+/* Callback to pass to void BKE_animdata_main_cb() for fixing driver ID's to point to the new ID */
+/* FIXME: For now, we only care about drivers here. When editing rigs, it's very rare to have animation
+ * on the rigs being edited already, so it should be safe to skip these.
+ */
+static void joined_armature_fix_animdata_cb(ID *id, AnimData *adt, void *user_data)
+{
+ tJoinArmature_AdtFixData *afd = (tJoinArmature_AdtFixData *)user_data;
+ ID *src_id = &afd->srcArm->id;
+ ID *dst_id = &afd->tarArm->id;
+
+ GHashIterator gh_iter;
+ FCurve *fcu;
+
+ /* Fix paths - If this is the target object, it will have some "dirty" paths */
+ if (id == src_id) {
+ /* Fix drivers */
+ for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
+ /* skip driver if it doesn't affect the bones */
+ if (strstr(fcu->rna_path, "pose.bones[") == NULL) {
+ continue;
+ }
+
+ // FIXME: this is too crude... it just does everything!
+ GHASH_ITER(gh_iter, afd->names_map) {
+ const char *old_name = BLI_ghashIterator_getKey(&gh_iter);
+ const char *new_name = BLI_ghashIterator_getValue(&gh_iter);
+
+ /* only remap if changed; this still means there will be some waste if there aren't many drivers/keys */
+ if (!STREQ(old_name, new_name) && strstr(fcu->rna_path, old_name)) {
+ fcu->rna_path = BKE_animsys_fix_rna_path_rename(id, fcu->rna_path, "pose.bones",
+ old_name, new_name, 0, 0, false);
+
+ /* we don't want to apply a second remapping on this driver now,
+ * so stop trying names, but keep fixing drivers
+ */
+ break;
+ }
+ }
+ }
+ }
+
+
+ /* Driver targets */
+ for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ /* Fix driver references to invalid ID's */
+ 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)
+ {
+ /* change the ID's used... */
+ if (dtar->id == src_id) {
+ dtar->id = dst_id;
+
+ /* also check on the subtarget...
+ * XXX: We duplicate the logic from drivers_path_rename_fix() here, with our own
+ * little twists so that we know that it isn't going to clobber the wrong data
+ */
+ if ((dtar->rna_path && strstr(dtar->rna_path, "pose.bones[")) || (dtar->pchan_name[0])) {
+ GHASH_ITER(gh_iter, afd->names_map) {
+ const char *old_name = BLI_ghashIterator_getKey(&gh_iter);
+ const char *new_name = BLI_ghashIterator_getValue(&gh_iter);
+
+ /* only remap if changed */
+ if (!STREQ(old_name, new_name)) {
+ if ((dtar->rna_path) && strstr(dtar->rna_path, old_name)) {
+ /* Fix up path */
+ dtar->rna_path = BKE_animsys_fix_rna_path_rename(id, dtar->rna_path, "pose.bones",
+ old_name, new_name, 0, 0, false);
+ break; /* no need to try any more names for bone path */
+ }
+ else if (STREQ(dtar->pchan_name, old_name)) {
+ /* Change target bone name */
+ BLI_strncpy(dtar->pchan_name, new_name, sizeof(dtar->pchan_name));
+ break; /* no need to try any more names for bone subtarget */
+ }
+ }
+ }
}
}
}
+ DRIVER_TARGETS_LOOPER_END
}
-
}
}
/* Helper function for armature joining - link fixing */
-static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone)
+static void joined_armature_fix_links(Main *bmain, Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone)
{
Object *ob;
bPose *pose;
bPoseChannel *pchant;
/* let's go through all objects in database */
- for (ob = G.main->object.first; ob; ob = ob->id.next) {
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
/* do some object-type specific things */
if (ob->type == OB_ARMATURE) {
pose = ob->pose;
@@ -198,8 +293,17 @@ int join_armature_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
{
if ((base->object->type == OB_ARMATURE) && (base->object != ob)) {
+ tJoinArmature_AdtFixData afd = {NULL};
bArmature *curarm = base->object->data;
+ /* we assume that each armature datablock is only used in a single place */
+ BLI_assert(ob->data != base->object->data);
+
+ /* init callback data for fixing up AnimData links later */
+ afd.srcArm = base->object;
+ afd.tarArm = ob;
+ afd.names_map = BLI_ghash_str_new("join_armature_adt_fix");
+
/* Make a list of editbones in current armature */
ED_armature_to_edit(base->object->data);
@@ -219,6 +323,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
/* Get new name */
unique_editbone_name(arm->edbo, curbone->name, NULL);
+ BLI_ghash_insert(afd.names_map, BLI_strdup(pchan->name), curbone->name);
/* Transform the bone */
{
@@ -249,7 +354,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
}
/* Fix Constraints and Other Links to this Bone and Armature */
- joined_armature_fix_links(ob, base->object, pchan, curbone);
+ joined_armature_fix_links(bmain, ob, base->object, pchan, curbone);
/* Rename pchan */
BLI_strncpy(pchan->name, curbone->name, sizeof(pchan->name));
@@ -264,6 +369,37 @@ int join_armature_exec(bContext *C, wmOperator *op)
BKE_pose_channels_hash_free(pose);
}
+ /* Fix all the drivers (and animation data) */
+ BKE_animdata_main_cb(bmain, joined_armature_fix_animdata_cb, &afd);
+ BLI_ghash_free(afd.names_map, MEM_freeN, NULL);
+
+ /* Only copy over animdata now, after all the remapping has been done,
+ * so that we don't have to worry about ambiguities re which armature
+ * a bone came from!
+ */
+ if (base->object->adt) {
+ if (ob->adt == NULL) {
+ /* no animdata, so just use a copy of the whole thing */
+ ob->adt = BKE_copy_animdata(base->object->adt, false);
+ }
+ else {
+ /* merge in data - we'll fix the drivers manually */
+ BKE_animdata_merge_copy(&ob->id, &base->object->id, ADT_MERGECOPY_KEEP_DST, false);
+ }
+ }
+
+ if (curarm->adt) {
+ if (arm->adt == NULL) {
+ /* no animdata, so just use a copy of the whole thing */
+ arm->adt = BKE_copy_animdata(curarm->adt, false);
+ }
+ else {
+ /* merge in data - we'll fix the drivers manually */
+ BKE_animdata_merge_copy(&arm->id, &curarm->id, ADT_MERGECOPY_KEEP_DST, false);
+ }
+ }
+
+ /* Free the old object data */
ED_base_object_free_and_unlink(bmain, scene, base);
}
}
@@ -673,8 +809,8 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
EditBone *actbone = CTX_data_active_bone(C);
- uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE);
- uiLayout *layout = uiPupMenuLayout(pup);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
int allchildbones = 0;
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
@@ -691,9 +827,9 @@ static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const
if (allchildbones)
uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_OFFSET);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
void ARMATURE_OT_parent_set(wmOperatorType *ot)
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index c6ef76c570c..581dd00e285 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -174,7 +174,6 @@ void *get_nearest_bone(bContext *C, short findunsel, int x, int y)
rect.xmin = rect.xmax = x;
rect.ymin = rect.ymax = y;
- glInitNames();
hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true);
if (hits > 0)
@@ -254,7 +253,7 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEv
static int armature_select_linked_poll(bContext *C)
{
- return (ED_operator_view3d_active(C) && ED_operator_editarmature(C) );
+ return (ED_operator_view3d_active(C) && ED_operator_editarmature(C));
}
void ARMATURE_OT_select_linked(wmOperatorType *ot)
@@ -288,11 +287,9 @@ static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2],
rcti rect;
unsigned int buffer[MAXPICKBUF];
unsigned int hitresult, besthitresult = BONESEL_NOSEL;
- int i, mindep = 4;
+ int i, mindep = 5;
short hits;
- glInitNames();
-
/* find the bone after the current active bone, so as to bump up its chances in selection.
* this way overlapping bones will cycle selection state as with objects. */
if (ebone_next_act &&
@@ -345,16 +342,16 @@ static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2],
dep = 2;
}
else {
- dep = 2;
+ dep = 1;
}
}
else {
/* bone found */
if (findunsel) {
if ((ebone->flag & BONE_SELECTED) == 0)
- dep = 2;
- else
dep = 3;
+ else
+ dep = 4;
}
else {
dep = 3;
@@ -485,7 +482,9 @@ bool mouse_armature(bContext *C, const int mval[2], bool extend, bool deselect,
view3d_set_viewcontext(C, &vc);
- BIF_sk_selectStroke(C, mval, extend);
+ if (BIF_sk_selectStroke(C, mval, extend)) {
+ return true;
+ }
nearBone = get_nearest_editbonepoint(&vc, mval, arm->edbo, 1, &selmask);
if (nearBone) {
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index 5ff15b84284..ea1a94fbba6 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -43,6 +43,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_deform.h"
+#include "BKE_object_deform.h"
#include "BKE_report.h"
#include "BKE_subsurf.h"
#include "BKE_modifier.h"
@@ -52,7 +53,10 @@
#include "armature_intern.h"
-#include "meshlaplacian.h"
+
+#ifdef WITH_OPENNL
+# include "meshlaplacian.h"
+#endif
#if 0
#include "reeb.h"
@@ -117,7 +121,7 @@ static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
*/
if (!(bone->flag & BONE_NO_DEFORM)) {
if (!defgroup_find_name(ob, bone->name)) {
- ED_vgroup_add_name(ob, bone->name);
+ BKE_object_defgroup_add_name(ob, bone->name);
return 1;
}
}
@@ -162,9 +166,15 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
else
segments = 1;
- if (!wpmode || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED)))
- if (!(defgroup = defgroup_find_name(ob, bone->name)))
- defgroup = ED_vgroup_add_name(ob, bone->name);
+ if (!wpmode || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))) {
+ if (!(defgroup = defgroup_find_name(ob, bone->name))) {
+ defgroup = BKE_object_defgroup_add_name(ob, bone->name);
+ }
+ else if (defgroup->flag & DG_LOCK_WEIGHT) {
+ /* In case vgroup already exists and is locked, do not modify it here. See T43814. */
+ defgroup = NULL;
+ }
+ }
if (data->list != NULL) {
hgroup = (bDeformGroup ***) &data->list;
@@ -276,7 +286,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob,
if (numbones == 0)
return;
- if (ED_vgroup_data_create(ob->data) == false)
+ if (BKE_object_defgroup_data_create(ob->data) == NULL)
return;
/* create an array of pointer to bones that are skinnable
@@ -428,7 +438,7 @@ void create_vgroups_from_armature(ReportList *reports, Scene *scene, Object *ob,
bArmature *arm = par->data;
if (mode == ARM_GROUPS_NAME) {
- const int defbase_tot = BLI_countlist(&ob->defbase);
+ const int defbase_tot = BLI_listbase_count(&ob->defbase);
int defbase_add;
/* Traverse the bone list, trying to create empty vertex
* groups corresponding to the bone.
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index 647b640ee61..5376fc8c79b 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -718,7 +718,7 @@ static void RIG_reconnectControlBones(RigGraph *rg)
cti->get_constraint_targets(con, &targets);
for (target_index = 0, ct = targets.first; ct; target_index++, ct = ct->next) {
- if ((ct->tar == rg->ob) && strcmp(ct->subtarget, ctrl->bone->name) == 0) {
+ if ((ct->tar == rg->ob) && STREQ(ct->subtarget, ctrl->bone->name)) {
/* SET bone link to bone corresponding to pchan */
EditBone *link = BLI_ghash_lookup(rg->bones_map, pchan->name);
@@ -841,7 +841,7 @@ static void RIG_reconnectControlBones(RigGraph *rg)
cti->get_constraint_targets(con, &targets);
for (ct = targets.first; ct; ct = ct->next) {
- if ((ct->tar == rg->ob) && strcmp(ct->subtarget, ctrl->bone->name) == 0) {
+ if ((ct->tar == rg->ob) && STREQ(ct->subtarget, ctrl->bone->name)) {
/* SET bone link to ctrl corresponding to pchan */
RigControl *link = BLI_ghash_lookup(rg->controls_map, pchan->name);
@@ -1160,7 +1160,7 @@ static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bo
last_bone = bone;
- if (strcmp(bone->name, "head") == 0) {
+ if (STREQ(bone->name, "head")) {
contain_head = 1;
}
}
@@ -1205,7 +1205,7 @@ static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bo
static void RIG_findHead(RigGraph *rg)
{
if (rg->head == NULL) {
- if (BLI_countlist(&rg->arcs) == 1) {
+ if (BLI_listbase_is_single(&rg->arcs)) {
RigArc *arc = rg->arcs.first;
rg->head = (RigNode *)arc->head;
@@ -1958,7 +1958,7 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc,
#endif
float *vec0, *vec1;
int *best_positions;
- int nb_edges = BLI_countlist(&iarc->edges);
+ int nb_edges = BLI_listbase_count(&iarc->edges);
int nb_joints = nb_edges - 1;
RetargetMethod method = METHOD_MEMOIZE;
int i;
@@ -2152,7 +2152,7 @@ void exec_retargetArctoArc(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(th
RigNode *inode_start = p->inode_start;
ReebArc *earc = iarc->link_mesh;
- if (BLI_countlist(&iarc->edges) == 1) {
+ if (BLI_listbase_is_single(&iarc->edges)) {
RigEdge *edge = iarc->edges.first;
if (testFlipArc(iarc, inode_start)) {
@@ -2454,7 +2454,7 @@ const char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index)
return "None";
}
- if (bone_index == BLI_countlist(&arc->edges)) {
+ if (bone_index == BLI_listbase_count(&arc->edges)) {
return "Last joint";
}
@@ -2476,10 +2476,10 @@ int RIG_nbJoints(RigGraph *rg)
RigArc *arc;
int total = 0;
- total += BLI_countlist(&rg->nodes);
+ total += BLI_listbase_count(&rg->nodes);
for (arc = rg->arcs.first; arc; arc = arc->next) {
- total += BLI_countlist(&arc->edges) - 1; /* -1 because end nodes are already counted */
+ total += BLI_listbase_count(&arc->edges) - 1; /* -1 because end nodes are already counted */
}
return total;
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index d75a23a6322..c0098a3726a 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -31,8 +31,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLF_translation.h"
-
#include "BKE_context.h"
#include "BKE_sketch.h"
@@ -335,11 +333,11 @@ static void sk_autoname(bContext *C, ReebArc *arc)
if (side[0] == '\0') {
valid = 1;
}
- else if (strcmp(side, "R") == 0 || strcmp(side, "L") == 0) {
+ else if (STREQ(side, "R") || STREQ(side, "L")) {
valid = 1;
caps = 1;
}
- else if (strcmp(side, "r") == 0 || strcmp(side, "l") == 0) {
+ else if (STREQ(side, "r") || STREQ(side, "l")) {
valid = 1;
caps = 0;
}
@@ -403,9 +401,7 @@ static void sk_retargetStroke(bContext *C, SK_Stroke *stk)
RigGraph *rg;
invert_m4_m4(imat, obedit->obmat);
-
- copy_m3_m4(tmat, obedit->obmat);
- transpose_m3(tmat);
+ transpose_m3_m4(tmat, obedit->obmat);
arc = sk_strokeToArc(stk, imat, tmat);
@@ -1358,9 +1354,7 @@ static void sk_convertStroke(bContext *C, SK_Stroke *stk)
head = NULL;
invert_m4_m4(invmat, obedit->obmat);
-
- copy_m3_m4(tmat, obedit->obmat);
- transpose_m3(tmat);
+ transpose_m3_m4(tmat, obedit->obmat);
for (i = 0; i < stk->nb_points; i++) {
SK_Point *pt = stk->points + i;
@@ -1579,7 +1573,7 @@ static int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, S
added = MAX2(s_added, added);
}
- BLI_sortlist(list, cmpIntersections);
+ BLI_listbase_sort(list, cmpIntersections);
return added;
}
@@ -1698,7 +1692,7 @@ int sk_detectCommandGesture(bContext *UNUSED(C), SK_Gesture *gest, SK_Sketch *UN
if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 1) {
SK_Intersection *isect, *self_isect;
- /* get the the last intersection of the first pair */
+ /* get the last intersection of the first pair */
for (isect = gest->intersections.first; isect; isect = isect->next) {
if (isect->stroke == isect->next->stroke) {
isect = isect->next;
@@ -1957,7 +1951,7 @@ static void sk_applyGesture(bContext *C, SK_Sketch *sketch)
/********************************************/
-static int sk_selectStroke(bContext *C, SK_Sketch *sketch, const int mval[2], int extend)
+static bool sk_selectStroke(bContext *C, SK_Sketch *sketch, const int mval[2], const bool extend)
{
ViewContext vc;
rcti rect;
@@ -2245,15 +2239,19 @@ static int sketch_delete(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNU
return OPERATOR_FINISHED;
}
-void BIF_sk_selectStroke(bContext *C, const int mval[2], short extend)
+bool BIF_sk_selectStroke(bContext *C, const int mval[2], const bool extend)
{
ToolSettings *ts = CTX_data_tool_settings(C);
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch != NULL && ts->bone_sketching & BONE_SKETCHING) {
- if (sk_selectStroke(C, sketch, mval, extend))
+ if (sk_selectStroke(C, sketch, mval, extend)) {
ED_area_tag_redraw(CTX_wm_area(C));
+ return true;
+ }
}
+
+ return false;
}
void BIF_convertSketch(bContext *C)
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index da68108285f..549a3854bac 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -381,14 +381,14 @@ static void pose_copy_menu(Scene *scene)
* but for constraints (just add local constraints)
*/
if (pose_has_protected_selected(ob, 0)) {
- i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
+ i = BLI_listbase_count(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
if (i < 25)
nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|Constraints... %x5");
else
nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4");
}
else {
- i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
+ i = BLI_listbase_count(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
if (i < 25)
nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|Constraints... %x5|%l|Transform Locks %x6|IK Limits %x7|Bone Shape %x8");
else
@@ -503,7 +503,7 @@ static void pose_copy_menu(Scene *scene)
/* build the puplist of constraints */
for (con = pchanact->constraints.first, i = 0; con; con = con->next, i++) {
const_toggle[i] = 1;
-// add_numbut(i, TOG|INT, con->name, 0, 0, &(const_toggle[i]), "");
+// add_numbut(i, UI_BTYPE_TOGGLE|INT, con->name, 0, 0, &(const_toggle[i]), "");
}
// if (!do_clever_numbuts("Select Constraints", i, REDRAW)) {
@@ -595,7 +595,7 @@ void POSE_OT_flip_names(wmOperatorType *ot)
/* identifiers */
ot->name = "Flip Names";
ot->idname = "POSE_OT_flip_names";
- ot->description = "Flips (and corrects) the axis suffixes of the the names of selected bones";
+ ot->description = "Flips (and corrects) the axis suffixes of the names of selected bones";
/* api callbacks */
ot->exec = pose_flip_names_exec;
@@ -853,7 +853,7 @@ void ARMATURE_OT_armature_layers(wmOperatorType *ot)
/* Present a popup to get the layers that should be used */
static int pose_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
+ int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
/* get layers that are active already */
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
@@ -862,8 +862,7 @@ static int pose_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *e
/* loop over the bits for this pchan's layers, adding layers where they're needed */
for (bit = 0; bit < 32; bit++) {
- if (pchan->bone->layer & (1 << bit))
- layers[bit] = 1;
+ layers[bit] = (pchan->bone->layer & (1 << bit)) != 0;
}
}
CTX_DATA_END;
diff --git a/source/blender/editors/armature/pose_group.c b/source/blender/editors/armature/pose_group.c
index 50d9d300d15..413a74d24b5 100644
--- a/source/blender/editors/armature/pose_group.c
+++ b/source/blender/editors/armature/pose_group.c
@@ -144,8 +144,8 @@ static int pose_groups_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U
/* if there's no active group (or active is invalid), create a new menu to find it */
if (pose->active_group <= 0) {
/* create a new menu, and start populating it with group names */
- pup = uiPupMenuBegin(C, op->type->name, ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
/* special entry - allow to create new group, then use that
* (not to be used for removing though)
@@ -160,9 +160,9 @@ static int pose_groups_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U
uiItemIntO(layout, grp->name, ICON_NONE, op->idname, "type", i);
/* finish building the menu, and process it (should result in calling self again) */
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
else {
/* just use the active group index, and call the exec callback for the calling operator */
@@ -365,8 +365,8 @@ typedef struct tSortActionGroup {
/* compare bone groups by name */
static int compare_agroup(const void *sgrp_a_ptr, const void *sgrp_b_ptr)
{
- tSortActionGroup *sgrp_a = (tSortActionGroup *)sgrp_a_ptr;
- tSortActionGroup *sgrp_b = (tSortActionGroup *)sgrp_b_ptr;
+ const tSortActionGroup *sgrp_a = sgrp_a_ptr;
+ const tSortActionGroup *sgrp_b = sgrp_b_ptr;
return strcmp(sgrp_a->agrp->name, sgrp_b->agrp->name);
}
@@ -387,7 +387,7 @@ static int group_sort_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
/* create temporary array with bone groups and indices */
- agrp_count = BLI_countlist(&pose->agroups);
+ agrp_count = BLI_listbase_count(&pose->agroups);
agrp_array = MEM_mallocN(sizeof(tSortActionGroup) * agrp_count, "sort bone groups");
for (agrp = pose->agroups.first, i = 0; agrp; agrp = agrp->next, i++) {
BLI_assert(i < agrp_count);
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 0609fcc29e8..d571fb374d9 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -404,8 +404,8 @@ static int poselib_add_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U
return OPERATOR_CANCELLED;
/* start building */
- pup = uiPupMenuBegin(C, op->type->name, ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
/* add new (adds to the first unoccupied frame) */
@@ -420,10 +420,10 @@ static int poselib_add_menu_invoke(bContext *C, wmOperator *op, const wmEvent *U
uiItemMenuF(layout, IFACE_("Replace Existing..."), 0, poselib_add_menu_invoke__replacemenu, NULL);
}
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
/* this operator is only for a menu, not used further */
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
@@ -472,7 +472,7 @@ static int poselib_add_exec(bContext *C, wmOperator *op)
ANIM_apply_keyingset(C, NULL, act, ks, MODIFYKEY_MODE_INSERT, (float)frame);
/* store new 'active' pose number */
- act->active_marker = BLI_countlist(&act->markers);
+ act->active_marker = BLI_listbase_count(&act->markers);
/* done */
return OPERATOR_FINISHED;
@@ -916,7 +916,7 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, tPoseLib_PreviewData
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
ListBase dsources = {NULL, NULL};
- short autokey = autokeyframe_cfra_can_key(scene, &pld->ob->id);
+ bool autokey = autokeyframe_cfra_can_key(scene, &pld->ob->id);
/* start tagging/keying */
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
@@ -1050,7 +1050,7 @@ static void poselib_preview_get_next(tPoseLib_PreviewData *pld, int step)
LinkData *ld, *ldn, *ldc;
/* free and rebuild if needed (i.e. if search-str changed) */
- if (strcmp(pld->searchstr, pld->searchold)) {
+ if (!STREQ(pld->searchstr, pld->searchold)) {
/* free list of temporary search matches */
BLI_freelistN(&pld->searchp);
@@ -1348,7 +1348,7 @@ static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, con
else {
/* change to last pose */
pld->marker = pld->act->markers.last;
- pld->act->active_marker = BLI_countlist(&pld->act->markers);
+ pld->act->active_marker = BLI_listbase_count(&pld->act->markers);
pld->redraw = PL_PREVIEW_REDRAWALL;
}
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index ba5ef4f3b5d..5d5a9bf363c 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -642,7 +642,7 @@ static bool pose_select_same_group(bContext *C, Object *ob, bool extend)
return 0;
/* count the number of groups */
- numGroups = BLI_countlist(&pose->agroups);
+ numGroups = BLI_listbase_count(&pose->agroups);
if (numGroups == 0)
return 0;
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 0cde8f30ace..fbf6dccdb38 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -811,7 +811,7 @@ void POSE_OT_transforms_clear(wmOperatorType *ot)
static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Object *ob = CTX_data_active_object(C);
+ Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
float cframe = (float)CFRA;
const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index 380a3fffc6d..2ba1eedd33b 100644
--- a/source/blender/editors/armature/pose_utils.c
+++ b/source/blender/editors/armature/pose_utils.c
@@ -49,8 +49,6 @@
#include "WM_api.h"
#include "WM_types.h"
-
-
#include "ED_armature.h"
#include "ED_keyframing.h"
@@ -261,7 +259,7 @@ LinkData *poseAnim_mapping_getNextFCurve(ListBase *fcuLinks, LinkData *prev, con
FCurve *fcu = (FCurve *)ld->data;
/* check if paths match */
- if (strcmp(path, fcu->rna_path) == 0)
+ if (STREQ(path, fcu->rna_path))
return ld;
}
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index 8cc6059e87b..f29d15ff416 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -107,7 +107,7 @@ static VertexData *allocVertexData(EditMesh *em)
EditVert *eve;
int totvert, index;
- totvert = BLI_countlist(&em->verts);
+ totvert = BLI_listbase_count(&em->verts);
data = MEM_callocN(sizeof(VertexData) * totvert, "VertexData");
@@ -1141,7 +1141,7 @@ static int compareNodesWeight(void *vnode1, void *vnode2)
void sortNodes(ReebGraph *rg)
{
- BLI_sortlist(&rg->nodes, compareNodesWeight);
+ BLI_listbase_sort(&rg->nodes, compareNodesWeight);
}
static int compareArcsWeight(void *varc1, void *varc2)
@@ -1166,7 +1166,7 @@ static int compareArcsWeight(void *varc1, void *varc2)
void sortArcs(ReebGraph *rg)
{
- BLI_sortlist(&rg->arcs, compareArcsWeight);
+ BLI_listbase_sort(&rg->arcs, compareArcsWeight);
}
/******************************************* JOINING ***************************************************/
@@ -1512,7 +1512,7 @@ static int filterInternalExternalReebGraph(ReebGraph *rg, float threshold_intern
ReebArc *arc = NULL, *nextArc = NULL;
int value = 0;
- BLI_sortlist(&rg->arcs, compareArcs);
+ BLI_listbase_sort(&rg->arcs, compareArcs);
for (arc = rg->arcs.first; arc; arc = nextArc) {
nextArc = arc->next;
@@ -1632,7 +1632,7 @@ int filterSmartReebGraph(ReebGraph *UNUSED(rg), float UNUSED(threshold))
#if 0 //XXX
ReebArc *arc = NULL, *nextArc = NULL;
- BLI_sortlist(&rg->arcs, compareArcs);
+ BLI_listbase_sort(&rg->arcs, compareArcs);
#ifdef DEBUG_REEB
{
@@ -1867,7 +1867,7 @@ static void spreadWeight(EditMesh *em)
{
EditVert **verts, *eve;
float lastWeight = 0.0f;
- int totvert = BLI_countlist(&em->verts);
+ int totvert = BLI_listbase_count(&em->verts);
int i;
int work_needed = 1;
@@ -2399,9 +2399,9 @@ ReebGraph *generateReebGraph(EditMesh *em, int subdivisions)
rg->resolution = subdivisions;
- /*totvert = BLI_countlist(&em->verts);*/ /*UNUSED*/
+ /*totvert = BLI_listbase_count(&em->verts);*/ /*UNUSED*/
#ifdef DEBUG_REEB
- totfaces = BLI_countlist(&em->faces);
+ totfaces = BLI_listbase_count(&em->faces);
#endif
renormalizeWeight(em, 1.0f);
@@ -2460,7 +2460,7 @@ void renormalizeWeight(EditMesh *em, float newmax)
EditVert *eve;
float minimum, maximum, range;
- if (em == NULL || BLI_countlist(&em->verts) == 0)
+ if (em == NULL || BLI_listbase_is_empty(&em->verts))
return;
/* First pass, determine maximum and minimum */
@@ -2486,7 +2486,7 @@ int weightFromLoc(EditMesh *em, int axis)
{
EditVert *eve;
- if (em == NULL || BLI_countlist(&em->verts) == 0 || axis < 0 || axis > 2)
+ if (em == NULL || BLI_listbase_is_empty(&em->verts) || axis < 0 || axis > 2)
return 0;
/* Copy coordinate in weight */
@@ -2738,7 +2738,7 @@ static void buildIndexedEdges(EditMesh *em, EdgeIndex *indexed_edges)
int tot_indexed = 0;
int offset = 0;
- totvert = BLI_countlist(&em->verts);
+ totvert = BLI_listbase_count(&em->verts);
indexed_edges->offset = MEM_callocN(totvert * sizeof(int), "EdgeIndex offset");
@@ -2791,13 +2791,13 @@ int weightFromDistance(EditMesh *em, EdgeIndex *indexed_edges)
int totvert = 0;
int vCount = 0;
- totvert = BLI_countlist(&em->verts);
+ totvert = BLI_listbase_count(&em->verts);
if (em == NULL || totvert == 0) {
return 0;
}
- totedge = BLI_countlist(&em->edges);
+ totedge = BLI_listbase_count(&em->edges);
if (totedge == 0) {
return 0;
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index f1b34182439..0f42dc923a4 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -36,10 +36,6 @@
#include "DNA_curve_types.h"
#include "DNA_scene_types.h"
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-
-
#include "RNA_access.h"
#include "WM_api.h"
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index a52b2a619dc..936a40b83b6 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -85,6 +85,7 @@ typedef struct {
GHash *undoIndex;
ListBase fcurves, drivers;
int actnu;
+ int flag;
} UndoCurve;
/* Definitions needed for shape keys */
@@ -233,6 +234,7 @@ static int isNurbsel_count(Curve *cu, Nurb *nu)
/* ******************* PRINTS ********************* */
+#if 0
void printknots(Object *obedit)
{
ListBase *editnurb = object_editcurve_get(obedit);
@@ -252,6 +254,7 @@ void printknots(Object *obedit)
}
}
}
+#endif
/* ********************* Shape keys *************** */
@@ -642,25 +645,20 @@ static void keyData_switchDirectionNurb(Curve *cu, Nurb *nu)
static GHash *dupli_keyIndexHash(GHash *keyindex)
{
GHash *gh;
- GHashIterator *hashIter;
+ GHashIterator gh_iter;
gh = BLI_ghash_ptr_new_ex("dupli_keyIndex gh", BLI_ghash_size(keyindex));
- for (hashIter = BLI_ghashIterator_new(keyindex);
- BLI_ghashIterator_done(hashIter) == false;
- BLI_ghashIterator_step(hashIter))
- {
- void *cv = BLI_ghashIterator_getKey(hashIter);
- CVKeyIndex *index = BLI_ghashIterator_getValue(hashIter);
- CVKeyIndex *newIndex = MEM_callocN(sizeof(CVKeyIndex), "dupli_keyIndexHash index");
+ GHASH_ITER (gh_iter, keyindex) {
+ void *cv = BLI_ghashIterator_getKey(&gh_iter);
+ CVKeyIndex *index = BLI_ghashIterator_getValue(&gh_iter);
+ CVKeyIndex *newIndex = MEM_mallocN(sizeof(CVKeyIndex), "dupli_keyIndexHash index");
memcpy(newIndex, index, sizeof(CVKeyIndex));
BLI_ghash_insert(gh, cv, newIndex);
}
- BLI_ghashIterator_free(hashIter);
-
return gh;
}
@@ -766,16 +764,7 @@ static void calc_shapeKeys(Object *obedit)
/* editing the base key should update others */
if (cu->key->type == KEY_RELATIVE) {
- int act_is_basis = 0;
- /* find if this key is a basis for any others */
- for (currkey = cu->key->block.first; currkey; currkey = currkey->next) {
- if (editnurb->shapenr - 1 == currkey->relative) {
- act_is_basis = 1;
- break;
- }
- }
-
- if (act_is_basis) { /* active key is a base */
+ if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */
int totvec = 0;
/* Calculate needed memory to store offset */
@@ -1007,7 +996,7 @@ static void fcurve_path_rename(AnimData *adt, const char *orig_rna_path, char *r
for (fcu = orig_curves->first; fcu; fcu = nextfcu) {
nextfcu = fcu->next;
- if (!strncmp(fcu->rna_path, orig_rna_path, len)) {
+ if (STREQLEN(fcu->rna_path, orig_rna_path, len)) {
char *spath, *suffix = fcu->rna_path + len;
nfcu = copy_fcurve(fcu);
spath = nfcu->rna_path;
@@ -1110,10 +1099,10 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
for (fcu = orig_curves->first; fcu; fcu = next) {
next = fcu->next;
- if (!strncmp(fcu->rna_path, "splines", 7)) {
+ if (STREQLEN(fcu->rna_path, "splines", 7)) {
const char *ch = strchr(fcu->rna_path, '.');
- if (ch && (!strncmp(ch, ".bezier_points", 14) || !strncmp(ch, ".points", 7)))
+ if (ch && (STREQLEN(ch, ".bezier_points", 14) || STREQLEN(ch, ".points", 7)))
fcurve_remove(adt, orig_curves, fcu);
}
}
@@ -1137,7 +1126,7 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves)
for (fcu = orig_curves->first; fcu; fcu = next) {
next = fcu->next;
- if (!strncmp(fcu->rna_path, "splines", 7)) fcurve_remove(adt, orig_curves, fcu);
+ if (STREQLEN(fcu->rna_path, "splines", 7)) fcurve_remove(adt, orig_curves, fcu);
else BLI_addtail(&curves, fcu);
}
@@ -1358,7 +1347,7 @@ void make_editNurb(Object *obedit)
if (actkey) {
// XXX strcpy(G.editModeTitleExtra, "(Key) ");
undo_editmode_clear();
- BKE_key_convert_to_curve(actkey, cu, &cu->nurb);
+ BKE_keyblock_convert_to_curve(actkey, cu, &cu->nurb);
}
if (editnurb) {
@@ -2015,7 +2004,7 @@ static void ed_curve_delete_selected(Object *obedit)
}
/* only for OB_SURF */
-bool ed_editnurb_extrude_flag(EditNurb *editnurb, short flag)
+bool ed_editnurb_extrude_flag(EditNurb *editnurb, const short flag)
{
Nurb *nu;
BPoint *bp, *bpn, *newbp;
@@ -2376,7 +2365,6 @@ static void adduplicateflagNurb(Object *obedit, ListBase *newnurb,
}
else {
/* knots done after duplicate as pntsu may change */
- nu->knotsu = nu->knotsv = NULL;
BKE_nurb_order_clamp_u(nu);
BKE_nurb_knot_calc_u(nu);
@@ -4799,7 +4787,7 @@ bool ed_editnurb_spin(float viewmat[4][4], Object *obedit, const float axis[3],
ok = true;
for (a = 0; a < 7; a++) {
- ok = ed_editnurb_extrude_flag(cu->editnurb, 1);
+ ok = ed_editnurb_extrude_flag(cu->editnurb, SELECT);
if (ok == false)
return changed;
@@ -4897,285 +4885,409 @@ void CURVE_OT_spin(wmOperatorType *ot)
RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f);
}
-/***************** add vertex operator **********************/
+/***************** extrude vertex operator **********************/
-static int addvert_Nurb(bContext *C, short mode, float location[3])
+static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb)
{
- Object *obedit = CTX_data_edit_object(C);
- Curve *cu = (Curve *)obedit->data;
- EditNurb *editnurb = cu->editnurb;
- Nurb *nu, *newnu = NULL;
- BezTriple *bezt, *newbezt = NULL;
- BPoint *bp, *newbp = NULL;
- float imat[4][4], temp[3];
- bool ok = false;
- BezTriple *bezt_recalc[3] = {NULL};
+ Nurb *nu = NULL;
+ Nurb *nu_last = NULL;
- invert_m4_m4(imat, obedit->obmat);
+ bool changed = false;
- findselectedNurbvert(&editnurb->nurbs, &nu, &bezt, &bp);
-
- if ((nu == NULL) || (nu->type == CU_BEZIER && bezt == NULL) || (nu->type != CU_BEZIER && bp == NULL)) {
- if (mode != 'e') {
- if (cu->actnu != CU_ACT_NONE)
- nu = BLI_findlink(&editnurb->nurbs, cu->actnu);
-
- if (!nu || nu->type == CU_BEZIER) {
- newbezt = (BezTriple *)MEM_callocN(sizeof(BezTriple), "addvert_Nurb");
- newbezt->radius = 1;
- newbezt->alfa = 0;
- BEZ_SEL(newbezt);
- newbezt->h2 = newbezt->h1 = HD_AUTO;
-
- newnu = (Nurb *)MEM_callocN(sizeof(Nurb), "addvert_Nurb newnu");
- if (!nu) {
- /* no selected segment -- create new one which is BEZIER type
- * type couldn't be determined from Curve bt could be changed
- * in the future, so shouldn't make much headache */
- newnu->type = CU_BEZIER;
- newnu->resolu = cu->resolu;
- newnu->flag |= CU_SMOOTH;
- }
- else {
- memcpy(newnu, nu, sizeof(Nurb));
- }
+ Nurb *cu_actnu;
+ union {
+ BezTriple *bezt;
+ BPoint *bp;
+ void *p;
+ } cu_actvert;
- BLI_addtail(&editnurb->nurbs, newnu);
- newnu->bezt = newbezt;
- newnu->pntsu = 1;
+ if (BLI_listbase_is_empty(&editnurb->nurbs)) {
+ return changed;
+ }
- temp[0] = 1;
- temp[1] = 0;
- temp[2] = 0;
+ BKE_curve_nurb_vert_active_get(cu, &cu_actnu, &cu_actvert.p);
+ BKE_curve_nurb_vert_active_set(cu, NULL, NULL);
- copy_v3_v3(newbezt->vec[1], location);
- sub_v3_v3v3(newbezt->vec[0], newbezt->vec[1], temp);
- add_v3_v3v3(newbezt->vec[2], newbezt->vec[1], temp);
+ /* first pass (endpoints) */
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
- mul_m4_v3(imat, newbezt->vec[0]);
- mul_m4_v3(imat, newbezt->vec[1]);
- mul_m4_v3(imat, newbezt->vec[2]);
+ if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) {
+ continue;
+ }
- ok = 1;
- nu = newnu;
- }
- else if (nu->pntsv == 1) {
- newbp = (BPoint *)MEM_callocN(sizeof(BPoint), "addvert_Nurb5");
- newbp->radius = 1;
- newbp->alfa = 0;
- newbp->f1 |= SELECT;
+ if (nu->type == CU_BEZIER) {
- newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
- memcpy(newnu, nu, sizeof(Nurb));
- BLI_addtail(&editnurb->nurbs, newnu);
- newnu->bp = newbp;
- newnu->orderu = 2;
- newnu->pntsu = 1;
+ /* Check to see if the first bezier point is selected */
+ if (nu->pntsu > 0 && nu->bezt != NULL) {
+ BezTriple *nu_bezt_old = nu->bezt;
+ BezTriple *bezt = nu->bezt;
- mul_v3_m4v3(newbp->vec, imat, location);
- newbp->vec[3] = 1.0;
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+ BezTriple *bezt_new;
+ BEZ_DESEL(bezt);
- newnu->knotsu = newnu->knotsv = NULL;
- BKE_nurb_knot_calc_u(newnu);
+ bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__);
+ ED_curve_beztcpy(editnurb, bezt_new + 1, bezt, nu->pntsu);
+ *bezt_new = *bezt;
- ok = 1;
- nu = newnu;
+
+ MEM_freeN(nu->bezt);
+ nu->bezt = bezt_new;
+
+ nu->pntsu += 1;
+
+ if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) {
+ cu_actvert.bezt = (cu_actvert.bezt == bezt) ?
+ bezt_new : &nu->bezt[(cu_actvert.bezt - nu_bezt_old) + 1];
+ BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt);
+ }
+
+ BEZ_SEL(bezt_new);
+ changed = true;
+ }
}
+ /* Check to see if the last bezier point is selected */
+ if (nu->pntsu > 1) {
+ BezTriple *nu_bezt_old = nu->bezt;
+ BezTriple *bezt = &nu->bezt[nu->pntsu - 1];
+
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+ BezTriple *bezt_new;
+ BEZ_DESEL(bezt);
+
+ bezt_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BezTriple), __func__);
+ ED_curve_beztcpy(editnurb, bezt_new, nu->bezt, nu->pntsu);
+ bezt_new[nu->pntsu] = *bezt;
+
+ MEM_freeN(nu->bezt);
+ nu->bezt = bezt_new;
+
+ bezt_new += nu->pntsu;
+ nu->pntsu += 1;
+
+ if (ARRAY_HAS_ITEM(cu_actvert.bezt, nu_bezt_old, nu->pntsu - 1)) {
+ cu_actvert.bezt = (cu_actvert.bezt == bezt) ?
+ bezt_new : &nu->bezt[cu_actvert.bezt - nu_bezt_old];
+ BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bezt);
+ }
+
+ BEZ_SEL(bezt_new);
+ changed = true;
+ }
+ }
}
+ else {
- if (!ok)
- return OPERATOR_CANCELLED;
- }
+ /* Check to see if the first bpoint is selected */
+ if (nu->pntsu > 0 && nu->bp != NULL) {
+ BPoint *nu_bp_old = nu->bp;
+ BPoint *bp = nu->bp;
- if (!ok && nu->type == CU_BEZIER) {
- /* which bezpoint? */
- if (bezt == &nu->bezt[nu->pntsu - 1]) { /* last */
- BEZ_DESEL(bezt);
- newbezt = (BezTriple *)MEM_callocN((nu->pntsu + 1) * sizeof(BezTriple), "addvert_Nurb");
- ED_curve_beztcpy(editnurb, newbezt, nu->bezt, nu->pntsu);
- newbezt[nu->pntsu] = *bezt;
- copy_v3_v3(temp, bezt->vec[1]);
- MEM_freeN(nu->bezt);
- nu->bezt = newbezt;
- newbezt += nu->pntsu;
- BEZ_SEL(newbezt);
- newbezt->h1 = newbezt->h2;
- bezt = &nu->bezt[nu->pntsu - 1];
- ok = 1;
+ if (bp->f1 & SELECT) {
+ BPoint *bp_new;
+ bp->f1 &= ~SELECT;
- if (nu->pntsu > 1) {
- bezt_recalc[1] = newbezt;
- bezt_recalc[0] = newbezt - 1;
- }
- }
- else if (bezt == nu->bezt) { /* first */
- BEZ_DESEL(bezt);
- newbezt = (BezTriple *)MEM_callocN((nu->pntsu + 1) * sizeof(BezTriple), "addvert_Nurb");
- ED_curve_beztcpy(editnurb, newbezt + 1, bezt, nu->pntsu);
- *newbezt = *bezt;
- BEZ_SEL(newbezt);
- newbezt->h2 = newbezt->h1;
- copy_v3_v3(temp, bezt->vec[1]);
- MEM_freeN(nu->bezt);
- nu->bezt = newbezt;
- bezt = newbezt + 1;
- ok = 1;
+ bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__);
+ ED_curve_bpcpy(editnurb, bp_new + 1, bp, nu->pntsu);
+ *bp_new = *bp;
+
+ MEM_freeN(nu->bp);
+ nu->bp = bp_new;
+
+ nu->pntsu += 1;
+ BKE_nurb_knot_calc_u(nu);
+
+ if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) {
+ cu_actvert.bp = (cu_actvert.bp == bp) ?
+ bp_new : &nu->bp[(cu_actvert.bp - nu_bp_old) + 1];
+ BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp);
+ }
+
+ bp_new->f1 |= SELECT;
+ changed = true;
+ }
+ }
+ /* Check to see if the last bpoint is selected */
if (nu->pntsu > 1) {
- bezt_recalc[1] = newbezt;
- bezt_recalc[2] = newbezt + 1;
+ BPoint *nu_bp_old = nu->bp;
+ BPoint *bp = &nu->bp[nu->pntsu - 1];
+
+ if (bp->f1 & SELECT) {
+ BPoint *bp_new;
+ bp->f1 &= ~SELECT;
+
+ bp_new = MEM_mallocN((nu->pntsu + 1) * sizeof(BPoint), __func__);
+ ED_curve_bpcpy(editnurb, bp_new, nu->bp, nu->pntsu);
+ bp_new[nu->pntsu] = *bp;
+
+ MEM_freeN(nu->bp);
+ nu->bp = bp_new;
+
+ bp_new += nu->pntsu;
+ nu->pntsu += 1;
+
+ if (ARRAY_HAS_ITEM(cu_actvert.bp, nu_bp_old, nu->pntsu - 1)) {
+ cu_actvert.bp = (cu_actvert.bp == bp) ?
+ bp_new : &nu->bp[cu_actvert.bp - nu_bp_old];
+ BKE_curve_nurb_vert_active_set(cu, nu, cu_actvert.bp);
+ }
+
+ BKE_nurb_knot_calc_u(nu);
+
+ bp_new->f1 |= SELECT;
+ changed = true;
+ }
}
}
- else if (mode != 'e') {
- BEZ_DESEL(bezt);
- newbezt = (BezTriple *)MEM_callocN(sizeof(BezTriple), "addvert_Nurb");
- *newbezt = *bezt;
- BEZ_SEL(newbezt);
- newbezt->h2 = newbezt->h1;
- copy_v3_v3(temp, bezt->vec[1]);
+ }
- newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
- memcpy(newnu, nu, sizeof(Nurb));
- BLI_addtail(&editnurb->nurbs, newnu);
- newnu->bezt = newbezt;
- newnu->pntsu = 1;
+ /* second pass (interior points) */
+ nu_last = editnurb->nurbs.last;
+ for (nu = editnurb->nurbs.first; (nu != nu_last->next); nu = nu->next) {
+ int i, i_end;
- nu = newnu;
- bezt = newbezt;
- ok = 1;
+ if ((nu->flagu & CU_NURB_CYCLIC) && (nu->pntsu > 1)) {
+ /* all points are interior */
+ i = 0;
+ i_end = nu->pntsu;
}
else {
- bezt = NULL;
+ /* skip endpoints */
+ i = 1;
+ i_end = nu->pntsu - 1;
}
- if (bezt) {
- if (!newnu) nu->pntsu++;
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt;
- if (mode == 'e') {
- copy_v3_v3(newbezt->vec[0], bezt->vec[0]);
- copy_v3_v3(newbezt->vec[1], bezt->vec[1]);
- copy_v3_v3(newbezt->vec[2], bezt->vec[2]);
- }
- else {
- mul_v3_m4v3(newbezt->vec[1], imat, location);
- sub_v3_v3v3(temp, newbezt->vec[1], temp);
+ for (bezt = &nu->bezt[i]; i < i_end; i++, bezt++) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+ Nurb *nurb_new;
+ BezTriple *bezt_new;
+
+ BEZ_DESEL(bezt);
+ nurb_new = BKE_nurb_copy(nu, 1, 1);
+ nurb_new->flagu &= ~CU_NURB_CYCLIC;
+ BLI_addtail(&editnurb->nurbs, nurb_new);
+ bezt_new = nurb_new->bezt;
+ ED_curve_beztcpy(editnurb, bezt_new, bezt, 1);
+ BEZ_SEL(bezt_new);
+
+ if (cu_actvert.bezt == bezt || cu_actnu == NULL) {
+ BKE_curve_nurb_vert_active_set(cu, nurb_new, bezt_new);
+ }
- if (bezt_recalc[1]) {
- const char h1 = bezt_recalc[1]->h1, h2 = bezt_recalc[1]->h2;
- bezt_recalc[1]->h1 = bezt_recalc[1]->h2 = HD_AUTO;
- BKE_nurb_handle_calc(bezt_recalc[1], bezt_recalc[0], bezt_recalc[2], 0);
- bezt_recalc[1]->h1 = h1;
- bezt_recalc[1]->h2 = h2;
- }
- else {
- add_v3_v3v3(newbezt->vec[0], bezt->vec[0], temp);
- add_v3_v3v3(newbezt->vec[2], bezt->vec[2], temp);
+ changed = true;
}
-
+ }
+ }
+ else {
+ BPoint *bp;
- if (newnu) BKE_nurb_handles_calc(newnu);
- else BKE_nurb_handles_calc(nu);
+ for (bp = &nu->bp[i]; i < i_end; i++, bp++) {
+ if (bp->f1 & SELECT) {
+ Nurb *nurb_new;
+ BPoint *bp_new;
+
+ bp->f1 &= ~SELECT;
+ nurb_new = BKE_nurb_copy(nu, 1, 1);
+ nurb_new->flagu &= ~CU_NURB_CYCLIC;
+ BLI_addtail(&editnurb->nurbs, nurb_new);
+ bp_new = nurb_new->bp;
+ ED_curve_bpcpy(editnurb, bp_new, bp, 1);
+ bp_new->f1 |= SELECT;
+
+ if (cu_actvert.bp == bp || cu_actnu == NULL) {
+ BKE_curve_nurb_vert_active_set(cu, nurb_new, bp_new);
+ }
+
+ changed = true;
+ }
}
}
}
- else if (!ok && nu->pntsv == 1) {
- /* which b-point? */
- if (bp == &nu->bp[nu->pntsu - 1]) { /* last */
- bp->f1 = 0;
- newbp = (BPoint *)MEM_callocN((nu->pntsu + 1) * sizeof(BPoint), "addvert_Nurb4");
- ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu);
- newbp[nu->pntsu] = *bp;
- MEM_freeN(nu->bp);
- nu->bp = newbp;
- newbp += nu->pntsu;
- newbp->f1 |= SELECT;
- bp = newbp - 1;
- ok = 1;
- }
- else if (bp == nu->bp) { /* first */
- bp->f1 = 0;
- newbp = (BPoint *)MEM_callocN((nu->pntsu + 1) * sizeof(BPoint), "addvert_Nurb3");
- ED_curve_bpcpy(editnurb, newbp + 1, bp, nu->pntsu);
- *newbp = *bp;
- newbp->f1 |= SELECT;
- MEM_freeN(nu->bp);
- nu->bp = newbp;
- bp = newbp + 1;
- ok = 1;
- }
- else if (mode != 'e') {
- bp->f1 = 0;
- newbp = (BPoint *)MEM_callocN(sizeof(BPoint), "addvert_Nurb5");
- *newbp = *bp;
- newbp->f1 |= SELECT;
- newnu = (Nurb *)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu");
- memcpy(newnu, nu, sizeof(Nurb));
- BLI_addtail(&editnurb->nurbs, newnu);
- newnu->bp = newbp;
- newnu->orderu = 2;
- newnu->pntsu = 1;
- newnu->knotsu = newnu->knotsv = NULL;
+ if (changed == false) {
+ BKE_curve_nurb_vert_active_set(cu, cu_actnu, cu_actvert.p);
+ }
- nu = newnu;
- bp = newbp;
- ok = 1;
+ return changed;
+}
+
+/***************** add vertex operator **********************/
+
+static int ed_editcurve_addvert(Curve *cu, EditNurb *editnurb, const float location[3])
+{
+ Nurb *nu;
+
+ float minmax[2][3];
+ float temp[3];
+ bool nu_has_select = false;
+
+ bool changed = false;
+
+ INIT_MINMAX(minmax[0], minmax[1]);
+
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ int i;
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt;
+
+ for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+ minmax_v3v3_v3(UNPACK2(minmax), bezt->vec[1]);
+ nu_has_select = true;
+ }
+ }
}
else {
- bp = NULL;
+ BPoint *bp;
+
+ for (i = 0, bp = nu->bp; i < nu->pntsu; i++, bp++) {
+ if (bp->f1 & SELECT) {
+ minmax_v3v3_v3(UNPACK2(minmax), bp->vec);
+ nu_has_select = true;
+ }
+ }
}
+ }
+
+ if (nu_has_select && ed_editcurve_extrude(cu, editnurb)) {
+ float ofs[3], center[3];
+ int i;
+
+ mid_v3_v3v3(center, minmax[0], minmax[1]);
+ sub_v3_v3v3(ofs, location, center);
- if (bp) {
- if (mode == 'e') {
- copy_v3_v3(newbp->vec, bp->vec);
+ if ((cu->flag & CU_3D) == 0) {
+ ofs[2] = 0.0f;
+ }
+
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ BezTriple *bezt;
+ for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+ add_v3_v3(bezt->vec[0], ofs);
+ add_v3_v3(bezt->vec[1], ofs);
+ add_v3_v3(bezt->vec[2], ofs);
+
+ if (((nu->flagu & CU_NURB_CYCLIC) == 0) &&
+ (i == 0 || i == nu->pntsu - 1))
+ {
+ BKE_nurb_handle_calc_simple_auto(nu, bezt);
+ }
+ }
+ }
}
else {
- mul_v3_m4v3(newbp->vec, imat, location);
- newbp->vec[3] = 1.0;
+ BPoint *bp;
- if (!newnu && nu->orderu < 4 && nu->orderu <= nu->pntsu)
- nu->orderu++;
+ for (i = 0, bp = nu->bp; i < nu->pntsu; i++, bp++) {
+ if (bp->f1 & SELECT) {
+ add_v3_v3(bp->vec, ofs);
+ }
+ }
}
+ }
+ changed = true;
+ }
+ else {
+ /* nothing selected: create a new curve */
+ nu = BKE_curve_nurb_active_get(cu);
- if (!newnu) {
- nu->pntsu++;
- BKE_nurb_knot_calc_u(nu);
+ if (!nu || nu->type == CU_BEZIER) {
+ Nurb *nurb_new;
+ BezTriple *bezt_new;
+
+ if (nu) {
+ nurb_new = BKE_nurb_copy(nu, 1, 1);
}
else {
- BKE_nurb_knot_calc_u(newnu);
+ nurb_new = MEM_callocN(sizeof(Nurb), "BLI_editcurve_addvert new_bezt_nurb 2");
+ nurb_new->type = CU_BEZIER;
+ nurb_new->resolu = cu->resolu;
+ nurb_new->orderu = 4;
+ nurb_new->flag |= CU_SMOOTH;
+ BKE_nurb_bezierPoints_add(nurb_new, 1);
}
- }
- }
+ BLI_addtail(&editnurb->nurbs, nurb_new);
- if (ok) {
- if (nu->bezt) {
- BKE_curve_nurb_vert_active_set(cu, nu, newbezt);
+ bezt_new = nurb_new->bezt;
+
+ BEZ_SEL(bezt_new);
+
+ bezt_new->h1 = HD_AUTO;
+ bezt_new->h2 = HD_AUTO;
+
+ temp[0] = 1.0f;
+ temp[1] = 0.0f;
+ temp[2] = 0.0f;
+
+ copy_v3_v3(bezt_new->vec[1], location);
+ sub_v3_v3v3(bezt_new->vec[0], bezt_new->vec[1], temp);
+ add_v3_v3v3(bezt_new->vec[2], bezt_new->vec[1], temp);
+
+ changed = true;
}
else {
- BKE_curve_nurb_vert_active_set(cu, nu, newbp);
- }
+ Nurb *nurb_new;
+ BPoint *bp_new;
- BKE_nurb_test2D(nu);
+ {
+ nurb_new = MEM_callocN(sizeof(Nurb), __func__);
+ nurb_new->type = CU_POLY;
+ nurb_new->resolu = cu->resolu;
+ nurb_new->flag |= CU_SMOOTH;
+ nurb_new->orderu = 4;
+ BKE_nurb_points_add(nurb_new, 1);
+ }
+ BLI_addtail(&editnurb->nurbs, nurb_new);
- if (ED_curve_updateAnimPaths(obedit->data))
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ bp_new = nurb_new->bp;
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DAG_id_tag_update(obedit->data, 0);
+ bp_new->f1 |= SELECT;
- return OPERATOR_FINISHED;
+ copy_v3_v3(bp_new->vec, location);
+ bp_new->vec[3] = 1.0f;
+
+ BKE_nurb_knot_calc_u(nurb_new);
+
+ changed = true;
+ }
}
- return OPERATOR_CANCELLED;
+ return changed;
}
static int add_vertex_exec(bContext *C, wmOperator *op)
{
+ Object *obedit = CTX_data_edit_object(C);
+ Curve *cu = obedit->data;
+ EditNurb *editnurb = cu->editnurb;
float location[3];
+ float imat[4][4];
RNA_float_get_array(op->ptr, "location", location);
- return addvert_Nurb(C, 0, location);
+
+ invert_m4_m4(imat, obedit->obmat);
+ mul_m4_v3(imat, location);
+
+ if (ed_editcurve_addvert(cu, editnurb, location)) {
+ if (ED_curve_updateAnimPaths(obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DAG_id_tag_update(obedit->data, 0);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -5244,29 +5356,39 @@ void CURVE_OT_vertex_add(wmOperatorType *ot)
/***************** extrude operator **********************/
-static int extrude_exec(bContext *C, wmOperator *UNUSED(op))
+static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
EditNurb *editnurb = cu->editnurb;
- Nurb *nu;
+ bool changed = false;
+ bool as_curve = false;
/* first test: curve? */
- for (nu = editnurb->nurbs.first; nu; nu = nu->next)
- if (nu->pntsv == 1 && isNurbsel_count(cu, nu) == 1)
- break;
+ if (obedit->type != OB_CURVE) {
+ Nurb *nu;
+ for (nu = editnurb->nurbs.first; nu; nu = nu->next) {
+ if (nu->pntsv == 1 && isNurbsel_count(cu, nu) == 1) {
+ as_curve = true;
+ break;
+ }
+ }
+ }
- if (obedit->type == OB_CURVE || nu) {
- addvert_Nurb(C, 'e', NULL);
+ if (obedit->type == OB_CURVE || as_curve) {
+ changed = ed_editcurve_extrude(cu, editnurb);
}
else {
- if (ed_editnurb_extrude_flag(editnurb, 1)) { /* '1'= flag */
- if (ED_curve_updateAnimPaths(obedit->data))
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ changed = ed_editnurb_extrude_flag(editnurb, SELECT);
+ }
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DAG_id_tag_update(obedit->data, 0);
+ if (changed) {
+ if (ED_curve_updateAnimPaths(obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
}
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DAG_id_tag_update(obedit->data, 0);
}
return OPERATOR_FINISHED;
@@ -5280,7 +5402,7 @@ void CURVE_OT_extrude(wmOperatorType *ot)
ot->idname = "CURVE_OT_extrude";
/* api callbacks */
- ot->exec = extrude_exec;
+ ot->exec = curve_extrude_exec;
ot->poll = ED_operator_editsurfcurve;
/* flags */
@@ -5382,11 +5504,11 @@ static int toggle_cyclic_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->pntsu > 1 || nu->pntsv > 1) {
if (nu->type == CU_NURBS) {
- pup = uiPupMenuBegin(C, IFACE_("Direction"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("Direction"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiItemsEnumO(layout, op->type->idname, "direction");
- uiPupMenuEnd(C, pup);
- return OPERATOR_CANCELLED;
+ UI_popup_menu_end(C, pup);
+ return OPERATOR_INTERFACE;
}
}
}
@@ -6551,7 +6673,6 @@ static int curve_delete_segments(Object *obedit, const bool split)
}
}
- nu->knotsu = nu->knotsv = NULL;
BKE_nurb_order_clamp_u(nu);
BKE_nurb_knot_calc_u(nu);
@@ -6648,7 +6769,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
ListBase *editnurb = object_editcurve_get(obedit);
Nurb *nu;
- int clear = (strcmp(op->idname, "CURVE_OT_shade_flat") == 0);
+ int clear = (STREQ(op->idname, "CURVE_OT_shade_flat"));
if (obedit->type != OB_CURVE)
return OPERATOR_CANCELLED;
@@ -6889,6 +7010,7 @@ static void undoCurve_to_editCurve(void *ucu, void *UNUSED(edata), void *cu_v)
cu->actvert = undoCurve->actvert;
cu->actnu = undoCurve->actnu;
+ cu->flag = undoCurve->flag;
ED_curve_updateAnimPaths(cu);
}
@@ -6928,6 +7050,7 @@ static void *editCurve_to_undoCurve(void *UNUSED(edata), void *cu_v)
undoCurve->actvert = cu->actvert;
undoCurve->actnu = cu->actnu;
+ undoCurve->flag = cu->flag;
return undoCurve;
}
diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c
index 8a3d4f3f4f5..7c53896b969 100644
--- a/source/blender/editors/curve/editcurve_add.c
+++ b/source/blender/editors/curve/editcurve_add.c
@@ -355,10 +355,10 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type
mul_mat3_m4_v3(mat, vec);
- ed_editnurb_translate_flag(editnurb, 1, vec);
- ed_editnurb_extrude_flag(cu->editnurb, 1);
+ ed_editnurb_translate_flag(editnurb, SELECT, vec);
+ ed_editnurb_extrude_flag(cu->editnurb, SELECT);
mul_v3_fl(vec, -2.0f);
- ed_editnurb_translate_flag(editnurb, 1, vec);
+ ed_editnurb_translate_flag(editnurb, SELECT, vec);
BLI_remlink(editnurb, nu);
@@ -460,7 +460,7 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type
if (nu) { /* should always be set */
nu->flag |= CU_SMOOTH;
- cu->actnu = BLI_countlist(editnurb);
+ cu->actnu = BLI_listbase_count(editnurb);
cu->actvert = CU_ACT_NONE;
BKE_nurb_test2D(nu);
@@ -529,11 +529,9 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
if (newob && enter_editmode)
ED_undo_push(C, "Enter Editmode");
- ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, false);
+ ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
dia = RNA_float_get(op->ptr, "radius");
- mat[0][0] *= dia;
- mat[1][1] *= dia;
- mat[2][2] *= dia;
+ mul_mat3_m4_fl(mat, dia);
nu = add_nurbs_primitive(C, obedit, mat, type, newob);
editnurb = object_editcurve_get(obedit);
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 4655deec4c4..8393acc6919 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -500,7 +500,7 @@ void FONT_OT_text_paste_from_file(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_TEXT, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
}
@@ -558,7 +558,7 @@ void FONT_OT_text_paste_from_clipboard(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_TEXT, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
}
@@ -668,7 +668,7 @@ void ED_text_to_object(bContext *C, Text *text, const bool split_lines)
offset[1] = 0.0f;
offset[2] = 0.0f;
- txt_add_object(C, text->lines.first, BLI_countlist(&text->lines), offset);
+ txt_add_object(C, text->lines.first, BLI_listbase_count(&text->lines), offset);
}
}
@@ -1744,7 +1744,7 @@ static void font_ui_template_init(bContext *C, wmOperator *op)
PropertyPointerRNA *pprop;
op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
- uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
+ UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop);
}
static void font_open_cancel(bContext *UNUSED(C), wmOperator *op)
@@ -1835,7 +1835,7 @@ void FONT_OT_open(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | FTFONTFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_FTFONT, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
}
@@ -1848,7 +1848,7 @@ static int font_unlink_exec(bContext *C, wmOperator *op)
PointerRNA idptr;
PropertyPointerRNA pprop;
- uiIDContextProperty(C, &pprop.ptr, &pprop.prop);
+ UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop);
if (pprop.prop == NULL) {
BKE_report(op->reports, RPT_ERROR, "Incorrect context for running font unlink");
@@ -1884,8 +1884,8 @@ static void undoFont_to_editFont(void *strv, void *ecu, void *UNUSED(obdata))
EditFont *ef = cu->editfont;
const char *str = strv;
- ef->pos = *((short *)str);
- ef->len = *((short *)(str + 2));
+ ef->pos = *((const short *)str);
+ ef->len = *((const short *)(str + 2));
memcpy(ef->textbuf, str + 4, (ef->len + 1) * sizeof(wchar_t));
memcpy(ef->textbufinfo, str + 4 + (ef->len + 1) * sizeof(wchar_t), ef->len * sizeof(CharInfo));
diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt
index 5dc9679777f..58192f59219 100644
--- a/source/blender/editors/gpencil/CMakeLists.txt
+++ b/source/blender/editors/gpencil/CMakeLists.txt
@@ -39,11 +39,12 @@ set(INC_SYS
set(SRC
drawgpencil.c
editaction_gpencil.c
- gpencil_buttons.c
gpencil_edit.c
gpencil_ops.c
gpencil_paint.c
+ gpencil_select.c
gpencil_undo.c
+ gpencil_utils.c
gpencil_intern.h
)
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 5a838d7bc39..55224b87c59 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -27,6 +27,7 @@
* \ingroup edgpencil
*/
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -58,6 +59,8 @@
#include "ED_gpencil.h"
#include "ED_view3d.h"
+#include "UI_resources.h"
+
#include "gpencil_intern.h"
/* ************************************************** */
@@ -73,6 +76,9 @@ typedef enum eDrawStrokeFlags {
GP_DRAWDATA_ONLYI2D = (1 << 3), /* only draw 'image' strokes */
GP_DRAWDATA_IEDITHACK = (1 << 4), /* special hack for drawing strokes in Image Editor (weird coordinates) */
GP_DRAWDATA_NO_XRAY = (1 << 5), /* don't draw xray in 3D view (which is default) */
+ GP_DRAWDATA_NO_ONIONS = (1 << 6), /* no onionskins should be drawn (for animation playback) */
+ GP_DRAWDATA_VOLUMETRIC = (1 << 7), /* draw strokes as "volumetric" circular billboards */
+ GP_DRAWDATA_FILL = (1 << 8), /* fill insides/bounded-regions of strokes */
} eDrawStrokeFlags;
@@ -111,10 +117,10 @@ static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickn
/* draw stroke curve */
if (G.debug & G_DEBUG) setlinestyle(2);
-
+
glLineWidth(oldpressure * thickness);
glBegin(GL_LINE_STRIP);
-
+
for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
/* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
* and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
@@ -126,7 +132,7 @@ static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickn
/* need to roll-back one point to ensure that there are no gaps in the stroke */
if (i != 0) glVertex2iv(&(pt - 1)->x);
-
+
/* now the point we want... */
glVertex2iv(&pt->x);
@@ -136,20 +142,230 @@ static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickn
glVertex2iv(&pt->x);
}
glEnd();
-
+
/* reset for predictable OpenGL context */
glLineWidth(1.0f);
-
+
if (G.debug & G_DEBUG) setlinestyle(0);
}
}
+/* --------- 2D Stroke Drawing Helpers --------- */
+
+/* helper function to calculate x-y drawing coordinates for 2D points */
+static void gp_calc_2d_stroke_xy(bGPDspoint *pt, short sflag, int offsx, int offsy, int winx, int winy, float r_co[2])
+{
+ if (sflag & GP_STROKE_2DSPACE) {
+ r_co[0] = pt->x;
+ r_co[1] = pt->y;
+ }
+ else if (sflag & GP_STROKE_2DIMAGE) {
+ const float x = (float)((pt->x * winx) + offsx);
+ const float y = (float)((pt->y * winy) + offsy);
+
+ r_co[0] = x;
+ r_co[1] = y;
+ }
+ else {
+ const float x = (float)(pt->x / 100 * winx) + offsx;
+ const float y = (float)(pt->y / 100 * winy) + offsy;
+
+ r_co[0] = x;
+ r_co[1] = y;
+ }
+}
+
+/* ----------- Volumetric Strokes --------------- */
+
+/* draw a 2D buffer stroke in "volumetric" style
+ * NOTE: the stroke buffer doesn't have any coordinate offsets/transforms
+ */
+static void gp_draw_stroke_volumetric_buffer(tGPspoint *points, int totpoints, short thickness,
+ short dflag, short UNUSED(sflag))
+{
+ GLUquadricObj *qobj = gluNewQuadric();
+ float modelview[4][4];
+
+ tGPspoint *pt;
+ int i;
+
+ /* error checking */
+ if ((points == NULL) || (totpoints <= 0))
+ return;
+
+ /* check if buffer can be drawn */
+ if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D))
+ return;
+
+ /* get basic matrix - should be camera space (i.e "identity") */
+ glGetFloatv(GL_MODELVIEW_MATRIX, (float *)modelview);
+
+ /* draw points */
+ glPushMatrix();
+
+ for (i = 0, pt = points; i < totpoints; i++, pt++) {
+ /* set the transformed position */
+ // TODO: scale should change based on zoom level, which requires proper translation mult too!
+ modelview[3][0] = pt->x;
+ modelview[3][1] = pt->y;
+
+ glLoadMatrixf((float *)modelview);
+
+ /* draw the disk using the current state... */
+ gluDisk(qobj, 0.0, pt->pressure * thickness, 32, 1);
+
+
+ modelview[3][0] = modelview[3][1] = 0.0f;
+ }
+
+ glPopMatrix();
+ gluDeleteQuadric(qobj);
+}
+
+/* draw a 2D strokes in "volumetric" style */
+static void gp_draw_stroke_volumetric_2d(bGPDspoint *points, int totpoints, short thickness,
+ short dflag, short sflag,
+ int offsx, int offsy, int winx, int winy)
+{
+ GLUquadricObj *qobj = gluNewQuadric();
+ float modelview[4][4];
+ float baseloc[3];
+ float scalefac = 1.0f;
+
+ bGPDspoint *pt;
+ int i;
+
+
+ /* HACK: We need a scale factor for the drawing in the image editor,
+ * which seems to use 1 unit as it's maximum size, whereas everything
+ * else assumes 1 unit = 1 pixel. Otherwise, we only get a massive blob.
+ */
+ if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) {
+ scalefac = 0.001f;
+ }
+
+ /* get basic matrix */
+ glGetFloatv(GL_MODELVIEW_MATRIX, (float *)modelview);
+ copy_v3_v3(baseloc, modelview[3]);
+
+ /* draw points */
+ glPushMatrix();
+
+ for (i = 0, pt = points; i < totpoints; i++, pt++) {
+ /* set the transformed position */
+ float co[2];
+
+ gp_calc_2d_stroke_xy(pt, sflag, offsx, offsy, winx, winy, co);
+ translate_m4(modelview, co[0], co[1], 0.0f);
+
+ glLoadMatrixf((float *)modelview);
+
+ /* draw the disk using the current state... */
+ gluDisk(qobj, 0.0, pt->pressure * thickness * scalefac, 32, 1);
+
+ /* restore matrix */
+ copy_v3_v3(modelview[3], baseloc);
+ }
+
+ glPopMatrix();
+ gluDeleteQuadric(qobj);
+}
+
+/* draw a 3D stroke in "volumetric" style */
+static void gp_draw_stroke_volumetric_3d(bGPDspoint *points, int totpoints, short thickness,
+ short UNUSED(dflag), short UNUSED(sflag))
+{
+ GLUquadricObj *qobj = gluNewQuadric();
+
+ float base_modelview[4][4], modelview[4][4];
+ float base_loc[3];
+
+ bGPDspoint *pt;
+ int i;
+
+
+ /* Get the basic modelview matrix we use for performing calculations */
+ glGetFloatv(GL_MODELVIEW_MATRIX, (float *)base_modelview);
+ copy_v3_v3(base_loc, base_modelview[3]);
+
+ /* Create the basic view-aligned billboard matrix we're going to actually draw qobj with:
+ * - We need to knock out the rotation so that we are
+ * simply left with a camera-facing billboard
+ * - The scale factors here are chosen so that the thickness
+ * is relatively reasonable. Otherwise, it gets far too
+ * large!
+ */
+ scale_m4_fl(modelview, 0.1f);
+
+ /* draw each point as a disk... */
+ glPushMatrix();
+
+ for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
+ /* apply translation to base_modelview, so that the translated point is put in the right place */
+ translate_m4(base_modelview, pt->x, pt->y, pt->z);
+
+ /* copy the translation component to the billboard matrix we're going to use,
+ * then reset the base matrix to the original values so that we can do the same
+ * for the next point without accumulation/pollution effects
+ */
+ copy_v3_v3(modelview[3], base_modelview[3]); /* copy offset value */
+ copy_v3_v3(base_modelview[3], base_loc); /* restore */
+
+ /* apply our billboard matrix for drawing... */
+ glLoadMatrixf((float *)modelview);
+
+ /* draw the disk using the current state... */
+ gluDisk(qobj, 0.0, pt->pressure * thickness, 32, 1);
+ }
+
+ glPopMatrix();
+ gluDeleteQuadric(qobj);
+}
+
+
+/* --------------- Stroke Fills ----------------- */
+
+/* draw fills for shapes */
+static void gp_draw_stroke_fill(bGPDspoint *points, int totpoints, short UNUSED(thickness),
+ short UNUSED(dflag), short sflag,
+ int offsx, int offsy, int winx, int winy)
+{
+ bGPDspoint *pt;
+ int i;
+
+ BLI_assert(totpoints >= 3);
+
+ /* As an initial implementation, we use the OpenGL filled polygon drawing
+ * here since it's the easiest option to implement for this case. It does
+ * come with limitations (notably for concave shapes), though it shouldn't
+ * be much of an issue in most cases.
+ */
+ glBegin(GL_POLYGON);
+
+ for (i = 0, pt = points; i < totpoints; i++, pt++) {
+ if (sflag & GP_STROKE_3DSPACE) {
+ glVertex3fv(&pt->x);
+ }
+ else {
+ float co[2];
+
+ gp_calc_2d_stroke_xy(pt, sflag, offsx, offsy, winx, winy, co);
+ glVertex2fv(co);
+ }
+ }
+
+ glEnd();
+}
+
/* ----- Existing Strokes Drawing (3D and Point) ------ */
/* draw a given stroke - just a single dot (only one point) */
static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dflag, short sflag,
int offsx, int offsy, int winx, int winy)
{
+ /* set point thickness (since there's only one of these) */
+ glPointSize((float)(thickness + 2) * points->pressure);
+
/* draw point */
if (sflag & GP_STROKE_3DSPACE) {
glBegin(GL_POINTS);
@@ -160,18 +376,7 @@ static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dfla
float co[2];
/* get coordinates of point */
- if (sflag & GP_STROKE_2DSPACE) {
- co[0] = points->x;
- co[1] = points->y;
- }
- else if (sflag & GP_STROKE_2DIMAGE) {
- co[0] = (points->x * winx) + offsx;
- co[1] = (points->y * winy) + offsy;
- }
- else {
- co[0] = (points->x / 100 * winx) + offsx;
- co[1] = (points->y / 100 * winy) + offsy;
- }
+ gp_calc_2d_stroke_xy(points, sflag, offsx, offsy, winx, winy, co);
/* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, simple dot looks ok
* - also mandatory in if Image Editor 'image-based' dot
@@ -185,13 +390,13 @@ static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dfla
}
else {
/* draw filled circle as is done in circf (but without the matrix push/pops which screwed things up) */
- GLUquadricObj *qobj = gluNewQuadric();
+ GLUquadricObj *qobj = gluNewQuadric();
- gluQuadricDrawStyle(qobj, GLU_FILL);
+ gluQuadricDrawStyle(qobj, GLU_FILL);
/* need to translate drawing position, but must reset after too! */
glTranslatef(co[0], co[1], 0.0);
- gluDisk(qobj, 0.0, thickness, 32, 1);
+ gluDisk(qobj, 0.0, thickness, 32, 1);
glTranslatef(-co[0], -co[1], 0.0);
gluDeleteQuadric(qobj);
@@ -200,7 +405,7 @@ static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dfla
}
/* draw a given stroke in 3d (i.e. in 3d-space), using simple ogl lines */
-static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness, short debug)
+static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness, bool debug, short UNUSED(sflag))
{
bGPDspoint *pt;
float curpressure = points[0].pressure;
@@ -231,8 +436,9 @@ static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness
}
}
glEnd();
-
+
/* draw debug points of curve on top? */
+ /* XXX: for now, we represent "selected" strokes in the same way as debug, which isn't used anymore */
if (debug) {
glBegin(GL_POINTS);
for (i = 0, pt = points; i < totpoints && pt; i++, pt++)
@@ -244,46 +450,22 @@ static void gp_draw_stroke_3d(bGPDspoint *points, int totpoints, short thickness
/* ----- Fancy 2D-Stroke Drawing ------ */
/* draw a given stroke in 2d */
-static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag,
- short debug, int offsx, int offsy, int winx, int winy)
+static void gp_draw_stroke_2d(bGPDspoint *points, int totpoints, short thickness_s, short dflag, short sflag,
+ bool debug, int offsx, int offsy, int winx, int winy)
{
/* otherwise thickness is twice that of the 3D view */
float thickness = (float)thickness_s * 0.5f;
-
- /* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, 'smooth' opengl lines look better
- * - 'smooth' opengl lines are also required if Image Editor 'image-based' stroke
- */
- if ((thickness < GP_DRAWTHICKNESS_SPECIAL) ||
- ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)))
- {
- bGPDspoint *pt;
- int i;
-
- glBegin(GL_LINE_STRIP);
- for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
- if (sflag & GP_STROKE_2DSPACE) {
- glVertex2f(pt->x, pt->y);
- }
- else if (sflag & GP_STROKE_2DIMAGE) {
- const float x = (pt->x * winx) + offsx;
- const float y = (pt->y * winy) + offsy;
-
- glVertex2f(x, y);
- }
- else {
- const float x = (pt->x / 100 * winx) + offsx;
- const float y = (pt->y / 100 * winy) + offsy;
-
- glVertex2f(x, y);
- }
- }
- glEnd();
+
+ /* strokes in Image Editor need a scale factor, since units there are not pixels! */
+ float scalefac = 1.0f;
+ if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) {
+ scalefac = 0.001f;
}
/* tessellation code - draw stroke as series of connected quads with connection
* edges rotated to minimize shrinking artifacts, and rounded endcaps
*/
- else {
+ {
bGPDspoint *pt1, *pt2;
float pm[2];
int i;
@@ -299,22 +481,8 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s,
float pthick; /* thickness at segment point */
/* get x and y coordinates from points */
- if (sflag & GP_STROKE_2DSPACE) {
- s0[0] = pt1->x; s0[1] = pt1->y;
- s1[0] = pt2->x; s1[1] = pt2->y;
- }
- else if (sflag & GP_STROKE_2DIMAGE) {
- s0[0] = (pt1->x * winx) + offsx;
- s0[1] = (pt1->y * winy) + offsy;
- s1[0] = (pt2->x * winx) + offsx;
- s1[1] = (pt2->y * winy) + offsy;
- }
- else {
- s0[0] = (pt1->x / 100 * winx) + offsx;
- s0[1] = (pt1->y / 100 * winy) + offsy;
- s1[0] = (pt2->x / 100 * winx) + offsx;
- s1[1] = (pt2->y / 100 * winy) + offsy;
- }
+ gp_calc_2d_stroke_xy(pt1, sflag, offsx, offsy, winx, winy, s0);
+ gp_calc_2d_stroke_xy(pt2, sflag, offsx, offsy, winx, winy, s1);
/* calculate gradient and normal - 'angle'=(ny/nx) */
m1[1] = s1[1] - s0[1];
@@ -324,12 +492,12 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s,
m2[0] = m1[1];
/* always use pressure from first point here */
- pthick = (pt1->pressure * thickness);
+ pthick = (pt1->pressure * thickness * scalefac);
/* if the first segment, start of segment is segment's normal */
if (i == 0) {
- /* draw start cap first
- * - make points slightly closer to center (about halfway across)
+ /* draw start cap first
+ * - make points slightly closer to center (about halfway across)
*/
mt[0] = m2[0] * pthick * 0.5f;
mt[1] = m2[1] * pthick * 0.5f;
@@ -369,7 +537,7 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s,
mb[1] = (pm[1] + m2[1]) / 2;
normalize_v2(mb);
- /* calculate gradient to apply
+ /* calculate gradient to apply
* - as basis, use just pthick * bisector gradient
* - if cross-section not as thick as it should be, add extra padding to fix it
*/
@@ -399,7 +567,7 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s,
/* if last segment, also draw end of segment (defined as segment's normal) */
if (i == totpoints - 2) {
/* for once, we use second point's pressure (otherwise it won't be drawn) */
- pthick = (pt2->pressure * thickness);
+ pthick = (pt2->pressure * thickness * scalefac);
/* calculate points for end of segment */
mt[0] = m2[0] * pthick;
@@ -417,8 +585,8 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s,
glVertex2fv(t1);
- /* draw end cap as last step
- * - make points slightly closer to center (about halfway across)
+ /* draw end cap as last step
+ * - make points slightly closer to center (about halfway across)
*/
mt[0] = m2[0] * pthick * 0.5f;
mt[1] = m2[1] * pthick * 0.5f;
@@ -448,52 +616,57 @@ static void gp_draw_stroke(bGPDspoint *points, int totpoints, short thickness_s,
glBegin(GL_POINTS);
for (i = 0, pt = points; i < totpoints && pt; i++, pt++) {
- if (sflag & GP_STROKE_2DSPACE) {
- glVertex2fv(&pt->x);
- }
- else if (sflag & GP_STROKE_2DIMAGE) {
- const float x = (float)((pt->x * winx) + offsx);
- const float y = (float)((pt->y * winy) + offsy);
-
- glVertex2f(x, y);
- }
- else {
- const float x = (float)(pt->x / 100 * winx) + offsx;
- const float y = (float)(pt->y / 100 * winy) + offsy;
-
- glVertex2f(x, y);
- }
+ float co[2];
+
+ gp_calc_2d_stroke_xy(pt, sflag, offsx, offsy, winx, winy, co);
+ glVertex2fv(co);
}
glEnd();
}
}
-/* ----- General Drawing ------ */
+/* ----- Strokes Drawing ------ */
+
+/* Helper for doing all the checks on whether a stroke can be drawn */
+static bool gp_can_draw_stroke(const bGPDstroke *gps, const int dflag)
+{
+ /* skip stroke if it isn't in the right display space for this drawing context */
+ /* 1) 3D Strokes */
+ if ((dflag & GP_DRAWDATA_ONLY3D) && !(gps->flag & GP_STROKE_3DSPACE))
+ return false;
+ if (!(dflag & GP_DRAWDATA_ONLY3D) && (gps->flag & GP_STROKE_3DSPACE))
+ return false;
+
+ /* 2) Screen Space 2D Strokes */
+ if ((dflag & GP_DRAWDATA_ONLYV2D) && !(gps->flag & GP_STROKE_2DSPACE))
+ return false;
+ if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE))
+ return false;
+
+ /* 3) Image Space (2D) */
+ if ((dflag & GP_DRAWDATA_ONLYI2D) && !(gps->flag & GP_STROKE_2DIMAGE))
+ return false;
+ if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE))
+ return false;
+
+
+ /* skip stroke if it doesn't have any valid data */
+ if ((gps->points == NULL) || (gps->totpoints < 1))
+ return false;
+
+ /* stroke can be drawn */
+ return true;
+}
/* draw a set of strokes */
static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag,
- short debug, short lthick, const float color[4])
+ bool debug, short lthick, const float color[4], const float fill_color[4])
{
bGPDstroke *gps;
- /* set color first (may need to reset it again later too) */
- glColor4fv(color);
-
for (gps = gpf->strokes.first; gps; gps = gps->next) {
- /* check if stroke can be drawn - checks here generally fall into pairs */
- if ((dflag & GP_DRAWDATA_ONLY3D) && !(gps->flag & GP_STROKE_3DSPACE))
- continue;
- if (!(dflag & GP_DRAWDATA_ONLY3D) && (gps->flag & GP_STROKE_3DSPACE))
- continue;
- if ((dflag & GP_DRAWDATA_ONLYV2D) && !(gps->flag & GP_STROKE_2DSPACE))
- continue;
- if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE))
- continue;
- if ((dflag & GP_DRAWDATA_ONLYI2D) && !(gps->flag & GP_STROKE_2DIMAGE))
- continue;
- if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE))
- continue;
- if ((gps->points == NULL) || (gps->totpoints < 1))
+ /* check if stroke can be drawn */
+ if (gp_can_draw_stroke(gps, dflag) == false)
continue;
/* check which stroke-drawer to use */
@@ -515,11 +688,27 @@ static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int
#endif
}
- if (gps->totpoints == 1) {
- gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy);
+ /* 3D Fill */
+ if ((dflag & GP_DRAWDATA_FILL) && (gps->totpoints >= 3)) {
+ glColor4fv(fill_color);
+ gp_draw_stroke_fill(gps->points, gps->totpoints, lthick, dflag, gps->flag, offsx, offsy, winx, winy);
+ }
+
+ /* 3D Stroke */
+ glColor4fv(color);
+
+ if (dflag & GP_DRAWDATA_VOLUMETRIC) {
+ /* volumetric stroke drawing */
+ gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, lthick, dflag, gps->flag);
}
else {
- gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, debug);
+ /* 3D Lines - OpenGL primitives-based */
+ if (gps->totpoints == 1) {
+ gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy);
+ }
+ else {
+ gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, debug, gps->flag);
+ }
}
if (no_xray) {
@@ -534,116 +723,301 @@ static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int
}
}
else {
- if (gps->totpoints == 1) {
- gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy);
+ /* 2D - Fill */
+ if ((dflag & GP_DRAWDATA_FILL) && (gps->totpoints >= 3)) {
+ glColor4fv(fill_color);
+ gp_draw_stroke_fill(gps->points, gps->totpoints, lthick, dflag, gps->flag, offsx, offsy, winx, winy);
+ }
+
+ /* 2D Strokes... */
+ glColor4fv(color);
+
+ if (dflag & GP_DRAWDATA_VOLUMETRIC) {
+ /* blob/disk-based "volumetric" drawing */
+ gp_draw_stroke_volumetric_2d(gps->points, gps->totpoints, lthick, dflag, gps->flag, offsx, offsy, winx, winy);
}
else {
- gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, offsx, offsy, winx, winy);
+ /* normal 2D strokes */
+ if (gps->totpoints == 1) {
+ gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy);
+ }
+ else {
+ gp_draw_stroke_2d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, offsx, offsy, winx, winy);
+ }
}
}
}
}
-/* draw grease-pencil datablock */
-static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag)
+/* Draw selected verts for strokes being edited */
+static void gp_draw_strokes_edit(bGPDframe *gpf, int offsx, int offsy, int winx, int winy, short dflag, const float tcolor[3])
{
- bGPDlayer *gpl;
+ bGPDstroke *gps;
- /* reset line drawing style (in case previous user didn't reset) */
- setlinestyle(0);
+ const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY);
+ int mask_orig = 0;
- /* turn on smooth lines (i.e. anti-aliasing) */
- glEnable(GL_LINE_SMOOTH);
+ /* set up depth masks... */
+ if (dflag & GP_DRAWDATA_ONLY3D) {
+ if (no_xray) {
+ glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
+ glDepthMask(0);
+ glEnable(GL_DEPTH_TEST);
+
+ /* first arg is normally rv3d->dist, but this isn't
+ * available here and seems to work quite well without */
+ bglPolygonOffset(1.0f, 1.0f);
+#if 0
+ glEnable(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(-1.0f, -1.0f);
+#endif
+ }
+ }
- /* turn on alpha-blending */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
+
+ /* draw stroke verts */
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ bGPDspoint *pt;
+ float vsize, bsize;
+ int i;
+
+ /* check if stroke can be drawn */
+ if (gp_can_draw_stroke(gps, dflag) == false)
+ continue;
+
+ /* Optimisation: only draw points for selected strokes
+ * We assume that selected points can only occur in
+ * strokes that are selected too.
+ */
+ if ((gps->flag & GP_STROKE_SELECT) == 0)
+ continue;
+
+ /* Get size of verts:
+ * - The selected state needs to be larger than the unselected state so that
+ * they stand out more.
+ * - We use the theme setting for size of the unselected verts
+ */
+ bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
+ if ((int)bsize > 8) {
+ vsize = 10.0f;
+ bsize = 8.0f;
+ }
+ else {
+ vsize = bsize + 2;
+ }
+
+ /* First Pass: Draw all the verts (i.e. these become the unselected state) */
+ if (tcolor != NULL) {
+ /* for now, we assume that the base color of the points is not too close to the real color */
+ glColor3fv(tcolor);
+ }
+ else {
+ /* this doesn't work well with the default theme and black strokes... */
+ UI_ThemeColor(TH_GP_VERTEX);
+ }
+ glPointSize(bsize);
+
+ glBegin(GL_POINTS);
+ for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) {
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ glVertex3fv(&pt->x);
+ }
+ else {
+ float co[2];
+
+ gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co);
+ glVertex2fv(co);
+ }
+ }
+ glEnd();
+
+
+ /* Second Pass: Draw only verts which are selected */
+ UI_ThemeColor(TH_GP_VERTEX_SELECT);
+ glPointSize(vsize);
+
+ glBegin(GL_POINTS);
+ for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ glVertex3fv(&pt->x);
+ }
+ else {
+ float co[2];
+
+ gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co);
+ glVertex2fv(co);
+ }
+ }
+ }
+ glEnd();
+ }
+
+
+ /* clear depth mask */
+ if (dflag & GP_DRAWDATA_ONLY3D) {
+ if (no_xray) {
+ glDepthMask(mask_orig);
+ glDisable(GL_DEPTH_TEST);
+
+ bglPolygonOffset(0.0, 0.0);
+#if 0
+ glDisable(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(0, 0);
+#endif
+ }
+ }
+}
+
+/* ----- General Drawing ------ */
+
+/* draw onion-skinning for a layer */
+static void gp_draw_onionskins(bGPDlayer *gpl, bGPDframe *gpf, int offsx, int offsy, int winx, int winy,
+ int UNUSED(cfra), int dflag, short debug, short lthick)
+{
+ const float alpha = gpl->color[3];
+ float color[4];
+
+ /* 1) Draw Previous Frames First */
+ if (gpl->flag & GP_LAYER_GHOST_PREVCOL) {
+ copy_v3_v3(color, gpl->gcolor_prev);
+ }
+ else {
+ copy_v3_v3(color, gpl->color);
+ }
+
+ if (gpl->gstep) {
+ bGPDframe *gf;
+ float fac;
+
+ /* draw previous frames first */
+ for (gf = gpf->prev; gf; gf = gf->prev) {
+ /* check if frame is drawable */
+ if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
+ /* alpha decreases with distance from curframe index */
+ fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1));
+ color[3] = alpha * fac * 0.66f;
+ gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, color, color);
+ }
+ else
+ break;
+ }
+ }
+ else {
+ /* draw the strokes for the ghost frames (at half of the alpha set by user) */
+ if (gpf->prev) {
+ color[3] = (alpha / 7);
+ gp_draw_strokes(gpf->prev, offsx, offsy, winx, winy, dflag, debug, lthick, color, color);
+ }
+ }
+
+
+ /* 2) Now draw next frames */
+ if (gpl->flag & GP_LAYER_GHOST_NEXTCOL) {
+ copy_v3_v3(color, gpl->gcolor_next);
+ }
+ else {
+ copy_v3_v3(color, gpl->color);
+ }
+
+ if (gpl->gstep_next) {
+ bGPDframe *gf;
+ float fac;
- /* loop over layers, drawing them */
+ /* now draw next frames */
+ for (gf = gpf->next; gf; gf = gf->next) {
+ /* check if frame is drawable */
+ if ((gf->framenum - gpf->framenum) <= gpl->gstep_next) {
+ /* alpha decreases with distance from curframe index */
+ fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep_next + 1));
+ color[3] = alpha * fac * 0.66f;
+ gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, color, color);
+ }
+ else
+ break;
+ }
+ }
+ else {
+ /* draw the strokes for the ghost frames (at half of the alpha set by user) */
+ if (gpf->next) {
+ color[3] = (alpha / 4);
+ gp_draw_strokes(gpf->next, offsx, offsy, winx, winy, dflag, debug, lthick, color, color);
+ }
+ }
+
+ /* 3) restore alpha */
+ glColor4fv(gpl->color);
+}
+
+/* loop over gpencil data layers, drawing them */
+static void gp_draw_data_layers(bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag)
+{
+ bGPDlayer *gpl;
+
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
bGPDframe *gpf;
- short debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? 1 : 0;
+ bool debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? true : false;
short lthick = gpl->thickness;
- float color[4], tcolor[4];
/* don't draw layer if hidden */
- if (gpl->flag & GP_LAYER_HIDE)
+ if (gpl->flag & GP_LAYER_HIDE)
continue;
/* get frame to draw */
gpf = gpencil_layer_getframe(gpl, cfra, 0);
- if (gpf == NULL)
+ if (gpf == NULL)
continue;
- /* set color, stroke thickness, and point size */
+ /* set basic stroke thickness */
glLineWidth(lthick);
- copy_v4_v4(color, gpl->color); // just for copying 4 array elements
- copy_v4_v4(tcolor, gpl->color); // additional copy of color (for ghosting)
- glColor4fv(color);
- glPointSize((float)(gpl->thickness + 2));
- /* apply xray layer setting */
- if (gpl->flag & GP_LAYER_NO_XRAY) dflag |= GP_DRAWDATA_NO_XRAY;
- else dflag &= ~GP_DRAWDATA_NO_XRAY;
+ /* Add layer drawing settings to the set of "draw flags"
+ * NOTE: If the setting doesn't apply, it *must* be cleared,
+ * as dflag's carry over from the previous layer
+ */
+#define GP_DRAWFLAG_APPLY(condition, draw_flag_value) { \
+ if (condition) dflag |= (draw_flag_value); \
+ else dflag &= ~(draw_flag_value); \
+ } (void)0
+
+ /* xray... */
+ GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_NO_XRAY), GP_DRAWDATA_NO_XRAY);
+
+ /* volumetric strokes... */
+ GP_DRAWFLAG_APPLY((gpl->flag & GP_LAYER_VOLUMETRIC), GP_DRAWDATA_VOLUMETRIC);
+
+ /* fill strokes... */
+ // XXX: this is not a very good limit
+ GP_DRAWFLAG_APPLY((gpl->fill[3] > 0.001f), GP_DRAWDATA_FILL);
+#undef GP_DRAWFLAG_APPLY
/* draw 'onionskins' (frame left + right) */
- if (gpl->flag & GP_LAYER_ONIONSKIN) {
- /* drawing method - only immediately surrounding (gstep = 0),
- * or within a frame range on either side (gstep > 0)*/
- if (gpl->gstep) {
- bGPDframe *gf;
- float fac;
-
- /* draw previous frames first */
- for (gf = gpf->prev; gf; gf = gf->prev) {
- /* check if frame is drawable */
- if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
- /* alpha decreases with distance from curframe index */
- fac = 1.0f - ((float)(gpf->framenum - gf->framenum) / (float)(gpl->gstep + 1));
- tcolor[3] = color[3] * fac * 0.66f;
- gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
- }
- else
- break;
- }
-
- /* now draw next frames */
- for (gf = gpf->next; gf; gf = gf->next) {
- /* check if frame is drawable */
- if ((gf->framenum - gpf->framenum) <= gpl->gstep) {
- /* alpha decreases with distance from curframe index */
- fac = 1.0f - ((float)(gf->framenum - gpf->framenum) / (float)(gpl->gstep + 1));
- tcolor[3] = color[3] * fac * 0.66f;
- gp_draw_strokes(gf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
- }
- else
- break;
- }
-
- /* restore alpha */
- glColor4fv(color);
- }
- else {
- /* draw the strokes for the ghost frames (at half of the alpha set by user) */
- if (gpf->prev) {
- tcolor[3] = (color[3] / 7);
- gp_draw_strokes(gpf->prev, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
- }
-
- if (gpf->next) {
- tcolor[3] = (color[3] / 4);
- gp_draw_strokes(gpf->next, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
- }
-
- /* restore alpha */
- glColor4fv(color);
- }
+ if ((gpl->flag & GP_LAYER_ONIONSKIN) && !(dflag & GP_DRAWDATA_NO_ONIONS)) {
+ /* Drawing method - only immediately surrounding (gstep = 0),
+ * or within a frame range on either side (gstep > 0)
+ */
+ gp_draw_onionskins(gpl, gpf, offsx, offsy, winx, winy, cfra, dflag, debug, lthick);
}
/* draw the strokes already in active frame */
- tcolor[3] = color[3];
- gp_draw_strokes(gpf, offsx, offsy, winx, winy, dflag, debug, lthick, tcolor);
+ gp_draw_strokes(gpf, offsx, offsy, winx, winy, dflag, debug, lthick, gpl->color, gpl->fill);
+
+ /* Draw verts of selected strokes
+ * - when doing OpenGL renders, we don't want to be showing these, as that ends up flickering
+ * - locked layers can't be edited, so there's no point showing these verts
+ * as they will have no bearings on what gets edited
+ * - only show when in editmode, since operators shouldn't work otherwise
+ * (NOTE: doing it this way means that the toggling editmode shows visible change immediately)
+ */
+ /* XXX: perhaps we don't want to show these when users are drawing... */
+ if ((G.f & G_RENDER_OGL) == 0 &&
+ (gpl->flag & GP_LAYER_LOCKED) == 0 &&
+ (gpd->flag & GP_DATA_STROKE_EDITMODE))
+ {
+ gp_draw_strokes_edit(gpf, offsx, offsy, winx, winy, dflag,
+ (gpl->color[3] < 0.95f) ? gpl->color : NULL);
+ }
/* Check if may need to draw the active stroke cache, only if this layer is the active layer
* that is being edited. (Stroke buffer is currently stored in gp-data)
@@ -651,22 +1025,84 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy,
if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) &&
(gpf->flag & GP_FRAME_PAINT))
{
+ /* Set color for drawing buffer stroke - since this may not be set yet */
+ glColor4fv(gpl->color);
+
/* Buffer stroke needs to be drawn with a different linestyle
- * to help differentiate them from normal strokes. */
- gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag);
+ * to help differentiate them from normal strokes.
+ *
+ * It should also be noted that sbuffer contains temporary point types
+ * i.e. tGPspoints NOT bGPDspoints
+ */
+ if (gpl->flag & GP_LAYER_VOLUMETRIC) {
+ gp_draw_stroke_volumetric_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag);
+ }
+ else {
+ gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag);
+ }
}
}
+}
+
+/* draw grease-pencil datablock */
+static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, int cfra, int dflag)
+{
+ /* reset line drawing style (in case previous user didn't reset) */
+ setlinestyle(0);
+
+ /* turn on smooth lines (i.e. anti-aliasing) */
+ glEnable(GL_LINE_SMOOTH);
+
+ /* XXX: turn on some way of ensuring that the polygon edges get smoothed
+ * GL_POLYGON_SMOOTH is nasty and shouldn't be used, as it ends up
+ * creating internal white rays due to the ways it accumulates stuff
+ */
+
+ /* turn on alpha-blending */
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ /* draw! */
+ gp_draw_data_layers(gpd, offsx, offsy, winx, winy, cfra, dflag);
/* turn off alpha blending, then smooth lines */
glDisable(GL_BLEND); // alpha blending
glDisable(GL_LINE_SMOOTH); // smooth lines
-
+
/* restore initial gl conditions */
glLineWidth(1.0);
glPointSize(1.0);
glColor4f(0, 0, 0, 1);
}
+/* if we have strokes for scenes (3d view)/clips (movie clip editor)
+ * and objects/tracks, multiple data blocks have to be drawn */
+static void gp_draw_data_all(Scene *scene, bGPdata *gpd, int offsx, int offsy, int winx, int winy,
+ int cfra, int dflag, const char spacetype)
+{
+ bGPdata *gpd_source = NULL;
+
+ if (scene) {
+ if (spacetype == SPACE_VIEW3D) {
+ gpd_source = (scene->gpd ? scene->gpd : NULL);
+ }
+ else if (spacetype == SPACE_CLIP && scene->clip) {
+ /* currently drawing only gpencil data from either clip or track, but not both - XXX fix logic behind */
+ gpd_source = (scene->clip->gpd ? scene->clip->gpd : NULL);
+ }
+
+ if (gpd_source) {
+ gp_draw_data(gpd_source, offsx, offsy, winx, winy, cfra, dflag);
+ }
+ }
+
+ /* scene/clip data has already been drawn, only object/track data is drawn here
+ * if gpd_source == gpd, we don't have any object/track data and we can skip */
+ if (gpd_source == NULL || (gpd_source && gpd_source != gpd)) {
+ gp_draw_data(gpd, offsx, offsy, winx, winy, cfra, dflag);
+ }
+}
+
/* ----- Grease Pencil Sketches Drawing API ------ */
/* ............................
@@ -693,7 +1129,7 @@ void ED_gpencil_draw_2dimage(const bContext *C)
case SPACE_IMAGE: /* image */
case SPACE_CLIP: /* clip */
{
-
+
/* just draw using standard scaling (settings here are currently ignored anyways) */
/* FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled */
offsx = 0;
@@ -714,8 +1150,8 @@ void ED_gpencil_draw_2dimage(const bContext *C)
sizex = ar->winx;
sizey = ar->winy;
- /* NOTE: I2D was used in 2.4x, but the old settings for that have been deprecated
- * and everything moved to standard View2d
+ /* NOTE: I2D was used in 2.4x, but the old settings for that have been deprecated
+ * and everything moved to standard View2d
*/
dflag |= GP_DRAWDATA_ONLYV2D;
break;
@@ -732,10 +1168,10 @@ void ED_gpencil_draw_2dimage(const bContext *C)
/* draw it! */
- gp_draw_data(gpd, offsx, offsy, sizex, sizey, CFRA, dflag);
+ gp_draw_data_all(scene, gpd, offsx, offsy, sizex, sizey, CFRA, dflag, sa->spacetype);
}
-/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly
+/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly
* Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes,
* second time with onlyv2d=0 for screen-aligned strokes */
void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d)
@@ -758,10 +1194,10 @@ void ED_gpencil_draw_view2d(const bContext *C, bool onlyv2d)
/* draw it! */
if (onlyv2d) dflag |= (GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_NOSTATUS);
- gp_draw_data(gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag);
+ gp_draw_data_all(scene, gpd, 0, 0, ar->winx, ar->winy, CFRA, dflag, sa->spacetype);
}
-/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly
+/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly
* Note: this gets called twice - first time with only3d=1 to draw 3d-strokes,
* second time with only3d=0 for screen-aligned strokes */
void ED_gpencil_draw_view3d(Scene *scene, View3D *v3d, ARegion *ar, bool only3d)
@@ -770,17 +1206,17 @@ void ED_gpencil_draw_view3d(Scene *scene, View3D *v3d, ARegion *ar, bool only3d)
int dflag = 0;
RegionView3D *rv3d = ar->regiondata;
int offsx, offsy, winx, winy;
-
+
/* check that we have grease-pencil stuff to draw */
gpd = ED_gpencil_data_get_active_v3d(scene, v3d);
if (gpd == NULL) return;
-
+
/* when rendering to the offscreen buffer we don't want to
* deal with the camera border, otherwise map the coords to the camera border. */
if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_RENDER_OGL)) {
rctf rectf;
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &rectf, true); /* no shift */
-
+
offsx = iroundf(rectf.xmin);
offsy = iroundf(rectf.ymin);
winx = iroundf(rectf.xmax - rectf.xmin);
@@ -795,15 +1231,15 @@ void ED_gpencil_draw_view3d(Scene *scene, View3D *v3d, ARegion *ar, bool only3d)
/* draw it! */
if (only3d) dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS);
-
- gp_draw_data(gpd, offsx, offsy, winx, winy, CFRA, dflag);
+
+ gp_draw_data_all(scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype);
}
-void ED_gpencil_draw_ex(bGPdata *gpd, int winx, int winy, const int cfra)
+void ED_gpencil_draw_ex(Scene *scene, bGPdata *gpd, int winx, int winy, const int cfra, const char spacetype)
{
int dflag = GP_DRAWDATA_NOSTATUS | GP_DRAWDATA_ONLYV2D;
-
- gp_draw_data(gpd, 0, 0, winx, winy, cfra, dflag);
+
+ gp_draw_data_all(scene, gpd, 0, 0, winx, winy, cfra, dflag, spacetype);
}
/* ************************************************** */
diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c
index dba80164e93..a2ba6216f9c 100644
--- a/source/blender/editors/gpencil/editaction_gpencil.c
+++ b/source/blender/editors/gpencil/editaction_gpencil.c
@@ -27,7 +27,7 @@
* \ingroup edgpencil
*/
-
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -49,8 +49,6 @@
#include "ED_keyframes_edit.h"
#include "ED_markers.h"
-#include "gpencil_intern.h"
-
/* ***************************************** */
/* NOTE ABOUT THIS FILE:
* This file contains code for editing Grease Pencil data in the Action Editor
@@ -75,7 +73,7 @@ bool ED_gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPD
if (gpf_cb(gpf, scene))
return true;
}
-
+
/* nothing to return */
return false;
}
@@ -115,7 +113,7 @@ bool ED_gplayer_frame_select_check(bGPDlayer *gpl)
bGPDframe *gpf;
/* error checking */
- if (gpl == NULL)
+ if (gpl == NULL)
return false;
/* stop at the first one found */
@@ -153,9 +151,9 @@ void ED_gpencil_select_frames(bGPDlayer *gpl, short select_mode)
bGPDframe *gpf;
/* error checking */
- if (gpl == NULL)
+ if (gpl == NULL)
return;
-
+
/* handle according to mode */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
gpframe_select(gpf, select_mode);
@@ -166,7 +164,7 @@ void ED_gpencil_select_frames(bGPDlayer *gpl, short select_mode)
void ED_gplayer_frame_select_set(bGPDlayer *gpl, short mode)
{
/* error checking */
- if (gpl == NULL)
+ if (gpl == NULL)
return;
/* now call the standard function */
@@ -178,11 +176,11 @@ void ED_gpencil_select_frame(bGPDlayer *gpl, int selx, short select_mode)
{
bGPDframe *gpf;
- if (gpl == NULL)
+ if (gpl == NULL)
return;
-
+
gpf = BKE_gpencil_layer_find_frame(gpl, selx);
-
+
if (gpf) {
gpframe_select(gpf, select_mode);
}
@@ -215,7 +213,7 @@ bool ED_gplayer_frames_delete(bGPDlayer *gpl)
/* error checking */
if (gpl == NULL)
return false;
-
+
/* check for frames to delete */
for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
gpfn = gpf->next;
@@ -223,7 +221,7 @@ bool ED_gplayer_frames_delete(bGPDlayer *gpl)
if (gpf->flag & GP_FRAME_SELECT)
changed |= gpencil_layer_delframe(gpl, gpf);
}
-
+
return changed;
}
@@ -242,7 +240,7 @@ void ED_gplayer_frames_duplicate(bGPDlayer *gpl)
/* duplicate this frame */
if (gpf->flag & GP_FRAME_SELECT) {
- bGPDframe *gpfd;
+ bGPDframe *gpfd;
/* duplicate frame, and deselect self */
gpfd = gpencil_frame_duplicate(gpf);
@@ -253,6 +251,23 @@ void ED_gplayer_frames_duplicate(bGPDlayer *gpl)
}
}
+/* Set keyframe type for selected frames from given gp-layer
+ * \param type The type of keyframe (eBezTriple_KeyframeType) to set selected frames to
+ */
+void ED_gplayer_frames_keytype_set(bGPDlayer *gpl, short type)
+{
+ bGPDframe *gpf;
+
+ if (gpl == NULL)
+ return;
+
+ for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ if (gpf->flag & GP_FRAME_SELECT) {
+ gpf->key_type = type;
+ }
+ }
+}
+
#if 0 // XXX disabled until grease pencil code stabilises again
/* -------------------------------------- */
/* Copy and Paste Tools */
@@ -263,7 +278,7 @@ void ED_gplayer_frames_duplicate(bGPDlayer *gpl)
* the current frame and the 'first keyframe' (i.e. the earliest one in all channels).
* - The earliest frame is calculated per copy operation.
*/
-
+
/* globals for copy/paste data (like for other copy/paste buffers) */
ListBase gpcopybuf = {NULL, NULL};
static int gpcopy_firstframe = 999999999;
@@ -271,7 +286,7 @@ static int gpcopy_firstframe = 999999999;
/* This function frees any MEM_calloc'ed copy/paste buffer data */
void free_gpcopybuf()
{
- free_gpencil_layers(&gpcopybuf);
+ free_gpencil_layers(&gpcopybuf);
BLI_listbase_clear(&gpcopybuf);
gpcopy_firstframe = 999999999;
@@ -375,7 +390,7 @@ void paste_gpdata(Scene *scene)
/* find suitable layer from buffer to use to paste from */
for (gpls = gpcopybuf.first; gpls; gpls = gpls->next) {
/* check if layer name matches */
- if ((no_name) || (strcmp(gpls->info, gpld->info) == 0))
+ if ((no_name) || STREQ(gpls->info, gpld->info))
break;
}
@@ -398,8 +413,8 @@ void paste_gpdata(Scene *scene)
//sa = gpencil_data_findowner((bGPdata *)ale->owner);
sa = NULL;
- /* this should be the right frame... as it may be a pre-existing frame,
- * must make sure that only compatible stroke types get copied over
+ /* this should be the right frame... as it may be a pre-existing frame,
+ * must make sure that only compatible stroke types get copied over
* - we cannot just add a duplicate frame, as that would cause errors
* - need to check for compatible types to minimize memory usage (copying 'junk' over)
*/
@@ -418,14 +433,14 @@ void paste_gpdata(Scene *scene)
if ((gps->flag == 0) || (gps->flag & GP_STROKE_3DSPACE))
stroke_ok = 1;
break;
-
+
case SPACE_NODE: /* Nodes Editor: either screen-aligned or view-aligned */
case SPACE_IMAGE: /* Image Editor: either screen-aligned or view\image-aligned */
case SPACE_CLIP: /* Image Editor: either screen-aligned or view\image-aligned */
if ((gps->flag == 0) || (gps->flag & GP_STROKE_2DSPACE))
stroke_ok = 1;
break;
-
+
case SPACE_SEQ: /* Sequence Editor: either screen-aligned or view-aligned */
if ((gps->flag == 0) || (gps->flag & GP_STROKE_2DIMAGE))
stroke_ok = 1;
@@ -567,9 +582,9 @@ static short mirror_gpf_marker(bGPDframe *gpf, Scene *scene)
/* In order for this mirror function to work without
* any extra arguments being added, we use the case
- * of bezt==NULL to denote that we should find the
+ * of bezt==NULL to denote that we should find the
* marker to mirror over. The static pointer is safe
- * to use this way, as it will be set to null after
+ * to use this way, as it will be set to null after
* each cycle in which this is called.
*/
diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c
deleted file mode 100644
index 0acff8fc0a5..00000000000
--- a/source/blender/editors/gpencil/gpencil_buttons.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2008, Blender Foundation, Joshua Leung
- * This is a new part of Blender
- *
- * Contributor(s): Joshua Leung
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/editors/gpencil/gpencil_buttons.c
- * \ingroup edgpencil
- */
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-
-#include "BLI_blenlib.h"
-
-#include "BLF_translation.h"
-
-#include "DNA_gpencil_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-
-#include "BKE_context.h"
-#include "BKE_global.h"
-#include "BKE_gpencil.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "RNA_access.h"
-
-#include "ED_gpencil.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "gpencil_intern.h"
-
-/* ************************************************** */
-/* GREASE PENCIL PANEL-UI DRAWING */
-
-/* Every space which implements Grease-Pencil functionality should have a panel
- * for the settings. All of the space-dependent parts should be coded in the panel
- * code for that space, but the rest is all handled by generic panel here.
- */
-
-/* ------- Callbacks ----------- */
-/* These are just 'dummy wrappers' around gpencil api calls */
-
-/* make layer active one after being clicked on */
-static void gp_ui_activelayer_cb(bContext *C, void *gpd, void *gpl)
-{
- /* make sure the layer we want to remove is the active one */
- gpencil_layer_setactive(gpd, gpl);
-
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-}
-
-/* delete 'active' layer */
-static void gp_ui_dellayer_cb(bContext *C, void *gpd, void *gpl)
-{
- gpencil_layer_delete((bGPdata *)gpd, (bGPDlayer *)gpl);
-
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-}
-
-/* move layer up */
-static void gp_ui_layer_up_cb(bContext *C, void *gpd_v, void *gpl_v)
-{
- bGPdata *gpd = gpd_v;
- bGPDlayer *gpl = gpl_v;
-
- BLI_remlink(&gpd->layers, gpl);
- BLI_insertlinkbefore(&gpd->layers, gpl->prev, gpl);
-
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-}
-
-/* move layer down */
-static void gp_ui_layer_down_cb(bContext *C, void *gpd_v, void *gpl_v)
-{
- bGPdata *gpd = gpd_v;
- bGPDlayer *gpl = gpl_v;
-
- BLI_remlink(&gpd->layers, gpl);
- BLI_insertlinkafter(&gpd->layers, gpl->next, gpl);
-
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-}
-
-/* ------- Drawing Code ------- */
-
-/* draw the controls for a given layer */
-static void gp_drawui_layer(uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl, const bool is_v3d)
-{
- uiLayout *box = NULL, *split = NULL;
- uiLayout *col = NULL;
- uiLayout *row = NULL, *sub = NULL;
- uiBlock *block;
- uiBut *but;
- PointerRNA ptr;
- int icon;
-
- /* make pointer to layer data */
- RNA_pointer_create((ID *)gpd, &RNA_GPencilLayer, gpl, &ptr);
-
- /* unless button has own callback, it adds this callback to button */
- block = uiLayoutGetBlock(layout);
- uiBlockSetFunc(block, gp_ui_activelayer_cb, gpd, gpl);
-
- /* draw header ---------------------------------- */
- /* get layout-row + UI-block for header */
- box = uiLayoutBox(layout);
-
- row = uiLayoutRow(box, false);
- uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_EXPAND);
- block = uiLayoutGetBlock(row); /* err... */
-
- uiBlockSetEmboss(block, UI_EMBOSSN);
-
- /* left-align ............................... */
- sub = uiLayoutRow(row, false);
-
- /* active */
- block = uiLayoutGetBlock(sub);
- icon = (gpl->flag & GP_LAYER_ACTIVE) ? ICON_RADIOBUT_ON : ICON_RADIOBUT_OFF;
- but = uiDefIconButBitI(block, TOG, GP_LAYER_ACTIVE, 0, icon, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &gpl->flag, 0.0, 0.0, 0.0, 0.0, TIP_("Set active layer"));
- uiButSetFunc(but, gp_ui_activelayer_cb, gpd, gpl);
-
- /* locked */
- icon = (gpl->flag & GP_LAYER_LOCKED) ? ICON_LOCKED : ICON_UNLOCKED;
- uiItemR(sub, &ptr, "lock", 0, "", icon);
-
- /* when layer is locked or hidden, only draw header */
- if (gpl->flag & (GP_LAYER_LOCKED | GP_LAYER_HIDE)) {
- char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */
-
- /* visibility button (only if hidden but not locked!) */
- if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED))
- uiItemR(sub, &ptr, "hide", 0, "", ICON_RESTRICT_VIEW_ON);
-
- /* name */
- if (gpl->flag & GP_LAYER_HIDE)
- BLI_snprintf(name, sizeof(name), IFACE_("%s (Hidden)"), gpl->info);
- else
- BLI_snprintf(name, sizeof(name), IFACE_("%s (Locked)"), gpl->info);
- uiItemL(sub, name, ICON_NONE);
-
- /* delete button (only if hidden but not locked!) */
- if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) {
- /* right-align ............................... */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
- block = uiLayoutGetBlock(sub); /* XXX... err... */
-
- but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete layer"));
- uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl);
- }
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- else {
- /* draw rest of header -------------------------------- */
- /* visibility button */
- uiItemR(sub, &ptr, "hide", 0, "", ICON_RESTRICT_VIEW_OFF);
-
- /* frame locking */
- /* TODO: this needs its own icons... */
- icon = (gpl->flag & GP_LAYER_FRAMELOCK) ? ICON_RENDER_STILL : ICON_RENDER_ANIMATION;
- uiItemR(sub, &ptr, "lock_frame", 0, "", icon);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- /* name */
- uiItemR(sub, &ptr, "info", 0, "", ICON_NONE);
-
- /* move up/down */
- uiBlockBeginAlign(block);
-
- if (gpl->prev) {
- but = uiDefIconBut(block, BUT, 0, ICON_TRIA_UP, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Move layer up"));
- uiButSetFunc(but, gp_ui_layer_up_cb, gpd, gpl);
- }
- if (gpl->next) {
- but = uiDefIconBut(block, BUT, 0, ICON_TRIA_DOWN, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Move layer down"));
- uiButSetFunc(but, gp_ui_layer_down_cb, gpd, gpl);
- }
-
- uiBlockEndAlign(block);
-
- /* delete 'button' */
- uiBlockSetEmboss(block, UI_EMBOSSN);
- /* right-align ............................... */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
- block = uiLayoutGetBlock(sub); /* XXX... err... */
-
- but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete layer"));
- uiButSetFunc(but, gp_ui_dellayer_cb, gpd, gpl);
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- /* new backdrop ----------------------------------- */
- box = uiLayoutBox(layout);
- split = uiLayoutSplit(box, 0.5f, false);
-
- /* draw settings ---------------------------------- */
- /* left column ..................... */
- col = uiLayoutColumn(split, false);
-
- /* color */
- sub = uiLayoutColumn(col, true);
- uiItemR(sub, &ptr, "color", 0, "", ICON_NONE);
- uiItemR(sub, &ptr, "alpha", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
-
- /* stroke thickness */
- uiItemR(col, &ptr, "line_width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
-
- /* debugging options */
- if (G.debug & G_DEBUG) {
- uiItemR(col, &ptr, "show_points", 0, NULL, ICON_NONE);
- }
-
- /* right column ................... */
- col = uiLayoutColumn(split, false);
-
- /* onion-skinning */
- sub = uiLayoutColumn(col, true);
- uiItemR(sub, &ptr, "use_onion_skinning", 0, NULL, ICON_NONE);
- uiItemR(sub, &ptr, "ghost_range_max", 0, IFACE_("Frames"), ICON_NONE);
-
- /* 3d-view specific drawing options */
- if (is_v3d) {
- uiItemR(col, &ptr, "show_x_ray", 0, NULL, ICON_NONE);
- }
- }
-}
-
-/* stroke drawing options available */
-typedef enum eGP_Stroke_Ops {
- STROKE_OPTS_NORMAL = 0,
- STROKE_OPTS_V3D_OFF,
- STROKE_OPTS_V3D_ON,
-} eGP_Stroke_Ops;
-
-static void draw_gpencil_space_specials(const bContext *C, uiLayout *layout)
-{
- uiLayout *col, *row;
- SpaceClip *sc = CTX_wm_space_clip(C);
-
- col = uiLayoutColumn(layout, false);
-
- if (sc) {
- bScreen *screen = CTX_wm_screen(C);
- PointerRNA sc_ptr;
-
- RNA_pointer_create(&screen->id, &RNA_SpaceClipEditor, sc, &sc_ptr);
- row = uiLayoutRow(col, true);
- uiItemR(row, &sc_ptr, "grease_pencil_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- }
-}
-
-/* Draw the contents for a grease-pencil panel*/
-static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, PointerRNA *ctx_ptr)
-{
- PointerRNA gpd_ptr;
- bGPDlayer *gpl;
- uiLayout *col, *row;
- SpaceClip *sc = CTX_wm_space_clip(C);
- short v3d_stroke_opts = STROKE_OPTS_NORMAL;
- const bool is_v3d = CTX_wm_view3d(C) != NULL;
-
- /* make new PointerRNA for Grease Pencil block */
- RNA_id_pointer_create((ID *)gpd, &gpd_ptr);
-
- /* draw gpd settings first ------------------------------------- */
- col = uiLayoutColumn(layout, false);
-
- /* current Grease Pencil block */
- /* TODO: show some info about who owns this? */
- uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink");
-
- /* add new layer button - can be used even when no data, since it can add a new block too */
- uiItemO(col, IFACE_("New Layer"), ICON_NONE, "GPENCIL_OT_layer_add");
- row = uiLayoutRow(col, true);
- uiItemO(row, IFACE_("Delete Frame"), ICON_NONE, "GPENCIL_OT_active_frame_delete");
- uiItemO(row, IFACE_("Convert"), ICON_NONE, "GPENCIL_OT_convert");
-
- /* sanity checks... */
- if (gpd == NULL)
- return;
-
- /* draw each layer --------------------------------------------- */
- for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- col = uiLayoutColumn(layout, true);
- gp_drawui_layer(col, gpd, gpl, is_v3d);
- }
-
- /* draw gpd drawing settings first ------------------------------------- */
- col = uiLayoutColumn(layout, true);
- /* label */
- uiItemL(col, IFACE_("Drawing Settings:"), ICON_NONE);
-
- /* check whether advanced 3D-View drawing space options can be used */
- if (is_v3d) {
- if (gpd->flag & (GP_DATA_DEPTH_STROKE | GP_DATA_DEPTH_VIEW))
- v3d_stroke_opts = STROKE_OPTS_V3D_ON;
- else
- v3d_stroke_opts = STROKE_OPTS_V3D_OFF;
- }
-
- /* drawing space options */
- row = uiLayoutRow(col, true);
- uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "VIEW", NULL, ICON_NONE);
- uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "CURSOR", NULL, ICON_NONE);
-
- if (sc == NULL) {
- row = uiLayoutRow(col, true);
- uiLayoutSetActive(row, v3d_stroke_opts);
- uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE);
- uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE);
-
- row = uiLayoutRow(col, false);
- uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON);
- uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE);
- }
-}
-
-void ED_gpencil_panel_standard_header(const bContext *C, Panel *pa)
-{
- PointerRNA ptr;
- RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Space, CTX_wm_space_data(C), &ptr);
-
- uiItemR(pa->layout, &ptr, "show_grease_pencil", 0, "", ICON_NONE);
-}
-
-/* Standard panel to be included wherever Grease Pencil is used... */
-void ED_gpencil_panel_standard(const bContext *C, Panel *pa)
-{
- bGPdata **gpd_ptr = NULL;
- PointerRNA ptr;
-
- /* if (v3d->flag2 & V3D_DISPGP)... etc. */
-
- draw_gpencil_space_specials(C, pa->layout);
-
- /* get pointer to Grease Pencil Data */
- gpd_ptr = ED_gpencil_data_get_pointers((bContext *)C, &ptr);
-
- if (gpd_ptr)
- draw_gpencil_panel((bContext *)C, pa->layout, *gpd_ptr, &ptr);
-}
-
-/* ************************************************** */
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 13334448941..212d384e5ca 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -27,6 +27,7 @@
* \ingroup edgpencil
*/
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -86,50 +87,60 @@
/* ************************************************ */
/* Context Wrangling... */
-/* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it */
-bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
+/* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it,
+ * when context info is not available.
+ */
+bGPdata **ED_gpencil_data_get_pointers_direct(ID *screen_id, Scene *scene, ScrArea *sa, Object *ob, PointerRNA *ptr)
{
- ID *screen_id = (ID *)CTX_wm_screen(C);
- Scene *scene = CTX_data_scene(C);
- ScrArea *sa = CTX_wm_area(C);
-
/* if there's an active area, check if the particular editor may
* have defined any special Grease Pencil context for editing...
*/
if (sa) {
+ SpaceLink *sl = sa->spacedata.first;
+
switch (sa->spacetype) {
case SPACE_VIEW3D: /* 3D-View */
+ case SPACE_TIME: /* Timeline - XXX: this is a hack to get it to show GP keyframes for 3D view */
+ case SPACE_ACTION: /* DepeSheet - XXX: this is a hack to get the keyframe jump operator to take GP Keyframes into account */
{
- Object *ob = CTX_data_active_object(C);
-
- /* TODO: we can include other data-types such as bones later if need be... */
-
- /* just in case no active/selected object */
- if (ob && (ob->flag & SELECT)) {
- /* for now, as long as there's an object, default to using that in 3D-View */
- if (ptr) RNA_id_pointer_create(&ob->id, ptr);
- return &ob->gpd;
+ BLI_assert(scene && ELEM(scene->toolsettings->gpencil_src,
+ GP_TOOL_SOURCE_SCENE, GP_TOOL_SOURCE_OBJECT));
+
+ if (scene->toolsettings->gpencil_src == GP_TOOL_SOURCE_OBJECT) {
+ /* legacy behaviour for usage with old addons requiring object-linked to objects */
+
+ /* just in case no active/selected object... */
+ if (ob && (ob->flag & SELECT)) {
+ /* for now, as long as there's an object, default to using that in 3D-View */
+ if (ptr) RNA_id_pointer_create(&ob->id, ptr);
+ return &ob->gpd;
+ }
+ /* else: defaults to scene... */
+ }
+ else {
+ if (ptr) RNA_id_pointer_create(&scene->id, ptr);
+ return &scene->gpd;
}
break;
}
case SPACE_NODE: /* Nodes Editor */
{
- SpaceNode *snode = (SpaceNode *)CTX_wm_space_data(C);
-
+ SpaceNode *snode = (SpaceNode *)sl;
+
/* return the GP data for the active node block/node */
if (snode && snode->nodetree) {
/* for now, as long as there's an active node tree, default to using that in the Nodes Editor */
if (ptr) RNA_id_pointer_create(&snode->nodetree->id, ptr);
return &snode->nodetree->gpd;
}
-
+
/* even when there is no node-tree, don't allow this to flow to scene */
return NULL;
}
case SPACE_SEQ: /* Sequencer */
{
- SpaceSeq *sseq = (SpaceSeq *)CTX_wm_space_data(C);
-
+ SpaceSeq *sseq = (SpaceSeq *)sl;
+
/* for now, Grease Pencil data is associated with the space (actually preview region only) */
/* XXX our convention for everything else is to link to data though... */
if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceSequenceEditor, sseq, ptr);
@@ -137,8 +148,8 @@ bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
}
case SPACE_IMAGE: /* Image/UV Editor */
{
- SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C);
-
+ SpaceImage *sima = (SpaceImage *)sl;
+
/* for now, Grease Pencil data is associated with the space... */
/* XXX our convention for everything else is to link to data though... */
if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr);
@@ -146,25 +157,25 @@ bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
}
case SPACE_CLIP: /* Nodes Editor */
{
- SpaceClip *sc = (SpaceClip *)CTX_wm_space_data(C);
+ SpaceClip *sc = (SpaceClip *)sl;
MovieClip *clip = ED_space_clip_get_clip(sc);
-
+
if (clip) {
if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
-
+
if (!track)
return NULL;
-
+
if (ptr)
RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr);
-
+
return &track->gpd;
}
else {
if (ptr)
RNA_id_pointer_create(&clip->id, ptr);
-
+
return &clip->gpd;
}
}
@@ -174,12 +185,32 @@ bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
return NULL;
}
}
-
+
/* just fall back on the scene's GP data */
if (ptr) RNA_id_pointer_create((ID *)scene, ptr);
return (scene) ? &scene->gpd : NULL;
}
+/* Get pointer to active Grease Pencil datablock, and an RNA-pointer to trace back to whatever owns it */
+bGPdata **ED_gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr)
+{
+ ID *screen_id = (ID *)CTX_wm_screen(C);
+ Scene *scene = CTX_data_scene(C);
+ ScrArea *sa = CTX_wm_area(C);
+ Object *ob = CTX_data_active_object(C);
+
+ return ED_gpencil_data_get_pointers_direct(screen_id, scene, sa, ob, ptr);
+}
+
+/* -------------------------------------------------------- */
+
+/* Get the active Grease Pencil datablock, when context is not available */
+bGPdata *ED_gpencil_data_get_active_direct(ID *screen_id, Scene *scene, ScrArea *sa, Object *ob)
+{
+ bGPdata **gpd_ptr = ED_gpencil_data_get_pointers_direct(screen_id, scene, sa, ob, NULL);
+ return (gpd_ptr) ? *(gpd_ptr) : NULL;
+}
+
/* Get the active Grease Pencil datablock */
bGPdata *ED_gpencil_data_get_active(const bContext *C)
{
@@ -187,6 +218,9 @@ bGPdata *ED_gpencil_data_get_active(const bContext *C)
return (gpd_ptr) ? *(gpd_ptr) : NULL;
}
+/* -------------------------------------------------------- */
+
+// XXX: this should be removed... We really shouldn't duplicate logic like this!
bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, View3D *v3d)
{
Base *base = scene->basact;
@@ -194,7 +228,7 @@ bGPdata *ED_gpencil_data_get_active_v3d(Scene *scene, View3D *v3d)
/* We have to make sure active object is actually visible and selected, else we must use default scene gpd,
* to be consistent with ED_gpencil_data_get_active's behavior.
*/
-
+
if (base && TESTBASE(v3d, base)) {
gpd = base->object->gpd;
}
@@ -211,13 +245,22 @@ static int gp_add_poll(bContext *C)
return ED_gpencil_data_get_pointers(C, NULL) != NULL;
}
+/* poll callback for checking if there is an active layer */
+static int gp_active_layer_poll(bContext *C)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bGPDlayer *gpl = gpencil_layer_getactive(gpd);
+
+ return (gpl != NULL);
+}
+
/* ******************* Add New Data ************************ */
/* add new datablock - wrapper around API */
static int gp_data_add_exec(bContext *C, wmOperator *op)
{
bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+
if (gpd_ptr == NULL) {
BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
return OPERATOR_CANCELLED;
@@ -225,14 +268,14 @@ static int gp_data_add_exec(bContext *C, wmOperator *op)
else {
/* decrement user count and add new datablock */
bGPdata *gpd = (*gpd_ptr);
-
+
id_us_min(&gpd->id);
*gpd_ptr = gpencil_data_addnew(DATA_("GPencil"));
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -243,7 +286,7 @@ void GPENCIL_OT_data_add(wmOperatorType *ot)
ot->idname = "GPENCIL_OT_data_add";
ot->description = "Add new Grease Pencil datablock";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* callbacks */
ot->exec = gp_data_add_exec;
ot->poll = gp_add_poll;
@@ -255,7 +298,7 @@ void GPENCIL_OT_data_add(wmOperatorType *ot)
static int gp_data_unlink_poll(bContext *C)
{
bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+
/* if we have access to some active data, make sure there's a datablock before enabling this */
return (gpd_ptr && *gpd_ptr);
}
@@ -265,7 +308,7 @@ static int gp_data_unlink_poll(bContext *C)
static int gp_data_unlink_exec(bContext *C, wmOperator *op)
{
bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+
if (gpd_ptr == NULL) {
BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
return OPERATOR_CANCELLED;
@@ -277,10 +320,10 @@ static int gp_data_unlink_exec(bContext *C, wmOperator *op)
id_us_min(&gpd->id);
*gpd_ptr = NULL;
}
-
+
/* notifiers */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
return OPERATOR_FINISHED;
}
@@ -291,7 +334,7 @@ void GPENCIL_OT_data_unlink(wmOperatorType *ot)
ot->idname = "GPENCIL_OT_data_unlink";
ot->description = "Unlink active Grease Pencil datablock";
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* callbacks */
ot->exec = gp_data_unlink_exec;
ot->poll = gp_data_unlink_poll;
@@ -303,7 +346,7 @@ void GPENCIL_OT_data_unlink(wmOperatorType *ot)
static int gp_layer_add_exec(bContext *C, wmOperator *op)
{
bGPdata **gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+
/* if there's no existing Grease-Pencil data there, add some */
if (gpd_ptr == NULL) {
BKE_report(op->reports, RPT_ERROR, "Nowhere for grease pencil data to go");
@@ -311,13 +354,13 @@ static int gp_layer_add_exec(bContext *C, wmOperator *op)
}
if (*gpd_ptr == NULL)
*gpd_ptr = gpencil_data_addnew(DATA_("GPencil"));
-
+
/* add new layer now */
gpencil_layer_addnew(*gpd_ptr, DATA_("GP_Layer"), 1);
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -327,20 +370,531 @@ void GPENCIL_OT_layer_add(wmOperatorType *ot)
ot->name = "Add New Layer";
ot->idname = "GPENCIL_OT_layer_add";
ot->description = "Add new Grease Pencil layer for the active Grease Pencil datablock";
+
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* callbacks */
ot->exec = gp_layer_add_exec;
ot->poll = gp_add_poll;
}
+/* ******************* Remove Active Layer ************************* */
+
+static int gp_layer_remove_exec(bContext *C, wmOperator *op)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bGPDlayer *gpl = gpencil_layer_getactive(gpd);
+
+ /* sanity checks */
+ if (ELEM(NULL, gpd, gpl))
+ return OPERATOR_CANCELLED;
+
+ if (gpl->flag & GP_LAYER_LOCKED) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot delete locked layers");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* make the layer before this the new active layer
+ * - use the one after if this is the first
+ * - if this is the only layer, this naturally becomes NULL
+ */
+ if (gpl->prev)
+ gpencil_layer_setactive(gpd, gpl->prev);
+ else
+ gpencil_layer_setactive(gpd, gpl->next);
+
+ /* delete the layer now... */
+ gpencil_layer_delete(gpd, gpl);
+
+ /* notifiers */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_layer_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Layer";
+ ot->idname = "GPENCIL_OT_layer_remove";
+ ot->description = "Remove active Grease Pencil layer";
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* callbacks */
+ ot->exec = gp_layer_remove_exec;
+ ot->poll = gp_active_layer_poll;
+}
+
+/* ******************* Move Layer Up/Down ************************** */
+
+enum {
+ GP_LAYER_MOVE_UP = -1,
+ GP_LAYER_MOVE_DOWN = 1
+};
+
+static int gp_layer_move_exec(bContext *C, wmOperator *op)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bGPDlayer *gpl = gpencil_layer_getactive(gpd);
+
+ int direction = RNA_enum_get(op->ptr, "type");
+
+ /* sanity checks */
+ if (ELEM(NULL, gpd, gpl))
+ return OPERATOR_CANCELLED;
+
+ /* up or down? */
+ if (direction == GP_LAYER_MOVE_UP) {
+ /* up */
+ BLI_remlink(&gpd->layers, gpl);
+ BLI_insertlinkbefore(&gpd->layers, gpl->prev, gpl);
+ }
+ else {
+ /* down */
+ BLI_remlink(&gpd->layers, gpl);
+ BLI_insertlinkafter(&gpd->layers, gpl->next, gpl);
+ }
+
+ /* notifiers */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_layer_move(wmOperatorType *ot)
+{
+ static EnumPropertyItem slot_move[] = {
+ {GP_LAYER_MOVE_UP, "UP", 0, "Up", ""},
+ {GP_LAYER_MOVE_DOWN, "DOWN", 0, "Down", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name = "Move Grease Pencil Layer";
+ ot->idname = "GPENCIL_OT_layer_move";
+ ot->description = "Move the active Grease Pencil layer up/down in the list";
+
+ /* api callbacks */
+ ot->exec = gp_layer_move_exec;
+ ot->poll = gp_active_layer_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
+}
+
+/* ********************* Duplicate Layer ************************** */
+
+static int gp_layer_copy_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bGPDlayer *gpl = gpencil_layer_getactive(gpd);
+ bGPDlayer *new_layer;
+
+ /* sanity checks */
+ if (ELEM(NULL, gpd, gpl))
+ return OPERATOR_CANCELLED;
+
+ /* make copy of layer, and add it immediately after the existing layer */
+ new_layer = gpencil_layer_duplicate(gpl);
+ BLI_insertlinkafter(&gpd->layers, gpl, new_layer);
+
+ /* ensure new layer has a unique name, and is now the active layer */
+ BLI_uniquename(&gpd->layers, new_layer, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(new_layer->info));
+ gpencil_layer_setactive(gpd, new_layer);
+
+ /* notifiers */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_layer_duplicate(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Duplicate Layer";
+ ot->idname = "GPENCIL_OT_layer_duplicate";
+ ot->description = "Make a copy of the active Grease Pencil layer";
+
+ /* callbacks */
+ ot->exec = gp_layer_copy_exec;
+ ot->poll = gp_active_layer_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ************************************************ */
+/* Stroke Editing Operators */
+
+/* poll callback for all stroke editing operators */
+static int gp_stroke_edit_poll(bContext *C)
+{
+ /* NOTE: this is a bit slower, but is the most accurate... */
+ return CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0;
+}
+
+/* ************** Duplicate Selected Strokes **************** */
+
+/* Make copies of selected point segments in a selected stroke */
+static void gp_duplicate_points(const bGPDstroke *gps, ListBase *new_strokes)
+{
+ bGPDspoint *pt;
+ int i;
+
+ int start_idx = -1;
+
+
+ /* Step through the original stroke's points:
+ * - We accumulate selected points (from start_idx to current index)
+ * and then convert that to a new stroke
+ */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ /* searching for start, are waiting for end? */
+ if (start_idx == -1) {
+ /* is this the first selected point for a new island? */
+ if (pt->flag & GP_SPOINT_SELECT) {
+ start_idx = i;
+ }
+ }
+ else {
+ size_t len = 0;
+
+ /* is this the end of current island yet?
+ * 1) Point i-1 was the last one that was selected
+ * 2) Point i is the last in the array
+ */
+ if ((pt->flag & GP_SPOINT_SELECT) == 0) {
+ len = i - start_idx;
+ }
+ else if (i == gps->totpoints - 1) {
+ len = i - start_idx + 1;
+ }
+ //printf("copying from %d to %d = %d\n", start_idx, i, len);
+
+ /* make copies of the relevant data */
+ if (len) {
+ bGPDstroke *gpsd;
+
+ /* make a stupid copy first of the entire stroke (to get the flags too) */
+ gpsd = MEM_dupallocN(gps);
+
+ /* now, make a new points array, and copy of the relevant parts */
+ gpsd->points = MEM_callocN(sizeof(bGPDspoint) * len, "gps stroke points copy");
+ memcpy(gpsd->points, gps->points + start_idx, sizeof(bGPDspoint) * len);
+ gpsd->totpoints = len;
+
+ /* add to temp buffer */
+ gpsd->next = gpsd->prev = NULL;
+ BLI_addtail(new_strokes, gpsd);
+
+ /* cleanup + reset for next */
+ start_idx = -1;
+ }
+ }
+ }
+}
+
+static int gp_duplicate_exec(bContext *C, wmOperator *op)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+
+ if (gpd == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* for each visible (and editable) layer's selected strokes,
+ * copy the strokes into a temporary buffer, then append
+ * once all done
+ */
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ ListBase new_strokes = {NULL, NULL};
+ bGPDframe *gpf = gpl->actframe;
+ bGPDstroke *gps;
+
+ if (gpf == NULL)
+ continue;
+
+ /* make copies of selected strokes, and deselect these once we're done */
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+
+ if (gps->flag & GP_STROKE_SELECT) {
+ if (gps->totpoints == 1) {
+ /* Special Case: If there's just a single point in this stroke... */
+ bGPDstroke *gpsd;
+
+ /* make direct copies of the stroke and its points */
+ gpsd = MEM_dupallocN(gps);
+ gpsd->points = MEM_dupallocN(gps->points);
+
+ /* add to temp buffer */
+ gpsd->next = gpsd->prev = NULL;
+ BLI_addtail(&new_strokes, gpsd);
+ }
+ else {
+ /* delegate to a helper, as there's too much to fit in here (for copying subsets)... */
+ gp_duplicate_points(gps, &new_strokes);
+ }
+
+ /* deselect original stroke, or else the originals get moved too
+ * (when using the copy + move macro)
+ */
+ gps->flag &= ~GP_STROKE_SELECT;
+ }
+ }
+
+ /* add all new strokes in temp buffer to the frame (preventing double-copies) */
+ BLI_movelisttolist(&gpf->strokes, &new_strokes);
+ BLI_assert(new_strokes.first == NULL);
+ }
+ CTX_DATA_END;
+
+ /* updates */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_duplicate(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Duplicate Strokes";
+ ot->idname = "GPENCIL_OT_duplicate";
+ ot->description = "Duplicate the selected Grease Pencil strokes";
+
+ /* callbacks */
+ ot->exec = gp_duplicate_exec;
+ ot->poll = gp_stroke_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ******************* Copy/Paste Strokes ************************* */
+/* Grease Pencil stroke data copy/paste buffer:
+ * - The copy operation collects all segments of selected strokes,
+ * dumping "ready to be copied" copies of the strokes into the buffer.
+ * - The paste operation makes a copy of those elements, and adds them
+ * to the active layer. This effectively flattens down the strokes
+ * from several different layers into a single layer.
+ */
+
+/* list of bGPDstroke instances */
+static ListBase gp_strokes_copypastebuf = {NULL, NULL};
+
+/* Free copy/paste buffer data */
+void ED_gpencil_strokes_copybuf_free(void)
+{
+ bGPDstroke *gps, *gpsn;
+
+ for (gps = gp_strokes_copypastebuf.first; gps; gps = gpsn) {
+ gpsn = gps->next;
+
+ MEM_freeN(gps->points);
+ BLI_freelinkN(&gp_strokes_copypastebuf, gps);
+ }
+
+ gp_strokes_copypastebuf.first = gp_strokes_copypastebuf.last = NULL;
+}
+
+/* --------------------- */
+/* Copy selected strokes */
+
+static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+
+ if (gpd == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* clear the buffer first */
+ ED_gpencil_strokes_copybuf_free();
+
+ /* for each visible (and editable) layer's selected strokes,
+ * copy the strokes into a temporary buffer, then append
+ * once all done
+ */
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ bGPDframe *gpf = gpl->actframe;
+ bGPDstroke *gps;
+
+ if (gpf == NULL)
+ continue;
+
+ /* make copies of selected strokes, and deselect these once we're done */
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+
+ if (gps->flag & GP_STROKE_SELECT) {
+ if (gps->totpoints == 1) {
+ /* Special Case: If there's just a single point in this stroke... */
+ bGPDstroke *gpsd;
+
+ /* make direct copies of the stroke and its points */
+ gpsd = MEM_dupallocN(gps);
+ gpsd->points = MEM_dupallocN(gps->points);
+
+ /* add to temp buffer */
+ gpsd->next = gpsd->prev = NULL;
+ BLI_addtail(&gp_strokes_copypastebuf, gpsd);
+ }
+ else {
+ /* delegate to a helper, as there's too much to fit in here (for copying subsets)... */
+ gp_duplicate_points(gps, &gp_strokes_copypastebuf);
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ /* done - no updates needed */
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_copy(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Copy Strokes";
+ ot->idname = "GPENCIL_OT_copy";
+ ot->description = "Copy selected Grease Pencil points and strokes";
+
+ /* callbacks */
+ ot->exec = gp_strokes_copy_exec;
+ ot->poll = gp_stroke_edit_poll;
+
+ /* flags */
+ //ot->flag = OPTYPE_REGISTER;
+}
+
+/* --------------------- */
+/* Paste selected strokes */
+
+static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bGPDlayer *gpl = CTX_data_active_gpencil_layer(C);
+ bGPDframe *gpf;
+
+ /* check for various error conditions */
+ if (gpd == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
+ return OPERATOR_CANCELLED;
+ }
+ else if (gp_strokes_copypastebuf.first == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No strokes to paste, select and copy some points before trying again");
+ return OPERATOR_CANCELLED;
+ }
+ else if (gpl == NULL) {
+ /* no active layer - let's just create one */
+ gpl = gpencil_layer_addnew(gpd, DATA_("GP_Layer"), 1);
+ }
+ else if (gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) {
+ BKE_report(op->reports, RPT_ERROR, "Can not paste strokes when active layer is hidden or locked");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* Check that some of the strokes in the buffer can be used */
+ bGPDstroke *gps;
+ bool ok = false;
+
+ for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
+ if (ED_gpencil_stroke_can_use(C, gps)) {
+ ok = true;
+ break;
+ }
+ }
+
+ if (ok == false) {
+ /* XXX: this check is not 100% accurate (i.e. image editor is incompatible with normal 2D strokes),
+ * but should be enough to give users a good idea of what's going on
+ */
+ if (CTX_wm_area(C)->spacetype == SPACE_VIEW3D)
+ BKE_report(op->reports, RPT_ERROR, "Cannot paste 2D strokes in 3D View");
+ else
+ BKE_report(op->reports, RPT_ERROR, "Cannot paste 3D strokes in 2D editors");
+
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ /* Deselect all strokes first */
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ bGPDspoint *pt;
+ int i;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+
+ gps->flag &= ~GP_STROKE_SELECT;
+ }
+ CTX_DATA_END;
+
+ /* Ensure we have a frame to draw into
+ * NOTE: Since this is an op which creates strokes,
+ * we are obliged to add a new frame if one
+ * doesn't exist already
+ */
+ gpf = gpencil_layer_getframe(gpl, CFRA, true);
+
+ if (gpf) {
+ bGPDstroke *gps;
+
+ /* Copy each stroke into the layer */
+ for (gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
+ if (ED_gpencil_stroke_can_use(C, gps)) {
+ bGPDstroke *new_stroke = MEM_dupallocN(gps);
+
+ new_stroke->points = MEM_dupallocN(gps->points);
+ new_stroke->next = new_stroke->prev = NULL;
+
+ BLI_addtail(&gpf->strokes, new_stroke);
+ }
+ }
+ }
+
+ /* updates */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_paste(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Paste Strokes";
+ ot->idname = "GPENCIL_OT_paste";
+ ot->description = "Paste previously copied strokes into active layer";
+
+ /* callbacks */
+ ot->exec = gp_strokes_paste_exec;
+ ot->poll = gp_stroke_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/* ******************* Delete Active Frame ************************ */
static int gp_actframe_delete_poll(bContext *C)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = gpencil_layer_getactive(gpd);
-
+
/* only if there's an active layer with an active frame */
return (gpl && gpl->actframe);
}
@@ -352,7 +906,7 @@ static int gp_actframe_delete_exec(bContext *C, wmOperator *op)
bGPdata *gpd = ED_gpencil_data_get_active(C);
bGPDlayer *gpl = gpencil_layer_getactive(gpd);
bGPDframe *gpf = gpencil_layer_getframe(gpl, CFRA, 0);
-
+
/* if there's no existing Grease-Pencil data there, add some */
if (gpd == NULL) {
BKE_report(op->reports, RPT_ERROR, "No grease pencil data");
@@ -362,13 +916,13 @@ static int gp_actframe_delete_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No active frame to delete");
return OPERATOR_CANCELLED;
}
-
+
/* delete it... */
gpencil_layer_delframe(gpl, gpf);
-
+
/* notifiers */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -378,13 +932,329 @@ void GPENCIL_OT_active_frame_delete(wmOperatorType *ot)
ot->name = "Delete Active Frame";
ot->idname = "GPENCIL_OT_active_frame_delete";
ot->description = "Delete the active frame for the active Grease Pencil datablock";
+
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* callbacks */
ot->exec = gp_actframe_delete_exec;
ot->poll = gp_actframe_delete_poll;
}
+/* ******************* Delete Operator ************************ */
+
+typedef enum eGP_DeleteMode {
+ /* delete selected stroke points */
+ GP_DELETEOP_POINTS = 0,
+ /* delete selected strokes */
+ GP_DELETEOP_STROKES = 1,
+ /* delete active frame */
+ GP_DELETEOP_FRAME = 2,
+ /* delete selected stroke points (without splitting stroke) */
+ GP_DELETEOP_POINTS_DISSOLVE = 3,
+} eGP_DeleteMode;
+
+
+/* Delete selected strokes */
+static int gp_delete_selected_strokes(bContext *C)
+{
+ bool changed = false;
+
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ bGPDframe *gpf = gpl->actframe;
+ bGPDstroke *gps, *gpsn;
+
+ if (gpf == NULL)
+ continue;
+
+ /* simply delete strokes which are selected */
+ for (gps = gpf->strokes.first; gps; gps = gpsn) {
+ gpsn = gps->next;
+
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+
+ /* free stroke if selected */
+ if (gps->flag & GP_STROKE_SELECT) {
+ /* free stroke memory arrays, then stroke itself */
+ if (gps->points) MEM_freeN(gps->points);
+ BLI_freelinkN(&gpf->strokes, gps);
+
+ changed = true;
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ if (changed) {
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+/* Delete selected points but keep the stroke */
+static int gp_dissolve_selected_points(bContext *C)
+{
+ bool changed = false;
+
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ bGPDframe *gpf = gpl->actframe;
+ bGPDstroke *gps, *gpsn;
+
+ if (gpf == NULL)
+ continue;
+
+ /* simply delete points from selected strokes
+ * NOTE: we may still have to remove the stroke if it ends up having no points!
+ */
+ for (gps = gpf->strokes.first; gps; gps = gpsn) {
+ gpsn = gps->next;
+
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+
+ if (gps->flag & GP_STROKE_SELECT) {
+ bGPDspoint *pt;
+ int i;
+
+ int tot = gps->totpoints; /* number of points in new buffer */
+
+ /* First Pass: Count how many points are selected (i.e. how many to remove) */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ /* selected point - one of the points to remove */
+ tot--;
+ }
+ }
+
+ /* if no points are left, we simply delete the entire stroke */
+ if (tot <= 0) {
+ /* remove the entire stroke */
+ MEM_freeN(gps->points);
+ BLI_freelinkN(&gpf->strokes, gps);
+ }
+ else {
+ /* just copy all unselected into a smaller buffer */
+ bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * tot, "new gp stroke points copy");
+ bGPDspoint *npt = new_points;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if ((pt->flag & GP_SPOINT_SELECT) == 0) {
+ *npt = *pt;
+ npt++;
+ }
+ }
+
+ /* free the old buffer */
+ MEM_freeN(gps->points);
+
+ /* save the new buffer */
+ gps->points = new_points;
+ gps->totpoints = tot;
+
+ /* deselect the stroke, since none of its selected points will still be selected */
+ gps->flag &= ~GP_STROKE_SELECT;
+ }
+
+ changed = true;
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ if (changed) {
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+/* Split selected strokes into segments, splitting on selected points */
+static int gp_delete_selected_points(bContext *C)
+{
+ bool changed = false;
+
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ bGPDframe *gpf = gpl->actframe;
+ bGPDstroke *gps, *gpsn;
+
+ if (gpf == NULL)
+ continue;
+
+ /* simply delete strokes which are selected */
+ for (gps = gpf->strokes.first; gps; gps = gpsn) {
+ gpsn = gps->next;
+
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+
+
+ if (gps->flag & GP_STROKE_SELECT) {
+ bGPDspoint *pt;
+ int i;
+
+ /* The algorithm used here is as follows:
+ * 1) We firstly identify the number of "islands" of non-selected points
+ * which will all end up being in new strokes.
+ * - In the most extreme case (i.e. every other vert is a 1-vert island),
+ * we have at most n / 2 islands
+ * - Once we start having larger islands than that, the number required
+ * becomes much less
+ * 2) Each island gets converted to a new stroke
+ */
+ typedef struct tGPDeleteIsland {
+ int start_idx;
+ int end_idx;
+ } tGPDeleteIsland;
+
+ tGPDeleteIsland *islands = MEM_callocN(sizeof(tGPDeleteIsland) * (gps->totpoints + 1) / 2, "gp_point_islands");
+ bool in_island = false;
+ int num_islands = 0;
+
+ /* First Pass: Identify start/end of islands */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ /* selected - stop accumulating to island */
+ in_island = false;
+ }
+ else {
+ /* unselected - start of a new island? */
+ int idx;
+
+ if (in_island) {
+ /* extend existing island */
+ idx = num_islands - 1;
+ islands[idx].end_idx = i;
+ }
+ else {
+ /* start of new island */
+ in_island = true;
+ num_islands++;
+
+ idx = num_islands - 1;
+ islands[idx].start_idx = islands[idx].end_idx = i;
+ }
+ }
+ }
+
+ /* Watch out for special case where No islands = All points selected = Delete Stroke only */
+ if (num_islands) {
+ /* there are islands, so create a series of new strokes, adding them before the "next" stroke */
+ int idx;
+
+ /* deselect old stroke, since it will be used as template for the new strokes */
+ gps->flag &= ~GP_STROKE_SELECT;
+
+ /* create each new stroke... */
+ for (idx = 0; idx < num_islands; idx++) {
+ tGPDeleteIsland *island = &islands[idx];
+ bGPDstroke *new_stroke = MEM_dupallocN(gps);
+
+ /* compute new buffer size (+ 1 needed as the endpoint index is "inclusive") */
+ new_stroke->totpoints = island->end_idx - island->start_idx + 1;
+ new_stroke->points = MEM_callocN(sizeof(bGPDspoint) * new_stroke->totpoints, "gp delete stroke fragment");
+
+ /* copy over the relevant points */
+ memcpy(new_stroke->points, gps->points + island->start_idx, sizeof(bGPDspoint) * new_stroke->totpoints);
+
+ /* add new stroke to the frame */
+ if (gpsn) {
+ BLI_insertlinkbefore(&gpf->strokes, gpsn, new_stroke);
+ }
+ else {
+ BLI_addtail(&gpf->strokes, new_stroke);
+ }
+ }
+ }
+
+ /* free islands */
+ MEM_freeN(islands);
+
+ /* Delete the old stroke */
+ MEM_freeN(gps->points);
+ BLI_freelinkN(&gpf->strokes, gps);
+
+ changed = true;
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ if (changed) {
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+
+static int gp_delete_exec(bContext *C, wmOperator *op)
+{
+ eGP_DeleteMode mode = RNA_enum_get(op->ptr, "type");
+ int result = OPERATOR_CANCELLED;
+
+ switch (mode) {
+ case GP_DELETEOP_STROKES: /* selected strokes */
+ result = gp_delete_selected_strokes(C);
+ break;
+
+ case GP_DELETEOP_POINTS: /* selected points (breaks the stroke into segments) */
+ result = gp_delete_selected_points(C);
+ break;
+
+ case GP_DELETEOP_POINTS_DISSOLVE: /* selected points (without splitting the stroke) */
+ result = gp_dissolve_selected_points(C);
+ break;
+
+ case GP_DELETEOP_FRAME: /* active frame */
+ result = gp_actframe_delete_exec(C, op);
+ break;
+ }
+
+ return result;
+}
+
+void GPENCIL_OT_delete(wmOperatorType *ot)
+{
+ static EnumPropertyItem prop_gpencil_delete_types[] = {
+ {GP_DELETEOP_POINTS, "POINTS", 0, "Points", "Delete selected points and split strokes into segments"},
+ {GP_DELETEOP_STROKES, "STROKES", 0, "Strokes", "Delete selected strokes"},
+ {GP_DELETEOP_FRAME, "FRAME", 0, "Frame", "Delete active frame"},
+ {0, "", 0, NULL, NULL},
+ {GP_DELETEOP_POINTS_DISSOLVE, "DISSOLVE_POINTS", 0, "Dissolve Points",
+ "Delete selected points without splitting strokes"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ /* identifiers */
+ ot->name = "Delete...";
+ ot->idname = "GPENCIL_OT_delete";
+ ot->description = "Delete selected Grease Pencil strokes, vertices, or frames";
+
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = gp_delete_exec;
+ ot->poll = gp_stroke_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
+
+ /* props */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_delete_types, 0, "Type", "Method used for deleting Grease Pencil data");
+}
+
/* ************************************************ */
/* Grease Pencil to Data Operator */
@@ -437,7 +1307,7 @@ static EnumPropertyItem *rna_GPConvert_mode_items(bContext *UNUSED(C), PointerRN
/* --- */
-/* convert the coordinates from the given stroke point into 3d-coordinates
+/* convert the coordinates from the given stroke point into 3d-coordinates
* - assumes that the active space is the 3D-View
*/
static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoint *pt, float p3d[3], rctf *subrect)
@@ -445,7 +1315,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
-
+
if (gps->flag & GP_STROKE_3DSPACE) {
/* directly use 3d-coordinates */
copy_v3_v3(p3d, &pt->x);
@@ -453,7 +1323,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
else {
const float *fp = ED_view3d_cursor3d_get(scene, v3d);
float mvalf[2];
-
+
/* get screen coordinate */
if (gps->flag & GP_STROKE_2DSPACE) {
View2D *v2d = &ar->v2d;
@@ -469,7 +1339,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin
mvalf[1] = (float)pt->y / 100.0f * ar->winy;
}
}
-
+
ED_view3d_win_to_3d(ar, fp, mvalf, p3d);
}
}
@@ -485,19 +1355,19 @@ typedef struct tGpTimingData {
bool realtime; /* Will overwrite end_frame in case of Original or CustomGap timing... */
float gap_duration, gap_randomness; /* To be used with CustomGap mode*/
int seed;
-
+
/* Data set from points, used to compute final timing FCurve */
int num_points, cur_point;
-
+
/* Distances */
float *dists;
float tot_dist;
-
+
/* Times */
float *times; /* Note: Gap times will be negative! */
float tot_time, gap_tot_time;
double inittime;
-
+
/* Only used during creation of dists & times lists. */
float offset_time;
} tGpTimingData;
@@ -508,9 +1378,9 @@ typedef struct tGpTimingData {
static void gp_timing_data_set_nbr(tGpTimingData *gtd, const int nbr)
{
float *tmp;
-
+
BLI_assert(nbr > gtd->num_points);
-
+
/* distances */
tmp = gtd->dists;
gtd->dists = MEM_callocN(sizeof(float) * nbr, __func__);
@@ -518,7 +1388,7 @@ static void gp_timing_data_set_nbr(tGpTimingData *gtd, const int nbr)
memcpy(gtd->dists, tmp, sizeof(float) * gtd->num_points);
MEM_freeN(tmp);
}
-
+
/* times */
tmp = gtd->times;
gtd->times = MEM_callocN(sizeof(float) * nbr, __func__);
@@ -526,7 +1396,7 @@ static void gp_timing_data_set_nbr(tGpTimingData *gtd, const int nbr)
memcpy(gtd->times, tmp, sizeof(float) * gtd->num_points);
MEM_freeN(tmp);
}
-
+
gtd->num_points = nbr;
}
@@ -536,7 +1406,7 @@ static void gp_timing_data_add_point(tGpTimingData *gtd, const double stroke_ini
{
float delta_time = 0.0f;
const int cur_point = gtd->cur_point;
-
+
if (!cur_point) {
/* Special case, first point, if time is not 0.0f we have to compensate! */
gtd->offset_time = -time;
@@ -546,18 +1416,18 @@ static void gp_timing_data_add_point(tGpTimingData *gtd, const double stroke_ini
/* This is a gap, negative value! */
gtd->times[cur_point] = -(((float)(stroke_inittime - gtd->inittime)) + time + gtd->offset_time);
delta_time = -gtd->times[cur_point] - gtd->times[cur_point - 1];
-
+
gtd->gap_tot_time += delta_time;
}
else {
gtd->times[cur_point] = (((float)(stroke_inittime - gtd->inittime)) + time + gtd->offset_time);
delta_time = gtd->times[cur_point] - fabsf(gtd->times[cur_point - 1]);
}
-
+
gtd->tot_time += delta_time;
gtd->tot_dist += delta_dist;
gtd->dists[cur_point] = gtd->tot_dist;
-
+
gtd->cur_point++;
}
@@ -572,7 +1442,7 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, RNG *rng, const int idx
float *next_delta_time)
{
int j;
-
+
for (j = idx + 1; j < gtd->num_points; j++) {
if (gtd->times[j] < 0) {
gtd->times[j] = -gtd->times[j];
@@ -591,16 +1461,16 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, RNG *rng, const int idx
}
else {
float delta, min, max;
-
+
/* This code ensures that if the first gaps have been shorter than average gap_duration,
* next gaps will tend to be longer (i.e. try to recover the lateness), and vice-versa!
*/
delta = delta_time - (gtd->gap_duration * (*nbr_done_gaps));
-
+
/* Clamp min between [-gap_randomness, 0.0], with lower delta giving higher min */
min = -gtd->gap_randomness - delta;
CLAMP(min, -gtd->gap_randomness, 0.0f);
-
+
/* Clamp max between [0.0, gap_randomness], with lower delta giving higher max */
max = gtd->gap_randomness - delta;
CLAMP(max, 0.0f, gtd->gap_randomness);
@@ -615,7 +1485,7 @@ static int gp_find_end_of_stroke_idx(tGpTimingData *gtd, RNG *rng, const int idx
break;
}
}
-
+
return j - 1;
}
@@ -623,7 +1493,7 @@ static void gp_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd, RNG *rn
{
int i;
float delta_time = 0.0f;
-
+
for (i = 0; i < gtd->num_points; i++) {
if (gtd->times[i] < 0 && i) {
(*nbr_gaps)++;
@@ -636,7 +1506,7 @@ static void gp_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd, RNG *rn
}
}
gtd->tot_time -= delta_time;
-
+
*tot_gaps_time = (float)(*nbr_gaps) * gtd->gap_duration;
gtd->tot_time += *tot_gaps_time;
if (G.debug & G_DEBUG) {
@@ -653,18 +1523,18 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerR
{
/* Use actual recorded timing! */
const float time_start = (float)gtd->start_frame;
-
+
float last_valid_time = 0.0f;
int end_stroke_idx = -1, start_stroke_idx = 0;
float end_stroke_time = 0.0f;
-
+
/* CustomGaps specific */
float delta_time = 0.0f, next_delta_time = 0.0f;
int nbr_done_gaps = 0;
-
+
int i;
float cfra;
-
+
/* This is a bit tricky, as:
* - We can't add arbitrarily close points on FCurve (in time).
* - We *must* have all "caps" points of all strokes in FCurve, as much as possible!
@@ -680,11 +1550,11 @@ static void gp_stroke_path_animation_add_keyframes(ReportList *reports, PointerR
/* This one should *never* be negative! */
end_stroke_time = time_start + ((gtd->times[end_stroke_idx] + delta_time) / gtd->tot_time * time_range);
}
-
+
/* Simple proportional stuff... */
cu->ctime = gtd->dists[i] / gtd->tot_dist * cu->pathlen;
cfra = time_start + ((gtd->times[i] + delta_time) / gtd->tot_time * time_range);
-
+
/* And now, the checks about timing... */
if (i == start_stroke_idx) {
/* If first point of a stroke, be sure it's enough ahead of last valid keyframe, and
@@ -735,43 +1605,43 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
PointerRNA ptr;
PropertyRNA *prop = NULL;
int nbr_gaps = 0, i;
-
+
if (gtd->mode == GP_STROKECONVERT_TIMING_NONE)
return;
-
+
/* gap_duration and gap_randomness are in frames, but we need seconds!!! */
gtd->gap_duration = FRA2TIME(gtd->gap_duration);
gtd->gap_randomness = FRA2TIME(gtd->gap_randomness);
-
+
/* Enable path! */
cu->flag |= CU_PATH;
cu->pathlen = gtd->frame_range;
-
+
/* Get RNA pointer to read/write path time values */
RNA_id_pointer_create((ID *)cu, &ptr);
prop = RNA_struct_find_property(&ptr, "eval_time");
-
+
/* Ensure we have an F-Curve to add keyframes to */
act = verify_adt_action((ID *)cu, true);
fcu = verify_fcurve(act, NULL, &ptr, "eval_time", 0, true);
-
+
if (G.debug & G_DEBUG) {
printf("%s: tot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
for (i = 0; i < gtd->num_points; i++) {
printf("\tpoint %d:\t\tlen: %f\t\ttime: %f\n", i, gtd->dists[i], gtd->times[i]);
}
}
-
+
if (gtd->mode == GP_STROKECONVERT_TIMING_LINEAR) {
float cfra;
-
+
/* Linear extrapolation! */
fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
-
+
cu->ctime = 0.0f;
cfra = (float)gtd->start_frame;
insert_keyframe_direct(reports, ptr, prop, fcu, cfra, INSERTKEY_FAST);
-
+
cu->ctime = cu->pathlen;
if (gtd->realtime) {
cfra += (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
@@ -785,35 +1655,35 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
/* Use actual recorded timing! */
RNG *rng = BLI_rng_new(0);
float time_range;
-
+
/* CustomGaps specific */
float tot_gaps_time = 0.0f;
-
+
/* Pre-process gaps, in case we don't want to keep their original timing */
if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
gp_stroke_path_animation_preprocess_gaps(gtd, rng, &nbr_gaps, &tot_gaps_time);
}
-
+
if (gtd->realtime) {
time_range = (float)TIME2FRA(gtd->tot_time); /* Seconds to frames */
}
else {
time_range = (float)(gtd->end_frame - gtd->start_frame);
}
-
+
if (G.debug & G_DEBUG) {
printf("GP Stroke Path Conversion: Starting keying!\n");
}
-
+
gp_stroke_path_animation_add_keyframes(reports, ptr, prop, fcu, cu, gtd, rng, time_range,
nbr_gaps, tot_gaps_time);
-
+
BLI_rng_free(rng);
}
-
+
/* As we used INSERTKEY_FAST mode, we need to recompute all curve's handles now */
calchandles_fcurve(fcu);
-
+
if (G.debug & G_DEBUG) {
printf("%s: \ntot len: %f\t\ttot time: %f\n", __func__, gtd->tot_dist, gtd->tot_time);
for (i = 0; i < gtd->num_points; i++) {
@@ -821,9 +1691,9 @@ static void gp_stroke_path_animation(bContext *C, ReportList *reports, Curve *cu
}
printf("\n\n");
}
-
+
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
+
/* send updates */
DAG_id_tag_update(&cu->id, 0);
}
@@ -843,7 +1713,7 @@ static void gp_stroke_to_path_add_point(tGpTimingData *gtd, BPoint *bp, const fl
{
copy_v3_v3(bp->vec, p);
bp->vec[3] = 1.0f;
-
+
/* set settings */
bp->f1 = SELECT;
bp->radius = width * rad_fac;
@@ -855,7 +1725,7 @@ static void gp_stroke_to_path_add_point(tGpTimingData *gtd, BPoint *bp, const fl
else if (bp->weight > minmax_weights[1]) {
minmax_weights[1] = bp->weight;
}
-
+
/* Update timing data */
if (do_gtd) {
gp_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p));
@@ -872,7 +1742,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
const bool do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
const int add_start_end_points = (add_start_point ? 1 : 0) + (add_end_point ? 1 : 0);
int i, old_nbp = 0;
-
+
/* create new 'nurb' or extend current one within the curve */
if (nu) {
old_nbp = nu->pntsu;
@@ -884,7 +1754,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
}
else {
nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_path(nurb)");
-
+
nu->pntsu = gps->totpoints + add_start_end_points;
nu->pntsv = 1;
nu->orderu = 2; /* point-to-point! */
@@ -893,16 +1763,16 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
nu->resolu = cu->resolu;
nu->resolv = cu->resolv;
nu->knotsu = NULL;
-
+
nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * nu->pntsu, "bpoints");
-
+
stitch = false; /* Security! */
}
-
+
if (do_gtd) {
gp_timing_data_set_nbr(gtd, nu->pntsu);
}
-
+
/* If needed, make the link between both strokes with two zero-radius additional points */
/* About "zero-radius" point interpolations:
* - If we have at least two points in current curve (most common case), we linearly extrapolate
@@ -915,16 +1785,16 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
if (curnu && !stitch && old_nbp) {
float p1[3], p2[3], p[3], next_p[3];
float dt1 = 0.0f, dt2 = 0.0f;
-
+
BLI_assert(gps->prev != NULL);
-
+
prev_bp = NULL;
if ((old_nbp > 1) && (gps->prev->totpoints > 1)) {
/* Only use last curve segment if previous stroke was not a single-point one! */
prev_bp = &nu->bp[old_nbp - 2];
}
bp = &nu->bp[old_nbp - 1];
-
+
/* First point */
gp_strokepoint_convertcoords(C, gps, gps->points, p, subrect);
if (prev_bp) {
@@ -943,7 +1813,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
bp++;
gp_stroke_to_path_add_point(gtd, bp, p1, (bp - 1)->vec, do_gtd, gps->prev->inittime, dt1,
0.0f, rad_fac, minmax_weights);
-
+
/* Second point */
/* Note dt2 is always negative, which marks the gap. */
if (gps->totpoints > 1) {
@@ -961,13 +1831,13 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
}
bp++;
gp_stroke_to_path_add_point(gtd, bp, p2, p1, do_gtd, gps->inittime, dt2, 0.0f, rad_fac, minmax_weights);
-
+
old_nbp += 2;
}
else if (add_start_point) {
float p[3], next_p[3];
float dt = 0.0f;
-
+
gp_strokepoint_convertcoords(C, gps, gps->points, p, subrect);
if (gps->totpoints > 1) {
gp_strokepoint_convertcoords(C, gps, gps->points + 1, next_p, subrect);
@@ -985,14 +1855,14 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
* would not work (it would be *before* gtd->inittime, which is not supported currently).
*/
gp_stroke_to_path_add_point(gtd, bp, p, p, do_gtd, gps->inittime, dt, 0.0f, rad_fac, minmax_weights);
-
+
old_nbp++;
}
-
+
if (old_nbp) {
prev_bp = &nu->bp[old_nbp - 1];
}
-
+
/* add points */
for (i = (stitch) ? 1 : 0, pt = &gps->points[(stitch) ? 1 : 0], bp = &nu->bp[old_nbp];
i < gps->totpoints;
@@ -1000,20 +1870,20 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
{
float p[3];
float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
-
+
/* get coordinates to add at */
gp_strokepoint_convertcoords(C, gps, pt, p, subrect);
-
+
gp_stroke_to_path_add_point(gtd, bp, p, (prev_bp) ? prev_bp->vec : p, do_gtd, gps->inittime, pt->time,
width, rad_fac, minmax_weights);
-
+
prev_bp = bp;
}
if (add_end_point) {
float p[3];
float dt = 0.0f;
-
+
if (gps->totpoints > 1) {
interp_v3_v3v3(p, prev_bp->vec, (prev_bp - 1)->vec, -GAP_DFAC);
if (do_gtd) {
@@ -1029,7 +1899,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
/* Note bp has already been incremented in main loop above, so it points to the right place. */
gp_stroke_to_path_add_point(gtd, bp, p, prev_bp->vec, do_gtd, gps->inittime, dt, 0.0f, rad_fac, minmax_weights);
}
-
+
/* add nurb to curve */
if (!curnu || !*curnu) {
BLI_addtail(&cu->nurb, nu);
@@ -1037,7 +1907,7 @@ static void gp_stroke_to_path(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curv
if (curnu) {
*curnu = nu;
}
-
+
BKE_nurb_knot_calc_u(nu);
}
@@ -1052,7 +1922,7 @@ static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd, BezTriple *bezt,
copy_v3_v3(bezt->vec[0], h1);
copy_v3_v3(bezt->vec[1], p);
copy_v3_v3(bezt->vec[2], h2);
-
+
/* set settings */
bezt->h1 = bezt->h2 = HD_FREE;
bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
@@ -1065,7 +1935,7 @@ static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd, BezTriple *bezt,
else if (bezt->weight > minmax_weights[1]) {
minmax_weights[1] = bezt->weight;
}
-
+
/* Update timing data */
if (do_gtd) {
gp_timing_data_add_point(gtd, inittime, time, len_v3v3(prev_p, p));
@@ -1073,8 +1943,8 @@ static void gp_stroke_to_bezier_add_point(tGpTimingData *gtd, BezTriple *bezt,
}
static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Curve *cu, rctf *subrect, Nurb **curnu,
- float minmax_weights[2], const float rad_fac, bool stitch, const bool add_start_point,
- const bool add_end_point, tGpTimingData *gtd)
+ float minmax_weights[2], const float rad_fac, bool stitch, const bool add_start_point,
+ const bool add_end_point, tGpTimingData *gtd)
{
bGPDspoint *pt;
Nurb *nu = (curnu) ? *curnu : NULL;
@@ -1083,7 +1953,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
const int add_start_end_points = (add_start_point ? 1 : 0) + (add_end_point ? 1 : 0);
float p3d_cur[3], p3d_prev[3], p3d_next[3], h1[3], h2[3];
const bool do_gtd = (gtd->mode != GP_STROKECONVERT_TIMING_NONE);
-
+
/* create new 'nurb' or extend current one within the curve */
if (nu) {
old_nbezt = nu->pntsu;
@@ -1095,22 +1965,22 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
}
else {
nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)");
-
+
nu->pntsu = gps->totpoints + add_start_end_points;
nu->resolu = 12;
nu->resolv = 12;
nu->type = CU_BEZIER;
nu->bezt = (BezTriple *)MEM_callocN(sizeof(BezTriple) * nu->pntsu, "bezts");
-
+
stitch = false; /* Security! */
}
-
+
if (do_gtd) {
gp_timing_data_set_nbr(gtd, nu->pntsu);
}
-
+
tot = gps->totpoints;
-
+
/* get initial coordinates */
pt = gps->points;
if (tot) {
@@ -1122,11 +1992,11 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
}
}
-
+
/* If needed, make the link between both strokes with two zero-radius additional points */
if (curnu && old_nbezt) {
BLI_assert(gps->prev != NULL);
-
+
/* Update last point's second handle */
if (stitch) {
bezt = &nu->bezt[old_nbezt - 1];
@@ -1134,7 +2004,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
copy_v3_v3(bezt->vec[2], h2);
pt++;
}
-
+
/* Create "link points" */
/* About "zero-radius" point interpolations:
* - If we have at least two points in current curve (most common case), we linearly extrapolate
@@ -1147,14 +2017,14 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
else {
float p1[3], p2[3];
float dt1 = 0.0f, dt2 = 0.0f;
-
+
prev_bezt = NULL;
if ((old_nbezt > 1) && (gps->prev->totpoints > 1)) {
/* Only use last curve segment if previous stroke was not a single-point one! */
prev_bezt = &nu->bezt[old_nbezt - 2];
}
bezt = &nu->bezt[old_nbezt - 1];
-
+
/* First point */
if (prev_bezt) {
interp_v3_v3v3(p1, prev_bezt->vec[1], bezt->vec[1], 1.0f + GAP_DFAC);
@@ -1169,7 +2039,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
dt1 = interpf(gps->inittime - gps->prev->inittime, 0.0f, GAP_DFAC);
}
}
-
+
/* Second point */
/* Note dt2 is always negative, which marks the gap. */
if (tot > 1) {
@@ -1184,25 +2054,25 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
dt2 = interpf(gps->prev->inittime - gps->inittime, 0.0f, GAP_DFAC);
}
}
-
+
/* Second handle of last point of previous stroke. */
interp_v3_v3v3(h2, bezt->vec[1], p1, BEZT_HANDLE_FAC);
copy_v3_v3(bezt->vec[2], h2);
-
+
/* First point */
interp_v3_v3v3(h1, p1, bezt->vec[1], BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p1, p2, BEZT_HANDLE_FAC);
bezt++;
gp_stroke_to_bezier_add_point(gtd, bezt, p1, h1, h2, (bezt - 1)->vec[1], do_gtd, gps->prev->inittime, dt1,
0.0f, rad_fac, minmax_weights);
-
+
/* Second point */
interp_v3_v3v3(h1, p2, p1, BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p2, p3d_cur, BEZT_HANDLE_FAC);
bezt++;
gp_stroke_to_bezier_add_point(gtd, bezt, p2, h1, h2, p1, do_gtd, gps->inittime, dt2,
0.0f, rad_fac, minmax_weights);
-
+
old_nbezt += 2;
copy_v3_v3(p3d_prev, p2);
}
@@ -1210,7 +2080,7 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
else if (add_start_point) {
float p[3];
float dt = 0.0f;
-
+
if (gps->totpoints > 1) {
interp_v3_v3v3(p, p3d_cur, p3d_next, -GAP_DFAC);
if (do_gtd) {
@@ -1227,51 +2097,51 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
bezt = &nu->bezt[old_nbezt];
gp_stroke_to_bezier_add_point(gtd, bezt, p, h1, h2, p, do_gtd, gps->inittime, dt,
0.0f, rad_fac, minmax_weights);
-
+
old_nbezt++;
copy_v3_v3(p3d_prev, p);
}
-
+
if (old_nbezt) {
prev_bezt = &nu->bezt[old_nbezt - 1];
}
-
+
/* add points */
for (i = stitch ? 1 : 0, bezt = &nu->bezt[old_nbezt]; i < tot; i++, pt++, bezt++) {
float width = pt->pressure * gpl->thickness * WIDTH_CORR_FAC;
-
+
if (i || old_nbezt) {
interp_v3_v3v3(h1, p3d_cur, p3d_prev, BEZT_HANDLE_FAC);
}
else {
interp_v3_v3v3(h1, p3d_cur, p3d_next, -BEZT_HANDLE_FAC);
}
-
+
if (i < tot - 1) {
interp_v3_v3v3(h2, p3d_cur, p3d_next, BEZT_HANDLE_FAC);
}
else {
interp_v3_v3v3(h2, p3d_cur, p3d_prev, -BEZT_HANDLE_FAC);
}
-
+
gp_stroke_to_bezier_add_point(gtd, bezt, p3d_cur, h1, h2, prev_bezt ? prev_bezt->vec[1] : p3d_cur,
do_gtd, gps->inittime, pt->time, width, rad_fac, minmax_weights);
-
+
/* shift coord vects */
copy_v3_v3(p3d_prev, p3d_cur);
copy_v3_v3(p3d_cur, p3d_next);
-
+
if (i + 2 < tot) {
gp_strokepoint_convertcoords(C, gps, pt + 2, p3d_next, subrect);
}
-
+
prev_bezt = bezt;
}
if (add_end_point) {
float p[3];
float dt = 0.0f;
-
+
if (gps->totpoints > 1) {
interp_v3_v3v3(p, prev_bezt->vec[1], (prev_bezt - 1)->vec[1], -GAP_DFAC);
if (do_gtd) {
@@ -1284,11 +2154,11 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
p[0] += GAP_DFAC; /* Rather arbitrary... */
dt = GAP_DFAC; /* Rather arbitrary too! */
}
-
+
/* Second handle of last point of this stroke. */
interp_v3_v3v3(h2, prev_bezt->vec[1], p, BEZT_HANDLE_FAC);
copy_v3_v3(prev_bezt->vec[2], h2);
-
+
/* The end point */
interp_v3_v3v3(h1, p, prev_bezt->vec[1], BEZT_HANDLE_FAC);
interp_v3_v3v3(h2, p, prev_bezt->vec[1], -BEZT_HANDLE_FAC);
@@ -1296,10 +2166,10 @@ static void gp_stroke_to_bezier(bContext *C, bGPDlayer *gpl, bGPDstroke *gps, Cu
gp_stroke_to_bezier_add_point(gtd, bezt, p, h1, h2, prev_bezt->vec[1], do_gtd, gps->inittime, dt,
0.0f, rad_fac, minmax_weights);
}
-
+
/* must calculate handles or else we crash */
BKE_nurb_handles_calc(nu);
-
+
if (!curnu || !*curnu) {
BLI_addtail(&cu->nurb, nu);
}
@@ -1329,7 +2199,7 @@ static void gp_stroke_finalize_curve_endpoints(Curve *cu)
bp[i].weight = bp[i].radius = 0.0f;
}
}
-
+
/* end */
nu = cu->nurb.last;
i = nu->pntsu - 1;
@@ -1353,13 +2223,13 @@ static void gp_stroke_norm_curve_weights(Curve *cu, const float minmax_weights[2
const float delta = minmax_weights[0];
float fac;
int i;
-
+
/* when delta == minmax_weights[0] == minmax_weights[1], we get div by zero [#35686] */
if (IS_EQF(delta, minmax_weights[1]))
fac = 1.0f;
else
fac = 1.0f / (minmax_weights[1] - delta);
-
+
for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->bezt) {
BezTriple *bezt = nu->bezt;
@@ -1380,10 +2250,10 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
{
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
-
+
if (v3d) {
RegionView3D *rv3d = ar->regiondata;
-
+
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
Scene *scene = CTX_data_scene(C);
@@ -1391,7 +2261,7 @@ static int gp_camera_view_subrect(bContext *C, rctf *subrect)
return 1;
}
}
-
+
return 0;
}
@@ -1409,57 +2279,57 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
Nurb *nu = NULL;
Base *base_orig = BASACT, *base_new = NULL;
float minmax_weights[2] = {1.0f, 0.0f};
-
+
/* camera framing */
rctf subrect, *subrect_ptr = NULL;
-
+
/* error checking */
if (ELEM(NULL, gpd, gpl, gpf))
return;
-
+
/* only convert if there are any strokes on this layer's frame to convert */
if (BLI_listbase_is_empty(&gpf->strokes))
return;
-
+
/* initialize camera framing */
if (gp_camera_view_subrect(C, &subrect)) {
subrect_ptr = &subrect;
}
-
+
/* init the curve object (remove rotation and get curve data from it)
* - must clear transforms set on object, as those skew our results
*/
ob = BKE_object_add_only_object(bmain, OB_CURVE, gpl->info);
cu = ob->data = BKE_curve_add(bmain, gpl->info, OB_CURVE);
base_new = BKE_scene_base_add(scene, ob);
-
+
cu->flag |= CU_3D;
-
+
gtd->inittime = ((bGPDstroke *)gpf->strokes.first)->inittime;
-
+
/* add points to curve */
for (gps = gpf->strokes.first; gps; gps = gps->next) {
const bool add_start_point = (link_strokes && !(prev_gps));
const bool add_end_point = (link_strokes && !(gps->next));
-
+
/* Detect new strokes created because of GP_STROKE_BUFFER_MAX reached, and stitch them to previous one. */
bool stitch = false;
if (prev_gps) {
bGPDspoint *pt1 = &prev_gps->points[prev_gps->totpoints - 1];
bGPDspoint *pt2 = &gps->points[0];
-
+
if ((pt1->x == pt2->x) && (pt1->y == pt2->y)) {
stitch = true;
}
}
-
+
/* Decide whether we connect this stroke to previous one */
if (!(stitch || link_strokes)) {
nu = NULL;
}
-
+
switch (mode) {
- case GP_STROKECONVERT_PATH:
+ case GP_STROKECONVERT_PATH:
gp_stroke_to_path(C, gpl, gps, cu, subrect_ptr, &nu, minmax_weights, rad_fac, stitch,
add_start_point, add_end_point, gtd);
break;
@@ -1474,26 +2344,26 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
}
prev_gps = gps;
}
-
+
/* If link_strokes, be sure first and last points have a zero weight/size! */
if (link_strokes) {
gp_stroke_finalize_curve_endpoints(cu);
}
-
+
/* Update curve's weights, if needed */
if (norm_weights && ((minmax_weights[0] > 0.0f) || (minmax_weights[1] < 1.0f))) {
gp_stroke_norm_curve_weights(cu, minmax_weights);
}
-
+
/* Create the path animation, if needed */
gp_stroke_path_animation(C, reports, cu, gtd);
-
+
if (mode == GP_STROKECONVERT_POLY) {
for (nu = cu->nurb.first; nu; nu = nu->next) {
BKE_nurb_type_convert(nu, CU_POLY, false);
}
}
-
+
/* set the layer and select */
base_new->lay = ob->lay = base_orig ? base_orig->lay : BKE_screen_view3d_layer_active(v3d, scene);
base_new->flag = ob->flag = base_new->flag | SELECT;
@@ -1513,17 +2383,17 @@ static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOpe
double base_time, cur_time, prev_time = -1.0;
int i;
bool valid = true;
-
+
if (!gpl || !(gpf = gpencil_layer_getframe(gpl, CFRA, 0)) || !(gps = gpf->strokes.first))
return false;
-
+
do {
base_time = cur_time = gps->inittime;
if (cur_time <= prev_time) {
valid = false;
break;
}
-
+
prev_time = cur_time;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
cur_time = base_time + (double)pt->time;
@@ -1536,12 +2406,12 @@ static bool gp_convert_check_has_valid_timing(bContext *C, bGPDlayer *gpl, wmOpe
}
prev_time = cur_time;
}
-
+
if (!valid) {
break;
}
} while ((gps = gps->next));
-
+
if (op) {
RNA_boolean_set(op->ptr, "use_timing_data", valid);
}
@@ -1553,7 +2423,7 @@ static void gp_convert_set_end_frame(struct Main *UNUSED(main), struct Scene *UN
{
int start_frame = RNA_int_get(ptr, "start_frame");
int end_frame = RNA_int_get(ptr, "end_frame");
-
+
if (end_frame <= start_frame) {
RNA_int_set(ptr, "end_frame", start_frame + 1);
}
@@ -1566,7 +2436,7 @@ static int gp_convert_poll(bContext *C)
bGPDframe *gpf = NULL;
ScrArea *sa = CTX_wm_area(C);
Scene *scene = CTX_data_scene(C);
-
+
/* only if the current view is 3D View, if there's valid data (i.e. at least one stroke!),
* and if we are not in edit mode!
*/
@@ -1589,19 +2459,19 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
const bool link_strokes = RNA_boolean_get(op->ptr, "use_link_strokes");
bool valid_timing;
tGpTimingData gtd;
-
+
/* check if there's data to work with */
if (gpd == NULL) {
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data to work on");
return OPERATOR_CANCELLED;
}
-
+
if (!RNA_property_is_set(op->ptr, prop) && !gp_convert_check_has_valid_timing(C, gpl, op)) {
BKE_report(op->reports, RPT_WARNING,
"Current Grease Pencil strokes have no valid timing data, most timing options will be hidden!");
}
valid_timing = RNA_property_boolean_get(op->ptr, prop);
-
+
gtd.mode = RNA_enum_get(op->ptr, "timing_mode");
/* Check for illegal timing mode! */
if (!valid_timing && !ELEM(gtd.mode, GP_STROKECONVERT_TIMING_NONE, GP_STROKECONVERT_TIMING_LINEAR)) {
@@ -1611,7 +2481,7 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
if (!link_strokes) {
gtd.mode = GP_STROKECONVERT_TIMING_NONE;
}
-
+
/* grab all relevant settings */
gtd.frame_range = RNA_int_get(op->ptr, "frame_range");
gtd.start_frame = RNA_int_get(op->ptr, "start_frame");
@@ -1626,10 +2496,10 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
gtd.tot_dist = gtd.tot_time = gtd.gap_tot_time = 0.0f;
gtd.inittime = 0.0;
gtd.offset_time = 0.0f;
-
+
/* perform conversion */
gp_layer_to_curve(C, op->reports, gpd, gpl, mode, norm_weights, rad_fac, link_strokes, &gtd);
-
+
/* free temp memory */
if (gtd.dists) {
MEM_freeN(gtd.dists);
@@ -1639,11 +2509,11 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
MEM_freeN(gtd.times);
gtd.times = NULL;
}
-
+
/* notifiers */
WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
-
+
/* done */
return OPERATOR_FINISHED;
}
@@ -1657,57 +2527,57 @@ static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
float gap_duration = RNA_float_get(ptr, "gap_duration");
float gap_randomness = RNA_float_get(ptr, "gap_randomness");
const bool valid_timing = RNA_boolean_get(ptr, "use_timing_data");
-
+
/* Always show those props */
- if (strcmp(prop_id, "type") == 0 ||
- strcmp(prop_id, "use_normalize_weights") == 0 ||
- strcmp(prop_id, "radius_multiplier") == 0 ||
- strcmp(prop_id, "use_link_strokes") == 0)
+ if (STREQ(prop_id, "type") ||
+ STREQ(prop_id, "use_normalize_weights") ||
+ STREQ(prop_id, "radius_multiplier") ||
+ STREQ(prop_id, "use_link_strokes"))
{
return true;
}
-
+
/* Never show this prop */
- if (strcmp(prop_id, "use_timing_data") == 0)
+ if (STREQ(prop_id, "use_timing_data"))
return false;
-
+
if (link_strokes) {
/* Only show when link_stroke is true */
- if (strcmp(prop_id, "timing_mode") == 0)
+ if (STREQ(prop_id, "timing_mode"))
return true;
-
+
if (timing_mode != GP_STROKECONVERT_TIMING_NONE) {
/* Only show when link_stroke is true and stroke timing is enabled */
- if (strcmp(prop_id, "frame_range") == 0 ||
- strcmp(prop_id, "start_frame") == 0)
+ if (STREQ(prop_id, "frame_range") ||
+ STREQ(prop_id, "start_frame"))
{
return true;
}
-
+
/* Only show if we have valid timing data! */
- if (valid_timing && strcmp(prop_id, "use_realtime") == 0)
+ if (valid_timing && STREQ(prop_id, "use_realtime"))
return true;
-
+
/* Only show if realtime or valid_timing is false! */
- if ((!realtime || !valid_timing) && strcmp(prop_id, "end_frame") == 0)
+ if ((!realtime || !valid_timing) && STREQ(prop_id, "end_frame"))
return true;
-
+
if (valid_timing && timing_mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
/* Only show for custom gaps! */
- if (strcmp(prop_id, "gap_duration") == 0)
+ if (STREQ(prop_id, "gap_duration"))
return true;
-
+
/* Only show randomness for non-null custom gaps! */
- if (strcmp(prop_id, "gap_randomness") == 0 && (gap_duration > 0.0f))
+ if (STREQ(prop_id, "gap_randomness") && (gap_duration > 0.0f))
return true;
-
+
/* Only show seed for randomize action! */
- if (strcmp(prop_id, "seed") == 0 && (gap_duration > 0.0f) && (gap_randomness > 0.0f))
+ if (STREQ(prop_id, "seed") && (gap_duration > 0.0f) && (gap_randomness > 0.0f))
return true;
}
}
}
-
+
/* Else, hidden! */
return false;
}
@@ -1717,9 +2587,9 @@ static void gp_convert_ui(bContext *C, wmOperator *op)
uiLayout *layout = op->layout;
wmWindowManager *wm = CTX_wm_manager(C);
PointerRNA ptr;
-
+
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
+
/* Main auto-draw call */
uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, '\0');
}
@@ -1727,35 +2597,35 @@ static void gp_convert_ui(bContext *C, wmOperator *op)
void GPENCIL_OT_convert(wmOperatorType *ot)
{
PropertyRNA *prop;
-
+
/* identifiers */
ot->name = "Convert Grease Pencil";
ot->idname = "GPENCIL_OT_convert";
ot->description = "Convert the active Grease Pencil layer to a new Curve Object";
-
+
/* callbacks */
ot->invoke = WM_menu_invoke;
ot->exec = gp_convert_layer_exec;
ot->poll = gp_convert_poll;
ot->ui = gp_convert_ui;
-
+
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
+
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_convertmodes, 0, "Type", "Which type of curve to convert to");
-
+
RNA_def_boolean(ot->srna, "use_normalize_weights", true, "Normalize Weight",
"Normalize weight (set from stroke width)");
RNA_def_float(ot->srna, "radius_multiplier", 1.0f, 0.0f, 1000.0f, "Radius Fac",
"Multiplier for the points' radii (set from stroke width)", 0.0f, 10.0f);
RNA_def_boolean(ot->srna, "use_link_strokes", true, "Link Strokes",
"Whether to link strokes with zero-radius sections of curves");
-
+
prop = RNA_def_enum(ot->srna, "timing_mode", prop_gpencil_convert_timingmodes, GP_STROKECONVERT_TIMING_FULL,
"Timing Mode", "How to use timing data stored in strokes");
RNA_def_enum_funcs(prop, rna_GPConvert_mode_items);
-
+
RNA_def_int(ot->srna, "frame_range", 100, 1, 10000, "Frame Range",
"The duration of evaluation of the path control curve", 1, 1000);
RNA_def_int(ot->srna, "start_frame", 1, 1, 100000, "Start Frame",
@@ -1765,7 +2635,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
prop = RNA_def_int(ot->srna, "end_frame", 250, 1, 100000, "End Frame",
"The end frame of the path control curve (if Realtime is not set)", 1, 100000);
RNA_def_property_update_runtime(prop, gp_convert_set_end_frame);
-
+
RNA_def_float(ot->srna, "gap_duration", 0.0f, 0.0f, 10000.0f, "Gap Duration",
"Custom Gap mode: (Average) length of gaps, in frames "
"(Note: Realtime value, will be scaled if Realtime is not set)", 0.0f, 1000.0f);
@@ -1773,7 +2643,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
"Custom Gap mode: Number of frames that gap lengths can vary", 0.0f, 1000.0f);
RNA_def_int(ot->srna, "seed", 0, 0, 1000, "Random Seed",
"Custom Gap mode: Random generator seed", 0, 100);
-
+
/* Note: Internal use, this one will always be hidden by UI code... */
prop = RNA_def_boolean(ot->srna, "use_timing_data", false, "Has Valid Timing",
"Whether the converted Grease Pencil layer has valid timing data (internal use)");
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 28eb1355caf..56420434494 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -31,15 +31,74 @@
#ifndef __GPENCIL_INTERN_H__
#define __GPENCIL_INTERN_H__
-/* internal exports only */
+#include "DNA_vec_types.h"
-/* ***************************************************** */
-/* Operator Defines */
+/* internal exports only */
struct bGPdata;
+struct bGPDstroke;
+struct bGPDspoint;
+
+struct ARegion;
+struct View2D;
struct wmOperatorType;
+
+/* ***************************************************** */
+/* Internal API */
+
+/* Stroke Coordinates API ------------------------------ */
+/* gpencil_utils.c */
+
+typedef struct GP_SpaceConversion {
+ struct bGPdata *gpd;
+ struct bGPDlayer *gpl;
+
+ struct ScrArea *sa;
+ struct ARegion *ar;
+ struct View2D *v2d;
+
+ rctf *subrect; /* for using the camera rect within the 3d view */
+ rctf subrect_data;
+
+ float mat[4][4]; /* transform matrix on the strokes (introduced in [b770964]) */
+} GP_SpaceConversion;
+
+
+/**
+ * Check whether a given stroke segment is inside a circular brush
+ *
+ * \param mval The current screen-space coordinates (midpoint) of the brush
+ * \param mvalo The previous screen-space coordinates (midpoint) of the brush (NOT CURRENTLY USED)
+ * \param rad The radius of the brush
+ *
+ * \param x0, y0 The screen-space x and y coordinates of the start of the stroke segment
+ * \param x1, y1 The screen-space x and y coordinates of the end of the stroke segment
+ */
+bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]),
+ int rad, int x0, int y0, int x1, int y1);
+
+
+/**
+ * Init settings for stroke point space conversions
+ *
+ * \param[out] r_gsc The space conversion settings struct, populated with necessary params
+ */
+void gp_point_conversion_init(struct bContext *C, GP_SpaceConversion *r_gsc);
+
+/**
+ * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D)
+ *
+ * \param[out] r_x The screen-space x-coordinate of the point
+ * \param[out] r_y The screen-space y-coordinate of the point
+ */
+void gp_point_to_xy(GP_SpaceConversion *settings, struct bGPDstroke *gps, struct bGPDspoint *pt,
+ int *r_x, int *r_y);
+
+/* ***************************************************** */
+/* Operator Defines */
+
/* drawing ---------- */
void GPENCIL_OT_draw(struct wmOperatorType *ot);
@@ -52,12 +111,32 @@ typedef enum eGPencil_PaintModes {
GP_PAINTMODE_DRAW_POLY
} eGPencil_PaintModes;
+/* stroke editing ----- */
+
+void GPENCIL_OT_select(struct wmOperatorType *ot);
+void GPENCIL_OT_select_all(struct wmOperatorType *ot);
+void GPENCIL_OT_select_circle(struct wmOperatorType *ot);
+void GPENCIL_OT_select_border(struct wmOperatorType *ot);
+void GPENCIL_OT_select_lasso(struct wmOperatorType *ot);
+
+void GPENCIL_OT_select_linked(struct wmOperatorType *ot);
+void GPENCIL_OT_select_more(struct wmOperatorType *ot);
+void GPENCIL_OT_select_less(struct wmOperatorType *ot);
+
+void GPENCIL_OT_duplicate(struct wmOperatorType *ot);
+void GPENCIL_OT_delete(struct wmOperatorType *ot);
+void GPENCIL_OT_copy(struct wmOperatorType *ot);
+void GPENCIL_OT_paste(struct wmOperatorType *ot);
+
/* buttons editing --- */
void GPENCIL_OT_data_add(struct wmOperatorType *ot);
void GPENCIL_OT_data_unlink(struct wmOperatorType *ot);
void GPENCIL_OT_layer_add(struct wmOperatorType *ot);
+void GPENCIL_OT_layer_remove(struct wmOperatorType *ot);
+void GPENCIL_OT_layer_move(struct wmOperatorType *ot);
+void GPENCIL_OT_layer_duplicate(struct wmOperatorType *ot);
void GPENCIL_OT_active_frame_delete(struct wmOperatorType *ot);
@@ -76,17 +155,17 @@ void gpencil_undo_finish(void);
/* This struct defines a structure used for quick access */
typedef struct bActListElem {
struct bActListElem *next, *prev;
-
+
void *data; /* source data this elem represents */
int type; /* one of the ACTTYPE_* values */
int flag; /* copy of elem's flags for quick access */
int index; /* copy of adrcode where applicable */
-
+
void *key_data; /* motion data - ipo or ipo-curve */
short datatype; /* type of motion data to expect */
-
+
struct bActionGroup *grp; /* action group that owns the channel */
-
+
void *owner; /* will either be an action channel or fake ipo-channel (for keys) */
short ownertype; /* type of owner */
} bActListElem;
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index 75ff0895931..3fae208a2e2 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -36,40 +36,195 @@
#include "BLI_blenlib.h"
+#include "BKE_context.h"
+
+#include "DNA_gpencil_types.h"
+
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "ED_gpencil.h"
+#include "ED_object.h"
+#include "ED_transform.h"
#include "gpencil_intern.h"
/* ****************************************** */
-/* Generic Editing Keymap */
+/* Grease Pencil Keymaps */
-void ED_keymap_gpencil(wmKeyConfig *keyconf)
+/* Generic Drawing Keymap */
+static void ed_keymap_gpencil_general(wmKeyConfig *keyconf)
{
wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil", 0, 0);
wmKeyMapItem *kmi;
- /* Draw */
-
+ /* Draw --------------------------------------- */
/* draw */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, 0, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW);
-
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
/* draw - straight lines */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", LEFTMOUSE, KM_PRESS, KM_CTRL, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_STRAIGHT);
-
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
/* draw - poly lines */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, KM_CTRL, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_DRAW_POLY);
-
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
/* erase */
kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_draw", RIGHTMOUSE, KM_PRESS, 0, DKEY);
RNA_enum_set(kmi->ptr, "mode", GP_PAINTMODE_ERASER);
+ RNA_boolean_set(kmi->ptr, "wait_for_input", false);
+
+ /* Viewport Tools ------------------------------- */
+
+ /* Enter EditMode */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, 0, DKEY);
+ RNA_string_set(kmi->ptr, "data_path", "gpencil_data.use_stroke_edit_mode");
+
+ /* Pie Menu - For standard tools */
+ WM_keymap_add_menu_pie(keymap, "GPENCIL_PIE_tool_palette", QKEY, KM_PRESS, 0, DKEY);
+ WM_keymap_add_menu_pie(keymap, "GPENCIL_PIE_settings_palette", WKEY, KM_PRESS, 0, DKEY);
+}
+
+/* ==================== */
+
+/* Poll callback for stroke editing mode */
+static int gp_stroke_editmode_poll(bContext *C)
+{
+ bGPdata *gpd = CTX_data_gpencil_data(C);
+ return (gpd && (gpd->flag & GP_DATA_STROKE_EDITMODE));
+}
+
+/* Stroke Editing Keymap - Only when editmode is enabled */
+static void ed_keymap_gpencil_editing(wmKeyConfig *keyconf)
+{
+ wmKeyMap *keymap = WM_keymap_find(keyconf, "Grease Pencil Stroke Edit Mode", 0, 0);
+ wmKeyMapItem *kmi;
+
+ /* set poll callback - so that this keymap only gets enabled when stroke editmode is enabled */
+ keymap->poll = gp_stroke_editmode_poll;
+
+ /* ----------------------------------------------- */
+
+ /* Exit EditMode */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "gpencil_data.use_stroke_edit_mode");
+
+ /* Brush Settings */
+ /* NOTE: We cannot expose these in the standard keymap, as they will interfere with regular hotkeys
+ * in other modes. However, when we are dealing with Stroke Edit Mode, we know for certain
+ * that the only data being edited is that of the Grease Pencil strokes
+ */
+
+ /* FKEY = Eraser Radius */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path_primary", "user_preferences.edit.grease_pencil_eraser_radius");
+
+ /* Selection ------------------------------------- */
+ /* select all */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_all", AKEY, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
+
+ /* circle select */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select_circle", CKEY, KM_PRESS, 0, 0);
+
+ /* border select */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select_border", BKEY, KM_PRESS, 0, 0);
+
+ /* lasso select */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT | KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
+
+ /* normal select */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
+
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "extend", true);
+ RNA_boolean_set(kmi->ptr, "toggle", true);
+
+ /* whole stroke select */
+ kmi = WM_keymap_add_item(keymap, "GPENCIL_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
+ RNA_boolean_set(kmi->ptr, "entire_strokes", true);
+
+ /* select linked */
+ /* NOTE: While LKEY is redundant, not having it breaks the mode illusion too much */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select_linked", LKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
+
+ /* select more/less */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "GPENCIL_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
+
+
+ /* Editing ----------------------------------------- */
+
+ /* duplicate and move selected points */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
+
+ /* delete */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "GPENCIL_OT_delete", DELKEY, KM_PRESS, 0, 0);
+
+ /* copy + paste */
+ WM_keymap_add_item(keymap, "GPENCIL_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "GPENCIL_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
+
+#ifdef __APPLE__
+ WM_keymap_add_item(keymap, "GPENCIL_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
+ WM_keymap_add_item(keymap, "GPENCIL_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
+#endif
+
+ /* Transform Tools */
+ kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+
+ kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
+ RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+
+ kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_rotate", RKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+
+ kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_resize", SKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+
+ kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+
+ kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_bend", WKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+
+ WM_keymap_add_item(keymap, "TRANSFORM_OT_tosphere", SKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+
+ WM_keymap_add_item(keymap, "TRANSFORM_OT_shear", SKEY, KM_PRESS, KM_ALT | KM_CTRL | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+
+ kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0);
+ RNA_enum_set(kmi->ptr, "mode", TFM_GPENCIL_SHRINKFATTEN);
+ RNA_boolean_set(kmi->ptr, "gpencil_strokes", true);
+
+ /* Proportional Editing */
+ ED_keymap_proportional_cycle(keyconf, keymap);
+ ED_keymap_proportional_editmode(keyconf, keymap, true);
+}
+
+/* ==================== */
+
+void ED_keymap_gpencil(wmKeyConfig *keyconf)
+{
+ ed_keymap_gpencil_general(keyconf);
+ ed_keymap_gpencil_editing(keyconf);
}
/* ****************************************** */
@@ -80,18 +235,51 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_draw);
+ /* Editing (Strokes) ------------ */
+
+ WM_operatortype_append(GPENCIL_OT_select);
+ WM_operatortype_append(GPENCIL_OT_select_all);
+ WM_operatortype_append(GPENCIL_OT_select_circle);
+ WM_operatortype_append(GPENCIL_OT_select_border);
+ WM_operatortype_append(GPENCIL_OT_select_lasso);
+
+ WM_operatortype_append(GPENCIL_OT_select_linked);
+ WM_operatortype_append(GPENCIL_OT_select_more);
+ WM_operatortype_append(GPENCIL_OT_select_less);
+
+ WM_operatortype_append(GPENCIL_OT_duplicate);
+ WM_operatortype_append(GPENCIL_OT_delete);
+ WM_operatortype_append(GPENCIL_OT_copy);
+ WM_operatortype_append(GPENCIL_OT_paste);
+
/* Editing (Buttons) ------------ */
WM_operatortype_append(GPENCIL_OT_data_add);
WM_operatortype_append(GPENCIL_OT_data_unlink);
WM_operatortype_append(GPENCIL_OT_layer_add);
+ WM_operatortype_append(GPENCIL_OT_layer_remove);
+ WM_operatortype_append(GPENCIL_OT_layer_move);
+ WM_operatortype_append(GPENCIL_OT_layer_duplicate);
WM_operatortype_append(GPENCIL_OT_active_frame_delete);
WM_operatortype_append(GPENCIL_OT_convert);
-
+
/* Editing (Time) --------------- */
}
+void ED_operatormacros_gpencil(void)
+{
+ wmOperatorType *ot;
+ wmOperatorTypeMacro *otmacro;
+
+ ot = WM_operatortype_append_macro("GPENCIL_OT_duplicate_move", "Duplicate Strokes",
+ "Make copies of the selected Grease Pencil strokes and move them",
+ OPTYPE_UNDO | OPTYPE_REGISTER);
+ WM_operatortype_macro_define(ot, "GPENCIL_OT_duplicate");
+ otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
+ RNA_boolean_set(otmacro->ptr, "gpencil_strokes", true);
+}
+
/* ****************************************** */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 7c1976df3e0..c8774cb73a1 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -27,6 +27,7 @@
* \ingroup edgpencil
*/
+
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
@@ -86,11 +87,13 @@ typedef struct tGPsdata {
rctf *subrect; /* for using the camera rect within the 3d view */
rctf subrect_data;
+ GP_SpaceConversion gsc; /* settings to pass to gp_points_to_xy() */
+
PointerRNA ownerPtr; /* pointer to owner of gp-datablock */
bGPdata *gpd; /* gp-datablock layer comes from */
bGPDlayer *gpl; /* layer we're working on */
bGPDframe *gpf; /* frame we're working on */
-
+
short status; /* current status of painting */
short paintmode; /* mode for painting */
@@ -110,7 +113,7 @@ typedef struct tGPsdata {
double inittime; /* Used when converting to path */
double curtime; /* Used when converting to path */
double ocurtime; /* Used when converting to path */
-
+
float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space
* to region space */
float mat[4][4];
@@ -219,7 +222,7 @@ static void gp_get_3d_reference(tGPsdata *p, float vec[3])
if (p->ownerPtr.type == &RNA_Object) {
Object *ob = (Object *)p->ownerPtr.data;
- /* active Object
+ /* active Object
* - use relative distance of 3D-cursor from object center
*/
sub_v3_v3v3(vec, fp, ob->loc);
@@ -244,13 +247,13 @@ static bool gp_stroke_filtermval(tGPsdata *p, const int mval[2], int pmval[2])
if (p->gpd->sbuffer_size == 0)
return true;
- /* check if mouse moved at least certain distance on both axes (best case)
+ /* check if mouse moved at least certain distance on both axes (best case)
* - aims to eliminate some jitter-noise from input when trying to draw straight lines freehand
*/
else if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX))
return true;
- /* check if the distance since the last point is significant enough
+ /* check if the distance since the last point is significant enough
* - prevents points being added too densely
* - distance here doesn't use sqrt to prevent slowness... we should still be safe from overflows though
*/
@@ -280,7 +283,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
float rvec[3], dvec[3];
float mval_f[2] = {UNPACK2(mval)};
float zfac;
-
+
/* Current method just converts each point in screen-coordinates to
* 3D-coordinates using the 3D-cursor as reference. In general, this
* works OK, but it could of course be improved.
@@ -292,7 +295,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
gp_get_3d_reference(p, rvec);
zfac = ED_view3d_calc_zfac(p->ar->regiondata, rvec, NULL);
-
+
if (ED_view3d_project_float_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
sub_v2_v2v2(mval_f, mval_prj, mval_f);
ED_view3d_win_to_delta(p->ar, mval_f, dvec, zfac);
@@ -328,7 +331,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
{
bGPdata *gpd = p->gpd;
tGPspoint *pt;
-
+
/* check painting mode */
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
/* straight lines only - i.e. only store start and end point in buffer */
@@ -345,7 +348,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
gpd->sbuffer_size++;
}
else {
- /* normally, we just reset the endpoint to the latest value
+ /* normally, we just reset the endpoint to the latest value
* - assume that pointers for this are always valid...
*/
pt = ((tGPspoint *)(gpd->sbuffer) + 1);
@@ -439,7 +442,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
return GP_STROKEADD_NORMAL;
}
-
+
/* return invalid state for now... */
return GP_STROKEADD_INVALID;
}
@@ -459,12 +462,12 @@ static void gp_stroke_smooth(tGPsdata *p)
if ((cmx <= 2) || (gpd->sbuffer == NULL))
return;
- /* Calculate smoothing coordinates using weighted-averages
+ /* Calculate smoothing coordinates using weighted-averages
* WARNING: we do NOT smooth first and last points (to avoid shrinkage)
*/
spt = (tGPspoint *)gpd->sbuffer;
- /* This (tmp_spt) small array stores the last two points' original coordinates,
+ /* This (tmp_spt) small array stores the last two points' original coordinates,
* as we don't want to use already averaged ones! It is used as a cyclic buffer...
*/
tmp_spt[0] = *spt;
@@ -483,7 +486,7 @@ static void gp_stroke_smooth(tGPsdata *p)
}
}
-/* simplify a stroke (in buffer) before storing it
+/* simplify a stroke (in buffer) before storing it
* - applies a reverse Chaikin filter
* - code adapted from etch-a-ton branch (editarmature_sketch.c)
*/
@@ -503,7 +506,7 @@ static void gp_stroke_simplify(tGPsdata *p)
if ((num_points <= 4) || (old_points == NULL))
return;
- /* clear buffer (but don't free mem yet) so that we can write to it
+ /* clear buffer (but don't free mem yet) so that we can write to it
* - firstly set sbuffer to NULL, so a new one is allocated
* - secondly, reset flag after, as it gets cleared auto
*/
@@ -570,7 +573,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
/* 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
+ /* get total number of points to allocate space for
* - drawing straight-lines only requires the endpoints
*/
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT)
@@ -626,7 +629,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
pt++;
}
-
+
if (totelem == 2) {
/* last point if applicable */
ptc = ((tGPspoint *)gpd->sbuffer) + (gpd->sbuffer_size - 1);
@@ -747,7 +750,7 @@ static short gp_stroke_eraser_splitdel(bGPDframe *gpf, bGPDstroke *gps, int i)
/* free stroke points, then stroke */
MEM_freeN(pt_tmp);
BLI_freelinkN(&gpf->strokes, gps);
-
+
/* nothing left in stroke, so stop */
return 1;
}
@@ -853,8 +856,7 @@ static float view3d_point_depth(const RegionView3D *rv3d, const float co[3])
}
}
-static bool gp_stroke_eraser_is_occluded(tGPsdata *p,
- const bGPDspoint *pt, const int x, const int y)
+static bool gp_stroke_eraser_is_occluded(tGPsdata *p, const bGPDspoint *pt, const int x, const int y)
{
if ((p->sa->spacetype == SPACE_VIEW3D) &&
(p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH))
@@ -862,11 +864,11 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p,
RegionView3D *rv3d = p->ar->regiondata;
const int mval[2] = {x, y};
float mval_3d[3];
-
+
if (ED_view3d_autodist_simple(p->ar, mval, mval_3d, 0, NULL)) {
const float depth_mval = view3d_point_depth(rv3d, mval_3d);
const float depth_pt = view3d_point_depth(rv3d, &pt->x);
-
+
if (depth_pt > depth_mval) {
return true;
}
@@ -875,58 +877,6 @@ static bool gp_stroke_eraser_is_occluded(tGPsdata *p,
return false;
}
-/* eraser tool - check if part of stroke occurs within last segment drawn by eraser */
-static short gp_stroke_eraser_strokeinside(const int mval[2], const int UNUSED(mvalo[2]),
- int rad, int x0, int y0, int x1, int y1)
-{
- /* simple within-radius check for now */
- const float mval_fl[2] = {mval[0], mval[1]};
- const float screen_co_a[2] = {x0, y0};
- const float screen_co_b[2] = {x1, y1};
-
- if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) {
- return true;
- }
-
- /* not inside */
- return false;
-}
-
-static void gp_point_to_xy(tGPsdata *p, bGPDstroke *gps, bGPDspoint *pt,
- int *r_x, int *r_y)
-{
- ARegion *ar = p->ar;
- View2D *v2d = p->v2d;
- rctf *subrect = p->subrect;
- int xyval[2];
-
- if (gps->flag & GP_STROKE_3DSPACE) {
- if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
- *r_x = xyval[0];
- *r_y = xyval[1];
- }
- else {
- *r_x = V2D_IS_CLIPPED;
- *r_y = V2D_IS_CLIPPED;
- }
- }
- else if (gps->flag & GP_STROKE_2DSPACE) {
- float vec[3] = {pt->x, pt->y, 0.0f};
- mul_m4_v3(p->mat, vec);
- UI_view2d_view_to_region_clip(v2d, vec[0], vec[1], r_x, r_y);
- }
- else {
- if (subrect == NULL) { /* normal 3D view */
- *r_x = (int)(pt->x / 100 * ar->winx);
- *r_y = (int)(pt->y / 100 * ar->winy);
- }
- else { /* camera view, use subrect */
- *r_x = (int)((pt->x / 100) * BLI_rctf_size_x(subrect)) + subrect->xmin;
- *r_y = (int)((pt->y / 100) * BLI_rctf_size_y(subrect)) + subrect->ymin;
- }
- }
-}
-
/* eraser tool - evaluation per stroke */
/* TODO: this could really do with some optimization (KD-Tree/BVH?) */
@@ -940,12 +890,12 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
if (gps->totpoints == 0) {
/* just free stroke */
- if (gps->points)
+ if (gps->points)
MEM_freeN(gps->points);
BLI_freelinkN(&gpf->strokes, gps);
}
else if (gps->totpoints == 1) {
- gp_point_to_xy(p, gps, gps->points, &x0, &y0);
+ gp_point_to_xy(&p->gsc, gps, gps->points, &x0, &y0);
/* do boundbox check first */
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
@@ -958,7 +908,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
}
}
else {
- /* loop over the points in the stroke, checking for intersections
+ /* loop over the points in the stroke, checking for intersections
* - an intersection will require the stroke to be split
*/
for (i = 0; (i + 1) < gps->totpoints; i++) {
@@ -966,8 +916,8 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
pt1 = gps->points + i;
pt2 = gps->points + i + 1;
- gp_point_to_xy(p, gps, pt1, &x0, &y0);
- gp_point_to_xy(p, gps, pt2, &x1, &y1);
+ gp_point_to_xy(&p->gsc, gps, pt1, &x0, &y0);
+ gp_point_to_xy(&p->gsc, gps, pt2, &x1, &y1);
/* check that point segment of the boundbox of the eraser stroke */
if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
@@ -977,7 +927,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
* eraser region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
*/
- if (gp_stroke_eraser_strokeinside(mval, mvalo, rad, x0, y0, x1, y1)) {
+ if (gp_stroke_inside_circle(mval, mvalo, rad, x0, y0, x1, y1)) {
if ((gp_stroke_eraser_is_occluded(p, pt1, x0, y0) == false) ||
(gp_stroke_eraser_is_occluded(p, pt2, x1, y1) == false))
{
@@ -1003,16 +953,16 @@ static void gp_stroke_doeraser(tGPsdata *p)
rect.ymin = p->mval[1] - p->radius;
rect.xmax = p->mval[0] + p->radius;
rect.ymax = p->mval[1] + p->radius;
-
+
if (p->sa->spacetype == SPACE_VIEW3D) {
if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) {
View3D *v3d = p->sa->spacedata.first;
-
+
view3d_region_operator_needs_opengl(p->win, p->ar);
ED_view3d_autodist_init(p->scene, p->ar, v3d, 0);
}
}
-
+
/* loop over strokes, checking segments for intersections */
for (gps = gpf->strokes.first; gps; gps = gpn) {
gpn = gps->next;
@@ -1043,13 +993,13 @@ static void gp_session_validatebuffer(tGPsdata *p)
/* reset flags */
gpd->sbuffer_sflag = 0;
-
+
/* reset inittime */
p->inittime = 0.0;
}
/* (re)init new painting data */
-static int gp_session_initdata(bContext *C, tGPsdata *p)
+static bool gp_session_initdata(bContext *C, tGPsdata *p)
{
bGPdata **gpd_ptr = NULL;
ScrArea *curarea = CTX_wm_area(C);
@@ -1066,8 +1016,9 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
/* pass on current scene and window */
p->scene = CTX_data_scene(C);
p->win = CTX_wm_window(C);
-
+
unit_m4(p->imat);
+ unit_m4(p->mat);
switch (curarea->spacetype) {
/* supported views first */
@@ -1076,7 +1027,7 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
/* View3D *v3d = curarea->spacedata.first; */
/* RegionView3D *rv3d = ar->regiondata; */
- /* set current area
+ /* set current area
* - must verify that region data is 3D-view (and not something else)
*/
p->sa = curarea;
@@ -1131,7 +1082,13 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
case SPACE_CLIP:
{
SpaceClip *sc = curarea->spacedata.first;
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ if (clip == NULL) {
+ p->status = GP_STATUS_ERROR;
+ return false;
+ }
+
/* set the current area */
p->sa = curarea;
p->ar = ar;
@@ -1146,15 +1103,22 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
p->custom_color[3] = 0.9f;
if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
- MovieClip *clip = ED_space_clip_get_clip(sc);
int framenr = ED_space_clip_get_clip_frame_number(sc);
MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking);
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
-
- p->imat[3][0] -= marker->pos[0];
- p->imat[3][1] -= marker->pos[1];
+ MovieTrackingMarker *marker = track ? BKE_tracking_marker_get(track, framenr) : NULL;
+
+ if (marker) {
+ p->imat[3][0] -= marker->pos[0];
+ p->imat[3][1] -= marker->pos[1];
+ }
+ else {
+ p->status = GP_STATUS_ERROR;
+ return false;
+ }
}
+
invert_m4_m4(p->mat, p->imat);
+ copy_m4_m4(p->gsc.mat, p->mat);
break;
}
/* unsupported views */
@@ -1199,10 +1163,10 @@ static int gp_session_initdata(bContext *C, tGPsdata *p)
static tGPsdata *gp_session_initpaint(bContext *C)
{
tGPsdata *p = NULL;
-
+
/* create new context data */
p = MEM_callocN(sizeof(tGPsdata), "GPencil Drawing Data");
-
+
gp_session_initdata(C, p);
/* return context data for running paint operator */
@@ -1233,7 +1197,7 @@ static void gp_session_cleanup(tGPsdata *p)
/* init new stroke */
static void gp_paint_initstroke(tGPsdata *p, short paintmode)
-{
+{
/* get active layer (or add a new one if non-existent) */
p->gpl = gpencil_layer_getactive(p->gpd);
if (p->gpl == NULL) {
@@ -1248,7 +1212,7 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode)
printf("Error: Cannot paint on locked layer\n");
return;
}
-
+
/* get active frame (add a new one if not matching frame) */
p->gpf = gpencil_layer_getframe(p->gpl, p->scene->r.cfra, 1);
if (p->gpf == NULL) {
@@ -1264,7 +1228,7 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode)
p->paintmode = paintmode;
if (p->paintmode == GP_PAINTMODE_ERASER) {
p->gpd->sbuffer_sflag |= GP_STROKE_ERASER;
-
+
/* check if we should respect depth while erasing */
if (p->sa->spacetype == SPACE_VIEW3D) {
if (p->gpl->flag & GP_LAYER_NO_XRAY) {
@@ -1272,11 +1236,21 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode)
}
}
}
-
+ else {
+ /* disable eraser flags - so that we can switch modes during a session */
+ p->gpd->sbuffer_sflag &= ~GP_STROKE_ERASER;
+
+ if (p->sa->spacetype == SPACE_VIEW3D) {
+ if (p->gpl->flag & GP_LAYER_NO_XRAY) {
+ p->flags &= ~GP_PAINTFLAG_V3D_ERASER_DEPTH;
+ }
+ }
+ }
+
/* set 'initial run' flag, which is only used to denote when a new stroke is starting */
p->flags |= GP_PAINTFLAG_FIRSTRUN;
-
+
/* when drawing in the camera view, in 2D space, set the subrect */
if (!(p->gpd->flag & GP_DATA_VIEWALIGN)) {
if (p->sa->spacetype == SPACE_VIEW3D) {
@@ -1290,7 +1264,21 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode)
}
}
}
-
+
+ /* init stroke point space-conversion settings... */
+ p->gsc.gpd = p->gpd;
+ p->gsc.gpl = p->gpl;
+
+ p->gsc.sa = p->sa;
+ p->gsc.ar = p->ar;
+ p->gsc.v2d = p->v2d;
+
+ p->gsc.subrect_data = p->subrect_data;
+ p->gsc.subrect = p->subrect;
+
+ copy_m4_m4(p->gsc.mat, p->mat);
+
+
/* check if points will need to be made in view-aligned space */
if (p->gpd->flag & GP_DATA_VIEWALIGN) {
switch (p->sa->spacetype) {
@@ -1340,7 +1328,7 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode)
/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */
static void gp_paint_strokeend(tGPsdata *p)
{
- /* for surface sketching, need to set the right OpenGL context stuff so that
+ /* for surface sketching, need to set the right OpenGL context stuff so that
* the conversions will project the values correctly...
*/
if (gpencil_project_check(p)) {
@@ -1395,13 +1383,18 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr)
glTranslatef((float)x, (float)y, 0.0f);
- glColor4ub(255, 255, 255, 128);
-
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
+ glColor4ub(255, 100, 100, 20);
+ glutil_draw_filled_arc(0.0, M_PI * 2.0, p->radius, 40);
+
+ setlinestyle(6);
+
+ glColor4ub(255, 100, 100, 200);
glutil_draw_lined_arc(0.0, M_PI * 2.0, p->radius, 40);
+ setlinestyle(0);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
@@ -1417,9 +1410,9 @@ static void gpencil_draw_toggle_eraser_cursor(bContext *C, tGPsdata *p, short en
WM_paint_cursor_end(CTX_wm_manager(C), p->erasercursor);
p->erasercursor = NULL;
}
- else if (enable) {
+ else if (enable && !p->erasercursor) {
/* enable cursor */
- p->erasercursor = WM_paint_cursor_activate(CTX_wm_manager(C),
+ p->erasercursor = WM_paint_cursor_activate(CTX_wm_manager(C),
NULL, /* XXX */
gpencil_draw_eraser, p);
}
@@ -1526,13 +1519,13 @@ static void gpencil_draw_status_indicators(tGPsdata *p)
ED_area_headerprint(p->sa, IFACE_("Grease Pencil Freehand Session: Hold and drag LMB to draw | "
"ESC/Enter to end"));
break;
-
+
default: /* unhandled future cases */
ED_area_headerprint(p->sa, IFACE_("Grease Pencil Session: ESC/Enter to end"));
break;
}
break;
-
+
case GP_STATUS_ERROR:
case GP_STATUS_DONE:
/* clear status string */
@@ -1626,15 +1619,6 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event)
else
p->pressure = 1.0f;
- /* fill in stroke data (not actually used directly by gpencil_draw_apply) */
- RNA_collection_add(op->ptr, "stroke", &itemptr);
-
- mousef[0] = p->mval[0];
- mousef[1] = p->mval[1];
- RNA_float_set_array(&itemptr, "mouse", mousef);
- RNA_float_set(&itemptr, "pressure", p->pressure);
- RNA_boolean_set(&itemptr, "is_start", (p->flags & GP_PAINTFLAG_FIRSTRUN));
-
/* special exception for start of strokes (i.e. maybe for just a dot) */
if (p->flags & GP_PAINTFLAG_FIRSTRUN) {
p->flags &= ~GP_PAINTFLAG_FIRSTRUN;
@@ -1651,6 +1635,15 @@ static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event)
return;
}
+ /* fill in stroke data (not actually used directly by gpencil_draw_apply) */
+ RNA_collection_add(op->ptr, "stroke", &itemptr);
+
+ mousef[0] = p->mval[0];
+ mousef[1] = p->mval[1];
+ RNA_float_set_array(&itemptr, "mouse", mousef);
+ RNA_float_set(&itemptr, "pressure", p->pressure);
+ RNA_boolean_set(&itemptr, "is_start", (p->flags & GP_PAINTFLAG_FIRSTRUN) != 0);
+
RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
/* apply the current latest drawing point */
@@ -1721,7 +1714,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
gpencil_draw_apply(op, p);
}
RNA_END;
-
+
/* printf("\tGP - done\n"); */
/* cleanup */
@@ -1747,7 +1740,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
/* try to initialize context data needed while drawing */
if (!gpencil_draw_init(C, op)) {
- if (op->customdata)
+ if (op->customdata)
MEM_freeN(op->customdata);
if (G.debug & G_DEBUG)
printf("\tGP - no valid data\n");
@@ -1755,12 +1748,12 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
}
else
p = op->customdata;
-
+
/* TODO: set any additional settings that we can take from the events?
* TODO? if tablet is erasing, force eraser to be on? */
-
+
/* TODO: move cursor setting stuff to stroke-start so that paintmode can be changed midway... */
-
+
/* if eraser is on, draw radial aid */
if (p->paintmode == GP_PAINTMODE_ERASER) {
gpencil_draw_toggle_eraser_cursor(C, p, true);
@@ -1772,11 +1765,8 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
else
WM_cursor_modal_set(win, BC_PAINTBRUSHCURSOR);
- /* special hack: if there was an initial event, then we were invoked via a hotkey, and
- * painting should start immediately. Otherwise, this was called from a toolbar, in which
- * case we should wait for the mouse to be clicked.
- */
- if (event->val == KM_PRESS) {
+ /* only start drawing immediately if we're allowed to do so... */
+ if (RNA_boolean_get(op->ptr, "wait_for_input") == false) {
/* hotkey invoked - start drawing */
/* printf("\tGP - set first spot\n"); */
p->status = GP_STATUS_PAINTING;
@@ -1833,15 +1823,15 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
static void gpencil_stroke_end(wmOperator *op)
{
tGPsdata *p = op->customdata;
-
+
gp_paint_cleanup(p);
-
+
gpencil_undo_push(p->gpd);
-
+
gp_session_cleanup(p);
-
+
p->status = GP_STATUS_IDLING;
-
+
p->gpd = NULL;
p->gpl = NULL;
p->gpf = NULL;
@@ -1865,11 +1855,14 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
* better in tools that immediately apply
* in 3D space.
*/
-
+
/* we don't pass on key events, GP is used with key-modifiers - prevents Dkey to insert drivers */
if (ISKEYBOARD(event->type)) {
- if (ELEM(event->type, LEFTARROWKEY, DOWNARROWKEY, RIGHTARROWKEY, UPARROWKEY)) {
- /* allow some keys - for frame changing: [#33412] */
+ if (ELEM(event->type, LEFTARROWKEY, DOWNARROWKEY, RIGHTARROWKEY, UPARROWKEY, ZKEY)) {
+ /* allow some keys:
+ * - for frame changing [#33412]
+ * - for undo (during sketching sessions)
+ */
}
else {
estate = OPERATOR_RUNNING_MODAL;
@@ -1878,7 +1871,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
//printf("\tGP - handle modal event...\n");
- /* exit painting mode (and/or end current stroke)
+ /* exit painting mode (and/or end current stroke)
* NOTE: cannot do RIGHTMOUSE (as is standard for canceling) as that would break polyline [#32647]
*/
if (ELEM(event->type, RETKEY, PADENTER, ESCKEY, SPACEKEY)) {
@@ -1888,7 +1881,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
estate = OPERATOR_FINISHED;
}
- /* toggle painting mode upon mouse-button movement
+ /* toggle painting mode upon mouse-button movement
* - LEFTMOUSE = standard drawing (all) / straight line drawing (all) / polyline (toolbox only)
* - RIGHTMOUSE = polyline (hotkey) / eraser (all)
* (Disabling RIGHTMOUSE case here results in bugs like [#32647])
@@ -1898,7 +1891,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (p->status == GP_STATUS_PAINTING) {
int sketch = 0;
- /* basically, this should be mouse-button up = end stroke
+ /* basically, this should be mouse-button up = end stroke
* BUT what happens next depends on whether we 'painting sessions' is enabled
*/
sketch |= GPENCIL_SKETCH_SESSIONS_ON(p->scene);
@@ -1910,6 +1903,27 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* printf("\t\tGP - end stroke only\n"); */
gpencil_stroke_end(op);
+ /* If eraser mode is on, turn it off after the stroke finishes
+ * NOTE: This just makes it nicer to work with drawing sessions
+ */
+ if (p->paintmode == GP_PAINTMODE_ERASER) {
+ p->paintmode = RNA_enum_get(op->ptr, "mode");
+
+ /* if the original mode was *still* eraser,
+ * we'll let it say for now, since this gives
+ * users an opportunity to have visual feedback
+ * when adjusting eraser size
+ */
+ if (p->paintmode != GP_PAINTMODE_ERASER) {
+ /* turn off cursor...
+ * NOTE: this should be enough for now
+ * Just hiding this makes it seem like
+ * you can paint again...
+ */
+ gpencil_draw_toggle_eraser_cursor(C, p, false);
+ }
+ }
+
/* we've just entered idling state, so this event was processed (but no others yet) */
estate = OPERATOR_RUNNING_MODAL;
@@ -1923,6 +1937,20 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
else if (event->val == KM_PRESS) {
+ /* Switch paintmode (temporarily if need be) based on which button was used
+ * NOTE: This is to make it more convenient to erase strokes when using drawing sessions
+ */
+ if (event->type == LEFTMOUSE) {
+ /* restore drawmode to default */
+ p->paintmode = RNA_enum_get(op->ptr, "mode");
+ }
+ else if (event->type == RIGHTMOUSE) {
+ /* turn on eraser */
+ p->paintmode = GP_PAINTMODE_ERASER;
+ }
+
+ gpencil_draw_toggle_eraser_cursor(C, p, p->paintmode == GP_PAINTMODE_ERASER);
+
/* not painting, so start stroke (this should be mouse-button down) */
p = gpencil_stroke_begin(C, op);
@@ -1967,12 +1995,12 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
case PADPLUSKEY:
p->radius += 5;
break;
-
+
case WHEELUPMOUSE: /* smaller */
case PADMINUS:
p->radius -= 5;
- if (p->radius < 0)
+ if (p->radius < 0)
p->radius = 0;
break;
}
@@ -1983,7 +2011,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* event handled, so just tag as running modal */
estate = OPERATOR_RUNNING_MODAL;
}
- /* there shouldn't be any other events, but just in case there are, let's swallow them
+ /* there shouldn't be any other events, but just in case there are, let's swallow them
* (i.e. to prevent problems with undo)
*/
else {
@@ -2006,7 +2034,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
gpencil_draw_exit(C, op);
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
break;
-
+
case OPERATOR_CANCELLED:
gpencil_draw_exit(C, op);
break;
@@ -2053,6 +2081,8 @@ void GPENCIL_OT_draw(wmOperatorType *ot)
/* settings for drawing */
ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements");
-
RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
+
+ /* NOTE: wait for input is enabled by default, so that all UI code can work properly without needing users to know about this */
+ RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", "Wait for first click instead of painting immediately");
}
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
new file mode 100644
index 00000000000..9ba77a4244e
--- /dev/null
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -0,0 +1,946 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014, Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/gpencil/gpencil_select.c
+ * \ingroup edgpencil
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_lasso.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_gpencil_types.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 "BKE_context.h"
+#include "BKE_curve.h"
+#include "BKE_depsgraph.h"
+#include "BKE_global.h"
+#include "BKE_gpencil.h"
+#include "BKE_library.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+#include "BKE_screen.h"
+
+#include "UI_interface.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_view2d.h"
+
+#include "ED_gpencil.h"
+#include "ED_view3d.h"
+#include "ED_keyframing.h"
+
+#include "gpencil_intern.h"
+
+/* ********************************************** */
+/* Polling callbacks */
+
+static int gpencil_select_poll(bContext *C)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bGPDlayer *gpl = gpencil_layer_getactive(gpd);
+
+ /* only if there's an active layer with an active frame */
+ return (gpl && gpl->actframe);
+}
+
+/* ********************************************** */
+/* Select All Operator */
+
+static int gpencil_select_all_exec(bContext *C, wmOperator *op)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ int action = RNA_enum_get(op->ptr, "action");
+
+ if (gpd == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* for "toggle", test for existing selected strokes */
+ if (action == SEL_TOGGLE) {
+ action = SEL_SELECT;
+
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ if (gps->flag & GP_STROKE_SELECT) {
+ action = SEL_DESELECT;
+ break; // XXX: this only gets out of the inner loop...
+ }
+ }
+ CTX_DATA_END;
+ }
+
+ /* if deselecting, we need to deselect strokes across all frames
+ * - Currently, an exception is only given for deselection
+ * Selecting and toggling should only affect what's visible,
+ * while deselecting helps clean up unintended/forgotten
+ * stuff on other frames
+ */
+ if (action == SEL_DESELECT) {
+ /* deselect strokes across editable layers
+ * NOTE: we limit ourselves to editable layers, since once a layer is "locked/hidden
+ * nothing should be able to touch it
+ */
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ bGPDframe *gpf;
+
+ /* deselect all strokes on all frames */
+ for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ bGPDstroke *gps;
+
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ bGPDspoint *pt;
+ int i;
+
+ /* only edit strokes that are valid in this view... */
+ if (ED_gpencil_stroke_can_use(C, gps)) {
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+
+ gps->flag &= ~GP_STROKE_SELECT;
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+ }
+ else {
+ /* select or deselect all strokes */
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ bGPDspoint *pt;
+ int i;
+ bool selected = false;
+
+ /* Change selection status of all points, then make the stroke match */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ switch (action) {
+ case SEL_SELECT:
+ pt->flag |= GP_SPOINT_SELECT;
+ break;
+ //case SEL_DESELECT:
+ // pt->flag &= ~GP_SPOINT_SELECT;
+ // break;
+ case SEL_INVERT:
+ pt->flag ^= GP_SPOINT_SELECT;
+ break;
+ }
+
+ if (pt->flag & GP_SPOINT_SELECT)
+ selected = true;
+ }
+
+ /* Change status of stroke */
+ if (selected)
+ gps->flag |= GP_STROKE_SELECT;
+ else
+ gps->flag &= ~GP_STROKE_SELECT;
+ }
+ CTX_DATA_END;
+ }
+
+ /* updates */
+ WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_select_all(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "(De)select All Strokes";
+ ot->idname = "GPENCIL_OT_select_all";
+ ot->description = "Change selection of all Grease Pencil strokes currently visible";
+
+ /* callbacks */
+ ot->exec = gpencil_select_all_exec;
+ ot->poll = gpencil_select_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ WM_operator_properties_select_all(ot);
+}
+
+/* ********************************************** */
+/* Select Linked */
+
+static int gpencil_select_linked_exec(bContext *C, wmOperator *op)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+
+ if (gpd == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* select all points in selected strokes */
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ if (gps->flag & GP_STROKE_SELECT) {
+ bGPDspoint *pt;
+ int i;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ pt->flag |= GP_SPOINT_SELECT;
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ /* updates */
+ WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_select_linked(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Linked";
+ ot->idname = "GPENCIL_OT_select_linked";
+ ot->description = "Select all points in same strokes as already selected points";
+
+ /* callbacks */
+ ot->exec = gpencil_select_linked_exec;
+ ot->poll = gpencil_select_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ********************************************** */
+/* Select More */
+
+static int gpencil_select_more_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ if (gps->flag & GP_STROKE_SELECT) {
+ bGPDspoint *pt;
+ int i;
+ bool prev_sel;
+
+ /* First Pass: Go in forward order, expanding selection if previous was selected (pre changes)...
+ * - This pass covers the "after" edges of selection islands
+ */
+ prev_sel = false;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ /* selected point - just set flag for next point */
+ prev_sel = true;
+ }
+ else {
+ /* unselected point - expand selection if previous was selected... */
+ if (prev_sel) {
+ pt->flag |= GP_SPOINT_SELECT;
+ }
+ prev_sel = false;
+ }
+ }
+
+ /* Second Pass: Go in reverse order, doing the same as before (except in opposite order)
+ * - This pass covers the "before" edges of selection islands
+ */
+ prev_sel = false;
+ for (pt -= 1; i > 0; i--, pt--) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ prev_sel = true;
+ }
+ else {
+ /* unselected point - expand selection if previous was selected... */
+ if (prev_sel) {
+ pt->flag |= GP_SPOINT_SELECT;
+ }
+ prev_sel = false;
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ /* updates */
+ WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_select_more(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select More";
+ ot->idname = "GPENCIL_OT_select_more";
+ ot->description = "Grow sets of selected Grease Pencil points";
+
+ /* callbacks */
+ ot->exec = gpencil_select_more_exec;
+ ot->poll = gpencil_select_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ********************************************** */
+/* Select Less */
+
+static int gpencil_select_less_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ if (gps->flag & GP_STROKE_SELECT) {
+ bGPDspoint *pt;
+ int i;
+ bool prev_sel;
+
+ /* First Pass: Go in forward order, shrinking selection if previous was not selected (pre changes)...
+ * - This pass covers the "after" edges of selection islands
+ */
+ prev_sel = false;
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ /* shrink if previous wasn't selected */
+ if (prev_sel == false) {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+ prev_sel = true;
+ }
+ else {
+ /* mark previous as being unselected - and hence, is trigger for shrinking */
+ prev_sel = false;
+ }
+ }
+
+ /* Second Pass: Go in reverse order, doing the same as before (except in opposite order)
+ * - This pass covers the "before" edges of selection islands
+ */
+ prev_sel = false;
+ for (pt -= 1; i > 0; i--, pt--) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ /* shrink if previous wasn't selected */
+ if (prev_sel == false) {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+ prev_sel = true;
+ }
+ else {
+ /* mark previous as being unselected - and hence, is trigger for shrinking */
+ prev_sel = false;
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ /* updates */
+ WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_select_less(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Less";
+ ot->idname = "GPENCIL_OT_select_less";
+ ot->description = "Shrink sets of selected Grease Pencil points";
+
+ /* callbacks */
+ ot->exec = gpencil_select_less_exec;
+ ot->poll = gpencil_select_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ********************************************** */
+/* Circle Select Operator */
+
+/* Helper to check if a given stroke is within the area */
+/* NOTE: Code here is adapted (i.e. copied directly) from gpencil_paint.c::gp_stroke_eraser_dostroke()
+ * It would be great to de-duplicate the logic here sometime, but that can wait...
+ */
+static bool gp_stroke_do_circle_sel(bGPDstroke *gps, GP_SpaceConversion *gsc,
+ const int mx, const int my, const int radius,
+ const bool select, rcti *rect)
+{
+ bGPDspoint *pt1, *pt2;
+ int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
+ int i;
+ bool changed = false;
+
+ if (gps->totpoints == 1) {
+ gp_point_to_xy(gsc, gps, gps->points, &x0, &y0);
+
+ /* do boundbox check first */
+ if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
+ /* only check if point is inside */
+ if (((x0 - mx) * (x0 - mx) + (y0 - my) * (y0 - my)) <= radius * radius) {
+ /* change selection */
+ if (select) {
+ gps->points->flag |= GP_SPOINT_SELECT;
+ gps->flag |= GP_STROKE_SELECT;
+ }
+ else {
+ gps->points->flag &= ~GP_SPOINT_SELECT;
+ gps->flag &= ~GP_STROKE_SELECT;
+ }
+
+ return true;
+ }
+ }
+ }
+ else {
+ /* Loop over the points in the stroke, checking for intersections
+ * - an intersection means that we touched the stroke
+ */
+ for (i = 0; (i + 1) < gps->totpoints; i++) {
+ /* get points to work with */
+ pt1 = gps->points + i;
+ pt2 = gps->points + i + 1;
+
+ gp_point_to_xy(gsc, gps, pt1, &x0, &y0);
+ gp_point_to_xy(gsc, gps, pt2, &x1, &y1);
+
+ /* check that point segment of the boundbox of the selection stroke */
+ if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
+ ((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1)))
+ {
+ int mval[2] = {mx, my};
+ int mvalo[2] = {mx, my}; /* dummy - this isn't used... */
+
+ /* check if point segment of stroke had anything to do with
+ * eraser region (either within stroke painted, or on its lines)
+ * - this assumes that linewidth is irrelevant
+ */
+ if (gp_stroke_inside_circle(mval, mvalo, radius, x0, y0, x1, y1)) {
+ /* change selection of stroke, and then of both points
+ * (as the last point otherwise wouldn't get selected
+ * as we only do n-1 loops through)
+ */
+ if (select) {
+ pt1->flag |= GP_SPOINT_SELECT;
+ pt2->flag |= GP_SPOINT_SELECT;
+
+ changed = true;
+ }
+ else {
+ pt1->flag &= ~GP_SPOINT_SELECT;
+ pt2->flag &= ~GP_SPOINT_SELECT;
+
+ changed = true;
+ }
+ }
+ }
+ }
+
+ /* Ensure that stroke selection is in sync with its points */
+ gpencil_stroke_sync_selection(gps);
+ }
+
+ return changed;
+}
+
+
+static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
+{
+ ScrArea *sa = CTX_wm_area(C);
+
+ const int mx = RNA_int_get(op->ptr, "x");
+ const int my = RNA_int_get(op->ptr, "y");
+ const int radius = RNA_int_get(op->ptr, "radius");
+
+ const int gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
+ const bool select = (gesture_mode == GESTURE_MODAL_SELECT);
+
+ GP_SpaceConversion gsc = {NULL};
+ rcti rect = {0}; /* for bounding rect around circle (for quicky intersection testing) */
+
+ bool changed = false;
+
+
+ /* sanity checks */
+ if (sa == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active area");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* init space conversion stuff */
+ gp_point_conversion_init(C, &gsc);
+
+
+ /* rect is rectangle of selection circle */
+ rect.xmin = mx - radius;
+ rect.ymin = my - radius;
+ rect.xmax = mx + radius;
+ rect.ymax = my + radius;
+
+
+ /* find visible strokes, and select if hit */
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ changed |= gp_stroke_do_circle_sel(gps, &gsc, mx, my, radius, select, &rect);
+ }
+ CTX_DATA_END;
+
+ /* updates */
+ if (changed) {
+ WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_select_circle(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Circle Select";
+ ot->description = "Select Grease Pencil strokes using brush selection";
+ ot->idname = "GPENCIL_OT_select_circle";
+
+ /* callbacks */
+ ot->invoke = WM_gesture_circle_invoke;
+ ot->modal = WM_gesture_circle_modal;
+ ot->exec = gpencil_circle_select_exec;
+ ot->poll = gpencil_select_poll;
+ ot->cancel = WM_gesture_circle_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "radius", 1, 1, INT_MAX, "Radius", "", 1, INT_MAX);
+ RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX);
+}
+
+/* ********************************************** */
+/* Box Selection */
+
+static int gpencil_border_select_exec(bContext *C, wmOperator *op)
+{
+ ScrArea *sa = CTX_wm_area(C);
+
+ const int gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
+ const bool select = (gesture_mode == GESTURE_MODAL_SELECT);
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
+
+ GP_SpaceConversion gsc = {NULL};
+ rcti rect = {0};
+
+ bool changed = false;
+
+
+ /* sanity checks */
+ if (sa == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active area");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* init space conversion stuff */
+ gp_point_conversion_init(C, &gsc);
+
+
+ /* deselect all strokes first? */
+ if (select && !extend) {
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ bGPDspoint *pt;
+ int i;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+
+ gps->flag &= ~GP_STROKE_SELECT;
+ }
+ CTX_DATA_END;
+ }
+
+ /* get settings from operator */
+ WM_operator_properties_border_to_rcti(op, &rect);
+
+ /* select/deselect points */
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ bGPDspoint *pt;
+ int i;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ int x0, y0;
+
+ /* convert point coords to screenspace */
+ gp_point_to_xy(&gsc, gps, pt, &x0, &y0);
+
+ /* test if in selection rect */
+ if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0)) {
+ if (select) {
+ pt->flag |= GP_SPOINT_SELECT;
+ }
+ else {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+
+ changed = true;
+ }
+ }
+
+ /* Ensure that stroke selection is in sync with its points */
+ gpencil_stroke_sync_selection(gps);
+ }
+ CTX_DATA_END;
+
+ /* updates */
+ if (changed) {
+ WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_select_border(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Border Select";
+ ot->description = "Select Grease Pencil strokes within a rectangular region";
+ ot->idname = "GPENCIL_OT_select_border";
+
+ /* callbacks */
+ ot->invoke = WM_border_select_invoke;
+ ot->exec = gpencil_border_select_exec;
+ ot->modal = WM_border_select_modal;
+ ot->cancel = WM_border_select_cancel;
+
+ ot->poll = gpencil_select_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* rna */
+ WM_operator_properties_gesture_border(ot, true);
+}
+
+/* ********************************************** */
+/* Lasso */
+
+static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
+{
+ GP_SpaceConversion gsc = {NULL};
+ rcti rect = {0};
+
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
+ const bool select = !RNA_boolean_get(op->ptr, "deselect");
+
+ int mcords_tot;
+ const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
+
+ bool changed = false;
+
+ /* sanity check */
+ if (mcords == NULL)
+ return OPERATOR_PASS_THROUGH;
+
+ /* compute boundbox of lasso (for faster testing later) */
+ BLI_lasso_boundbox(&rect, mcords, mcords_tot);
+
+ /* init space conversion stuff */
+ gp_point_conversion_init(C, &gsc);
+
+ /* deselect all strokes first? */
+ if (select && !extend) {
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ bGPDspoint *pt;
+ int i;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+
+ gps->flag &= ~GP_STROKE_SELECT;
+ }
+ CTX_DATA_END;
+ }
+
+ /* select/deselect points */
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ bGPDspoint *pt;
+ int i;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ int x0, y0;
+
+ /* convert point coords to screenspace */
+ gp_point_to_xy(&gsc, gps, pt, &x0, &y0);
+
+ /* test if in lasso boundbox + within the lasso noose */
+ if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0) &&
+ BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX))
+ {
+ if (select) {
+ pt->flag |= GP_SPOINT_SELECT;
+ }
+ else {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+
+ changed = true;
+ }
+ }
+
+ /* Ensure that stroke selection is in sync with its points */
+ gpencil_stroke_sync_selection(gps);
+ }
+ CTX_DATA_END;
+
+ /* cleanup */
+ MEM_freeN((void *)mcords);
+
+ /* updates */
+ if (changed) {
+ WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_select_lasso(wmOperatorType *ot)
+{
+ ot->name = "Lasso Select Strokes";
+ ot->description = "Select Grease Pencil strokes using lasso selection";
+ ot->idname = "GPENCIL_OT_select_lasso";
+
+ ot->invoke = WM_gesture_lasso_invoke;
+ ot->modal = WM_gesture_lasso_modal;
+ ot->exec = gpencil_lasso_select_exec;
+ ot->poll = gpencil_select_poll;
+ ot->cancel = WM_gesture_lasso_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", "");
+ RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items");
+ RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first");
+}
+
+/* ********************************************** */
+/* Mouse Click to Select */
+
+static int gpencil_select_exec(bContext *C, wmOperator *op)
+{
+ ScrArea *sa = CTX_wm_area(C);
+
+ /* "radius" is simply a threshold (screen space) to make it easier to test with a tolerance */
+ const float radius = 0.75f * U.widget_unit;
+ const int radius_squared = (int)(radius * radius);
+
+ bool extend = RNA_boolean_get(op->ptr, "extend");
+ bool deselect = RNA_boolean_get(op->ptr, "deselect");
+ bool toggle = RNA_boolean_get(op->ptr, "toggle");
+ bool whole = RNA_boolean_get(op->ptr, "entire_strokes");
+
+ int location[2] = {0};
+ int mx, my;
+
+ GP_SpaceConversion gsc = {NULL};
+
+ bGPDstroke *hit_stroke = NULL;
+ bGPDspoint *hit_point = NULL;
+
+ /* sanity checks */
+ if (sa == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active area");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* init space conversion stuff */
+ gp_point_conversion_init(C, &gsc);
+
+ /* get mouse location */
+ RNA_int_get_array(op->ptr, "location", location);
+
+ mx = location[0];
+ my = location[1];
+
+ /* First Pass: Find stroke point which gets hit */
+ /* XXX: maybe we should go from the top of the stack down instead... */
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ bGPDspoint *pt;
+ int i;
+ int hit_index = -1;
+
+ /* firstly, check for hit-point */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ int x0, y0;
+
+ gp_point_to_xy(&gsc, gps, pt, &x0, &y0);
+
+ /* do boundbox check first */
+ if (!ELEM(V2D_IS_CLIPPED, x0, x0)) {
+ /* only check if point is inside */
+ if (((x0 - mx) * (x0 - mx) + (y0 - my) * (y0 - my)) <= radius_squared) {
+ hit_stroke = gps;
+ hit_point = pt;
+ break;
+ }
+ }
+ }
+
+ /* skip to next stroke if nothing found */
+ if (hit_index == -1)
+ continue;
+ }
+ CTX_DATA_END;
+
+ /* Abort if nothing hit... */
+ if (ELEM(NULL, hit_stroke, hit_point)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* adjust selection behaviour - for toggle option */
+ if (toggle) {
+ deselect = (hit_point->flag & GP_SPOINT_SELECT) != 0;
+ }
+
+ /* If not extending selection, deselect everything else */
+ if (extend == false) {
+ CTX_DATA_BEGIN(C, bGPDstroke *, gps, editable_gpencil_strokes)
+ {
+ /* deselect stroke and its points if selected */
+ if (gps->flag & GP_STROKE_SELECT) {
+ bGPDspoint *pt;
+ int i;
+
+ /* deselect points */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+
+ /* deselect stroke itself too */
+ gps->flag &= ~GP_STROKE_SELECT;
+ }
+ }
+ CTX_DATA_END;
+ }
+
+ /* Perform selection operations... */
+ if (whole) {
+ bGPDspoint *pt;
+ int i;
+
+ /* entire stroke's points */
+ for (i = 0, pt = hit_stroke->points; i < hit_stroke->totpoints; i++, pt++) {
+ if (deselect == false)
+ pt->flag |= GP_SPOINT_SELECT;
+ else
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+
+ /* stroke too... */
+ if (deselect == false)
+ hit_stroke->flag |= GP_STROKE_SELECT;
+ else
+ hit_stroke->flag &= ~GP_STROKE_SELECT;
+ }
+ else {
+ /* just the point (and the stroke) */
+ if (deselect == false) {
+ /* we're adding selection, so selection must be true */
+ hit_point->flag |= GP_SPOINT_SELECT;
+ hit_stroke->flag |= GP_STROKE_SELECT;
+ }
+ else {
+ /* deselect point */
+ hit_point->flag &= ~GP_SPOINT_SELECT;
+
+ /* ensure that stroke is selected correctly */
+ gpencil_stroke_sync_selection(hit_stroke);
+ }
+ }
+
+ /* updates */
+ if (hit_point != NULL) {
+ WM_event_add_notifier(C, NC_GPENCIL | NA_SELECTED, NULL);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static int gpencil_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ RNA_int_set_array(op->ptr, "location", event->mval);
+ return gpencil_select_exec(C, op);
+}
+
+void GPENCIL_OT_select(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Select";
+ ot->description = "Select Grease Pencil strokes and/or stroke points";
+ ot->idname = "GPENCIL_OT_select";
+
+ /* callbacks */
+ ot->invoke = gpencil_select_invoke;
+ ot->exec = gpencil_select_exec;
+ ot->poll = gpencil_select_poll;
+
+ /* flag */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_mouse_select(ot);
+
+ prop = RNA_def_boolean(ot->srna, "entire_strokes", false, "Entire Strokes", "Select entire strokes instead of just the nearest stroke vertex");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_int_vector(ot->srna, "location", 2, NULL, INT_MIN, INT_MAX, "Location", "Mouse location", INT_MIN, INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+}
+
+/* ********************************************** */
diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.c
index ff92d69f39d..34e640a4b7b 100644
--- a/source/blender/editors/gpencil/gpencil_undo.c
+++ b/source/blender/editors/gpencil/gpencil_undo.c
@@ -29,6 +29,7 @@
* \ingroup edgpencil
*/
+
#include <stdlib.h>
#include <string.h>
@@ -53,7 +54,7 @@
typedef struct bGPundonode {
struct bGPundonode *next, *prev;
-
+
char name[BKE_UNDO_STR_MAX];
struct bGPdata *gpd;
} bGPundonode;
@@ -69,13 +70,13 @@ int ED_gpencil_session_active(void)
int ED_undo_gpencil_step(bContext *C, int step, const char *name)
{
bGPdata **gpd_ptr = NULL, *new_gpd = NULL;
-
+
gpd_ptr = ED_gpencil_data_get_pointers(C, NULL);
-
+
if (step == 1) { /* undo */
//printf("\t\tGP - undo step\n");
if (cur_node->prev) {
- if (!name || strcmp(cur_node->name, name) == 0) {
+ if (!name || STREQ(cur_node->name, name)) {
cur_node = cur_node->prev;
new_gpd = cur_node->gpd;
}
@@ -84,24 +85,24 @@ int ED_undo_gpencil_step(bContext *C, int step, const char *name)
else if (step == -1) {
//printf("\t\tGP - redo step\n");
if (cur_node->next) {
- if (!name || strcmp(cur_node->name, name) == 0) {
+ if (!name || STREQ(cur_node->name, name)) {
cur_node = cur_node->next;
new_gpd = cur_node->gpd;
}
}
}
-
+
if (new_gpd) {
if (gpd_ptr) {
if (*gpd_ptr) {
bGPdata *gpd = *gpd_ptr;
bGPDlayer *gpl, *gpld;
-
+
free_gpencil_layers(&gpd->layers);
-
+
/* copy layers */
BLI_listbase_clear(&gpd->layers);
-
+
for (gpl = new_gpd->layers.first; gpl; gpl = gpl->next) {
/* make a copy of source layer and its data */
gpld = gpencil_layer_duplicate(gpl);
@@ -110,9 +111,9 @@ int ED_undo_gpencil_step(bContext *C, int step, const char *name)
}
}
}
-
+
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
-
+
return OPERATOR_FINISHED;
}
@@ -124,46 +125,56 @@ void gpencil_undo_init(bGPdata *gpd)
void gpencil_undo_push(bGPdata *gpd)
{
bGPundonode *undo_node;
-
+
//printf("\t\tGP - undo push\n");
-
+
if (cur_node) {
/* remove all un-done nodes from stack */
undo_node = cur_node->next;
-
+
while (undo_node) {
bGPundonode *next_node = undo_node->next;
-
+
+ /* HACK: animdata wasn't duplicated, so it shouldn't be freed here,
+ * or else the real copy will segfault when accessed
+ */
+ undo_node->gpd->adt = NULL;
+
BKE_gpencil_free(undo_node->gpd);
MEM_freeN(undo_node->gpd);
-
+
BLI_freelinkN(&undo_nodes, undo_node);
-
+
undo_node = next_node;
}
}
-
+
/* create new undo node */
undo_node = MEM_callocN(sizeof(bGPundonode), "gpencil undo node");
- undo_node->gpd = gpencil_data_duplicate(gpd);
-
+ undo_node->gpd = gpencil_data_duplicate(gpd, true);
+
cur_node = undo_node;
-
+
BLI_addtail(&undo_nodes, undo_node);
}
void gpencil_undo_finish(void)
{
bGPundonode *undo_node = undo_nodes.first;
-
+
while (undo_node) {
+ /* HACK: animdata wasn't duplicated, so it shouldn't be freed here,
+ * or else the real copy will segfault when accessed
+ */
+ undo_node->gpd->adt = NULL;
+
BKE_gpencil_free(undo_node->gpd);
MEM_freeN(undo_node->gpd);
-
+
undo_node = undo_node->next;
}
-
+
BLI_freelistN(&undo_nodes);
-
+
cur_node = NULL;
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
new file mode 100644
index 00000000000..289cbc568d2
--- /dev/null
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -0,0 +1,211 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014, Blender Foundation
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/gpencil/gpencil_utils.c
+ * \ingroup edgpencil
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_gpencil_types.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 "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_gpencil.h"
+#include "BKE_library.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+#include "BKE_screen.h"
+
+#include "UI_interface.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "UI_view2d.h"
+
+#include "ED_gpencil.h"
+#include "ED_view3d.h"
+
+#include "gpencil_intern.h"
+
+/* ******************************************************** */
+
+/* Check if part of stroke occurs within last segment drawn by eraser */
+bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]),
+ int rad, int x0, int y0, int x1, int y1)
+{
+ /* simple within-radius check for now */
+ const float mval_fl[2] = {mval[0], mval[1]};
+ const float screen_co_a[2] = {x0, y0};
+ const float screen_co_b[2] = {x1, y1};
+
+ if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) {
+ return true;
+ }
+
+ /* not inside */
+ return false;
+}
+
+/* ******************************************************** */
+
+/* Check whether given stroke can be edited given the supplied context */
+// XXX: do we need additional flags for screenspace vs dataspace?
+bool ED_gpencil_stroke_can_use_direct(const ScrArea *sa, const bGPDstroke *gps)
+{
+ /* sanity check */
+ if (ELEM(NULL, sa, gps))
+ return false;
+
+ /* filter stroke types by flags + spacetype */
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ /* 3D strokes - only in 3D view */
+ return (sa->spacetype == SPACE_VIEW3D);
+ }
+ else if (gps->flag & GP_STROKE_2DIMAGE) {
+ /* Special "image" strokes - only in Image Editor */
+ return (sa->spacetype == SPACE_IMAGE);
+ }
+ else if (gps->flag & GP_STROKE_2DSPACE) {
+ /* 2D strokes (dataspace) - for any 2D view (i.e. everything other than 3D view) */
+ return (sa->spacetype != SPACE_VIEW3D);
+ }
+ else {
+ /* view aligned - anything goes */
+ return true;
+ }
+}
+
+/* Check whether given stroke can be edited in the current context */
+bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ return ED_gpencil_stroke_can_use_direct(sa, gps);
+}
+
+/* ******************************************************** */
+
+/* Init handling for space-conversion function (from passed-in parameters) */
+void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+
+ /* zero out the storage (just in case) */
+ memset(r_gsc, 0, sizeof(GP_SpaceConversion));
+ unit_m4(r_gsc->mat);
+
+ /* store settings */
+ r_gsc->sa = sa;
+ r_gsc->ar = ar;
+ r_gsc->v2d = &ar->v2d;
+
+ /* init region-specific stuff */
+ if (sa->spacetype == SPACE_VIEW3D) {
+ wmWindow *win = CTX_wm_window(C);
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = (View3D *)CTX_wm_space_data(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* init 3d depth buffers */
+ view3d_operator_needs_opengl(C);
+
+ view3d_region_operator_needs_opengl(win, ar);
+ ED_view3d_autodist_init(scene, ar, v3d, 0);
+
+ /* for camera view set the subrect */
+ if (rv3d->persp == RV3D_CAMOB) {
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &r_gsc->subrect_data, true); /* no shift */
+ r_gsc->subrect = &r_gsc->subrect_data;
+ }
+ }
+}
+
+
+/* Convert Grease Pencil points to screen-space values
+ * WARNING: This assumes that the caller has already checked whether the stroke in question can be drawn
+ */
+void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
+ int *r_x, int *r_y)
+{
+ ARegion *ar = gsc->ar;
+ View2D *v2d = gsc->v2d;
+ rctf *subrect = gsc->subrect;
+ int xyval[2];
+
+ /* sanity checks */
+ BLI_assert(!(gps->flag & GP_STROKE_3DSPACE) || (gsc->sa->spacetype == SPACE_VIEW3D));
+ BLI_assert(!(gps->flag & GP_STROKE_2DSPACE) || (gsc->sa->spacetype != SPACE_VIEW3D));
+
+
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ *r_x = xyval[0];
+ *r_y = xyval[1];
+ }
+ else {
+ *r_x = V2D_IS_CLIPPED;
+ *r_y = V2D_IS_CLIPPED;
+ }
+ }
+ else if (gps->flag & GP_STROKE_2DSPACE) {
+ float vec[3] = {pt->x, pt->y, 0.0f};
+ mul_m4_v3(gsc->mat, vec);
+ UI_view2d_view_to_region_clip(v2d, vec[0], vec[1], r_x, r_y);
+ }
+ else {
+ if (subrect == NULL) {
+ /* normal 3D view (or view space) */
+ *r_x = (int)(pt->x / 100 * ar->winx);
+ *r_y = (int)(pt->y / 100 * ar->winy);
+ }
+ else {
+ /* camera view, use subrect */
+ *r_x = (int)((pt->x / 100) * BLI_rctf_size_x(subrect)) + subrect->xmin;
+ *r_y = (int)((pt->y / 100) * BLI_rctf_size_y(subrect)) + subrect->ymin;
+ }
+ }
+}
+
+/* ******************************************************** */
diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h
index cd26bb22ada..3b7d7bac44f 100644
--- a/source/blender/editors/include/BIF_gl.h
+++ b/source/blender/editors/include/BIF_gl.h
@@ -35,17 +35,6 @@
#include "GPU_glew.h"
-#ifdef __APPLE__
-
-/* hacking pointsize and linewidth */
-# define glPointSize(f) glPointSize(U.pixelsize * (f))
-# define glLineWidth(f) glLineWidth(U.pixelsize * (f))
-#else
- /* avoid include mismatch by referencing 'U' from both */
-# define glPointSize(f) glPointSize(((void)U.pixelsize, (f)))
-# define glLineWidth(f) glLineWidth(((void)U.pixelsize, (f)))
-#endif
-
/*
* these should be phased out. cpack should be replaced in
* code with calls to glColor3ub. - zr
@@ -58,23 +47,33 @@
* */
void cpack(unsigned int x);
-
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
# define glMultMatrixf(x) \
glMultMatrixf(_Generic((x), \
float *: (float *)(x), \
+ float [16]: (float *)(x), \
float (*)[4]: (float *)(x), \
+ float [4][4]: (float *)(x), \
const float *: (float *)(x), \
- const float (*)[4]: (float *)(x)) \
+ const float [16]: (float *)(x), \
+ const float (*)[4]: (float *)(x), \
+ const float [4][4]: (float *)(x)) \
)
# define glLoadMatrixf(x) \
glLoadMatrixf(_Generic((x), \
float *: (float *)(x), \
- float (*)[4]: (float *)(x)) \
+ float [16]: (float *)(x), \
+ float (*)[4]: (float *)(x), \
+ float [4][4]: (float *)(x)) \
)
+/* hacking pointsize and linewidth */
+#define glPointSize(f) glPointSize(U.pixelsize * _Generic((f), double: (float)(f), default: (f)))
+#define glLineWidth(f) glLineWidth(U.pixelsize * _Generic((f), double: (float)(f), default: (f)))
#else
# define glMultMatrixf(x) glMultMatrixf((float *)(x))
# define glLoadMatrixf(x) glLoadMatrixf((float *)(x))
+#define glPointSize(f) glPointSize(U.pixelsize * (f))
+#define glLineWidth(f) glLineWidth(U.pixelsize * (f))
#endif
#define GLA_PIXEL_OFS 0.375f
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 4272fd49f7f..4dc39681ed2 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -90,13 +90,13 @@ void glutil_draw_lined_arc(float start, float angle, float radius, int nsegments
void glutil_draw_filled_arc(float start, float angle, float radius, int nsegments);
/**
- * Routines an integer value as obtained by glGetIntegerv.
+ * Returns an integer value as obtained by glGetIntegerv.
* The param must cause only one value to be gotten from GL.
*/
int glaGetOneInteger(int param);
/**
- * Routines a float value as obtained by glGetIntegerv.
+ * Returns a float value as obtained by glGetFloatv.
* The param must cause only one value to be gotten from GL.
*/
float glaGetOneFloat(int param);
@@ -164,8 +164,8 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
/** Define a 2D area (viewport, scissor, matrices) for OpenGL rendering.
*
- * glwDefine2DArea and glaBegin2DDraw set up an OpenGL state appropriate
- * for drawing using both vertice (Vertex, etc) and raster (RasterPos, Rect)
+ * glaDefine2DArea and glaBegin2DDraw set up an OpenGL state appropriate
+ * for drawing using both vertex (Vertex, etc) and raster (RasterPos, Rect)
* commands. All coordinates should be at integer positions. There is little
* to no reason to use glVertex2f etc. functions during 2D rendering, and
* thus no reason to +-0.5 the coordinates or perform other silly
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 956ec308daa..50581429700 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -159,6 +159,7 @@ typedef enum eAnim_ChannelType {
ANIMTYPE_DSLAT,
ANIMTYPE_DSLINESTYLE,
ANIMTYPE_DSSPK,
+ ANIMTYPE_DSGPENCIL,
ANIMTYPE_SHAPEKEY,
@@ -457,7 +458,7 @@ void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level);
/* Draw the given channel */
void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc);
/* Draw the widgets for the given channel */
-void ANIM_channel_draw_widgets(struct bContext *C, bAnimContext *ac, bAnimListElem *ale, struct uiBlock *block, float yminc, float ymaxc, size_t channel_index);
+void ANIM_channel_draw_widgets(const struct bContext *C, bAnimContext *ac, bAnimListElem *ale, struct uiBlock *block, float yminc, float ymaxc, size_t channel_index);
/* ------------------------ Editing API -------------------------- */
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index 58e64f30b05..27e9cad4fd5 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -90,7 +90,9 @@ bool ED_curve_active_center(struct Curve *cu, float center[3]);
bool mouse_font(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
+#if 0
/* debug only */
void printknots(struct Object *obedit);
+#endif
#endif /* __ED_CURVE_H__ */
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index f2a6ce0b129..b81ea55cca8 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -108,5 +108,40 @@ int ED_file_extension_icon(const char *relname);
void ED_file_read_bookmarks(void);
+void ED_file_change_dir(struct bContext *C, const bool checkdir);
+
+/* File menu stuff */
+
+typedef enum FSMenuCategory {
+ FS_CATEGORY_SYSTEM,
+ FS_CATEGORY_SYSTEM_BOOKMARKS,
+ FS_CATEGORY_BOOKMARKS,
+ FS_CATEGORY_RECENT
+} FSMenuCategory;
+
+typedef enum FSMenuInsert {
+ FS_INSERT_SORTED = (1 << 0),
+ FS_INSERT_SAVE = (1 << 1),
+ FS_INSERT_FIRST = (1 << 2), /* moves the item to the front of the list when its not already there */
+ FS_INSERT_LAST = (1 << 3), /* just append to preseve delivered order */
+} FSMenuInsert;
+
+struct FSMenu;
+struct FSMenuEntry;
+
+struct FSMenu *ED_fsmenu_get(void);
+struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category);
+void ED_fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, struct FSMenuEntry *fsm_head);
+
+int ED_fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category);
+
+struct FSMenuEntry *ED_fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index);
+
+char *ED_fsmenu_entry_get_path(struct FSMenuEntry *fsentry);
+void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *path);
+
+char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry);
+void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name);
+
#endif /* __ED_FILESELECT_H__ */
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 05fb76b7aea..c4f08ca4775 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -30,6 +30,7 @@
#ifndef __ED_GPENCIL_H__
#define __ED_GPENCIL_H__
+struct ID;
struct ListBase;
struct bContext;
struct bScreen;
@@ -38,11 +39,12 @@ struct ARegion;
struct View3D;
struct SpaceNode;
struct SpaceSeq;
+struct Object;
struct bGPdata;
struct bGPDlayer;
struct bGPDframe;
+struct bGPDstroke;
struct PointerRNA;
-struct Panel;
struct ImBuf;
struct wmKeyConfig;
@@ -65,14 +67,37 @@ typedef struct tGPspoint {
/* ----------- Grease Pencil Tools/Context ------------- */
+/* Context-dependent */
struct bGPdata **ED_gpencil_data_get_pointers(const struct bContext *C, struct PointerRNA *ptr);
struct bGPdata *ED_gpencil_data_get_active(const struct bContext *C);
+
+/* Context independent (i.e. each required part is passed in instead) */
+struct bGPdata **ED_gpencil_data_get_pointers_direct(struct ID *screen_id, struct Scene *scene,
+ struct ScrArea *sa, struct Object *ob,
+ struct PointerRNA *ptr);
+struct bGPdata *ED_gpencil_data_get_active_direct(struct ID *screen_id, struct Scene *scene,
+ struct ScrArea *sa, struct Object *ob);
+
+/* 3D View */
struct bGPdata *ED_gpencil_data_get_active_v3d(struct Scene *scene, struct View3D *v3d);
+/* ----------- Stroke Editing Utilities ---------------- */
+
+bool ED_gpencil_stroke_can_use_direct(const struct ScrArea *sa, const struct bGPDstroke *gps);
+bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke *gps);
+
/* ----------- Grease Pencil Operators ----------------- */
void ED_keymap_gpencil(struct wmKeyConfig *keyconf);
+
void ED_operatortypes_gpencil(void);
+void ED_operatormacros_gpencil(void);
+
+/* ------------- Copy-Paste Buffers -------------------- */
+
+/* Strokes copybuf */
+void ED_gpencil_strokes_copybuf_free(void);
+
/* ------------ Grease-Pencil Drawing API ------------------ */
/* drawgpencil.c */
@@ -80,10 +105,8 @@ void ED_operatortypes_gpencil(void);
void ED_gpencil_draw_2dimage(const struct bContext *C);
void ED_gpencil_draw_view2d(const struct bContext *C, bool onlyv2d);
void ED_gpencil_draw_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, bool only3d);
-void ED_gpencil_draw_ex(struct bGPdata *gpd, int winx, int winy, const int cfra);
-
-void ED_gpencil_panel_standard_header(const struct bContext *C, struct Panel *pa);
-void ED_gpencil_panel_standard(const struct bContext *C, struct Panel *pa);
+void ED_gpencil_draw_ex(struct Scene *scene, struct bGPdata *gpd, int winx, int winy,
+ const int cfra, const char spacetype);
/* ----------- Grease-Pencil AnimEdit API ------------------ */
bool ED_gplayer_frames_looper(struct bGPDlayer *gpl, struct Scene *scene,
@@ -99,6 +122,8 @@ void ED_gpencil_select_frame(struct bGPDlayer *gpl, int selx, short select_mode
bool ED_gplayer_frames_delete(struct bGPDlayer *gpl);
void ED_gplayer_frames_duplicate(struct bGPDlayer *gpl);
+void ED_gplayer_frames_keytype_set(struct bGPDlayer *gpl, short type);
+
void ED_gplayer_snap_frames(struct bGPDlayer *gpl, struct Scene *scene, short mode);
#if 0
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index a9995de068e..704876e1261 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -35,6 +35,7 @@ struct Main;
struct bContext;
struct Image;
struct ImageUser;
+struct ImBuf;
struct ToolSettings;
struct uiBlock;
struct wmWindowManager;
@@ -58,6 +59,8 @@ void ED_space_image_get_aspect(struct SpaceImage *sima, float *aspx, float *aspy
void ED_space_image_get_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy);
void ED_space_image_get_uv_aspect(struct SpaceImage *sima, float *aspx, float *aspy);
+void ED_space_image_scopes_update(const struct bContext *C, struct SpaceImage *sima, struct ImBuf *ibuf, bool use_view_settings);
+
void ED_space_image_paint_update(struct wmWindowManager *wm, struct ToolSettings *settings);
void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSettings *settings);
@@ -79,5 +82,7 @@ int ED_space_image_maskedit_mask_poll(struct bContext *C);
void ED_image_draw_info(struct Scene *scene, struct ARegion *ar, bool color_manage, bool use_default_view, int channels, int x, int y,
const unsigned char cp[4], const float fp[4], const float linearcol[4], int *zp, float *zpf);
+bool ED_space_image_show_cache(struct SpaceImage *sima);
+
#endif /* __ED_IMAGE_H__ */
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index 58a262e150a..0359153317b 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -120,8 +120,9 @@ void draw_object_channel(struct View2D *v2d, struct bDopeSheet *ads, struct Obje
void draw_scene_channel(struct View2D *v2d, struct bDopeSheet *ads, struct Scene *sce, float ypos);
/* DopeSheet Summary */
void draw_summary_channel(struct View2D *v2d, struct bAnimContext *ac, float ypos);
-/* Grease Pencil Layer */
-// XXX not restored
+/* Grease Pencil datablock summary */
+void draw_gpencil_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPdata *gpd, float ypos);
+/* Grease Pencil Layer */
void draw_gpl_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPDlayer *gpl, float ypos);
/* Mask Layer */
void draw_masklay_channel(struct View2D *v2d, struct bDopeSheet *ads, struct MaskLayer *masklay, float ypos);
@@ -139,11 +140,11 @@ void ob_to_keylist(struct bDopeSheet *ads, struct Object *ob, struct DLRBT_Tree
void scene_to_keylist(struct bDopeSheet *ads, struct Scene *sce, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks);
/* DopeSheet Summary */
void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct DLRBT_Tree *blocks);
+/* Grease Pencil datablock summary */
+void gpencil_to_keylist(struct bDopeSheet *ads, struct bGPdata *gpd, struct DLRBT_Tree *keys);
/* Grease Pencil Layer */
-// XXX not restored
void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys);
/* Mask */
-// XXX not restored
void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskLayer *masklay, struct DLRBT_Tree *keys);
/* ActKeyColumn API ---------------- */
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index c8365689803..adf82acb399 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -58,6 +58,7 @@ typedef enum eEditKeyframes_Validate {
BEZT_OK_VALUERANGE,
BEZT_OK_REGION,
BEZT_OK_REGION_LASSO,
+ BEZT_OK_REGION_CIRCLE,
} eEditKeyframes_Validate;
/* ------------ */
@@ -107,6 +108,14 @@ struct KeyframeEdit_LassoData {
int mcords_tot;
};
+/* use with BEZT_OK_REGION_CIRCLE */
+struct KeyframeEdit_CircleData {
+ const rctf *rectf_scaled;
+ const rctf *rectf_view;
+ float mval[2];
+ float radius_squared;
+};
+
/* ************************************************ */
/* Non-Destuctive Editing API (keyframes_edit.c) */
@@ -233,7 +242,7 @@ short bezt_selmap_flush(KeyframeEditData *ked, struct BezTriple *bezt);
/* ----------- BezTriple Callback (Assorted Utilities) ---------- */
-/* used to calculate the the average location of all relevant BezTriples by summing their locations */
+/* used to calculate the average location of all relevant BezTriples by summing their locations */
short bezt_calc_average(KeyframeEditData *ked, struct BezTriple *bezt);
/* used to extract a set of cfra-elems from the keyframes */
@@ -261,7 +270,7 @@ void sample_fcurve(struct FCurve *fcu);
void free_anim_copybuf(void);
short copy_animedit_keys(struct bAnimContext *ac, ListBase *anim_data);
short paste_animedit_keys(struct bAnimContext *ac, ListBase *anim_data,
- const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode);
+ const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip);
/* ************************************************ */
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 5c7b3c531be..e5b5e79875d 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -293,7 +293,7 @@ bool ANIM_paste_driver(struct ReportList *reports, struct ID *id, const char rna
(U.autokey_flag & AUTOKEY_FLAG_##flag))
/* auto-keyframing feature - checks for whether anything should be done for the current frame */
-int autokeyframe_cfra_can_key(struct Scene *scene, struct ID *id);
+bool autokeyframe_cfra_can_key(struct Scene *scene, struct ID *id);
/* ************ Keyframe Checking ******************** */
diff --git a/source/blender/editors/include/ED_markers.h b/source/blender/editors/include/ED_markers.h
index 76d36623b60..5eaf459a4e1 100644
--- a/source/blender/editors/include/ED_markers.h
+++ b/source/blender/editors/include/ED_markers.h
@@ -43,10 +43,11 @@ struct TimeMarker;
/* flags for drawing markers */
enum {
DRAW_MARKERS_LINES = (1 << 0),
- DRAW_MARKERS_LOCAL = (1 << 1)
+ DRAW_MARKERS_LOCAL = (1 << 1),
+ DRAW_MARKERS_MARGIN = (1 << 2),
};
-void draw_markers_time(const struct bContext *C, int flag);
+void ED_markers_draw(const struct bContext *C, int flag);
/* Backend API ----------------------------- */
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 6a562da0a0e..ccf97221112 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -101,8 +101,8 @@ struct DerivedMesh *EDBM_mesh_deform_dm_get(struct BMEditMesh *em);
* verts select/deselect edges and faces, if in edge select mode,
* edges select/deselect faces and vertices, and in face select mode faces select/deselect
* edges and vertices.*/
-void EDBM_select_more(struct BMEditMesh *em);
-void EDBM_select_less(struct BMEditMesh *em);
+void EDBM_select_more(struct BMEditMesh *em, const bool use_face_step);
+void EDBM_select_less(struct BMEditMesh *em, const bool use_face_step);
void EDBM_selectmode_flush_ex(struct BMEditMesh *em, const short selectmode);
void EDBM_selectmode_flush(struct BMEditMesh *em);
@@ -220,14 +220,8 @@ void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store);
#define WEIGHT_SUBTRACT 3
bool ED_vgroup_sync_from_pose(struct Object *ob);
-struct bDeformGroup *ED_vgroup_add(struct Object *ob);
-struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, const char *name);
-void ED_vgroup_delete(struct Object *ob, struct bDeformGroup *defgroup);
-void ED_vgroup_clear(struct Object *ob);
void ED_vgroup_select_by_name(struct Object *ob, const char *name);
-bool ED_vgroup_data_create(struct ID *id);
void ED_vgroup_data_clamp_range(struct ID *id, const int total);
-bool ED_vgroup_array_get(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
bool ED_vgroup_array_copy(struct Object *ob, struct Object *ob_from);
bool ED_vgroup_parray_alloc(struct ID *id, struct MDeformVert ***dvert_arr, int *dvert_tot,
const bool use_vert_sel);
@@ -244,8 +238,6 @@ void ED_vgroup_mirror(struct Object *ob,
const bool all_vgroups, const bool use_topology,
int *r_totmirr, int *r_totfail);
-bool ED_vgroup_object_is_edit_mode(struct Object *ob);
-
void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum, float weight, int assignmode);
void ED_vgroup_vert_remove(struct Object *ob, struct bDeformGroup *dg, int vertnum);
float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int vertnum);
@@ -264,9 +256,10 @@ void ED_mesh_faces_remove(struct Mesh *mesh, struct ReportList *reports, int cou
void ED_mesh_edges_remove(struct Mesh *mesh, struct ReportList *reports, int count);
void ED_mesh_vertices_remove(struct Mesh *mesh, struct ReportList *reports, int count);
-void ED_mesh_calc_tessface(struct Mesh *mesh);
+void ED_mesh_calc_tessface(struct Mesh *mesh, bool free_mpoly);
void ED_mesh_update(struct Mesh *mesh, struct bContext *C, int calc_edges, int calc_tessface);
+void ED_mesh_uv_texture_ensure(struct Mesh *me, const char *name);
int ED_mesh_uv_texture_add(struct Mesh *me, const char *name, const bool active_set);
bool ED_mesh_uv_texture_remove_index(struct Mesh *me, const int n);
bool ED_mesh_uv_texture_remove_active(struct Mesh *me);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 39586039e8f..295bb752a08 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -138,12 +138,14 @@ void ED_object_editmode_exit(struct bContext *C, int flag);
void ED_object_editmode_enter(struct bContext *C, int flag);
bool ED_object_editmode_load(struct Object *obedit);
+bool ED_object_editmode_calc_active_center(struct Object *obedit, const bool select_only, float r_center[3]);
+
void ED_object_location_from_view(struct bContext *C, float loc[3]);
void ED_object_rotation_from_view(struct bContext *C, float rot[3], const char align_axis);
void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]);
-float ED_object_new_primitive_matrix(struct bContext *C, struct Object *editob,
- const float loc[3], const float rot[3], float primmat[4][4],
- bool apply_diameter);
+float ED_object_new_primitive_matrix(
+ struct bContext *C, struct Object *editob,
+ const float loc[3], const float rot[3], float primmat[4][4]);
void ED_object_add_unit_props(struct wmOperatorType *ot);
void ED_object_add_generic_props(struct wmOperatorType *ot, bool do_editmode);
@@ -209,12 +211,6 @@ bool ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v)
/* object_select.c */
void ED_object_select_linked_by_id(struct bContext *C, struct ID *id);
-
-bool *ED_vgroup_subset_from_select_type(struct Object *ob, enum eVGroupSelect subset_type,
- int *r_vgroup_tot, int *r_subset_count);
-void ED_vgroup_subset_to_index_array(const bool *vgroup_validmap, const int vgroup_tot,
- int *r_vgroup_subset_map);
-
struct EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(
const struct bContext *C,
struct PointerRNA *ptr,
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h
index ab1dbabe793..293621c3d19 100644
--- a/source/blender/editors/include/ED_render.h
+++ b/source/blender/editors/include/ED_render.h
@@ -40,6 +40,7 @@ struct ScrArea;
struct RegionView3D;
struct RenderEngine;
struct View3D;
+struct wmWindowManager;
/* render_ops.c */
@@ -52,8 +53,9 @@ void ED_render_engine_changed(struct Main *bmain);
void ED_render_engine_area_exit(struct ScrArea *sa);
void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated);
-void ED_viewport_render_kill_jobs(const struct bContext *C, bool free_database);
+void ED_viewport_render_kill_jobs(struct wmWindowManager *wm, struct Main *bmain, bool free_database);
struct Scene *ED_render_job_get_scene(const struct bContext *C);
+struct Scene *ED_render_job_get_current_scene(const struct bContext *C);
/* Render the preview
*
@@ -71,8 +73,9 @@ void ED_preview_init_dbase(void);
void ED_preview_free_dbase(void);
void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, struct ID *parent, struct MTex *slot, int sizex, int sizey, int method);
+void ED_preview_icon_render(struct Scene *scene, struct ID *id, unsigned int *rect, int sizex, int sizey);
void ED_preview_icon_job(const struct bContext *C, void *owner, struct ID *id, unsigned int *rect, int sizex, int sizey);
-void ED_preview_kill_jobs(const struct bContext *C);
+void ED_preview_kill_jobs(struct wmWindowManager *wm, struct Main *bmain);
void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *slot, rcti *rect);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index ed2465647da..8c33395cc49 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -107,6 +107,7 @@ void ED_screen_set_subwinactive(struct bContext *C, struct wmEvent *event);
void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
void ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable);
void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh);
+void ED_screen_restore_temp_type(struct bContext *C, ScrArea *sa);
ScrArea *ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
void ED_screen_full_prevspace(struct bContext *C, ScrArea *sa);
void ED_screen_full_restore(struct bContext *C, ScrArea *sa);
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h
index 85ff9b5d246..d3b1a824104 100644
--- a/source/blender/editors/include/ED_sculpt.h
+++ b/source/blender/editors/include/ED_sculpt.h
@@ -34,6 +34,7 @@ struct ARegion;
struct bContext;
struct Object;
struct RegionView3D;
+struct Scene;
struct ViewContext;
struct rcti;
@@ -41,8 +42,6 @@ struct rcti;
void ED_operatortypes_sculpt(void);
void ED_sculpt_redraw_planes_get(float planes[4][4], struct ARegion *ar,
struct RegionView3D *rv3d, struct Object *ob);
-void ED_sculpt_stroke_get_average(struct Object *ob, float stroke[3]);
-bool ED_sculpt_minmax(struct bContext *C, float min[3], float max[3]);
int ED_sculpt_mask_box_select(struct bContext *C, struct ViewContext *vc, const struct rcti *rect, bool select, bool extend);
#endif /* __ED_SCULPT_H__ */
diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h
index 4e9d67df61e..94885c2abe0 100644
--- a/source/blender/editors/include/ED_sequencer.h
+++ b/source/blender/editors/include/ED_sequencer.h
@@ -27,6 +27,7 @@
#ifndef __ED_SEQUENCER_H__
#define __ED_SEQUENCER_H__
+struct bContext;
struct Scene;
struct Sequence;
struct SpaceSeq;
@@ -39,7 +40,12 @@ bool ED_space_sequencer_check_show_maskedit(struct SpaceSeq *sseq, struct Scene
int ED_space_sequencer_maskedit_poll(struct bContext *C);
bool ED_space_sequencer_check_show_imbuf(struct SpaceSeq *sseq);
+bool ED_space_sequencer_check_show_strip(struct SpaceSeq *sseq);
void ED_operatormacros_sequencer(void);
+Sequence *ED_sequencer_special_preview_get(void);
+void ED_sequencer_special_preview_set(struct bContext *C, const int mval[2]);
+void ED_sequencer_special_preview_clear(void);
+
#endif /* __ED_SEQUENCER_H__ */
diff --git a/source/blender/editors/include/ED_text.h b/source/blender/editors/include/ED_text.h
index 9a36cb3d6ab..5df7d9cfaef 100644
--- a/source/blender/editors/include/ED_text.h
+++ b/source/blender/editors/include/ED_text.h
@@ -31,8 +31,11 @@
#define __ED_TEXT_H__
struct bContext;
+struct SpaceText;
+struct ARegion;
void ED_text_undo_step(struct bContext *C, int step);
+bool ED_text_region_location_from_cursor(struct SpaceText *st, struct ARegion *ar, const int cursor_co[2], int r_pixel_co[2]);
#endif /* __ED_TEXT_H__ */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index daa6864b5aa..a3b4981dad8 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -73,6 +73,7 @@ enum TfmMode {
TFM_BONE_ENVELOPE,
TFM_CURVE_SHRINKFATTEN,
TFM_MASK_SHRINKFATTEN,
+ TFM_GPENCIL_SHRINKFATTEN,
TFM_BONE_ROLL,
TFM_TIME_TRANSLATE,
TFM_TIME_SLIDE,
@@ -99,6 +100,7 @@ enum TfmMode {
#define CTX_MOVIECLIP (1 << 6)
#define CTX_MASK (1 << 7)
#define CTX_PAINT_CURVE (1 << 8)
+#define CTX_GPENCIL_STROKES (1 << 9)
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
@@ -146,6 +148,7 @@ int BIF_countTransformOrientation(const struct bContext *C);
#define P_CORRECT_UV (1 << 8)
#define P_NO_DEFAULTS (1 << 10)
#define P_NO_TEXSPACE (1 << 11)
+#define P_GPENCIL_EDIT (1 << 12)
void Transform_Properties(struct wmOperatorType *ot, int flags);
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 4b82fa40c6a..3e8f234e979 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -31,6 +31,7 @@
#define __ED_UVEDIT_H__
struct ARegionType;
+struct BMesh;
struct BMEditMesh;
struct BMFace;
struct BMLoop;
@@ -52,6 +53,7 @@ void ED_keymap_uvedit(struct wmKeyConfig *keyconf);
void ED_uvedit_assign_image(struct Main *bmain, struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma);
bool ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float min[2], float max[2]);
+void ED_uvedit_select_all(struct BMesh *bm);
bool ED_object_get_active_image(struct Object *ob, int mat_nr,
struct Image **r_ima, struct ImageUser **r_iuser, struct bNode **r_node, struct bNodeTree **r_ntree);
@@ -92,19 +94,24 @@ void uvedit_uv_select_disable(struct BMEditMesh *em, struct Scene *scene, struct
bool ED_uvedit_nearest_uv(struct Scene *scene, struct Object *obedit, struct Image *ima,
const float co[2], float r_uv[2]);
+void ED_uvedit_get_aspect(struct Scene *scene, struct Object *ob, struct BMesh *em, float *aspx, float *aspy);
+
/* uvedit_unwrap_ops.c */
void ED_uvedit_live_unwrap_begin(struct Scene *scene, struct Object *obedit);
void ED_uvedit_live_unwrap_re_solve(void);
void ED_uvedit_live_unwrap_end(short cancel);
void ED_uvedit_live_unwrap(struct Scene *scene, struct Object *obedit);
+void ED_uvedit_pack_islands(struct Scene *scene, struct Object *ob, struct BMesh *bm, bool selected, bool correct_aspect, bool do_rotate);
+void ED_uvedit_unwrap_cube_project(struct Object *ob, struct BMesh *bm, float cube_size, bool use_select);
/* single call up unwrap using scene settings, used for edge tag unwrapping */
void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel);
+
/* uvedit_draw.c */
-void draw_image_cursor(struct ARegion *ar, const float cursor[2]);
-void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact);
+void ED_image_draw_cursor(struct ARegion *ar, const float cursor[2]);
+void ED_uvedit_draw_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit, struct Object *obact);
/* uvedit_buttons.c */
void ED_uvedit_buttons_register(struct ARegionType *art);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index bd4f37cfb1e..5fc5738c88f 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -61,6 +61,10 @@ struct rcti;
struct wmOperator;
struct wmOperatorType;
struct wmWindow;
+struct GPUFX;
+struct GPUOffScreen;
+struct GPUFXSettings;
+enum eGPUFXFlags;
/* for derivedmesh drawing callbacks, for view3d_select, .... */
typedef struct ViewContext {
@@ -237,6 +241,7 @@ void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar,
bool ED_view3d_calc_render_border(struct Scene *scene, struct View3D *v3d,
struct ARegion *ar, struct rcti *rect);
+void ED_view3d_clipping_calc_from_boundbox(float clip[6][4], const struct BoundBox *clipbb, const bool is_flip);
void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect);
void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[4][4]);
bool ED_view3d_clipping_test(struct RegionView3D *rv3d, const float co[3], const bool is_local);
@@ -271,7 +276,8 @@ bool ED_view3d_autodist_depth(struct ARegion *ar, const int mval[2], int margin,
bool ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], const int mval_end[2], int margin, float *depth);
/* select */
-#define MAXPICKBUF 10000
+#define MAXPICKELEMS 2500
+#define MAXPICKBUF (4 * MAXPICKELEMS)
short view3d_opengl_select(struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const struct rcti *input, bool do_nearest);
/* view3d_select.c */
@@ -303,14 +309,16 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active);
bool ED_view3d_context_activate(struct bContext *C);
void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d);
-void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
- int winx, int winy, float viewmat[4][4], float winmat[4][4], bool do_bgpic, bool do_sky);
+void ED_view3d_draw_offscreen(
+ struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4],
+ float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp,
+ struct GPUOffScreen *ofs,
+ struct GPUFX *fx, struct GPUFXSettings *fx_settings);
struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag,
bool draw_background, int alpha_mode, char err_out[256]);
struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype,
- bool use_solid_tex, bool draw_background, int alpha_mode, char err_out[256]);
-void ED_view3d_offscreen_sky_color_get(struct Scene *scene, float sky_color[3]);
+ bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, char err_out[256]);
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip);
@@ -318,6 +326,7 @@ void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct AR
bool ED_view3d_quat_from_axis_view(const char view, float quat[4]);
char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon);
char ED_view3d_lock_view_from_index(int index);
+char ED_view3d_axis_view_opposite(char view);
bool ED_view3d_lock(struct RegionView3D *rv3d);
uint64_t ED_view3d_datamask(struct Scene *scene, struct View3D *v3d);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index 618fa44349e..bfb7a3420c9 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -54,7 +54,7 @@ DEF_ICON(DOT)
DEF_ICON(COLLAPSEMENU)
DEF_ICON(X)
#ifndef DEF_ICON_BLANK_SKIP
- DEF_ICON(BLANK005)
+ DEF_ICON(BLANK005) /* XXX 'DOWNARROW' icon! */
#endif
DEF_ICON(GO_LEFT)
DEF_ICON(PLUG)
@@ -461,9 +461,9 @@ DEF_ICON(FORCE_SMOKEFLOW)
DEF_ICON(BLANK685)
/* EMPTY */
- DEF_ICON(BLANK690)
- DEF_ICON(BLANK691)
- DEF_ICON(BLANK692)
+ DEF_ICON(BLANK690) /* XXX 'Temperature' icon! */
+ DEF_ICON(BLANK691) /* XXX 'Temperature' icon! */
+ DEF_ICON(BLANK692) /* XXX 'Gear' icon! */
DEF_ICON(BLANK693)
DEF_ICON(BLANK694)
DEF_ICON(BLANK695)
@@ -589,9 +589,9 @@ DEF_ICON(MOD_WARP)
DEF_ICON(MOD_SKIN)
DEF_ICON(MOD_TRIANGULATE)
DEF_ICON(MOD_WIREFRAME)
+DEF_ICON(MOD_DATA_TRANSFER)
+DEF_ICON(MOD_NORMALEDIT)
#ifndef DEF_ICON_BLANK_SKIP
- DEF_ICON(BLANK167)
- DEF_ICON(BLANK168)
DEF_ICON(BLANK169)
DEF_ICON(BLANK170)
DEF_ICON(BLANK171)
@@ -689,7 +689,7 @@ DEF_ICON(RNDCURVE)
DEF_ICON(PROP_OFF)
DEF_ICON(PROP_ON)
DEF_ICON(PROP_CON)
-DEF_ICON(SCULPT_DYNTOPO)
+DEF_ICON(SCULPT_DYNTOPO) /* XXX Empty icon! */
DEF_ICON(PARTICLE_POINT)
DEF_ICON(PARTICLE_TIP)
DEF_ICON(PARTICLE_PATH)
@@ -876,8 +876,8 @@ DEF_ICON(FORWARD)
DEF_ICON(BLANK312)
DEF_ICON(BLANK313)
DEF_ICON(BLANK314)
- DEF_ICON(BLANK315)
#endif
+DEF_ICON(FILE_HIDDEN)
DEF_ICON(FILE_BACKUP)
DEF_ICON(DISK_DRIVE)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index bc794bf3350..b1bb48b58ed 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -98,20 +98,23 @@ typedef struct uiLayout uiLayout;
#define UI_SCREEN_MARGIN 10
/* uiBlock->dt and uiBut->dt */
-#define UI_EMBOSS 0 /* use widget style for drawing */
-#define UI_EMBOSSN 1 /* Nothing, only icon and/or text */
-#define UI_EMBOSSP 2 /* Pulldown menu style */
-#define UI_EMBOSST 3 /* Table */
-#define UI_EMBOSSR 4 /* Pie Menu */
+enum {
+ UI_EMBOSS = 0, /* use widget style for drawing */
+ UI_EMBOSS_NONE = 1, /* Nothing, only icon and/or text */
+ UI_EMBOSS_PULLDOWN = 2, /* Pulldown menu style */
+ UI_EMBOSS_RADIAL = 3, /* Pie Menu */
+};
/* uiBlock->direction */
-#define UI_DIRECTION (UI_TOP | UI_DOWN | UI_LEFT | UI_RIGHT)
-#define UI_TOP (1 << 0)
-#define UI_DOWN (1 << 1)
-#define UI_LEFT (1 << 2)
-#define UI_RIGHT (1 << 3)
-#define UI_CENTER (1 << 4)
-#define UI_SHIFT_FLIPPED (1 << 5)
+enum {
+ UI_DIR_UP = (1 << 0),
+ UI_DIR_DOWN = (1 << 1),
+ UI_DIR_LEFT = (1 << 2),
+ UI_DIR_RIGHT = (1 << 3),
+ UI_DIR_CENTER_Y = (1 << 4),
+
+ UI_DIR_ALL = (UI_DIR_UP | UI_DIR_DOWN | UI_DIR_LEFT | UI_DIR_RIGHT),
+};
#if 0
/* uiBlock->autofill (not yet used) */
@@ -121,8 +124,8 @@ typedef struct uiLayout uiLayout;
/* uiBlock->flag (controls) */
#define UI_BLOCK_LOOP (1 << 0)
-#define UI_BLOCK_REDRAW (1 << 1)
-#define UI_BLOCK_SEARCH_MENU (1 << 2)
+#define UI_BLOCK_IS_FLIP (1 << 1)
+#define UI_BLOCK_NO_FLIP (1 << 2)
#define UI_BLOCK_NUMSELECT (1 << 3)
#define UI_BLOCK_NO_WIN_CLIP (1 << 4) /* don't apply window clipping */ /* was UI_BLOCK_ENTER_OK */
#define UI_BLOCK_CLIPBOTTOM (1 << 5)
@@ -131,7 +134,7 @@ typedef struct uiLayout uiLayout;
#define UI_BLOCK_KEEP_OPEN (1 << 8)
#define UI_BLOCK_POPUP (1 << 9)
#define UI_BLOCK_OUT_1 (1 << 10)
-#define UI_BLOCK_NO_FLIP (1 << 11)
+#define UI_BLOCK_SEARCH_MENU (1 << 11)
#define UI_BLOCK_POPUP_MEMORY (1 << 12)
#define UI_BLOCK_CLIP_EVENTS (1 << 13) /* stop handling mouse events */
@@ -156,31 +159,32 @@ typedef struct uiLayout uiLayout;
/* but->flag - general state flags. */
enum {
/* warning, the first 6 flags are internal */
- UI_ICON_SUBMENU = (1 << 6),
- UI_ICON_PREVIEW = (1 << 7),
-
- UI_BUT_NODE_LINK = (1 << 8),
- UI_BUT_NODE_ACTIVE = (1 << 9),
- UI_BUT_DRAG_LOCK = (1 << 10),
- UI_BUT_DISABLED = (1 << 11),
- UI_BUT_COLOR_LOCK = (1 << 12),
- UI_BUT_ANIMATED = (1 << 13),
- UI_BUT_ANIMATED_KEY = (1 << 14),
- UI_BUT_DRIVEN = (1 << 15),
- UI_BUT_REDALERT = (1 << 16),
- UI_BUT_INACTIVE = (1 << 17),
- UI_BUT_LAST_ACTIVE = (1 << 18),
- UI_BUT_UNDO = (1 << 19),
- UI_BUT_IMMEDIATE = (1 << 20),
- UI_BUT_NO_UTF8 = (1 << 21),
-
- UI_BUT_VEC_SIZE_LOCK = (1 << 22), /* used to flag if color hsv-circle should keep luminance */
- UI_BUT_COLOR_CUBIC = (1 << 23), /* cubic saturation for the color wheel */
- UI_BUT_LIST_ITEM = (1 << 24), /* This but is "inside" a list item (currently used to change theme colors). */
- UI_BUT_DRAG_MULTI = (1 << 25), /* edit this button as well as the active button (not just dragging) */
- UI_BUT_SCA_LINK_GREY = (1 << 26), /* used to flag if sca links shoud be grey out */
- UI_BUT_HAS_SEP_CHAR = (1 << 27), /* but->str contains UI_SEP_CHAR, used for key shortcuts */
- UI_BUT_TIP_FORCE = (1 << 28), /* force show tooltips when holding option/alt if U's USER_TOOLTIPS is off */
+ UI_BUT_ICON_SUBMENU = (1 << 6),
+ UI_BUT_ICON_PREVIEW = (1 << 7),
+
+ UI_BUT_NODE_LINK = (1 << 8),
+ UI_BUT_NODE_ACTIVE = (1 << 9),
+ UI_BUT_DRAG_LOCK = (1 << 10),
+ UI_BUT_DISABLED = (1 << 11),
+ UI_BUT_COLOR_LOCK = (1 << 12),
+ UI_BUT_ANIMATED = (1 << 13),
+ UI_BUT_ANIMATED_KEY = (1 << 14),
+ UI_BUT_DRIVEN = (1 << 15),
+ UI_BUT_REDALERT = (1 << 16),
+ UI_BUT_INACTIVE = (1 << 17),
+ UI_BUT_LAST_ACTIVE = (1 << 18),
+ UI_BUT_UNDO = (1 << 19),
+ UI_BUT_IMMEDIATE = (1 << 20),
+ UI_BUT_NO_UTF8 = (1 << 21),
+
+ UI_BUT_VEC_SIZE_LOCK = (1 << 22), /* used to flag if color hsv-circle should keep luminance */
+ UI_BUT_COLOR_CUBIC = (1 << 23), /* cubic saturation for the color wheel */
+ UI_BUT_LIST_ITEM = (1 << 24), /* This but is "inside" a list item (currently used to change theme colors). */
+ UI_BUT_DRAG_MULTI = (1 << 25), /* edit this button as well as the active button (not just dragging) */
+ UI_BUT_SCA_LINK_GREY = (1 << 26), /* used to flag if sca links shoud be grey out */
+ UI_BUT_HAS_SEP_CHAR = (1 << 27), /* but->str contains UI_SEP_CHAR, used for key shortcuts */
+ UI_BUT_TIP_FORCE = (1 << 28), /* force show tooltips when holding option/alt if U's USER_TOOLTIPS is off */
+ UI_BUT_TEXTEDIT_UPDATE = (1 << 29), /* when widget is in textedit mode, update value on each char stroke */
};
#define UI_PANEL_WIDTH 340
@@ -234,56 +238,57 @@ typedef enum {
/* assigned to but->type, OR'd with the flags above when passing args */
typedef enum {
- BUT = (1 << 9),
- ROW = (2 << 9),
- TOG = (3 << 9),
- NUM = (5 << 9),
- TEX = (6 << 9),
- TOGN = (9 << 9),
- LABEL = (10 << 9),
- MENU = (11 << 9), /* Dropdown list, actually! */
- ICONTOG = (13 << 9),
- NUMSLI = (14 << 9),
- COLOR = (15 << 9),
- SCROLL = (18 << 9),
- BLOCK = (19 << 9),
- BUTM = (20 << 9),
- SEPR = (21 << 9),
- LINK = (22 << 9),
- INLINK = (23 << 9),
- KEYEVT = (24 << 9),
- HSVCUBE = (26 << 9),
- PULLDOWN = (27 << 9), /* Menu, actually! */
- ROUNDBOX = (28 << 9),
- BUT_COLORBAND = (30 << 9),
- BUT_NORMAL = (31 << 9),
- BUT_CURVE = (32 << 9),
- ICONTOGN = (34 << 9),
- LISTBOX = (35 << 9),
- LISTROW = (36 << 9),
- TOGBUT = (37 << 9),
- OPTION = (38 << 9),
- OPTIONN = (39 << 9),
- TRACKPREVIEW = (40 << 9),
- /* buttons with value >= SEARCH_MENU don't get undo pushes */
- SEARCH_MENU = (41 << 9),
- BUT_EXTRA = (42 << 9),
- HSVCIRCLE = (43 << 9),
- HOTKEYEVT = (46 << 9),
- BUT_IMAGE = (47 << 9),
- HISTOGRAM = (48 << 9),
- WAVEFORM = (49 << 9),
- VECTORSCOPE = (50 << 9),
- PROGRESSBAR = (51 << 9),
- SEARCH_MENU_UNLINK = (52 << 9),
- NODESOCKET = (53 << 9),
- SEPRLINE = (54 << 9),
- GRIP = (55 << 9),
+ UI_BTYPE_BUT = (1 << 9),
+ UI_BTYPE_ROW = (2 << 9),
+ UI_BTYPE_TEXT = (3 << 9),
+ UI_BTYPE_MENU = (4 << 9), /* dropdown list */
+ UI_BTYPE_BUT_MENU = (5 << 9),
+ UI_BTYPE_NUM = (6 << 9), /* number button */
+ UI_BTYPE_NUM_SLIDER = (7 << 9), /* number slider */
+ UI_BTYPE_TOGGLE = (8 << 9),
+ UI_BTYPE_TOGGLE_N = (9 << 9),
+ UI_BTYPE_ICON_TOGGLE = (10 << 9),
+ UI_BTYPE_ICON_TOGGLE_N = (11 << 9),
+ UI_BTYPE_BUT_TOGGLE = (12 << 9), /* same as regular toggle, but no on/off state displayed */
+ UI_BTYPE_CHECKBOX = (13 << 9), /* similar to toggle, display a 'tick' */
+ UI_BTYPE_CHECKBOX_N = (14 << 9),
+ UI_BTYPE_COLOR = (15 << 9),
+ UI_BTYPE_SCROLL = (18 << 9),
+ UI_BTYPE_BLOCK = (19 << 9),
+ UI_BTYPE_LABEL = (20 << 9),
+ UI_BTYPE_LINK = (22 << 9),
+ UI_BTYPE_INLINK = (23 << 9),
+ UI_BTYPE_KEY_EVENT = (24 << 9),
+ UI_BTYPE_HSVCUBE = (26 << 9),
+ UI_BTYPE_PULLDOWN = (27 << 9), /* menu (often used in headers), **_MENU /w different draw-type */
+ UI_BTYPE_ROUNDBOX = (28 << 9),
+ UI_BTYPE_COLORBAND = (30 << 9),
+ UI_BTYPE_UNITVEC = (31 << 9), /* sphere widget (used to input a unit-vector, aka normal) */
+ UI_BTYPE_CURVE = (32 << 9),
+ UI_BTYPE_LISTBOX = (36 << 9),
+ UI_BTYPE_LISTROW = (37 << 9),
+ UI_BTYPE_HSVCIRCLE = (38 << 9),
+ UI_BTYPE_TRACK_PREVIEW = (40 << 9),
+
+ /* buttons with value >= UI_BTYPE_SEARCH_MENU don't get undo pushes */
+ UI_BTYPE_SEARCH_MENU = (41 << 9),
+ UI_BTYPE_EXTRA = (42 << 9),
+ UI_BTYPE_HOTKEY_EVENT = (46 << 9),
+ UI_BTYPE_IMAGE = (47 << 9), /* non-interactive image, used for splash screen */
+ UI_BTYPE_HISTOGRAM = (48 << 9),
+ UI_BTYPE_WAVEFORM = (49 << 9),
+ UI_BTYPE_VECTORSCOPE = (50 << 9),
+ UI_BTYPE_PROGRESS_BAR = (51 << 9),
+ UI_BTYPE_SEARCH_MENU_UNLINK = (52 << 9),
+ UI_BTYPE_NODE_SOCKET = (53 << 9),
+ UI_BTYPE_SEPR = (54 << 9),
+ UI_BTYPE_SEPR_LINE = (55 << 9),
+ UI_BTYPE_GRIP = (56 << 9), /* resize handle (resize uilist) */
} eButType;
#define BUTTYPE (63 << 9)
-/* gradient types, for color picker HSVCUBE etc */
+/* gradient types, for color picker UI_BTYPE_HSVCUBE etc */
#define UI_GRAD_SV 0
#define UI_GRAD_HV 1
#define UI_GRAD_HS 2
@@ -301,35 +306,40 @@ typedef enum {
* Functions to draw various shapes, taking theme settings into account.
* Used for code that draws its own UI style elements. */
-void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad);
-void uiSetRoundBox(int type);
-int uiGetRoundBox(void);
-void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad);
-void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy);
-void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float rad);
-void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown);
-void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight);
+void UI_draw_roundbox(float minx, float miny, float maxx, float maxy, float rad);
+void UI_draw_roundbox_corner_set(int type);
+int UI_draw_roundbox_corner_get(void);
+void UI_draw_roundbox_unfilled(float minx, float miny, float maxx, float maxy, float rad);
+void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx, float maxy);
+void UI_draw_roundbox_gl_mode(int mode, float minx, float miny, float maxx, float maxy, float rad);
+void UI_draw_roundbox_shade_x(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown);
+void UI_draw_roundbox_shade_y(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight);
+void UI_draw_text_underline(int pos_x, int pos_y, int len, int height);
+
+void UI_draw_safe_areas(
+ float x1, float x2, float y1, float y2,
+ const float title_aspect[2], const float action_aspect[2]);
/* state for scrolldrawing */
#define UI_SCROLL_PRESSED (1 << 0)
#define UI_SCROLL_ARROWS (1 << 1)
#define UI_SCROLL_NO_OUTLINE (1 << 2)
-void uiWidgetScrollDraw(struct uiWidgetColors *wcol, const struct rcti *rect, const struct rcti *slider, int state);
+void UI_draw_widget_scroll(struct uiWidgetColors *wcol, const struct rcti *rect, const struct rcti *slider, int state);
/* Callbacks
*
- * uiBlockSetHandleFunc/ButmFunc are for handling events through a callback.
+ * UI_block_func_handle_set/ButmFunc are for handling events through a callback.
* HandleFunc gets the retval passed on, and ButmFunc gets a2. The latter is
* mostly for compatibility with older code.
*
- * uiButSetCompleteFunc is for tab completion.
+ * UI_but_func_complete_set is for tab completion.
*
* uiButSearchFunc is for name buttons, showing a popup with matches
*
- * uiBlockSetFunc and uiButSetFunc are callbacks run when a button is used,
+ * UI_block_func_set and UI_but_func_set are callbacks run when a button is used,
* in case events, operators or RNA are not sufficient to handle the button.
*
- * uiButSetNFunc will free the argument with MEM_freeN. */
+ * UI_but_funcN_set will free the argument with MEM_freeN. */
typedef struct uiSearchItems uiSearchItems;
@@ -338,6 +348,9 @@ typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origs
typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items);
+/* Must return allocated string. */
+typedef char *(*uiButToolTipFunc)(struct bContext *C, void *argN, const char *tip);
+
typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
/* Menu Callbacks */
@@ -348,30 +361,35 @@ typedef void (*uiMenuHandleFunc)(struct bContext *C, void *arg, int event);
/* Popup Menus
*
* Functions used to create popup menus. For more extended menus the
- * uiPupMenuBegin/End functions can be used to define own items with
+ * UI_popup_menu_begin/End functions can be used to define own items with
* the uiItem functions in between. If it is a simple confirmation menu
* or similar, popups can be created with a single function call. */
typedef struct uiPopupMenu uiPopupMenu;
-struct uiPopupMenu *uiPupMenuBegin(struct bContext *C, const char *title, int icon) ATTR_NONNULL();
-void uiPupMenuEnd(struct bContext *C, struct uiPopupMenu *head);
-struct uiLayout *uiPupMenuLayout(uiPopupMenu *head);
+struct uiPopupMenu *UI_popup_menu_begin(struct bContext *C, const char *title, int icon) ATTR_NONNULL();
+void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *head);
+struct uiLayout *UI_popup_menu_layout(uiPopupMenu *head);
-void uiPupMenuReports(struct bContext *C, struct ReportList *reports) ATTR_NONNULL();
-bool uiPupMenuInvoke(struct bContext *C, const char *idname, struct ReportList *reports) ATTR_NONNULL(1, 2);
+void UI_popup_menu_reports(struct bContext *C, struct ReportList *reports) ATTR_NONNULL();
+int UI_popup_menu_invoke(struct bContext *C, const char *idname, struct ReportList *reports) ATTR_NONNULL(1, 2);
/* Pie menus */
typedef struct uiPieMenu uiPieMenu;
-void uiPieMenuInvoke(struct bContext *C, const char *idname, const struct wmEvent *event);
-void uiPieOperatorEnumInvoke(struct bContext *C, const char *title, const char *opname,
- const char *propname, const struct wmEvent *event);
-void uiPieEnumInvoke(struct bContext *C, const char *title, const char *path, const struct wmEvent *event);
-
-struct uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const struct wmEvent *event) ATTR_NONNULL();
-void uiPieMenuEnd(struct bContext *C, uiPieMenu *pie);
-struct uiLayout *uiPieMenuLayout(struct uiPieMenu *pie);
+int UI_pie_menu_invoke(struct bContext *C, const char *idname, const struct wmEvent *event);
+int UI_pie_menu_invoke_from_operator_enum(
+ struct bContext *C, const char *title, const char *opname,
+ const char *propname, const struct wmEvent *event);
+int UI_pie_menu_invoke_from_rna_enum(
+ struct bContext *C, const char *title,
+ const char *path, const struct wmEvent *event);
+
+struct uiPieMenu *UI_pie_menu_begin(
+ struct bContext *C, const char *title, int icon,
+ const struct wmEvent *event) ATTR_NONNULL();
+void UI_pie_menu_end(struct bContext *C, uiPieMenu *pie);
+struct uiLayout *UI_pie_menu_layout(struct uiPieMenu *pie);
/* Popup Blocks
*
* Functions used to create popup blocks. These are like popup menus
@@ -380,12 +398,12 @@ struct uiLayout *uiPieMenuLayout(struct uiPieMenu *pie);
typedef uiBlock * (*uiBlockCreateFunc)(struct bContext *C, struct ARegion *ar, void *arg1);
typedef void (*uiBlockCancelFunc)(struct bContext *C, void *arg1);
-void uiPupBlock(struct bContext *C, uiBlockCreateFunc func, void *arg);
-void uiPupBlockO(struct bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext);
-void uiPupBlockEx(struct bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg);
+void UI_popup_block_invoke(struct bContext *C, uiBlockCreateFunc func, void *arg);
+void UI_popup_block_invoke_ex(struct bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext);
+void UI_popup_block_ex(struct bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg);
/* void uiPupBlockOperator(struct bContext *C, uiBlockCreateFunc func, struct wmOperator *op, int opcontext); */ /* UNUSED */
-void uiPupBlockClose(struct bContext *C, uiBlock *block);
+void UI_popup_block_close(struct bContext *C, uiBlock *block);
/* Blocks
*
@@ -398,29 +416,29 @@ void uiPupBlockClose(struct bContext *C, uiBlock *block);
*
* */
-uiBlock *uiBeginBlock(const struct bContext *C, struct ARegion *region, const char *name, short dt);
-void uiEndBlock_ex(const struct bContext *C, uiBlock *block, const int xy[2]);
-void uiEndBlock(const struct bContext *C, uiBlock *block);
-void uiDrawBlock(const struct bContext *C, struct uiBlock *block);
-void uiBlockUpdateFromOld(const struct bContext *C, struct uiBlock *block);
+uiBlock *UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, short dt);
+void UI_block_end_ex(const struct bContext *C, uiBlock *block, const int xy[2]);
+void UI_block_end(const struct bContext *C, uiBlock *block);
+void UI_block_draw(const struct bContext *C, struct uiBlock *block);
+void UI_block_update_from_old(const struct bContext *C, struct uiBlock *block);
-uiBlock *uiGetBlock(const char *name, struct ARegion *ar);
+uiBlock *UI_block_find_in_region(const char *name, struct ARegion *ar);
-void uiBlockSetEmboss(uiBlock *block, char dt);
+void UI_block_emboss_set(uiBlock *block, char dt);
-void uiFreeBlock(const struct bContext *C, uiBlock *block);
-void uiFreeBlocks(const struct bContext *C, struct ListBase *lb);
-void uiFreeInactiveBlocks(const struct bContext *C, struct ListBase *lb);
-void uiFreeActiveButtons(const struct bContext *C, struct bScreen *screen);
+void UI_block_free(const struct bContext *C, uiBlock *block);
+void UI_blocklist_free(const struct bContext *C, struct ListBase *lb);
+void UI_blocklist_free_inactive(const struct bContext *C, struct ListBase *lb);
+void UI_screen_free_active_but(const struct bContext *C, struct bScreen *screen);
-void uiBlockSetRegion(uiBlock *block, struct ARegion *region);
+void UI_block_region_set(uiBlock *block, struct ARegion *region);
-void uiBlockSetButLock(uiBlock *block, bool val, const char *lockstr);
-void uiBlockClearButLock(uiBlock *block);
+void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr);
+void UI_block_lock_clear(uiBlock *block);
/* automatic aligning, horiz or verical */
-void uiBlockBeginAlign(uiBlock *block);
-void uiBlockEndAlign(uiBlock *block);
+void UI_block_align_begin(uiBlock *block);
+void UI_block_align_end(uiBlock *block);
/* block bounds/position calculation */
typedef enum {
@@ -433,44 +451,44 @@ typedef enum {
UI_BLOCK_BOUNDS_PIE_CENTER,
} eBlockBoundsCalc;
-void uiBoundsBlock(struct uiBlock *block, int addval);
-void uiTextBoundsBlock(uiBlock *block, int addval);
-void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my);
-void uiMenuPopupBoundsBlock(uiBlock *block, int addvall, int mx, int my);
-void uiCenteredBoundsBlock(uiBlock *block, int addval);
-void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int maxy);
+void UI_block_bounds_set_normal(struct uiBlock *block, int addval);
+void UI_block_bounds_set_text(uiBlock *block, int addval);
+void UI_block_bounds_set_popup(uiBlock *block, int addval, int mx, int my);
+void UI_block_bounds_set_menu(uiBlock *block, int addvall, int mx, int my);
+void UI_block_bounds_set_centered(uiBlock *block, int addval);
+void UI_block_bounds_set_explicit(uiBlock *block, int minx, int miny, int maxx, int maxy);
-int uiBlocksGetYMin(struct ListBase *lb);
+int UI_blocklist_min_y_get(struct ListBase *lb);
-void uiBlockSetDirection(uiBlock *block, char direction);
-void uiBlockFlipOrder(uiBlock *block);
-void uiBlockSetFlag(uiBlock *block, int flag);
-void uiBlockClearFlag(uiBlock *block, int flag);
+void UI_block_direction_set(uiBlock *block, char direction);
+void UI_block_order_flip(uiBlock *block);
+void UI_block_flag_enable(uiBlock *block, int flag);
+void UI_block_flag_disable(uiBlock *block, int flag);
-int uiButGetRetVal(uiBut *but);
+int UI_but_return_value_get(uiBut *but);
-void uiButSetDragID(uiBut *but, struct ID *id);
-void uiButSetDragRNA(uiBut *but, struct PointerRNA *ptr);
-void uiButSetDragPath(uiBut *but, const char *path);
-void uiButSetDragName(uiBut *but, const char *name);
-void uiButSetDragValue(uiBut *but);
-void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale);
+void UI_but_drag_set_id(uiBut *but, struct ID *id);
+void UI_but_drag_set_rna(uiBut *but, struct PointerRNA *ptr);
+void UI_but_drag_set_path(uiBut *but, const char *path);
+void UI_but_drag_set_name(uiBut *but, const char *name);
+void UI_but_drag_set_value(uiBut *but);
+void UI_but_drag_set_image(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale);
bool UI_but_active_drop_name(struct bContext *C);
bool UI_but_active_drop_color(struct bContext *C);
-void uiButSetFlag(uiBut *but, int flag);
-void uiButClearFlag(uiBut *but, int flag);
+void UI_but_flag_enable(uiBut *but, int flag);
+void UI_but_flag_disable(uiBut *but, int flag);
-void uiButSetDrawFlag(uiBut *but, int flag);
-void uiButClearDrawFlag(uiBut *but, int flag);
+void UI_but_drawflag_enable(uiBut *but, int flag);
+void UI_but_drawflag_disable(uiBut *but, int flag);
-void uiButSetMenuFromPulldown(uiBut *but);
+void UI_but_type_set_menu_from_pulldown(uiBut *but);
/* special button case, only draw it when used actively, for outliner etc */
-bool uiButActiveOnly(const struct bContext *C, struct ARegion *ar, uiBlock *block, uiBut *but);
+bool UI_but_active_only(const struct bContext *C, struct ARegion *ar, uiBlock *block, uiBut *but);
-void uiButExecute(const struct bContext *C, uiBut *but);
+void UI_but_execute(const struct bContext *C, uiBut *but);
/* Buttons
@@ -544,10 +562,10 @@ uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcon
uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip);
/* for passing inputs to ButO buttons */
-struct PointerRNA *uiButGetOperatorPtrRNA(uiBut *but);
+struct PointerRNA *UI_but_operator_ptr_get(uiBut *but);
-void uiButSetUnitType(uiBut *but, const int unit_type);
-int uiButGetUnitType(const uiBut *but);
+void UI_but_unit_type_set(uiBut *but, const int unit_type);
+int UI_but_unit_type_get(const uiBut *but);
enum {
BUT_GET_RNAPROP_IDENTIFIER = 1,
@@ -572,7 +590,7 @@ typedef struct uiStringInfo {
/* Note: Expects pointers to uiStringInfo structs as parameters.
* Will fill them with translated strings, when possible.
* Strings in uiStringInfo must be MEM_freeN'ed by caller. */
-void uiButGetStrInfo(struct bContext *C, uiBut *but, ...) ATTR_SENTINEL(0);
+void UI_but_string_info_get(struct bContext *C, uiBut *but, ...) ATTR_SENTINEL(0);
/* Edit i18n stuff. */
/* Name of the main py op from i18n addon. */
@@ -602,8 +620,8 @@ void uiButGetStrInfo(struct bContext *C, uiBut *but, ...) ATTR_SENTINEL(0);
#define UI_ID_PREVIEWS (1 << 11)
#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)
-int uiIconFromID(struct ID *id);
-int uiIconFromReportType(int type);
+int UI_icon_from_id(struct ID *id);
+int UI_icon_from_report_type(int type);
uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip);
uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip);
@@ -632,41 +650,44 @@ int uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, bool (*check_prop
* Game engine logic brick links. Non-functional currently in 2.5,
* code to handle and draw these is disabled internally. */
-void uiSetButLink(struct uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to);
+void UI_but_link_set(struct uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to);
-void uiComposeLinks(uiBlock *block);
-uiBut *uiFindInlink(uiBlock *block, void *poin);
+void UI_block_links_compose(uiBlock *block);
+uiBut *UI_block_links_find_inlink(uiBlock *block, void *poin);
/* use inside searchfunc to add items */
-bool uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid);
+bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid);
/* bfunc gets search item *poin as arg2, or if NULL the old string */
-void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc, void *active);
+void UI_but_func_search_set(uiBut *but, uiButSearchFunc sfunc, void *arg1, uiButHandleFunc bfunc, void *active);
/* height in pixels, it's using hardcoded values still */
-int uiSearchBoxHeight(void);
-int uiSearchBoxWidth(void);
+int UI_searchbox_size_y(void);
+int UI_searchbox_size_x(void);
/* check if a string is in an existing search box */
-int uiSearchItemFindIndex(uiSearchItems *items, const char *name);
+int UI_search_items_find_index(uiSearchItems *items, const char *name);
+
+void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg);
+void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg);
+void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2);
+void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2);
-void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg);
-void uiBlockSetButmFunc(uiBlock *block, uiMenuHandleFunc func, void *arg);
-void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2);
-void uiBlockSetNFunc(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2);
+void UI_but_func_rename_set(uiBut *but, uiButHandleRenameFunc func, void *arg1);
+void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2);
+void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2);
-void uiButSetRenameFunc(uiBut *but, uiButHandleRenameFunc func, void *arg1);
-void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2);
-void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2);
+void UI_but_func_complete_set(uiBut *but, uiButCompleteFunc func, void *arg);
-void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg);
+void UI_but_func_drawextra_set(
+ uiBlock *block,
+ void (*func)(const struct bContext *C, void *, void *, void *, struct rcti *rect),
+ void *arg1, void *arg2);
-void uiBlockSetDrawExtraFunc(uiBlock *block,
- void (*func)(const struct bContext *C, void *, void *, void *, struct rcti *rect),
- void *arg1, void *arg2);
+void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN);
bool UI_textbutton_activate_rna(const struct bContext *C, struct ARegion *ar,
const void *rna_poin_data, const char *rna_prop_id);
bool UI_textbutton_activate_but(const struct bContext *C, uiBut *but);
-void uiButSetFocusOnEnter(struct wmWindow *win, uiBut *but);
+void UI_but_focus_on_enter_event(struct wmWindow *win, uiBut *but);
/* Autocomplete
*
@@ -680,9 +701,9 @@ typedef struct AutoComplete AutoComplete;
#define AUTOCOMPLETE_FULL_MATCH 1
#define AUTOCOMPLETE_PARTIAL_MATCH 2
-AutoComplete *autocomplete_begin(const char *startname, size_t maxlen);
-void autocomplete_do_name(AutoComplete *autocpl, const char *name);
-int autocomplete_end(AutoComplete *autocpl, char *autoname);
+AutoComplete *UI_autocomplete_begin(const char *startname, size_t maxlen);
+void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name);
+int UI_autocomplete_end(AutoComplete *autocpl, char *autoname);
/* Panels
*
@@ -690,15 +711,15 @@ int autocomplete_end(AutoComplete *autocpl, char *autoname);
* could use a good cleanup, though how they will function in 2.5 is
* not clear yet so we postpone that. */
-void uiBeginPanels(const struct bContext *C, struct ARegion *ar);
-void uiEndPanels(const struct bContext *C, struct ARegion *ar, int *x, int *y);
-void uiDrawPanels(const struct bContext *C, struct ARegion *ar);
+void UI_panels_begin(const struct bContext *C, struct ARegion *ar);
+void UI_panels_end(const struct bContext *C, struct ARegion *ar, int *x, int *y);
+void UI_panels_draw(const struct bContext *C, struct ARegion *ar);
-struct Panel *uiPanelFindByType(struct ARegion *ar, struct PanelType *pt);
-struct Panel *uiBeginPanel(struct ScrArea *sa, struct ARegion *ar, uiBlock *block,
- struct PanelType *pt, struct Panel *pa, bool *r_open);
-void uiEndPanel(uiBlock *block, int width, int height);
-void uiScalePanels(struct ARegion *ar, float new_width);
+struct Panel *UI_panel_find_by_type(struct ARegion *ar, struct PanelType *pt);
+struct Panel *UI_panel_begin(struct ScrArea *sa, struct ARegion *ar, uiBlock *block,
+ struct PanelType *pt, struct Panel *pa, bool *r_open);
+void UI_panel_end(uiBlock *block, int width, int height);
+void UI_panels_scale(struct ARegion *ar, float new_width);
bool UI_panel_category_is_visible(struct ARegion *ar);
void UI_panel_category_add(struct ARegion *ar, const char *name);
@@ -717,10 +738,10 @@ void UI_panel_category_draw_all(struct ARegion *ar, const
* handling WM events. Mostly this is done automatic by modules such
* as screen/ if ED_KEYMAP_UI is set, or internally in popup functions. */
-void UI_add_region_handlers(struct ListBase *handlers);
-void UI_add_popup_handlers(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *popup, const bool accept_dbl_click);
-void UI_remove_popup_handlers(struct ListBase *handlers, uiPopupBlockHandle *popup);
-void UI_remove_popup_handlers_all(struct bContext *C, struct ListBase *handlers);
+void UI_region_handlers_add(struct ListBase *handlers);
+void UI_popup_handlers_add(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *popup, const bool accept_dbl_click);
+void UI_popup_handlers_remove(struct ListBase *handlers, uiPopupBlockHandle *popup);
+void UI_popup_handlers_remove_all(struct bContext *C, struct ListBase *handlers);
/* Module
*
@@ -797,9 +818,9 @@ enum {
/* not apart of the corner flags but mixed in some functions */
#define UI_RB_ALPHA (UI_CNR_ALL + 1)
-uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, struct uiStyle *style);
-void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout);
-void uiBlockLayoutResolve(uiBlock *block, int *x, int *y);
+uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, struct uiStyle *style);
+void UI_block_layout_set_current(uiBlock *block, uiLayout *layout);
+void UI_block_layout_resolve(uiBlock *block, int *x, int *y);
uiBlock *uiLayoutGetBlock(uiLayout *layout);
@@ -810,7 +831,7 @@ const char *uiLayoutIntrospect(uiLayout *layout); // XXX - testing
void uiLayoutOperatorButs(const struct bContext *C, struct uiLayout *layout, struct wmOperator *op,
bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
const char label_align, const short flag);
-struct MenuType *uiButGetMenuType(uiBut *but);
+struct MenuType *UI_but_menutype_get(uiBut *but);
void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext);
void uiLayoutSetActive(uiLayout *layout, bool active);
@@ -876,8 +897,9 @@ void uiTemplateGameStates(uiLayout *layout, struct PointerRNA *ptr, const char *
void uiTemplateImage(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, struct PointerRNA *userptr, int compact);
void uiTemplateImageSettings(uiLayout *layout, struct PointerRNA *imfptr, int color_management);
void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser);
+void uiTemplateImageInfo(uiLayout *layout, struct bContext *C, Image *ima, ImageUser *iuser);
void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C);
-void uiOperatorSearch_But(uiBut *but);
+void UI_but_func_operator_search(uiBut *but);
void uiTemplateOperatorSearch(uiLayout *layout);
void uiTemplateHeader3D(uiLayout *layout, struct bContext *C);
void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C);
@@ -890,7 +912,8 @@ void uiTemplateNodeSocket(uiLayout *layout, struct bContext *C, float *color);
#define UI_UL_DEFAULT_CLASS_NAME "UI_UL_list"
void uiTemplateList(uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id,
struct PointerRNA *dataptr, const char *propname, struct PointerRNA *active_dataptr,
- const char *active_propname, int rows, int maxrows, int layout_type, int columns);
+ const char *active_propname, const char *item_dyntip_propname,
+ int rows, int maxrows, int layout_type, int columns);
void uiTemplateNodeLink(uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input);
void uiTemplateNodeView(uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input);
void uiTemplateTextureUser(uiLayout *layout, struct bContext *C);
@@ -935,6 +958,7 @@ void uiItemS(uiLayout *layout); /* separator */
void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg);
void uiItemMenuEnumO(uiLayout *layout, struct bContext *C, const char *opname, const char *propname, const char *name, int icon);
+void uiItemMenuEnumR_prop(uiLayout *layout, struct PointerRNA *ptr, PropertyRNA *prop, const char *name, int icon);
void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon);
/* UI Operators */
@@ -943,32 +967,38 @@ typedef struct uiDragColorHandle {
bool gamma_corrected;
} uiDragColorHandle;
-void UI_buttons_operatortypes(void);
+void ED_button_operatortypes(void);
void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop);
int UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event);
/* Helpers for Operators */
-uiBut *uiContextActiveButton(const struct bContext *C);
-void uiContextActiveProperty(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index);
-void uiContextActivePropertyHandle(struct bContext *C);
-struct wmOperator *uiContextActiveOperator(const struct bContext *C);
-void uiContextAnimUpdate(const struct bContext *C);
-void uiFileBrowseContextProperty(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop);
-void uiIDContextProperty(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop);
+uiBut *UI_context_active_but_get(const struct bContext *C);
+void UI_context_active_but_prop_get(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index);
+void UI_context_active_but_prop_handle(struct bContext *C);
+struct wmOperator *UI_context_active_operator_get(const struct bContext *C);
+void UI_context_update_anim_flag(const struct bContext *C);
+void UI_context_active_but_prop_get_filebrowser(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop);
+void UI_context_active_but_prop_get_templateID(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop);
/* Styled text draw */
-void uiStyleFontSet(struct uiFontStyle *fs);
-void uiStyleFontDrawExt(struct uiFontStyle *fs, const struct rcti *rect, const char *str,
- size_t len, float *r_xofs, float *r_yofs);
-void uiStyleFontDraw(struct uiFontStyle *fs, const struct rcti *rect, const char *str);
-void uiStyleFontDrawRotated(struct uiFontStyle *fs, const struct rcti *rect, const char *str);
+void UI_fontstyle_set(const struct uiFontStyle *fs);
+void UI_fontstyle_draw_ex(
+ const struct uiFontStyle *fs, const struct rcti *rect, const char *str,
+ size_t len, float *r_xofs, float *r_yofs);
+void UI_fontstyle_draw(const struct uiFontStyle *fs, const struct rcti *rect, const char *str);
+void UI_fontstyle_draw_rotated(const struct uiFontStyle *fs, const struct rcti *rect, const char *str);
+void UI_fontstyle_draw_simple(const struct uiFontStyle *fs, float x, float y, const char *str);
+void UI_fontstyle_draw_simple_backdrop(
+ const uiFontStyle *fs, float x, float y, const char *str,
+ const unsigned char fg[4], const unsigned char bg[4]);
-int UI_GetStringWidth(const char *str); // XXX temp
-void UI_DrawString(float x, float y, const char *str); // XXX temp
-void UI_DrawTriIcon(float x, float y, char dir);
+int UI_fontstyle_string_width(const struct uiFontStyle *fs, const char *str);
+int UI_fontstyle_height_max(const struct uiFontStyle *fs);
-uiStyle *UI_GetStyle(void); /* use for fonts etc */
-uiStyle *UI_GetStyleDraw(void); /* DPI scaled settings for drawing */
+void UI_draw_icon_tri(float x, float y, char dir);
+
+uiStyle *UI_style_get(void); /* use for fonts etc */
+uiStyle *UI_style_get_dpi(void); /* DPI scaled settings for drawing */
/* linker workaround ack! */
void UI_template_fix_linking(void);
@@ -988,12 +1018,16 @@ void UI_butstore_free(uiBlock *block, uiButStore *bs);
bool UI_butstore_is_valid(uiButStore *bs);
bool UI_butstore_is_registered(uiBlock *block, uiBut *but);
void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p);
+bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src);
void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p);
/* Float precision helpers */
#define UI_PRECISION_FLOAT_MAX 7
-int uiFloatPrecisionCalc(int prec, double value);
+/* Typical UI text */
+#define UI_FSTYLE_WIDGET (const uiFontStyle *)&(UI_style_get()->widget)
+
+int UI_calc_float_precision(int prec, double value);
#endif /* __UI_INTERFACE_H__ */
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 6104505ef58..74927428363 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -33,6 +33,7 @@
#define __UI_INTERFACE_ICONS_H__
struct bContext;
+struct ID;
struct Image;
struct ImBuf;
struct World;
@@ -63,6 +64,9 @@ void UI_icons_init(int first_dyn_id);
int UI_icon_get_width(int icon_id);
int UI_icon_get_height(int icon_id);
+void UI_id_icon_render(
+ const struct bContext *C, struct Scene *scene, struct ID *id, const bool big, const bool use_job);
+
void UI_icon_draw(float x, float y, int icon_id);
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);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 5b61e76f514..4a484212a63 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -111,6 +111,8 @@ enum {
TH_FACE_DOT,
TH_FACEDOT_SIZE,
TH_CFRAME,
+ TH_TIME_KEYFRAME,
+ TH_TIME_GP_KEYFRAME,
TH_NURB_ULINE,
TH_NURB_VLINE,
TH_NURB_SEL_ULINE,
@@ -207,6 +209,10 @@ enum {
TH_HANDLE_VERTEX_SELECT,
TH_HANDLE_VERTEX_SIZE,
+ TH_GP_VERTEX,
+ TH_GP_VERTEX_SELECT,
+ TH_GP_VERTEX_SIZE,
+
TH_DOPESHEET_CHANNELOB,
TH_DOPESHEET_CHANNELSUBOB,
@@ -266,6 +272,8 @@ enum {
TH_NLA_SOUND,
TH_NLA_SOUND_SEL,
+ TH_WIDGET_EMBOSS,
+
TH_AXIS_X, /* X/Y/Z Axis */
TH_AXIS_Y,
TH_AXIS_Z,
@@ -285,6 +293,8 @@ enum {
TH_INFO_DEBUG,
TH_INFO_DEBUG_TEXT,
TH_VIEW_OVERLAY,
+
+ TH_V3D_CLIPPING_BORDER
};
/* XXX WARNING: previous is saved in file, so do not change order! */
@@ -293,6 +303,11 @@ enum {
struct bTheme;
struct PointerRNA;
+struct bThemeState {
+ struct bTheme *theme;
+ int spacetype, regionid;
+};
+
// THE CODERS API FOR THEMES:
// sets the color
@@ -346,12 +361,18 @@ void UI_GetColorPtrBlendShade3ubv(const unsigned char cp1[3], const unsigned
// clear the openGL ClearColor using the input colorid
void UI_ThemeClearColor(int colorid);
+// clear the openGL ClearColor using the input colorid using optional transparency
+void UI_ThemeClearColorAlpha(int colorid, float alpha);
+
// internal (blender) usage only, for init and set active
void UI_SetTheme(int spacetype, int regionid);
// get current theme
struct bTheme *UI_GetTheme(void);
+void UI_Theme_Store(struct bThemeState *theme_state);
+void UI_Theme_Restore(struct bThemeState *theme_state);
+
// return shadow width outside menus and popups */
int UI_ThemeMenuShadowWidth(void);
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index cb7cf3ee404..4d7446a7a81 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -162,7 +162,7 @@ void UI_view2d_zoom_cache_reset(void);
/* view matrix operations */
void UI_view2d_view_ortho(struct View2D *v2d);
-void UI_view2d_view_orthoSpecial(struct ARegion *ar, struct View2D *v2d, short xaxis);
+void UI_view2d_view_orthoSpecial(struct ARegion *ar, struct View2D *v2d, const bool xaxis);
void UI_view2d_view_restore(const struct bContext *C);
/* grid drawing */
@@ -234,5 +234,6 @@ void ED_keymap_view2d(struct wmKeyConfig *keyconf);
void UI_view2d_smooth_view(struct bContext *C, struct ARegion *ar,
const struct rctf *cur, const int smooth_viewtx);
-#endif /* __UI_VIEW2D_H__ */
+#define UI_MARKER_MARGIN_Y (42 * UI_DPI_FAC)
+#endif /* __UI_VIEW2D_H__ */
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index b921d17104c..972eca747b9 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -71,6 +71,12 @@ if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
endif()
+if(WIN32)
+ if(WITH_INPUT_IME)
+ add_definitions(-DWITH_INPUT_IME)
+ endif()
+endif()
+
add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_interface "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/interface/SConscript b/source/blender/editors/interface/SConscript
index 303ab7ff286..5af8bba5a9f 100644
--- a/source/blender/editors/interface/SConscript
+++ b/source/blender/editors/interface/SConscript
@@ -48,6 +48,10 @@ incs = [
defs = env['BF_GL_DEFINITIONS']
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'win64-mingw'):
+ if env['WITH_BF_IME']:
+ defs.append('WITH_INPUT_IME')
+
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 41bf5d5494e..bad09a7c441 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -76,9 +76,9 @@
#include "interface_intern.h"
-/* avoid unneeded calls to ui_get_but_val */
+/* avoid unneeded calls to ui_but_value_get */
#define UI_BUT_VALUE_UNSET DBL_MAX
-#define UI_GET_BUT_VALUE_INIT(_but, _value) if (_value == DBL_MAX) { (_value) = ui_get_but_val(_but); } (void)0
+#define UI_GET_BUT_VALUE_INIT(_but, _value) if (_value == DBL_MAX) { (_value) = ui_but_value_get(_but); } (void)0
#define B_NOP -1
@@ -89,7 +89,7 @@
* ui_blah_blah() internal function
*/
-static void ui_free_but(const bContext *C, uiBut *but);
+static void ui_but_free(const bContext *C, uiBut *but);
bool ui_block_is_menu(const uiBlock *block)
{
@@ -103,17 +103,17 @@ bool ui_block_is_pie_menu(const uiBlock *block)
return ((block->flag & UI_BLOCK_RADIAL) != 0);
}
-static bool ui_is_but_unit_radians_ex(UnitSettings *unit, const int unit_type)
+static bool ui_but_is_unit_radians_ex(UnitSettings *unit, const int unit_type)
{
return (unit->system_rotation == USER_UNIT_ROT_RADIANS && unit_type == PROP_UNIT_ROTATION);
}
-static bool ui_is_but_unit_radians(const uiBut *but)
+static bool ui_but_is_unit_radians(const uiBut *but)
{
UnitSettings *unit = but->block->unit;
- const int unit_type = uiButGetUnitType(but);
+ const int unit_type = UI_but_unit_type_get(but);
- return ui_is_but_unit_radians_ex(unit, unit_type);
+ return ui_but_is_unit_radians_ex(unit, unit_type);
}
/* ************* window matrix ************** */
@@ -209,6 +209,11 @@ void ui_window_to_region(const ARegion *ar, int *x, int *y)
*y -= ar->winrct.ymin;
}
+void ui_region_to_window(const ARegion *ar, int *x, int *y)
+{
+ *x += ar->winrct.xmin;
+ *y += ar->winrct.ymin;
+}
/* ******************* block calc ************************* */
void ui_block_translate(uiBlock *block, int x, int y)
@@ -222,16 +227,16 @@ void ui_block_translate(uiBlock *block, int x, int y)
BLI_rctf_translate(&block->rect, x, y);
}
-static void ui_text_bounds_block(uiBlock *block, float offset)
+static void ui_block_bounds_calc_text(uiBlock *block, float offset)
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
uiBut *bt, *init_col_bt, *col_bt;
int i = 0, j, x1addval = offset;
- uiStyleFontSet(&style->widget);
+ UI_fontstyle_set(&style->widget);
for (init_col_bt = bt = block->buttons.first; bt; bt = bt->next) {
- if (!ELEM(bt->type, SEPR, SEPRLINE)) {
+ if (!ELEM(bt->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr));
if (j > i)
@@ -244,7 +249,7 @@ static void ui_text_bounds_block(uiBlock *block, float offset)
col_bt->rect.xmin = x1addval;
col_bt->rect.xmax = x1addval + i + block->bounds;
- ui_check_but(col_bt); /* clips text again */
+ ui_but_update(col_bt); /* clips text again */
}
/* And we prepare next column. */
@@ -259,11 +264,11 @@ static void ui_text_bounds_block(uiBlock *block, float offset)
col_bt->rect.xmin = x1addval;
col_bt->rect.xmax = max_ff(x1addval + i + block->bounds, offset + block->minbounds);
- ui_check_but(col_bt); /* clips text again */
+ ui_but_update(col_bt); /* clips text again */
}
}
-void ui_bounds_block(uiBlock *block)
+void ui_block_bounds_calc(uiBlock *block)
{
uiBut *bt;
int xof;
@@ -292,7 +297,7 @@ void ui_bounds_block(uiBlock *block)
/* hardcoded exception... but that one is annoying with larger safety */
bt = block->buttons.first;
- if (bt && strncmp(bt->str, "ERROR", 5) == 0) xof = 10;
+ if (bt && STREQLEN(bt->str, "ERROR", 5)) xof = 10;
else xof = 40;
block->safety.xmin = block->rect.xmin - xof;
@@ -301,7 +306,7 @@ void ui_bounds_block(uiBlock *block)
block->safety.ymax = block->rect.ymax + xof;
}
-static void ui_centered_bounds_block(wmWindow *window, uiBlock *block)
+static void ui_block_bounds_calc_centered(wmWindow *window, uiBlock *block)
{
int xmax, ymax;
int startx, starty;
@@ -313,7 +318,7 @@ static void ui_centered_bounds_block(wmWindow *window, uiBlock *block)
xmax = WM_window_pixels_x(window);
ymax = WM_window_pixels_y(window);
- ui_bounds_block(block);
+ ui_block_bounds_calc(block);
width = BLI_rctf_size_x(&block->rect);
height = BLI_rctf_size_y(&block->rect);
@@ -324,11 +329,11 @@ static void ui_centered_bounds_block(wmWindow *window, uiBlock *block)
ui_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin);
/* now recompute bounds and safety */
- ui_bounds_block(block);
+ ui_block_bounds_calc(block);
}
-static void ui_centered_pie_bounds_block(uiBlock *block)
+static void ui_block_bounds_calc_centered_pie(uiBlock *block)
{
const int xy[2] = {
block->pie_data.pie_center_spawned[0],
@@ -338,11 +343,12 @@ static void ui_centered_pie_bounds_block(uiBlock *block)
ui_block_translate(block, xy[0], xy[1]);
/* now recompute bounds and safety */
- ui_bounds_block(block);
+ ui_block_bounds_calc(block);
}
-static void ui_popup_bounds_block(wmWindow *window, uiBlock *block,
- eBlockBoundsCalc bounds_calc, const int xy[2])
+static void ui_block_bounds_calc_popup(
+ wmWindow *window, uiBlock *block,
+ eBlockBoundsCalc bounds_calc, const int xy[2])
{
int startx, starty, endx, endy, width, height, oldwidth, oldheight;
int oldbounds, xmax, ymax;
@@ -351,7 +357,7 @@ static void ui_popup_bounds_block(wmWindow *window, uiBlock *block,
oldbounds = block->bounds;
/* compute mouse position with user defined offset */
- ui_bounds_block(block);
+ ui_block_bounds_calc(block);
xmax = WM_window_pixels_x(window);
ymax = WM_window_pixels_y(window);
@@ -363,13 +369,13 @@ static void ui_popup_bounds_block(wmWindow *window, uiBlock *block,
if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) {
if (block->flag & UI_BLOCK_LOOP) {
block->bounds = 2.5f * UI_UNIT_X;
- ui_text_bounds_block(block, block->rect.xmin);
+ ui_block_bounds_calc_text(block, block->rect.xmin);
}
}
/* next we recompute bounds */
block->bounds = oldbounds;
- ui_bounds_block(block);
+ ui_block_bounds_calc(block);
/* and we adjust the position to fit within window */
width = BLI_rctf_size_x(&block->rect);
@@ -380,7 +386,7 @@ static void ui_popup_bounds_block(wmWindow *window, uiBlock *block,
oldheight = oldheight > 0 ? oldheight : MAX2(1, height);
/* offset block based on mouse position, user offset is scaled
- * along in case we resized the block in ui_text_bounds_block */
+ * along in case we resized the block in ui_block_bounds_calc_text */
startx = xy[0] + block->rect.xmin + (block->mx * width) / oldwidth;
starty = xy[1] + block->rect.ymin + (block->my * height) / oldheight;
@@ -404,11 +410,11 @@ static void ui_popup_bounds_block(wmWindow *window, uiBlock *block,
ui_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin);
/* now recompute bounds and safety */
- ui_bounds_block(block);
+ ui_block_bounds_calc(block);
}
/* used for various cases */
-void uiBoundsBlock(uiBlock *block, int addval)
+void UI_block_bounds_set_normal(uiBlock *block, int addval)
{
if (block == NULL)
return;
@@ -418,14 +424,14 @@ void uiBoundsBlock(uiBlock *block, int addval)
}
/* used for pulldowns */
-void uiTextBoundsBlock(uiBlock *block, int addval)
+void UI_block_bounds_set_text(uiBlock *block, int addval)
{
block->bounds = addval;
block->bounds_type = UI_BLOCK_BOUNDS_TEXT;
}
/* used for block popups */
-void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my)
+void UI_block_bounds_set_popup(uiBlock *block, int addval, int mx, int my)
{
block->bounds = addval;
block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MOUSE;
@@ -434,7 +440,7 @@ void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my)
}
/* used for menu popups */
-void uiMenuPopupBoundsBlock(uiBlock *block, int addval, int mx, int my)
+void UI_block_bounds_set_menu(uiBlock *block, int addval, int mx, int my)
{
block->bounds = addval;
block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MENU;
@@ -443,13 +449,13 @@ void uiMenuPopupBoundsBlock(uiBlock *block, int addval, int mx, int my)
}
/* used for centered popups, i.e. splash */
-void uiCenteredBoundsBlock(uiBlock *block, int addval)
+void UI_block_bounds_set_centered(uiBlock *block, int addval)
{
block->bounds = addval;
block->bounds_type = UI_BLOCK_BOUNDS_POPUP_CENTER;
}
-void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int maxy)
+void UI_block_bounds_set_explicit(uiBlock *block, int minx, int miny, int maxx, int maxy)
{
block->rect.xmin = minx;
block->rect.ymin = miny;
@@ -458,21 +464,21 @@ void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int max
block->bounds_type = UI_BLOCK_BOUNDS_NONE;
}
-static int ui_but_float_precision(uiBut *but, double value)
+static int ui_but_calc_float_precision(uiBut *but, double value)
{
int prec = (int)but->a2;
/* first check for various special cases:
* * If button is radians, we want additional precision (see T39861).
* * If prec is not set, we fallback to a simple default */
- if (ui_is_but_unit_radians(but) && prec < 5) {
+ if (ui_but_is_unit_radians(but) && prec < 5) {
prec = 5;
}
else if (prec == -1) {
prec = (but->hardmax < 10.001f) ? 3 : 2;
}
- return uiFloatPrecisionCalc(prec, value);
+ return UI_calc_float_precision(prec, value);
}
/* ************** LINK LINE DRAWING ************* */
@@ -514,7 +520,7 @@ static void ui_draw_links(uiBlock *block)
bool found_activeline = false;
for (but = block->buttons.first; but; but = but->next) {
- if (but->type == LINK && but->link) {
+ if (but->type == UI_BTYPE_LINK && but->link) {
for (line = but->link->lines.first; line; line = line->next) {
if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE)) {
if (line->deactive)
@@ -531,7 +537,7 @@ static void ui_draw_links(uiBlock *block)
/* Draw the inactive lines (lines with neither button being hovered over) */
for (but = block->buttons.first; but; but = but->next) {
- if (but->type == LINK && but->link) {
+ if (but->type == UI_BTYPE_LINK && but->link) {
for (line = but->link->lines.first; line; line = line->next) {
if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE)) {
if (!line->deactive)
@@ -545,7 +551,7 @@ static void ui_draw_links(uiBlock *block)
* Do this last so they appear on top of inactive and grey out lines. */
if (found_activeline) {
for (but = block->buttons.first; but; but = but->next) {
- if (but->type == LINK && but->link) {
+ if (but->type == UI_BTYPE_LINK && but->link) {
for (line = but->link->lines.first; line; line = line->next) {
if ((line->from->flag & UI_ACTIVE) || (line->to->flag & UI_ACTIVE))
ui_draw_linkline(line, !found_selectline, false);
@@ -603,8 +609,8 @@ static void ui_but_update_linklines(uiBlock *block, uiBut *oldbut, uiBut *newbut
uiLinkLine *line;
uiBut *but;
- /* if active button is LINK */
- if (newbut->type == LINK && newbut->link) {
+ /* if active button is UI_BTYPE_LINK */
+ if (newbut->type == UI_BTYPE_LINK && newbut->link) {
SWAP(uiLink *, oldbut->link, newbut->link);
@@ -618,7 +624,7 @@ static void ui_but_update_linklines(uiBlock *block, uiBut *oldbut, uiBut *newbut
/* check all other button links */
for (but = block->buttons.first; but; but = but->next) {
- if (but != newbut && but->type == LINK && but->link) {
+ if (but != newbut && but->type == UI_BTYPE_LINK && but->link) {
for (line = but->link->lines.first; line; line = line->next) {
if (line->to == newbut)
line->to = oldbut;
@@ -710,6 +716,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu
if (oldbut->poin != (char *)oldbut) {
SWAP(char *, oldbut->poin, but->poin);
SWAP(void *, oldbut->func_argN, but->func_argN);
+ SWAP(void *, oldbut->tip_argN, but->tip_argN);
}
oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy);
@@ -717,11 +724,15 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu
/* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
* when scrolling without moving mouse (see [#28432]) */
- if (ELEM(oldbut->type, ROW, LISTROW))
+ if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW))
oldbut->hardmax = but->hardmax;
ui_but_update_linklines(block, oldbut, but);
+ if (!BLI_listbase_is_empty(&block->butstore)) {
+ UI_butstore_register_update(block, oldbut, but);
+ }
+
/* move/copy string from the new button to the old */
/* needed for alt+mouse wheel over enums */
if (but->str != but->strdata) {
@@ -742,7 +753,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu
}
BLI_remlink(&block->buttons, but);
- ui_free_but(C, but);
+ ui_but_free(C, but);
/* note: if layout hasn't been applied yet, it uses old button pointers... */
}
@@ -754,7 +765,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu
/* ensures one button can get activated, and in case the buttons
* draw are the same this gives O(1) lookup for each button */
BLI_remlink(&oldblock->buttons, oldbut);
- ui_free_but(C, oldbut);
+ ui_but_free(C, oldbut);
}
return found_active;
@@ -763,7 +774,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu
/* needed for temporarily rename buttons, such as in outliner or file-select,
* they should keep calling uiDefButs to keep them alive */
/* returns 0 when button removed */
-bool uiButActiveOnly(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but)
+bool UI_but_active_only(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but)
{
uiBlock *oldblock;
uiBut *oldbut;
@@ -784,11 +795,11 @@ bool uiButActiveOnly(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but)
}
}
if ((activate == true) || (found == false)) {
- ui_button_activate_do((bContext *)C, ar, but);
+ ui_but_activate_event((bContext *)C, ar, but);
}
else if ((found == true) && (isactive == false)) {
BLI_remlink(&block->buttons, but);
- ui_free_but(C, but);
+ ui_but_free(C, but);
return false;
}
@@ -796,18 +807,18 @@ bool uiButActiveOnly(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but)
}
/* simulate button click */
-void uiButExecute(const bContext *C, uiBut *but)
+void UI_but_execute(const bContext *C, uiBut *but)
{
ARegion *ar = CTX_wm_region(C);
void *active_back;
- ui_button_execute_begin((bContext *)C, ar, but, &active_back);
+ ui_but_execute_begin((bContext *)C, ar, but, &active_back);
/* Value is applied in begin. No further action required. */
- ui_button_execute_end((bContext *)C, ar, but, active_back);
+ ui_but_execute_end((bContext *)C, ar, but, active_back);
}
/* use to check if we need to disable undo, but don't make any changes
* returns false if undo needs to be disabled. */
-static bool ui_is_but_rna_undo(const uiBut *but)
+static bool ui_but_is_rna_undo(const uiBut *but)
{
if (but->rnapoin.id.data) {
/* avoid undo push for buttons who's ID are screen or wm level
@@ -850,7 +861,13 @@ static void ui_menu_block_set_keyaccels(uiBlock *block)
* fun first pass on all buttons so first word chars always get first priority */
for (but = block->buttons.first; but; but = but->next) {
- if (!ELEM(but->type, BUT, BUTM, MENU, BLOCK, PULLDOWN) || (but->flag & UI_HIDDEN)) {
+ if (!ELEM(but->type,
+ UI_BTYPE_BUT,
+ UI_BTYPE_BUT_MENU,
+ UI_BTYPE_MENU, UI_BTYPE_BLOCK,
+ UI_BTYPE_PULLDOWN) ||
+ (but->flag & UI_HIDDEN))
+ {
/* pass */
}
else if (but->menu_key == '\0') {
@@ -930,7 +947,7 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str
MEM_freeN(butstr_orig);
but->str = but->strdata;
but->flag |= UI_BUT_HAS_SEP_CHAR;
- ui_check_but(but);
+ ui_but_update(but);
}
}
@@ -948,7 +965,7 @@ static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *bu
found = true;
}
}
- else if ((mt = uiButGetMenuType(but))) {
+ else if ((mt = UI_but_menutype_get(but))) {
IDProperty *prop_menu;
IDProperty *prop_menu_name;
@@ -1147,7 +1164,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
}
}
-void uiBlockUpdateFromOld(const bContext *C, uiBlock *block)
+void UI_block_update_from_old(const bContext *C, uiBlock *block)
{
uiBut *but_old;
uiBut *but;
@@ -1163,20 +1180,19 @@ void uiBlockUpdateFromOld(const bContext *C, uiBlock *block)
for (but = block->buttons.first; but; but = but->next) {
if (ui_but_update_from_old_block(C, block, &but, &but_old)) {
- ui_check_but(but);
+ ui_but_update(but);
}
}
block->auto_open = block->oldblock->auto_open;
block->auto_open_last = block->oldblock->auto_open_last;
block->tooltipdisabled = block->oldblock->tooltipdisabled;
- copy_v3_v3(ui_block_hsv_get(block),
- ui_block_hsv_get(block->oldblock));
+ BLI_movelisttolist(&block->color_pickers.list, &block->oldblock->color_pickers.list);
block->oldblock = NULL;
}
-void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2])
+void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2])
{
wmWindow *window = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
@@ -1184,7 +1200,7 @@ void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2])
BLI_assert(block->active);
- uiBlockUpdateFromOld(C, block);
+ UI_block_update_from_old(C, block);
/* inherit flags from 'old' buttons that was drawn here previous, based
* on matching buttons, we need this to make button event handling non
@@ -1214,9 +1230,9 @@ void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2])
/* handle pending stuff */
if (block->layouts.first) {
- uiBlockLayoutResolve(block, NULL, NULL);
+ UI_block_layout_resolve(block, NULL, NULL);
}
- ui_block_do_align(block);
+ ui_block_align_calc(block);
if ((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) {
ui_menu_block_set_keyaccels(block); /* could use a different flag to check */
}
@@ -1230,40 +1246,40 @@ void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2])
case UI_BLOCK_BOUNDS_NONE:
break;
case UI_BLOCK_BOUNDS:
- ui_bounds_block(block);
+ ui_block_bounds_calc(block);
break;
case UI_BLOCK_BOUNDS_TEXT:
- ui_text_bounds_block(block, 0.0f);
+ ui_block_bounds_calc_text(block, 0.0f);
break;
case UI_BLOCK_BOUNDS_POPUP_CENTER:
- ui_centered_bounds_block(window, block);
+ ui_block_bounds_calc_centered(window, block);
break;
case UI_BLOCK_BOUNDS_PIE_CENTER:
- ui_centered_pie_bounds_block(block);
+ ui_block_bounds_calc_centered_pie(block);
break;
/* fallback */
case UI_BLOCK_BOUNDS_POPUP_MOUSE:
case UI_BLOCK_BOUNDS_POPUP_MENU:
- ui_popup_bounds_block(window, block, block->bounds_type, xy);
+ ui_block_bounds_calc_popup(window, block, block->bounds_type, xy);
break;
}
if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
- uiBoundsBlock(block, 0);
+ UI_block_bounds_set_normal(block, 0);
}
if (block->flag & UI_BUT_ALIGN) {
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
}
block->endblock = 1;
}
-void uiEndBlock(const bContext *C, uiBlock *block)
+void UI_block_end(const bContext *C, uiBlock *block)
{
wmWindow *window = CTX_wm_window(C);
- uiEndBlock_ex(C, block, &window->eventstate->x);
+ UI_block_end_ex(C, block, &window->eventstate->x);
}
/* ************** BLOCK DRAWING FUNCTION ************* */
@@ -1304,9 +1320,9 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u
}
/* uses local copy of style, to scale things down, and allow widgets to change stuff */
-void uiDrawBlock(const bContext *C, uiBlock *block)
+void UI_block_draw(const bContext *C, uiBlock *block)
{
- uiStyle style = *UI_GetStyleDraw(); /* XXX pass on as arg */
+ uiStyle style = *UI_style_get_dpi(); /* XXX pass on as arg */
ARegion *ar;
uiBut *but;
rcti rect;
@@ -1318,7 +1334,7 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
ar = CTX_wm_region(C);
if (!block->endblock)
- uiEndBlock(C, block);
+ UI_block_end(C, block);
/* disable AA, makes widgets too blurry */
multisample_enabled = glIsEnabled(GL_MULTISAMPLE_ARB);
@@ -1385,12 +1401,12 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
*
* \return (0 == UNSELECT), (1 == SELECT), (-1 == DO-NOTHING)
*/
-int ui_is_but_push_ex(uiBut *but, double *value)
+int ui_but_is_pushed_ex(uiBut *but, double *value)
{
int is_push = 0;
if (but->bit) {
- const bool state = ELEM(but->type, TOGN, ICONTOGN, OPTIONN) ? false : true;
+ const bool state = ELEM(but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N) ? false : true;
int lvalue;
UI_GET_BUT_VALUE_INIT(but, *value);
lvalue = (int)*value;
@@ -1403,27 +1419,27 @@ int ui_is_but_push_ex(uiBut *but, double *value)
}
else {
switch (but->type) {
- case BUT:
- case HOTKEYEVT:
- case KEYEVT:
- case COLOR:
+ case UI_BTYPE_BUT:
+ case UI_BTYPE_HOTKEY_EVENT:
+ case UI_BTYPE_KEY_EVENT:
+ case UI_BTYPE_COLOR:
is_push = -1;
break;
- case TOGBUT:
- case TOG:
- case ICONTOG:
- case OPTION:
+ case UI_BTYPE_BUT_TOGGLE:
+ case UI_BTYPE_TOGGLE:
+ case UI_BTYPE_ICON_TOGGLE:
+ case UI_BTYPE_CHECKBOX:
UI_GET_BUT_VALUE_INIT(but, *value);
if (*value != (double)but->hardmin) is_push = true;
break;
- case ICONTOGN:
- case TOGN:
- case OPTIONN:
+ case UI_BTYPE_ICON_TOGGLE_N:
+ case UI_BTYPE_TOGGLE_N:
+ case UI_BTYPE_CHECKBOX_N:
UI_GET_BUT_VALUE_INIT(but, *value);
if (*value == 0.0) is_push = true;
break;
- case ROW:
- case LISTROW:
+ case UI_BTYPE_ROW:
+ case UI_BTYPE_LISTROW:
UI_GET_BUT_VALUE_INIT(but, *value);
/* support for rna enum buts */
if (but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) {
@@ -1441,15 +1457,15 @@ int ui_is_but_push_ex(uiBut *but, double *value)
return is_push;
}
-int ui_is_but_push(uiBut *but)
+int ui_but_is_pushed(uiBut *but)
{
double value = UI_BUT_VALUE_UNSET;
- return ui_is_but_push_ex(but, &value);
+ return ui_but_is_pushed_ex(but, &value);
}
-static void ui_check_but_select(uiBut *but, double *value)
+static void ui_but_update_select_flag(uiBut *but, double *value)
{
- switch (ui_is_but_push_ex(but, value)) {
+ switch (ui_but_is_pushed_ex(but, value)) {
case true:
but->flag |= UI_SELECT;
break;
@@ -1459,13 +1475,13 @@ static void ui_check_but_select(uiBut *but, double *value)
}
}
-static uiBut *ui_find_inlink(uiBlock *block, void *poin)
+static uiBut *ui_linkline_find_inlink(uiBlock *block, void *poin)
{
uiBut *but;
but = block->buttons.first;
while (but) {
- if (but->type == INLINK) {
+ if (but->type == UI_BTYPE_INLINK) {
if (but->poin == poin) return but;
}
but = but->next;
@@ -1473,7 +1489,7 @@ static uiBut *ui_find_inlink(uiBlock *block, void *poin)
return NULL;
}
-static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt, short deactive)
+static void ui_linkline_add(ListBase *listb, uiBut *but, uiBut *bt, short deactive)
{
uiLinkLine *line;
@@ -1484,12 +1500,12 @@ static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt, short deact
line->deactive = deactive;
}
-uiBut *uiFindInlink(uiBlock *block, void *poin)
+uiBut *UI_block_links_find_inlink(uiBlock *block, void *poin)
{
- return ui_find_inlink(block, poin);
+ return ui_linkline_find_inlink(block, poin);
}
-void uiComposeLinks(uiBlock *block)
+void UI_block_links_compose(uiBlock *block)
{
uiBut *but, *bt;
uiLink *link;
@@ -1498,7 +1514,7 @@ void uiComposeLinks(uiBlock *block)
but = block->buttons.first;
while (but) {
- if (but->type == LINK) {
+ if (but->type == UI_BTYPE_LINK) {
link = but->link;
/* for all pointers in the array */
@@ -1506,26 +1522,26 @@ void uiComposeLinks(uiBlock *block)
if (link->ppoin) {
ppoin = link->ppoin;
for (a = 0; a < *(link->totlink); a++) {
- bt = ui_find_inlink(block, (*ppoin)[a]);
+ bt = ui_linkline_find_inlink(block, (*ppoin)[a]);
if (bt) {
if ((but->flag & UI_BUT_SCA_LINK_GREY) || (bt->flag & UI_BUT_SCA_LINK_GREY)) {
- ui_add_link_line(&link->lines, but, bt, true);
+ ui_linkline_add(&link->lines, but, bt, true);
}
else {
- ui_add_link_line(&link->lines, but, bt, false);
+ ui_linkline_add(&link->lines, but, bt, false);
}
}
}
}
else if (link->poin) {
- bt = ui_find_inlink(block, *link->poin);
+ bt = ui_linkline_find_inlink(block, *link->poin);
if (bt) {
if ((but->flag & UI_BUT_SCA_LINK_GREY) || (bt->flag & UI_BUT_SCA_LINK_GREY)) {
- ui_add_link_line(&link->lines, but, bt, true);
+ ui_linkline_add(&link->lines, but, bt, true);
}
else {
- ui_add_link_line(&link->lines, but, bt, false);
+ ui_linkline_add(&link->lines, but, bt, false);
}
}
}
@@ -1538,7 +1554,7 @@ void uiComposeLinks(uiBlock *block)
/* ************************************************ */
-void uiBlockSetButLock(uiBlock *block, bool val, const char *lockstr)
+void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr)
{
if (val) {
block->lock = val;
@@ -1546,7 +1562,7 @@ void uiBlockSetButLock(uiBlock *block, bool val, const char *lockstr)
}
}
-void uiBlockClearButLock(uiBlock *block)
+void UI_block_lock_clear(uiBlock *block)
{
block->lock = false;
block->lockstr = NULL;
@@ -1554,7 +1570,7 @@ void uiBlockClearButLock(uiBlock *block)
/* *************************************************************** */
-void ui_delete_linkline(uiLinkLine *line, uiBut *but)
+void ui_linkline_remove(uiLinkLine *line, uiBut *but)
{
uiLink *link;
int a, b;
@@ -1595,7 +1611,7 @@ void ui_delete_linkline(uiLinkLine *line, uiBut *but)
* an edit override pointer while dragging for example */
/* for buttons pointing to color for example */
-void ui_get_but_vectorf(uiBut *but, float vec[3])
+void ui_but_v3_get(uiBut *but, float vec[3])
{
PropertyRNA *prop;
int a;
@@ -1641,13 +1657,13 @@ void ui_get_but_vectorf(uiBut *but, float vec[3])
}
}
- if (but->type == BUT_NORMAL) {
+ if (but->type == UI_BTYPE_UNITVEC) {
normalize_v3(vec);
}
}
/* for buttons pointing to color for example */
-void ui_set_but_vectorf(uiBut *but, const float vec[3])
+void ui_but_v3_set(uiBut *but, const float vec[3])
{
PropertyRNA *prop;
@@ -1687,7 +1703,7 @@ void ui_set_but_vectorf(uiBut *but, const float vec[3])
}
}
-bool ui_is_but_float(const uiBut *but)
+bool ui_but_is_float(const uiBut *but)
{
if (but->pointype == UI_BUT_POIN_FLOAT && but->poin)
return true;
@@ -1698,28 +1714,31 @@ bool ui_is_but_float(const uiBut *but)
return false;
}
-bool ui_is_but_bool(const uiBut *but)
+bool ui_but_is_bool(const uiBut *but)
{
- if (ELEM(but->type, TOG, TOGN, ICONTOG, ICONTOGN))
+ if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE, UI_BTYPE_ICON_TOGGLE_N))
return true;
if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_BOOLEAN)
return true;
+ if ((but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) && (but->type == UI_BTYPE_ROW))
+ return true;
+
return false;
}
-bool ui_is_but_unit(const uiBut *but)
+bool ui_but_is_unit(const uiBut *but)
{
UnitSettings *unit = but->block->unit;
- const int unit_type = uiButGetUnitType(but);
+ const int unit_type = UI_but_unit_type_get(but);
if (unit_type == PROP_UNIT_NONE)
return false;
#if 1 /* removed so angle buttons get correct snapping */
- if (ui_is_but_unit_radians_ex(unit, unit_type))
+ if (ui_but_is_unit_radians_ex(unit, unit_type))
return false;
#endif
@@ -1739,7 +1758,7 @@ bool ui_is_but_unit(const uiBut *but)
/**
* Check if this button is similar enough to be grouped with another.
*/
-bool ui_is_but_compatible(const uiBut *but_a, const uiBut *but_b)
+bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b)
{
if (but_a->type != but_b->type)
return false;
@@ -1747,12 +1766,10 @@ bool ui_is_but_compatible(const uiBut *but_a, const uiBut *but_b)
return false;
if (but_a->rnaprop) {
+ /* skip 'rnapoin.data', 'rnapoin.id.data'
+ * allow different data to have the same props edited at once */
if (but_a->rnapoin.type != but_b->rnapoin.type)
return false;
- if (but_a->rnapoin.data != but_b->rnapoin.data)
- return false;
- if (but_a->rnapoin.id.data != but_b->rnapoin.id.data)
- return false;
if (RNA_property_type(but_a->rnaprop) != RNA_property_type(but_b->rnaprop))
return false;
if (RNA_property_subtype(but_a->rnaprop) != RNA_property_subtype(but_b->rnaprop))
@@ -1762,7 +1779,7 @@ bool ui_is_but_compatible(const uiBut *but_a, const uiBut *but_b)
return true;
}
-bool ui_is_but_rna_valid(uiBut *but)
+bool ui_but_is_rna_valid(uiBut *but)
{
if (but->rnaprop == NULL || RNA_struct_contains_property(&but->rnapoin, but->rnaprop)) {
return true;
@@ -1773,7 +1790,7 @@ bool ui_is_but_rna_valid(uiBut *but)
}
}
-double ui_get_but_val(uiBut *but)
+double ui_but_value_get(uiBut *but)
{
PropertyRNA *prop;
double value = 0.0;
@@ -1829,7 +1846,7 @@ double ui_get_but_val(uiBut *but)
return value;
}
-void ui_set_but_val(uiBut *but, double value)
+void ui_but_value_set(uiBut *but, double value)
{
PropertyRNA *prop;
@@ -1908,18 +1925,18 @@ void ui_set_but_val(uiBut *but, double value)
value = *((float *)but->poin) = (float)value;
}
- ui_check_but_select(but, &value);
+ ui_but_update_select_flag(but, &value);
}
-int ui_get_but_string_max_length(uiBut *but)
+int ui_but_string_get_max_length(uiBut *but)
{
- if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK))
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK))
return but->hardmax;
else
return UI_MAX_DRAW_STR;
}
-uiBut *ui_get_but_drag_multi_edit(uiBut *but)
+uiBut *ui_but_drag_multi_edit_get(uiBut *but)
{
uiBut *but_iter;
@@ -1937,7 +1954,7 @@ uiBut *ui_get_but_drag_multi_edit(uiBut *but)
static double ui_get_but_scale_unit(uiBut *but, double value)
{
UnitSettings *unit = but->block->unit;
- int unit_type = uiButGetUnitType(but);
+ int unit_type = UI_but_unit_type_get(but);
/* Time unit is a bit special, not handled by BKE_scene_unit_scale() for now. */
if (unit_type == PROP_UNIT_TIME) { /* WARNING - using evil_C :| */
@@ -1950,11 +1967,11 @@ static double ui_get_but_scale_unit(uiBut *but, double value)
}
/* str will be overwritten */
-void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen)
+void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen)
{
- if (ui_is_but_unit(but)) {
+ if (ui_but_is_unit(but)) {
UnitSettings *unit = but->block->unit;
- int unit_type = uiButGetUnitType(but);
+ int unit_type = UI_but_unit_type_get(but);
char *orig_str;
orig_str = BLI_strdup(str);
@@ -1972,7 +1989,7 @@ static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double va
{
UnitSettings *unit = but->block->unit;
const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0;
- int unit_type = uiButGetUnitType(but);
+ int unit_type = UI_but_unit_type_get(but);
int precision;
if (unit->scale_length < 0.0001f) unit->scale_length = 1.0f; // XXX do_versions
@@ -1994,7 +2011,7 @@ static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double va
static float ui_get_but_step_unit(uiBut *but, float step_default)
{
- int unit_type = RNA_SUBTYPE_UNIT_VALUE(uiButGetUnitType(but));
+ int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
double step;
step = bUnit_ClosestScalar(ui_get_but_scale_unit(but, step_default), but->block->unit->system, unit_type);
@@ -2012,9 +2029,9 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
/**
* \param float_precision For number buttons the precision to use or -1 to fallback to the button default.
*/
-void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision)
+void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision)
{
- if (but->rnaprop && ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
PropertyType type;
const char *buf = NULL;
int buf_len;
@@ -2051,12 +2068,12 @@ void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int
MEM_freeN((void *)buf);
}
}
- else if (but->type == TEX) {
+ else if (but->type == UI_BTYPE_TEXT) {
/* string */
BLI_strncpy(str, but->poin, maxlen);
return;
}
- else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ else if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
/* string */
BLI_strncpy(str, but->poin, maxlen);
return;
@@ -2068,14 +2085,14 @@ void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int
/* number editing */
double value;
- value = ui_get_but_val(but);
+ value = ui_but_value_get(but);
- if (ui_is_but_float(but)) {
- if (ui_is_but_unit(but)) {
+ if (ui_but_is_float(but)) {
+ if (ui_but_is_unit(but)) {
ui_get_but_string_unit(but, str, maxlen, value, false, float_precision);
}
else {
- const int prec = (float_precision == -1) ? ui_but_float_precision(but, value) : float_precision;
+ const int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision;
BLI_snprintf(str, maxlen, "%.*f", prec, value);
}
}
@@ -2083,9 +2100,9 @@ void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int
BLI_snprintf(str, maxlen, "%d", (int)value);
}
}
-void ui_get_but_string(uiBut *but, char *str, const size_t maxlen)
+void ui_but_string_get(uiBut *but, char *str, const size_t maxlen)
{
- ui_get_but_string_ex(but, str, maxlen, -1);
+ ui_but_string_get_ex(but, str, maxlen, -1);
}
#ifdef WITH_PYTHON
@@ -2093,7 +2110,7 @@ void ui_get_but_string(uiBut *but, char *str, const size_t maxlen)
static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char *str, double *value)
{
char str_unit_convert[256];
- const int unit_type = uiButGetUnitType(but);
+ const int unit_type = UI_but_unit_type_get(but);
BLI_strncpy(str_unit_convert, str, sizeof(str_unit_convert));
@@ -2108,14 +2125,14 @@ static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char
#endif /* WITH_PYTHON */
-bool ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double *value)
+bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *value)
{
bool ok = false;
#ifdef WITH_PYTHON
if (str[0] != '\0') {
- bool is_unit_but = (ui_is_but_float(but) && ui_is_but_unit(but));
+ bool is_unit_but = (ui_but_is_float(but) && ui_but_is_unit(but));
/* only enable verbose if we won't run again with units */
if (BPY_button_exec(C, str, value, is_unit_but == false) != -1) {
/* if the value parsed ok without unit conversion this button may still need a unit multiplier */
@@ -2148,10 +2165,36 @@ bool ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double
return ok;
}
+/* just the assignment/free part */
+static void ui_but_string_set_internal(uiBut *but, const char *str, size_t str_len)
+{
+ BLI_assert(str_len == strlen(str));
+ BLI_assert(but->str == NULL);
+ str_len += 1;
+
+ if (str_len > UI_MAX_NAME_STR) {
+ but->str = MEM_mallocN(str_len, "ui_def_but str");
+ }
+ else {
+ but->str = but->strdata;
+ }
+ memcpy(but->str, str, str_len);
+}
+
+static void ui_but_string_free_internal(uiBut *but)
+{
+ if (but->str) {
+ if (but->str != but->strdata) {
+ MEM_freeN(but->str);
+ }
+ /* must call 'ui_but_string_set_internal' after */
+ but->str = NULL;
+ }
+}
-bool ui_set_but_string(bContext *C, uiBut *but, const char *str)
+bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
{
- if (but->rnaprop && ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
if (RNA_property_editable(&but->rnapoin, but->rnaprop)) {
PropertyType type;
@@ -2196,14 +2239,14 @@ bool ui_set_but_string(bContext *C, uiBut *but, const char *str)
}
}
}
- else if (but->type == TEX) {
+ else if (but->type == UI_BTYPE_TEXT) {
/* string */
- if (ui_is_but_utf8(but)) BLI_strncpy_utf8(but->poin, str, but->hardmax);
+ if (ui_but_is_utf8(but)) BLI_strncpy_utf8(but->poin, str, but->hardmax);
else BLI_strncpy(but->poin, str, but->hardmax);
return true;
}
- else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ else if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
/* string */
BLI_strncpy(but->poin, str, but->hardmax);
return true;
@@ -2220,38 +2263,37 @@ bool ui_set_but_string(bContext *C, uiBut *but, const char *str)
/* number editing */
double value;
- if (ui_set_but_string_eval_num(C, but, str, &value) == false) {
+ if (ui_but_string_set_eval_num(C, but, str, &value) == false) {
return false;
}
- if (!ui_is_but_float(but)) value = (int)floor(value + 0.5);
+ if (!ui_but_is_float(but)) value = (int)floor(value + 0.5);
/* not that we use hard limits here */
if (value < (double)but->hardmin) value = but->hardmin;
if (value > (double)but->hardmax) value = but->hardmax;
- ui_set_but_val(but, value);
+ ui_but_value_set(but, value);
return true;
}
return false;
}
-void ui_set_but_default(bContext *C, const bool all, const bool use_afterfunc)
+void ui_but_default_set(bContext *C, const bool all, const bool use_afterfunc)
{
- const char *opstring = "UI_OT_reset_default_button";
+ wmOperatorType *ot = WM_operatortype_find("UI_OT_reset_default_button", true);
if (use_afterfunc) {
PointerRNA *ptr;
- wmOperatorType *ot = WM_operatortype_find(opstring, 0);
ptr = ui_handle_afterfunc_add_operator(ot, WM_OP_EXEC_DEFAULT, true);
RNA_boolean_set(ptr, "all", all);
}
else {
PointerRNA ptr;
- WM_operator_properties_create(&ptr, opstring);
+ WM_operator_properties_create_ptr(&ptr, ot);
RNA_boolean_set(&ptr, "all", all);
- WM_operator_name_call(C, opstring, WM_OP_EXEC_DEFAULT, &ptr);
+ WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &ptr);
WM_operator_properties_free(&ptr);
}
}
@@ -2367,7 +2409,7 @@ static void ui_set_but_soft_range(uiBut *but)
but->softmax = softmax;
}
else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) {
- float value = ui_get_but_val(but);
+ float value = ui_but_value_get(but);
CLAMP(value, but->hardmin, but->hardmax);
but->softmin = min_ff(but->softmin, value);
but->softmax = max_ff(but->softmax, value);
@@ -2388,7 +2430,7 @@ static void ui_free_link(uiLink *link)
}
/* can be called with C==NULL */
-static void ui_free_but(const bContext *C, uiBut *but)
+static void ui_but_free(const bContext *C, uiBut *but)
{
if (but->opptr) {
WM_operator_properties_free(but->opptr);
@@ -2399,12 +2441,16 @@ static void ui_free_but(const bContext *C, uiBut *but)
MEM_freeN(but->func_argN);
}
+ if (but->tip_argN) {
+ MEM_freeN(but->tip_argN);
+ }
+
if (but->active) {
/* XXX solve later, buttons should be free-able without context ideally,
* however they may have open tooltips or popup windows, which need to
* be closed using a context pointer */
if (C) {
- ui_button_active_free(C, but);
+ ui_but_active_free(C, but);
}
else {
if (but->active) {
@@ -2417,7 +2463,7 @@ static void ui_free_but(const bContext *C, uiBut *but)
}
ui_free_link(but->link);
- if ((but->type == BUT_IMAGE) && but->poin) {
+ if ((but->type == UI_BTYPE_IMAGE) && but->poin) {
IMB_freeImBuf((struct ImBuf *)but->poin);
}
@@ -2427,14 +2473,14 @@ static void ui_free_but(const bContext *C, uiBut *but)
}
/* can be called with C==NULL */
-void uiFreeBlock(const bContext *C, uiBlock *block)
+void UI_block_free(const bContext *C, uiBlock *block)
{
uiBut *but;
UI_butstore_clear(block);
while ((but = BLI_pophead(&block->buttons))) {
- ui_free_but(C, but);
+ ui_but_free(C, but);
}
if (block->unit) {
@@ -2448,21 +2494,22 @@ void uiFreeBlock(const bContext *C, uiBlock *block)
CTX_store_free_list(&block->contexts);
BLI_freelistN(&block->saferct);
+ BLI_freelistN(&block->color_pickers.list);
MEM_freeN(block);
}
/* can be called with C==NULL */
-void uiFreeBlocks(const bContext *C, ListBase *lb)
+void UI_blocklist_free(const bContext *C, ListBase *lb)
{
uiBlock *block;
while ((block = BLI_pophead(lb))) {
- uiFreeBlock(C, block);
+ UI_block_free(C, block);
}
}
-void uiFreeInactiveBlocks(const bContext *C, ListBase *lb)
+void UI_blocklist_free_inactive(const bContext *C, ListBase *lb)
{
uiBlock *block, *nextblock;
@@ -2472,7 +2519,7 @@ void uiFreeInactiveBlocks(const bContext *C, ListBase *lb)
if (!block->handle) {
if (!block->active) {
BLI_remlink(lb, block);
- uiFreeBlock(C, block);
+ UI_block_free(C, block);
}
else
block->active = 0;
@@ -2480,7 +2527,7 @@ void uiFreeInactiveBlocks(const bContext *C, ListBase *lb)
}
}
-void uiBlockSetRegion(uiBlock *block, ARegion *region)
+void UI_block_region_set(uiBlock *block, ARegion *region)
{
ListBase *lb = &region->uiblocks;
uiBlock *oldblock = NULL;
@@ -2503,7 +2550,7 @@ void uiBlockSetRegion(uiBlock *block, ARegion *region)
block->oldblock = oldblock;
}
-uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, short dt)
+uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, short dt)
{
uiBlock *block;
wmWindow *window;
@@ -2536,7 +2583,7 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor
BLI_strncpy(block->name, name, sizeof(block->name));
if (region)
- uiBlockSetRegion(block, region);
+ UI_block_region_set(block, region);
/* window matrix and aspect */
if (region && region->swinid) {
@@ -2560,23 +2607,23 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor
return block;
}
-uiBlock *uiGetBlock(const char *name, ARegion *ar)
+uiBlock *UI_block_find_in_region(const char *name, ARegion *ar)
{
return BLI_findstring(&ar->uiblocks, name, offsetof(uiBlock, name));
}
-void uiBlockSetEmboss(uiBlock *block, char dt)
+void UI_block_emboss_set(uiBlock *block, char dt)
{
block->dt = dt;
}
-void ui_check_but(uiBut *but)
+void ui_but_update(uiBut *but)
{
/* if something changed in the button */
double value = UI_BUT_VALUE_UNSET;
// float okwidth; // UNUSED
- ui_check_but_select(but, &value);
+ ui_but_update_select_flag(but, &value);
/* only update soft range while not editing */
if (!(but->editval || but->editstr || but->editvec)) {
@@ -2589,16 +2636,20 @@ void ui_check_but(uiBut *but)
/* test for min and max, icon sliders, etc */
switch (but->type) {
- case NUM:
- case SCROLL:
- case NUMSLI:
+ case UI_BTYPE_NUM:
+ case UI_BTYPE_SCROLL:
+ case UI_BTYPE_NUM_SLIDER:
UI_GET_BUT_VALUE_INIT(but, value);
- if (value < (double)but->hardmin) ui_set_but_val(but, but->hardmin);
- else if (value > (double)but->hardmax) ui_set_but_val(but, but->hardmax);
+ if (value < (double)but->hardmin) ui_but_value_set(but, but->hardmin);
+ else if (value > (double)but->hardmax) ui_but_value_set(but, but->hardmax);
+
+ /* max must never be smaller than min! Both being equal is allowed though */
+ BLI_assert(but->softmin <= but->softmax &&
+ but->hardmin <= but->hardmax);
break;
- case ICONTOG:
- case ICONTOGN:
+ case UI_BTYPE_ICON_TOGGLE:
+ case UI_BTYPE_ICON_TOGGLE_N:
if (!but->rnaprop || (RNA_property_flag(but->rnaprop) & PROP_ICONS_CONSECUTIVE)) {
if (but->flag & UI_SELECT) but->iconadd = 1;
else but->iconadd = 0;
@@ -2617,7 +2668,7 @@ void ui_check_but(uiBut *but)
/* name: */
switch (but->type) {
- case MENU:
+ case UI_BTYPE_MENU:
if (BLI_rctf_size_x(&but->rect) > 24.0f) {
/* only needed for menus in popup blocks that don't recreate buttons on redraw */
if (but->block->flag & UI_BLOCK_LOOP) {
@@ -2627,7 +2678,9 @@ void ui_check_but(uiBut *but)
if (RNA_property_enum_name_gettexted(but->block->evil_C,
&but->rnapoin, but->rnaprop, value, &buf))
{
- BLI_strncpy(but->str, buf, sizeof(but->strdata));
+ size_t slen = strlen(buf);
+ ui_but_string_free_internal(but);
+ ui_but_string_set_internal(but, buf, slen);
}
}
}
@@ -2635,8 +2688,8 @@ void ui_check_but(uiBut *but)
}
break;
- case NUM:
- case NUMSLI:
+ case UI_BTYPE_NUM:
+ case UI_BTYPE_NUM_SLIDER:
if (!but->editstr) {
const char *drawstr_suffix = NULL;
@@ -2646,7 +2699,7 @@ void ui_check_but(uiBut *but)
slen = BLI_strncpy_rlen(but->drawstr, but->str, sizeof(but->drawstr));
- if (ui_is_but_float(but)) {
+ if (ui_but_is_float(but)) {
if (value == (double) FLT_MAX) {
slen += BLI_strncpy_rlen(but->drawstr + slen, "inf", sizeof(but->drawstr) - slen);
}
@@ -2654,13 +2707,13 @@ void ui_check_but(uiBut *but)
slen += BLI_strncpy_rlen(but->drawstr + slen, "-inf", sizeof(but->drawstr) - slen);
}
/* support length type buttons */
- else if (ui_is_but_unit(but)) {
+ else if (ui_but_is_unit(but)) {
char new_str[sizeof(but->drawstr)];
ui_get_but_string_unit(but, new_str, sizeof(new_str), value, true, -1);
slen += BLI_strncpy_rlen(but->drawstr + slen, new_str, sizeof(but->drawstr) - slen);
}
else {
- const int prec = ui_but_float_precision(but, value);
+ const int prec = ui_but_calc_float_precision(but, value);
slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%.*f", prec, value);
}
}
@@ -2686,11 +2739,11 @@ void ui_check_but(uiBut *but)
}
break;
- case LABEL:
- if (ui_is_but_float(but)) {
+ case UI_BTYPE_LABEL:
+ if (ui_but_is_float(but)) {
int prec;
UI_GET_BUT_VALUE_INIT(but, value);
- prec = ui_but_float_precision(but, value);
+ prec = ui_but_calc_float_precision(but, value);
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
}
else {
@@ -2699,18 +2752,18 @@ void ui_check_but(uiBut *but)
break;
- case TEX:
- case SEARCH_MENU:
- case SEARCH_MENU_UNLINK:
+ case UI_BTYPE_TEXT:
+ case UI_BTYPE_SEARCH_MENU:
+ case UI_BTYPE_SEARCH_MENU_UNLINK:
if (!but->editstr) {
char str[UI_MAX_DRAW_STR];
- ui_get_but_string(but, str, UI_MAX_DRAW_STR);
+ ui_but_string_get(but, str, UI_MAX_DRAW_STR);
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, str);
}
break;
- case KEYEVT:
+ case UI_BTYPE_KEY_EVENT:
{
const char *str;
if (but->flag & UI_SELECT) {
@@ -2723,7 +2776,7 @@ void ui_check_but(uiBut *but)
BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str);
break;
}
- case HOTKEYEVT:
+ case UI_BTYPE_HOTKEY_EVENT:
if (but->flag & UI_SELECT) {
if (but->modifier_key) {
@@ -2750,8 +2803,8 @@ void ui_check_but(uiBut *but)
break;
- case HSVCUBE:
- case HSVCIRCLE:
+ case UI_BTYPE_HSVCUBE:
+ case UI_BTYPE_HSVCIRCLE:
break;
default:
BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
@@ -2767,10 +2820,10 @@ void ui_check_but(uiBut *but)
}
-void uiBlockBeginAlign(uiBlock *block)
+void UI_block_align_begin(uiBlock *block)
{
/* if other align was active, end it */
- if (block->flag & UI_BUT_ALIGN) uiBlockEndAlign(block);
+ if (block->flag & UI_BUT_ALIGN) UI_block_align_end(block);
block->flag |= UI_BUT_ALIGN_DOWN;
block->alignnr++;
@@ -2796,17 +2849,17 @@ static bool buts_are_horiz(uiBut *but1, uiBut *but2)
return (dx <= dy);
}
-void uiBlockEndAlign(uiBlock *block)
+void UI_block_align_end(uiBlock *block)
{
block->flag &= ~UI_BUT_ALIGN; /* all 4 flags */
}
bool ui_but_can_align(uiBut *but)
{
- return !ELEM(but->type, LABEL, OPTION, OPTIONN, SEPR, SEPRLINE);
+ return !ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE);
}
-static void ui_block_do_align_but(uiBut *first, short nr)
+static void ui_block_align_calc_but(uiBut *first, short nr)
{
uiBut *prev, *but = NULL, *next;
int flag = 0, cols = 0, rows = 0;
@@ -2946,7 +2999,7 @@ static void ui_block_do_align_but(uiBut *first, short nr)
}
}
-void ui_block_do_align(uiBlock *block)
+void ui_block_align_calc(uiBlock *block)
{
uiBut *but;
short nr;
@@ -2955,7 +3008,7 @@ void ui_block_do_align(uiBlock *block)
for (but = block->buttons.first; but; ) {
if (but->alignnr) {
nr = but->alignnr;
- ui_block_do_align_but(but, nr);
+ ui_block_align_calc_but(but, nr);
/* skip with same number */
for (; but && but->alignnr == nr; but = but->next) {
@@ -2972,21 +3025,21 @@ void ui_block_do_align(uiBlock *block)
}
}
-struct ColorManagedDisplay *ui_block_display_get(uiBlock *block)
+struct ColorManagedDisplay *ui_block_cm_display_get(uiBlock *block)
{
return IMB_colormanagement_display_get_named(block->display_device);
}
-void ui_block_to_display_space_v3(uiBlock *block, float pixel[3])
+void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3])
{
- struct ColorManagedDisplay *display = ui_block_display_get(block);
+ struct ColorManagedDisplay *display = ui_block_cm_display_get(block);
IMB_colormanagement_scene_linear_to_display_v3(pixel, display);
}
-void ui_block_to_scene_linear_v3(uiBlock *block, float pixel[3])
+void ui_block_cm_to_scene_linear_v3(uiBlock *block, float pixel[3])
{
- struct ColorManagedDisplay *display = ui_block_display_get(block);
+ struct ColorManagedDisplay *display = ui_block_cm_display_get(block);
IMB_colormanagement_display_to_scene_linear_v3(pixel, display);
}
@@ -3012,7 +3065,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
BLI_assert(width >= 0 && height >= 0);
/* we could do some more error checks here */
- if ((type & BUTTYPE) == LABEL) {
+ if ((type & BUTTYPE) == UI_BTYPE_LABEL) {
BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == false);
}
@@ -3035,13 +3088,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
but->retval = retval;
slen = strlen(str);
- if (slen >= UI_MAX_NAME_STR) {
- but->str = MEM_mallocN(slen + 1, "ui_def_but str");
- }
- else {
- but->str = but->strdata;
- }
- memcpy(but->str, str, slen + 1);
+ ui_but_string_set_internal(but, str, slen);
but->rect.xmin = x;
but->rect.ymin = y;
@@ -3075,7 +3122,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
but->pos = -1; /* cursor invisible */
- if (ELEM(but->type, NUM, NUMSLI)) { /* add a space to name */
+ if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { /* add a space to name */
/* slen remains unchanged from previous assignment, ensure this stays true */
if (slen > 0 && slen < UI_MAX_NAME_STR - 2) {
if (but->str[slen - 1] != ' ') {
@@ -3089,12 +3136,15 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT);
}
else if ((block->flag & UI_BLOCK_LOOP) ||
- ELEM(but->type, MENU, TEX, LABEL, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK))
+ ELEM(but->type,
+ UI_BTYPE_MENU, UI_BTYPE_TEXT, UI_BTYPE_LABEL,
+ UI_BTYPE_BLOCK, UI_BTYPE_BUT_MENU, UI_BTYPE_SEARCH_MENU,
+ UI_BTYPE_PROGRESS_BAR, UI_BTYPE_SEARCH_MENU_UNLINK))
{
but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT);
}
#ifdef USE_NUMBUTS_LR_ALIGN
- else if (ELEM(but->type, NUM, NUMSLI)) {
+ else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {
but->drawflag |= UI_BUT_TEXT_LEFT;
}
#endif
@@ -3108,9 +3158,18 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
}
/* keep track of UI_interface.h */
- if (ELEM(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR, SEPRLINE, GRIP)) {}
- else if (but->type >= SEARCH_MENU) {}
- else but->flag |= UI_BUT_UNDO;
+ if (ELEM(but->type,
+ UI_BTYPE_BLOCK, UI_BTYPE_BUT, UI_BTYPE_LABEL,
+ UI_BTYPE_PULLDOWN, UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX,
+ UI_BTYPE_BUT_MENU, UI_BTYPE_SCROLL, UI_BTYPE_GRIP,
+ UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE) ||
+ (but->type >= UI_BTYPE_SEARCH_MENU))
+ {
+ /* pass */
+ }
+ else {
+ but->flag |= UI_BUT_UNDO;
+ }
BLI_addtail(&block->buttons, but);
@@ -3151,13 +3210,13 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
int column_start = 0, column_end = 0;
int nbr_entries_nosepr = 0;
- uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
+ UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
RNA_property_enum_items_gettexted(block->evil_C, &but->rnapoin, but->rnaprop, &item_array, NULL, &free);
/* we dont want nested rows, cols in menus */
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
for (item = item_array; item->identifier; item++, totitems++) {
if (!item->identifier[0]) {
@@ -3186,7 +3245,7 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
rows++;
/* Title */
- uiDefBut(block, LABEL, 0, RNA_property_ui_name(but->rnaprop),
+ uiDefBut(block, UI_BTYPE_LABEL, 0, RNA_property_ui_name(but->rnaprop),
0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
uiItemS(layout);
@@ -3229,7 +3288,7 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
}
else {
/* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */
- uiDefBut(block, LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
}
else {
@@ -3238,21 +3297,24 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
}
else {
if (item->icon) {
- uiDefIconTextButI(block, BUTM, B_NOP, item->icon, item->name, 0, 0,
+ uiDefIconTextButI(block, UI_BTYPE_BUT_MENU, B_NOP, item->icon, item->name, 0, 0,
UI_UNIT_X * 5, UI_UNIT_Y, &handle->retvalue, item->value, 0.0, 0, -1, item->description);
}
else {
- uiDefButI(block, BUTM, B_NOP, item->name, 0, 0,
+ uiDefButI(block, UI_BTYPE_BUT_MENU, B_NOP, item->name, 0, 0,
UI_UNIT_X * 5, UI_UNIT_X, &handle->retvalue, item->value, 0.0, 0, -1, item->description);
}
}
}
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
if (free) {
MEM_freeN(item_array);
}
+
+ BLI_assert((block->flag & UI_BLOCK_IS_FLIP) == 0);
+ block->flag |= UI_BLOCK_IS_FLIP;
}
/**
@@ -3273,13 +3335,13 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
int icon = 0;
uiMenuCreateFunc func = NULL;
- if (ELEM(type, COLOR, HSVCIRCLE, HSVCUBE)) {
+ if (ELEM(type, UI_BTYPE_COLOR, UI_BTYPE_HSVCIRCLE, UI_BTYPE_HSVCUBE)) {
BLI_assert(index == -1);
}
/* use rna values if parameters are not specified */
- if ((proptype == PROP_ENUM) && ELEM(type, MENU, ROW, LISTROW)) {
- /* MENU is handled a little differently here */
+ if ((proptype == PROP_ENUM) && ELEM(type, UI_BTYPE_MENU, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
+ /* UI_BTYPE_MENU is handled a little differently here */
EnumPropertyItem *item;
int value;
bool free;
@@ -3287,7 +3349,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
RNA_property_enum_items(block->evil_C, ptr, prop, &item, NULL, &free);
- if (type == MENU) {
+ if (type == UI_BTYPE_MENU) {
value = RNA_property_enum_get(ptr, prop);
}
else {
@@ -3308,7 +3370,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
}
else {
if (!str) {
- if (type == MENU) {
+ if (type == UI_BTYPE_MENU) {
str = "";
}
else {
@@ -3317,7 +3379,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
}
}
- if (type == MENU) {
+ if (type == UI_BTYPE_MENU) {
func = ui_def_but_rna__menu;
}
@@ -3342,7 +3404,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
RNA_property_int_range(ptr, prop, &hardmin, &hardmax);
RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step);
- if (!ELEM(type, ROW, LISTROW) && min == max) {
+ if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) {
min = hardmin;
max = hardmax;
}
@@ -3357,7 +3419,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
- if (!ELEM(type, ROW, LISTROW) && min == max) {
+ if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) {
min = hardmin;
max = hardmax;
}
@@ -3393,20 +3455,20 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
}
}
- if ((type == MENU) && (but->dt == UI_EMBOSSP)) {
- but->flag |= UI_ICON_SUBMENU;
+ if ((type == UI_BTYPE_MENU) && (but->dt == UI_EMBOSS_PULLDOWN)) {
+ but->flag |= UI_BUT_ICON_SUBMENU;
}
if (!RNA_property_editable(&but->rnapoin, prop)) {
ui_def_but_rna__disable(but);
}
- if (but->flag & UI_BUT_UNDO && (ui_is_but_rna_undo(but) == false)) {
+ if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == false)) {
but->flag &= ~UI_BUT_UNDO;
}
/* If this button uses units, calculate the step from this */
- if ((proptype == PROP_FLOAT) && ui_is_but_unit(but)) {
+ if ((proptype == PROP_FLOAT) && ui_but_is_unit(but)) {
but->a1 = ui_get_but_step_unit(but, but->a1);
}
@@ -3453,7 +3515,7 @@ static uiBut *ui_def_but_operator_ptr(uiBlock *block, int type, wmOperatorType *
but = ui_def_but(block, type, -1, str, x, y, width, height, NULL, 0, 0, 0, 0, tip);
but->optype = ot;
but->opcontext = opcontext;
- but->flag &= ~UI_BUT_UNDO; /* no need for ui_is_but_rna_undo(), we never need undo here */
+ but->flag &= ~UI_BUT_UNDO; /* no need for ui_but_is_rna_undo(), we never need undo here */
if (!ot) {
but->flag |= UI_BUT_DISABLED;
@@ -3468,7 +3530,7 @@ uiBut *uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, in
{
uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip);
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
@@ -3508,7 +3570,7 @@ struct AutoComplete {
const char *startname;
};
-AutoComplete *autocomplete_begin(const char *startname, size_t maxlen)
+AutoComplete *UI_autocomplete_begin(const char *startname, size_t maxlen)
{
AutoComplete *autocpl;
@@ -3521,7 +3583,7 @@ AutoComplete *autocomplete_begin(const char *startname, size_t maxlen)
return autocpl;
}
-void autocomplete_do_name(AutoComplete *autocpl, const char *name)
+void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name)
{
char *truncate = autocpl->truncate;
const char *startname = autocpl->startname;
@@ -3551,7 +3613,7 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name)
}
}
-int autocomplete_end(AutoComplete *autocpl, char *autoname)
+int UI_autocomplete_end(AutoComplete *autocpl, char *autoname)
{
int match = AUTOCOMPLETE_NO_MATCH;
if (autocpl->truncate[0]) {
@@ -3574,14 +3636,14 @@ int autocomplete_end(AutoComplete *autocpl, char *autoname)
return match;
}
-static void ui_check_but_and_iconize(uiBut *but, int icon)
+static void ui_but_update_and_icon_set(uiBut *but, int icon)
{
if (icon) {
but->icon = (BIFIconID) icon;
but->flag |= UI_HAS_ICON;
}
- ui_check_but(but);
+ ui_but_update(but);
}
static uiBut *uiDefButBit(uiBlock *block, int type, int bit, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
@@ -3630,14 +3692,14 @@ uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x, i
{
uiBut *but;
but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but;
but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
@@ -3645,7 +3707,7 @@ uiBut *uiDefButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext
{
uiBut *but;
but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip);
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip)
@@ -3659,7 +3721,7 @@ uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, co
uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but = ui_def_but(block, type, retval, "", x, y, width, height, poin, min, max, a1, a2, tip);
- ui_check_but_and_iconize(but, icon);
+ ui_but_update_and_icon_set(but, icon);
return but;
}
static uiBut *uiDefIconButBit(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
@@ -3709,14 +3771,14 @@ uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x, int
{
uiBut *but;
but = ui_def_but_rna_propname(block, type, retval, "", x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
- ui_check_but_and_iconize(but, icon);
+ ui_but_update_and_icon_set(but, icon);
return but;
}
uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but;
but = ui_def_but_rna(block, type, retval, "", x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
- ui_check_but_and_iconize(but, icon);
+ ui_but_update_and_icon_set(but, icon);
return but;
}
@@ -3724,7 +3786,7 @@ uiBut *uiDefIconButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcon
{
uiBut *but;
but = ui_def_but_operator_ptr(block, type, ot, opcontext, "", x, y, width, height, tip);
- ui_check_but_and_iconize(but, icon);
+ ui_but_update_and_icon_set(but, icon);
return but;
}
uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x, int y, short width, short height, const char *tip)
@@ -3737,7 +3799,7 @@ uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext
uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip);
- ui_check_but_and_iconize(but, icon);
+ ui_but_update_and_icon_set(but, icon);
but->drawflag |= UI_BUT_ICON_LEFT;
return but;
}
@@ -3788,7 +3850,7 @@ uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const c
{
uiBut *but;
but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
- ui_check_but_and_iconize(but, icon);
+ ui_but_update_and_icon_set(but, icon);
but->drawflag |= UI_BUT_ICON_LEFT;
return but;
}
@@ -3796,7 +3858,7 @@ uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, co
{
uiBut *but;
but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
- ui_check_but_and_iconize(but, icon);
+ ui_but_update_and_icon_set(but, icon);
but->drawflag |= UI_BUT_ICON_LEFT;
return but;
}
@@ -3804,7 +3866,7 @@ uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int o
{
uiBut *but;
but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip);
- ui_check_but_and_iconize(but, icon);
+ ui_but_update_and_icon_set(but, icon);
but->drawflag |= UI_BUT_ICON_LEFT;
return but;
}
@@ -3816,7 +3878,7 @@ uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcon
/* END Button containing both string label and icon */
-void uiSetButLink(uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to)
+void UI_but_link_set(uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to)
{
uiLink *link;
@@ -3831,7 +3893,7 @@ void uiSetButLink(uiBut *but, void **poin, void ***ppoin, short *tot, int from,
/* cruft to make uiBlock and uiBut private */
-int uiBlocksGetYMin(ListBase *lb)
+int UI_blocklist_min_y_get(ListBase *lb)
{
uiBlock *block;
int min = 0;
@@ -3843,13 +3905,13 @@ int uiBlocksGetYMin(ListBase *lb)
return min;
}
-void uiBlockSetDirection(uiBlock *block, char direction)
+void UI_block_direction_set(uiBlock *block, char direction)
{
block->direction = direction;
}
/* this call escapes if there's alignment flags */
-void uiBlockFlipOrder(uiBlock *block)
+void UI_block_order_flip(uiBlock *block)
{
uiBut *but;
float centy, miny = 10000, maxy = -10000;
@@ -3871,83 +3933,85 @@ void uiBlockFlipOrder(uiBlock *block)
but->rect.ymax = centy - (but->rect.ymax - centy);
SWAP(float, but->rect.ymin, but->rect.ymax);
}
+
+ block->flag ^= UI_BLOCK_IS_FLIP;
}
-void uiBlockSetFlag(uiBlock *block, int flag)
+void UI_block_flag_enable(uiBlock *block, int flag)
{
block->flag |= flag;
}
-void uiBlockClearFlag(uiBlock *block, int flag)
+void UI_block_flag_disable(uiBlock *block, int flag)
{
block->flag &= ~flag;
}
-void uiButSetFlag(uiBut *but, int flag)
+void UI_but_flag_enable(uiBut *but, int flag)
{
but->flag |= flag;
}
-void uiButClearFlag(uiBut *but, int flag)
+void UI_but_flag_disable(uiBut *but, int flag)
{
but->flag &= ~flag;
}
-void uiButSetDrawFlag(uiBut *but, int flag)
+void UI_but_drawflag_enable(uiBut *but, int flag)
{
but->drawflag |= flag;
}
-void uiButClearDrawFlag(uiBut *but, int flag)
+void UI_but_drawflag_disable(uiBut *but, int flag)
{
but->drawflag &= ~flag;
}
-void uiButSetMenuFromPulldown(uiBut *but)
+void UI_but_type_set_menu_from_pulldown(uiBut *but)
{
- BLI_assert(but->type == PULLDOWN);
- but->type = MENU;
- uiButClearDrawFlag(but, UI_BUT_TEXT_RIGHT);
- uiButSetDrawFlag(but, UI_BUT_TEXT_LEFT);
+ BLI_assert(but->type == UI_BTYPE_PULLDOWN);
+ but->type = UI_BTYPE_MENU;
+ UI_but_drawflag_disable(but, UI_BUT_TEXT_RIGHT);
+ UI_but_drawflag_enable(but, UI_BUT_TEXT_LEFT);
}
-int uiButGetRetVal(uiBut *but)
+int UI_but_return_value_get(uiBut *but)
{
return but->retval;
}
-void uiButSetDragID(uiBut *but, ID *id)
+void UI_but_drag_set_id(uiBut *but, ID *id)
{
but->dragtype = WM_DRAG_ID;
but->dragpoin = (void *)id;
}
-void uiButSetDragRNA(uiBut *but, PointerRNA *ptr)
+void UI_but_drag_set_rna(uiBut *but, PointerRNA *ptr)
{
but->dragtype = WM_DRAG_RNA;
but->dragpoin = (void *)ptr;
}
-void uiButSetDragPath(uiBut *but, const char *path)
+void UI_but_drag_set_path(uiBut *but, const char *path)
{
but->dragtype = WM_DRAG_PATH;
but->dragpoin = (void *)path;
}
-void uiButSetDragName(uiBut *but, const char *name)
+void UI_but_drag_set_name(uiBut *but, const char *name)
{
but->dragtype = WM_DRAG_NAME;
but->dragpoin = (void *)name;
}
/* value from button itself */
-void uiButSetDragValue(uiBut *but)
+void UI_but_drag_set_value(uiBut *but)
{
but->dragtype = WM_DRAG_VALUE;
}
-void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale)
+void UI_but_drag_set_image(uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale)
{
but->dragtype = WM_DRAG_PATH;
but->icon = icon; /* no flag UI_HAS_ICON, so icon doesnt draw in button */
@@ -3956,7 +4020,7 @@ void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *imb
but->imb_scale = scale;
}
-PointerRNA *uiButGetOperatorPtrRNA(uiBut *but)
+PointerRNA *UI_but_operator_ptr_get(uiBut *but)
{
if (but->optype && !but->opptr) {
but->opptr = MEM_callocN(sizeof(PointerRNA), "uiButOpPtr");
@@ -3966,12 +4030,12 @@ PointerRNA *uiButGetOperatorPtrRNA(uiBut *but)
return but->opptr;
}
-void uiButSetUnitType(uiBut *but, const int unit_type)
+void UI_but_unit_type_set(uiBut *but, const int unit_type)
{
but->unit_type = (unsigned char)(RNA_SUBTYPE_UNIT_VALUE(unit_type));
}
-int uiButGetUnitType(const uiBut *but)
+int UI_but_unit_type_get(const uiBut *but)
{
int ownUnit = (int)but->unit_type;
@@ -3987,26 +4051,26 @@ int uiButGetUnitType(const uiBut *but)
}
}
-void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg)
+void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg)
{
block->handle_func = func;
block->handle_func_arg = arg;
}
-void uiBlockSetButmFunc(uiBlock *block, uiMenuHandleFunc func, void *arg)
+void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg)
{
block->butm_func = func;
block->butm_func_arg = arg;
}
-void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2)
+void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2)
{
block->func = func;
block->func_arg1 = arg1;
block->func_arg2 = arg2;
}
-void uiBlockSetNFunc(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2)
+void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2)
{
if (block->func_argN) {
MEM_freeN(block->func_argN);
@@ -4017,27 +4081,27 @@ void uiBlockSetNFunc(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *a
block->func_arg2 = arg2;
}
-void uiButSetRenameFunc(uiBut *but, uiButHandleRenameFunc func, void *arg1)
+void UI_but_func_rename_set(uiBut *but, uiButHandleRenameFunc func, void *arg1)
{
but->rename_func = func;
but->rename_arg1 = arg1;
}
-void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(const bContext *C, void *idv, void *arg1, void *arg2, rcti *rect), void *arg1, void *arg2)
+void UI_but_func_drawextra_set(uiBlock *block, void (*func)(const bContext *C, void *idv, void *arg1, void *arg2, rcti *rect), void *arg1, void *arg2)
{
block->drawextra = func;
block->drawextra_arg1 = arg1;
block->drawextra_arg2 = arg2;
}
-void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
+void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
{
but->func = func;
but->func_arg1 = arg1;
but->func_arg2 = arg2;
}
-void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
+void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
{
if (but->func_argN) {
MEM_freeN(but->func_argN);
@@ -4048,75 +4112,84 @@ void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
but->func_arg2 = arg2;
}
-void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg)
+void UI_but_func_complete_set(uiBut *but, uiButCompleteFunc func, void *arg)
{
but->autocomplete_func = func;
but->autofunc_arg = arg;
}
+void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN)
+{
+ but->tip_func = func;
+ if (but->tip_argN) {
+ MEM_freeN(but->tip_argN);
+ }
+ but->tip_argN = argN;
+}
+
uiBut *uiDefBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip)
{
- uiBut *but = ui_def_but(block, BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
but->block_create_func = func;
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
uiBut *uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, const char *str, int x, int y, short width, short height, const char *tip)
{
- uiBut *but = ui_def_but(block, BLOCK, 0, str, x, y, width, height, NULL, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, NULL, 0.0, 0.0, 0.0, 0.0, tip);
but->block_create_func = func;
if (but->func_argN) {
MEM_freeN(but->func_argN);
}
but->func_argN = argN;
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip)
{
- uiBut *but = ui_def_but(block, PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
but->block_create_func = func;
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip)
{
- uiBut *but = ui_def_but(block, PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
but->menu_create_func = func;
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip)
{
- uiBut *but = ui_def_but(block, PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
but->icon = (BIFIconID) icon;
but->flag |= UI_HAS_ICON;
but->drawflag |= UI_BUT_ICON_LEFT;
- but->flag |= UI_ICON_SUBMENU;
+ but->flag |= UI_BUT_ICON_SUBMENU;
but->menu_create_func = func;
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, int x, int y, short width, short height, const char *tip)
{
- uiBut *but = ui_def_but(block, PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
but->icon = (BIFIconID) icon;
but->flag |= UI_HAS_ICON;
but->drawflag &= ~UI_BUT_ICON_LEFT;
but->menu_create_func = func;
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
@@ -4124,18 +4197,18 @@ uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int ic
/* Block button containing both string label and icon */
uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip)
{
- uiBut *but = ui_def_but(block, BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
- /* XXX temp, old menu calls pass on icon arrow, which is now UI_ICON_SUBMENU flag */
+ /* XXX temp, old menu calls pass on icon arrow, which is now UI_BUT_ICON_SUBMENU flag */
if (icon != ICON_RIGHTARROW_THIN) {
but->icon = (BIFIconID) icon;
but->drawflag |= UI_BUT_ICON_LEFT;
}
but->flag |= UI_HAS_ICON;
- but->flag |= UI_ICON_SUBMENU;
+ but->flag |= UI_BUT_ICON_SUBMENU;
but->block_create_func = func;
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
@@ -4143,7 +4216,7 @@ uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg,
/* Block button containing icon */
uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int retval, int icon, int x, int y, short width, short height, const char *tip)
{
- uiBut *but = ui_def_but(block, BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
but->icon = (BIFIconID) icon;
but->flag |= UI_HAS_ICON;
@@ -4151,15 +4224,15 @@ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int
but->drawflag |= UI_BUT_ICON_LEFT;
but->block_create_func = func;
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
uiBut *uiDefKeyevtButS(uiBlock *block, int retval, const char *str, int x, int y, short width, short height, short *spoin, const char *tip)
{
- uiBut *but = ui_def_but(block, KEYEVT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, spoin, 0.0, 0.0, 0.0, 0.0, tip);
- ui_check_but(but);
+ uiBut *but = ui_def_but(block, UI_BTYPE_KEY_EVENT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, spoin, 0.0, 0.0, 0.0, 0.0, tip);
+ ui_but_update(but);
return but;
}
@@ -4167,25 +4240,25 @@ uiBut *uiDefKeyevtButS(uiBlock *block, int retval, const char *str, int x, int y
/* modkeypoin will be set to KM_SHIFT, KM_ALT, KM_CTRL, KM_OSKEY bits */
uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, const char *str, int x, int y, short width, short height, short *keypoin, short *modkeypoin, const char *tip)
{
- uiBut *but = ui_def_but(block, HOTKEYEVT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, keypoin, 0.0, 0.0, 0.0, 0.0, tip);
+ uiBut *but = ui_def_but(block, UI_BTYPE_HOTKEY_EVENT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, keypoin, 0.0, 0.0, 0.0, 0.0, tip);
but->modifier_key = *modkeypoin;
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
-/* arg is pointer to string/name, use uiButSetSearchFunc() below to make this work */
+/* arg is pointer to string/name, use UI_but_func_search_set() below to make this work */
/* here a1 and a2, if set, control thumbnail preview rows/cols */
uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, int x, int y, short width, short height, float a1, float a2, const char *tip)
{
- uiBut *but = ui_def_but(block, SEARCH_MENU, retval, "", x, y, width, height, arg, 0.0, maxlen, a1, a2, tip);
+ uiBut *but = ui_def_but(block, UI_BTYPE_SEARCH_MENU, retval, "", x, y, width, height, arg, 0.0, maxlen, a1, a2, tip);
but->icon = (BIFIconID) icon;
but->flag |= UI_HAS_ICON;
but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
- ui_check_but(but);
+ ui_but_update(but);
return but;
}
@@ -4193,18 +4266,18 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle
/* arg is user value, searchfunc and handlefunc both get it as arg */
/* if active set, button opens with this item visible and selected */
-void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc, void *active)
+void UI_but_func_search_set(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc, void *active)
{
but->search_func = sfunc;
but->search_arg = arg;
- uiButSetFunc(but, bfunc, arg, active);
+ UI_but_func_set(but, bfunc, arg, active);
/* search buttons show red-alert if item doesn't exist, not for menus */
if (0 == (but->block->flag & UI_BLOCK_LOOP)) {
/* skip empty buttons, not all buttons need input, we only show invalid */
if (but->drawstr[0])
- ui_but_search_test(but);
+ ui_but_search_refresh(but);
}
}
@@ -4223,7 +4296,7 @@ static void operator_enum_search_cb(const struct bContext *C, void *but, const c
__func__, ot->idname, RNA_property_identifier(prop));
}
else {
- PointerRNA *ptr = uiButGetOperatorPtrRNA(but); /* Will create it if needed! */
+ PointerRNA *ptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */
EnumPropertyItem *item, *item_array;
bool do_free;
@@ -4232,7 +4305,7 @@ static void operator_enum_search_cb(const struct bContext *C, void *but, const c
for (item = item_array; item->identifier; item++) {
/* note: need to give the index rather than the identifier because the enum can be freed */
if (BLI_strcasestr(item->name, str)) {
- if (false == uiSearchItemAdd(items, item->name, SET_INT_IN_POINTER(item->value), 0))
+ if (false == UI_search_item_add(items, item->name, SET_INT_IN_POINTER(item->value), 0))
break;
}
}
@@ -4245,7 +4318,7 @@ static void operator_enum_search_cb(const struct bContext *C, void *but, const c
static void operator_enum_call_cb(struct bContext *UNUSED(C), void *but, void *arg2)
{
wmOperatorType *ot = ((uiBut *)but)->optype;
- PointerRNA *opptr = uiButGetOperatorPtrRNA(but); /* Will create it if needed! */
+ PointerRNA *opptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */
if (ot) {
if (ot->prop) {
@@ -4270,13 +4343,13 @@ uiBut *uiDefSearchButO_ptr(uiBlock *block, wmOperatorType *ot, IDProperty *prope
uiBut *but;
but = uiDefSearchBut(block, arg, retval, icon, maxlen, x, y, width, height, a1, a2, tip);
- uiButSetSearchFunc(but, operator_enum_search_cb, but, operator_enum_call_cb, NULL);
+ UI_but_func_search_set(but, operator_enum_search_cb, but, operator_enum_call_cb, NULL);
but->optype = ot;
but->opcontext = WM_OP_EXEC_DEFAULT;
if (properties) {
- PointerRNA *ptr = uiButGetOperatorPtrRNA(but);
+ PointerRNA *ptr = UI_but_operator_ptr_get(but);
/* Copy idproperties. */
ptr->data = IDP_CopyProperty(properties);
}
@@ -4287,7 +4360,7 @@ uiBut *uiDefSearchButO_ptr(uiBlock *block, wmOperatorType *ot, IDProperty *prope
/* push a new event onto event queue to activate the given button
* (usually a text-field) upon entering a popup
*/
-void uiButSetFocusOnEnter(wmWindow *win, uiBut *but)
+void UI_but_focus_on_enter_event(wmWindow *win, uiBut *but)
{
wmEvent event;
@@ -4301,7 +4374,7 @@ void uiButSetFocusOnEnter(wmWindow *win, uiBut *but)
wm_event_add(win, &event);
}
-void uiButGetStrInfo(bContext *C, uiBut *but, ...)
+void UI_but_string_info_get(bContext *C, uiBut *but, ...)
{
va_list args;
uiStringInfo *si;
@@ -4324,7 +4397,10 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...)
}
}
else if (type == BUT_GET_TIP) {
- if (but->tip && but->tip[0])
+ if (but->tip_func) {
+ tmp = but->tip_func(C, but->tip_argN, but->tip);
+ }
+ else if (but->tip && but->tip[0])
tmp = BLI_strdup(but->tip);
else
type = BUT_GET_RNA_TIP; /* Fail-safe solution... */
@@ -4339,8 +4415,8 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...)
tmp = BLI_strdup(RNA_struct_identifier(but->rnapoin.type));
else if (but->optype)
tmp = BLI_strdup(but->optype->idname);
- else if (ELEM(but->type, MENU, PULLDOWN)) {
- MenuType *mt = uiButGetMenuType(but);
+ else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
+ MenuType *mt = UI_but_menutype_get(but);
if (mt)
tmp = BLI_strdup(mt->idname);
}
@@ -4364,8 +4440,8 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...)
tmp = BLI_strdup(t);
}
}
- else if (ELEM(but->type, MENU, PULLDOWN)) {
- MenuType *mt = uiButGetMenuType(but);
+ else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
+ MenuType *mt = UI_but_menutype_get(but);
if (mt) {
/* not all menus are from python */
if (mt->ext.srna) {
@@ -4386,8 +4462,8 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...)
_tmp = RNA_property_translation_context(but->rnaprop);
else if (but->optype)
_tmp = RNA_struct_translation_context(but->optype->srna);
- else if (ELEM(but->type, MENU, PULLDOWN)) {
- MenuType *mt = uiButGetMenuType(but);
+ else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
+ MenuType *mt = UI_but_menutype_get(but);
if (mt)
_tmp = RNA_struct_translation_context(mt->ext.srna);
}
@@ -4406,10 +4482,10 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...)
/* enum property */
ptr = &but->rnapoin;
prop = but->rnaprop;
- value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but);
+ value = (but->type == UI_BTYPE_ROW) ? (int)but->hardmax : (int)ui_but_value_get(but);
}
else if (but->optype) {
- PointerRNA *opptr = uiButGetOperatorPtrRNA(but);
+ PointerRNA *opptr = UI_but_operator_ptr_get(but);
wmOperatorType *ot = but->optype;
/* if the default property of the operator is enum and it is set,
@@ -4494,6 +4570,6 @@ void UI_reinit_font(void)
void UI_exit(void)
{
ui_resources_free();
- ui_button_clipboard_free();
+ ui_but_clipboard_free();
}
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 48e54270e95..24a30ebe3d8 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -34,15 +34,14 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_animsys.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
+#include "BKE_nla.h"
#include "ED_keyframing.h"
@@ -55,28 +54,37 @@
#include "interface_intern.h"
-static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, bool *r_driven)
+static FCurve *ui_but_get_fcurve(uiBut *but, AnimData **adt, bAction **action, bool *r_driven)
{
/* for entire array buttons we check the first component, it's not perfect
* but works well enough in typical cases */
int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
- return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
+ return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven);
}
void ui_but_anim_flag(uiBut *but, float cfra)
{
+ AnimData *adt;
+ bAction *act;
FCurve *fcu;
bool driven;
but->flag &= ~(UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN);
- fcu = ui_but_get_fcurve(but, NULL, &driven);
+ fcu = ui_but_get_fcurve(but, &adt, &act, &driven);
if (fcu) {
if (!driven) {
but->flag |= UI_BUT_ANIMATED;
+ /* T41525 - When the active action is a NLA strip being edited,
+ * we need to correct the frame number to "look inside" the
+ * remapped action
+ */
+ if (adt)
+ cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
+
if (fcurve_frame_has_keyframe(fcu, cfra, 0))
but->flag |= UI_BUT_ANIMATED_KEY;
}
@@ -92,7 +100,7 @@ bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen)
ChannelDriver *driver;
bool driven;
- fcu = ui_but_get_fcurve(but, NULL, &driven);
+ fcu = ui_but_get_fcurve(but, NULL, NULL, &driven);
if (fcu && driven) {
driver = fcu->driver;
@@ -112,7 +120,7 @@ bool ui_but_anim_expression_set(uiBut *but, const char *str)
ChannelDriver *driver;
bool driven;
- fcu = ui_but_get_fcurve(but, NULL, &driven);
+ fcu = ui_but_get_fcurve(but, NULL, NULL, &driven);
if (fcu && driven) {
driver = fcu->driver;
@@ -208,7 +216,7 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
FCurve *fcu;
bool driven;
- fcu = ui_but_get_fcurve(but, &action, &driven);
+ fcu = ui_but_get_fcurve(but, NULL, &action, &driven);
if (fcu && !driven) {
id = but->rnapoin.id.data;
@@ -219,7 +227,14 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
short flag = ANIM_get_keyframing_flags(scene, 1);
fcu->flag &= ~FCURVE_SELECTED;
- insert_keyframe(reports, id, action, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
+
+ /* Note: We use but->rnaindex instead of fcu->array_index,
+ * because a button may control all items of an array at once.
+ * E.g., color wheels (see T42567). */
+ BLI_assert((fcu->array_index == but->rnaindex) || (but->rnaindex == -1));
+ insert_keyframe(reports, id, action, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
+ fcu->rna_path, but->rnaindex, cfra, flag);
+
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
}
@@ -227,54 +242,54 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
void ui_but_anim_insert_keyframe(bContext *C)
{
- /* this operator calls uiContextActiveProperty */
+ /* this operator calls UI_context_active_but_prop_get */
WM_operator_name_call(C, "ANIM_OT_keyframe_insert_button", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_delete_keyframe(bContext *C)
{
- /* this operator calls uiContextActiveProperty */
+ /* this operator calls UI_context_active_but_prop_get */
WM_operator_name_call(C, "ANIM_OT_keyframe_delete_button", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_clear_keyframe(bContext *C)
{
- /* this operator calls uiContextActiveProperty */
+ /* this operator calls UI_context_active_but_prop_get */
WM_operator_name_call(C, "ANIM_OT_keyframe_clear_button", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_add_driver(bContext *C)
{
- /* this operator calls uiContextActiveProperty */
+ /* this operator calls UI_context_active_but_prop_get */
WM_operator_name_call(C, "ANIM_OT_driver_button_add", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_remove_driver(bContext *C)
{
- /* this operator calls uiContextActiveProperty */
+ /* this operator calls UI_context_active_but_prop_get */
WM_operator_name_call(C, "ANIM_OT_driver_button_remove", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_copy_driver(bContext *C)
{
- /* this operator calls uiContextActiveProperty */
+ /* this operator calls UI_context_active_but_prop_get */
WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_paste_driver(bContext *C)
{
- /* this operator calls uiContextActiveProperty */
+ /* this operator calls UI_context_active_but_prop_get */
WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_add_keyingset(bContext *C)
{
- /* this operator calls uiContextActiveProperty */
+ /* this operator calls UI_context_active_but_prop_get */
WM_operator_name_call(C, "ANIM_OT_keyingset_button_add", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_remove_keyingset(bContext *C)
{
- /* this operator calls uiContextActiveProperty */
+ /* this operator calls UI_context_active_but_prop_get */
WM_operator_name_call(C, "ANIM_OT_keyingset_button_remove", WM_OP_INVOKE_DEFAULT, NULL);
}
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 235d7652539..07d580b9138 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -62,21 +62,21 @@
static int roundboxtype = UI_CNR_ALL;
-void uiSetRoundBox(int type)
+void UI_draw_roundbox_corner_set(int type)
{
/* Not sure the roundbox function is the best place to change this
- * if this is undone, its not that big a deal, only makes curves edges
+ * if this is undone, it's not that big a deal, only makes curves edges
* square for the */
roundboxtype = type;
}
-int uiGetRoundBox(void)
+int UI_draw_roundbox_corner_get(void)
{
return roundboxtype;
}
-void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float rad)
+void UI_draw_roundbox_gl_mode(int mode, float minx, float miny, float maxx, float maxy, float rad)
{
float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
@@ -152,7 +152,9 @@ static void round_box_shade_col(const float col1[3], float const col2[3], const
/* linear horizontal shade within button or in outline */
/* view2d scrollers use it */
-void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown)
+void UI_draw_roundbox_shade_x(
+ int mode, float minx, float miny, float maxx, float maxy,
+ float rad, float shadetop, float shadedown)
{
float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
@@ -260,8 +262,9 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl
/* linear vertical shade within button or in outline */
/* view2d scrollers use it */
-void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float maxy,
- float rad, float shadeLeft, float shadeRight)
+void UI_draw_roundbox_shade_y(
+ int mode, float minx, float miny, float maxx, float maxy,
+ float rad, float shadeLeft, float shadeRight)
{
float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
@@ -365,7 +368,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float
}
/* plain antialiased unfilled rectangle */
-void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
+void UI_draw_roundbox_unfilled(float minx, float miny, float maxx, float maxy, float rad)
{
float color[4];
@@ -380,18 +383,24 @@ void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
- uiDrawBox(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
+ UI_draw_roundbox_gl_mode(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
glDisable(GL_BLEND);
glDisable(GL_LINE_SMOOTH);
}
/* (old, used in outliner) plain antialiased filled box */
-void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad)
+void UI_draw_roundbox(float minx, float miny, float maxx, float maxy, float rad)
{
ui_draw_anti_roundbox(GL_POLYGON, minx, miny, maxx, maxy, rad, roundboxtype & UI_RB_ALPHA);
}
+void UI_draw_text_underline(int pos_x, int pos_y, int len, int height)
+{
+ int ofs_y = 4 * U.pixelsize;
+ glRecti(pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize));
+}
+
/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect)
@@ -441,6 +450,51 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
#endif
}
+/**
+ * Draw title and text safe areas.
+ *
+ * The first 4 parameters are the offsets for the view, not the zones.
+ */
+void UI_draw_safe_areas(
+ float x1, float x2, float y1, float y2,
+ const float title_aspect[2], const float action_aspect[2])
+{
+ const float size_x_half = (x2 - x1) * 0.5f;
+ const float size_y_half = (y2 - y1) * 0.5f;
+
+ const float *safe_areas[] = {title_aspect, action_aspect};
+ int i, safe_len = ARRAY_SIZE(safe_areas);
+ bool is_first = true;
+
+ for (i = 0; i < safe_len; i++) {
+ if (safe_areas[i][0] || safe_areas[i][1]) {
+ float margin_x, margin_y;
+ float minx, miny, maxx, maxy;
+
+ if (is_first) {
+ UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
+ is_first = false;
+ }
+
+ margin_x = safe_areas[i][0] * size_x_half;
+ margin_y = safe_areas[i][1] * size_y_half;
+
+ minx = x1 + margin_x;
+ miny = y1 + margin_y;
+ maxx = x2 - margin_x;
+ maxy = y2 - margin_y;
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(maxx, miny);
+ glVertex2f(maxx, maxy);
+ glVertex2f(minx, maxy);
+ glVertex2f(minx, miny);
+ glEnd();
+ }
+ }
+}
+
+
static void draw_scope_end(const rctf *rect, GLint *scissor)
{
/* restore scissortest */
@@ -450,8 +504,8 @@ static void draw_scope_end(const rctf *rect, GLint *scissor)
/* outline */
glColor4f(0.f, 0.f, 0.f, 0.5f);
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_LINE_LOOP, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f);
}
static void histogram_draw_one(float r, float g, float b, float alpha,
@@ -485,7 +539,7 @@ static void histogram_draw_one(float r, float g, float b, float alpha,
glColor4f(r, g, b, alpha);
glShadeModel(GL_FLAT);
- glBegin(GL_QUAD_STRIP);
+ glBegin(GL_TRIANGLE_STRIP);
glVertex2f(x, y);
glVertex2f(x, y + (data[0] * h));
for (i = 1; i < res; i++) {
@@ -535,8 +589,8 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.f, 0.f, 0.f, 0.3f);
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
/* need scissor test, histogram can draw outside of boundary */
glGetIntegerv(GL_VIEWPORT, scissor);
@@ -622,8 +676,8 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.f, 0.f, 0.f, 0.3f);
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
/* need scissor test, waveform can draw outside of boundary */
glGetIntegerv(GL_VIEWPORT, scissor);
@@ -768,8 +822,8 @@ static void vectorscope_draw_target(float centerx, float centery, float diam, co
if (u > 0 && v >= 0) tangle = atanf(v / u);
else if (u > 0 && v < 0) tangle = atanf(v / u) + 2.0f * (float)M_PI;
else if (u < 0) tangle = atanf(v / u) + (float)M_PI;
- else if (u == 0 && v > 0.0f) tangle = (float)M_PI / 2.0f;
- else if (u == 0 && v < 0.0f) tangle = -(float)M_PI / 2.0f;
+ else if (u == 0 && v > 0.0f) tangle = M_PI_2;
+ else if (u == 0 && v < 0.0f) tangle = -M_PI_2;
tampli = sqrtf(u * u + v * v);
/* small target vary by 2.5 degree and 2.5 IRE unit */
@@ -841,8 +895,8 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.f, 0.f, 0.f, 0.3f);
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
/* need scissor test, hvectorscope can draw outside of boundary */
glGetIntegerv(GL_VIEWPORT, scissor);
@@ -1067,7 +1121,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
if (coba == NULL) return;
if (but->block->color_profile)
- display = ui_block_display_get(but->block);
+ display = ui_block_cm_display_get(but->block);
x1 = rect->xmin;
sizex = rect->xmax - x1;
@@ -1093,7 +1147,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
v1[1] = y1 + sizey_solid;
v2[1] = rect->ymax;
- glBegin(GL_QUAD_STRIP);
+ glBegin(GL_TRIANGLE_STRIP);
for (a = 0; a <= sizex; a++) {
pos = ((float)a) / sizex;
do_colorband(coba, pos, colf);
@@ -1112,7 +1166,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
v1[1] = y1;
v2[1] = y1 + sizey_solid;
- glBegin(GL_QUAD_STRIP);
+ glBegin(GL_TRIANGLE_STRIP);
for (a = 0; a <= sizex; a++) {
pos = ((float)a) / sizex;
do_colorband(coba, pos, colf);
@@ -1158,7 +1212,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti
}
}
-void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
+void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
{
static GLuint displist = 0;
int a, old[8];
@@ -1171,8 +1225,8 @@ void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
/* backdrop */
glColor3ubv((unsigned char *)wcol->inner);
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_POLYGON, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f);
/* sphere color */
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffn);
@@ -1189,7 +1243,7 @@ void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
glEnable(GL_LIGHT7);
glEnable(GL_LIGHTING);
- ui_get_but_vectorf(but, dir);
+ ui_but_v3_get(but, dir);
dir[3] = 0.0f; /* glLightfv needs 4 args, 0.0 is sun */
glLightfv(GL_LIGHT7, GL_POSITION, dir);
@@ -1511,8 +1565,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
if (scopes->track_disabled) {
glColor4f(0.7f, 0.3f, 0.3f, 0.3f);
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
ok = 1;
}
@@ -1559,8 +1613,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
if (scopes->use_track_mask) {
glColor4f(0.0f, 0.0f, 0.0f, 0.3f);
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
}
glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y,
@@ -1600,8 +1654,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
if (!ok) {
glColor4f(0.f, 0.f, 0.f, 0.3f);
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
}
/* outline */
@@ -1717,7 +1771,7 @@ static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float s
glShadeModel(GL_FLAT);
}
-void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
+void UI_draw_box_shadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
{
/* accumulated outline boxes to make shade not linear, is more pleasant */
ui_shadowbox(minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8);
@@ -1727,7 +1781,7 @@ void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, fl
}
-void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int UNUSED(select))
+void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int UNUSED(select))
{
int i;
float rad;
@@ -1758,13 +1812,13 @@ void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int
glColor4f(0.0f, 0.0f, 0.0f, calpha);
calpha += dalpha;
- uiDrawBox(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a);
}
/* outline emphasis */
glEnable(GL_LINE_SMOOTH);
glColor4ub(0, 0, 0, 100);
- uiDrawBox(GL_LINE_LOOP, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f);
+ UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index 5b7915e20c5..aabb8e29fa9 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -40,6 +40,7 @@
#include "BKE_screen.h"
#include "BKE_report.h"
#include "BKE_idcode.h"
+#include "BKE_unit.h"
#include "RNA_access.h"
@@ -64,6 +65,38 @@
#include "ED_screen.h"
#include "ED_view3d.h"
+/* -------------------------------------------------------------------- */
+/* Utility Functions
+ */
+/** \name Generic Shared Functions
+ * \{ */
+
+static void eyedropper_draw_cursor_text(const struct bContext *C, ARegion *ar, const char *name)
+{
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ wmWindow *win = CTX_wm_window(C);
+ int x = win->eventstate->x;
+ int y = win->eventstate->y;
+ const unsigned char fg[4] = {255, 255, 255, 255};
+ const unsigned char bg[4] = {0, 0, 0, 50};
+
+
+ if ((name[0] == '\0') ||
+ (BLI_rcti_isect_pt(&ar->winrct, x, y) == false))
+ {
+ return;
+ }
+
+ x = x - ar->winrct.xmin;
+ y = y - ar->winrct.ymin;
+
+ y += U.widget_unit;
+
+ UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, fg, bg);
+}
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/* Eyedropper
@@ -91,7 +124,7 @@ static bool eyedropper_init(bContext *C, wmOperator *op)
op->customdata = eye = MEM_callocN(sizeof(Eyedropper), "Eyedropper");
- uiContextActiveProperty(C, &eye->ptr, &eye->prop, &eye->index);
+ UI_context_active_but_prop_get(C, &eye->ptr, &eye->prop, &eye->index);
if ((eye->ptr.data == NULL) ||
(eye->prop == NULL) ||
@@ -139,43 +172,42 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
/* we could use some clever */
wmWindow *win = CTX_wm_window(C);
- ScrArea *sa;
- for (sa = win->screen->areabase.first; sa; sa = sa->next) {
- if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) {
- if (sa->spacetype == SPACE_IMAGE) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
- SpaceImage *sima = sa->spacedata.first;
- int mval[2] = {mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
-
- if (ED_space_image_color_sample(CTX_data_scene(C), sima, ar, mval, r_col)) {
- return;
- }
+ ScrArea *sa = BKE_screen_find_area_xy(win->screen, SPACE_TYPE_ANY, mx, my);
+
+ if (sa) {
+ if (sa->spacetype == SPACE_IMAGE) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ SpaceImage *sima = sa->spacedata.first;
+ int mval[2] = {mx - ar->winrct.xmin,
+ my - ar->winrct.ymin};
+
+ if (ED_space_image_color_sample(CTX_data_scene(C), sima, ar, mval, r_col)) {
+ return;
}
}
- else if (sa->spacetype == SPACE_NODE) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
- SpaceNode *snode = sa->spacedata.first;
- int mval[2] = {mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
-
- if (ED_space_node_color_sample(CTX_data_scene(C), snode, ar, mval, r_col)) {
- return;
- }
+ }
+ else if (sa->spacetype == SPACE_NODE) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ SpaceNode *snode = sa->spacedata.first;
+ int mval[2] = {mx - ar->winrct.xmin,
+ my - ar->winrct.ymin};
+
+ if (ED_space_node_color_sample(CTX_data_scene(C), snode, ar, mval, r_col)) {
+ return;
}
}
- else if (sa->spacetype == SPACE_CLIP) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
- SpaceClip *sc = sa->spacedata.first;
- int mval[2] = {mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
-
- if (ED_space_clip_color_sample(CTX_data_scene(C), sc, ar, mval, r_col)) {
- return;
- }
+ }
+ else if (sa->spacetype == SPACE_CLIP) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ SpaceClip *sc = sa->spacedata.first;
+ int mval[2] = {mx - ar->winrct.xmin,
+ my - ar->winrct.ymin};
+
+ if (ED_space_clip_color_sample(CTX_data_scene(C), sc, ar, mval, r_col)) {
+ return;
}
}
}
@@ -328,7 +360,7 @@ void UI_OT_eyedropper_color(wmOperatorType *ot)
/* identifiers */
ot->name = "Eyedropper";
ot->idname = "UI_OT_eyedropper_color";
- ot->description = "Sample a color from the Blender Window to store in a property";
+ ot->description = "Sample a data-block from the 3D view";
/* api callbacks */
ot->invoke = eyedropper_invoke;
@@ -338,10 +370,11 @@ void UI_OT_eyedropper_color(wmOperatorType *ot)
ot->poll = eyedropper_poll;
/* flags */
- ot->flag = OPTYPE_BLOCKING;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
/* properties */
}
+
/** \} */
@@ -369,31 +402,7 @@ typedef struct DataDropper {
static void datadropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg)
{
DataDropper *ddr = arg;
- int width;
- const char *name = ddr->name;
- wmWindow *win = CTX_wm_window(C);
- int x = win->eventstate->x;
- int y = win->eventstate->y;
-
- if ((name[0] == '\0') ||
- (BLI_rcti_isect_pt(&ar->winrct, x, y) == false))
- {
- return;
- }
-
- width = UI_GetStringWidth(name);
- x = x - ar->winrct.xmin;
- y = y - ar->winrct.ymin;
-
- y += 20;
-
- glColor4ub(0, 0, 0, 50);
-
- uiSetRoundBox(UI_CNR_ALL | UI_RB_ALPHA);
- uiRoundBox(x, y, x + width + 8, y + 15, 4);
-
- glColor4ub(255, 255, 255, 255);
- UI_DrawString(x + 4, y + 4, name);
+ eyedropper_draw_cursor_text(C, ar, ddr->name);
}
@@ -411,7 +420,7 @@ static int datadropper_init(bContext *C, wmOperator *op)
op->customdata = ddr = MEM_callocN(sizeof(DataDropper), "DataDropper");
- uiContextActiveProperty(C, &ddr->ptr, &ddr->prop, &index_dummy);
+ UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy);
if ((ddr->ptr.data == NULL) ||
(ddr->prop == NULL) ||
@@ -464,53 +473,49 @@ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int
/* we could use some clever */
wmWindow *win = CTX_wm_window(C);
- ScrArea *sa;
+ ScrArea *sa = BKE_screen_find_area_xy(win->screen, -1, mx, my);
ScrArea *area_prev = CTX_wm_area(C);
ARegion *ar_prev = CTX_wm_region(C);
ddr->name[0] = '\0';
- for (sa = win->screen->areabase.first; sa; sa = sa->next) {
- if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) {
- if (sa->spacetype == SPACE_VIEW3D) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
- const int mval[2] = {
- mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
- Base *base;
-
- CTX_wm_area_set(C, sa);
- CTX_wm_region_set(C, ar);
-
- /* grr, always draw else we leave stale text */
- ED_region_tag_redraw(ar);
-
- base = ED_view3d_give_base_under_cursor(C, mval);
- if (base) {
- Object *ob = base->object;
- ID *id = NULL;
- if (ddr->idcode == ID_OB) {
- id = (ID *)ob;
+ if (sa) {
+ if (sa->spacetype == SPACE_VIEW3D) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ const int mval[2] = {
+ mx - ar->winrct.xmin,
+ my - ar->winrct.ymin};
+ Base *base;
+
+ CTX_wm_area_set(C, sa);
+ CTX_wm_region_set(C, ar);
+
+ /* grr, always draw else we leave stale text */
+ ED_region_tag_redraw(ar);
+
+ base = ED_view3d_give_base_under_cursor(C, mval);
+ if (base) {
+ Object *ob = base->object;
+ ID *id = NULL;
+ if (ddr->idcode == ID_OB) {
+ id = (ID *)ob;
+ }
+ else if (ob->data) {
+ if (GS(((ID *)ob->data)->name) == ddr->idcode) {
+ id = (ID *)ob->data;
}
- else if (ob->data) {
- if (GS(((ID *)ob->data)->name) == ddr->idcode) {
- id = (ID *)ob->data;
- }
- else {
- BLI_snprintf(ddr->name, sizeof(ddr->name), "Incompatible, expected a %s",
- ddr->idcode_name);
- }
- }
-
- if (id) {
- BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s",
- ddr->idcode_name, id->name + 2);
- *r_id = id;
+ else {
+ BLI_snprintf(ddr->name, sizeof(ddr->name), "Incompatible, expected a %s",
+ ddr->idcode_name);
}
+ }
- break;
+ if (id) {
+ BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s",
+ ddr->idcode_name, id->name + 2);
+ *r_id = id;
}
}
}
@@ -637,7 +642,313 @@ void UI_OT_eyedropper_id(wmOperatorType *ot)
ot->poll = datadropper_poll;
/* flags */
- ot->flag = OPTYPE_BLOCKING;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
+
+ /* properties */
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+/* Depth Dropper
+ *
+ * note: depthdropper is only internal name to avoid confusion in this file
+ */
+
+/** \name Eyedropper (Depth)
+ * \{ */
+
+typedef struct DepthDropper {
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ bool accum_start; /* has mouse been presed */
+ float accum_depth;
+ int accum_tot;
+
+ ARegionType *art;
+ void *draw_handle_pixel;
+ char name[200];
+} DepthDropper;
+
+
+static void depthdropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg)
+{
+ DepthDropper *ddr = arg;
+ eyedropper_draw_cursor_text(C, ar, ddr->name);
+}
+
+
+static int depthdropper_init(bContext *C, wmOperator *op)
+{
+ DepthDropper *ddr;
+ int index_dummy;
+
+ SpaceType *st;
+ ARegionType *art;
+
+ st = BKE_spacetype_from_id(SPACE_VIEW3D);
+ art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW);
+
+ op->customdata = ddr = MEM_callocN(sizeof(DepthDropper), "DepthDropper");
+
+ UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy);
+
+ /* fallback to the active camera's dof */
+ if (ddr->prop == NULL) {
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (rv3d && rv3d->persp == RV3D_CAMOB) {
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->camera && v3d->camera->data && (((ID *)v3d->camera->data)->lib == NULL)) {
+ RNA_id_pointer_create(v3d->camera->data, &ddr->ptr);
+ ddr->prop = RNA_struct_find_property(&ddr->ptr, "dof_distance");
+ }
+ }
+ }
+
+ if ((ddr->ptr.data == NULL) ||
+ (ddr->prop == NULL) ||
+ (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
+ (RNA_property_type(ddr->prop) != PROP_FLOAT))
+ {
+ return false;
+ }
+
+ ddr->art = art;
+ ddr->draw_handle_pixel = ED_region_draw_cb_activate(art, depthdropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL);
+
+ return true;
+}
+
+static void depthdropper_exit(bContext *C, wmOperator *op)
+{
+ WM_cursor_modal_restore(CTX_wm_window(C));
+
+ if (op->customdata) {
+ DepthDropper *ddr = (DepthDropper *)op->customdata;
+
+ if (ddr->art) {
+ ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel);
+ }
+
+ MEM_freeN(op->customdata);
+
+ op->customdata = NULL;
+ }
+}
+
+static void depthdropper_cancel(bContext *C, wmOperator *op)
+{
+ depthdropper_exit(C, op);
+}
+
+/* *** depthdropper id helper functions *** */
+/**
+ * \brief get the ID from the screen.
+ *
+ */
+static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx, int my, float *r_depth)
+{
+
+ /* we could use some clever */
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = BKE_screen_find_area_xy(win->screen, SPACE_TYPE_ANY, mx, my);
+ Scene *scene = win->screen->scene;
+ UnitSettings *unit = &scene->unit;
+ const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0;
+
+ ScrArea *area_prev = CTX_wm_area(C);
+ ARegion *ar_prev = CTX_wm_region(C);
+
+ ddr->name[0] = '\0';
+
+ if (sa) {
+ if (sa->spacetype == SPACE_VIEW3D) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+ View3D *v3d = sa->spacedata.first;
+ RegionView3D *rv3d = ar->regiondata;
+ /* weak, we could pass in some reference point */
+ const float *view_co = v3d->camera ? v3d->camera->obmat[3] : rv3d->viewinv[3];
+ const int mval[2] = {
+ mx - ar->winrct.xmin,
+ my - ar->winrct.ymin};
+ float co[3];
+
+ CTX_wm_area_set(C, sa);
+ CTX_wm_region_set(C, ar);
+
+ /* grr, always draw else we leave stale text */
+ ED_region_tag_redraw(ar);
+
+ view3d_operator_needs_opengl(C);
+
+ if (ED_view3d_autodist(scene, ar, v3d, mval, co, true, NULL)) {
+ const float mval_center_fl[2] = {
+ (float)ar->winx / 2,
+ (float)ar->winy / 2};
+ float co_align[3];
+
+ /* quick way to get view-center aligned point */
+ ED_view3d_win_to_3d(ar, co, mval_center_fl, co_align);
+
+ *r_depth = len_v3v3(view_co, co_align);
+
+ bUnit_AsString(ddr->name, sizeof(ddr->name),
+ (double)*r_depth,
+ 4, unit->system, B_UNIT_LENGTH, do_split, false);
+ }
+ else {
+ BLI_strncpy(ddr->name, "Nothing under cursor", sizeof(ddr->name));
+ }
+ }
+ }
+ }
+
+ CTX_wm_area_set(C, area_prev);
+ CTX_wm_region_set(C, ar_prev);
+}
+
+/* sets the sample depth RGB, maintaining A */
+static void depthdropper_depth_set(bContext *C, DepthDropper *ddr, const float depth)
+{
+ RNA_property_float_set(&ddr->ptr, ddr->prop, depth);
+ RNA_property_update(C, &ddr->ptr, ddr->prop);
+}
+
+/* set sample from accumulated values */
+static void depthdropper_depth_set_accum(bContext *C, DepthDropper *ddr)
+{
+ float depth = ddr->accum_depth;
+ if (ddr->accum_tot) {
+ depth /= (float)ddr->accum_tot;
+ }
+ depthdropper_depth_set(C, ddr, depth);
+}
+
+/* single point sample & set */
+static void depthdropper_depth_sample(bContext *C, DepthDropper *ddr, int mx, int my)
+{
+ float depth = -1.0f;
+ if (depth != -1.0f) {
+ depthdropper_depth_sample_pt(C, ddr, mx, my, &depth);
+ depthdropper_depth_set(C, ddr, depth);
+ }
+}
+
+static void depthdropper_depth_sample_accum(bContext *C, DepthDropper *ddr, int mx, int my)
+{
+ float depth = -1.0f;
+ depthdropper_depth_sample_pt(C, ddr, mx, my, &depth);
+ if (depth != -1.0f) {
+ ddr->accum_depth += depth;
+ ddr->accum_tot++;
+ }
+}
+
+/* main modal status check */
+static int depthdropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ DepthDropper *ddr = (DepthDropper *)op->customdata;
+
+ switch (event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ depthdropper_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ case LEFTMOUSE:
+ if (event->val == KM_RELEASE) {
+ if (ddr->accum_tot == 0) {
+ depthdropper_depth_sample(C, ddr, event->x, event->y);
+ }
+ else {
+ depthdropper_depth_set_accum(C, ddr);
+ }
+ depthdropper_exit(C, op);
+ return OPERATOR_FINISHED;
+ }
+ else if (event->val == KM_PRESS) {
+ /* enable accum and make first sample */
+ ddr->accum_start = true;
+ depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
+ }
+ break;
+ case MOUSEMOVE:
+ if (ddr->accum_start) {
+ /* button is pressed so keep sampling */
+ depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
+ depthdropper_depth_set_accum(C, ddr);
+ }
+ break;
+ case SPACEKEY:
+ if (event->val == KM_RELEASE) {
+ ddr->accum_tot = 0;
+ ddr->accum_depth = 0.0f;
+ depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
+ depthdropper_depth_set_accum(C, ddr);
+ }
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* Modal Operator init */
+static int depthdropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ /* init */
+ if (depthdropper_init(C, op)) {
+ WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ depthdropper_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+}
+
+/* Repeat operator */
+static int depthdropper_exec(bContext *C, wmOperator *op)
+{
+ /* init */
+ if (depthdropper_init(C, op)) {
+ /* cleanup */
+ depthdropper_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+static int depthdropper_poll(bContext *C)
+{
+ if (!CTX_wm_window(C)) return 0;
+ else return 1;
+}
+
+void UI_OT_eyedropper_depth(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Eyedropper Depth";
+ ot->idname = "UI_OT_eyedropper_depth";
+ ot->description = "Sample depth from the 3D view";
+
+ /* api callbacks */
+ ot->invoke = depthdropper_invoke;
+ ot->modal = depthdropper_modal;
+ ot->cancel = depthdropper_cancel;
+ ot->exec = depthdropper_exec;
+ ot->poll = depthdropper_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
/* properties */
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index a3c52ec3e3c..a6ff5bb3ad3 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -87,6 +87,10 @@
#include "WM_api.h"
#include "WM_types.h"
+#ifdef WITH_INPUT_IME
+# include "wm_window.h"
+#endif
+
/* place the mouse at the scaled down location when un-grabbing */
#define USE_CONT_MOUSE_CORRECT
/* support dragging toggle buttons */
@@ -103,10 +107,14 @@
#define UI_MAX_PASSWORD_STR 128
+/* This hack is needed because we don't have a good way to re-reference keymap items once added: T42944 */
+#define USE_KEYMAP_ADD_HACK
+
/* proto */
-static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to);
-static void ui_add_link(bContext *C, uiBut *from, uiBut *to);
+static void ui_but_smart_controller_add(bContext *C, uiBut *from, uiBut *to);
+static void ui_but_link_add(bContext *C, uiBut *from, uiBut *to);
static int ui_do_but_EXIT(bContext *C, uiBut *but, struct uiHandleButtonData *data, const wmEvent *event);
+static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but_b);
#ifdef USE_KEYNAV_LIMIT
static void ui_mouse_motion_keynav_init(struct uiKeyNavLock *keynav, const wmEvent *event);
@@ -252,16 +260,16 @@ typedef struct uiHandleButtonData {
CBData *dragcbd;
#ifdef USE_CONT_MOUSE_CORRECT
- /* when ungrabbing buttons which are #ui_is_a_warp_but(), we may want to position them
+ /* when ungrabbing buttons which are #ui_but_is_cursor_warp(), we may want to position them
* FLT_MAX signifies do-nothing, use #ui_block_to_window_fl() to get this into a usable space */
float ungrab_mval[2];
#endif
- /* menu open (watch uiFreeActiveButtons) */
+ /* menu open (watch UI_screen_free_active_but) */
uiPopupBlockHandle *menu;
int menuretval;
- /* search box (watch uiFreeActiveButtons) */
+ /* search box (watch UI_screen_free_active_but) */
ARegion *searchbox;
#ifdef USE_KEYNAV_LIMIT
struct uiKeyNavLock searchbox_keynav_state;
@@ -313,9 +321,9 @@ typedef struct uiAfterFunc {
-static bool ui_is_but_interactive(const uiBut *but, const bool labeledit);
+static bool ui_but_is_interactive(const uiBut *but, const bool labeledit);
static bool ui_but_contains_pt(uiBut *but, float mx, float my);
-static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y);
+static bool ui_but_contains_point_px(ARegion *ar, uiBut *but, int x, int y);
static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, const bool labeledit);
static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event);
static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type);
@@ -348,6 +356,12 @@ static enum eSnapType ui_event_to_snap(const wmEvent *event)
return (event->ctrl) ? (event->shift) ? SNAP_ON_SMALL : SNAP_ON : SNAP_OFF;
}
+static bool ui_event_is_snap(const wmEvent *event)
+{
+ return (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY) ||
+ ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY));
+}
+
static void ui_color_snap_hue(const enum eSnapType snap, float *r_hue)
{
const float snap_increment = (snap == SNAP_ON_SMALL) ? 24 : 12;
@@ -390,7 +404,17 @@ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val)
bool ui_but_is_editable(const uiBut *but)
{
- return !ELEM(but->type, LABEL, SEPR, SEPRLINE, ROUNDBOX, LISTBOX, PROGRESSBAR);
+ return !ELEM(but->type,
+ UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE,
+ UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX, UI_BTYPE_PROGRESS_BAR);
+}
+
+bool ui_but_is_editable_as_text(const uiBut *but)
+{
+ return ELEM(but->type,
+ UI_BTYPE_TEXT, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER,
+ UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK);
+
}
static uiBut *ui_but_prev(uiBut *but)
@@ -435,10 +459,13 @@ static uiBut *ui_but_last(uiBlock *block)
return NULL;
}
-static bool ui_is_a_warp_but(uiBut *but)
+static bool ui_but_is_cursor_warp(uiBut *but)
{
if (U.uiflag & USER_CONTINUOUS_MOUSE) {
- if (ELEM(but->type, NUM, NUMSLI, HSVCIRCLE, TRACKPREVIEW, HSVCUBE, BUT_CURVE)) {
+ if (ELEM(but->type,
+ UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_HSVCIRCLE,
+ UI_BTYPE_TRACK_PREVIEW, UI_BTYPE_HSVCUBE, UI_BTYPE_CURVE))
+ {
return true;
}
}
@@ -464,7 +491,7 @@ static void ui_mouse_scale_warp(uiHandleButtonData *data,
}
/* file selectors are exempt from utf-8 checks */
-bool ui_is_but_utf8(const uiBut *but)
+bool ui_but_is_utf8(const uiBut *but)
{
if (but->rnaprop) {
const int subtype = RNA_property_subtype(but->rnaprop);
@@ -523,7 +550,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
* with these functions removing the buttons we are working with */
if (but->func || but->funcN || block->handle_func || but->rename_func ||
- (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop)
+ (but->type == UI_BTYPE_BUT_MENU && block->butm_func) || but->optype || but->rnaprop)
{
after = ui_afterfunc_new();
@@ -548,7 +575,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
after->handle_func_arg = block->handle_func_arg;
after->retval = but->retval;
- if (but->type == BUTM) {
+ if (but->type == UI_BTYPE_BUT_MENU) {
after->butm_func = block->butm_func;
after->butm_func_arg = block->butm_func_arg;
after->a2 = but->a2;
@@ -570,8 +597,8 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
}
}
-/* typically call ui_apply_undo(), ui_apply_autokey() */
-static void ui_apply_undo(uiBut *but)
+/* typically call ui_apply_but_undo(), ui_apply_but_autokey() */
+static void ui_apply_but_undo(uiBut *but)
{
uiAfterFunc *after;
@@ -579,8 +606,8 @@ static void ui_apply_undo(uiBut *but)
const char *str = NULL;
/* define which string to use for undo */
- if (ELEM(but->type, LINK, INLINK)) str = "Add button link";
- else if (but->type == MENU) str = but->drawstr;
+ if (ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) str = "Add button link";
+ else if (but->type == UI_BTYPE_MENU) str = but->drawstr;
else if (but->drawstr[0]) str = but->drawstr;
else str = but->tip;
@@ -595,7 +622,7 @@ static void ui_apply_undo(uiBut *but)
}
}
-static void ui_apply_autokey(bContext *C, uiBut *but)
+static void ui_apply_but_autokey(bContext *C, uiBut *but)
{
Scene *scene = CTX_data_scene(C);
@@ -689,7 +716,7 @@ static void ui_apply_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data)
static void ui_apply_but_BUTM(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_set_but_val(but, but->hardmin);
+ ui_but_value_set(but, but->hardmin);
ui_apply_but_func(C, but);
data->retval = but->retval;
@@ -698,10 +725,10 @@ 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 == MENU)
- ui_set_but_val(but, data->value);
+ if (but->type == UI_BTYPE_MENU)
+ ui_but_value_set(but, data->value);
- ui_check_but(but);
+ ui_but_update(but);
ui_apply_but_func(C, but);
data->retval = but->retval;
data->applied = true;
@@ -712,7 +739,7 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data)
double value;
int w, lvalue, push;
- value = ui_get_but_val(but);
+ value = ui_but_value_get(but);
lvalue = (int)value;
if (but->bit) {
@@ -720,17 +747,17 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data)
if (w) lvalue = UI_BITBUT_CLR(lvalue, but->bitnr);
else lvalue = UI_BITBUT_SET(lvalue, but->bitnr);
- ui_set_but_val(but, (double)lvalue);
- if (but->type == ICONTOG || but->type == ICONTOGN) ui_check_but(but);
+ ui_but_value_set(but, (double)lvalue);
+ if (but->type == UI_BTYPE_ICON_TOGGLE || but->type == UI_BTYPE_ICON_TOGGLE_N) ui_but_update(but);
}
else {
if (value == 0.0) push = 1;
else push = 0;
- if (ELEM(but->type, TOGN, ICONTOGN, OPTIONN)) push = !push;
- ui_set_but_val(but, (double)push);
- if (but->type == ICONTOG || but->type == ICONTOGN) ui_check_but(but);
+ if (ELEM(but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N)) push = !push;
+ ui_but_value_set(but, (double)push);
+ if (but->type == UI_BTYPE_ICON_TOGGLE || but->type == UI_BTYPE_ICON_TOGGLE_N) ui_but_update(but);
}
ui_apply_but_func(C, but);
@@ -743,14 +770,14 @@ static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
{
uiBut *bt;
- ui_set_but_val(but, but->hardmax);
+ ui_but_value_set(but, but->hardmax);
ui_apply_but_func(C, but);
/* states of other row buttons */
for (bt = block->buttons.first; bt; bt = bt->next)
- if (bt != but && bt->poin == but->poin && ELEM(bt->type, ROW, LISTROW))
- ui_check_but(bt);
+ if (bt != but && bt->poin == but->poin && ELEM(bt->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW))
+ ui_but_update(bt);
data->retval = but->retval;
data->applied = true;
@@ -761,14 +788,21 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data)
if (!data->str)
return;
- ui_set_but_string(C, but, data->str);
- ui_check_but(but);
+ ui_but_string_set(C, but, data->str);
+ ui_but_update(but);
- /* give butfunc the original text too */
- /* feature used for bone renaming, channels, etc */
- /* afterfunc frees origstr */
- but->rename_orig = data->origstr;
- data->origstr = NULL;
+ /* give butfunc a copy of the original text too.
+ * feature used for bone renaming, channels, etc.
+ * afterfunc frees rename_orig */
+ if (data->origstr && (but->flag & UI_BUT_TEXTEDIT_UPDATE)) {
+ /* In this case, we need to keep origstr available, to restore real org string in case we cancel after
+ * having typed something already. */
+ but->rename_orig = BLI_strdup(data->origstr);
+ }
+ else {
+ but->rename_orig = data->origstr;
+ data->origstr = NULL;
+ }
ui_apply_but_func(C, but);
data->retval = but->retval;
@@ -778,8 +812,8 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data)
static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data)
{
if (data->str) {
- if (ui_set_but_string(C, but, data->str)) {
- data->value = ui_get_but_val(but);
+ if (ui_but_string_set(C, but, data->str)) {
+ data->value = ui_but_value_get(but);
}
else {
data->cancel = true;
@@ -787,9 +821,9 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data)
}
}
else
- ui_set_but_val(but, data->value);
+ ui_but_value_set(but, data->value);
- ui_check_but(but);
+ ui_but_update(but);
ui_apply_but_func(C, but);
data->retval = but->retval;
@@ -798,8 +832,8 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data)
static void ui_apply_but_VEC(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_set_but_vectorf(but, data->vec);
- ui_check_but(but);
+ ui_but_v3_set(but, data->vec);
+ ui_but_update(but);
ui_apply_but_func(C, but);
data->retval = but->retval;
@@ -836,7 +870,7 @@ static void ui_multibut_add(uiHandleButtonData *data, uiBut *but)
mbut_state = MEM_callocN(sizeof(*mbut_state), __func__);
mbut_state->but = but;
- mbut_state->origvalue = ui_get_but_val(but);
+ mbut_state->origvalue = ui_but_value_get(but);
BLI_linklist_prepend(&data->multi_data.mbuts, mbut_state);
@@ -868,7 +902,7 @@ static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block)
if (but->flag & UI_BUT_DRAG_MULTI) {
uiButMultiState *mbut_state = ui_multibut_lookup(data, but);
if (mbut_state) {
- ui_set_but_val(but, mbut_state->origvalue);
+ ui_but_value_set(but, mbut_state->origvalue);
}
}
}
@@ -915,11 +949,11 @@ static bool ui_multibut_states_tag(uiBut *but_active, uiHandleButtonData *data,
drag_prev = true;
}
- if (ui_is_but_interactive(but, false)) {
+ if (ui_but_is_interactive(but, false)) {
/* drag checks */
if (but_active != but) {
- if (ui_is_but_compatible(but_active, but)) {
+ if (ui_but_is_compatible(but_active, but)) {
BLI_assert(but->active == NULL);
@@ -981,13 +1015,13 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl
if (mbut_state) {
void *active_back;
- ui_button_execute_begin(C, ar, but, &active_back);
+ ui_but_execute_begin(C, ar, but, &active_back);
BLI_assert(active_back == NULL);
/* no need to check 'data->state' here */
if (data->str) {
/* entering text (set all) */
but->active->value = data->value;
- ui_set_but_string(C, but, data->str);
+ ui_but_string_set(C, but, data->str);
}
else {
/* dragging (use delta) */
@@ -1001,7 +1035,7 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl
/* clamp based on soft limits, see: T40154 */
CLAMP(but->active->value, (double)but->softmin, (double)but->softmax);
}
- ui_button_execute_end(C, ar, but, active_back);
+ ui_but_execute_end(C, ar, but, active_back);
}
else {
/* highly unlikely */
@@ -1050,18 +1084,18 @@ static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set
for (but = block->buttons.first; but; but = but->next) {
/* Note: ctrl is always true here because (at least for now) we always want to consider text control
* in this case, even when not embossed. */
- if (ui_is_but_interactive(but, true)) {
+ if (ui_but_is_interactive(but, true)) {
if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) {
/* execute the button */
- if (ui_is_but_bool(but) && but->type == but_type_start) {
+ if (ui_but_is_bool(but) && but->type == but_type_start) {
/* is it pressed? */
- bool is_set_but = ui_is_but_push(but);
- BLI_assert(ui_is_but_bool(but) == true);
+ bool is_set_but = ui_but_is_pushed(but);
+ BLI_assert(ui_but_is_bool(but) == true);
if (is_set_but != is_set) {
- uiButExecute(C, but);
+ UI_but_execute(C, but);
if (do_check) {
- ui_check_but(but);
+ ui_but_update(but);
}
changed = true;
}
@@ -1164,7 +1198,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void
uiBut *but = ui_but_find_mouse_over_ex(ar, drag_info->xy_init[0], drag_info->xy_init[1], true);
if (but) {
- ui_apply_undo(but);
+ ui_apply_but_undo(but);
}
WM_event_remove_ui_handler(&win->modalhandlers,
@@ -1181,9 +1215,9 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void
}
}
-static bool ui_is_but_drag_toggle(const uiBut *but)
+static bool ui_but_is_drag_toggle(const uiBut *but)
{
- return ((ui_is_but_bool(but) == true) &&
+ return ((ui_but_is_bool(but) == true) &&
/* menu check is importnt so the button dragged over isn't removed instantly */
(ui_block_is_menu(but->block) == false));
}
@@ -1191,7 +1225,7 @@ static bool ui_is_but_drag_toggle(const uiBut *but)
#endif /* USE_DRAG_TOGGLE */
-static bool ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *event)
+static bool ui_but_contains_point_px_icon(uiBut *but, ARegion *ar, const wmEvent *event)
{
rcti rect;
int x = event->x, y = event->y;
@@ -1200,7 +1234,7 @@ static bool ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *eve
BLI_rcti_rctf_copy(&rect, &but->rect);
- if (but->imb || but->type == COLOR) {
+ if (but->imb || but->type == UI_BTYPE_COLOR) {
/* use button size itself */
}
else if (but->drawflag & UI_BUT_ICON_LEFT) {
@@ -1215,7 +1249,7 @@ static bool ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *eve
return BLI_rcti_isect_pt(&rect, x, y);
}
-static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+static bool ui_but_drag_init(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
/* prevent other WM gestures to start while we try to drag */
WM_gestures_remove(C);
@@ -1225,15 +1259,15 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data,
button_activate_state(C, but, BUTTON_STATE_EXIT);
data->cancel = true;
#ifdef USE_DRAG_TOGGLE
- if (ui_is_but_bool(but)) {
+ if (ui_but_is_bool(but)) {
uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
ARegion *ar_prev;
/* call here because regular mouse-up event wont run,
* typically 'button_activate_exit()' handles this */
- ui_apply_autokey(C, but);
+ ui_apply_but_autokey(C, but);
- drag_info->is_set = ui_is_but_push(but);
+ drag_info->is_set = ui_but_is_pushed(but);
drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
drag_info->but_type_start = but->type;
@@ -1253,7 +1287,7 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data,
}
else
#endif
- if (but->type == COLOR) {
+ if (but->type == UI_BTYPE_COLOR) {
bool valid = false;
uiDragColorHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
@@ -1288,7 +1322,7 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data,
else {
wmDrag *drag;
- drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but), WM_DRAG_NOP);
+ drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_but_value_get(but), WM_DRAG_NOP);
if (but->imb)
WM_event_drag_image(drag, but->imb, but->imb_scale, BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect));
}
@@ -1300,7 +1334,7 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data,
/* ********************** linklines *********************** */
-static void ui_delete_active_linkline(uiBlock *block)
+static void ui_linkline_remove_active(uiBlock *block)
{
uiBut *but;
uiLink *link;
@@ -1308,7 +1342,7 @@ static void ui_delete_active_linkline(uiBlock *block)
int a, b;
for (but = block->buttons.first; but; but = but->next) {
- if (but->type == LINK && but->link) {
+ if (but->type == UI_BTYPE_LINK && but->link) {
for (line = but->link->lines.first; line; line = nline) {
nline = line->next;
@@ -1349,7 +1383,7 @@ static void ui_delete_active_linkline(uiBlock *block)
}
-static uiLinkLine *ui_is_a_link(uiBut *from, uiBut *to)
+static uiLinkLine *ui_but_find_link(uiBut *from, uiBut *to)
{
uiLinkLine *line;
uiLink *link;
@@ -1367,7 +1401,7 @@ static uiLinkLine *ui_is_a_link(uiBut *from, uiBut *to)
/* XXX BAD BAD HACK, fixme later **************** */
/* Try to add an AND Controller between the sensor and the actuator logic bricks and to connect them all */
-static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to)
+static void ui_but_smart_controller_add(bContext *C, uiBut *from, uiBut *to)
{
Object *ob = NULL;
bSensor *sens_iter;
@@ -1422,15 +1456,15 @@ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to)
/* (4) link the sensor->controller->actuator */
tmp_but = MEM_callocN(sizeof(uiBut), "uiBut");
- uiSetButLink(tmp_but, (void **)&cont, (void ***)&(cont->links), &(cont->totlinks), from->link->tocode, (int)to->hardmin);
+ UI_but_link_set(tmp_but, (void **)&cont, (void ***)&(cont->links), &(cont->totlinks), from->link->tocode, (int)to->hardmin);
tmp_but->hardmin = from->link->tocode;
tmp_but->poin = (char *)cont;
- tmp_but->type = INLINK;
- ui_add_link(C, from, tmp_but);
+ tmp_but->type = UI_BTYPE_INLINK;
+ ui_but_link_add(C, from, tmp_but);
- tmp_but->type = LINK;
- ui_add_link(C, tmp_but, to);
+ tmp_but->type = UI_BTYPE_LINK;
+ ui_but_link_add(C, tmp_but, to);
/* (5) garbage collection */
MEM_freeN(tmp_but->link);
@@ -1439,7 +1473,7 @@ static void ui_add_smart_controller(bContext *C, uiBut *from, uiBut *to)
WM_operator_properties_free(&props_ptr);
}
-static void ui_add_link(bContext *C, uiBut *from, uiBut *to)
+static void ui_but_link_add(bContext *C, uiBut *from, uiBut *to)
{
/* in 'from' we have to add a link to 'to' */
uiLink *link;
@@ -1447,22 +1481,22 @@ static void ui_add_link(bContext *C, uiBut *from, uiBut *to)
void **oldppoin;
int a;
- if ((line = ui_is_a_link(from, to))) {
+ if ((line = ui_but_find_link(from, to))) {
line->flag |= UI_SELECT;
- ui_delete_active_linkline(from->block);
+ ui_linkline_remove_active(from->block);
return;
}
- if (from->type == INLINK && to->type == INLINK) {
+ if (from->type == UI_BTYPE_INLINK && to->type == UI_BTYPE_INLINK) {
return;
}
- else if (from->type == LINK && to->type == INLINK) {
+ else if (from->type == UI_BTYPE_LINK && to->type == UI_BTYPE_INLINK) {
if (from->link->tocode != (int)to->hardmin) {
- ui_add_smart_controller(C, from, to);
+ ui_but_smart_controller_add(C, from, to);
return;
}
}
- else if (from->type == INLINK && to->type == LINK) {
+ else if (from->type == UI_BTYPE_INLINK && to->type == UI_BTYPE_LINK) {
if (to->link->tocode == (int)from->hardmin) {
return;
}
@@ -1497,15 +1531,15 @@ static void ui_apply_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data)
uiBut *bt;
for (bt = but->block->buttons.first; bt; bt = bt->next) {
- if (ui_mouse_inside_button(ar, bt, but->linkto[0] + ar->winrct.xmin, but->linkto[1] + ar->winrct.ymin) )
+ if (ui_but_contains_point_px(ar, bt, but->linkto[0] + ar->winrct.xmin, but->linkto[1] + ar->winrct.ymin) )
break;
}
if (bt && bt != but) {
- if (!ELEM(bt->type, LINK, INLINK) || !ELEM(but->type, LINK, INLINK))
+ if (!ELEM(bt->type, UI_BTYPE_LINK, UI_BTYPE_INLINK) || !ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK))
return;
- if (but->type == LINK) ui_add_link(C, but, bt);
- else ui_add_link(C, bt, but);
+ if (but->type == UI_BTYPE_LINK) ui_but_link_add(C, but, bt);
+ else ui_but_link_add(C, bt, but);
ui_apply_but_func(C, but);
data->retval = but->retval;
@@ -1542,7 +1576,7 @@ static void ui_apply_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDat
}
-static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const bool interactive)
+static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const bool interactive)
{
char *editstr;
double *editval;
@@ -1591,76 +1625,76 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
/* handle different types */
switch (but->type) {
- case BUT:
+ case UI_BTYPE_BUT:
ui_apply_but_BUT(C, but, data);
break;
- case TEX:
- case SEARCH_MENU_UNLINK:
- case SEARCH_MENU:
+ case UI_BTYPE_TEXT:
+ case UI_BTYPE_SEARCH_MENU_UNLINK:
+ case UI_BTYPE_SEARCH_MENU:
ui_apply_but_TEX(C, but, data);
break;
- case TOGBUT:
- case TOG:
- case ICONTOG:
- case ICONTOGN:
- case TOGN:
- case OPTION:
- case OPTIONN:
+ case UI_BTYPE_BUT_TOGGLE:
+ case UI_BTYPE_TOGGLE:
+ case UI_BTYPE_TOGGLE_N:
+ case UI_BTYPE_ICON_TOGGLE:
+ case UI_BTYPE_ICON_TOGGLE_N:
+ case UI_BTYPE_CHECKBOX:
+ case UI_BTYPE_CHECKBOX_N:
ui_apply_but_TOG(C, but, data);
break;
- case ROW:
- case LISTROW:
+ case UI_BTYPE_ROW:
+ case UI_BTYPE_LISTROW:
ui_apply_but_ROW(C, block, but, data);
break;
- case SCROLL:
- case GRIP:
- case NUM:
- case NUMSLI:
+ case UI_BTYPE_SCROLL:
+ case UI_BTYPE_GRIP:
+ case UI_BTYPE_NUM:
+ case UI_BTYPE_NUM_SLIDER:
ui_apply_but_NUM(C, but, data);
break;
- case MENU:
- case BLOCK:
- case PULLDOWN:
+ case UI_BTYPE_MENU:
+ case UI_BTYPE_BLOCK:
+ case UI_BTYPE_PULLDOWN:
ui_apply_but_BLOCK(C, but, data);
break;
- case COLOR:
+ case UI_BTYPE_COLOR:
if (data->cancel)
ui_apply_but_VEC(C, but, data);
else
ui_apply_but_BLOCK(C, but, data);
break;
- case BUTM:
+ case UI_BTYPE_BUT_MENU:
ui_apply_but_BUTM(C, but, data);
break;
- case BUT_NORMAL:
- case HSVCUBE:
- case HSVCIRCLE:
+ case UI_BTYPE_UNITVEC:
+ case UI_BTYPE_HSVCUBE:
+ case UI_BTYPE_HSVCIRCLE:
ui_apply_but_VEC(C, but, data);
break;
- case BUT_COLORBAND:
+ case UI_BTYPE_COLORBAND:
ui_apply_but_COLORBAND(C, but, data);
break;
- case BUT_CURVE:
+ case UI_BTYPE_CURVE:
ui_apply_but_CURVE(C, but, data);
break;
- case KEYEVT:
- case HOTKEYEVT:
+ case UI_BTYPE_KEY_EVENT:
+ case UI_BTYPE_HOTKEY_EVENT:
ui_apply_but_BUT(C, but, data);
break;
- case LINK:
- case INLINK:
+ case UI_BTYPE_LINK:
+ case UI_BTYPE_INLINK:
ui_apply_but_LINK(C, but, data);
break;
- case BUT_IMAGE:
+ case UI_BTYPE_IMAGE:
ui_apply_but_IMAGE(C, but, data);
break;
- case HISTOGRAM:
+ case UI_BTYPE_HISTOGRAM:
ui_apply_but_HISTOGRAM(C, but, data);
break;
- case WAVEFORM:
+ case UI_BTYPE_WAVEFORM:
ui_apply_but_WAVEFORM(C, but, data);
break;
- case TRACKPREVIEW:
+ case UI_BTYPE_TRACK_PREVIEW:
ui_apply_but_TRACKPREVIEW(C, but, data);
break;
default:
@@ -1698,13 +1732,13 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB
for (wmd = drags->first; wmd; wmd = wmd->next) {
if (wmd->type == WM_DRAG_ID) {
/* align these types with UI_but_active_drop_name */
- if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
ID *id = (ID *)wmd->poin;
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
BLI_strncpy(data->str, id->name + 2, data->maxlen);
- if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
but->changed = true;
ui_searchbox_update(C, data->searchbox, but, true);
}
@@ -1751,7 +1785,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* numeric value */
- if (ELEM(but->type, NUM, NUMSLI)) {
+ if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {
if (but->poin == NULL && but->rnapoin.data == NULL) {
/* pass */
@@ -1760,7 +1794,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* Get many decimal places, then strip trailing zeros.
* note: too high values start to give strange results (6 or so is ok) */
char buf_copy[UI_MAX_DRAW_STR];
- ui_get_but_string_ex(but, buf_copy, sizeof(buf_copy), 6);
+ ui_but_string_get_ex(but, buf_copy, sizeof(buf_copy), 6);
BLI_str_rstrip_float_zero(buf_copy, '\0');
WM_clipboard_text_set(buf_copy, 0);
@@ -1768,17 +1802,17 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
else {
double val;
- if (ui_set_but_string_eval_num(C, but, buf_paste, &val)) {
+ if (ui_but_string_set_eval_num(C, but, buf_paste, &val)) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
data->value = val;
- ui_set_but_string(C, but, buf_paste);
+ ui_but_string_set(C, but, buf_paste);
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
}
/* NORMAL button */
- else if (but->type == BUT_NORMAL) {
+ else if (but->type == UI_BTYPE_UNITVEC) {
float xyz[3];
if (but->poin == NULL && but->rnapoin.data == NULL) {
@@ -1786,7 +1820,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
else if (mode == 'c') {
char buf_copy[UI_MAX_DRAW_STR];
- ui_get_but_vectorf(but, xyz);
+ ui_but_v3_get(but, xyz);
BLI_snprintf(buf_copy, sizeof(buf_copy), "[%f, %f, %f]", xyz[0], xyz[1], xyz[2]);
WM_clipboard_text_set(buf_copy, 0);
}
@@ -1797,7 +1831,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
xyz[2] = 1.0;
}
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- ui_set_but_vectorf(but, xyz);
+ ui_but_v3_set(but, xyz);
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
@@ -1805,7 +1839,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* RGB triple */
- else if (but->type == COLOR) {
+ else if (but->type == UI_BTYPE_COLOR) {
float rgba[4];
if (but->poin == NULL && but->rnapoin.data == NULL) {
@@ -1819,7 +1853,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
else
rgba[3] = 1.0f;
- ui_get_but_vectorf(but, rgba);
+ ui_but_v3_get(but, rgba);
/* convert to linear color to do compatible copy between gamma and non-gamma */
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
srgb_to_linearrgb_v3_v3(rgba, rgba);
@@ -1835,7 +1869,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
linearrgb_to_srgb_v3_v3(rgba, rgba);
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- ui_set_but_vectorf(but, rgba);
+ ui_but_v3_set(but, rgba);
if (but->rnaprop && RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4)
RNA_property_float_set_index(&but->rnapoin, but->rnaprop, 3, rgba[3]);
@@ -1845,7 +1879,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
/* text/string and ID data */
- else if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ else if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
uiHandleButtonData *active_data = but->active;
if (but->poin == NULL && but->rnapoin.data == NULL) {
@@ -1860,12 +1894,12 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
else {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- if (ui_is_but_utf8(but))
+ if (ui_but_is_utf8(but))
BLI_strncpy_utf8(active_data->str, buf_paste, active_data->maxlen);
else
BLI_strncpy(active_data->str, buf_paste, active_data->maxlen);
- if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
/* else uiSearchboxData.active member is not updated [#26856] */
but->changed = true;
ui_searchbox_update(C, data->searchbox, but, true);
@@ -1874,7 +1908,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
}
/* colorband (not supported by system clipboard) */
- else if (but->type == BUT_COLORBAND) {
+ else if (but->type == UI_BTYPE_COLORBAND) {
if (mode == 'c') {
if (but->poin != NULL) {
memcpy(&but_copypaste_coba, but->poin, sizeof(ColorBand));
@@ -1891,7 +1925,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
}
}
- else if (but->type == BUT_CURVE) {
+ else if (but->type == UI_BTYPE_CURVE) {
if (mode == 'c') {
if (but->poin != NULL) {
but_copypaste_curve_alive = true;
@@ -1916,7 +1950,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
if (mode == 'c') {
PointerRNA *opptr;
char *str;
- opptr = uiButGetOperatorPtrRNA(but); /* allocated when needed, the button owns it */
+ opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */
str = WM_operator_pystring_ex(C, NULL, false, true, but->optype, opptr);
@@ -1926,8 +1960,8 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
}
/* menu (any type) */
- else if (ELEM(but->type, MENU, PULLDOWN)) {
- MenuType *mt = uiButGetMenuType(but);
+ else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
+ MenuType *mt = UI_but_menutype_get(but);
if (mt) {
char str[32 + sizeof(mt->idname)];
BLI_snprintf(str, sizeof(str), "bpy.ops.wm.call_menu(name=\"%s\")", mt->idname);
@@ -1971,7 +2005,7 @@ static int ui_text_position_to_hidden(uiBut *but, int pos)
return BLI_strnlen_utf8(butstr, pos);
}
-void ui_button_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *but, const bool restore)
+void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *but, const bool restore)
{
char *butstr;
@@ -2034,7 +2068,7 @@ static bool ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
*/
static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, const float x)
{
- uiStyle *style = UI_GetStyle(); // XXX pass on as arg
+ uiStyle *style = UI_style_get(); // XXX pass on as arg
uiFontStyle *fstyle = &style->widget;
const float aspect = but->block->aspect;
const short fstyle_points_prev = fstyle->points;
@@ -2047,18 +2081,18 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con
ui_fontscale(&fstyle->points, aspect);
- uiStyleFontSet(fstyle);
+ UI_fontstyle_set(fstyle);
if (fstyle->kerning == 1) /* for BLF_width */
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- ui_button_text_password_hide(password_str, but, false);
+ ui_but_text_password_hide(password_str, but, false);
origstr = MEM_mallocN(sizeof(char) * data->maxlen, "ui_textedit origstr");
BLI_strncpy(origstr, but->editstr, data->maxlen);
- if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
if (but->flag & UI_HAS_ICON) {
startx += UI_DPI_ICON_SIZE / aspect;
}
@@ -2128,7 +2162,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con
if (fstyle->kerning == 1)
BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- ui_button_text_password_hide(password_str, but, true);
+ ui_but_text_password_hide(password_str, but, true);
MEM_freeN(origstr);
@@ -2145,7 +2179,7 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data,
if (data->selextend == EXTEND_RIGHT) but->selend = but->pos;
else if (data->selextend == EXTEND_LEFT) but->selsta = but->pos;
- ui_check_but(but);
+ ui_but_update(but);
}
/* this is used for both utf8 and ascii, its meant to be used for single keys,
@@ -2185,7 +2219,7 @@ static bool ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char as
{
char buf[2] = {ascii, '\0'};
- if (ui_is_but_utf8(but) && (BLI_str_utf8_size(buf) == -1)) {
+ if (ui_but_is_utf8(but) && (BLI_str_utf8_size(buf) == -1)) {
printf("%s: entering invalid ascii char into an ascii key (%d)\n",
__func__, (int)(unsigned char)ascii);
@@ -2204,7 +2238,7 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, strCursorJump
const int pos_prev = but->pos;
const bool has_sel = (but->selend - but->selsta) > 0;
- ui_check_but(but);
+ ui_but_update(but);
/* special case, quit selection and set cursor */
if (has_sel && !select) {
@@ -2356,7 +2390,7 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in
/* paste */
if (mode == UI_TEXTEDIT_PASTE) {
- /* TODO, ensure UTF8 ui_is_but_utf8() - campbell */
+ /* TODO, ensure UTF8 ui_but_is_utf8() - campbell */
/* extract the first line from the clipboard */
pbuf = WM_clipboard_text_get_firstline(false, &buf_len);
@@ -2412,9 +2446,54 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in
return changed;
}
+#ifdef WITH_INPUT_IME
+/* enable ime, and set up uibut ime data */
+static void ui_textedit_ime_begin(wmWindow *win, uiBut *UNUSED(but))
+{
+ /* XXX Is this really needed? */
+ int x, y;
+
+ BLI_assert(win->ime_data == NULL);
+
+ /* enable IME and position to cursor, it's a trick */
+ x = win->eventstate->x;
+ /* flip y and move down a bit, prevent the IME panel cover the edit button */
+ y = win->eventstate->y - 12;
+
+ wm_window_IME_begin(win, x, y, 0, 0, true);
+}
+
+/* disable ime, and clear uibut ime data */
+static void ui_textedit_ime_end(wmWindow *win, uiBut *UNUSED(but))
+{
+ wm_window_IME_end(win);
+}
+
+void ui_but_ime_reposition(uiBut *but, int x, int y, bool complete)
+{
+ BLI_assert(but->active);
+
+ ui_region_to_window(but->active->region, &x, &y);
+ wm_window_IME_begin(but->active->window, x, y - 4, 0, 0, complete);
+}
+
+/* should be ui_but_ime_data_get */
+wmIMEData *ui_but_get_ime_data(uiBut *but)
+{
+ if (but->active && but->active->window) {
+ return but->active->window->ime_data;
+ }
+ else {
+ return NULL;
+ }
+}
+#endif /* WITH_INPUT_IME */
+
static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
{
+ wmWindow *win = CTX_wm_window(C);
int len;
+ const bool is_num_but = ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER);
if (data->str) {
MEM_freeN(data->str);
@@ -2426,7 +2505,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
if (data->applied_interactive) {
/* remove any small changes so canceling edit doesn't restore invalid value: T40538 */
data->cancel = true;
- ui_apply_button(C, but->block, but, data, true);
+ ui_apply_but(C, but->block, but, data, true);
data->cancel = false;
data->applied_interactive = false;
@@ -2434,16 +2513,16 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
#endif
/* retrieve string */
- data->maxlen = ui_get_but_string_max_length(but);
+ data->maxlen = ui_but_string_get_max_length(but);
data->str = MEM_callocN(sizeof(char) * data->maxlen + 1, "textedit str");
- ui_get_but_string(but, data->str, data->maxlen);
+ ui_but_string_get(but, data->str, data->maxlen);
- if (ui_is_but_float(but) && !ui_is_but_unit(but)) {
+ if (ui_but_is_float(but) && !ui_but_is_unit(but)) {
BLI_str_rstrip_float_zero(data->str, '\0');
}
- if (ELEM(but->type, NUM, NUMSLI)) {
- ui_convert_to_unit_alt_name(but, data->str, data->maxlen);
+ if (is_num_but) {
+ ui_but_convert_to_unit_alt_name(but, data->str, data->maxlen);
}
/* won't change from now on */
@@ -2460,7 +2539,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
but->selend = len;
/* optional searchbox */
- if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
data->searchbox = ui_searchbox_create(C, data->region, but);
ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */
}
@@ -2468,15 +2547,23 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
/* reset alert flag (avoid confusion, will refresh on exit) */
but->flag &= ~UI_BUT_REDALERT;
- ui_check_but(but);
-
- WM_cursor_modal_set(CTX_wm_window(C), BC_TEXTEDITCURSOR);
+ ui_but_update(but);
+
+ WM_cursor_modal_set(win, BC_TEXTEDITCURSOR);
+
+#ifdef WITH_INPUT_IME
+ if (is_num_but == false) {
+ ui_textedit_ime_begin(win, but);
+ }
+#endif
}
static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data)
{
+ wmWindow *win = CTX_wm_window(C);
+
if (but) {
- if (ui_is_but_utf8(but)) {
+ if (ui_but_is_utf8(but)) {
int strip = BLI_utf8_invalid_strip(but->editstr, strlen(but->editstr));
/* not a file?, strip non utf-8 chars */
if (strip) {
@@ -2505,7 +2592,13 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data)
but->pos = -1;
}
- WM_cursor_modal_restore(CTX_wm_window(C));
+ WM_cursor_modal_restore(win);
+
+#ifdef WITH_INPUT_IME
+ if (win->ime_data) {
+ ui_textedit_ime_end(win, but);
+ }
+#endif
}
static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data)
@@ -2513,11 +2606,11 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
uiBut *but;
/* label and roundbox can overlap real buttons (backdrops...) */
- if (ELEM(actbut->type, LABEL, SEPR, SEPRLINE, ROUNDBOX, LISTBOX))
+ if (ELEM(actbut->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX))
return;
for (but = actbut->next; but; but = but->next) {
- if (ELEM(but->type, TEX, NUM, NUMSLI, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ui_but_is_editable_as_text(but)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -2526,7 +2619,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
}
}
for (but = block->buttons.first; but != actbut; but = but->next) {
- if (ELEM(but->type, TEX, NUM, NUMSLI, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ui_but_is_editable_as_text(but)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -2541,11 +2634,11 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
uiBut *but;
/* label and roundbox can overlap real buttons (backdrops...) */
- if (ELEM(actbut->type, LABEL, SEPR, SEPRLINE, ROUNDBOX, LISTBOX))
+ if (ELEM(actbut->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX))
return;
for (but = actbut->prev; but; but = but->prev) {
- if (ELEM(but->type, TEX, NUM, NUMSLI, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ui_but_is_editable_as_text(but)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -2554,7 +2647,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa
}
}
for (but = block->buttons.last; but != actbut; but = but->prev) {
- if (ELEM(but->type, TEX, NUM, NUMSLI, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ui_but_is_editable_as_text(but)) {
if (!(but->flag & UI_BUT_DISABLED)) {
data->postbut = but;
data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
@@ -2570,6 +2663,14 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
int retval = WM_UI_HANDLER_CONTINUE;
bool changed = false, inbox = false, update = false;
+#ifdef WITH_INPUT_IME
+ wmWindow *win = CTX_wm_window(C);
+ wmIMEData *ime_data = win->ime_data;
+ bool is_ime_composing = ime_data && ime_data->is_ime_composing;
+#else
+ bool is_ime_composing = false;
+#endif
+
switch (event->type) {
case MOUSEMOVE:
case MOUSEPAN:
@@ -2590,6 +2691,12 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
case RIGHTMOUSE:
case ESCKEY:
if (event->val == KM_PRESS) {
+#ifdef WITH_INPUT_IME
+ /* skips button handling since it is not wanted */
+ if (is_ime_composing) {
+ break;
+ }
+#endif
data->cancel = true;
data->escapecancel = true;
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -2647,12 +2754,12 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
}
}
- if (event->val == KM_PRESS) {
+ if (event->val == KM_PRESS && !is_ime_composing) {
switch (event->type) {
case VKEY:
case XKEY:
case CKEY:
- if (event->ctrl || event->oskey) {
+ if (IS_EVENT_MOD(event, ctrl, oskey)) {
if (event->type == VKEY)
changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_PASTE);
else if (event->type == CKEY)
@@ -2725,10 +2832,10 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
/* Ctrl + A: Select all */
#if defined(__APPLE__)
/* OSX uses cmd-a systemwide, so add it */
- if ((event->oskey && !(event->alt || event->shift || event->ctrl)) ||
- (event->ctrl && !(event->alt || event->shift || event->oskey)))
+ if ((event->oskey && !IS_EVENT_MOD(event, shift, alt, ctrl)) ||
+ (event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey)))
#else
- if (event->ctrl && !(event->alt || event->shift || event->oskey))
+ if (event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey))
#endif
{
ui_textedit_move(but, data, STRCUR_DIR_PREV,
@@ -2751,7 +2858,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
update = true; /* do live update for tab key */
}
/* the hotkey here is not well defined, was G.qual so we check all */
- else if (event->shift || event->ctrl || event->alt || event->oskey) {
+ else if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
ui_textedit_prev_but(block, but, data);
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
@@ -2763,13 +2870,21 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
break;
}
- if ((event->ascii || event->utf8_buf[0]) && (retval == WM_UI_HANDLER_CONTINUE)) {
+ if ((event->ascii || event->utf8_buf[0]) &&
+ (retval == WM_UI_HANDLER_CONTINUE)
+#ifdef WITH_INPUT_IME
+ &&
+ !is_ime_composing &&
+ !WM_event_is_ime_switch(event)
+#endif
+ )
+ {
char ascii = event->ascii;
const char *utf8_buf = event->utf8_buf;
/* exception that's useful for number buttons, some keyboard
* numpads have a comma instead of a period */
- if (ELEM(but->type, NUM, NUMSLI)) { /* could use data->min*/
+ if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { /* could use data->min*/
if (event->type == PADPERIOD && ascii == ',') {
ascii = '.';
utf8_buf = NULL; /* force ascii fallback */
@@ -2793,18 +2908,38 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
retval = WM_UI_HANDLER_BREAK;
}
- /* textbutton with magnifier icon: do live update for search button */
- if (but->icon == ICON_VIEWZOOM)
+ /* textbutton with this flag: do live update (e.g. for search buttons) */
+ if (but->flag & UI_BUT_TEXTEDIT_UPDATE) {
update = true;
+ }
+ }
+
+#ifdef WITH_INPUT_IME
+ if (event->type == WM_IME_COMPOSITE_START || event->type == WM_IME_COMPOSITE_EVENT) {
+ changed = true;
+
+ if (event->type == WM_IME_COMPOSITE_START && but->selend > but->selsta) {
+ ui_textedit_delete_selection(but, data);
+ }
+ if (event->type == WM_IME_COMPOSITE_EVENT && ime_data->result_len) {
+ ui_textedit_type_buf(
+ but, data,
+ ime_data->str_result,
+ ime_data->result_len);
+ }
+ }
+ else if (event->type == WM_IME_COMPOSITE_END) {
+ changed = true;
}
+#endif
if (changed) {
/* only update when typing for TAB key */
if (update && data->interactive) {
- ui_apply_button(C, block, but, data, true);
+ ui_apply_but(C, block, but, data, true);
}
else {
- ui_check_but(but);
+ ui_but_update(but);
}
but->changed = true;
@@ -2839,7 +2974,7 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u
}
if (retval == WM_UI_HANDLER_BREAK) {
- ui_check_but(but);
+ ui_but_update(but);
ED_region_tag_redraw(data->region);
}
}
@@ -2848,22 +2983,22 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u
static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
{
- if (but->type == BUT_CURVE) {
+ if (but->type == UI_BTYPE_CURVE) {
but->editcumap = (CurveMapping *)but->poin;
}
- else if (but->type == BUT_COLORBAND) {
+ else if (but->type == UI_BTYPE_COLORBAND) {
data->coba = (ColorBand *)but->poin;
but->editcoba = data->coba;
}
- else if (ELEM(but->type, BUT_NORMAL, HSVCUBE, HSVCIRCLE, COLOR)) {
- ui_get_but_vectorf(but, data->origvec);
+ else if (ELEM(but->type, UI_BTYPE_UNITVEC, UI_BTYPE_HSVCUBE, UI_BTYPE_HSVCIRCLE, UI_BTYPE_COLOR)) {
+ ui_but_v3_get(but, data->origvec);
copy_v3_v3(data->vec, data->origvec);
but->editvec = data->vec;
}
else {
float softrange, softmin, softmax;
- data->startvalue = ui_get_but_val(but);
+ data->startvalue = ui_but_value_get(but);
data->origvalue = data->startvalue;
data->value = data->origvalue;
but->editval = &data->value;
@@ -2897,10 +3032,10 @@ static void ui_numedit_end(uiBut *but, uiHandleButtonData *data)
static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
{
if (data->interactive) {
- ui_apply_button(C, block, but, data, true);
+ ui_apply_but(C, block, but, data, true);
}
else {
- ui_check_but(but);
+ ui_but_update(but);
}
ED_region_tag_redraw(data->region);
@@ -2908,7 +3043,7 @@ static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
/* ****************** menu opening for various types **************** */
-static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
+static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
{
uiBlockCreateFunc func = NULL;
uiBlockHandleCreateFunc handlefunc = NULL;
@@ -2916,8 +3051,8 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data
void *arg = NULL;
switch (but->type) {
- case BLOCK:
- case PULLDOWN:
+ case UI_BTYPE_BLOCK:
+ case UI_BTYPE_PULLDOWN:
if (but->menu_create_func) {
menufunc = but->menu_create_func;
arg = but->poin;
@@ -2927,13 +3062,13 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data
arg = but->poin ? but->poin : but->func_argN;
}
break;
- case MENU:
+ case UI_BTYPE_MENU:
BLI_assert(but->menu_create_func);
menufunc = but->menu_create_func;
arg = but->poin;
break;
- case COLOR:
- ui_get_but_vectorf(but, data->origvec);
+ case UI_BTYPE_COLOR:
+ ui_but_v3_get(but, data->origvec);
copy_v3_v3(data->vec, data->origvec);
but->editvec = data->vec;
@@ -2961,7 +3096,7 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data
//if (but->block->auto_open == 0) but->block->auto_open = 1;
}
-static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data)
+static void ui_block_open_end(bContext *C, uiBut *but, uiHandleButtonData *data)
{
if (but) {
but->editval = NULL;
@@ -2976,7 +3111,7 @@ static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data)
}
}
-int ui_button_open_menu_direction(uiBut *but)
+int ui_but_menu_direction(uiBut *but)
{
uiHandleButtonData *data = but->active;
@@ -2986,14 +3121,14 @@ int ui_button_open_menu_direction(uiBut *but)
return 0;
}
-/* Hack for uiList LISTROW buttons to "give" events to overlaying TEX buttons (cltr-clic rename feature & co). */
+/* Hack for uiList UI_BTYPE_LISTROW buttons to "give" events to overlaying UI_BTYPE_TEXT buttons (cltr-clic rename feature & co). */
static uiBut *ui_but_list_row_text_activate(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event,
uiButtonActivateType activate_type)
{
ARegion *ar = CTX_wm_region(C);
uiBut *labelbut = ui_but_find_mouse_over_ex(ar, event->x, event->y, true);
- if (labelbut && labelbut->type == TEX && !(labelbut->flag & UI_BUT_DISABLED)) {
+ if (labelbut && labelbut->type == UI_BTYPE_TEXT && !(labelbut->flag & UI_BUT_DISABLED)) {
/* exit listrow */
data->cancel = true;
button_activate_exit(C, but, data, false, false);
@@ -3050,16 +3185,16 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data
}
}
else if (data->state == BUTTON_STATE_WAIT_KEY_EVENT) {
-
- if (event->type == MOUSEMOVE)
+ if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
return WM_UI_HANDLER_CONTINUE;
-
+ }
+
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
/* only cancel if click outside the button */
- if (ui_mouse_inside_button(but->active->region, but, event->x, event->y) == 0) {
+ if (ui_but_contains_point_px(but->active->region, but, event->x, event->y) == 0) {
/* data->cancel doesnt work, this button opens immediate */
if (but->flag & UI_BUT_IMMEDIATE)
- ui_set_but_val(but, 0);
+ ui_but_value_set(but, 0);
else
data->cancel = true;
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -3074,14 +3209,14 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data
if (event->ctrl) but->modifier_key |= KM_CTRL;
if (event->oskey) but->modifier_key |= KM_OSKEY;
- ui_check_but(but);
+ ui_but_update(but);
ED_region_tag_redraw(data->region);
if (event->val == KM_PRESS) {
if (ISHOTKEY(event->type)) {
if (WM_key_event_string(event->type)[0])
- ui_set_but_val(but, event->type);
+ ui_but_value_set(but, event->type);
else
data->cancel = true;
@@ -3117,7 +3252,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, c
if (event->val == KM_PRESS) {
if (WM_key_event_string(event->type)[0])
- ui_set_but_val(but, event->type);
+ ui_but_value_set(but, event->type);
else
data->cancel = true;
@@ -3132,10 +3267,10 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) {
- if (ELEM(event->type, PADENTER, RETKEY) && (!ui_is_but_utf8(but))) {
+ if (ELEM(event->type, PADENTER, RETKEY) && (!ui_but_is_utf8(but))) {
/* pass - allow filesel, enter to execute */
}
- else if (but->dt == UI_EMBOSSN && !event->ctrl) {
+ else if (but->dt == UI_EMBOSS_NONE && !event->ctrl) {
/* pass */
}
else {
@@ -3160,7 +3295,7 @@ static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHa
{
/* unlink icon is on right */
if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS &&
- ui_is_but_search_unlink_visible(but))
+ ui_but_is_search_unlink_visible(but))
{
ARegion *ar = data->region;
rcti rect;
@@ -3190,12 +3325,12 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons
{
#ifdef USE_DRAG_TOGGLE
if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_is_but_drag_toggle(but)) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_but_is_drag_toggle(but)) {
#if 0 /* UNUSED */
data->togdual = event->ctrl;
data->togonly = !event->shift;
#endif
- ui_apply_button(C, but->block, but, data, true);
+ ui_apply_but(C, but->block, but, data, true);
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
data->dragstarty = event->y;
@@ -3217,6 +3352,38 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons
button_activate_state(C, but, BUTTON_STATE_EXIT);
return WM_UI_HANDLER_BREAK;
}
+ else if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ /* Support alt+wheel on expanded enum rows */
+ if (but->type == UI_BTYPE_ROW) {
+ const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
+ uiBut *but_select = ui_but_find_select_in_enum(but, direction);
+ if (but_select) {
+ uiBut *but_other = (direction == -1) ? but_select->next : but_select->prev;
+ if (but_other && ui_but_find_select_in_enum__cmp(but, but_other)) {
+ ARegion *ar = data->region;
+
+ data->cancel = true;
+ button_activate_exit(C, but, data, false, false);
+
+ /* Activate the text button. */
+ button_activate_init(C, ar, but_other, BUTTON_ACTIVATE_OVER);
+ data = but_other->active;
+ if (data) {
+ ui_apply_but(C, but->block, but_other, but_other->active, true);
+ button_activate_exit(C, but_other, data, false, false);
+
+ /* restore active button */
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+ }
+ else {
+ /* shouldn't happen */
+ BLI_assert(0);
+ }
+ }
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
}
return WM_UI_HANDLER_CONTINUE;
}
@@ -3228,7 +3395,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con
/* first handle click on icondrag type button */
if (event->type == LEFTMOUSE && but->dragpoin) {
- if (ui_but_mouse_inside_icon(but, data->region, event)) {
+ if (ui_but_contains_point_px_icon(but, data->region, event)) {
/* tell the button to wait and keep checking further events to
* see if it should start dragging */
@@ -3239,7 +3406,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con
}
}
#ifdef USE_DRAG_TOGGLE
- if (event->type == LEFTMOUSE && ui_is_but_drag_toggle(but)) {
+ if (event->type == LEFTMOUSE && ui_but_is_drag_toggle(but)) {
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
data->dragstarty = event->y;
@@ -3250,7 +3417,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con
if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
int ret = WM_UI_HANDLER_BREAK;
/* XXX (a bit ugly) Special case handling for filebrowser drag button */
- if (but->dragpoin && but->imb && ui_but_mouse_inside_icon(but, data->region, event)) {
+ if (but->dragpoin && but->imb && ui_but_contains_point_px_icon(but, data->region, event)) {
ret = WM_UI_HANDLER_CONTINUE;
}
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -3260,7 +3427,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con
else if (data->state == BUTTON_STATE_WAIT_DRAG) {
/* this function also ends state */
- if (ui_but_start_drag(C, but, data, event)) {
+ if (ui_but_drag_init(C, but, data, event)) {
return WM_UI_HANDLER_BREAK;
}
@@ -3290,9 +3457,9 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa
else {
float fac = 1.0f;
- if (ui_is_but_unit(but)) {
+ if (ui_but_is_unit(but)) {
UnitSettings *unit = but->block->unit;
- int unit_type = RNA_SUBTYPE_UNIT_VALUE(uiButGetUnitType(but));
+ int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
if (bUnit_IsValid(unit->system, unit_type)) {
fac = (float)bUnit_BaseScalar(unit->system, unit_type);
@@ -3358,7 +3525,7 @@ static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data,
float deler, tempf, softmin, softmax, softrange;
int lvalue, temp;
bool changed = false;
- const bool is_float = ui_is_but_float(but);
+ const bool is_float = ui_but_is_float(but);
if (mx == data->draglastx)
return changed;
@@ -3382,7 +3549,7 @@ static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data,
softmax = but->softmax;
softrange = softmax - softmin;
- if (ui_is_a_warp_but(but)) {
+ if (ui_but_is_cursor_warp(but)) {
/* Mouse location isn't screen clamped to the screen so use a linear mapping
* 2px == 1-int, or 1px == 1-ClickStep */
if (is_float) {
@@ -3536,7 +3703,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
retval = WM_UI_HANDLER_BREAK;
}
else if (event->type == LEFTMOUSE) {
- data->dragstartx = data->draglastx = ui_is_a_warp_but(but) ? screen_mx : mx;
+ data->dragstartx = data->draglastx = ui_but_is_cursor_warp(but) ? screen_mx : mx;
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
retval = WM_UI_HANDLER_BREAK;
}
@@ -3581,7 +3748,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
click = 1;
}
}
- else if (event->type == MOUSEMOVE) {
+ else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
const enum eSnapType snap = ui_event_to_snap(event);
float fac;
@@ -3594,7 +3761,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
if (event->shift) fac /= 10.0f;
if (event->alt) fac /= 20.0f;
- if (ui_numedit_but_NUM(but, data, (ui_is_a_warp_but(but) ? screen_mx : mx), snap, fac))
+ if (ui_numedit_but_NUM(but, data, (ui_but_is_cursor_warp(but) ? screen_mx : mx), snap, fac))
ui_numedit_apply(C, block, but, data);
#ifdef USE_DRAG_MULTINUM
else if (data->multi_data.has_mbuts) {
@@ -3627,7 +3794,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
handlewidth = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect));
- if (!ui_is_but_float(but)) {
+ if (!ui_but_is_float(but)) {
if (mx < (but->rect.xmin + handlewidth)) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
@@ -3705,11 +3872,11 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
/* yes, 'mx' as both x/y is intentional */
ui_mouse_scale_warp(data, mx, mx, &mx_fl, &my_fl, shift);
- if (but->type == NUMSLI) {
+ if (but->type == UI_BTYPE_NUM_SLIDER) {
offs = (BLI_rctf_size_y(&but->rect) / 2.0f);
deler = BLI_rctf_size_x(&but->rect) - offs;
}
- else if (but->type == SCROLL) {
+ else if (but->type == UI_BTYPE_SCROLL) {
const float size = (is_horizontal) ? BLI_rctf_size_x(&but->rect) : -BLI_rctf_size_y(&but->rect);
deler = size * (but->softmax - but->softmin) / (but->softmax - but->softmin + but->a1);
offs = 0.0;
@@ -3725,7 +3892,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
/* deal with mouse correction */
#ifdef USE_CONT_MOUSE_CORRECT
- if (ui_is_a_warp_but(but)) {
+ if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
if (is_horizontal) {
data->ungrab_mval[0] = (but->rect.xmin + offs) + (f * deler);
@@ -3748,7 +3915,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
if (tempf == softmin || tempf == softmax) {
/* pass */
}
- else if (ui_is_but_float(but)) {
+ else if (ui_but_is_float(but)) {
if (shift) {
if (tempf == softmin || tempf == softmax) {}
@@ -3768,7 +3935,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
}
}
- if (!ui_is_but_float(but)) {
+ if (!ui_but_is_float(but)) {
lvalue = floor(data->value + 0.5);
CLAMP(temp, softmin, softmax);
@@ -3824,7 +3991,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
retval = WM_UI_HANDLER_BREAK;
}
- /* alt-click on sides to get "arrows" like in NUM buttons, and match wheel usage above */
+ /* alt-click on sides to get "arrows" like in UI_BTYPE_NUM buttons, and match wheel usage above */
else if (event->type == LEFTMOUSE && event->alt) {
int halfpos = BLI_rctf_cent_x(&but->rect);
click = 2;
@@ -3878,7 +4045,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
click = 1;
}
}
- else if (event->type == MOUSEMOVE) {
+ else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
#ifdef USE_DRAG_MULTINUM
data->multi_data.drag_dir[0] += abs(data->draglastx - mx);
data->multi_data.drag_dir[1] += abs(data->draglasty - my);
@@ -3932,7 +4099,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
f = softmin + f * softrange;
- if (!ui_is_but_float(but)) {
+ if (!ui_but_is_float(but)) {
if (f < temp) temp--;
else temp++;
@@ -4098,7 +4265,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
/* first handle click on icondrag type button */
if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
- if (ui_but_mouse_inside_icon(but, data->region, event)) {
+ if (ui_but_contains_point_px_icon(but, data->region, event)) {
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
data->dragstarty = event->y;
@@ -4106,7 +4273,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
}
#ifdef USE_DRAG_TOGGLE
- if (event->type == LEFTMOUSE && event->val == KM_PRESS && (ui_is_but_drag_toggle(but))) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS && (ui_but_is_drag_toggle(but))) {
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
data->dragstarty = event->y;
@@ -4118,14 +4285,14 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
return WM_UI_HANDLER_BREAK;
}
- else if (but->type == MENU) {
+ else if (but->type == UI_BTYPE_MENU) {
if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
- data->value = ui_step_name_menu(but, direction);
+ data->value = ui_but_menu_step(but, direction);
button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_apply_button(C, but->block, but, data, true);
+ ui_apply_but(C, but->block, but, data, true);
/* button's state need to be changed to EXIT so moving mouse away from this mouse wouldn't lead
* to cancel changes made to this button, but changing state to EXIT also makes no button active for
@@ -4154,12 +4321,12 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
else if (data->state == BUTTON_STATE_WAIT_DRAG) {
/* this function also ends state */
- if (ui_but_start_drag(C, but, data, event)) {
+ if (ui_but_drag_init(C, but, data, event)) {
return WM_UI_HANDLER_BREAK;
}
/* outside icon quit, not needed if drag activated */
- if (0 == ui_but_mouse_inside_icon(but, data->region, event)) {
+ if (0 == ui_but_contains_point_px_icon(but, data->region, event)) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
data->cancel = true;
return WM_UI_HANDLER_BREAK;
@@ -4175,7 +4342,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
return WM_UI_HANDLER_CONTINUE;
}
-static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data,
+static bool ui_numedit_but_UNITVEC(uiBut *but, uiHandleButtonData *data,
int mx, int my,
const enum eSnapType snap)
{
@@ -4271,7 +4438,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
/* first handle click on icondrag type button */
if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
ui_palette_set_active(but);
- if (ui_but_mouse_inside_icon(but, data->region, event)) {
+ if (ui_but_contains_point_px_icon(but, data->region, event)) {
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
data->dragstarty = event->y;
@@ -4294,10 +4461,12 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
return WM_UI_HANDLER_BREAK;
}
else if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
- float *hsv = ui_block_hsv_get(but->block);
+ ColorPicker *cpicker = but->custom_data;
+ float hsv_static[3] = {0.0f};
+ float *hsv = cpicker ? cpicker->color_data : hsv_static;
float col[3];
- ui_get_but_vectorf(but, col);
+ ui_but_v3_get(but, col);
rgb_to_hsv_compat_v(col, hsv);
if (event->type == WHEELDOWNMOUSE)
@@ -4310,10 +4479,10 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
hsv_to_rgb_v(hsv, data->vec);
- ui_set_but_vectorf(but, data->vec);
+ ui_but_v3_set(but, data->vec);
button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_apply_button(C, but->block, but, data, true);
+ ui_apply_but(C, but->block, but, data, true);
return WM_UI_HANDLER_BREAK;
}
else if ((int)(but->a1) == UI_PALETTE_COLOR &&
@@ -4331,12 +4500,12 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
else if (data->state == BUTTON_STATE_WAIT_DRAG) {
/* this function also ends state */
- if (ui_but_start_drag(C, but, data, event)) {
+ if (ui_but_drag_init(C, but, data, event)) {
return WM_UI_HANDLER_BREAK;
}
/* outside icon quit, not needed if drag activated */
- if (0 == ui_but_mouse_inside_icon(but, data->region, event)) {
+ if (0 == ui_but_contains_point_px_icon(but, data->region, event)) {
button_activate_state(C, but, BUTTON_STATE_EXIT);
data->cancel = true;
return WM_UI_HANDLER_BREAK;
@@ -4355,7 +4524,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target);
- ui_block_to_scene_linear_v3(but->block, target);
+ ui_block_cm_to_scene_linear_v3(but->block, target);
}
else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target);
@@ -4368,7 +4537,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, color);
- ui_block_to_display_space_v3(but->block, color);
+ ui_block_cm_to_display_space_v3(but->block, color);
BKE_brush_color_set(scene, brush, color);
}
}
@@ -4390,7 +4559,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
return WM_UI_HANDLER_CONTINUE;
}
-static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+static int ui_do_but_UNITVEC(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
int mx, my;
@@ -4408,17 +4577,17 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
/* also do drag the first time */
- if (ui_numedit_but_NORMAL(but, data, mx, my, snap))
+ if (ui_numedit_but_UNITVEC(but, data, mx, my, snap))
ui_numedit_apply(C, block, but, data);
return WM_UI_HANDLER_BREAK;
}
}
else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == MOUSEMOVE) {
- if (mx != data->draglastx || my != data->draglasty) {
+ if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
+ if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
const enum eSnapType snap = ui_event_to_snap(event);
- if (ui_numedit_but_NORMAL(but, data, mx, my, snap))
+ if (ui_numedit_but_UNITVEC(but, data, mx, my, snap))
ui_numedit_apply(C, block, but, data);
}
}
@@ -4473,17 +4642,18 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
int mx, int my,
const enum eSnapType snap, const bool shift)
{
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
float rgb[3];
- float *hsv = ui_block_hsv_get(but->block);
float x, y;
float mx_fl, my_fl;
bool changed = true;
- bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
+ bool use_display_colorspace = ui_but_is_colorpicker_display_space(but);
ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
#ifdef USE_CONT_MOUSE_CORRECT
- if (ui_is_a_warp_but(but)) {
+ if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
data->ungrab_mval[0] = mx_fl;
data->ungrab_mval[1] = my_fl;
@@ -4491,10 +4661,10 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
}
#endif
- ui_get_but_vectorf(but, rgb);
+ ui_but_v3_get(but, rgb);
if (use_display_colorspace)
- ui_block_to_display_space_v3(but->block, rgb);
+ ui_block_cm_to_display_space_v3(but->block, rgb);
ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
@@ -4508,9 +4678,9 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
/* calculate original hsv again */
copy_v3_v3(rgb, data->origvec);
if (use_display_colorspace)
- ui_block_to_display_space_v3(but->block, rgb);
+ ui_block_cm_to_display_space_v3(but->block, rgb);
- copy_v3_v3(hsvo, ui_block_hsv_get(but->block));
+ copy_v3_v3(hsvo, hsv);
ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsvo);
@@ -4572,7 +4742,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
ui_color_picker_to_rgb_HSVCUBE_v(but, hsv, rgb);
if (use_display_colorspace)
- ui_block_to_scene_linear_v3(but->block, rgb);
+ ui_block_cm_to_scene_linear_v3(but->block, rgb);
/* clamp because with color conversion we can exceed range [#34295] */
if (but->a1 == UI_GRAD_V_ALT) {
@@ -4591,16 +4761,17 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
const wmNDOFMotionData *ndof,
const enum eSnapType snap, const bool shift)
{
- float *hsv = ui_block_hsv_get(but->block);
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
const float hsv_v_max = max_ff(hsv[2], but->softmax);
float rgb[3];
float sensitivity = (shift ? 0.15f : 0.3f) * ndof->dt;
- bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
+ bool use_display_colorspace = ui_but_is_colorpicker_display_space(but);
- ui_get_but_vectorf(but, rgb);
+ ui_but_v3_get(but, rgb);
if (use_display_colorspace)
- ui_block_to_display_space_v3(but->block, rgb);
+ ui_block_cm_to_display_space_v3(but->block, rgb);
ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
@@ -4652,10 +4823,10 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
ui_color_picker_to_rgb_HSVCUBE_v(but, hsv, rgb);
if (use_display_colorspace)
- ui_block_to_scene_linear_v3(but->block, rgb);
+ ui_block_cm_to_scene_linear_v3(but->block, rgb);
copy_v3_v3(data->vec, rgb);
- ui_set_but_vectorf(but, data->vec);
+ ui_but_v3_set(but, data->vec);
}
static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
@@ -4689,7 +4860,7 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
ui_ndofedit_but_HSVCUBE(but, data, ndof, snap, event->shift != 0);
button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_apply_button(C, but->block, but, data, true);
+ ui_apply_but(C, but->block, but, data, true);
return WM_UI_HANDLER_BREAK;
}
@@ -4704,19 +4875,20 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
if (ELEM(len, 3, 4)) {
float rgb[3], def_hsv[3];
float def[4];
- float *hsv = ui_block_hsv_get(but->block);
-
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+
RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
ui_rgb_to_color_picker_HSVCUBE_v(but, def, def_hsv);
- ui_get_but_vectorf(but, rgb);
+ ui_but_v3_get(but, rgb);
ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
def_hsv[0] = hsv[0];
def_hsv[1] = hsv[1];
ui_color_picker_to_rgb_HSVCUBE_v(but, def_hsv, rgb);
- ui_set_but_vectorf(but, rgb);
+ ui_but_v3_set(but, rgb);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
return WM_UI_HANDLER_BREAK;
@@ -4732,8 +4904,8 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
}
- else if (event->type == MOUSEMOVE) {
- if (mx != data->draglastx || my != data->draglasty) {
+ else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
+ if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
const enum eSnapType snap = ui_event_to_snap(event);
if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->shift != 0))
@@ -4758,13 +4930,14 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
bool changed = true;
float mx_fl, my_fl;
float rgb[3];
- float *hsv = ui_block_hsv_get(but->block);
- bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+ bool use_display_colorspace = ui_but_is_colorpicker_display_space(but);
ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
#ifdef USE_CONT_MOUSE_CORRECT
- if (ui_is_a_warp_but(but)) {
+ if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
data->ungrab_mval[0] = mx_fl;
data->ungrab_mval[1] = my_fl;
@@ -4781,9 +4954,9 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
BLI_rcti_rctf_copy(&rect, &but->rect);
- ui_get_but_vectorf(but, rgb);
+ ui_but_v3_get(but, rgb);
if (use_display_colorspace)
- ui_block_to_display_space_v3(but->block, rgb);
+ ui_block_cm_to_display_space_v3(but->block, rgb);
ui_rgb_to_color_picker_compat_v(rgb, hsv);
@@ -4794,8 +4967,8 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
if (hsv[2] == 0.f) hsv[2] = 0.0001f;
}
else {
- if (hsv[2] == 0.f) hsv[2] = 0.0001f;
- if (hsv[2] == 1.f) hsv[2] = 0.9999f;
+ if (hsv[2] == 0.0f) hsv[2] = 0.0001f;
+ if (hsv[2] >= 0.9999f) hsv[2] = 0.9999f;
}
}
@@ -4804,10 +4977,10 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
float xpos, ypos, hsvo[3], rgbo[3];
/* calculate original hsv again */
- copy_v3_v3(hsvo, ui_block_hsv_get(but->block));
+ copy_v3_v3(hsvo, hsv);
copy_v3_v3(rgbo, data->origvec);
if (use_display_colorspace)
- ui_block_to_display_space_v3(but->block, rgbo);
+ ui_block_cm_to_display_space_v3(but->block, rgbo);
ui_rgb_to_color_picker_compat_v(rgbo, hsvo);
@@ -4836,9 +5009,9 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
}
if (use_display_colorspace)
- ui_block_to_scene_linear_v3(but->block, rgb);
+ ui_block_cm_to_scene_linear_v3(but->block, rgb);
- ui_set_but_vectorf(but, rgb);
+ ui_but_v3_set(but, rgb);
data->draglastx = mx;
data->draglasty = my;
@@ -4850,15 +5023,16 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
const wmNDOFMotionData *ndof,
const enum eSnapType snap, const bool shift)
{
- float *hsv = ui_block_hsv_get(but->block);
- bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+ bool use_display_colorspace = ui_but_is_colorpicker_display_space(but);
float rgb[3];
float phi, r /*, sqr */ /* UNUSED */, v[2];
float sensitivity = (shift ? 0.06f : 0.3f) * ndof->dt;
- ui_get_but_vectorf(but, rgb);
+ ui_but_v3_get(but, rgb);
if (use_display_colorspace)
- ui_block_to_display_space_v3(but->block, rgb);
+ ui_block_cm_to_display_space_v3(but->block, rgb);
ui_rgb_to_color_picker_compat_v(rgb, hsv);
/* Convert current color on hue/sat disc to circular coordinates phi, r */
@@ -4911,14 +5085,16 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
}
if (use_display_colorspace)
- ui_block_to_scene_linear_v3(but->block, data->vec);
+ ui_block_cm_to_scene_linear_v3(but->block, data->vec);
- ui_set_but_vectorf(but, data->vec);
+ ui_but_v3_set(but, data->vec);
}
static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
int mx, my;
mx = event->x;
my = event->y;
@@ -4946,7 +5122,7 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle
ui_ndofedit_but_HSVCIRCLE(but, data, ndof, snap, event->shift != 0);
button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_apply_button(C, but->block, but, data, true);
+ ui_apply_but(C, but->block, but, data, true);
return WM_UI_HANDLER_BREAK;
}
@@ -4960,20 +5136,19 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle
if (len >= 3) {
float rgb[3], def_hsv[3];
float *def;
- float *hsv = ui_block_hsv_get(but->block);
def = MEM_callocN(sizeof(float) * len, "reset_defaults - float");
RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
ui_color_picker_to_rgb_v(def, def_hsv);
- ui_get_but_vectorf(but, rgb);
+ ui_but_v3_get(but, rgb);
ui_rgb_to_color_picker_compat_v(rgb, hsv);
def_hsv[0] = hsv[0];
def_hsv[2] = hsv[2];
hsv_to_rgb_v(def_hsv, rgb);
- ui_set_but_vectorf(but, rgb);
+ ui_but_v3_set(but, rgb);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
@@ -4992,19 +5167,17 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle
}
/* XXX hardcoded keymap check.... */
else if (event->type == WHEELDOWNMOUSE) {
- float *hsv = ui_block_hsv_get(but->block);
hsv[2] = CLAMPIS(hsv[2] - 0.05f, 0.0f, 1.0f);
- ui_set_but_hsv(but); /* converts to rgb */
+ ui_but_hsv_set(but); /* converts to rgb */
ui_numedit_apply(C, block, but, data);
}
else if (event->type == WHEELUPMOUSE) {
- float *hsv = ui_block_hsv_get(but->block);
hsv[2] = CLAMPIS(hsv[2] + 0.05f, 0.0f, 1.0f);
- ui_set_but_hsv(but); /* converts to rgb */
+ ui_but_hsv_set(but); /* converts to rgb */
ui_numedit_apply(C, block, but, data);
}
- else if (event->type == MOUSEMOVE) {
- if (mx != data->draglastx || my != data->draglasty) {
+ else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
+ if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
const enum eSnapType snap = ui_event_to_snap(event);
if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->shift != 0)) {
@@ -5177,7 +5350,7 @@ static bool ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData
#ifdef USE_CONT_MOUSE_CORRECT
/* note: using 'cmp_last' is weak since there may be multiple points selected,
* but in practice this isnt really an issue */
- if (ui_is_a_warp_but(but)) {
+ if (ui_but_is_cursor_warp(but)) {
/* OK but can go outside bounds */
data->ungrab_mval[0] = but->rect.xmin + ((cmp_last->x - cumap->curr.xmin) * zoomx);
data->ungrab_mval[1] = but->rect.ymin + ((cmp_last->y - cumap->curr.ymin) * zoomy);
@@ -5375,7 +5548,7 @@ static bool ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int m
float dy = my - data->draglasty;
/* scale histogram values (dy / 10 for better control) */
- const float yfac = min_ff(powf(hist->ymax, 2.0f), 1.0f) * 0.5f;
+ const float yfac = min_ff(pow2f(hist->ymax), 1.0f) * 0.5f;
hist->ymax += (dy * 0.1f) * yfac;
/* 0.1 allows us to see HDR colors up to 10 */
@@ -5653,7 +5826,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
wmKeyMapItem *kmi;
PointerRNA ptr;
uiLayout *layout;
- uiStyle *style = UI_GetStyleDraw();
+ uiStyle *style = UI_style_get_dpi();
IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km);
@@ -5661,20 +5834,24 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
- block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
- uiBlockSetHandleFunc(block, but_shortcut_name_func, but);
- uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
- uiBlockSetDirection(block, UI_CENTER);
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_func_handle_set(block, but_shortcut_name_func, but);
+ UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
+ UI_block_direction_set(block, UI_DIR_CENTER_Y);
- layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
+ layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
- uiPopupBoundsBlock(block, 6, -50, 26);
+ UI_block_bounds_set_popup(block, 6, -50, 26);
return block;
}
+#ifdef USE_KEYMAP_ADD_HACK
+static int g_kmi_id_hack;
+#endif
+
static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
{
wmWindowManager *wm = CTX_wm_manager(C);
@@ -5684,7 +5861,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
wmKeyMapItem *kmi;
PointerRNA ptr;
uiLayout *layout;
- uiStyle *style = UI_GetStyleDraw();
+ uiStyle *style = UI_style_get_dpi();
IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
int kmi_id;
@@ -5706,16 +5883,19 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
- block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
- uiBlockSetHandleFunc(block, but_shortcut_name_func, but);
- uiBlockSetDirection(block, UI_CENTER);
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_func_handle_set(block, but_shortcut_name_func, but);
+ UI_block_direction_set(block, UI_DIR_CENTER_Y);
- layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
+ layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
- uiPopupBoundsBlock(block, 6, -50, 26);
-
+ UI_block_bounds_set_popup(block, 6, -50, 26);
+
+#ifdef USE_KEYMAP_ADD_HACK
+ g_kmi_id_hack = kmi_id;
+#endif
return block;
}
@@ -5724,9 +5904,20 @@ static void menu_add_shortcut_cancel(struct bContext *C, void *arg1)
uiBut *but = (uiBut *)arg1;
wmKeyMap *km;
wmKeyMapItem *kmi;
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
- int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km);
-
+#ifndef USE_KEYMAP_ADD_HACK
+ IDProperty *prop;
+#endif
+ int kmi_id;
+
+#ifdef USE_KEYMAP_ADD_HACK
+ km = WM_keymap_guess_opname(C, but->optype->idname);
+ kmi_id = g_kmi_id_hack;
+ UNUSED_VARS(but);
+#else
+ prop = (but->opptr) ? but->opptr->data : NULL;
+ kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km);
+#endif
+
kmi = WM_keymap_item_find_id(km, kmi_id);
WM_keymap_remove_item(km, kmi);
}
@@ -5735,7 +5926,7 @@ static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg
{
uiBut *but = (uiBut *)arg1;
button_timers_tooltip_remove(C, but);
- uiPupBlock(C, menu_change_shortcut, but);
+ UI_popup_block_invoke(C, menu_change_shortcut, but);
}
static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
@@ -5756,7 +5947,7 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
uiBut *but = (uiBut *)arg1;
button_timers_tooltip_remove(C, but);
- uiPupBlockEx(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but);
+ UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but);
}
/**
@@ -5771,8 +5962,8 @@ void ui_panel_menu(bContext *C, ARegion *ar, Panel *pa)
RNA_pointer_create(&sc->id, &RNA_Panel, pa, &ptr);
- pup = uiPupMenuBegin(C, IFACE_("Panel"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("Panel"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
if (UI_panel_category_is_visible(ar)) {
char tmpstr[80];
BLI_snprintf(tmpstr, sizeof(tmpstr), "%s" UI_SEP_CHAR_S "%s", IFACE_("Pin"), IFACE_("Shift+Left Mouse"));
@@ -5786,7 +5977,7 @@ void ui_panel_menu(bContext *C, ARegion *ar, Panel *pa)
}
}
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
static bool ui_but_menu(bContext *C, uiBut *but)
@@ -5800,17 +5991,17 @@ static bool ui_but_menu(bContext *C, uiBut *but)
/* return 0;*/
/* having this menu for some buttons makes no sense */
- if (but->type == BUT_IMAGE) {
+ if (but->type == UI_BTYPE_IMAGE) {
return false;
}
button_timers_tooltip_remove(C, but);
/* highly unlikely getting the label ever fails */
- uiButGetStrInfo(C, but, &label, NULL);
+ UI_but_string_info_get(C, but, &label, NULL);
- pup = uiPupMenuBegin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
if (label.strinfo)
MEM_freeN(label.strinfo);
@@ -6001,19 +6192,19 @@ static bool ui_but_menu(bContext *C, uiBut *but)
/* would rather use a block but, but gets weirdly positioned... */
//uiDefBlockBut(block, menu_change_shortcut, but, "Change Shortcut", 0, 0, uiLayoutGetWidth(layout), UI_UNIT_Y, "");
- but2 = uiDefIconTextBut(block, BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"),
+ but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"),
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiButSetFunc(but2, popup_change_shortcut_func, but, NULL);
+ UI_but_func_set(but2, popup_change_shortcut_func, but, NULL);
- but2 = uiDefIconTextBut(block, BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"),
+ but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"),
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiButSetFunc(but2, remove_shortcut_func, but, NULL);
+ UI_but_func_set(but2, remove_shortcut_func, but, NULL);
}
/* only show 'add' if there's a suitable key map for it to go in */
else if (WM_keymap_guess_opname(C, but->optype->idname)) {
- but2 = uiDefIconTextBut(block, BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Shortcut"),
+ but2 = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, 0, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Add Shortcut"),
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiButSetFunc(but2, popup_add_shortcut_func, but, NULL);
+ UI_but_func_set(but2, popup_add_shortcut_func, but, NULL);
}
uiItemS(layout);
@@ -6087,7 +6278,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
}
uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
return true;
}
@@ -6105,9 +6296,11 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
if ((data->state == BUTTON_STATE_HIGHLIGHT) || (event->type == EVT_DROP)) {
/* handle copy-paste */
- if (ELEM(event->type, CKEY, VKEY) && event->val == KM_PRESS && (event->ctrl || event->oskey)) {
+ if (ELEM(event->type, CKEY, VKEY) && event->val == KM_PRESS &&
+ IS_EVENT_MOD(event, ctrl, oskey))
+ {
/* Specific handling for listrows, we try to find their overlapping tex button. */
- if (but->type == LISTROW) {
+ if (but->type == UI_BTYPE_LISTROW) {
uiBut *labelbut = ui_but_list_row_text_activate(C, but, data, event, BUTTON_ACTIVATE_OVER);
if (labelbut) {
but = labelbut;
@@ -6124,15 +6317,15 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
}
/* handle eyedropper */
else if ((event->type == EKEY) && (event->val == KM_PRESS)) {
- if (event->alt || event->shift || event->ctrl || event->oskey) {
+ if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
/* pass */
}
else {
- if (but->type == COLOR) {
+ if (but->type == UI_BTYPE_COLOR) {
WM_operator_name_call(C, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, NULL);
return WM_UI_HANDLER_BREAK;
}
- else if (but->type == SEARCH_MENU_UNLINK) {
+ else if (but->type == UI_BTYPE_SEARCH_MENU_UNLINK) {
if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_POINTER) {
StructRNA *type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
const short idcode = RNA_type_to_ID_code(type);
@@ -6142,11 +6335,21 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
}
}
}
+ else if (but->type == UI_BTYPE_NUM) {
+ if (but->rnaprop &&
+ (RNA_property_type(but->rnaprop) == PROP_FLOAT) &&
+ (RNA_property_subtype(but->rnaprop) & PROP_UNIT_LENGTH) &&
+ (RNA_property_array_check(but->rnaprop) == false))
+ {
+ WM_operator_name_call(C, "UI_OT_eyedropper_depth", WM_OP_INVOKE_DEFAULT, NULL);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
}
}
/* handle keyframing */
else if ((event->type == IKEY) &&
- !ELEM(KM_MOD_FIRST, event->ctrl, event->oskey) &&
+ !IS_EVENT_MOD(event, ctrl, oskey) &&
(event->val == KM_PRESS))
{
if (event->alt) {
@@ -6167,7 +6370,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
}
/* handle drivers */
else if ((event->type == DKEY) &&
- !ELEM(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift) &&
+ !IS_EVENT_MOD(event, shift, ctrl, oskey) &&
(event->val == KM_PRESS))
{
if (event->alt)
@@ -6181,7 +6384,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
}
/* handle keyingsets */
else if ((event->type == KKEY) &&
- !ELEM(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift) &&
+ !IS_EVENT_MOD(event, shift, ctrl, oskey) &&
(event->val == KM_PRESS))
{
if (event->alt)
@@ -6194,7 +6397,10 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
return WM_UI_HANDLER_BREAK;
}
/* handle menu */
- else if (event->type == RIGHTMOUSE && event->val == KM_PRESS) {
+ else if ((event->type == RIGHTMOUSE) &&
+ !IS_EVENT_MOD(event, shift, ctrl, alt, oskey) &&
+ (event->val == KM_PRESS))
+ {
/* RMB has two options now */
if (ui_but_menu(C, but)) {
return WM_UI_HANDLER_BREAK;
@@ -6221,107 +6427,107 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
}
switch (but->type) {
- case BUT:
+ case UI_BTYPE_BUT:
retval = ui_do_but_BUT(C, but, data, event);
break;
- case KEYEVT:
+ case UI_BTYPE_KEY_EVENT:
retval = ui_do_but_KEYEVT(C, but, data, event);
break;
- case HOTKEYEVT:
+ case UI_BTYPE_HOTKEY_EVENT:
retval = ui_do_but_HOTKEYEVT(C, but, data, event);
break;
- case TOGBUT:
- case TOG:
- case ICONTOG:
- case ICONTOGN:
- case TOGN:
- case OPTION:
- case OPTIONN:
+ case UI_BTYPE_BUT_TOGGLE:
+ case UI_BTYPE_TOGGLE:
+ case UI_BTYPE_ICON_TOGGLE:
+ case UI_BTYPE_ICON_TOGGLE_N:
+ case UI_BTYPE_TOGGLE_N:
+ case UI_BTYPE_CHECKBOX:
+ case UI_BTYPE_CHECKBOX_N:
+ case UI_BTYPE_ROW:
retval = ui_do_but_TOG(C, but, data, event);
break;
- case SCROLL:
+ case UI_BTYPE_SCROLL:
retval = ui_do_but_SCROLL(C, block, but, data, event);
break;
- case GRIP:
+ case UI_BTYPE_GRIP:
retval = ui_do_but_GRIP(C, block, but, data, event);
break;
- case NUM:
+ case UI_BTYPE_NUM:
retval = ui_do_but_NUM(C, block, but, data, event);
break;
- case NUMSLI:
+ case UI_BTYPE_NUM_SLIDER:
retval = ui_do_but_SLI(C, block, but, data, event);
break;
- case LISTBOX:
+ case UI_BTYPE_LISTBOX:
/* Nothing to do! */
break;
- case LISTROW:
+ case UI_BTYPE_LISTROW:
retval = ui_do_but_LISTROW(C, but, data, event);
break;
- case ROUNDBOX:
- case LABEL:
- case ROW:
- case BUT_IMAGE:
- case PROGRESSBAR:
- case NODESOCKET:
+ case UI_BTYPE_ROUNDBOX:
+ case UI_BTYPE_LABEL:
+ case UI_BTYPE_IMAGE:
+ case UI_BTYPE_PROGRESS_BAR:
+ case UI_BTYPE_NODE_SOCKET:
retval = ui_do_but_EXIT(C, but, data, event);
break;
- case HISTOGRAM:
+ case UI_BTYPE_HISTOGRAM:
retval = ui_do_but_HISTOGRAM(C, block, but, data, event);
break;
- case WAVEFORM:
+ case UI_BTYPE_WAVEFORM:
retval = ui_do_but_WAVEFORM(C, block, but, data, event);
break;
- case VECTORSCOPE:
+ case UI_BTYPE_VECTORSCOPE:
/* Nothing to do! */
break;
- case TEX:
- case SEARCH_MENU:
+ case UI_BTYPE_TEXT:
+ case UI_BTYPE_SEARCH_MENU:
retval = ui_do_but_TEX(C, block, but, data, event);
break;
- case SEARCH_MENU_UNLINK:
+ case UI_BTYPE_SEARCH_MENU_UNLINK:
retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
break;
- case MENU:
- case BLOCK:
- case PULLDOWN:
+ case UI_BTYPE_MENU:
+ case UI_BTYPE_BLOCK:
+ case UI_BTYPE_PULLDOWN:
retval = ui_do_but_BLOCK(C, but, data, event);
break;
- case BUTM:
+ case UI_BTYPE_BUT_MENU:
retval = ui_do_but_BUT(C, but, data, event);
break;
- case COLOR:
+ case UI_BTYPE_COLOR:
if (but->a1 == -1) /* signal to prevent calling up color picker */
retval = ui_do_but_EXIT(C, but, data, event);
else
retval = ui_do_but_COLOR(C, but, data, event);
break;
- case BUT_NORMAL:
- retval = ui_do_but_NORMAL(C, block, but, data, event);
+ case UI_BTYPE_UNITVEC:
+ retval = ui_do_but_UNITVEC(C, block, but, data, event);
break;
- case BUT_COLORBAND:
+ case UI_BTYPE_COLORBAND:
retval = ui_do_but_COLORBAND(C, block, but, data, event);
break;
- case BUT_CURVE:
+ case UI_BTYPE_CURVE:
retval = ui_do_but_CURVE(C, block, but, data, event);
break;
- case HSVCUBE:
+ case UI_BTYPE_HSVCUBE:
retval = ui_do_but_HSVCUBE(C, block, but, data, event);
break;
- case HSVCIRCLE:
+ case UI_BTYPE_HSVCIRCLE:
retval = ui_do_but_HSVCIRCLE(C, block, but, data, event);
break;
- case LINK:
- case INLINK:
+ case UI_BTYPE_LINK:
+ case UI_BTYPE_INLINK:
retval = ui_do_but_LINK(C, but, data, event);
break;
- case TRACKPREVIEW:
+ case UI_BTYPE_TRACK_PREVIEW:
retval = ui_do_but_TRACKPREVIEW(C, block, but, data, event);
break;
/* quiet warnings for unhandled types */
- case SEPR:
- case SEPRLINE:
- case BUT_EXTRA:
+ case UI_BTYPE_SEPR:
+ case UI_BTYPE_SEPR_LINE:
+ case UI_BTYPE_EXTRA:
break;
}
@@ -6334,7 +6540,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
(event->type == BACKSPACEKEY && event->val == KM_PRESS))
{
/* ctrl+backspace = reset active button; backspace = reset a whole array*/
- ui_set_but_default(C, !event->ctrl, true);
+ ui_but_default_set(C, !event->ctrl, true);
ED_region_tag_redraw(data->region);
retval = WM_UI_HANDLER_BREAK;
}
@@ -6346,7 +6552,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
/* if we started dragging, progress on any event */
(data->multi_data.init == BUTTON_MULTI_INIT_SETUP))
{
- if (ELEM(but->type, NUM, NUMSLI) &&
+ if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) &&
ELEM(data->state, BUTTON_STATE_TEXT_EDITING, BUTTON_STATE_NUM_EDITING))
{
/* initialize! */
@@ -6432,7 +6638,46 @@ static bool ui_but_isect_pie_seg(uiBlock *block, uiBut *but)
return false;
}
-uiBut *ui_but_find_activated(ARegion *ar)
+static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but_b)
+{
+ return ((but_a->type == but_b->type) &&
+ (but_a->alignnr == but_b->alignnr) &&
+ (but_a->poin == but_b->poin) &&
+ (but_a->rnapoin.type == but_b->rnapoin.type) &&
+ (but_a->rnaprop == but_b->rnaprop));
+}
+
+/**
+ * Finds the pressed button in an aligned row (typically an expanded enum).
+ *
+ * \param direction Use when there may be multiple buttons pressed.
+ */
+uiBut *ui_but_find_select_in_enum(uiBut *but, int direction)
+{
+ uiBut *but_iter = but;
+ uiBut *but_found = NULL;
+ BLI_assert(ELEM(direction, -1, 1));
+
+ while ((but_iter->prev) &&
+ ui_but_find_select_in_enum__cmp(but_iter->prev, but))
+ {
+ but_iter = but_iter->prev;
+ }
+
+ while (but_iter && ui_but_find_select_in_enum__cmp(but_iter, but)) {
+ if (but_iter->flag & UI_SELECT) {
+ but_found = but_iter;
+ if (direction == 1) {
+ break;
+ }
+ }
+ but_iter = but_iter->next;
+ }
+
+ return but_found;
+}
+
+uiBut *ui_but_find_active_in_region(ARegion *ar)
{
uiBlock *block;
uiBut *but;
@@ -6445,26 +6690,26 @@ uiBut *ui_but_find_activated(ARegion *ar)
return NULL;
}
-bool ui_button_is_active(ARegion *ar)
+bool ui_but_is_active(ARegion *ar)
{
- return (ui_but_find_activated(ar) != NULL);
+ return (ui_but_find_active_in_region(ar) != NULL);
}
/* is called by notifier */
-void uiFreeActiveButtons(const bContext *C, bScreen *screen)
+void UI_screen_free_active_but(const bContext *C, bScreen *screen)
{
ScrArea *sa = screen->areabase.first;
for (; sa; sa = sa->next) {
ARegion *ar = sa->regionbase.first;
for (; ar; ar = ar->next) {
- uiBut *but = ui_but_find_activated(ar);
+ uiBut *but = ui_but_find_active_in_region(ar);
if (but) {
uiHandleButtonData *data = but->active;
if (data->menu == NULL && data->searchbox == NULL)
if (data->state == BUTTON_STATE_HIGHLIGHT)
- ui_button_active_free(C, but);
+ ui_but_active_free(C, but);
}
}
}
@@ -6477,10 +6722,10 @@ void uiFreeActiveButtons(const bContext *C, bScreen *screen)
bool UI_but_active_drop_name(bContext *C)
{
ARegion *ar = CTX_wm_region(C);
- uiBut *but = ui_but_find_activated(ar);
+ uiBut *but = ui_but_find_active_in_region(ar);
if (but) {
- if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK))
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK))
return 1;
}
@@ -6492,9 +6737,9 @@ bool UI_but_active_drop_color(bContext *C)
ARegion *ar = CTX_wm_region(C);
if (ar) {
- uiBut *but = ui_but_find_activated(ar);
+ uiBut *but = ui_but_find_active_in_region(ar);
- if (but && but->type == COLOR)
+ if (but && but->type == UI_BTYPE_COLOR)
return true;
}
@@ -6514,7 +6759,7 @@ static void ui_blocks_set_tooltips(ARegion *ar, const bool enable)
block->tooltipdisabled = !enable;
}
-static bool ui_mouse_inside_region(ARegion *ar, int x, int y)
+static bool ui_region_contains_point_px(ARegion *ar, int x, int y)
{
uiBlock *block;
@@ -6548,11 +6793,11 @@ static bool ui_mouse_inside_region(ARegion *ar, int x, int y)
return true;
}
-static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y)
+static bool ui_but_contains_point_px(ARegion *ar, uiBut *but, int x, int y)
{
uiBlock *block = but->block;
float mx, my;
- if (!ui_mouse_inside_region(ar, x, y))
+ if (!ui_region_contains_point_px(ar, x, y))
return false;
mx = x;
@@ -6574,30 +6819,30 @@ static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y)
/**
* Can we mouse over the button or is it hidden/disabled/layout.
- * Note: ctrl is kind of a hack currently, so that non-embossed TEX button behaves as a label when ctrl is not pressed.
+ * Note: ctrl is kind of a hack currently, so that non-embossed UI_BTYPE_TEXT button behaves as a label when ctrl is not pressed.
*/
-static bool ui_is_but_interactive(const uiBut *but, const bool labeledit)
+static bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
{
- /* note, LABEL is included for highlights, this allows drags */
- if ((but->type == LABEL) && but->dragpoin == NULL)
+ /* note, UI_BTYPE_LABEL is included for highlights, this allows drags */
+ if ((but->type == UI_BTYPE_LABEL) && but->dragpoin == NULL)
return false;
- if (ELEM(but->type, ROUNDBOX, SEPR, SEPRLINE, LISTBOX))
+ if (ELEM(but->type, UI_BTYPE_ROUNDBOX, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_LISTBOX))
return false;
if (but->flag & UI_HIDDEN)
return false;
if (but->flag & UI_SCROLLED)
return false;
- if ((but->type == TEX) && (but->dt == UI_EMBOSSN) && !labeledit)
+ if ((but->type == UI_BTYPE_TEXT) && (but->dt == UI_EMBOSS_NONE) && !labeledit)
return false;
- if ((but->type == LISTROW) && labeledit)
+ if ((but->type == UI_BTYPE_LISTROW) && labeledit)
return false;
return true;
}
-bool ui_is_but_search_unlink_visible(const uiBut *but)
+bool ui_but_is_search_unlink_visible(const uiBut *but)
{
- BLI_assert(but->type == SEARCH_MENU_UNLINK);
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU_UNLINK);
return ((but->editstr == NULL) &&
(but->drawstr[0] != '\0'));
}
@@ -6611,7 +6856,7 @@ static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, c
// if (!win->active)
// return NULL;
- if (!ui_mouse_inside_region(ar, x, y))
+ if (!ui_region_contains_point_px(ar, x, y))
return NULL;
for (block = ar->uiblocks.first; block; block = block->next) {
@@ -6620,7 +6865,7 @@ static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, c
ui_window_to_block_fl(ar, block, &mx, &my);
for (but = block->buttons.last; but; but = but->prev) {
- if (ui_is_but_interactive(but, labeledit)) {
+ if (ui_but_is_interactive(but, labeledit)) {
if (but->pie_dir != UI_RADIAL_NONE) {
if (ui_but_isect_pie_seg(block, but)) {
butover = but;
@@ -6658,7 +6903,7 @@ static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y)
uiBut *but;
float mx, my;
- if (!ui_mouse_inside_region(ar, x, y))
+ if (!ui_region_contains_point_px(ar, x, y))
return NULL;
for (block = ar->uiblocks.first; block; block = block->next) {
@@ -6667,7 +6912,7 @@ static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y)
ui_window_to_block_fl(ar, block, &mx, &my);
for (but = block->buttons.last; but; but = but->prev) {
- if (but->type == LISTBOX && ui_but_contains_pt(but, mx, my)) {
+ if (but->type == UI_BTYPE_LISTBOX && ui_but_contains_pt(but, mx, my)) {
return but;
}
}
@@ -6748,14 +6993,14 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
button_tooltip_timer_reset(C, but);
/* automatic open pulldown block timer */
- if (ELEM(but->type, BLOCK, PULLDOWN)) {
+ if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) {
if (data->used_mouse && !data->autoopentimer) {
int time;
if (but->block->auto_open == true) { /* test for toolbox */
time = 1;
}
- else if ((but->block->flag & UI_BLOCK_LOOP && but->type != BLOCK) || but->block->auto_open == true) {
+ else if ((but->block->flag & UI_BLOCK_LOOP && but->type != UI_BTYPE_BLOCK) || but->block->auto_open == true) {
time = 5 * U.menuthreshold2;
}
else if (U.uiflag & USER_MENUOPENAUTO) {
@@ -6786,7 +7031,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
/* number editing */
if (state == BUTTON_STATE_NUM_EDITING) {
- if (ui_is_a_warp_but(but))
+ if (ui_but_is_cursor_warp(but))
WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL);
ui_numedit_begin(but, data);
}
@@ -6796,7 +7041,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
if (but->flag & UI_BUT_DRIVEN)
WM_report(C, RPT_INFO, "Can't edit driven number value, see graph editor for the driver setup.");
- if (ui_is_a_warp_but(but)) {
+ if (ui_but_is_cursor_warp(but)) {
#ifdef USE_CONT_MOUSE_CORRECT
if (data->ungrab_mval[0] != FLT_MAX) {
@@ -6817,9 +7062,9 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
}
/* menu open */
if (state == BUTTON_STATE_MENU_OPEN)
- ui_blockopen_begin(C, but, data);
+ ui_block_open_begin(C, but, data);
else if (data->state == BUTTON_STATE_MENU_OPEN)
- ui_blockopen_end(C, but, data);
+ ui_block_open_end(C, but, data);
/* add a short delay before exiting, to ensure there is some feedback */
if (state == BUTTON_STATE_WAIT_FLASH) {
@@ -6853,13 +7098,13 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
data->state = state;
if (state != BUTTON_STATE_EXIT) {
- /* When objects for eg. are removed, running ui_check_but() can access
+ /* When objects for eg. are removed, running ui_but_update() can access
* the removed data - so disable update on exit. Also in case of
* highlight when not in a popup menu, we remove because data used in
* button below popup might have been removed by action of popup. Needs
* a more reliable solution... */
if (state != BUTTON_STATE_HIGHLIGHT || (but->block->flag & UI_BLOCK_LOOP))
- ui_check_but(but);
+ ui_but_update(but);
}
/* redraw */
@@ -6880,7 +7125,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
copy_v2_fl(data->ungrab_mval, FLT_MAX);
#endif
- if (ELEM(but->type, BUT_CURVE, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_CURVE, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
/* XXX curve is temp */
}
else {
@@ -6907,7 +7152,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
/* activate right away */
if (but->flag & UI_BUT_IMMEDIATE) {
- if (but->type == HOTKEYEVT)
+ if (but->type == UI_BTYPE_HOTKEY_EVENT)
button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
/* .. more to be added here */
}
@@ -6934,7 +7179,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
else if (type == BUTTON_ACTIVATE_APPLY)
button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
- if (but->type == GRIP) {
+ if (but->type == UI_BTYPE_GRIP) {
const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect));
WM_cursor_modal_set(data->window, horizontal ? CURSOR_X_MOVE : CURSOR_Y_MOVE);
}
@@ -6946,7 +7191,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da
uiBlock *block = but->block;
uiBut *bt;
- if (but->type == GRIP) {
+ if (but->type == UI_BTYPE_GRIP) {
WM_cursor_modal_restore(data->window);
}
@@ -6956,7 +7201,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da
/* apply the button action or value */
if (!onfree)
- ui_apply_button(C, block, but, data, false);
+ ui_apply_but(C, block, but, data, false);
#ifdef USE_DRAG_MULTINUM
if (data->multi_data.has_mbuts) {
@@ -6965,7 +7210,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da
bt->flag &= ~UI_BUT_DRAG_MULTI;
if (!data->cancel) {
- ui_apply_autokey(C, bt);
+ ui_apply_but_autokey(C, bt);
}
}
}
@@ -6989,8 +7234,8 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da
if (!onfree && !data->cancel) {
/* autokey & undo push */
- ui_apply_undo(but);
- ui_apply_autokey(C, but);
+ ui_apply_but_undo(but);
+ ui_apply_but_autokey(C, but);
/* popup menu memory */
if (block->flag & UI_BLOCK_POPUP_MEMORY)
@@ -7025,7 +7270,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da
but->flag &= ~(UI_ACTIVE | UI_SELECT);
but->flag |= UI_BUT_LAST_ACTIVE;
if (!onfree)
- ui_check_but(but);
+ ui_but_update(but);
/* adds empty mousemove in queue for re-init handler, in case mouse is
* still over a button. we cannot just check for this ourselfs because
@@ -7034,7 +7279,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da
WM_event_add_mousemove(C);
}
-void ui_button_active_free(const bContext *C, uiBut *but)
+void ui_but_active_free(const bContext *C, uiBut *but)
{
uiHandleButtonData *data;
@@ -7100,13 +7345,13 @@ static uiBut *ui_context_rna_button_active(const bContext *C)
return ui_context_button_active(C, ui_context_rna_button_active_test);
}
-uiBut *uiContextActiveButton(const struct bContext *C)
+uiBut *UI_context_active_but_get(const struct bContext *C)
{
return ui_context_button_active(C, NULL);
}
/* helper function for insert keyframe, reset to default, etc operators */
-void uiContextActiveProperty(const bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index)
+void UI_context_active_but_prop_get(const bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index)
{
uiBut *activebut = ui_context_rna_button_active(C);
@@ -7123,7 +7368,7 @@ void uiContextActiveProperty(const bContext *C, struct PointerRNA *ptr, struct P
}
}
-void uiContextActivePropertyHandle(bContext *C)
+void UI_context_active_but_prop_handle(bContext *C)
{
uiBut *activebut = ui_context_rna_button_active(C);
if (activebut) {
@@ -7137,7 +7382,7 @@ void uiContextActivePropertyHandle(bContext *C)
}
}
-wmOperator *uiContextActiveOperator(const struct bContext *C)
+wmOperator *UI_context_active_operator_get(const struct bContext *C)
{
ARegion *ar_ctx = CTX_wm_region(C);
uiBlock *block;
@@ -7175,7 +7420,7 @@ wmOperator *uiContextActiveOperator(const struct bContext *C)
}
/* helper function for insert keyframe, reset to default, etc operators */
-void uiContextAnimUpdate(const bContext *C)
+void UI_context_update_anim_flag(const bContext *C)
{
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
@@ -7260,8 +7505,8 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *ar)
return WM_UI_HANDLER_CONTINUE;
}
-/* exported to interface.c: uiButActiveOnly() */
-void ui_button_activate_do(bContext *C, ARegion *ar, uiBut *but)
+/* exported to interface.c: UI_but_active_only() */
+void ui_but_activate_event(bContext *C, ARegion *ar, uiBut *but)
{
wmWindow *win = CTX_wm_window(C);
wmEvent event;
@@ -7283,12 +7528,12 @@ void ui_button_activate_do(bContext *C, ARegion *ar, uiBut *but)
* exported so menus can start with a highlighted button,
* even if the mouse isnt over it
*/
-void ui_button_activate_over(bContext *C, ARegion *ar, uiBut *but)
+void ui_but_activate_over(bContext *C, ARegion *ar, uiBut *but)
{
button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
}
-void ui_button_execute_begin(struct bContext *UNUSED(C), struct ARegion *ar, uiBut *but, void **active_back)
+void ui_but_execute_begin(struct bContext *UNUSED(C), struct ARegion *ar, uiBut *but, void **active_back)
{
/* note: ideally we would not have to change 'but->active' however
* some functions we call don't use data (as they should be doing) */
@@ -7299,12 +7544,12 @@ void ui_button_execute_begin(struct bContext *UNUSED(C), struct ARegion *ar, uiB
data->region = ar;
}
-void ui_button_execute_end(struct bContext *C, struct ARegion *UNUSED(ar), uiBut *but, void *active_back)
+void ui_but_execute_end(struct bContext *C, struct ARegion *UNUSED(ar), uiBut *but, void *active_back)
{
- ui_apply_button(C, but->block, but, but->active, true);
+ ui_apply_but(C, but->block, but, but->active, true);
if ((but->flag & UI_BUT_DRAG_MULTI) == 0) {
- ui_apply_autokey(C, but);
+ ui_apply_but_autokey(C, but);
}
/* use onfree event so undo is handled by caller and apply is already done above */
button_activate_exit((bContext *)C, but, but->active, false, true);
@@ -7316,7 +7561,7 @@ static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiBu
uiBut *oldbut;
uiHandleButtonData *data;
- oldbut = ui_but_find_activated(ar);
+ oldbut = ui_but_find_active_in_region(ar);
if (oldbut) {
data = oldbut->active;
data->cancel = true;
@@ -7355,7 +7600,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
bool exit = false;
if ((!ui_block_is_menu(block) || ui_block_is_pie_menu(but->block)) &&
- !ui_mouse_inside_button(ar, but, event->x, event->y))
+ !ui_but_contains_point_px(ar, but, event->x, event->y))
{
exit = true;
}
@@ -7390,7 +7635,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
data->autoopentimer = NULL;
- if (ui_mouse_inside_button(ar, but, event->x, event->y))
+ if (ui_but_contains_point_px(ar, but, event->x, event->y))
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
}
@@ -7418,7 +7663,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
break;
case MOUSEMOVE:
- if (ELEM(but->type, LINK, INLINK)) {
+ if (ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) {
ARegion *ar = data->region;
but->flag |= UI_SELECT;
ui_do_button(C, block, but, event);
@@ -7427,7 +7672,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
else {
/* deselect the button when moving the mouse away */
/* also de-activate for buttons that only show higlights */
- if (ui_mouse_inside_button(ar, but, event->x, event->y)) {
+ if (ui_but_contains_point_px(ar, but, event->x, event->y)) {
if (!(but->flag & UI_SELECT)) {
but->flag |= (UI_SELECT | UI_ACTIVE);
data->cancel = false;
@@ -7472,7 +7717,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
uiBut *bt;
if (data->menu && data->menu->region) {
- if (ui_mouse_inside_region(data->menu->region, event->x, event->y)) {
+ if (ui_region_contains_point_px(data->menu->region, event->x, event->y)) {
break;
}
}
@@ -7480,7 +7725,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
bt = ui_but_find_mouse_over(ar, event);
if (bt && bt->active != data) {
- if (but->type != COLOR) { /* exception */
+ if (but->type != UI_BTYPE_COLOR) { /* exception */
data->cancel = true;
}
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -7625,7 +7870,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
- ui_apply_undo(but);
+ ui_apply_but_undo(but);
ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
ED_region_tag_redraw(ar);
@@ -7669,18 +7914,18 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u
/* copy over return values from the closing menu */
if ((menu->menuretval & UI_RETURN_OK) || (menu->menuretval & UI_RETURN_UPDATE)) {
- if (but->type == COLOR)
+ if (but->type == UI_BTYPE_COLOR)
copy_v3_v3(data->vec, menu->retvec);
- else if (but->type == MENU)
+ else if (but->type == UI_BTYPE_MENU)
data->value = menu->retvalue;
}
if (menu->menuretval & UI_RETURN_UPDATE) {
if (data->interactive) {
- ui_apply_button(C, but->block, but, data, true);
+ ui_apply_but(C, but->block, but, data, true);
}
else {
- ui_check_but(but);
+ ui_but_update(but);
}
menu->menuretval = 0;
@@ -7694,7 +7939,7 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u
button_activate_exit(C, but, data, true, false);
}
else if (menu->menuretval & UI_RETURN_OUT) {
- if (event->type == MOUSEMOVE && ui_mouse_inside_button(data->region, but, event->x, event->y)) {
+ if (event->type == MOUSEMOVE && ui_but_contains_point_px(data->region, but, event->x, event->y)) {
button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
}
else {
@@ -7954,7 +8199,7 @@ static bool ui_menu_pass_event_to_parent_if_nonactive(uiPopupBlockHandle *menu,
static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu)
{
ARegion *ar = menu->region;
- uiBut *but = ui_but_find_activated(ar);
+ uiBut *but = ui_but_find_active_in_region(ar);
int retval;
if (but) {
@@ -7966,11 +8211,11 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
else if (!ui_block_is_menu(but->block) || ui_block_is_pie_menu(but->block)) {
/* pass, skip for dialogs */
}
- else if (!ui_mouse_inside_region(but->active->region, event->x, event->y)) {
+ else if (!ui_region_contains_point_px(but->active->region, event->x, event->y)) {
/* pass, needed to click-exit outside of non-flaoting menus */
}
else if ((!ELEM(event->type, MOUSEMOVE, WHEELUPMOUSE, WHEELDOWNMOUSE, MOUSEPAN)) && ISMOUSE(event->type)) {
- if (!ui_mouse_inside_button(but->active->region, but, event->x, event->y)) {
+ if (!ui_but_contains_point_px(but->active->region, but, event->x, event->y)) {
but = NULL;
}
}
@@ -7995,7 +8240,7 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock
return retval;
}
-float ui_block_calculate_pie_segment(uiBlock *block, const float event_xy[2])
+float ui_block_calc_pie_segment(uiBlock *block, const float event_xy[2])
{
float seg1[2];
float seg2[2];
@@ -8012,7 +8257,6 @@ float ui_block_calculate_pie_segment(uiBlock *block, const float event_xy[2])
len = normalize_v2_v2(block->pie_data.pie_dir, seg2);
- /* ten pixels for now, a bit arbitrary */
if (len < U.pie_menu_threshold * U.pixelsize)
block->pie_data.flags |= UI_PIE_INVALID_DIR;
else
@@ -8027,7 +8271,7 @@ static int ui_handle_menu_event(
{
ARegion *ar;
uiBlock *block;
- uiBut *but, *bt;
+ uiBut *but;
int mx, my, retval;
bool inside;
bool inside_title; /* check for title dragging */
@@ -8046,7 +8290,7 @@ static int ui_handle_menu_event(
inside_title = inside && ((my + (UI_UNIT_Y * 1.5f)) > block->rect.ymax);
/* if there's an active modal button, don't check events or outside, except for search menu */
- but = ui_but_find_activated(ar);
+ but = ui_but_find_active_in_region(ar);
#ifdef USE_DRAG_POPUP
if (menu->is_grab) {
@@ -8122,15 +8366,15 @@ static int ui_handle_menu_event(
if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval))
break;
- but = ui_but_find_activated(ar);
+ but = ui_but_find_active_in_region(ar);
if (!but) {
/* no item active, we make first active */
- if (block->direction & UI_TOP) but = ui_but_last(block);
+ if (block->direction & UI_DIR_UP) but = ui_but_last(block);
else but = ui_but_first(block);
}
- if (but && ELEM(but->type, BLOCK, PULLDOWN))
+ if (but && ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN))
ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN);
}
@@ -8143,7 +8387,7 @@ static int ui_handle_menu_event(
case WHEELDOWNMOUSE:
case MOUSEPAN:
/* arrowkeys: only handle for block_loop blocks */
- if (event->alt || event->shift || event->ctrl || event->oskey) {
+ if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
/* pass */
}
else if (inside || (block->flag & UI_BLOCK_LOOP)) {
@@ -8155,7 +8399,9 @@ static int ui_handle_menu_event(
ui_pan_to_scroll(event, &type, &val);
if (val == KM_PRESS) {
- const eButType type_flip = BUT | ROW;
+ const bool is_next =
+ (ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE) ==
+ ((block->flag & UI_BLOCK_IS_FLIP) != 0));
if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval))
break;
@@ -8164,58 +8410,24 @@ static int ui_handle_menu_event(
ui_mouse_motion_keynav_init(&menu->keynav_state, event);
#endif
- but = ui_but_find_activated(ar);
+ but = ui_but_find_active_in_region(ar);
if (but) {
- /* is there a situation where UI_LEFT or UI_RIGHT would also change navigation direction? */
- if (((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_DOWN)) ||
- ((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_RIGHT)) ||
- ((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_TOP)))
- {
- /* the following is just a hack - uiBut->type set to BUT and BUTM have there menus built
- * opposite ways - this should be changed so that all popup-menus use the same uiBlock->direction */
- if (but->type & type_flip)
- but = ui_but_next(but);
- else
- but = ui_but_prev(but);
- }
- else {
- if (but->type & type_flip)
- but = ui_but_prev(but);
- else
- but = ui_but_next(but);
- }
-
- if (but) {
- ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
- ui_menu_scroll(ar, block, my, but);
- }
+ /* next button */
+ but = is_next ? ui_but_next(but) : ui_but_prev(but);
}
if (!but) {
- if (((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_DOWN)) ||
- ((ELEM(type, UPARROWKEY, WHEELUPMOUSE)) && (block->direction & UI_RIGHT)) ||
- ((ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE)) && (block->direction & UI_TOP)))
- {
- if ((bt = ui_but_first(block)) && (bt->type & type_flip)) {
- bt = ui_but_last(block);
- }
- else {
- /* keep ui_but_first() */
- }
- }
- else {
- if ((bt = ui_but_first(block)) && (bt->type & type_flip)) {
- /* keep ui_but_first() */
- }
- else {
- bt = ui_but_last(block);
- }
+ /* wrap button */
+ uiBut *but_wrap;
+ but_wrap = is_next ? ui_but_first(block) : ui_but_last(block);
+ if (but_wrap) {
+ but = but_wrap;
}
+ }
- if (bt) {
- ui_handle_button_activate(C, ar, bt, BUTTON_ACTIVATE);
- ui_menu_scroll(ar, block, my, bt);
- }
+ if (but) {
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
+ ui_menu_scroll(ar, block, my, but);
}
}
@@ -8257,7 +8469,7 @@ static int ui_handle_menu_event(
for (but = block->buttons.first; but; but = but->next) {
bool doit = false;
- if (!ELEM(but->type, LABEL, SEPR, SEPRLINE))
+ if (!ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE))
count++;
/* exception for rna layer buts */
@@ -8275,7 +8487,7 @@ static int ui_handle_menu_event(
if (doit) {
/* activate buttons but open menu's */
uiButtonActivateType activate;
- if (but->type == PULLDOWN) {
+ if (but->type == UI_BTYPE_PULLDOWN) {
activate = BUTTON_ACTIVATE_OPEN;
}
else {
@@ -8320,9 +8532,7 @@ static int ui_handle_menu_event(
case ZKEY:
{
if ((event->val == KM_PRESS || event->val == KM_DBL_CLICK) &&
- (event->shift == 0) &&
- (event->ctrl == 0) &&
- (event->oskey == 0))
+ !IS_EVENT_MOD(event, shift, ctrl, oskey))
{
if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval))
break;
@@ -8330,15 +8540,15 @@ static int ui_handle_menu_event(
for (but = block->buttons.first; but; but = but->next) {
if (but->menu_key == event->type) {
- if (ELEM(but->type, BUT, BUTM)) {
+ if (ELEM(but->type, UI_BTYPE_BUT, UI_BTYPE_BUT_MENU)) {
/* mainly for operator buttons */
ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_APPLY);
}
- else if (ELEM(but->type, BLOCK, PULLDOWN)) {
+ else if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) {
/* open submenus (like right arrow key) */
ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN);
}
- else if (but->type == MENU) {
+ else if (but->type == UI_BTYPE_MENU) {
/* activate menu items */
ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
}
@@ -8403,14 +8613,14 @@ static int ui_handle_menu_event(
else if (ELEM(event->type, RETKEY, PADENTER) && event->val == KM_PRESS) {
/* enter will always close this block, we let the event
* get handled by the button if it is activated, otherwise we cancel */
- if (!ui_but_find_activated(ar))
+ if (!ui_but_find_active_in_region(ar))
menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK;
}
#ifdef USE_DRAG_POPUP
else if ((event->type == LEFTMOUSE) && (event->val == KM_PRESS) &&
(inside && is_floating && inside_title))
{
- if (!but || !ui_mouse_inside_button(ar, but, event->x, event->y)) {
+ if (!but || !ui_but_contains_point_px(ar, but, event->x, event->y)) {
if (but) {
button_timers_tooltip_remove(C, but);
}
@@ -8490,7 +8700,7 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo
ar = menu->region;
block = ar->uiblocks.first;
- but = ui_but_find_activated(ar);
+ but = ui_but_find_active_in_region(ar);
data = but->active;
submenu = data->menu;
@@ -8532,7 +8742,7 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo
static bool ui_but_pie_menu_supported_apply(uiBut *but)
{
- return (!ELEM(but->type, NUMSLI, NUM));
+ return (!ELEM(but->type, UI_BTYPE_NUM_SLIDER, UI_BTYPE_NUM));
}
static int ui_but_pie_menu_apply(bContext *C, uiPopupBlockHandle *menu, uiBut *but, bool force_close)
@@ -8540,10 +8750,10 @@ static int ui_but_pie_menu_apply(bContext *C, uiPopupBlockHandle *menu, uiBut *b
int retval = WM_UI_HANDLER_BREAK;
if (but && ui_but_pie_menu_supported_apply(but)) {
- if (but->type == MENU) {
+ if (but->type == UI_BTYPE_MENU) {
/* forcing the pie menu to close will not handle menus */
if (!force_close) {
- uiBut *active_but = ui_but_find_activated(menu->region);
+ uiBut *active_but = ui_but_find_active_in_region(menu->region);
if (active_but) {
button_activate_exit(C, active_but, active_but->active, false, false);
@@ -8557,7 +8767,7 @@ static int ui_but_pie_menu_apply(bContext *C, uiPopupBlockHandle *menu, uiBut *b
}
}
else {
- ui_apply_button(C, but->block, but, but->active, false);
+ ui_apply_but(C, but->block, but, but->active, false);
button_activate_exit((bContext *)C, but, but->active, false, true);
menu->menuretval = UI_RETURN_OK;
@@ -8578,7 +8788,7 @@ static uiBut *ui_block_pie_dir_activate(uiBlock *block, const wmEvent *event, Ra
if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) {
for (but = block->buttons.first; but; but = but->next) {
- if (but->pie_dir == dir && !ELEM(but->type, SEPR, SEPRLINE)) {
+ if (but->pie_dir == dir && !ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
return but;
}
}
@@ -8594,7 +8804,7 @@ static int ui_but_pie_button_activate(bContext *C, uiBut *but, uiPopupBlockHandl
if (but == NULL)
return WM_UI_HANDLER_BREAK;
- active_but = ui_but_find_activated(menu->region);
+ active_but = ui_but_find_active_in_region(menu->region);
if (active_but)
button_activate_exit(C, active_but, active_but->active, false, false);
@@ -8603,7 +8813,7 @@ static int ui_but_pie_button_activate(bContext *C, uiBut *but, uiPopupBlockHandl
return ui_but_pie_menu_apply(C, menu, but, false);
}
-static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu)
+static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu)
{
ARegion *ar;
uiBlock *block;
@@ -8640,7 +8850,7 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
ui_window_to_block_fl(ar, block, &event_xy[0], &event_xy[1]);
- dist = ui_block_calculate_pie_segment(block, event_xy);
+ dist = ui_block_calc_pie_segment(block, event_xy);
if (event->type == TIMER) {
if (event->customdata == menu->scrolltimer) {
@@ -8699,8 +8909,8 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
block->pie_data.duration_gesture = duration;
}
- if (len_sq < 1.0) {
- uiBut *but = ui_but_find_activated(menu->region);
+ if (len_sq < 1.0f) {
+ uiBut *but = ui_but_find_active_in_region(menu->region);
if (but) {
return ui_but_pie_menu_apply(C, menu, but, true);
@@ -8726,7 +8936,7 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
block->pie_data.flags |= UI_PIE_CLICK_STYLE;
}
else {
- uiBut *but = ui_but_find_activated(menu->region);
+ uiBut *but = ui_but_find_active_in_region(menu->region);
if (but && (U.pie_menu_confirm > 0) &&
(dist >= U.pie_menu_threshold + U.pie_menu_confirm))
@@ -8814,9 +9024,7 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
case ZKEY:
{
if ((event->val == KM_PRESS || event->val == KM_DBL_CLICK) &&
- (event->shift == 0) &&
- (event->ctrl == 0) &&
- (event->oskey == 0))
+ !IS_EVENT_MOD(event, shift, ctrl, oskey))
{
for (but = block->buttons.first; but; but = but->next) {
if (but->menu_key == event->type) {
@@ -8865,7 +9073,7 @@ static int ui_handle_menus_recursive(
bool do_towards_reinit = false;
/* check if we have a submenu, and handle events for it first */
- but = ui_but_find_activated(menu->region);
+ but = ui_but_find_active_in_region(menu->region);
data = (but) ? but->active : NULL;
submenu = (data) ? data->menu : NULL;
@@ -8892,7 +9100,7 @@ static int ui_handle_menus_recursive(
/* now handle events for our own menu */
if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
- const bool do_but_search = (but && ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK));
+ const bool do_but_search = (but && ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK));
if (submenu && submenu->menuretval) {
const bool do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT) != 0;
retval = ui_handle_menu_return_submenu(C, event, menu);
@@ -8914,7 +9122,7 @@ static int ui_handle_menus_recursive(
if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) {
/* when there is a active search button and we close it,
* we need to reinit the mouse coords [#35346] */
- if (ui_but_find_activated(menu->region) != but) {
+ if (ui_but_find_active_in_region(menu->region) != but) {
do_towards_reinit = true;
}
}
@@ -8923,7 +9131,7 @@ static int ui_handle_menus_recursive(
uiBlock *block = menu->region->uiblocks.first;
if (block->flag & UI_BLOCK_RADIAL)
- retval = ui_handler_pie(C, event, menu);
+ retval = ui_pie_handler(C, event, menu);
else if (event->type == LEFTMOUSE || event->val != KM_DBL_CLICK)
retval = ui_handle_menu_event(C, event, menu, level, is_parent_inside, is_parent_menu, is_floating);
}
@@ -8938,7 +9146,7 @@ static int ui_handle_menus_recursive(
/* *************** UI event handlers **************** */
-static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(userdata))
+static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(userdata))
{
ARegion *ar;
uiBut *but;
@@ -8953,7 +9161,7 @@ static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(use
}
/* either handle events for already activated button or try to activate */
- but = ui_but_find_activated(ar);
+ but = ui_but_find_active_in_region(ar);
retval = ui_handler_panel_region(C, event, ar);
@@ -8977,7 +9185,7 @@ static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(use
return retval;
}
-static void ui_handler_remove_region(bContext *C, void *UNUSED(userdata))
+static void ui_region_handler_remove(bContext *C, void *UNUSED(userdata))
{
bScreen *sc;
ARegion *ar;
@@ -8985,40 +9193,59 @@ static void ui_handler_remove_region(bContext *C, void *UNUSED(userdata))
ar = CTX_wm_region(C);
if (ar == NULL) return;
- uiFreeBlocks(C, &ar->uiblocks);
+ UI_blocklist_free(C, &ar->uiblocks);
sc = CTX_wm_screen(C);
if (sc == NULL) return;
/* delayed apply callbacks, but not for screen level regions, those
* we rather do at the very end after closing them all, which will
- * be done in ui_handler_region/window */
+ * be done in ui_region_handler/window */
if (BLI_findindex(&sc->regionbase, ar) == -1)
ui_apply_but_funcs_after(C);
}
+/* handle buttons at the window level, modal, for example while
+ * number sliding, text editing, or when a menu block is open */
static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSED(userdata))
{
ARegion *ar;
uiBut *but;
- /* here we handle buttons at the window level, modal, for example
- * while number sliding, text editing, or when a menu block is open */
ar = CTX_wm_menu(C);
if (!ar)
ar = CTX_wm_region(C);
- but = ui_but_find_activated(ar);
+ but = ui_but_find_active_in_region(ar);
if (but) {
+ bScreen *screen = CTX_wm_screen(C);
+ ARegion *ar_temp;
uiBut *but_other;
uiHandleButtonData *data;
+ bool is_inside_menu = false;
+
+ /* look for a popup menu containing the mouse */
+ for (ar_temp = screen->regionbase.first; ar_temp; ar_temp = ar_temp->next) {
+ rcti rect = ar_temp->winrct;
+
+ /* resize region rect to ignore shadow */
+ BLI_rcti_resize(&rect, (BLI_rcti_size_x(&ar_temp->winrct) - UI_ThemeMenuShadowWidth() * 2),
+ (BLI_rcti_size_y(&ar_temp->winrct) - UI_ThemeMenuShadowWidth() * 2));
+ if (BLI_rcti_isect_pt_v(&rect, &event->x)) {
+ BLI_assert(ar_temp->type->regionid == RGN_TYPE_TEMPORARY);
+
+ is_inside_menu = true;
+ break;
+ }
+ }
/* handle activated button events */
data = but->active;
if ((data->state == BUTTON_STATE_MENU_OPEN) &&
- (but->type == PULLDOWN) &&
+ (is_inside_menu == false) && /* make sure mouse isn't inside another menu (see T43247) */
+ (but->type == UI_BTYPE_PULLDOWN) &&
(but_other = ui_but_find_mouse_over(ar, event)) &&
(but != but_other) &&
(but->type == but_other->type))
@@ -9064,7 +9291,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE
}
/* two types of popups, one with operator + enum, other with regular callbacks */
-static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
+static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata)
{
uiPopupBlockHandle *menu = userdata;
struct ARegion *menu_region;
@@ -9100,7 +9327,8 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
}
ui_popup_block_free(C, menu);
- UI_remove_popup_handlers(&win->modalhandlers, menu);
+ UI_popup_handlers_remove(&win->modalhandlers, menu);
+ CTX_wm_menu_set(C, NULL);
#ifdef USE_DRAG_TOGGLE
{
@@ -9142,7 +9370,7 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
return retval;
}
-static void ui_handler_remove_popup(bContext *C, void *userdata)
+static void ui_popup_handler_remove(bContext *C, void *userdata)
{
uiPopupBlockHandle *menu = userdata;
@@ -9153,25 +9381,25 @@ static void ui_handler_remove_popup(bContext *C, void *userdata)
ui_apply_but_funcs_after(C);
}
-void UI_add_region_handlers(ListBase *handlers)
+void UI_region_handlers_add(ListBase *handlers)
{
- WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL, false);
- WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region, NULL, false);
+ WM_event_remove_ui_handler(handlers, ui_region_handler, ui_region_handler_remove, NULL, false);
+ WM_event_add_ui_handler(NULL, handlers, ui_region_handler, ui_region_handler_remove, NULL, false);
}
-void UI_add_popup_handlers(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup, const bool accept_dbl_click)
+void UI_popup_handlers_add(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup, const bool accept_dbl_click)
{
- WM_event_add_ui_handler(C, handlers, ui_handler_popup, ui_handler_remove_popup, popup, accept_dbl_click);
+ WM_event_add_ui_handler(C, handlers, ui_popup_handler, ui_popup_handler_remove, popup, accept_dbl_click);
}
-void UI_remove_popup_handlers(ListBase *handlers, uiPopupBlockHandle *popup)
+void UI_popup_handlers_remove(ListBase *handlers, uiPopupBlockHandle *popup)
{
- WM_event_remove_ui_handler(handlers, ui_handler_popup, ui_handler_remove_popup, popup, false);
+ WM_event_remove_ui_handler(handlers, ui_popup_handler, ui_popup_handler_remove, popup, false);
}
-void UI_remove_popup_handlers_all(bContext *C, ListBase *handlers)
+void UI_popup_handlers_remove_all(bContext *C, ListBase *handlers)
{
- WM_event_free_ui_handler_all(C, handlers, ui_handler_popup, ui_handler_remove_popup);
+ WM_event_free_ui_handler_all(C, handlers, ui_popup_handler, ui_popup_handler_remove);
}
bool UI_textbutton_activate_rna(const bContext *C, ARegion *ar,
@@ -9182,7 +9410,7 @@ bool UI_textbutton_activate_rna(const bContext *C, ARegion *ar,
for (block = ar->uiblocks.first; block; block = block->next) {
for (but = block->buttons.first; but; but = but->next) {
- if (but->type == TEX) {
+ if (but->type == UI_BTYPE_TEXT) {
if (but->rnaprop && but->rnapoin.data == rna_poin_data) {
if (STREQ(RNA_property_identifier(but->rnaprop), rna_prop_id)) {
break;
@@ -9195,7 +9423,7 @@ bool UI_textbutton_activate_rna(const bContext *C, ARegion *ar,
}
if (but) {
- uiButActiveOnly(C, ar, block, but);
+ UI_but_active_only(C, ar, block, but);
return true;
}
else {
@@ -9211,7 +9439,7 @@ bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut)
for (block = ar->uiblocks.first; block; block = block->next) {
for (but = block->buttons.first; but; but = but->next)
- if (but == actbut && but->type == TEX)
+ if (but == actbut && but->type == UI_BTYPE_TEXT)
break;
if (but)
@@ -9219,7 +9447,7 @@ bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut)
}
if (but) {
- uiButActiveOnly(C, ar, block, but);
+ UI_but_active_only(C, ar, block, but);
return true;
}
else {
@@ -9228,7 +9456,7 @@ bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut)
}
-void ui_button_clipboard_free(void)
+void ui_but_clipboard_free(void)
{
curvemapping_free_data(&but_copypaste_curve);
}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 51dd9166e46..679681cb372 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -51,6 +51,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_icons.h"
+#include "BKE_appdir.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -587,7 +588,7 @@ static void init_internal_icons(void)
#if 0 // temp disabled
if ((btheme != NULL) && btheme->tui.iconfile[0]) {
- char *icondir = BLI_get_folder(BLENDER_DATAFILES, "icons");
+ char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
char iconfilestr[FILE_MAX];
if (icondir) {
@@ -702,12 +703,12 @@ static void init_iconfile_list(struct ListBase *list)
const char *icondir;
BLI_listbase_clear(list);
- icondir = BLI_get_folder(BLENDER_DATAFILES, "icons");
+ icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
if (icondir == NULL)
return;
- totfile = BLI_dir_contents(icondir, &dir);
+ totfile = BLI_filelist_dir_contents(icondir, &dir);
for (i = 0; i < totfile; i++) {
if ((dir[i].type & S_IFREG)) {
@@ -755,7 +756,7 @@ static void init_iconfile_list(struct ListBase *list)
}
}
- BLI_free_filelist(dir, totfile);
+ BLI_filelist_free(dir, totfile, NULL);
dir = NULL;
}
@@ -930,7 +931,8 @@ static void icon_create_rect(struct PreviewImage *prv_img, enum eIconSizes size)
/* only called when icon has changed */
/* only call with valid pointer from UI_icon_draw */
-static void icon_set_image(bContext *C, ID *id, PreviewImage *prv_img, enum eIconSizes size)
+static void icon_set_image(
+ const bContext *C, Scene *scene, ID *id, PreviewImage *prv_img, enum eIconSizes size, const bool use_job)
{
if (!prv_img) {
if (G.debug & G_DEBUG)
@@ -940,8 +942,17 @@ static void icon_set_image(bContext *C, ID *id, PreviewImage *prv_img, enum eIco
icon_create_rect(prv_img, size);
- ED_preview_icon_job(C, prv_img, id, prv_img->rect[size],
- prv_img->w[size], prv_img->h[size]);
+ if (use_job) {
+ /* Job (background) version */
+ ED_preview_icon_job(C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
+ }
+ else {
+ if (!scene) {
+ scene = CTX_data_scene(C);
+ }
+ /* Immediate version */
+ ED_preview_icon_render(scene, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
+ }
}
PreviewImage *UI_icon_to_preview(int icon_id)
@@ -1148,29 +1159,30 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
}
}
-static void ui_id_preview_image_render_size(bContext *C, ID *id, PreviewImage *pi, int size)
+static void ui_id_preview_image_render_size(
+ const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job)
{
if ((pi->changed[size] || !pi->rect[size])) { /* changed only ever set by dynamic icons */
/* create the rect if necessary */
- icon_set_image(C, id, pi, size);
+ icon_set_image(C, scene, id, pi, size, use_job);
pi->changed[size] = 0;
}
}
-static void ui_id_icon_render(bContext *C, ID *id, const bool big)
+void UI_id_icon_render(const bContext *C, Scene *scene, ID *id, const bool big, const bool use_job)
{
PreviewImage *pi = BKE_previewimg_get(id);
if (pi) {
if (big)
- ui_id_preview_image_render_size(C, id, pi, ICON_SIZE_PREVIEW); /* bigger preview size */
+ ui_id_preview_image_render_size(C, scene, id, pi, ICON_SIZE_PREVIEW, use_job); /* bigger preview size */
else
- ui_id_preview_image_render_size(C, id, pi, ICON_SIZE_ICON); /* icon size */
+ ui_id_preview_image_render_size(C, scene, id, pi, ICON_SIZE_ICON, use_job); /* icon size */
}
}
-static void ui_id_brush_render(bContext *C, ID *id)
+static void ui_id_brush_render(const bContext *C, ID *id)
{
PreviewImage *pi = BKE_previewimg_get(id);
enum eIconSizes i;
@@ -1182,14 +1194,14 @@ static void ui_id_brush_render(bContext *C, ID *id)
/* check if rect needs to be created; changed
* only set by dynamic icons */
if ((pi->changed[i] || !pi->rect[i])) {
- icon_set_image(C, id, pi, i);
+ icon_set_image(C, NULL, id, pi, i, true);
pi->changed[i] = 0;
}
}
}
-static int ui_id_brush_get_icon(bContext *C, ID *id)
+static int ui_id_brush_get_icon(const bContext *C, ID *id)
{
Brush *br = (Brush *)id;
@@ -1242,7 +1254,7 @@ static int ui_id_brush_get_icon(bContext *C, ID *id)
return id->icon_id;
}
-int ui_id_icon_get(bContext *C, ID *id, const bool big)
+int ui_id_icon_get(const bContext *C, ID *id, const bool big)
{
int iconid = 0;
@@ -1258,7 +1270,7 @@ int ui_id_icon_get(bContext *C, ID *id, const bool big)
case ID_LA: /* fall through */
iconid = BKE_icon_getid(id);
/* checks if not exists, or changed */
- ui_id_icon_render(C, id, big);
+ UI_id_icon_render(C, NULL, id, big, true);
break;
default:
break;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 47d0e29061c..03816a255ad 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -36,6 +36,7 @@
#include "BLI_compiler_attrs.h"
#include "UI_resources.h"
#include "RNA_types.h"
+#include "DNA_listBase.h"
struct ARegion;
struct bContext;
@@ -67,7 +68,7 @@ typedef enum {
/* standard set */
UI_WTYPE_LABEL,
UI_WTYPE_TOGGLE,
- UI_WTYPE_OPTION,
+ UI_WTYPE_CHECKBOX,
UI_WTYPE_RADIO,
UI_WTYPE_NUMBER,
UI_WTYPE_SLIDER,
@@ -95,7 +96,7 @@ typedef enum {
UI_WTYPE_ICON,
UI_WTYPE_SWATCH,
UI_WTYPE_RGB_PICKER,
- UI_WTYPE_NORMAL,
+ UI_WTYPE_UNITVEC,
UI_WTYPE_BOX,
UI_WTYPE_SCROLL,
UI_WTYPE_LISTITEM,
@@ -212,20 +213,20 @@ struct uiBut {
/* both these values use depends on the button type
* (polymorphic struct or union would be nicer for this stuff) */
- /* (type == HSVCUBE), Use UI_GRAD_* values.
- * (type == NUM), Use to store RNA 'step' value, for dragging and click-step.
- * (type == LABEL), Use (a1 == 1.0f) to use a2 as a blending factor (wow, this is imaginative!).
- * (type == SCROLL) Use as scroll size.
- * (type == SEARCH_MENU) Use as number or rows.
- * (type == COLOR) Use as indication of color palette
+ /* (type == UI_BTYPE_HSVCUBE), Use UI_GRAD_* values.
+ * (type == UI_BTYPE_NUM), Use to store RNA 'step' value, for dragging and click-step.
+ * (type == UI_BTYPE_LABEL), Use (a1 == 1.0f) to use a2 as a blending factor (wow, this is imaginative!).
+ * (type == UI_BTYPE_SCROLL) Use as scroll size.
+ * (type == UI_BTYPE_SEARCH_MENU) Use as number or rows.
+ * (type == UI_BTYPE_COLOR) Use as indication of color palette
*/
float a1;
- /* (type == HSVCIRCLE ), Use to store the luminosity.
- * (type == NUM), Use to store RNA 'precision' value, for dragging and click-step.
- * (type == LABEL), If (a1 == 1.0f) use a2 as a blending factor.
- * (type == SEARCH_MENU) Use as number or columns.
- * (type == COLOR) Use as index in palette (not so good, needs refactor)
+ /* (type == UI_BTYPE_HSVCIRCLE ), Use to store the luminosity.
+ * (type == UI_BTYPE_NUM), Use to store RNA 'precision' value, for dragging and click-step.
+ * (type == UI_BTYPE_LABEL), If (a1 == 1.0f) use a2 as a blending factor.
+ * (type == UI_BTYPE_SEARCH_MENU) Use as number or columns.
+ * (type == UI_BTYPE_COLOR) Use as index in palette (not so good, needs refactor)
*/
float a2;
@@ -253,21 +254,25 @@ struct uiBut {
uiLink *link;
short linkto[2]; /* region relative coords */
- const char *tip, *lockstr;
+ const char *tip;
+ uiButToolTipFunc tip_func;
+ void *tip_argN;
+
+ const char *lockstr;
BIFIconID icon;
bool lock;
- char dt; /* drawtype: UI_EMBOSS, UI_EMBOSSN ... etc, copied from the block */
+ char dt; /* drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the block */
signed char pie_dir; /* direction in a pie menu, used for collision detection (RadialDirection) */
char changed; /* could be made into a single flag */
unsigned char unit_type; /* so buttons can support unit systems which are not RNA */
short modifier_key;
short iconadd;
- /* BLOCK data */
+ /* UI_BTYPE_BLOCK data */
uiBlockCreateFunc block_create_func;
- /* PULLDOWN/MENU data */
+ /* UI_BTYPE_PULLDOWN/UI_BTYPE_MENU data */
uiMenuCreateFunc menu_create_func;
/* RNA data */
@@ -306,6 +311,16 @@ struct uiBut {
uiBlock *block;
};
+typedef struct ColorPicker {
+ struct ColorPicker *next, *prev;
+ float color_data[3]; /* colr data may be HSV or HSL for now */
+ int representation; /* store hsv/hsl value */
+} ColorPicker;
+
+typedef struct ColorPickerData {
+ ListBase list;
+} ColorPickerData;
+
struct PieMenuData {
float pie_dir[2];
float pie_center_init[2];
@@ -365,7 +380,7 @@ struct uiBlock {
short alignnr;
char direction;
- char dt; /* drawtype: UI_EMBOSS, UI_EMBOSSN ... etc, copied to buttons */
+ char dt; /* drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to buttons */
bool auto_open;
char _pad[7];
double auto_open_last;
@@ -375,7 +390,7 @@ struct uiBlock {
char lock;
char active; /* to keep blocks while drawing and free them afterwards */
char tooltipdisabled; /* to avoid tooltip after click */
- char endblock; /* uiEndBlock done? */
+ char endblock; /* UI_block_end done? */
eBlockBoundsCalc bounds_type; /* for doing delayed */
int mx, my;
@@ -392,7 +407,7 @@ struct uiBlock {
void *evil_C; /* XXX hack for dynamic operator enums */
struct UnitSettings *unit; /* unit system, used a lot for numeric buttons so include here rather then fetching through the scene every time. */
- float _hsv[3]; /* XXX, only access via ui_block_hsv_get() */
+ ColorPickerData color_pickers; /* XXX, only accessed by color picker templates */
bool color_profile; /* color profile for correcting linear colors for display */
@@ -410,7 +425,7 @@ typedef struct uiSafetyRct {
/* interface.c */
-extern void ui_delete_linkline(uiLinkLine *line, uiBut *but);
+extern void ui_linkline_remove(uiLinkLine *line, uiBut *but);
void ui_fontscale(short *points, float aspect);
@@ -422,49 +437,50 @@ extern void ui_block_to_window_rctf(const struct ARegion *ar, uiBlock *block, rc
extern void ui_window_to_block_fl(const struct ARegion *ar, uiBlock *block, float *x, float *y);
extern void ui_window_to_block(const struct ARegion *ar, uiBlock *block, int *x, int *y);
extern void ui_window_to_region(const ARegion *ar, int *x, int *y);
+extern void ui_region_to_window(const struct ARegion *ar, int *x, int *y);
-extern double ui_get_but_val(uiBut *but);
-extern void ui_set_but_val(uiBut *but, double value);
-extern void ui_set_but_hsv(uiBut *but);
-extern void ui_get_but_vectorf(uiBut *but, float vec[3]);
-extern void ui_set_but_vectorf(uiBut *but, const float vec[3]);
+extern double ui_but_value_get(uiBut *but);
+extern void ui_but_value_set(uiBut *but, double value);
+extern void ui_but_hsv_set(uiBut *but);
+extern void ui_but_v3_get(uiBut *but, float vec[3]);
+extern void ui_but_v3_set(uiBut *but, const float vec[3]);
extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect,
const float mx, const float my);
extern void ui_hsvcircle_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xpos, float *ypos);
extern void ui_hsvcube_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp);
-bool ui_color_picker_use_display_colorspace(struct uiBut *but);
+bool ui_but_is_colorpicker_display_space(struct uiBut *but);
-extern void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) ATTR_NONNULL();
-extern void ui_get_but_string(uiBut *but, char *str, const size_t maxlen) ATTR_NONNULL();
-extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL();
-extern bool ui_set_but_string(struct bContext *C, uiBut *but, const char *str) ATTR_NONNULL();
-extern bool ui_set_but_string_eval_num(struct bContext *C, uiBut *but, const char *str, double *value) ATTR_NONNULL();
-extern int ui_get_but_string_max_length(uiBut *but);
-extern uiBut *ui_get_but_drag_multi_edit(uiBut *but);
+extern void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) ATTR_NONNULL();
+extern void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) ATTR_NONNULL();
+extern void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL();
+extern bool ui_but_string_set(struct bContext *C, uiBut *but, const char *str) ATTR_NONNULL();
+extern bool ui_but_string_set_eval_num(struct bContext *C, uiBut *but, const char *str, double *value) ATTR_NONNULL();
+extern int ui_but_string_get_max_length(uiBut *but);
+extern uiBut *ui_but_drag_multi_edit_get(uiBut *but);
-extern void ui_set_but_default(struct bContext *C, const bool all, const bool use_afterfunc);
+extern void ui_but_default_set(struct bContext *C, const bool all, const bool use_afterfunc);
-extern void ui_check_but(uiBut *but);
-extern bool ui_is_but_float(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
-extern bool ui_is_but_bool(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
-extern bool ui_is_but_unit(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
-extern bool ui_is_but_compatible(const uiBut *but_a, const uiBut *but_b) ATTR_WARN_UNUSED_RESULT;
-extern bool ui_is_but_rna_valid(uiBut *but) ATTR_WARN_UNUSED_RESULT;
-extern bool ui_is_but_utf8(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
-extern bool ui_is_but_search_unlink_visible(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
+extern void ui_but_update(uiBut *but);
+extern bool ui_but_is_float(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
+extern bool ui_but_is_bool(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
+extern bool ui_but_is_unit(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
+extern bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b) ATTR_WARN_UNUSED_RESULT;
+extern bool ui_but_is_rna_valid(uiBut *but) ATTR_WARN_UNUSED_RESULT;
+extern bool ui_but_is_utf8(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
+extern bool ui_but_is_search_unlink_visible(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
-extern int ui_is_but_push_ex(uiBut *but, double *value) ATTR_WARN_UNUSED_RESULT;
-extern int ui_is_but_push(uiBut *but) ATTR_WARN_UNUSED_RESULT;
+extern int ui_but_is_pushed_ex(uiBut *but, double *value) ATTR_WARN_UNUSED_RESULT;
+extern int ui_but_is_pushed(uiBut *but) ATTR_WARN_UNUSED_RESULT;
-extern void ui_bounds_block(uiBlock *block);
+extern void ui_block_bounds_calc(uiBlock *block);
extern void ui_block_translate(uiBlock *block, int x, int y);
-extern void ui_block_do_align(uiBlock *block);
+extern void ui_block_align_calc(uiBlock *block);
-extern struct ColorManagedDisplay *ui_block_display_get(uiBlock *block);
-void ui_block_to_display_space_v3(uiBlock *block, float pixel[3]);
-void ui_block_to_scene_linear_v3(uiBlock *block, float pixel[3]);
+extern struct ColorManagedDisplay *ui_block_cm_display_get(uiBlock *block);
+void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3]);
+void ui_block_cm_to_scene_linear_v3(uiBlock *block, float pixel[3]);
/* interface_regions.c */
@@ -540,7 +556,7 @@ void ui_popup_menu_memory_set(uiBlock *block, struct uiBut *but);
void ui_popup_translate(struct bContext *C, struct ARegion *ar, const int mdiff[2]);
-float *ui_block_hsv_get(struct uiBlock *block);
+ColorPicker *ui_block_colorpicker_create(struct uiBlock *block);
void ui_popup_block_scrolltest(struct uiBlock *block);
void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3]);
@@ -557,7 +573,7 @@ int ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but
void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, const struct wmEvent *event);
bool ui_searchbox_apply(uiBut *but, struct ARegion *ar);
void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
-void ui_but_search_test(uiBut *but);
+void ui_but_search_refresh(uiBut *but);
uiBlock *ui_popup_block_refresh(struct bContext *C, uiPopupBlockHandle *handle,
ARegion *butregion, uiBut *but);
@@ -570,7 +586,7 @@ uiPopupBlockHandle *ui_popup_menu_create(struct bContext *C, struct ARegion *but
void ui_popup_block_free(struct bContext *C, uiPopupBlockHandle *handle);
-int ui_step_name_menu(uiBut *but, int step);
+int ui_but_menu_step(uiBut *but, int step);
struct AutoComplete;
@@ -579,7 +595,7 @@ extern int ui_handler_panel_region(struct bContext *C, const struct wmEvent *eve
extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, const rcti *rect, const bool show_pin);
/* interface_draw.c */
-extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select);
+extern void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select);
void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha);
@@ -587,7 +603,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol,
void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
void ui_draw_but_COLORBAND(uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
-void ui_draw_but_NORMAL(uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
+void ui_draw_but_UNITVEC(uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
void ui_draw_but_CURVE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
void ui_draw_but_IMAGE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
@@ -596,25 +612,32 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol
/* interface_handlers.c */
PointerRNA *ui_handle_afterfunc_add_operator(struct wmOperatorType *ot, int opcontext, bool create_props);
extern void ui_pan_to_scroll(const struct wmEvent *event, int *type, int *val);
-extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but);
-extern void ui_button_activate_over(struct bContext *C, struct ARegion *ar, uiBut *but);
-extern void ui_button_execute_begin(struct bContext *C, struct ARegion *ar, uiBut *but, void **active_back);
-extern void ui_button_execute_end(struct bContext *C, struct ARegion *ar, uiBut *but, void *active_back);
-extern void ui_button_active_free(const struct bContext *C, uiBut *but);
-extern bool ui_button_is_active(struct ARegion *ar) ATTR_WARN_UNUSED_RESULT;
-extern int ui_button_open_menu_direction(uiBut *but);
-extern void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, const bool restore);
-extern uiBut *ui_but_find_activated(struct ARegion *ar);
+extern void ui_but_activate_event(struct bContext *C, struct ARegion *ar, uiBut *but);
+extern void ui_but_activate_over(struct bContext *C, struct ARegion *ar, uiBut *but);
+extern void ui_but_execute_begin(struct bContext *C, struct ARegion *ar, uiBut *but, void **active_back);
+extern void ui_but_execute_end(struct bContext *C, struct ARegion *ar, uiBut *but, void *active_back);
+extern void ui_but_active_free(const struct bContext *C, uiBut *but);
+extern bool ui_but_is_active(struct ARegion *ar) ATTR_WARN_UNUSED_RESULT;
+extern int ui_but_menu_direction(uiBut *but);
+extern void ui_but_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, const bool restore);
+extern uiBut *ui_but_find_select_in_enum(uiBut *but, int direction);
+extern uiBut *ui_but_find_active_in_region(struct ARegion *ar);
bool ui_but_is_editable(const uiBut *but);
+bool ui_but_is_editable_as_text(const uiBut *but);
void ui_but_pie_dir_visual(RadialDirection dir, float vec[2]);
void ui_but_pie_dir(RadialDirection dir, float vec[2]);
-float ui_block_calculate_pie_segment(struct uiBlock *block, const float event_xy[2]);
+float ui_block_calc_pie_segment(struct uiBlock *block, const float event_xy[2]);
-void ui_button_clipboard_free(void);
+void ui_but_clipboard_free(void);
void ui_panel_menu(struct bContext *C, ARegion *ar, Panel *pa);
uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new);
uiBut *ui_but_find_new(uiBlock *block_old, const uiBut *but_new);
+#ifdef WITH_INPUT_IME
+void ui_but_ime_reposition(uiBut *but, int x, int y, bool complete);
+struct wmIMEData *ui_but_get_ime_data(uiBut *but);
+#endif
+
/* interface_widgets.c */
void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3);
void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad, bool use_alpha);
@@ -635,12 +658,13 @@ void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, const char *name,
void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state);
#define UI_TEXT_MARGIN_X 0.4f
+#define UI_POPUP_MARGIN (UI_DPI_FAC * 12)
/* interface_style.c */
void uiStyleInit(void);
/* interface_icons.c */
-int ui_id_icon_get(struct bContext *C, struct ID *id, const bool big);
+int ui_id_icon_get(const struct bContext *C, struct ID *id, const bool big);
/* resources.c */
void init_userdef_do_versions(void);
@@ -675,5 +699,6 @@ void ui_but_anim_autokey(struct bContext *C, uiBut *but, struct Scene *scene, fl
/* interface_eyedropper.c */
void UI_OT_eyedropper_color(struct wmOperatorType *ot);
void UI_OT_eyedropper_id(struct wmOperatorType *ot);
+void UI_OT_eyedropper_depth(struct wmOperatorType *ot);
#endif /* __INTERFACE_INTERN_H__ */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index c2bd6d307d1..44c1ed474d5 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -184,7 +184,7 @@ static const char *ui_item_name_add_colon(const char *name, char namestr[UI_MAX_
return name;
}
-static int ui_item_fit(int item, int pos, int all, int available, int last, int alignment, int *offset)
+static int ui_item_fit(int item, int pos, int all, int available, bool is_last, int alignment, int *offset)
{
if (offset)
*offset = 0;
@@ -195,7 +195,7 @@ static int ui_item_fit(int item, int pos, int all, int available, int last, int
if (all > available) {
/* contents is bigger than available space */
- if (last)
+ if (is_last)
return available - pos;
else
return (item * available) / all;
@@ -203,7 +203,7 @@ static int ui_item_fit(int item, int pos, int all, int available, int last, int
else {
/* contents is smaller or equal to available space */
if (alignment == UI_LAYOUT_ALIGN_EXPAND) {
- if (last)
+ if (is_last)
return available - pos;
else
return (item * available) / all;
@@ -235,9 +235,10 @@ static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, bool
variable = (ui_layout_vary_direction(layout) == UI_ITEM_VARY_X);
if (variable) {
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
/* it may seem odd that the icon only adds (UI_UNIT_X / 4)
* but taking margins into account its fine */
- return (UI_GetStringWidth(name) +
+ return (UI_fontstyle_string_width(fstyle, name) +
(UI_UNIT_X * ((compact ? 1.25f : 1.50f) +
(icon ? 0.25f : 0.0f))));
}
@@ -286,7 +287,7 @@ static void ui_item_position(uiItem *item, int x, int y, int w, int h)
bitem->but->rect.xmax = x + w;
bitem->but->rect.ymax = y + h;
- ui_check_but(bitem->but); /* for strlen */
+ ui_but_update(bitem->but); /* for strlen */
}
else {
uiLayout *litem = (uiLayout *)item;
@@ -350,14 +351,14 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index)
RNA_property_update(C, ptr, prop);
for (cbut = but->block->buttons.first; cbut; cbut = cbut->next)
- ui_check_but(cbut);
+ ui_but_update(cbut);
}
}
/* create buttons for an item with an RNA array */
static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, int icon,
PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int UNUSED(h),
- int expand, int slider, int toggle, int icon_only)
+ bool expand, bool slider, bool toggle, bool icon_only)
{
uiStyle *style = layout->root->style;
uiBut *but;
@@ -371,11 +372,11 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
subtype = RNA_property_subtype(prop);
sub = ui_item_local_sublayout(layout, layout, 1);
- uiBlockSetCurLayout(block, sub);
+ UI_block_layout_set_current(block, sub);
/* create label */
if (name[0])
- uiDefBut(block, LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* create buttons */
if (type == PROP_BOOLEAN && ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER)) {
@@ -386,7 +387,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
unsigned int layer_used = 0;
unsigned int layer_active = 0;
- uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, false));
+ UI_block_layout_set_current(block, uiLayoutAbsolute(layout, false));
unit = UI_UNIT_X * 0.75;
butw = unit;
@@ -410,7 +411,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
}
for (b = 0; b < cols; b++) {
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
for (a = 0; a < colbuts; a++) {
const int layer_num = a + b * colbuts;
@@ -428,7 +429,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
but = uiDefAutoButR(block, ptr, prop, layer_num, "", icon, x + butw * a, y + buth, butw, buth);
if (subtype == PROP_LAYER_MEMBER)
- uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num));
+ UI_but_func_set(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num));
}
for (a = 0; a < colbuts; a++) {
const int layer_num = a + len / 2 + b * colbuts;
@@ -446,9 +447,9 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
but = uiDefAutoButR(block, ptr, prop, layer_num, "", icon, x + butw * a, y, butw, buth);
if (subtype == PROP_LAYER_MEMBER)
- uiButSetFunc(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num));
+ UI_but_func_set(but, ui_layer_but_cb, but, SET_INT_IN_POINTER(layer_num));
}
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
x += colbuts * butw + style->buttonspacex;
}
@@ -457,7 +458,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
int totdim, dim_size[3]; /* 3 == RNA_MAX_ARRAY_DIMENSION */
int row, col;
- uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, true));
+ UI_block_layout_set_current(block, uiLayoutAbsolute(layout, true));
totdim = RNA_property_array_dimension(ptr, prop, dim_size);
if (totdim != 2) return; /* only 2D matrices supported in UI so far */
@@ -470,12 +471,12 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
row = a / dim_size[0];
but = uiDefAutoButR(block, ptr, prop, a, "", ICON_NONE, 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;
+ if (slider && but->type == UI_BTYPE_NUM)
+ but->type = UI_BTYPE_NUM_SLIDER;
}
}
else if (subtype == PROP_DIRECTION && !expand) {
- uiDefButR_prop(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X * 3, UI_UNIT_Y * 3, ptr, prop, 0, 0, 0, -1, -1, NULL);
+ uiDefButR_prop(block, UI_BTYPE_UNITVEC, 0, name, x, y, UI_UNIT_X * 3, UI_UNIT_Y * 3, ptr, prop, -1, 0, 0, -1, -1, NULL);
}
else {
/* note, this block of code is a bit arbitrary and has just been made
@@ -500,8 +501,8 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
}
/* show checkboxes for rna on a non-emboss block (menu for eg) */
- if (type == PROP_BOOLEAN && ELEM(layout->root->block->dt, UI_EMBOSSN, UI_EMBOSSP)) {
- boolarr = MEM_callocN(sizeof(int) * len, "ui_item_array");
+ if (type == PROP_BOOLEAN && ELEM(layout->root->block->dt, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) {
+ boolarr = MEM_callocN(sizeof(int) * len, __func__);
RNA_property_boolean_get_array(ptr, prop, boolarr);
}
@@ -509,12 +510,12 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
if (!icon_only) str[0] = RNA_property_array_item_char(prop, a);
if (boolarr) icon = boolarr[a] ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
but = uiDefAutoButR(block, ptr, prop, a, str, icon, 0, 0, w, UI_UNIT_Y);
- if (slider && but->type == NUM)
- but->type = NUMSLI;
- if (toggle && but->type == OPTION)
- but->type = TOG;
+ if (slider && but->type == UI_BTYPE_NUM)
+ but->type = UI_BTYPE_NUM_SLIDER;
+ if (toggle && but->type == UI_BTYPE_CHECKBOX)
+ but->type = UI_BTYPE_TOGGLE;
if ((a == 0) && (subtype == PROP_AXISANGLE))
- uiButSetUnitType(but, PROP_UNIT_ROTATION);
+ UI_but_unit_type_set(but, PROP_UNIT_ROTATION);
}
if (boolarr) {
@@ -523,7 +524,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
}
}
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
}
static void ui_item_enum_expand_handle(bContext *C, void *arg1, void *arg2)
@@ -545,7 +546,7 @@ static void ui_item_enum_expand_handle(bContext *C, void *arg1, void *arg2)
}
}
static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop,
- const char *uiname, int h, int icon_only)
+ const char *uiname, int h, bool icon_only)
{
/* XXX The way this function currently handles uiname parameter is insane and inconsistent with general UI API:
* * uiname is the *enum property* label.
@@ -571,13 +572,13 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt
/* we dont want nested rows, cols in menus */
if (radial) {
layout_radial = uiLayoutRadial(layout);
- uiBlockSetCurLayout(block, layout_radial);
+ UI_block_layout_set_current(block, layout_radial);
}
else if (layout->root->type != UI_LAYOUT_MENU) {
- uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1));
+ UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1));
}
else {
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
}
for (item = item_array; item->identifier; item++) {
@@ -593,20 +594,20 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt
itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0);
if (icon && name[0] && !icon_only)
- but = uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ but = uiDefIconTextButR_prop(block, UI_BTYPE_ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
else if (icon)
- but = uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ but = uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
else
- but = uiDefButR_prop(block, ROW, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ but = uiDefButR_prop(block, UI_BTYPE_ROW, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
- uiButSetFunc(but, ui_item_enum_expand_handle, but, SET_INT_IN_POINTER(value));
+ UI_but_func_set(but, ui_item_enum_expand_handle, but, SET_INT_IN_POINTER(value));
}
if (ui_layout_local_dir(layout) != UI_LAYOUT_HORIZONTAL)
but->drawflag |= UI_BUT_TEXT_LEFT;
}
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
if (free) {
MEM_freeN(item_array);
@@ -634,16 +635,16 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n
int labelw;
sub = uiLayoutRow(layout, layout->align);
- uiBlockSetCurLayout(block, sub);
+ UI_block_layout_set_current(block, sub);
if (name[0]) {
- /* XXX UI_GetStringWidth is not accurate */
+ /* XXX UI_fontstyle_string_width is not accurate */
#if 0
- labelw = UI_GetStringWidth(name);
+ labelw = UI_fontstyle_string_width(fstyle, name);
CLAMP(labelw, w / 4, 3 * w / 4);
#endif
labelw = w / 3;
- uiDefBut(block, LABEL, 0, name, x, y, labelw, h, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, name, x, y, labelw, h, NULL, 0.0, 0.0, 0, 0, "");
w = w - labelw;
}
@@ -651,15 +652,15 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n
subtype = RNA_property_subtype(prop);
if (subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) {
- uiBlockSetCurLayout(block, uiLayoutRow(sub, true));
+ UI_block_layout_set_current(block, uiLayoutRow(sub, true));
but = uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w - UI_UNIT_X, h);
- /* BUTTONS_OT_file_browse calls uiFileBrowseContextProperty */
- uiDefIconButO(block, BUT, subtype == PROP_DIRPATH ? "BUTTONS_OT_directory_browse" : "BUTTONS_OT_file_browse",
+ /* BUTTONS_OT_file_browse calls UI_context_active_but_prop_get_filebrowser */
+ uiDefIconButO(block, UI_BTYPE_BUT, subtype == PROP_DIRPATH ? "BUTTONS_OT_directory_browse" : "BUTTONS_OT_file_browse",
WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL);
}
else if (flag & UI_ITEM_R_EVENT) {
- uiDefButR_prop(block, KEYEVT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL);
+ uiDefButR_prop(block, UI_BTYPE_KEY_EVENT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL);
}
else if (flag & UI_ITEM_R_FULL_EVENT) {
if (RNA_struct_is_a(ptr->type, &RNA_KeyMapItem)) {
@@ -667,20 +668,20 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n
WM_keymap_item_to_string(ptr->data, buf, sizeof(buf));
- but = uiDefButR_prop(block, HOTKEYEVT, 0, buf, x, y, w, h, ptr, prop, 0, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, ui_keymap_but_cb, but, NULL);
+ but = uiDefButR_prop(block, UI_BTYPE_HOTKEY_EVENT, 0, buf, x, y, w, h, ptr, prop, 0, 0, 0, -1, -1, NULL);
+ UI_but_func_set(but, ui_keymap_but_cb, but, NULL);
if (flag & UI_ITEM_R_IMMEDIATE)
- uiButSetFlag(but, UI_BUT_IMMEDIATE);
+ UI_but_flag_enable(but, UI_BUT_IMMEDIATE);
}
}
else
but = uiDefAutoButR(block, ptr, prop, index, (type == PROP_ENUM && !(flag & UI_ITEM_R_ICON_ONLY)) ? NULL : "", icon, x, y, w, h);
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
return but;
}
-void uiFileBrowseContextProperty(const bContext *C, PointerRNA *ptr, PropertyRNA **prop)
+void UI_context_active_but_prop_get_filebrowser(const bContext *C, PointerRNA *ptr, PropertyRNA **prop)
{
ARegion *ar = CTX_wm_region(C);
uiBlock *block;
@@ -729,14 +730,14 @@ static void ui_item_disabled(uiLayout *layout, const char *name)
uiBut *but;
int w;
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
if (!name)
name = "";
w = ui_text_icon_width(layout, name, 0, 0);
- but = uiDefBut(block, LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
but->flag |= UI_BUT_DISABLED;
but->lock = true;
but->lockstr = "";
@@ -760,24 +761,24 @@ PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *nam
icon = ICON_BLANK1;
/* create button */
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
w = ui_text_icon_width(layout, name, icon, 0);
if (flag & UI_ITEM_R_NO_BG)
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
/* create the button */
if (icon) {
if (name[0]) {
- but = uiDefIconTextButO_ptr(block, BUT, ot, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL);
+ but = uiDefIconTextButO_ptr(block, UI_BTYPE_BUT, ot, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL);
}
else {
- but = uiDefIconButO_ptr(block, BUT, ot, context, icon, 0, 0, w, UI_UNIT_Y, NULL);
+ but = uiDefIconButO_ptr(block, UI_BTYPE_BUT, ot, context, icon, 0, 0, w, UI_UNIT_Y, NULL);
}
}
else {
- but = uiDefButO_ptr(block, BUT, ot, context, name, 0, 0, w, UI_UNIT_Y, NULL);
+ but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, context, name, 0, 0, w, UI_UNIT_Y, NULL);
}
assert(but->optype != NULL);
@@ -787,14 +788,14 @@ PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *nam
but->drawflag |= UI_BUT_TEXT_LEFT;
if (flag & UI_ITEM_R_NO_BG)
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
if (layout->redalert)
- uiButSetFlag(but, UI_BUT_REDALERT);
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
/* assign properties */
if (properties || (flag & UI_ITEM_O_RETURN_PROPS)) {
- PointerRNA *opptr = uiButGetOperatorPtrRNA(but);
+ PointerRNA *opptr = UI_but_operator_ptr_get(but);
if (properties) {
opptr->data = properties;
@@ -904,7 +905,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
if (prop && RNA_property_type(prop) == PROP_ENUM) {
EnumPropertyItem *item, *item_array = NULL;
bool free;
- uiLayout *split;
+ uiLayout *split = NULL;
uiLayout *target;
if (radial) {
@@ -958,7 +959,7 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
}
else {
/* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */
- but = uiDefBut(block, LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL,
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL,
0.0, 0.0, 0, 0, "");
}
ui_but_tip_from_enum_item(but, item);
@@ -977,6 +978,9 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
if (free) {
MEM_freeN(item_array);
}
+
+ /* intentionally don't touch UI_BLOCK_IS_FLIP here,
+ * we don't know the context this is called in */
}
else if (prop && RNA_property_type(prop) != PROP_ENUM) {
RNA_warning("%s.%s, not an enum type", RNA_struct_identifier(ptr.type), propname);
@@ -1000,7 +1004,7 @@ void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char
PointerRNA ptr;
PropertyRNA *prop;
- UI_OPERATOR_ERROR_RET(ot, opname, return );
+ UI_OPERATOR_ERROR_RET(ot, opname, return);
WM_operator_properties_create_ptr(&ptr, ot);
@@ -1032,7 +1036,7 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char
int value;
bool free;
- UI_OPERATOR_ERROR_RET(ot, opname, return );
+ UI_OPERATOR_ERROR_RET(ot, opname, return);
WM_operator_properties_create_ptr(&ptr, ot);
@@ -1071,7 +1075,7 @@ void uiItemBooleanO(uiLayout *layout, const char *name, int icon, const char *op
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr;
- UI_OPERATOR_ERROR_RET(ot, opname, return );
+ UI_OPERATOR_ERROR_RET(ot, opname, return);
WM_operator_properties_create_ptr(&ptr, ot);
RNA_boolean_set(&ptr, propname, value);
@@ -1084,7 +1088,7 @@ void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr;
- UI_OPERATOR_ERROR_RET(ot, opname, return );
+ UI_OPERATOR_ERROR_RET(ot, opname, return);
WM_operator_properties_create_ptr(&ptr, ot);
RNA_int_set(&ptr, propname, value);
@@ -1097,7 +1101,7 @@ void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opna
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr;
- UI_OPERATOR_ERROR_RET(ot, opname, return );
+ UI_OPERATOR_ERROR_RET(ot, opname, return);
WM_operator_properties_create_ptr(&ptr, ot);
RNA_float_set(&ptr, propname, value);
@@ -1110,7 +1114,7 @@ void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opn
wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
PointerRNA ptr;
- UI_OPERATOR_ERROR_RET(ot, opname, return );
+ UI_OPERATOR_ERROR_RET(ot, opname, return);
WM_operator_properties_create_ptr(&ptr, ot);
RNA_string_set(&ptr, propname, value);
@@ -1126,7 +1130,7 @@ void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
/* RNA property items */
static void ui_item_rna_size(uiLayout *layout, const char *name, int icon, PointerRNA *ptr, PropertyRNA *prop,
- int index, int icon_only, int *r_w, int *r_h)
+ int index, bool icon_only, int *r_w, int *r_h)
{
PropertyType type;
PropertySubType subtype;
@@ -1196,10 +1200,11 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
uiBut *but = NULL;
PropertyType type;
char namestr[UI_MAX_NAME_STR];
- int len, w, h, slider, toggle, expand, icon_only, no_bg;
+ int len, w, h;
+ bool slider, toggle, expand, icon_only, no_bg;
bool is_array;
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
/* retrieve info */
type = RNA_property_type(prop);
@@ -1232,7 +1237,8 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
name = ui_item_name_add_colon(name, namestr);
}
- if (layout->root->type == UI_LAYOUT_MENU) {
+ /* menus and pie-menus don't show checkbox without this */
+ if (ELEM(layout->root->type, UI_LAYOUT_MENU, UI_LAYOUT_PIEMENU)) {
if (type == PROP_BOOLEAN && ((is_array == false) || (index != RNA_NO_INDEX))) {
if (is_array) icon = (RNA_property_boolean_get_index(ptr, prop, index)) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
else icon = (RNA_property_boolean_get(ptr, prop)) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
@@ -1248,17 +1254,17 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
}
}
- slider = (flag & UI_ITEM_R_SLIDER);
- toggle = (flag & UI_ITEM_R_TOGGLE);
- expand = (flag & UI_ITEM_R_EXPAND);
- icon_only = (flag & UI_ITEM_R_ICON_ONLY);
+ slider = (flag & UI_ITEM_R_SLIDER) != 0;
+ toggle = (flag & UI_ITEM_R_TOGGLE) != 0;
+ expand = (flag & UI_ITEM_R_EXPAND) != 0;
+ icon_only = (flag & UI_ITEM_R_ICON_ONLY) != 0;
no_bg = (flag & UI_ITEM_R_NO_BG);
/* get size */
ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, &w, &h);
if (no_bg)
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
/* array property */
if (index == RNA_NO_INDEX && is_array)
@@ -1266,11 +1272,11 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
/* enum item */
else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) {
if (icon && name[0] && !icon_only)
- uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ uiDefIconTextButR_prop(block, UI_BTYPE_ROW, 0, icon, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
else if (icon)
- uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
else
- uiDefButR_prop(block, ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ uiDefButR_prop(block, UI_BTYPE_ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
}
/* expanded enum */
else if (type == PROP_ENUM && (expand || RNA_property_flag(prop) & PROP_ENUM_FLAG))
@@ -1281,29 +1287,29 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
ui_but_add_search(but, ptr, prop, NULL, NULL);
if (layout->redalert)
- uiButSetFlag(but, UI_BUT_REDALERT);
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
}
/* single button */
else {
but = uiDefAutoButR(block, ptr, prop, index, name, icon, 0, 0, w, h);
- if (slider && but->type == NUM)
- but->type = NUMSLI;
+ if (slider && but->type == UI_BTYPE_NUM)
+ but->type = UI_BTYPE_NUM_SLIDER;
- if (toggle && but->type == OPTION)
- but->type = TOG;
+ if (toggle && but->type == UI_BTYPE_CHECKBOX)
+ but->type = UI_BTYPE_TOGGLE;
if (layout->redalert)
- uiButSetFlag(but, UI_BUT_REDALERT);
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
}
/* Mark non-embossed textfields inside a listbox. */
- if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == TEX) && (but->dt & UI_EMBOSSN)) {
- uiButSetFlag(but, UI_BUT_LIST_ITEM);
+ if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == UI_BTYPE_TEXT) && (but->dt & UI_EMBOSS_NONE)) {
+ UI_but_flag_enable(but, UI_BUT_LIST_ITEM);
}
if (no_bg)
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
/* ensure text isn't added to icon_only buttons */
if (but && icon_only) {
@@ -1431,6 +1437,9 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname
MEM_freeN(item);
}
}
+
+ /* intentionally don't touch UI_BLOCK_IS_FLIP here,
+ * we don't know the context this is called in */
}
/* Pointer RNA button with search */
@@ -1444,8 +1453,8 @@ typedef struct CollItemSearch {
static int sort_search_items_list(const void *a, const void *b)
{
- CollItemSearch *cis1 = (CollItemSearch *)a;
- CollItemSearch *cis2 = (CollItemSearch *)b;
+ const CollItemSearch *cis1 = a;
+ const CollItemSearch *cis2 = b;
if (BLI_strcasecmp(cis1->name, cis2->name) > 0)
return 1;
@@ -1460,7 +1469,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, const char *s
int i = 0, iconid = 0, flag = RNA_property_flag(but->rnaprop);
ListBase *items_list = MEM_callocN(sizeof(ListBase), "items_list");
CollItemSearch *cis;
- const int skip_filter = !but->changed;
+ const bool skip_filter = !but->changed;
/* build a temporary list of relevant items first */
RNA_PROP_BEGIN (&but->rnasearchpoin, itemptr, but->rnasearchprop)
@@ -1486,7 +1495,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, const char *s
BLI_strncpy(name_ui, id->name + 2, sizeof(name_ui));
#endif
name = BLI_strdup(name_ui);
- iconid = ui_id_icon_get((bContext *)C, id, false);
+ iconid = ui_id_icon_get(C, id, false);
}
else {
name = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL); /* could use the string length here */
@@ -1508,11 +1517,11 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, const char *s
}
RNA_PROP_END;
- BLI_sortlist(items_list, sort_search_items_list);
+ BLI_listbase_sort(items_list, sort_search_items_list);
/* add search items from temporary list */
for (cis = items_list->first; cis; cis = cis->next) {
- if (false == uiSearchItemAdd(items, cis->name, SET_INT_IN_POINTER(cis->index), cis->iconid)) {
+ if (false == UI_search_item_add(items, cis->name, SET_INT_IN_POINTER(cis->index), cis->iconid)) {
break;
}
}
@@ -1564,7 +1573,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
/* turn button into search button */
if (searchprop) {
- but->type = RNA_property_is_unlink(prop) ? SEARCH_MENU_UNLINK : SEARCH_MENU;
+ but->type = RNA_property_is_unlink(prop) ? UI_BTYPE_SEARCH_MENU_UNLINK : UI_BTYPE_SEARCH_MENU;
but->hardmax = MAX2(but->hardmax, 256.0f);
but->rnasearchpoin = *searchptr;
but->rnasearchprop = searchprop;
@@ -1576,7 +1585,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
but->str[0] = 0;
}
- uiButSetSearchFunc(but, rna_search_cb, but, NULL, NULL);
+ UI_but_func_search_set(but, rna_search_cb, but, NULL, NULL);
}
}
@@ -1663,6 +1672,9 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
if (layout->context)
CTX_store_set(C, NULL);
+
+ /* menus are created flipped (from event handling pov) */
+ layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
}
static uiBut *ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN,
@@ -1672,10 +1684,10 @@ static uiBut *ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuC
uiBut *but;
int w, h;
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
if (layout->root->type == UI_LAYOUT_HEADER)
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
if (!name)
name = "";
@@ -1709,12 +1721,12 @@ static uiBut *ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuC
}
if (layout->root->type == UI_LAYOUT_HEADER) {
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
if (ELEM(layout->root->type, UI_LAYOUT_PANEL, UI_LAYOUT_TOOLBAR) ||
(force_menu && layout->root->type != UI_LAYOUT_MENU)) /* We never want a dropdown in menu! */
{
- uiButSetMenuFromPulldown(but);
+ UI_but_type_set_menu_from_pulldown(but);
}
return but;
@@ -1748,7 +1760,7 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon)
uiBut *but;
int w;
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
if (!name)
name = "";
@@ -1758,11 +1770,11 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon)
w = ui_text_icon_width(layout, name, icon, 0);
if (icon && name[0])
- but = uiDefIconTextBut(block, LABEL, 0, icon, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but = uiDefIconTextBut(block, UI_BTYPE_LABEL, 0, icon, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
else if (icon)
- but = uiDefIconBut(block, LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but = uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
else
- but = uiDefBut(block, LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
/* to compensate for string size padding in ui_text_icon_width,
* make text aligned right if the layout is aligned right.
@@ -1791,7 +1803,7 @@ void uiItemLDrag(uiLayout *layout, PointerRNA *ptr, const char *name, int icon)
if (ptr && ptr->type)
if (RNA_struct_is_ID(ptr->type))
- uiButSetDragID(but, ptr->id.data);
+ UI_but_drag_set_id(but, ptr->id.data);
}
@@ -1803,7 +1815,7 @@ void uiItemV(uiLayout *layout, const char *name, int icon, int argval)
int *retvalue = (block->handle) ? &block->handle->retvalue : NULL;
int w;
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
if (!name)
name = "";
@@ -1813,11 +1825,11 @@ void uiItemV(uiLayout *layout, const char *name, int icon, int argval)
w = ui_text_icon_width(layout, name, icon, 0);
if (icon && name[0])
- uiDefIconTextButI(block, BUT, argval, icon, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
+ uiDefIconTextButI(block, UI_BTYPE_BUT, argval, icon, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
else if (icon)
- uiDefIconButI(block, BUT, argval, icon, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
+ uiDefIconButI(block, UI_BTYPE_BUT, argval, icon, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
else
- uiDefButI(block, BUT, argval, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
+ uiDefButI(block, UI_BTYPE_BUT, argval, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
}
/* separator item */
@@ -1827,8 +1839,8 @@ void uiItemS(uiLayout *layout)
bool is_menu = ui_block_is_menu(block);
int space = (is_menu) ? 0.45f * UI_UNIT_X : 0.3f * UI_UNIT_X;
- uiBlockSetCurLayout(block, layout);
- uiDefBut(block, (is_menu) ? SEPRLINE : SEPR, 0, "", 0, 0, space, space, NULL, 0.0, 0.0, 0, 0, "");
+ UI_block_layout_set_current(block, layout);
+ uiDefBut(block, (is_menu) ? UI_BTYPE_SEPR_LINE : UI_BTYPE_SEPR, 0, "", 0, 0, space, space, NULL, 0.0, 0.0, 0, 0, "");
}
/* level items */
@@ -1856,8 +1868,10 @@ static void menu_item_enum_opname_menu(bContext *UNUSED(C), uiLayout *layout, vo
uiLayoutSetOperatorContext(layout, lvl->opcontext);
uiItemsEnumO(layout, lvl->opname, lvl->propname);
+ layout->root->block->flag |= UI_BLOCK_IS_FLIP;
+
/* override default, needed since this was assumed pre 2.70 */
- uiBlockSetDirection(layout->root->block, UI_DOWN);
+ UI_block_direction_set(layout->root->block, UI_DIR_DOWN);
}
void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const char *propname, const char *name, int icon)
@@ -1866,7 +1880,7 @@ void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const ch
MenuItemLevel *lvl;
uiBut *but;
- UI_OPERATOR_ERROR_RET(ot, opname, return );
+ UI_OPERATOR_ERROR_RET(ot, opname, return);
if (!ot->srna) {
ui_item_disabled(layout, opname);
@@ -1908,19 +1922,12 @@ static void menu_item_enum_rna_menu(bContext *UNUSED(C), uiLayout *layout, void
uiLayoutSetOperatorContext(layout, lvl->opcontext);
uiItemsEnumR(layout, &lvl->rnapoin, lvl->propname);
+ layout->root->block->flag |= UI_BLOCK_IS_FLIP;
}
-void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon)
+void uiItemMenuEnumR_prop(uiLayout *layout, struct PointerRNA *ptr, PropertyRNA *prop, const char *name, int icon)
{
MenuItemLevel *lvl;
- PropertyRNA *prop;
-
- prop = RNA_struct_find_property(ptr, propname);
- if (!prop) {
- ui_item_disabled(layout, propname);
- RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
if (!name)
name = RNA_property_ui_name(prop);
@@ -1929,12 +1936,26 @@ void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propn
lvl = MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel");
lvl->rnapoin = *ptr;
- BLI_strncpy(lvl->propname, propname, sizeof(lvl->propname));
+ BLI_strncpy(lvl->propname, RNA_property_identifier(prop), sizeof(lvl->propname));
lvl->opcontext = layout->root->opcontext;
ui_item_menu(layout, name, icon, menu_item_enum_rna_menu, NULL, lvl, RNA_property_description(prop), false);
}
+void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_struct_find_property(ptr, propname);
+ if (!prop) {
+ ui_item_disabled(layout, propname);
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ uiItemMenuEnumR_prop(layout, ptr, prop, name, icon);
+}
+
/**************************** Layout Items ***************************/
/* single-row layout */
@@ -2129,7 +2150,7 @@ static RadialDirection ui_get_radialbut_vec(float vec[2], short itemnum)
static bool ui_item_is_radial_displayable(uiItem *item)
{
- if ((item->type == ITEM_BUTTON) && (((uiButtonItem *)item)->but->type == LABEL))
+ if ((item->type == ITEM_BUTTON) && (((uiButtonItem *)item)->but->type == UI_BTYPE_LABEL))
return false;
return true;
@@ -2138,7 +2159,7 @@ static bool ui_item_is_radial_displayable(uiItem *item)
static bool ui_item_is_radial_drawable(uiButtonItem *bitem)
{
- if (ELEM(bitem->but->type, SEPR, SEPRLINE))
+ if (ELEM(bitem->but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE))
return false;
return true;
@@ -2194,7 +2215,7 @@ static void ui_litem_layout_radial(uiLayout *litem)
bitem->but->rect.xmax += 1.5f * UI_UNIT_X;
/* enable drawing as pie item if supported by widget */
if (ui_item_is_radial_drawable(bitem))
- bitem->but->dt = UI_EMBOSSR;
+ bitem->but->dt = UI_EMBOSS_RADIAL;
}
ui_item_size(item, &itemw, &itemh);
@@ -2499,7 +2520,7 @@ static void ui_litem_layout_split(uiLayout *litem)
uiLayoutItemSplit *split = (uiLayoutItemSplit *)litem;
uiItem *item;
float percentage;
- const int tot = BLI_countlist(&litem->items);
+ const int tot = BLI_listbase_count(&litem->items);
int itemh, x, y, w, colw = 0;
if (tot == 0)
@@ -2587,7 +2608,7 @@ uiLayout *uiLayoutRow(uiLayout *layout, int align)
litem->w = layout->w;
BLI_addtail(&layout->items, litem);
- uiBlockSetCurLayout(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
return litem;
}
@@ -2608,7 +2629,7 @@ uiLayout *uiLayoutColumn(uiLayout *layout, int align)
litem->w = layout->w;
BLI_addtail(&layout->items, litem);
- uiBlockSetCurLayout(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
return litem;
}
@@ -2630,7 +2651,7 @@ uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align)
flow->number = number;
BLI_addtail(&layout->items, flow);
- uiBlockSetCurLayout(layout->root->block, &flow->litem);
+ UI_block_layout_set_current(layout->root->block, &flow->litem);
return &flow->litem;
}
@@ -2650,7 +2671,7 @@ static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type)
box->litem.w = layout->w;
BLI_addtail(&layout->items, box);
- uiBlockSetCurLayout(layout->root->block, &box->litem);
+ UI_block_layout_set_current(layout->root->block, &box->litem);
box->roundbox = uiDefBut(layout->root->block, type, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, "");
@@ -2670,7 +2691,7 @@ uiLayout *uiLayoutRadial(uiLayout *layout)
for (item = layout->root->layout->items.first; item; item = item->next) {
litem = (uiLayout *)item;
if (litem->item.type == ITEM_LAYOUT_RADIAL) {
- uiBlockSetCurLayout(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
return litem;
}
}
@@ -2685,7 +2706,7 @@ uiLayout *uiLayoutRadial(uiLayout *layout)
litem->w = layout->w;
BLI_addtail(&layout->root->layout->items, litem);
- uiBlockSetCurLayout(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
return litem;
}
@@ -2693,7 +2714,7 @@ uiLayout *uiLayoutRadial(uiLayout *layout)
uiLayout *uiLayoutBox(uiLayout *layout)
{
- return (uiLayout *)ui_layout_box(layout, ROUNDBOX);
+ return (uiLayout *)ui_layout_box(layout, UI_BTYPE_ROUNDBOX);
}
/* Check all buttons defined in this layout, and set any button flagged as UI_BUT_LIST_ITEM as active/selected.
@@ -2707,7 +2728,7 @@ void ui_layout_list_set_labels_active(uiLayout *layout)
ui_layout_list_set_labels_active((uiLayout *)(&bitem->item));
}
else if (bitem->but->flag & UI_BUT_LIST_ITEM) {
- uiButSetFlag(bitem->but, UI_SELECT);
+ UI_but_flag_enable(bitem->but, UI_SELECT);
}
}
}
@@ -2715,7 +2736,7 @@ void ui_layout_list_set_labels_active(uiLayout *layout)
uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr,
PropertyRNA *actprop)
{
- uiLayoutItemBx *box = ui_layout_box(layout, LISTBOX);
+ uiLayoutItemBx *box = ui_layout_box(layout, UI_BTYPE_LISTBOX);
uiBut *but = box->roundbox;
but->custom_data = ui_list;
@@ -2747,7 +2768,7 @@ uiLayout *uiLayoutAbsolute(uiLayout *layout, int align)
litem->redalert = layout->redalert;
BLI_addtail(&layout->items, litem);
- uiBlockSetCurLayout(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
return litem;
}
@@ -2775,7 +2796,7 @@ uiLayout *uiLayoutOverlap(uiLayout *layout)
litem->redalert = layout->redalert;
BLI_addtail(&layout->items, litem);
- uiBlockSetCurLayout(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
return litem;
}
@@ -2797,7 +2818,7 @@ uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align)
split->percentage = percentage;
BLI_addtail(&layout->items, split);
- uiBlockSetCurLayout(layout->root->block, &split->litem);
+ UI_block_layout_set_current(layout->root->block, &split->litem);
return &split->litem;
}
@@ -3052,7 +3073,7 @@ static void ui_item_layout(uiItem *item)
static void ui_layout_end(uiBlock *block, uiLayout *layout, int *x, int *y)
{
if (layout->root->handlefunc)
- uiBlockSetHandleFunc(block, layout->root->handlefunc, layout->root->argv);
+ UI_block_func_handle_set(block, layout->root->handlefunc, layout->root->argv);
ui_item_estimate(&layout->item);
ui_item_layout(&layout->item);
@@ -3085,12 +3106,12 @@ static void ui_layout_add_padding_button(uiLayoutRoot *root)
uiLayout *prev_layout = block->curlayout;
block->curlayout = root->layout;
- uiDefBut(block, SEPR, 0, "", 0, 0, root->padding, root->padding, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_SEPR, 0, "", 0, 0, root->padding, root->padding, NULL, 0.0, 0.0, 0, 0, "");
block->curlayout = prev_layout;
}
}
-uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, uiStyle *style)
+uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, uiStyle *style)
{
uiLayout *layout;
uiLayoutRoot *root;
@@ -3145,7 +3166,7 @@ int uiLayoutGetOperatorContext(uiLayout *layout)
}
-void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout)
+void UI_block_layout_set_current(uiBlock *block, uiLayout *layout)
{
block->curlayout = layout;
}
@@ -3176,7 +3197,7 @@ void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv)
layout->root->argv = argv;
}
-void uiBlockLayoutResolve(uiBlock *block, int *x, int *y)
+void UI_block_layout_resolve(uiBlock *block, int *x, int *y)
{
uiLayoutRoot *root;
@@ -3252,7 +3273,7 @@ static void ui_intro_items(DynStr *ds, ListBase *lb)
/* could also use the INT but this is nicer*/
switch (item->type) {
case ITEM_BUTTON: BLI_dynstr_append(ds, "'type':'BUTTON', "); break;
- case ITEM_LAYOUT_ROW: BLI_dynstr_append(ds, "'type':'ROW', "); break;
+ case ITEM_LAYOUT_ROW: BLI_dynstr_append(ds, "'type':'UI_BTYPE_ROW', "); break;
case ITEM_LAYOUT_COLUMN: BLI_dynstr_append(ds, "'type':'COLUMN', "); break;
case ITEM_LAYOUT_COLUMN_FLOW: BLI_dynstr_append(ds, "'type':'COLUMN_FLOW', "); break;
case ITEM_LAYOUT_ROW_FLOW: BLI_dynstr_append(ds, "'type':'ROW_FLOW', "); break;
@@ -3328,7 +3349,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
/* poll() on this operator may still fail, at the moment there is no nice feedback when this happens
* just fails silently */
if (!WM_operator_repeat_check(C, op)) {
- uiBlockSetButLock(uiLayoutGetBlock(layout), true, "Operator can't' redo");
+ UI_block_lock_set(uiLayoutGetBlock(layout), true, "Operator can't' redo");
/* XXX, could give some nicer feedback or not show redo panel at all? */
uiItemL(layout, IFACE_("* Redo Unsupported *"), ICON_NONE);
@@ -3388,9 +3409,9 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
col = uiLayoutColumn(layout, false);
block = uiLayoutGetBlock(col);
- but = uiDefIconTextBut(block, BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults"));
- uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL);
+ UI_but_func_set(but, ui_layout_operator_buts__reset_cb, op, NULL);
}
#endif
@@ -3403,7 +3424,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
for (but = block->buttons.first; but; but = but->next) {
/* no undo for buttons for operator redo panels */
- uiButClearFlag(but, UI_BUT_UNDO);
+ UI_but_flag_disable(but, UI_BUT_UNDO);
/* only for popups, see [#36109] */
@@ -3411,8 +3432,8 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
* - this is used for allowing operators with popups to rename stuff with fewer clicks
*/
if (is_popup) {
- if ((but->rnaprop == op->type->prop) && (but->type == TEX)) {
- uiButSetFocusOnEnter(CTX_wm_window(C), but);
+ if ((but->rnaprop == op->type->prop) && (but->type == UI_BTYPE_TEXT)) {
+ UI_but_focus_on_enter_event(CTX_wm_window(C), but);
}
}
}
@@ -3420,7 +3441,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op,
}
/* this is a bit of a hack but best keep it in one place at least */
-MenuType *uiButGetMenuType(uiBut *but)
+MenuType *UI_but_menutype_get(uiBut *but)
{
if (but->menu_create_func == ui_item_menutype_func) {
return (MenuType *)but->poin;
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 817445cc14e..41d2a90e548 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -45,7 +45,6 @@
#include "BKE_global.h"
#include "BKE_text.h" /* for UI_OT_reports_to_text */
#include "BKE_report.h"
-#include "BKE_paint.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -98,7 +97,7 @@ static int copy_data_path_button_poll(bContext *C)
char *path;
int index;
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop) {
path = RNA_path_from_ID_to_property(&ptr, prop);
@@ -120,7 +119,7 @@ static int copy_data_path_button_exec(bContext *C, wmOperator *UNUSED(op))
int index;
/* try to create driver using property retrieved from UI */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop) {
path = RNA_path_from_ID_to_property(&ptr, prop);
@@ -160,7 +159,7 @@ static int operator_button_property_finish(bContext *C, PointerRNA *ptr, Propert
RNA_property_update(C, ptr, prop);
/* as if we pressed the button */
- uiContextActivePropertyHandle(C);
+ UI_context_active_but_prop_handle(C);
/* Since we don't want to undo _all_ edits to settings, eg window
* edits on the screen or on operator settings.
@@ -180,7 +179,7 @@ static int reset_default_button_poll(bContext *C)
PropertyRNA *prop;
int index;
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
return (ptr.data && prop && RNA_property_editable(&ptr, prop));
}
@@ -193,7 +192,7 @@ static int reset_default_button_exec(bContext *C, wmOperator *op)
const bool all = RNA_boolean_get(op->ptr, "all");
/* try to reset the nominated setting to its default value */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
/* if there is a valid property that is editable... */
if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
@@ -231,7 +230,7 @@ static int unset_property_button_exec(bContext *C, wmOperator *UNUSED(op))
int index;
/* try to unset the nominated property */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
/* if there is a valid property that is editable... */
if (ptr.data && prop && RNA_property_editable(&ptr, prop) &&
@@ -317,7 +316,7 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll)
int index;
/* try to reset the nominated setting to its default value */
- uiContextActiveProperty(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
/* if there is a valid property that is editable... */
if (ptr.data && prop) {
@@ -516,7 +515,7 @@ static bool ui_editsource_uibut_match(uiBut *but_a, uiBut *but_b)
(but_a->rnaprop == but_b->rnaprop) &&
(but_a->optype == but_b->optype) &&
(but_a->unit_type == but_b->unit_type) &&
- (strncmp(but_a->drawstr, but_b->drawstr, UI_MAX_DRAW_STR) == 0))
+ STREQLEN(but_a->drawstr, but_b->drawstr, UI_MAX_DRAW_STR))
{
return true;
}
@@ -595,7 +594,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op,
static int editsource_exec(bContext *C, wmOperator *op)
{
- uiBut *but = uiContextActiveButton(C);
+ uiBut *but = UI_context_active_but_get(C);
if (but) {
GHashIterator ghi;
@@ -605,7 +604,7 @@ static int editsource_exec(bContext *C, wmOperator *op)
int ret;
/* needed else the active button does not get tested */
- uiFreeActiveButtons(C, CTX_wm_screen(C));
+ UI_screen_free_active_but(C, CTX_wm_screen(C));
// printf("%s: begin\n", __func__);
@@ -715,7 +714,7 @@ static void edittranslation_find_po_file(const char *root, const char *uilng, ch
static int edittranslation_exec(bContext *C, wmOperator *op)
{
- uiBut *but = uiContextActiveButton(C);
+ uiBut *but = UI_context_active_but_get(C);
int ret = OPERATOR_CANCELLED;
if (but) {
@@ -755,7 +754,7 @@ static int edittranslation_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- uiButGetStrInfo(C, but, &but_label, &rna_label, &enum_label, &but_tip, &rna_tip, &enum_tip,
+ UI_but_string_info_get(C, but, &but_label, &rna_label, &enum_label, &but_tip, &rna_tip, &enum_tip,
&rna_struct, &rna_prop, &rna_enum, &rna_ctxt, NULL);
WM_operator_properties_create_ptr(&ptr, ot);
@@ -859,7 +858,7 @@ int UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(e
void UI_drop_color_copy(wmDrag *drag, wmDropBox *drop)
{
- uiDragColorHandle *drag_info = (uiDragColorHandle *)drag->poin;
+ uiDragColorHandle *drag_info = drag->poin;
RNA_float_set_array(drop->ptr, "color", drag_info->color);
RNA_boolean_set(drop->ptr, "gamma", drag_info->gamma_corrected);
@@ -877,9 +876,9 @@ static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
/* find button under mouse, check if it has RNA color property and
* if it does copy the data */
- but = ui_but_find_activated(ar);
+ but = ui_but_find_active_in_region(ar);
- if (but && but->type == COLOR && but->rnaprop) {
+ if (but && but->type == UI_BTYPE_COLOR && but->rnaprop) {
const int color_len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
BLI_assert(color_len <= 4);
@@ -890,13 +889,13 @@ static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
if (!gamma)
- ui_block_to_display_space_v3(but->block, color);
+ ui_block_cm_to_display_space_v3(but->block, color);
RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
}
else if (RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
if (gamma)
- ui_block_to_scene_linear_v3(but->block, color);
+ ui_block_cm_to_scene_linear_v3(but->block, color);
RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
RNA_property_update(C, &but->rnapoin, but->rnaprop);
}
@@ -922,6 +921,7 @@ static void UI_OT_drop_color(wmOperatorType *ot)
ot->description = "Drop colors to buttons";
ot->invoke = drop_color_invoke;
+ ot->flag = OPTYPE_INTERNAL;
RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0);
RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected ");
@@ -932,7 +932,7 @@ static void UI_OT_drop_color(wmOperatorType *ot)
/* ********************************************************* */
/* Registration */
-void UI_buttons_operatortypes(void)
+void ED_button_operatortypes(void)
{
WM_operatortype_append(UI_OT_reset_default_theme);
WM_operatortype_append(UI_OT_copy_data_path_button);
@@ -950,4 +950,5 @@ void UI_buttons_operatortypes(void)
/* external */
WM_operatortype_append(UI_OT_eyedropper_color);
WM_operatortype_append(UI_OT_eyedropper_id);
+ WM_operatortype_append(UI_OT_eyedropper_depth);
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 9265ca0d4b9..d165e2719c5 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -207,7 +207,7 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar)
*/
/* #define UI_USE_PANELTAB */
-Panel *uiPanelFindByType(ARegion *ar, PanelType *pt)
+Panel *UI_panel_find_by_type(ARegion *ar, PanelType *pt)
{
Panel *pa;
const char *idname = pt->idname;
@@ -233,9 +233,9 @@ Panel *uiPanelFindByType(ARegion *ar, PanelType *pt)
}
/**
- * \note \a pa should be return value from #uiPanelFindByType and can be NULL.
+ * \note \a pa should be return value from #UI_panel_find_by_type and can be NULL.
*/
-Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Panel *pa, bool *r_open)
+Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Panel *pa, bool *r_open)
{
Panel *palast, *panext;
const char *drawname = CTX_IFACE_(pt->translation_context, pt->label);
@@ -336,7 +336,7 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Pan
return pa;
}
-void uiEndPanel(uiBlock *block, int width, int height)
+void UI_panel_end(uiBlock *block, int width, int height)
{
Panel *pa = block->panel;
@@ -363,12 +363,12 @@ void uiEndPanel(uiBlock *block, int width, int height)
static void ui_offset_panel_block(uiBlock *block)
{
- uiStyle *style = UI_GetStyleDraw();
+ uiStyle *style = UI_style_get_dpi();
uiBut *but;
int ofsy;
/* compute bounds and offset */
- ui_bounds_block(block);
+ ui_block_bounds_calc(block);
ofsy = block->panel->sizey - style->panelspace;
@@ -401,7 +401,7 @@ static void uiPanelPop(uiBlock *UNUSED(block))
#endif
/* triangle 'icon' for panel header */
-void UI_DrawTriIcon(float x, float y, char dir)
+void UI_draw_icon_tri(float x, float y, char dir)
{
float f3 = 0.15 * U.widget_unit;
float f5 = 0.25 * U.widget_unit;
@@ -542,14 +542,14 @@ static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, const r
if (dir == 'h') {
hrect.xmin = rect->xmin + pnl_icons;
hrect.ymin += 2.0f / block->aspect;
- uiStyleFontDraw(&style->paneltitle, &hrect, activename);
+ UI_fontstyle_draw(&style->paneltitle, &hrect, activename);
}
else {
/* ignore 'pnl_icons', otherwise the text gets offset horizontally
* + 0.001f to avoid flirting with float inaccuracy
*/
hrect.xmin = rect->xmin + (PNL_ICON + 5) / block->aspect + 0.001f;
- uiStyleFontDrawRotated(&style->paneltitle, &hrect, activename);
+ UI_fontstyle_draw_rotated(&style->paneltitle, &hrect, activename);
}
}
@@ -641,11 +641,11 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
else {
/* in some occasions, draw a border */
if (panel->flag & PNL_SELECT) {
- if (panel->control & UI_PNL_SOLID) uiSetRoundBox(UI_CNR_ALL);
- else uiSetRoundBox(UI_CNR_NONE);
+ if (panel->control & UI_PNL_SOLID) UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ else UI_draw_roundbox_corner_set(UI_CNR_NONE);
UI_ThemeColorShade(TH_BACK, -120);
- uiRoundRect(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8);
+ UI_draw_roundbox_unfilled(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8);
}
/* panel backdrop */
@@ -753,9 +753,13 @@ static int find_highest_panel(const void *a1, const void *a2)
const PanelSort *ps1 = a1, *ps2 = a2;
/* stick uppermost header-less panels to the top of the region -
- * prevent them from being sorted */
- if (ps1->pa->sortorder < ps2->pa->sortorder && ps1->pa->type->flag & PNL_NO_HEADER) return -1;
-
+ * prevent them from being sorted (multiple header-less panels have to be sorted though) */
+ if (ps1->pa->type->flag & PNL_NO_HEADER && ps2->pa->type->flag & PNL_NO_HEADER) {
+ /* skip and check for ofs and sortorder below */
+ }
+ else if (ps1->pa->type->flag & PNL_NO_HEADER) return -1;
+ else if (ps2->pa->type->flag & PNL_NO_HEADER) return 1;
+
if (ps1->pa->ofsy + ps1->pa->sizey < ps2->pa->ofsy + ps2->pa->sizey) return 1;
else if (ps1->pa->ofsy + ps1->pa->sizey > ps2->pa->ofsy + ps2->pa->sizey) return -1;
else if (ps1->pa->sortorder > ps2->pa->sortorder) return 1;
@@ -938,7 +942,7 @@ static void ui_do_animate(const bContext *C, Panel *panel)
}
}
-void uiBeginPanels(const bContext *UNUSED(C), ARegion *ar)
+void UI_panels_begin(const bContext *UNUSED(C), ARegion *ar)
{
Panel *pa;
@@ -953,7 +957,7 @@ void uiBeginPanels(const bContext *UNUSED(C), ARegion *ar)
}
/* only draws blocks with panels */
-void uiEndPanels(const bContext *C, ARegion *ar, int *x, int *y)
+void UI_panels_end(const bContext *C, ARegion *ar, int *x, int *y)
{
ScrArea *sa = CTX_wm_area(C);
uiBlock *block;
@@ -1012,7 +1016,7 @@ void uiEndPanels(const bContext *C, ARegion *ar, int *x, int *y)
ui_panels_size(sa, ar, x, y);
}
-void uiDrawPanels(const bContext *C, ARegion *ar)
+void UI_panels_draw(const bContext *C, ARegion *ar)
{
uiBlock *block;
@@ -1021,18 +1025,18 @@ void uiDrawPanels(const bContext *C, ARegion *ar)
/* draw panels, selected on top */
for (block = ar->uiblocks.first; block; block = block->next) {
if (block->active && block->panel && !(block->panel->flag & PNL_SELECT)) {
- uiDrawBlock(C, block);
+ UI_block_draw(C, block);
}
}
for (block = ar->uiblocks.first; block; block = block->next) {
if (block->active && block->panel && (block->panel->flag & PNL_SELECT)) {
- uiDrawBlock(C, block);
+ UI_block_draw(C, block);
}
}
}
-void uiScalePanels(ARegion *ar, float new_width)
+void UI_panels_scale(ARegion *ar, float new_width)
{
uiBlock *block;
uiBut *but;
@@ -1226,7 +1230,7 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
bool UI_panel_category_is_visible(ARegion *ar)
{
- /* more then one */
+ /* more than one */
return ar->panels_category.first && ar->panels_category.first != ar->panels_category.last;
}
@@ -1327,7 +1331,7 @@ void UI_panel_category_clear_all(ARegion *ar)
BLI_freelistN(&ar->panels_category);
}
-/* based on uiDrawBox, check on making a version which allows us to skip some sides */
+/* based on UI_draw_roundbox_gl_mode, check on making a version which allows us to skip some sides */
static void ui_panel_category_draw_tab(int mode, float minx, float miny, float maxx, float maxy, float rad,
int roundboxtype,
const bool use_highlight, const bool use_shadow,
@@ -1420,7 +1424,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
/* no tab outlines for */
// #define USE_FLAT_INACTIVE
View2D *v2d = &ar->v2d;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
const uiFontStyle *fstyle = &style->widget;
const int fontid = fstyle->uifont_id;
short fstyle_points = fstyle->points;
@@ -1486,8 +1490,8 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
}
BLF_enable(fontid, BLF_ROTATION);
- BLF_rotation(fontid, M_PI / 2);
- //uiStyleFontSet(&style->widget);
+ BLF_rotation(fontid, M_PI_2);
+ //UI_fontstyle_set(&style->widget);
ui_fontscale(&fstyle_points, aspect / (U.pixelsize * 1.1f));
BLF_size(fontid, fstyle_points, U.dpi);
@@ -1753,7 +1757,7 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar)
/* XXX hardcoded key warning */
if ((inside || inside_header) && event->val == KM_PRESS) {
- if (event->type == AKEY && !ELEM(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift, event->alt)) {
+ if (event->type == AKEY && ((event->ctrl + event->oskey + event->shift + event->alt) == 0)) {
if (pa->flag & PNL_CLOSEDY) {
if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my))
@@ -1768,7 +1772,7 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar)
}
/* on active button, do not handle panels */
- if (ui_button_is_active(ar))
+ if (ui_but_is_active(ar))
continue;
if (inside || inside_header) {
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 1574ceace8a..6e5f6af3c5f 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -27,8 +27,6 @@
* \ingroup edinterface
*/
-
-
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@@ -54,7 +52,6 @@
#include "WM_types.h"
#include "wm_draw.h"
#include "wm_subwindow.h"
-#include "wm_window.h"
#include "RNA_access.h"
@@ -109,11 +106,11 @@ static int rna_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRN
return value;
}
-int ui_step_name_menu(uiBut *but, int direction)
+int ui_but_menu_step(uiBut *but, int direction)
{
/* currenly only RNA buttons */
if ((but->rnaprop == NULL) || (RNA_property_type(but->rnaprop) != PROP_ENUM)) {
- printf("%s: cannot cycle button '%s'", __func__, but->str);
+ printf("%s: cannot cycle button '%s'\n", __func__, but->str);
return 0;
}
@@ -122,7 +119,7 @@ int ui_step_name_menu(uiBut *but, int direction)
/******************** Creating Temporary regions ******************/
-static ARegion *ui_add_temporary_region(bScreen *sc)
+static ARegion *ui_region_temp_add(bScreen *sc)
{
ARegion *ar;
@@ -135,7 +132,7 @@ static ARegion *ui_add_temporary_region(bScreen *sc)
return ar;
}
-static void ui_remove_temporary_region(bContext *C, bScreen *sc, ARegion *ar)
+static void ui_region_temp_remove(bContext *C, bScreen *sc, ARegion *ar)
{
wmWindow *win = CTX_wm_window(C);
if (win)
@@ -225,7 +222,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
wmOrtho2_region_ui(ar);
/* draw background */
- ui_draw_tooltip_background(UI_GetStyle(), NULL, &bbox);
+ ui_draw_tooltip_background(UI_style_get(), NULL, &bbox);
/* set background_color */
rgb_uchar_to_float(background_color, (const unsigned char *)theme->inner);
@@ -268,15 +265,15 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
fstyle_header.shadx = fstyle_header.shady = 0;
fstyle_header.shadowalpha = 1.0f;
- uiStyleFontSet(&fstyle_header);
+ UI_fontstyle_set(&fstyle_header);
glColor3fv(tip_colors[UI_TIP_LC_MAIN]);
- uiStyleFontDraw(&fstyle_header, &bbox, data->header);
+ UI_fontstyle_draw(&fstyle_header, &bbox, data->header);
xofs = BLF_width(fstyle_header.uifont_id, data->header, sizeof(data->header));
bbox.xmin += xofs;
glColor3fv(tip_colors[UI_TIP_LC_ACTIVE]);
- uiStyleFontDraw(&data->fstyle, &bbox, data->active_info);
+ UI_fontstyle_draw(&data->fstyle, &bbox, data->active_info);
bbox.xmin -= xofs;
}
@@ -284,18 +281,18 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
uiFontStyle fstyle_mono = data->fstyle;
fstyle_mono.uifont_id = blf_mono_font;
- uiStyleFontSet(&fstyle_mono);
+ UI_fontstyle_set(&fstyle_mono);
/* XXX, needed because we dont have mono in 'U.uifonts' */
BLF_size(fstyle_mono.uifont_id, fstyle_mono.points * U.pixelsize, U.dpi);
glColor3fv(tip_colors[data->format[i].color_id]);
- uiStyleFontDraw(&fstyle_mono, &bbox, data->lines[i]);
+ UI_fontstyle_draw(&fstyle_mono, &bbox, data->lines[i]);
}
else {
BLI_assert(data->format[i].style == UI_TIP_STYLE_NORMAL);
/* draw remaining data */
- uiStyleFontSet(&data->fstyle);
+ UI_fontstyle_set(&data->fstyle);
glColor3fv(tip_colors[data->format[i].color_id]);
- uiStyleFontDraw(&data->fstyle, &bbox, data->lines[i]);
+ UI_fontstyle_draw(&data->fstyle, &bbox, data->lines[i]);
}
if ((i + 1 != data->totline) && data->format[i + 1].is_pad) {
bbox.ymax -= data->lineh * UI_TIP_PAD_FAC;
@@ -324,7 +321,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
{
const float pad_px = UI_TIP_PADDING;
wmWindow *win = CTX_wm_window(C);
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
static ARegionType type;
ARegion *ar;
uiTooltipData *data;
@@ -351,7 +348,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* create tooltip data */
data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
- uiButGetStrInfo(C, but, &but_tip, &enum_label, &enum_tip, &op_keymap, &prop_keymap, &rna_struct, &rna_prop, NULL);
+ UI_but_string_info_get(C, but, &but_tip, &enum_label, &enum_tip, &op_keymap, &prop_keymap, &rna_struct, &rna_prop, NULL);
/* Tip */
if (but_tip.strinfo) {
@@ -364,8 +361,9 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
data->totline++;
/* special case enum rna buttons */
- if ((but->type & ROW) && but->rnaprop && RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG) {
- BLI_strncpy(data->lines[data->totline], IFACE_("(Shift-click to select multiple)"), sizeof(data->lines[0]));
+ if ((but->type & UI_BTYPE_ROW) && but->rnaprop && RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG) {
+ BLI_strncpy(data->lines[data->totline], IFACE_("(Shift-Click/Drag to select multiple)"),
+ sizeof(data->lines[0]));
data->format[data->totline].color_id = UI_TIP_LC_NORMAL;
data->totline++;
@@ -396,11 +394,11 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
data->totline++;
}
- if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
/* better not show the value of a password */
if ((but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) == 0) {
/* full string */
- ui_get_but_string(but, buf, sizeof(buf));
+ ui_but_string_get(but, buf, sizeof(buf));
if (buf[0]) {
BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Value: %s"), buf);
data->format[data->totline].is_pad = true;
@@ -411,7 +409,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
}
if (but->rnaprop) {
- int unit_type = uiButGetUnitType(but);
+ int unit_type = UI_but_unit_type_get(but);
if (unit_type == PROP_UNIT_ROTATION) {
if (RNA_property_type(but->rnaprop) == PROP_FLOAT) {
@@ -445,7 +443,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
else if (but->optype) {
PointerRNA *opptr;
char *str;
- opptr = uiButGetOperatorPtrRNA(but); /* allocated when needed, the button owns it */
+ opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */
/* so the context is passed to itemf functions (some py itemf functions use it) */
WM_operator_properties_sanitize(opptr, false);
@@ -556,7 +554,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
}
/* create area region */
- ar = ui_add_temporary_region(CTX_wm_screen(C));
+ ar = ui_region_temp_add(CTX_wm_screen(C));
memset(&type, 0, sizeof(ARegionType));
type.draw = ui_tooltip_region_draw_cb;
@@ -568,7 +566,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
data->fstyle = style->widget; /* copy struct */
ui_fontscale(&data->fstyle.points, aspect);
- uiStyleFontSet(&data->fstyle);
+ UI_fontstyle_set(&data->fstyle);
/* these defines tweaked depending on font */
#define TIP_BORDER_X (16.0f / aspect)
@@ -668,18 +666,18 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* widget rect, in region coords */
{
- int width = UI_ThemeMenuShadowWidth();
+ const int margin = UI_POPUP_MARGIN;
- data->bbox.xmin = width;
- data->bbox.xmax = BLI_rcti_size_x(&rect_i) - width;
- data->bbox.ymin = width;
+ data->bbox.xmin = margin;
+ data->bbox.xmax = BLI_rcti_size_x(&rect_i) - margin;
+ data->bbox.ymin = margin;
data->bbox.ymax = BLI_rcti_size_y(&rect_i);
/* region bigger for shadow */
- ar->winrct.xmin = rect_i.xmin - width;
- ar->winrct.xmax = rect_i.xmax + width;
- ar->winrct.ymin = rect_i.ymin - width;
- ar->winrct.ymax = rect_i.ymax + width;
+ ar->winrct.xmin = rect_i.xmin - margin;
+ ar->winrct.xmax = rect_i.xmax + margin;
+ ar->winrct.ymin = rect_i.ymin - margin;
+ ar->winrct.ymax = rect_i.ymax + margin;
}
/* adds subwindow */
@@ -693,7 +691,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
void ui_tooltip_free(bContext *C, ARegion *ar)
{
- ui_remove_temporary_region(C, CTX_wm_screen(C), ar);
+ ui_region_temp_remove(C, CTX_wm_screen(C), ar);
}
@@ -728,11 +726,11 @@ typedef struct uiSearchboxData {
/* exported for use by search callbacks */
/* returns zero if nothing to add */
-bool uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int iconid)
+bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid)
{
/* hijack for autocomplete */
if (items->autocpl) {
- autocomplete_do_name(items->autocpl, name);
+ UI_autocomplete_update_name(items->autocpl, name);
return true;
}
@@ -767,17 +765,17 @@ bool uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int ico
return true;
}
-int uiSearchBoxHeight(void)
+int UI_searchbox_size_y(void)
{
return SEARCH_ITEMS * UI_UNIT_Y + 2 * MENU_TOP;
}
-int uiSearchBoxWidth(void)
+int UI_searchbox_size_x(void)
{
return 12 * UI_UNIT_X;
}
-int uiSearchItemFindIndex(uiSearchItems *items, const char *name)
+int UI_search_items_find_index(uiSearchItems *items, const char *name)
{
int i;
for (i = 0; i < items->totitem; i++) {
@@ -817,7 +815,7 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
}
else {
/* only let users step into an 'unset' state for unlink buttons */
- data->active = (but->type == SEARCH_MENU_UNLINK) ? -1 : 0;
+ data->active = (but->type == UI_BTYPE_SEARCH_MENU_UNLINK) ? -1 : 0;
}
}
@@ -860,7 +858,7 @@ static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr
int ui_searchbox_find_index(ARegion *ar, const char *name)
{
uiSearchboxData *data = ar->regiondata;
- return uiSearchItemFindIndex(&data->items, name);
+ return UI_search_items_find_index(&data->items, name);
}
/* x and y in screencoords */
@@ -888,7 +886,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *ar)
return true;
}
- else if (but->type == SEARCH_MENU_UNLINK) {
+ else if (but->type == UI_BTYPE_SEARCH_MENU_UNLINK) {
/* It is valid for _UNLINK flavor to have no active element (it's a valid way to unlink). */
but->editstr[0] = '\0';
@@ -1014,11 +1012,11 @@ int ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
int match = AUTOCOMPLETE_NO_MATCH;
if (str[0]) {
- data->items.autocpl = autocomplete_begin(str, ui_get_but_string_max_length(but));
+ data->items.autocpl = UI_autocomplete_begin(str, ui_but_string_get_max_length(but));
but->search_func(C, but->search_arg, but->editstr, &data->items);
- match = autocomplete_end(data->items.autocpl, str);
+ match = UI_autocomplete_end(data->items.autocpl, str);
data->items.autocpl = NULL;
}
@@ -1118,7 +1116,7 @@ static void ui_searchbox_region_free_cb(ARegion *ar)
ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
{
wmWindow *win = CTX_wm_window(C);
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
static ARegionType type;
ARegion *ar;
uiSearchboxData *data;
@@ -1129,7 +1127,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
int i;
/* create area region */
- ar = ui_add_temporary_region(CTX_wm_screen(C));
+ ar = ui_region_temp_add(CTX_wm_screen(C));
memset(&type, 0, sizeof(ARegionType));
type.draw = ui_searchbox_region_draw_cb;
@@ -1144,7 +1142,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
data->fstyle = style->widget; /* copy struct */
data->fstyle.align = UI_STYLE_TEXT_CENTER;
ui_fontscale(&data->fstyle.points, aspect);
- uiStyleFontSet(&data->fstyle);
+ UI_fontstyle_set(&data->fstyle);
ar->regiondata = data;
@@ -1166,15 +1164,15 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
/* compute position */
if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
- int width = UI_ThemeMenuShadowWidth();
+ const int margin = UI_POPUP_MARGIN;
/* this case is search menu inside other menu */
/* we copy region size */
ar->winrct = butregion->winrct;
/* widget rect, in region coords */
- data->bbox.xmin = width;
- data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - width;
+ data->bbox.xmin = margin;
+ data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - margin;
/* Do not use shadow width for height, gives insane margin with big shadows, and issue T41548 with small ones */
data->bbox.ymin = 8 * UI_DPI_FAC;
data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - 8 * UI_DPI_FAC;
@@ -1188,13 +1186,13 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
}
}
else {
- const int searchbox_width = uiSearchBoxWidth();
- const int shadow_width = UI_ThemeMenuShadowWidth();
+ const int searchbox_width = UI_searchbox_size_x();
+ const int margin = UI_POPUP_MARGIN;
rect_fl.xmin = but->rect.xmin - 5; /* align text with button */
rect_fl.xmax = but->rect.xmax + 5; /* symmetrical */
rect_fl.ymax = but->rect.ymin;
- rect_fl.ymin = rect_fl.ymax - uiSearchBoxHeight();
+ rect_fl.ymin = rect_fl.ymax - UI_searchbox_size_y();
ofsx = (but->block->panel) ? but->block->panel->ofsx : 0;
ofsy = (but->block->panel) ? but->block->panel->ofsy : 0;
@@ -1244,15 +1242,15 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
}
/* widget rect, in region coords */
- data->bbox.xmin = shadow_width;
- data->bbox.xmax = BLI_rcti_size_x(&rect_i) + shadow_width;
- data->bbox.ymin = shadow_width;
- data->bbox.ymax = BLI_rcti_size_y(&rect_i) + shadow_width;
+ data->bbox.xmin = margin;
+ data->bbox.xmax = BLI_rcti_size_x(&rect_i) + margin;
+ data->bbox.ymin = margin;
+ data->bbox.ymax = BLI_rcti_size_y(&rect_i) + margin;
/* region bigger for shadow */
- ar->winrct.xmin = rect_i.xmin - shadow_width;
- ar->winrct.xmax = rect_i.xmax + shadow_width;
- ar->winrct.ymin = rect_i.ymin - shadow_width;
+ ar->winrct.xmin = rect_i.xmin - margin;
+ ar->winrct.xmax = rect_i.xmax + margin;
+ ar->winrct.ymin = rect_i.ymin - margin;
ar->winrct.ymax = rect_i.ymax;
}
@@ -1282,12 +1280,12 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
void ui_searchbox_free(bContext *C, ARegion *ar)
{
- ui_remove_temporary_region(C, CTX_wm_screen(C), ar);
+ ui_region_temp_remove(C, CTX_wm_screen(C), ar);
}
/* sets red alert if button holds a string it can't find */
/* XXX weak: search_func adds all partial matches... */
-void ui_but_search_test(uiBut *but)
+void ui_but_search_refresh(uiBut *but)
{
uiSearchItems *items;
int x1;
@@ -1311,11 +1309,11 @@ void ui_but_search_test(uiBut *but)
/* only redalert when we are sure of it, this can miss cases when >10 matches */
if (items->totitem == 0) {
- uiButSetFlag(but, UI_BUT_REDALERT);
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
}
else if (items->more == 0) {
- if (uiSearchItemFindIndex(items, but->drawstr) == -1) {
- uiButSetFlag(but, UI_BUT_REDALERT);
+ if (UI_search_items_find_index(items, but->drawstr) == -1) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
}
}
@@ -1343,7 +1341,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
ui_block_to_window_rctf(butregion, but->block, &butrct, &but->rect);
/* widget_roundbox_set has this correction too, keep in sync */
- if (but->type != PULLDOWN) {
+ if (but->type != UI_BTYPE_PULLDOWN) {
if (but->drawflag & UI_BUT_ALIGN_TOP)
butrct.ymax += U.pixelsize;
if (but->drawflag & UI_BUT_ALIGN_LEFT)
@@ -1377,7 +1375,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
/* aspect /= (float)xsize;*/ /*UNUSED*/
{
- int left = 0, right = 0, top = 0, down = 0;
+ bool left = 0, right = 0, top = 0, down = 0;
int winx, winy;
// int offscreen;
@@ -1385,8 +1383,12 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
winy = WM_window_pixels_y(window);
// wm_window_get_size(window, &winx, &winy);
- if (block->direction & UI_CENTER) center = ysize / 2;
- else center = 0;
+ if (block->direction & UI_DIR_CENTER_Y) {
+ center = ysize / 2;
+ }
+ else {
+ center = 0;
+ }
/* check if there's space at all */
if (butrct.xmin - xsize > 0.0f) left = 1;
@@ -1401,69 +1403,65 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
down = 1;
}
- dir1 = block->direction & UI_DIRECTION;
+ dir1 = (block->direction & UI_DIR_ALL);
/* secundary directions */
- if (dir1 & (UI_TOP | UI_DOWN)) {
- if (dir1 & UI_LEFT) dir2 = UI_LEFT;
- else if (dir1 & UI_RIGHT) dir2 = UI_RIGHT;
- dir1 &= (UI_TOP | UI_DOWN);
+ if (dir1 & (UI_DIR_UP | UI_DIR_DOWN)) {
+ if (dir1 & UI_DIR_LEFT) dir2 = UI_DIR_LEFT;
+ else if (dir1 & UI_DIR_RIGHT) dir2 = UI_DIR_RIGHT;
+ dir1 &= (UI_DIR_UP | UI_DIR_DOWN);
}
- if ((dir2 == 0) && (dir1 == UI_LEFT || dir1 == UI_RIGHT)) dir2 = UI_DOWN;
- if ((dir2 == 0) && (dir1 == UI_TOP || dir1 == UI_DOWN)) dir2 = UI_LEFT;
+ if ((dir2 == 0) && (dir1 == UI_DIR_LEFT || dir1 == UI_DIR_RIGHT)) dir2 = UI_DIR_DOWN;
+ if ((dir2 == 0) && (dir1 == UI_DIR_UP || dir1 == UI_DIR_DOWN)) dir2 = UI_DIR_LEFT;
/* no space at all? don't change */
if (left || right) {
- if (dir1 == UI_LEFT && left == 0) dir1 = UI_RIGHT;
- if (dir1 == UI_RIGHT && right == 0) dir1 = UI_LEFT;
+ if (dir1 == UI_DIR_LEFT && left == 0) dir1 = UI_DIR_RIGHT;
+ if (dir1 == UI_DIR_RIGHT && right == 0) dir1 = UI_DIR_LEFT;
/* this is aligning, not append! */
- if (dir2 == UI_LEFT && right == 0) dir2 = UI_RIGHT;
- if (dir2 == UI_RIGHT && left == 0) dir2 = UI_LEFT;
+ if (dir2 == UI_DIR_LEFT && right == 0) dir2 = UI_DIR_RIGHT;
+ if (dir2 == UI_DIR_RIGHT && left == 0) dir2 = UI_DIR_LEFT;
}
if (down || top) {
- if (dir1 == UI_TOP && top == 0) dir1 = UI_DOWN;
- if (dir1 == UI_DOWN && down == 0) dir1 = UI_TOP;
- if (dir2 == UI_TOP && top == 0) dir2 = UI_DOWN;
- if (dir2 == UI_DOWN && down == 0) dir2 = UI_TOP;
+ if (dir1 == UI_DIR_UP && top == 0) dir1 = UI_DIR_DOWN;
+ if (dir1 == UI_DIR_DOWN && down == 0) dir1 = UI_DIR_UP;
+ if (dir2 == UI_DIR_UP && top == 0) dir2 = UI_DIR_DOWN;
+ if (dir2 == UI_DIR_DOWN && down == 0) dir2 = UI_DIR_UP;
}
- if (dir1 == UI_LEFT) {
+ if (dir1 == UI_DIR_LEFT) {
xof = butrct.xmin - block->rect.xmax;
- if (dir2 == UI_TOP) yof = butrct.ymin - block->rect.ymin - center - MENU_PADDING;
- else yof = butrct.ymax - block->rect.ymax + center + MENU_PADDING;
+ if (dir2 == UI_DIR_UP) yof = butrct.ymin - block->rect.ymin - center - MENU_PADDING;
+ else yof = butrct.ymax - block->rect.ymax + center + MENU_PADDING;
}
- else if (dir1 == UI_RIGHT) {
+ else if (dir1 == UI_DIR_RIGHT) {
xof = butrct.xmax - block->rect.xmin;
- if (dir2 == UI_TOP) yof = butrct.ymin - block->rect.ymin - center - MENU_PADDING;
- else yof = butrct.ymax - block->rect.ymax + center + MENU_PADDING;
+ if (dir2 == UI_DIR_UP) yof = butrct.ymin - block->rect.ymin - center - MENU_PADDING;
+ else yof = butrct.ymax - block->rect.ymax + center + MENU_PADDING;
}
- else if (dir1 == UI_TOP) {
+ else if (dir1 == UI_DIR_UP) {
yof = butrct.ymax - block->rect.ymin;
- if (dir2 == UI_RIGHT) xof = butrct.xmax - block->rect.xmax;
- else xof = butrct.xmin - block->rect.xmin;
+ if (dir2 == UI_DIR_RIGHT) xof = butrct.xmax - block->rect.xmax;
+ else xof = butrct.xmin - block->rect.xmin;
/* changed direction? */
if ((dir1 & block->direction) == 0) {
- if (block->direction & UI_SHIFT_FLIPPED)
- xof += dir2 == UI_LEFT ? 25 : -25;
- uiBlockFlipOrder(block);
+ UI_block_order_flip(block);
}
}
- else if (dir1 == UI_DOWN) {
+ else if (dir1 == UI_DIR_DOWN) {
yof = butrct.ymin - block->rect.ymax;
- if (dir2 == UI_RIGHT) xof = butrct.xmax - block->rect.xmax;
- else xof = butrct.xmin - block->rect.xmin;
+ if (dir2 == UI_DIR_RIGHT) xof = butrct.xmax - block->rect.xmax;
+ else xof = butrct.xmin - block->rect.xmin;
/* changed direction? */
if ((dir1 & block->direction) == 0) {
- if (block->direction & UI_SHIFT_FLIPPED)
- xof += dir2 == UI_LEFT ? 25 : -25;
- uiBlockFlipOrder(block);
+ UI_block_order_flip(block);
}
}
/* and now we handle the exception; no space below or to top */
if (top == 0 && down == 0) {
- if (dir1 == UI_LEFT || dir1 == UI_RIGHT) {
+ if (dir1 == UI_DIR_LEFT || dir1 == UI_DIR_RIGHT) {
/* align with bottom of screen */
// yof = ysize; (not with menu scrolls)
}
@@ -1471,7 +1469,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
/* or no space left or right */
if (left == 0 && right == 0) {
- if (dir1 == UI_TOP || dir1 == UI_DOWN) {
+ if (dir1 == UI_DIR_UP || dir1 == UI_DIR_DOWN) {
/* align with left size of screen */
xof = -block->rect.xmin + 5;
}
@@ -1493,8 +1491,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
BLI_rctf_translate(&bt->rect, xof, yof);
- /* ui_check_but recalculates drawstring size in pixels */
- ui_check_but(bt);
+ /* ui_but_update recalculates drawstring size in pixels */
+ ui_but_update(bt);
}
BLI_rctf_translate(&block->rect, xof, yof);
@@ -1522,8 +1520,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
/* exception for switched pulldowns... */
if (dir1 && (dir1 & block->direction) == 0) {
- if (dir2 == UI_RIGHT) block->safety.xmax = block->rect.xmax + 3;
- if (dir2 == UI_LEFT) block->safety.xmin = block->rect.xmin - 3;
+ if (dir2 == UI_DIR_RIGHT) block->safety.xmax = block->rect.xmax + 3;
+ if (dir2 == UI_DIR_LEFT) block->safety.xmin = block->rect.xmin - 3;
}
block->direction = dir1;
}
@@ -1551,7 +1549,7 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
}
for (block = ar->uiblocks.first; block; block = block->next)
- uiDrawBlock(C, block);
+ UI_block_draw(C, block);
}
static void ui_popup_block_clip(wmWindow *window, uiBlock *block)
@@ -1633,7 +1631,7 @@ void ui_popup_block_scrolltest(uiBlock *block)
static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle)
{
- ui_remove_temporary_region(C, CTX_wm_screen(C), handle->region);
+ ui_region_temp_remove(C, CTX_wm_screen(C), handle->region);
if (handle->scrolltimer)
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), handle->scrolltimer);
@@ -1646,7 +1644,7 @@ uiBlock *ui_popup_block_refresh(
bContext *C, uiPopupBlockHandle *handle,
ARegion *butregion, uiBut *but)
{
- const int width = UI_ThemeMenuShadowWidth();
+ const int margin = UI_POPUP_MARGIN;
wmWindow *window = CTX_wm_window(C);
ARegion *ar = handle->region;
@@ -1667,7 +1665,7 @@ uiBlock *ui_popup_block_refresh(
else
block = handle_create_func(C, handle, arg);
- /* callbacks _must_ leave this for us, otherwise we can't call uiBlockUpdateFromOld */
+ /* callbacks _must_ leave this for us, otherwise we can't call UI_block_update_from_old */
BLI_assert(!block->endblock);
/* ensure we don't use mouse coords here! */
@@ -1685,9 +1683,9 @@ uiBlock *ui_popup_block_refresh(
ar->regiondata = handle;
- /* set UI_BLOCK_NUMSELECT before uiEndBlock() so we get alphanumeric keys assigned */
+ /* set UI_BLOCK_NUMSELECT before UI_block_end() so we get alphanumeric keys assigned */
if (but) {
- if (but->type == PULLDOWN) {
+ if (but->type == UI_BTYPE_PULLDOWN) {
block->flag |= UI_BLOCK_NUMSELECT;
}
}
@@ -1701,7 +1699,7 @@ uiBlock *ui_popup_block_refresh(
block->oldblock = NULL;
if (!block->endblock)
- uiEndBlock_ex(C, block, handle->popup_create_vars.event_xy);
+ UI_block_end_ex(C, block, handle->popup_create_vars.event_xy);
/* if this is being created from a button */
if (but) {
@@ -1756,7 +1754,7 @@ uiBlock *ui_popup_block_refresh(
ar->winrct.ymin = 0;
ar->winrct.ymax = winy;
- ui_block_calculate_pie_segment(block, block->pie_data.pie_center_init);
+ ui_block_calc_pie_segment(block, block->pie_data.pie_center_init);
/* lastly set the buttons at the center of the pie menu, ready for animation */
if (U.pie_animation_timeout > 0) {
@@ -1773,9 +1771,9 @@ uiBlock *ui_popup_block_refresh(
/* the block and buttons were positioned in window space as in 2.4x, now
* these menu blocks are regions so we bring it back to region space.
* additionally we add some padding for the menu shadow or rounded menus */
- ar->winrct.xmin = block->rect.xmin - width;
- ar->winrct.xmax = block->rect.xmax + width;
- ar->winrct.ymin = block->rect.ymin - width;
+ ar->winrct.xmin = block->rect.xmin - margin;
+ ar->winrct.xmax = block->rect.xmax + margin;
+ ar->winrct.ymin = block->rect.ymin - margin;
ar->winrct.ymax = block->rect.ymax + MENU_TOP;
ui_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin);
@@ -1783,8 +1781,8 @@ uiBlock *ui_popup_block_refresh(
if (block_old) {
block->oldblock = block_old;
- uiBlockUpdateFromOld(C, block);
- uiFreeInactiveBlocks(C, &ar->uiblocks);
+ UI_block_update_from_old(C, block);
+ UI_blocklist_free_inactive(C, &ar->uiblocks);
}
/* checks which buttons are visible, sets flags to prevent draw (do after region init) */
@@ -1835,7 +1833,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
copy_v2_v2_int(handle->popup_create_vars.event_xy, &window->eventstate->x);
/* create area region */
- ar = ui_add_temporary_region(CTX_wm_screen(C));
+ ar = ui_region_temp_add(CTX_wm_screen(C));
handle->region = ar;
memset(&type, 0, sizeof(ARegionType));
@@ -1843,7 +1841,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
type.regionid = RGN_TYPE_TEMPORARY;
ar->type = &type;
- UI_add_region_handlers(&ar->handlers);
+ UI_region_handlers_add(&ar->handlers);
block = ui_popup_block_refresh(C, handle, butregion, but);
handle = block->handle;
@@ -1875,21 +1873,23 @@ static void ui_warp_pointer(int x, int y)
/********************* Color Button ****************/
/* for picker, while editing hsv */
-void ui_set_but_hsv(uiBut *but)
+void ui_but_hsv_set(uiBut *but)
{
float col[3];
- const float *hsv = ui_block_hsv_get(but->block);
-
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+
ui_color_picker_to_rgb_v(hsv, col);
- ui_set_but_vectorf(but, col);
+ ui_but_v3_set(but, col);
}
-/* also used by small picker, be careful with name checks below... */
-static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3], bool is_display_space)
+/* Updates all buttons who share the same color picker as the one passed
+ * also used by small picker, be careful with name checks below... */
+static void ui_update_color_picker_buts_rgb(uiBlock *block, ColorPicker *cpicker, const float rgb[3], bool is_display_space)
{
uiBut *bt;
- float *hsv = ui_block_hsv_get(block);
+ float *hsv = cpicker->color_data;
struct ColorManagedDisplay *display = NULL;
/* this is to keep the H and S value when V is equal to zero
* and we are working in HSV mode, of course!
@@ -1902,21 +1902,24 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3], bool is
float rgb_display[3];
copy_v3_v3(rgb_display, rgb);
- ui_block_to_display_space_v3(block, rgb_display);
+ ui_block_cm_to_display_space_v3(block, rgb_display);
ui_rgb_to_color_picker_compat_v(rgb_display, hsv);
}
if (block->color_profile)
- display = ui_block_display_get(block);
+ display = ui_block_cm_display_get(block);
/* 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 (bt->custom_data != cpicker)
+ continue;
+
if (bt->rnaprop) {
- ui_set_but_vectorf(bt, rgb);
+ ui_but_v3_set(bt, rgb);
}
- else if (strcmp(bt->str, "Hex: ") == 0) {
+ else if (STREQ(bt->str, "Hex: ")) {
float rgb_gamma[3];
unsigned char rgb_gamma_uchar[3];
double intpart;
@@ -1942,33 +1945,33 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3], bool is
}
else if (bt->str[1] == ' ') {
if (bt->str[0] == 'R') {
- ui_set_but_val(bt, rgb[0]);
+ ui_but_value_set(bt, rgb[0]);
}
else if (bt->str[0] == 'G') {
- ui_set_but_val(bt, rgb[1]);
+ ui_but_value_set(bt, rgb[1]);
}
else if (bt->str[0] == 'B') {
- ui_set_but_val(bt, rgb[2]);
+ ui_but_value_set(bt, rgb[2]);
}
else if (bt->str[0] == 'H') {
- ui_set_but_val(bt, hsv[0]);
+ ui_but_value_set(bt, hsv[0]);
}
else if (bt->str[0] == 'S') {
- ui_set_but_val(bt, hsv[1]);
+ ui_but_value_set(bt, hsv[1]);
}
else if (bt->str[0] == 'V') {
- ui_set_but_val(bt, hsv[2]);
+ ui_but_value_set(bt, hsv[2]);
}
else if (bt->str[0] == 'L') {
- ui_set_but_val(bt, hsv[2]);
+ ui_but_value_set(bt, hsv[2]);
}
}
- ui_check_but(bt);
+ ui_but_update(bt);
}
}
-static void do_picker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
+static void ui_colorpicker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
@@ -1978,38 +1981,40 @@ static void do_picker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
if (prop) {
RNA_property_float_get_array(&ptr, prop, rgb);
- ui_update_block_buts_rgb(but->block, rgb, (RNA_property_subtype(prop) == PROP_COLOR_GAMMA));
+ ui_update_color_picker_buts_rgb(but->block, but->custom_data, rgb, (RNA_property_subtype(prop) == PROP_COLOR_GAMMA));
}
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
}
-static void do_color_wheel_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
+static void ui_color_wheel_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
float rgb[3];
- const float *hsv = ui_block_hsv_get(but->block);
- bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+ bool use_display_colorspace = ui_but_is_colorpicker_display_space(but);
ui_color_picker_to_rgb_v(hsv, rgb);
/* hsv is saved in display space so convert back */
if (use_display_colorspace) {
- ui_block_to_scene_linear_v3(but->block, rgb);
+ ui_block_cm_to_scene_linear_v3(but->block, rgb);
}
- ui_update_block_buts_rgb(but->block, rgb, !use_display_colorspace);
+ ui_update_color_picker_buts_rgb(but->block, cpicker, rgb, !use_display_colorspace);
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
}
-static void do_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl)
+static void ui_colorpicker_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl)
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
+ ColorPicker *cpicker = but->custom_data;
char *hexcol = (char *)hexcl;
float rgb[3];
@@ -2018,16 +2023,16 @@ static void do_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl)
/* Hex code is assumed to be in sRGB space (coming from other applications, web, etc) */
if (but->block->color_profile) {
/* so we need to linearise it for Blender */
- ui_block_to_scene_linear_v3(but->block, rgb);
+ ui_block_cm_to_scene_linear_v3(but->block, rgb);
}
- ui_update_block_buts_rgb(but->block, rgb, false);
+ ui_update_color_picker_buts_rgb(but->block, cpicker, rgb, false);
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
}
-static void close_popup_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
+static void ui_popup_close_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
@@ -2036,23 +2041,23 @@ static void close_popup_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
popup->menuretval = UI_RETURN_OK;
}
-static void picker_new_hide_reveal(uiBlock *block, short colormode)
+static void ui_colorpicker_hide_reveal(uiBlock *block, short colormode)
{
uiBut *bt;
/* tag buttons */
for (bt = block->buttons.first; bt; bt = bt->next) {
- if ((bt->func == do_picker_rna_cb) && bt->type == NUMSLI && bt->rnaindex != 3) {
+ if ((bt->func == ui_colorpicker_rna_cb) && bt->type == UI_BTYPE_NUM_SLIDER && bt->rnaindex != 3) {
/* RGB sliders (color circle and alpha are always shown) */
if (colormode == 0) bt->flag &= ~UI_HIDDEN;
else bt->flag |= UI_HIDDEN;
}
- else if (bt->func == do_color_wheel_rna_cb) {
+ else if (bt->func == ui_color_wheel_rna_cb) {
/* HSV sliders */
if (colormode == 1) bt->flag &= ~UI_HIDDEN;
else bt->flag |= UI_HIDDEN;
}
- else if (bt->func == do_hex_rna_cb || bt->type == LABEL) {
+ else if (bt->func == ui_colorpicker_hex_rna_cb || bt->type == UI_BTYPE_LABEL) {
/* hex input or gamma correction status label */
if (colormode == 2) bt->flag &= ~UI_HIDDEN;
else bt->flag |= UI_HIDDEN;
@@ -2060,11 +2065,11 @@ static void picker_new_hide_reveal(uiBlock *block, short colormode)
}
}
-static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
+static void ui_colorpicker_create_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
uiBut *bt = bt1;
- short colormode = ui_get_but_val(bt);
- picker_new_hide_reveal(bt->block, colormode);
+ short colormode = ui_but_value_get(bt);
+ ui_colorpicker_hide_reveal(bt->block, colormode);
}
#define PICKER_H (7.5f * U.widget_unit)
@@ -2074,43 +2079,47 @@ static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a
#define PICKER_TOTAL_W (PICKER_W + PICKER_SPACE + PICKER_BAR)
-static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop)
+static void ui_colorpicker_circle(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, ColorPicker *cpicker)
{
uiBut *bt;
/* HS circle */
- bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0.0, 0, TIP_("Color"));
- uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ bt = uiDefButR_prop(block, UI_BTYPE_HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0.0, 0, TIP_("Color"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
/* value */
if (U.color_picker_type == USER_CP_CIRCLE_HSL) {
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_L_ALT, 0, "Lightness");
- uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ bt = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_L_ALT, 0, "Lightness");
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
}
else {
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, TIP_("Value"));
- uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ bt = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, TIP_("Value"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
}
+ bt->custom_data = cpicker;
}
-static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type)
+static void ui_colorpicker_square(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type, ColorPicker *cpicker)
{
uiBut *bt;
int bartype = type + 3;
/* HS square */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, -1, 0.0, 0.0, type, 0, TIP_("Color"));
- uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ bt = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, -1, 0.0, 0.0, type, 0, TIP_("Color"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
/* value */
- bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, -1, 0.0, 0.0, bartype, 0, TIP_("Value"));
- uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ bt = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, -1, 0.0, 0.0, bartype, 0, TIP_("Value"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
}
/* a HS circle, V slider, rgb/hsv/hex sliders */
-static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, PropertyRNA *prop, bool show_picker)
+static void ui_block_colorpicker(uiBlock *block, float rgba[4], PointerRNA *ptr, PropertyRNA *prop, bool show_picker)
{
static short colormode = 0; /* temp? 0=rgb, 1=hsv, 2=hex */
uiBut *bt;
@@ -2120,8 +2129,9 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
float rgb_gamma[3];
unsigned char rgb_gamma_uchar[3];
float softmin, softmax, hardmin, hardmax, step, precision;
- float *hsv = ui_block_hsv_get(block);
int yco;
+ ColorPicker *cpicker = ui_block_colorpicker_create(block);
+ float *hsv = cpicker->color_data;
width = PICKER_TOTAL_W;
butwidth = width - 1.5f * UI_UNIT_X;
@@ -2137,7 +2147,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
/* make a display version, for Hex code */
copy_v3_v3(rgb_gamma, rgba);
- ui_block_to_display_space_v3(block, rgb_gamma);
+ ui_block_cm_to_display_space_v3(block, rgb_gamma);
}
/* sneaky way to check for alpha */
@@ -2149,75 +2159,86 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
switch (U.color_picker_type) {
case USER_CP_SQUARE_SV:
- square_picker(block, ptr, prop, UI_GRAD_SV);
+ ui_colorpicker_square(block, ptr, prop, UI_GRAD_SV, cpicker);
break;
case USER_CP_SQUARE_HS:
- square_picker(block, ptr, prop, UI_GRAD_HS);
+ ui_colorpicker_square(block, ptr, prop, UI_GRAD_HS, cpicker);
break;
case USER_CP_SQUARE_HV:
- square_picker(block, ptr, prop, UI_GRAD_HV);
+ ui_colorpicker_square(block, ptr, prop, UI_GRAD_HV, cpicker);
break;
/* user default */
case USER_CP_CIRCLE_HSV:
case USER_CP_CIRCLE_HSL:
default:
- circle_picker(block, ptr, prop);
+ ui_colorpicker_circle(block, ptr, prop, cpicker);
break;
}
/* mode */
yco = -1.5f * UI_UNIT_Y;
- uiBlockBeginAlign(block);
- bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
- uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
+ UI_block_align_begin(block);
+ bt = uiDefButS(block, UI_BTYPE_ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
+ UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
+ bt->custom_data = cpicker;
if (U.color_picker_type == USER_CP_CIRCLE_HSL)
- bt = uiDefButS(block, ROW, 0, IFACE_("HSL"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
+ bt = uiDefButS(block, UI_BTYPE_ROW, 0, IFACE_("HSL"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
else
- bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
- uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
- bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
- uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL);
- uiBlockEndAlign(block);
+ bt = uiDefButS(block, UI_BTYPE_ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
+ UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ bt = uiDefButS(block, UI_BTYPE_ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
+ UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ UI_block_align_end(block);
yco = -3.0f * UI_UNIT_Y;
if (show_picker) {
- bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL);
- uiButSetFunc(bt, close_popup_cb, bt, NULL);
+ bt = uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL);
+ UI_but_func_set(bt, ui_popup_close_cb, bt, NULL);
+ bt->custom_data = cpicker;
}
/* RGB values */
- uiBlockBeginAlign(block);
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R:"), 0, yco, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red"));
- uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green"));
- uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue"));
- uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ UI_block_align_begin(block);
+ bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("R:"), 0, yco, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("G:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("B:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
/* could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE);
- * but need to use uiButSetFunc for updating other fake buttons */
+ * but need to use UI_but_func_set for updating other fake buttons */
/* HSV values */
yco = -3.0f * UI_UNIT_Y;
- uiBlockBeginAlign(block);
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("H:"), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue"));
- uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv);
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("S:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
- uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv);
+ UI_block_align_begin(block);
+ bt = uiDefButF(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("H:"), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue"));
+ UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv);
+ bt->custom_data = cpicker;
+ bt = uiDefButF(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("S:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
+ UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv);
+ bt->custom_data = cpicker;
if (U.color_picker_type == USER_CP_CIRCLE_HSL)
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("L:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, 1.0, 10, 3, TIP_("Lightness"));
+ bt = uiDefButF(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("L:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, 1.0, 10, 3, TIP_("Lightness"));
else
- bt = uiDefButF(block, NUMSLI, 0, IFACE_("V:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value"));
+ bt = uiDefButF(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("V:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value"));
bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */
- uiButSetFunc(bt, do_color_wheel_rna_cb, bt, hsv);
+ UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv);
+ bt->custom_data = cpicker;
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
if (rgba[3] != FLT_MAX) {
- bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A: "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 3, TIP_("Alpha"));
- uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+ bt = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("A: "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 3, TIP_("Alpha"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
}
else {
rgba[3] = 1.0f;
@@ -2227,17 +2248,18 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper
BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", UNPACK3_EX((unsigned int), rgb_gamma_uchar, ));
yco = -3.0f * UI_UNIT_Y;
- bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)"));
- uiButSetFunc(bt, do_hex_rna_cb, bt, hexcol);
- uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ bt = uiDefBut(block, UI_BTYPE_TEXT, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)"));
+ UI_but_func_set(bt, ui_colorpicker_hex_rna_cb, bt, hexcol);
+ bt->custom_data = cpicker;
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
ui_rgb_to_color_picker_v(rgb_gamma, hsv);
- picker_new_hide_reveal(block, colormode);
+ ui_colorpicker_hide_reveal(block, colormode);
}
-static int ui_picker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, const wmEvent *event)
+static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, const wmEvent *event)
{
float add = 0.0f;
@@ -2250,16 +2272,17 @@ static int ui_picker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, c
uiBut *but;
for (but = block->buttons.first; but; but = but->next) {
- if (but->type == HSVCUBE && but->active == NULL) {
+ if (but->type == UI_BTYPE_HSVCUBE && but->active == NULL) {
uiPopupBlockHandle *popup = block->handle;
float rgb[3];
- float *hsv = ui_block_hsv_get(block);
- bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+ bool use_display_colorspace = ui_but_is_colorpicker_display_space(but);
- ui_get_but_vectorf(but, rgb);
+ ui_but_v3_get(but, rgb);
if (use_display_colorspace)
- ui_block_to_display_space_v3(block, rgb);
+ ui_block_cm_to_display_space_v3(block, rgb);
ui_rgb_to_color_picker_compat_v(rgb, hsv);
@@ -2267,11 +2290,11 @@ static int ui_picker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, c
ui_color_picker_to_rgb_v(hsv, rgb);
if (use_display_colorspace)
- ui_block_to_scene_linear_v3(block, rgb);
+ ui_block_cm_to_scene_linear_v3(block, rgb);
- ui_set_but_vectorf(but, rgb);
+ ui_but_v3_set(but, rgb);
- ui_update_block_buts_rgb(block, rgb, !use_display_colorspace);
+ ui_update_color_picker_buts_rgb(block, cpicker, rgb, !use_display_colorspace);
if (popup)
popup->menuretval = UI_RETURN_UPDATE;
@@ -2288,7 +2311,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_
uiBlock *block;
bool show_picker = true;
- block = uiBeginBlock(C, handle->region, __func__, UI_EMBOSS);
+ block = UI_block_begin(C, handle->region, __func__, UI_EMBOSS);
if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
block->color_profile = false;
@@ -2304,15 +2327,15 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_
copy_v3_v3(handle->retvec, but->editvec);
- uiBlockPicker(block, handle->retvec, &but->rnapoin, but->rnaprop, show_picker);
+ ui_block_colorpicker(block, handle->retvec, &but->rnapoin, but->rnaprop, show_picker);
- block->flag = UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT;
- uiBoundsBlock(block, 0.5 * UI_UNIT_X);
+ block->flag = UI_BLOCK_LOOP | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT;
+ UI_block_bounds_set_normal(block, 0.5 * UI_UNIT_X);
- block->block_event_func = ui_picker_small_wheel_cb;
+ block->block_event_func = ui_colorpicker_small_wheel_cb;
/* and lets go */
- block->direction = UI_TOP;
+ block->direction = UI_DIR_UP;
return block;
}
@@ -2448,39 +2471,39 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
/* allow overriding the direction from menu_func */
direction = pup->block->direction;
}
- else if ((pup->but->type == PULLDOWN) ||
- (uiButGetMenuType(pup->but) != NULL))
+ else if ((pup->but->type == UI_BTYPE_PULLDOWN) ||
+ (UI_but_menutype_get(pup->but) != NULL))
{
- direction = UI_DOWN;
+ direction = UI_DIR_DOWN;
}
else {
- direction = UI_TOP;
+ direction = UI_DIR_UP;
}
}
else {
minwidth = 50;
- direction = UI_DOWN;
+ direction = UI_DIR_DOWN;
}
- flip = (direction == UI_DOWN);
+ flip = (direction == UI_DIR_DOWN);
block = pup->block;
/* in some cases we create the block before the region,
* so we set it delayed here if necessary */
if (BLI_findindex(&handle->region->uiblocks, block) == -1)
- uiBlockSetRegion(block, handle->region);
+ UI_block_region_set(block, handle->region);
block->direction = direction;
- uiBlockLayoutResolve(block, &width, &height);
+ UI_block_layout_resolve(block, &width, &height);
- uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
+ UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
if (pup->popup) {
uiBut *but_activate = NULL;
- uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_NUMSELECT);
- uiBlockSetDirection(block, direction);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT);
+ UI_block_direction_set(block, direction);
/* offset the mouse position, possibly based on earlier selection */
if ((block->flag & UI_BLOCK_POPUP_MEMORY) &&
@@ -2518,11 +2541,11 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
* to be within the window bounds may move it away from the mouse,
* This ensures we set an item to be active. */
if (but_activate) {
- ui_button_activate_over(C, handle->region, but_activate);
+ ui_but_activate_over(C, handle->region, but_activate);
}
block->minbounds = minwidth;
- uiMenuPopupBoundsBlock(block, 1, offset[0], offset[1]);
+ UI_block_bounds_set_menu(block, 1, offset[0], offset[1]);
}
else {
/* for a header menu we set the direction automatic */
@@ -2531,19 +2554,19 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
if (sa && sa->headertype == HEADERDOWN) {
ARegion *ar = CTX_wm_region(C);
if (ar && ar->regiontype == RGN_TYPE_HEADER) {
- uiBlockSetDirection(block, UI_TOP);
- uiBlockFlipOrder(block);
+ UI_block_direction_set(block, UI_DIR_UP);
+ UI_block_order_flip(block);
}
}
}
block->minbounds = minwidth;
- uiTextBoundsBlock(block, 3.0f * UI_UNIT_X);
+ UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
}
/* if menu slides out of other menu, override direction */
if (pup->slideout)
- uiBlockSetDirection(block, UI_RIGHT);
+ UI_block_direction_set(block, UI_DIR_RIGHT);
return pup->block;
}
@@ -2552,14 +2575,14 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut
uiMenuCreateFunc menu_func, void *arg)
{
wmWindow *window = CTX_wm_window(C);
- uiStyle *style = UI_GetStyleDraw();
+ uiStyle *style = UI_style_get_dpi();
uiPopupBlockHandle *handle;
uiPopupMenu *pup;
pup = MEM_callocN(sizeof(uiPopupMenu), __func__);
- pup->block = uiBeginBlock(C, NULL, __func__, UI_EMBOSSP);
+ pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS_PULLDOWN);
pup->block->flag |= UI_BLOCK_NUMSELECT; /* default menus to numselect */
- pup->layout = uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, MENU_PADDING, style);
+ pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, MENU_PADDING, style);
pup->slideout = but ? ui_block_is_menu(but->block) : false;
pup->but = but;
uiLayoutSetOperatorContext(pup->layout, WM_OP_INVOKE_REGION_WIN);
@@ -2596,7 +2619,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut
if (!but) {
handle->popup = true;
- UI_add_popup_handlers(C, &window->modalhandlers, handle, false);
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, false);
WM_event_add_mousemove(C);
}
@@ -2608,16 +2631,16 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut
/******************** Popup Menu API with begin and end ***********************/
/* only return handler, and set optional title */
-uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon)
+uiPopupMenu *UI_popup_menu_begin(bContext *C, const char *title, int icon)
{
- uiStyle *style = UI_GetStyleDraw();
+ uiStyle *style = UI_style_get_dpi();
uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu");
uiBut *but;
- pup->block = uiBeginBlock(C, NULL, __func__, UI_EMBOSSP);
- pup->block->flag |= UI_BLOCK_POPUP_MEMORY;
+ pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS_PULLDOWN);
+ pup->block->flag |= UI_BLOCK_POPUP_MEMORY | UI_BLOCK_IS_FLIP;
pup->block->puphash = ui_popup_menu_hash(title);
- pup->layout = uiBlockLayout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, MENU_PADDING, style);
+ pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, MENU_PADDING, style);
/* note, this intentionally differs from the menu & submenu default because many operators
* use popups like this to select one of their options - where having invoke doesn't make sense */
@@ -2632,10 +2655,10 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon)
if (icon) {
BLI_snprintf(titlestr, sizeof(titlestr), " %s", title);
- uiDefIconTextBut(pup->block, LABEL, 0, icon, titlestr, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(pup->block, UI_BTYPE_LABEL, 0, icon, titlestr, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
else {
- but = uiDefBut(pup->block, LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but = uiDefBut(pup->block, UI_BTYPE_LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
but->drawflag = UI_BUT_TEXT_LEFT;
}
@@ -2646,7 +2669,7 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon)
}
/* set the whole structure to work */
-void uiPupMenuEnd(bContext *C, uiPopupMenu *pup)
+void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *menu;
@@ -2658,13 +2681,13 @@ void uiPupMenuEnd(bContext *C, uiPopupMenu *pup)
menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPUP, pup);
menu->popup = true;
- UI_add_popup_handlers(C, &window->modalhandlers, menu, false);
+ UI_popup_handlers_add(C, &window->modalhandlers, menu, false);
WM_event_add_mousemove(C);
MEM_freeN(pup);
}
-uiLayout *uiPupMenuLayout(uiPopupMenu *pup)
+uiLayout *UI_popup_menu_layout(uiPopupMenu *pup)
{
return pup->layout;
}
@@ -2683,11 +2706,11 @@ static uiBlock *ui_block_func_PIE(bContext *UNUSED(C), uiPopupBlockHandle *handl
/* in some cases we create the block before the region,
* so we set it delayed here if necessary */
if (BLI_findindex(&handle->region->uiblocks, block) == -1)
- uiBlockSetRegion(block, handle->region);
+ UI_block_region_set(block, handle->region);
- uiBlockLayoutResolve(block, &width, &height);
+ UI_block_layout_resolve(block, &width, &height);
- uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_NUMSELECT);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT);
block->minbounds = minwidth;
block->bounds = 1;
@@ -2701,13 +2724,14 @@ static uiBlock *ui_block_func_PIE(bContext *UNUSED(C), uiPopupBlockHandle *handl
return pie->block_radial;
}
-static float uiPieTitleWidth(const char *name, int icon)
+static float ui_pie_menu_title_width(const char *name, int icon)
{
- return (UI_GetStringWidth(name) +
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ return (UI_fontstyle_string_width(fstyle, name) +
(UI_UNIT_X * (1.50f + (icon ? 0.25f : 0.0f))));
}
-uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const wmEvent *event)
+uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, const wmEvent *event)
{
uiStyle *style;
uiPieMenu *pie;
@@ -2715,10 +2739,10 @@ uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const
wmWindow *win = CTX_wm_window(C);
- style = UI_GetStyleDraw();
+ style = UI_style_get_dpi();
pie = MEM_callocN(sizeof(uiPopupMenu), "pie menu");
- pie->block_radial = uiBeginBlock(C, NULL, __func__, UI_EMBOSS);
+ pie->block_radial = UI_block_begin(C, NULL, __func__, UI_EMBOSS);
/* may be useful later to allow spawning pies
* from old positions */
/* pie->block_radial->flag |= UI_BLOCK_POPUP_MEMORY; */
@@ -2749,7 +2773,7 @@ uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const
win->lock_pie_event = event_type;
}
- pie->layout = uiBlockLayout(pie->block_radial, UI_LAYOUT_VERTICAL, UI_LAYOUT_PIEMENU, 0, 0, 200, 0, 0, style);
+ pie->layout = UI_block_layout(pie->block_radial, UI_LAYOUT_VERTICAL, UI_LAYOUT_PIEMENU, 0, 0, 200, 0, 0, style);
pie->mx = event->x;
pie->my = event->y;
@@ -2760,12 +2784,12 @@ uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const
int w;
if (icon) {
BLI_snprintf(titlestr, sizeof(titlestr), " %s", title);
- w = uiPieTitleWidth(titlestr, icon);
- but = uiDefIconTextBut(pie->block_radial, LABEL, 0, icon, titlestr, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ w = ui_pie_menu_title_width(titlestr, icon);
+ but = uiDefIconTextBut(pie->block_radial, UI_BTYPE_LABEL, 0, icon, titlestr, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
else {
- w = uiPieTitleWidth(title, 0);
- but = uiDefBut(pie->block_radial, LABEL, 0, title, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ w = ui_pie_menu_title_width(title, 0);
+ but = uiDefBut(pie->block_radial, UI_BTYPE_LABEL, 0, title, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
/* do not align left */
but->drawflag &= ~UI_BUT_TEXT_LEFT;
@@ -2774,7 +2798,7 @@ uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const
return pie;
}
-void uiPieMenuEnd(bContext *C, uiPieMenu *pie)
+void UI_pie_menu_end(bContext *C, uiPieMenu *pie)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *menu;
@@ -2783,18 +2807,18 @@ void uiPieMenuEnd(bContext *C, uiPieMenu *pie)
menu->popup = true;
menu->towardstime = PIL_check_seconds_timer();
- UI_add_popup_handlers(C, &window->modalhandlers, menu, true);
+ UI_popup_handlers_add(C, &window->modalhandlers, menu, true);
WM_event_add_mousemove(C);
MEM_freeN(pie);
}
-uiLayout *uiPieMenuLayout(uiPieMenu *pie)
+uiLayout *UI_pie_menu_layout(uiPieMenu *pie)
{
return pie->layout;
}
-void uiPieMenuInvoke(struct bContext *C, const char *idname, const wmEvent *event)
+int UI_pie_menu_invoke(struct bContext *C, const char *idname, const wmEvent *event)
{
uiPieMenu *pie;
uiLayout *layout;
@@ -2803,14 +2827,14 @@ void uiPieMenuInvoke(struct bContext *C, const char *idname, const wmEvent *even
if (mt == NULL) {
printf("%s: named menu \"%s\" not found\n", __func__, idname);
- return;
+ return OPERATOR_CANCELLED;
}
if (mt->poll && mt->poll(C, mt) == 0)
- return;
+ return OPERATOR_CANCELLED;
- pie = uiPieMenuBegin(C, IFACE_(mt->label), ICON_NONE, event);
- layout = uiPieMenuLayout(pie);
+ pie = UI_pie_menu_begin(C, IFACE_(mt->label), ICON_NONE, event);
+ layout = UI_pie_menu_layout(pie);
menu.layout = layout;
menu.type = mt;
@@ -2821,26 +2845,30 @@ void uiPieMenuInvoke(struct bContext *C, const char *idname, const wmEvent *even
mt->draw(C, &menu);
- uiPieMenuEnd(C, pie);
+ UI_pie_menu_end(C, pie);
+
+ return OPERATOR_INTERFACE;
}
-void uiPieOperatorEnumInvoke(struct bContext *C, const char *title, const char *opname,
- const char *propname, const wmEvent *event)
+int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title, const char *opname,
+ const char *propname, const wmEvent *event)
{
uiPieMenu *pie;
uiLayout *layout;
- pie = uiPieMenuBegin(C, IFACE_(title), ICON_NONE, event);
- layout = uiPieMenuLayout(pie);
+ pie = UI_pie_menu_begin(C, IFACE_(title), ICON_NONE, event);
+ layout = UI_pie_menu_layout(pie);
layout = uiLayoutRadial(layout);
uiItemsEnumO(layout, opname, propname);
- uiPieMenuEnd(C, pie);
+ UI_pie_menu_end(C, pie);
+
+ return OPERATOR_INTERFACE;
}
-void uiPieEnumInvoke(struct bContext *C, const char *title, const char *path,
- const wmEvent *event)
+int UI_pie_menu_invoke_from_rna_enum(struct bContext *C, const char *title, const char *path,
+ const wmEvent *event)
{
PointerRNA ctx_ptr;
PointerRNA r_ptr;
@@ -2851,29 +2879,31 @@ void uiPieEnumInvoke(struct bContext *C, const char *title, const char *path,
RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr);
if (!RNA_path_resolve(&ctx_ptr, path, &r_ptr, &r_prop)) {
- return;
+ return OPERATOR_CANCELLED;
}
/* invalid property, only accept enums */
if (RNA_property_type(r_prop) != PROP_ENUM) {
BLI_assert(0);
- return;
+ return OPERATOR_CANCELLED;
}
- pie = uiPieMenuBegin(C, IFACE_(title), ICON_NONE, event);
+ pie = UI_pie_menu_begin(C, IFACE_(title), ICON_NONE, event);
- layout = uiPieMenuLayout(pie);
+ layout = UI_pie_menu_layout(pie);
layout = uiLayoutRadial(layout);
uiItemFullR(layout, &r_ptr, r_prop, RNA_NO_INDEX, 0, UI_ITEM_R_EXPAND, NULL, 0);
- uiPieMenuEnd(C, pie);
+ UI_pie_menu_end(C, pie);
+
+ return OPERATOR_INTERFACE;
}
/*************************** Standard Popup Menus ****************************/
-void uiPupMenuReports(bContext *C, ReportList *reports)
+void UI_popup_menu_reports(bContext *C, ReportList *reports)
{
Report *report;
@@ -2894,8 +2924,8 @@ void uiPupMenuReports(bContext *C, ReportList *reports)
if (pup == NULL) {
char title[UI_MAX_DRAW_STR];
BLI_snprintf(title, sizeof(title), "%s: %s", IFACE_("Report"), report->typestr);
- pup = uiPupMenuBegin(C, title, ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, title, ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
}
else {
uiItemS(layout);
@@ -2903,7 +2933,7 @@ void uiPupMenuReports(bContext *C, ReportList *reports)
/* split each newline into a label */
msg = report->message;
- icon = uiIconFromReportType(report->type);
+ icon = UI_icon_from_report_type(report->type);
do {
char buf[UI_MAX_DRAW_STR];
msg_next = strchr(msg, '\n');
@@ -2918,11 +2948,11 @@ void uiPupMenuReports(bContext *C, ReportList *reports)
}
if (pup) {
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
}
-bool uiPupMenuInvoke(bContext *C, const char *idname, ReportList *reports)
+int UI_popup_menu_invoke(bContext *C, const char *idname, ReportList *reports)
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -2931,14 +2961,14 @@ bool uiPupMenuInvoke(bContext *C, const char *idname, ReportList *reports)
if (mt == NULL) {
BKE_reportf(reports, RPT_ERROR, "Menu \"%s\" not found", idname);
- return false;
+ return OPERATOR_CANCELLED;
}
if (mt->poll && mt->poll(C, mt) == 0)
- return false;
+ return OPERATOR_CANCELLED;
- pup = uiPupMenuBegin(C, IFACE_(mt->label), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_(mt->label), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
menu.layout = layout;
menu.type = mt;
@@ -2949,15 +2979,15 @@ bool uiPupMenuInvoke(bContext *C, const char *idname, ReportList *reports)
mt->draw(C, &menu);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return true;
+ return OPERATOR_INTERFACE;
}
/*************************** Popup Block API **************************/
-void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext)
+void UI_popup_block_invoke_ex(bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
@@ -2967,16 +2997,16 @@ void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, const char *opn
handle->optype = (opname) ? WM_operatortype_find(opname, 0) : NULL;
handle->opcontext = opcontext;
- UI_add_popup_handlers(C, &window->modalhandlers, handle, false);
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, false);
WM_event_add_mousemove(C);
}
-void uiPupBlock(bContext *C, uiBlockCreateFunc func, void *arg)
+void UI_popup_block_invoke(bContext *C, uiBlockCreateFunc func, void *arg)
{
- uiPupBlockO(C, func, arg, NULL, WM_OP_INVOKE_DEFAULT);
+ UI_popup_block_invoke_ex(C, func, arg, NULL, WM_OP_INVOKE_DEFAULT);
}
-void uiPupBlockEx(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg)
+void UI_popup_block_ex(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
@@ -2990,7 +3020,7 @@ void uiPupBlockEx(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_f
handle->cancel_func = cancel_func;
// handle->opcontext = opcontext;
- UI_add_popup_handlers(C, &window->modalhandlers, handle, false);
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, false);
WM_event_add_mousemove(C);
}
@@ -3009,27 +3039,30 @@ void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, int
handle->cancel_func = confirm_cancel_operator;
handle->opcontext = opcontext;
- UI_add_popup_handlers(C, &window->modalhandlers, handle);
+ UI_popup_handlers_add(C, &window->modalhandlers, handle);
WM_event_add_mousemove(C);
}
#endif
-void uiPupBlockClose(bContext *C, uiBlock *block)
+void UI_popup_block_close(bContext *C, uiBlock *block)
{
if (block->handle) {
wmWindow *win = CTX_wm_window(C);
/* if loading new .blend while popup is open, window will be NULL */
if (win) {
- UI_remove_popup_handlers(&win->modalhandlers, block->handle);
+ UI_popup_handlers_remove(&win->modalhandlers, block->handle);
ui_popup_block_free(C, block->handle);
}
}
}
-float *ui_block_hsv_get(uiBlock *block)
+ColorPicker *ui_block_colorpicker_create(struct uiBlock *block)
{
- return block->_hsv;
+ ColorPicker *cpicker = MEM_callocN(sizeof(ColorPicker), "color_picker");
+ BLI_addhead(&block->color_pickers.list, cpicker);
+
+ return cpicker;
}
void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3])
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index c27789c0fc9..2f46c0906ae 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -45,9 +45,12 @@
#include "BKE_global.h"
+#include "BIF_gl.h"
#include "BLF_api.h"
-#include "BLF_translation.h"
+#ifdef WITH_INTERNATIONAL
+# include "BLF_translation.h"
+#endif
#include "UI_interface.h"
@@ -145,13 +148,14 @@ static uiFont *uifont_to_blfont(int id)
/* *************** draw ************************ */
-void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str,
- size_t len, float *r_xofs, float *r_yofs)
+void UI_fontstyle_draw_ex(
+ const uiFontStyle *fs, const rcti *rect, const char *str,
+ size_t len, float *r_xofs, float *r_yofs)
{
float height;
int xofs = 0, yofs;
- uiStyleFontSet(fs);
+ UI_fontstyle_set(fs);
height = BLF_ascender(fs->uifont_id);
yofs = ceil(0.5f * (BLI_rcti_size_y(rect) - height));
@@ -192,22 +196,24 @@ void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str,
*r_yofs = yofs;
}
-void uiStyleFontDraw(uiFontStyle *fs, const rcti *rect, const char *str)
+void UI_fontstyle_draw(const uiFontStyle *fs, const rcti *rect, const char *str)
{
float xofs, yofs;
- uiStyleFontDrawExt(fs, rect, str,
- BLF_DRAW_STR_DUMMY_MAX, &xofs, &yofs);
+
+ UI_fontstyle_draw_ex(
+ fs, rect, str,
+ BLF_DRAW_STR_DUMMY_MAX, &xofs, &yofs);
}
/* drawn same as above, but at 90 degree angle */
-void uiStyleFontDrawRotated(uiFontStyle *fs, const rcti *rect, const char *str)
+void UI_fontstyle_draw_rotated(const uiFontStyle *fs, const rcti *rect, const char *str)
{
float height;
int xofs, yofs;
float angle;
rcti txtrect;
- uiStyleFontSet(fs);
+ UI_fontstyle_set(fs);
height = BLF_ascender(fs->uifont_id);
/* becomes x-offset when rotated */
@@ -218,7 +224,7 @@ void uiStyleFontDrawRotated(uiFontStyle *fs, const rcti *rect, const char *str)
/* rotate counter-clockwise for now (assumes left-to-right language)*/
xofs += height;
yofs = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX) + 5;
- angle = (float)M_PI / 2.0f;
+ angle = M_PI_2;
/* translate rect to vertical */
txtrect.xmin = rect->xmin - BLI_rcti_size_y(rect);
@@ -253,9 +259,69 @@ void uiStyleFontDrawRotated(uiFontStyle *fs, const rcti *rect, const char *str)
BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
}
+/**
+ * Similar to #UI_fontstyle_draw
+ * but ignore alignment, shadow & no clipping rect.
+ *
+ * For drawing on-screen labels.
+ */
+void UI_fontstyle_draw_simple(const uiFontStyle *fs, float x, float y, const char *str)
+{
+ if (fs->kerning == 1)
+ BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
+
+ UI_fontstyle_set(fs);
+ BLF_position(fs->uifont_id, x, y, 0.0f);
+ BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
+
+ if (fs->kerning == 1)
+ BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
+}
+
+/**
+ * Same as #UI_fontstyle_draw but draw a colored backdrop.
+ */
+void UI_fontstyle_draw_simple_backdrop(
+ const uiFontStyle *fs, float x, float y, const char *str,
+ const unsigned char fg[4], const unsigned char bg[4])
+{
+ if (fs->kerning == 1)
+ BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
+
+ UI_fontstyle_set(fs);
+
+ {
+ const float width = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ const float height = BLF_height_max(fs->uifont_id);
+ const float decent = BLF_descender(fs->uifont_id);
+ const float margin = height / 4.0f;
+
+ /* backdrop */
+ glColor4ubv(bg);
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL | UI_RB_ALPHA);
+ UI_draw_roundbox(
+ x - margin,
+ (y + decent) - margin,
+ x + width + margin,
+ (y + decent) + height + margin,
+ margin);
+
+ glColor4ubv(fg);
+ }
+
+
+ BLF_position(fs->uifont_id, x, y, 0.0f);
+ BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
+
+ if (fs->kerning == 1)
+ BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
+}
+
+
/* ************** helpers ************************ */
/* XXX: read a style configure */
-uiStyle *UI_GetStyle(void)
+uiStyle *UI_style_get(void)
{
uiStyle *style = NULL;
/* offset is two struct uiStyle pointers */
@@ -264,9 +330,9 @@ uiStyle *UI_GetStyle(void)
}
/* for drawing, scaled with DPI setting */
-uiStyle *UI_GetStyleDraw(void)
+uiStyle *UI_style_get_dpi(void)
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
static uiStyle _style;
_style = *style;
@@ -289,41 +355,29 @@ uiStyle *UI_GetStyleDraw(void)
return &_style;
}
-/* temporarily, does widget font */
-int UI_GetStringWidth(const char *str)
+int UI_fontstyle_string_width(const uiFontStyle *fs, const char *str)
{
- uiStyle *style = UI_GetStyle();
- uiFontStyle *fstyle = &style->widget;
int width;
- if (fstyle->kerning == 1) /* for BLF_width */
- BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ if (fs->kerning == 1) /* for BLF_width */
+ BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
- uiStyleFontSet(fstyle);
- width = BLF_width(fstyle->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ UI_fontstyle_set(fs);
+ width = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
- if (fstyle->kerning == 1)
- BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ if (fs->kerning == 1)
+ BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
return width;
}
-/* temporarily, does widget font */
-void UI_DrawString(float x, float y, const char *str)
+int UI_fontstyle_height_max(const uiFontStyle *fs)
{
- uiStyle *style = UI_GetStyle();
-
- if (style->widget.kerning == 1)
- BLF_enable(style->widget.uifont_id, BLF_KERNING_DEFAULT);
-
- uiStyleFontSet(&style->widget);
- BLF_position(style->widget.uifont_id, x, y, 0.0f);
- BLF_draw(style->widget.uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
-
- if (style->widget.kerning == 1)
- BLF_disable(style->widget.uifont_id, BLF_KERNING_DEFAULT);
+ UI_fontstyle_set(fs);
+ return BLF_height_max(fs->uifont_id);
}
+
/* ************** init exit ************************ */
/* called on each startup.blend read */
@@ -396,11 +450,10 @@ void uiStyleInit(void)
if (font->blf_id == -1) {
font->blf_id = BLF_load_mem("default", (unsigned char *)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
}
- else {
- BLF_default_set(font->blf_id);
- }
}
+ BLF_default_set(font->blf_id);
+
if (font->blf_id == -1) {
if (G.debug & G_DEBUG)
printf("%s: error, no fonts available\n", __func__);
@@ -451,7 +504,7 @@ void uiStyleInit(void)
BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72);
}
-void uiStyleFontSet(uiFontStyle *fs)
+void UI_fontstyle_set(const uiFontStyle *fs)
{
uiFont *font = uifont_to_blfont(fs->uifont_id);
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index b0bea42e3bc..b3c31a1a644 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -31,7 +31,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_dynamicpaint_types.h"
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -74,7 +73,6 @@
#include "ED_util.h"
#include "RNA_access.h"
-#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -156,9 +154,9 @@ static void id_search_cb(const bContext *C, void *arg_template, const char *str,
char name_ui[MAX_ID_NAME + 1];
name_uiprefix_id(name_ui, id);
- iconid = ui_id_icon_get((bContext *)C, id, template->preview);
+ iconid = ui_id_icon_get(C, id, template->preview);
- if (false == uiSearchItemAdd(items, name_ui, id, iconid))
+ if (false == UI_search_item_add(items, name_ui, id, iconid))
break;
}
}
@@ -183,8 +181,8 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
/* get active id for showing first item */
idptr = RNA_property_pointer_get(&template.ptr, template.prop);
- block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
- uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_SEARCH_MENU);
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
/* preview thumbnails */
if (template.prv_rows > 0 && template.prv_cols > 0) {
@@ -192,29 +190,29 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
int h = 4 * U.widget_unit * template.prv_rows + U.widget_unit;
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL);
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y,
template.prv_rows, template.prv_cols, "");
- uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
+ UI_but_func_search_set(but, id_search_cb, &template, id_search_call_cb, idptr.data);
}
/* list view */
else {
- const int searchbox_width = uiSearchBoxWidth();
- const int searchbox_height = uiSearchBoxHeight();
+ const int searchbox_width = UI_searchbox_size_x();
+ const int searchbox_height = UI_searchbox_size_y();
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL);
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, searchbox_width, UI_UNIT_Y - 1, 0, 0, "");
- uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data);
+ UI_but_func_search_set(but, id_search_cb, &template, id_search_call_cb, idptr.data);
}
- uiBoundsBlock(block, 0.3f * U.widget_unit);
- uiBlockSetDirection(block, UI_DOWN);
+ UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
+ UI_block_direction_set(block, UI_DIR_DOWN);
/* give search-field focus */
- uiButSetFocusOnEnter(win, but);
+ UI_but_focus_on_enter_event(win, but);
/* this type of search menu requires undo */
but->flag |= UI_BUT_UNDO;
@@ -225,7 +223,7 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
/* This is for browsing and editing the ID-blocks used */
/* for new/open operators */
-void uiIDContextProperty(bContext *C, PointerRNA *ptr, PropertyRNA **prop)
+void UI_context_active_but_prop_get_templateID(bContext *C, PointerRNA *ptr, PropertyRNA **prop)
{
TemplateID *template;
ARegion *ar = CTX_wm_region(C);
@@ -268,7 +266,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
break;
case UI_ID_OPEN:
case UI_ID_ADD_NEW:
- /* these call uiIDContextProperty */
+ /* these call UI_context_active_but_prop_get_templateID */
break;
case UI_ID_DELETE:
memset(&idptr, 0, sizeof(idptr));
@@ -352,6 +350,8 @@ static const char *template_id_browse_tip(StructRNA *type)
case ID_BR: return N_("Browse Brush to be linked");
case ID_PA: return N_("Browse Particle Settings to be linked");
case ID_GD: return N_("Browse Grease Pencil Data to be linked");
+ case ID_MC: return N_("Browse Movie Clip to be linked");
+ case ID_MSK: return N_("Browse Mask to be linked");
case ID_PAL: return N_("Browse Palette Data to be linked");
case ID_PC: return N_("Browse Paint Curve Data to be linked");
}
@@ -390,6 +390,10 @@ static const char *template_id_context(StructRNA *type)
case ID_BR: return BLF_I18NCONTEXT_ID_BRUSH;
case ID_PA: return BLF_I18NCONTEXT_ID_PARTICLESETTINGS;
case ID_GD: return BLF_I18NCONTEXT_ID_GPENCIL;
+ case ID_MC: return BLF_I18NCONTEXT_ID_MOVIECLIP;
+ case ID_MSK: return BLF_I18NCONTEXT_ID_MASK;
+ case ID_PAL: return BLF_I18NCONTEXT_ID_PALETTE;
+ case ID_PC: return BLF_I18NCONTEXT_ID_PAINTCURVE;
}
}
return BLF_I18NCONTEXT_DEFAULT;
@@ -412,7 +416,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
// lb = template->idlb;
block = uiLayoutGetBlock(layout);
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
if (idptr.type)
type = idptr.type;
@@ -423,10 +427,10 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
but = uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6,
TIP_(template_id_browse_tip(type)));
but->icon = id ? ui_id_icon_get(C, id, true) : RNA_struct_ui_icon(type);
- uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW);
+ UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
if ((idfrom && idfrom->lib) || !editable)
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
uiLayoutRow(layout, true);
}
@@ -435,12 +439,12 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
TIP_(template_id_browse_tip(type)));
but->icon = RNA_struct_ui_icon(type);
/* default dragging of icon for id browse buttons */
- uiButSetDragID(but, id);
- uiButSetFlag(but, UI_HAS_ICON);
- uiButSetDrawFlag(but, UI_BUT_ICON_LEFT);
+ UI_but_drag_set_id(but, id);
+ UI_but_flag_enable(but, UI_HAS_ICON);
+ UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
if ((idfrom && idfrom->lib) || !editable)
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
/* text button with name */
@@ -450,37 +454,39 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
//text_idbutton(id, name);
name[0] = '\0';
- but = uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y,
+ but = uiDefButR(block, UI_BTYPE_TEXT, 0, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y,
&idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type));
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
- if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT);
+ UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
+ if (user_alert) UI_but_flag_enable(but, UI_BUT_REDALERT);
if (id->lib) {
if (id->flag & LIB_INDIRECT) {
- but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Indirect library datablock, cannot change"));
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
else {
- but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Direct linked library datablock, click to make local"));
if (!id_make_local(id, true /* test */) || (idfrom && idfrom->lib))
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_LOCAL));
+ UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_LOCAL));
}
if (id->us > 1) {
char numstr[32];
+ short numstr_len;
- BLI_snprintf(numstr, sizeof(numstr), "%d", id->us);
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", id->us);
- but = uiDefBut(block, BUT, 0, numstr, 0, 0, UI_UNIT_X + ((id->us < 10) ? 0 : 10), UI_UNIT_Y,
- NULL, 0, 0, 0, 0,
+ but = uiDefBut(block, UI_BTYPE_BUT, 0, numstr, 0, 0,
+ numstr_len * 0.2f * UI_UNIT_X + UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
TIP_("Display number of users of this data (click to make a single-user copy)"));
+ but->flag |= UI_BUT_UNDO;
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
+ UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
if (/* test only */
(id_copy(id, NULL, true) == false) ||
(idfrom && idfrom->lib) ||
@@ -488,14 +494,14 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
/* object in editmode - don't change data */
(idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT)))
{
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
}
- if (user_alert) uiButSetFlag(but, UI_BUT_REDALERT);
+ if (user_alert) UI_but_flag_enable(but, UI_BUT_REDALERT);
if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB))) {
- uiDefButR(block, TOG, 0, "F", 0, 0, UI_UNIT_X, UI_UNIT_Y, &idptr, "use_fake_user", -1, 0, 0, -1, -1, NULL);
+ uiDefButR(block, UI_BTYPE_TOGGLE, 0, "F", 0, 0, UI_UNIT_X, UI_UNIT_Y, &idptr, "use_fake_user", -1, 0, 0, -1, -1, NULL);
}
}
@@ -531,26 +537,26 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
);
if (newop) {
- but = uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN,
+ but = uiDefIconTextButO(block, UI_BTYPE_BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN,
(id) ? "" : CTX_IFACE_(template_id_context(type), "New"), 0, 0, w, UI_UNIT_Y, NULL);
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
+ UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
}
else {
- but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
+ UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
}
if ((idfrom && idfrom->lib) || !editable)
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
/* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack.
* Only for images, sound and fonts */
if (id && BKE_pack_check(id)) {
- but = uiDefIconButO(block, BUT, "FILE_OT_unpack_item", WM_OP_INVOKE_REGION_WIN, ICON_PACKAGE, 0, 0,
+ but = uiDefIconButO(block, UI_BTYPE_BUT, "FILE_OT_unpack_item", WM_OP_INVOKE_REGION_WIN, ICON_PACKAGE, 0, 0,
UI_UNIT_X, UI_UNIT_Y, TIP_("Packed File, click to unpack"));
- uiButGetOperatorPtrRNA(but);
+ UI_but_operator_ptr_get(but);
RNA_string_set(but->opptr, "id_name", id->name + 2);
RNA_int_set(but->opptr, "id_type", GS(id->name));
@@ -560,18 +566,18 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
if (openop) {
- but = uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id) ? "" : IFACE_("Open"),
+ but = uiDefIconTextButO(block, UI_BTYPE_BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILESEL, (id) ? "" : IFACE_("Open"),
0, 0, w, UI_UNIT_Y, NULL);
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
+ UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
}
else {
- but = uiDefIconTextBut(block, BUT, 0, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y,
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_FILESEL, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y,
NULL, 0, 0, 0, 0, NULL);
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
+ UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
}
if ((idfrom && idfrom->lib) || !editable)
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
/* delete button */
@@ -581,26 +587,26 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
but = NULL;
if (unlinkop) {
- but = uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+ but = uiDefIconButO(block, UI_BTYPE_BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
/* so we can access the template from operators, font unlinking needs this */
- uiButSetNFunc(but, NULL, MEM_dupallocN(template), NULL);
+ UI_but_funcN_set(but, NULL, MEM_dupallocN(template), NULL);
}
else {
if ((RNA_property_flag(template->prop) & PROP_NEVER_UNLINK) == 0) {
- but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
+ but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
TIP_("Unlink datablock "
"(Shift + Click to set users to zero, data will then not be saved)"));
- uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
+ UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
if (RNA_property_flag(template->prop) & PROP_NEVER_NULL) {
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
}
}
if (but) {
if ((idfrom && idfrom->lib) || !editable) {
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
}
}
@@ -608,7 +614,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
if (idcode == ID_TE)
uiTemplateTextureShow(layout, C, &template->ptr, template->prop);
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
}
static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
@@ -842,26 +848,27 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
/* VIRTUAL MODIFIER */
/* XXX this is not used now, since these cannot be accessed via RNA */
BLI_snprintf(str, sizeof(str), IFACE_("%s parent deform"), md->name);
- uiDefBut(block, LABEL, 0, str, 0, 0, 185, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Modifier name"));
+ uiDefBut(block, UI_BTYPE_LABEL, 0, str, 0, 0, 185, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Modifier name"));
- but = uiDefBut(block, BUT, 0, IFACE_("Make Real"), 0, 0, 80, 16, NULL, 0.0, 0.0, 0.0, 0.0,
+ but = uiDefBut(block, UI_BTYPE_BUT, 0, IFACE_("Make Real"), 0, 0, 80, 16, NULL, 0.0, 0.0, 0.0, 0.0,
TIP_("Convert virtual modifier to a real modifier"));
- uiButSetFunc(but, modifiers_convertToReal, ob, md);
+ UI_but_func_set(but, modifiers_convertToReal, ob, md);
}
else {
/* REAL MODIFIER */
row = uiLayoutRow(box, false);
block = uiLayoutGetBlock(row);
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
/* Open/Close ................................. */
uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
/* modifier-type icon */
uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
/* modifier name */
+ md->scene = scene;
if (mti->isDisabled && mti->isDisabled(md, 0)) {
uiLayoutSetRedAlert(row, true);
}
@@ -869,7 +876,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
uiLayoutSetRedAlert(row, false);
/* mode enabling buttons */
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
/* Softbody not allowed in this situation, enforce! */
if (((md->type != eModifierType_Softbody && md->type != eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) &&
(md->type != eModifierType_Surface) )
@@ -900,10 +907,10 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
if (ELEM(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
/* add disabled pre-tessellated button, so users could have
* message for this modifiers */
- but = uiDefIconButBitI(block, TOG, eModifierMode_ApplyOnSpline, 0, ICON_SURFACE_DATA, 0, 0,
+ but = uiDefIconButBitI(block, UI_BTYPE_TOGGLE, eModifierMode_ApplyOnSpline, 0, ICON_SURFACE_DATA, 0, 0,
UI_UNIT_X - 2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0,
TIP_("This modifier can only be applied on splines' points"));
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
else if (mti->type != eModifierTypeType_Constructive) {
/* constructive modifiers tessellates curve before applying */
@@ -911,23 +918,29 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
}
}
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
/* Up/Down + Delete ........................... */
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_modifier_move_up");
uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_modifier_move_down");
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
/* When Modifier is a simulation, show button to switch to context rather than the delete button. */
- if (modifier_can_delete(md) && (!modifier_is_simulation(md) || STREQ(scene->r.engine, "BLENDER_GAME")))
+ if (modifier_can_delete(md) &&
+ (!modifier_is_simulation(md) ||
+ STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME)))
+ {
uiItemO(row, "", ICON_X, "OBJECT_OT_modifier_remove");
- else if (modifier_is_simulation(md) == 1)
+ }
+ else if (modifier_is_simulation(md) == 1) {
uiItemStringO(row, "", ICON_BUTS, "WM_OT_properties_context_change", "context", "PHYSICS");
- else if (modifier_is_simulation(md) == 2)
+ }
+ else if (modifier_is_simulation(md) == 2) {
uiItemStringO(row, "", ICON_BUTS, "WM_OT_properties_context_change", "context", "PARTICLES");
- uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+ UI_block_emboss_set(block, UI_EMBOSS);
}
@@ -939,7 +952,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
if (!ELEM(md->type, eModifierType_Collision, eModifierType_Surface)) {
/* only here obdata, the rest of modifiers is ob level */
- uiBlockSetButLock(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+ UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
if (md->type == eModifierType_ParticleSystem) {
ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
@@ -965,8 +978,8 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob,
}
}
- uiBlockClearButLock(block);
- uiBlockSetButLock(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE);
+ UI_block_lock_clear(block);
+ UI_block_lock_set(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE);
if (!ELEM(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem,
eModifierType_Cloth, eModifierType_Smoke))
@@ -1013,7 +1026,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr)
return NULL;
}
- uiBlockSetButLock(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
+ UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
/* find modifier and draw it */
cageIndex = modifiers_getCageIndex(scene, ob, &lastCageIndex, 0);
@@ -1107,8 +1120,8 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
/* unless button has own callback, it adds this callback to button */
block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_constraint_panels, ob);
- uiBlockSetFunc(block, constraint_active_func, ob, con);
+ UI_block_func_handle_set(block, do_constraint_panels, ob);
+ UI_block_func_set(block, constraint_active_func, ob, con);
RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr);
@@ -1122,12 +1135,12 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
/* Draw constraint header */
/* open/close */
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
uiItemR(row, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
/* name */
- uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr,
+ uiDefBut(block, UI_BTYPE_LABEL, B_CONSTRAINT_TEST, typestr,
xco + 0.5f * UI_UNIT_X, yco, 5 * UI_UNIT_X, 0.9f * UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "");
if (con->flag & CONSTRAINT_DISABLE)
@@ -1143,15 +1156,15 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
/* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
if (proxy_protected) {
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
/* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */
- uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 12.2f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y,
+ uiDefIconBut(block, UI_BTYPE_BUT, B_CONSTRAINT_TEST, ICON_GHOST, xco + 12.2f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
- uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 13.1f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y,
+ uiDefIconBut(block, UI_BTYPE_BUT, B_CONSTRAINT_TEST, ICON_LOCKED, xco + 13.1f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
else {
short prev_proxylock, show_upbut, show_downbut;
@@ -1177,33 +1190,33 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
show_downbut = (con->next) ? 1 : 0;
/* enabled */
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
uiItemR(row, &ptr, "mute", 0, "",
(con->flag & CONSTRAINT_OFF) ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
/* up/down */
if (show_upbut || show_downbut) {
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
if (show_upbut)
uiItemO(row, "", ICON_TRIA_UP, "CONSTRAINT_OT_move_up");
if (show_downbut)
uiItemO(row, "", ICON_TRIA_DOWN, "CONSTRAINT_OT_move_down");
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
}
/* Close 'button' - emboss calls here disable drawing of 'button' behind X */
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
uiItemO(row, "", ICON_X, "CONSTRAINT_OT_delete");
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
/* Set but-locks for protected settings (magic numbers are used here!) */
if (proxy_protected)
- uiBlockSetButLock(block, true, IFACE_("Cannot edit Proxy-Protected Constraint"));
+ UI_block_lock_set(block, true, IFACE_("Cannot edit Proxy-Protected Constraint"));
/* Draw constraint data */
if ((con->flag & CONSTRAINT_EXPAND) == 0) {
@@ -1216,7 +1229,7 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
}
/* clear any locks set up for proxies/lib-linking */
- uiBlockClearButLock(block);
+ UI_block_lock_clear(block);
return result;
}
@@ -1240,7 +1253,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
return NULL;
}
- uiBlockSetButLock(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
+ UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
/* hrms, the temporal constraint should not draw! */
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
@@ -1345,11 +1358,11 @@ void uiTemplatePreview(uiLayout *layout, bContext *C, ID *id, int show_buttons,
uiLayoutSetKeepAspect(col, true);
/* add preview */
- uiDefBut(block, BUT_EXTRA, 0, "", 0, 0, UI_UNIT_X * 10, ui_preview->height, pid, 0.0, 0.0, 0, 0, "");
- uiBlockSetDrawExtraFunc(block, ED_preview_draw, pparent, slot);
- uiBlockSetHandleFunc(block, do_preview_buttons, NULL);
+ uiDefBut(block, UI_BTYPE_EXTRA, 0, "", 0, 0, UI_UNIT_X * 10, ui_preview->height, pid, 0.0, 0.0, 0, 0, "");
+ UI_but_func_drawextra_set(block, ED_preview_draw, pparent, slot);
+ UI_block_func_handle_set(block, do_preview_buttons, NULL);
- uiDefIconButS(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &ui_preview->height,
+ uiDefIconButS(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &ui_preview->height,
UI_UNIT_Y, UI_UNIT_Y * 50.0f, 0.0f, 0.0f, "");
/* add buttons */
@@ -1371,25 +1384,25 @@ void uiTemplatePreview(uiLayout *layout, bContext *C, ID *id, int show_buttons,
RNA_pointer_create(id, &RNA_Texture, tex, &texture_ptr);
uiLayoutRow(layout, true);
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Texture"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Texture"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
pr_texture, 10, TEX_PR_TEXTURE, 0, 0, "");
if (GS(parent->name) == ID_MA) {
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Material"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Material"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
}
else if (GS(parent->name) == ID_LA) {
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Lamp"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Lamp"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
}
else if (GS(parent->name) == ID_WO) {
- uiDefButS(block, ROW, B_MATPRV, IFACE_("World"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("World"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
}
else if (GS(parent->name) == ID_LS) {
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Line Style"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Line Style"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
}
- uiDefButS(block, ROW, B_MATPRV, IFACE_("Both"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Both"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
pr_texture, 10, TEX_PR_BOTH, 0, 0, "");
/* Alpha button for texture preview */
@@ -1493,28 +1506,28 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand
split = uiLayoutSplit(layout, 0.4f, false);
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiBlockBeginAlign(block);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ UI_block_align_begin(block);
row = uiLayoutRow(split, false);
- bt = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, "", 0, 0, 2.0f * unit, UI_UNIT_Y, NULL,
+ bt = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMIN, "", 0, 0, 2.0f * unit, UI_UNIT_Y, NULL,
0, 0, 0, 0, TIP_("Add a new color stop to the colorband"));
- uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
+ UI_but_funcN_set(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
- bt = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMOUT, "", xs + 2.0f * unit, ys + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y,
+ bt = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMOUT, "", xs + 2.0f * unit, ys + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Delete the active position"));
- uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
+ UI_but_funcN_set(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
- bt = uiDefIconTextBut(block, BUT, 0, ICON_ARROW_LEFTRIGHT, "", xs + 4.0f * unit, ys + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y,
+ bt = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_ARROW_LEFTRIGHT, "", xs + 4.0f * unit, ys + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Flip the color ramp"));
- uiButSetNFunc(bt, colorband_flip_cb, MEM_dupallocN(cb), coba);
- uiBlockEndAlign(block);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_but_funcN_set(bt, colorband_flip_cb, MEM_dupallocN(cb), coba);
+ UI_block_align_end(block);
+ UI_block_emboss_set(block, UI_EMBOSS);
row = uiLayoutRow(split, false);
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
uiItemR(row, &ptr, "color_mode", 0, "", ICON_NONE);
if (ELEM(coba->color_mode, COLBAND_BLEND_HSV, COLBAND_BLEND_HSL)) {
uiItemR(row, &ptr, "hue_interpolation", 0, "", ICON_NONE);
@@ -1522,12 +1535,12 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand
else { /* COLBAND_BLEND_RGB */
uiItemR(row, &ptr, "interpolation", 0, "", ICON_NONE);
}
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
row = uiLayoutRow(layout, false);
- bt = uiDefBut(block, BUT_COLORBAND, 0, "", xs, ys, BLI_rctf_size_x(butr), UI_UNIT_Y, coba, 0, 0, 0, 0, "");
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ bt = uiDefBut(block, UI_BTYPE_COLORBAND, 0, "", xs, ys, BLI_rctf_size_x(butr), UI_UNIT_Y, coba, 0, 0, 0, 0, "");
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
row = uiLayoutRow(layout, false);
@@ -1540,34 +1553,34 @@ static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand
split = uiLayoutSplit(layout, 0.3f, false);
row = uiLayoutRow(split, false);
- uiDefButS(block, NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)),
+ uiDefButS(block, UI_BTYPE_NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)),
0, 0, TIP_("Choose active color stop"));
row = uiLayoutRow(split, false);
uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
bt = block->buttons.last;
- uiButSetFunc(bt, colorband_update_cb, bt, coba);
+ UI_but_func_set(bt, colorband_update_cb, bt, coba);
row = uiLayoutRow(layout, false);
uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
bt = block->buttons.last;
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
}
else {
split = uiLayoutSplit(layout, 0.5f, false);
subsplit = uiLayoutSplit(split, 0.35f, false);
row = uiLayoutRow(subsplit, false);
- uiDefButS(block, NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)),
+ uiDefButS(block, UI_BTYPE_NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)),
0, 0, TIP_("Choose active color stop"));
row = uiLayoutRow(subsplit, false);
uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE);
bt = block->buttons.last;
- uiButSetFunc(bt, colorband_update_cb, bt, coba);
+ UI_but_func_set(bt, colorband_update_cb, bt, coba);
row = uiLayoutRow(split, false);
uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
bt = block->buttons.last;
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
}
}
}
@@ -1598,11 +1611,11 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname
block = uiLayoutAbsoluteBlock(layout);
id = cptr.id.data;
- uiBlockSetButLock(block, (id && id->lib), ERROR_LIBDATA_MESSAGE);
+ UI_block_lock_set(block, (id && id->lib), ERROR_LIBDATA_MESSAGE);
colorband_buttons_layout(layout, block, cptr.data, &rect, cb, expand);
- uiBlockClearButLock(block);
+ UI_block_lock_clear(block);
MEM_freeN(cb);
}
@@ -1611,7 +1624,7 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname
/********************* Icon viewer Template ************************/
/* ID Search browse menu, open */
-static uiBlock *icon_view_menu(bContext *C, ARegion *ar, void *arg_litem)
+static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *ar, void *arg_litem)
{
static RNAUpdateCb cb;
uiBlock *block;
@@ -1627,8 +1640,8 @@ static uiBlock *icon_view_menu(bContext *C, ARegion *ar, void *arg_litem)
/* unused */
// icon = RNA_property_enum_get(&cb.ptr, cb.prop);
- block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
- uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW);
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP);
RNA_property_enum_items(C, &cb.ptr, cb.prop, &item, NULL, &free);
@@ -1641,12 +1654,12 @@ static uiBlock *icon_view_menu(bContext *C, ARegion *ar, void *arg_litem)
y = (a / 8) * UI_UNIT_X * 5;
icon = item[a].icon;
- but = uiDefIconButR_prop(block, ROW, 0, icon, x, y, UI_UNIT_X * 5, UI_UNIT_Y * 5, &cb.ptr, cb.prop, -1, 0, icon, -1, -1, NULL);
- uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW);
+ but = uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, x, y, UI_UNIT_X * 5, UI_UNIT_Y * 5, &cb.ptr, cb.prop, -1, 0, icon, -1, -1, NULL);
+ UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
}
- uiBoundsBlock(block, 0.3f * U.widget_unit);
- uiBlockSetDirection(block, UI_TOP);
+ UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
+ UI_block_direction_set(block, UI_DIR_UP);
if (free) {
MEM_freeN(item);
@@ -1678,15 +1691,15 @@ void uiTemplateIconView(uiLayout *layout, PointerRNA *ptr, const char *propname)
block = uiLayoutAbsoluteBlock(layout);
- but = uiDefBlockButN(block, icon_view_menu, MEM_dupallocN(cb), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, "");
+ but = uiDefBlockButN(block, ui_icon_view_menu_cb, MEM_dupallocN(cb), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, "");
-// but = uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect), ptr, prop, -1, 0, icon, -1, -1, NULL);
+// but = uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, 0, 0, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect), ptr, prop, -1, 0, icon, -1, -1, NULL);
but->icon = icon;
- uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW);
+ UI_but_flag_enable(but, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
- uiButSetNFunc(but, rna_update_cb, MEM_dupallocN(cb), NULL);
+ UI_but_funcN_set(but, rna_update_cb, MEM_dupallocN(cb), NULL);
MEM_freeN(cb);
}
@@ -1719,10 +1732,10 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname
col = uiLayoutColumn(layout, true);
block = uiLayoutGetBlock(col);
- uiDefBut(block, HISTOGRAM, 0, "", 0, 0, UI_UNIT_X * 10, hist->height, hist, 0, 0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_HISTOGRAM, 0, "", 0, 0, UI_UNIT_X * 10, hist->height, hist, 0, 0, 0, 0, "");
/* Resize grip. */
- uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &hist->height,
+ uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &hist->height,
UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
}
@@ -1754,10 +1767,10 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
scopes->wavefrm_height = UI_UNIT_Y * 20;
}
- uiDefBut(block, WAVEFORM, 0, "", 0, 0, UI_UNIT_X * 10, scopes->wavefrm_height, scopes, 0, 0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_WAVEFORM, 0, "", 0, 0, UI_UNIT_X * 10, scopes->wavefrm_height, scopes, 0, 0, 0, 0, "");
/* Resize grip. */
- uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->wavefrm_height,
+ uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->wavefrm_height,
UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
}
@@ -1789,10 +1802,10 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna
col = uiLayoutColumn(layout, true);
block = uiLayoutGetBlock(col);
- uiDefBut(block, VECTORSCOPE, 0, "", 0, 0, UI_UNIT_X * 10, scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_VECTORSCOPE, 0, "", 0, 0, UI_UNIT_X * 10, scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
/* Resize grip. */
- uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->vecscope_height,
+ uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->vecscope_height,
UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
}
@@ -1879,28 +1892,27 @@ static uiBlock *curvemap_clipping_func(bContext *C, ARegion *ar, void *cumap_v)
uiBut *bt;
float width = 8 * UI_UNIT_X;
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
/* use this for a fake extra empy space around the buttons */
- uiDefBut(block, LABEL, 0, "", -4, 16, width + 8, 6 * UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", -4, 16, width + 8, 6 * UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- bt = uiDefButBitI(block, TOG, CUMA_DO_CLIP, 1, IFACE_("Use Clipping"),
+ bt = uiDefButBitI(block, UI_BTYPE_TOGGLE, CUMA_DO_CLIP, 1, IFACE_("Use Clipping"),
0, 5 * UI_UNIT_Y, width, UI_UNIT_Y, &cumap->flag, 0.0, 0.0, 10, 0, "");
- uiButSetFunc(bt, curvemap_buttons_setclip, cumap, NULL);
+ UI_but_func_set(bt, curvemap_buttons_setclip, cumap, NULL);
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, 0, IFACE_("Min X "), 0, 4 * UI_UNIT_Y, width, UI_UNIT_Y,
+ UI_block_align_begin(block);
+ uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Min X "), 0, 4 * UI_UNIT_Y, width, UI_UNIT_Y,
&cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 2, "");
- uiDefButF(block, NUM, 0, IFACE_("Min Y "), 0, 3 * UI_UNIT_Y, width, UI_UNIT_Y,
+ uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Min Y "), 0, 3 * UI_UNIT_Y, width, UI_UNIT_Y,
&cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 2, "");
- uiDefButF(block, NUM, 0, IFACE_("Max X "), 0, 2 * UI_UNIT_Y, width, UI_UNIT_Y,
+ uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Max X "), 0, 2 * UI_UNIT_Y, width, UI_UNIT_Y,
&cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 2, "");
- uiDefButF(block, NUM, 0, IFACE_("Max Y "), 0, UI_UNIT_Y, width, UI_UNIT_Y,
+ uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Max Y "), 0, UI_UNIT_Y, width, UI_UNIT_Y,
&cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 2, "");
- uiBlockSetDirection(block, UI_RIGHT);
+ UI_block_direction_set(block, UI_DIR_RIGHT);
- uiEndBlock(C, block);
return block;
}
@@ -1956,26 +1968,25 @@ static uiBlock *curvemap_tools_posslope_func(bContext *C, ARegion *ar, void *cum
uiBlock *block;
short yco = 0, menuwidth = 10 * UI_UNIT_X;
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
- uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ UI_block_func_butmenu_set(block, curvemap_tools_dofunc, cumap_v);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_VIEW, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_VECTOR, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_AUTO, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Horizontal"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Extend Horizontal"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_EXTEND_HOZ, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_EXTEND_EXP, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_POS, "");
- uiBlockSetDirection(block, UI_RIGHT);
- uiTextBoundsBlock(block, 50);
+ UI_block_direction_set(block, UI_DIR_RIGHT);
+ UI_block_bounds_set_text(block, 50);
- uiEndBlock(C, block);
return block;
}
@@ -1984,26 +1995,25 @@ static uiBlock *curvemap_tools_negslope_func(bContext *C, ARegion *ar, void *cum
uiBlock *block;
short yco = 0, menuwidth = 10 * UI_UNIT_X;
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
- uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ UI_block_func_butmenu_set(block, curvemap_tools_dofunc, cumap_v);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_VIEW, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_VECTOR, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_AUTO, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Horizontal"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Extend Horizontal"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_EXTEND_HOZ, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_EXTEND_EXP, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_NEG, "");
- uiBlockSetDirection(block, UI_RIGHT);
- uiTextBoundsBlock(block, 50);
+ UI_block_direction_set(block, UI_DIR_RIGHT);
+ UI_block_bounds_set_text(block, 50);
- uiEndBlock(C, block);
return block;
}
@@ -2012,22 +2022,21 @@ static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *ar, void *cumap_
uiBlock *block;
short yco = 0, menuwidth = 10 * UI_UNIT_X;
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
- uiBlockSetButmFunc(block, curvemap_tools_dofunc, cumap_v);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ UI_block_func_butmenu_set(block, curvemap_tools_dofunc, cumap_v);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset View"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_VIEW, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Vector Handle"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_VECTOR, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto Handle"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_AUTO, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset Curve"), 0, yco -= UI_UNIT_Y,
menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_NEG, "");
- uiBlockSetDirection(block, UI_RIGHT);
- uiTextBoundsBlock(block, 50);
+ UI_block_direction_set(block, UI_DIR_RIGHT);
+ UI_block_bounds_set_text(block, 50);
- uiEndBlock(C, block);
return block;
}
@@ -2086,16 +2095,16 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
if (cumap->cm[0].curve) {
- bt = uiDefButI(block, ROW, 0, "X", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
- uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ bt = uiDefButI(block, UI_BTYPE_ROW, 0, "X", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
}
if (cumap->cm[1].curve) {
- bt = uiDefButI(block, ROW, 0, "Y", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
- uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ bt = uiDefButI(block, UI_BTYPE_ROW, 0, "Y", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
}
if (cumap->cm[2].curve) {
- bt = uiDefButI(block, ROW, 0, "Z", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
- uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ bt = uiDefButI(block, UI_BTYPE_ROW, 0, "Z", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
}
}
else if (labeltype == 'c') {
@@ -2104,20 +2113,20 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
if (cumap->cm[3].curve) {
- bt = uiDefButI(block, ROW, 0, "C", 0, 0, dx, dx, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
- uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ bt = uiDefButI(block, UI_BTYPE_ROW, 0, "C", 0, 0, dx, dx, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
}
if (cumap->cm[0].curve) {
- bt = uiDefButI(block, ROW, 0, "R", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
- uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ bt = uiDefButI(block, UI_BTYPE_ROW, 0, "R", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
}
if (cumap->cm[1].curve) {
- bt = uiDefButI(block, ROW, 0, "G", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
- uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ bt = uiDefButI(block, UI_BTYPE_ROW, 0, "G", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
}
if (cumap->cm[2].curve) {
- bt = uiDefButI(block, ROW, 0, "B", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
- uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ bt = uiDefButI(block, UI_BTYPE_ROW, 0, "B", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
}
}
else if (labeltype == 'h') {
@@ -2126,16 +2135,16 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
if (cumap->cm[0].curve) {
- bt = uiDefButI(block, ROW, 0, "H", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
- uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ bt = uiDefButI(block, UI_BTYPE_ROW, 0, "H", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
}
if (cumap->cm[1].curve) {
- bt = uiDefButI(block, ROW, 0, "S", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
- uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ bt = uiDefButI(block, UI_BTYPE_ROW, 0, "S", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
}
if (cumap->cm[2].curve) {
- bt = uiDefButI(block, ROW, 0, "V", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
- uiButSetFunc(bt, curvemap_buttons_redraw, NULL, NULL);
+ bt = uiDefButI(block, UI_BTYPE_ROW, 0, "V", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
}
}
else
@@ -2147,13 +2156,13 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
/* operation buttons */
sub = uiLayoutRow(row, true);
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
- bt = uiDefIconBut(block, BUT, 0, ICON_ZOOMIN, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Zoom in"));
- uiButSetFunc(bt, curvemap_buttons_zoom_in, cumap, NULL);
+ bt = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMIN, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Zoom in"));
+ UI_but_func_set(bt, curvemap_buttons_zoom_in, cumap, NULL);
- bt = uiDefIconBut(block, BUT, 0, ICON_ZOOMOUT, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Zoom out"));
- uiButSetFunc(bt, curvemap_buttons_zoom_out, cumap, NULL);
+ bt = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_ZOOMOUT, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Zoom out"));
+ UI_but_func_set(bt, curvemap_buttons_zoom_out, cumap, NULL);
if (brush)
bt = uiDefIconBlockBut(block, curvemap_brush_tools_func, cumap, 0, ICON_MODIFIER, 0, 0, dx, dx, TIP_("Tools"));
@@ -2164,23 +2173,23 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
bt = uiDefIconBlockBut(block, curvemap_tools_posslope_func, cumap, 0, ICON_MODIFIER,
0, 0, dx, dx, TIP_("Tools"));
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
icon = (cumap->flag & CUMA_DO_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT;
bt = uiDefIconBlockBut(block, curvemap_clipping_func, cumap, 0, icon, 0, 0, dx, dx, TIP_("Clipping Options"));
- uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- bt = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete points"));
- uiButSetNFunc(bt, curvemap_buttons_delete, MEM_dupallocN(cb), cumap);
+ bt = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_X, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete points"));
+ UI_but_funcN_set(bt, curvemap_buttons_delete, MEM_dupallocN(cb), cumap);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
- uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL);
+ UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL);
/* curve itself */
size = uiLayoutGetWidth(layout);
row = uiLayoutRow(layout, false);
- uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, 8.0f * UI_UNIT_X, cumap, 0.0f, 1.0f, bg, 0, "");
+ uiDefBut(block, UI_BTYPE_CURVE, 0, "", 0, 0, size, 8.0f * UI_UNIT_X, cumap, 0.0f, 1.0f, bg, 0, "");
/* sliders for selected point */
for (i = 0; i < cm->totpoint; i++) {
@@ -2202,10 +2211,10 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
}
uiLayoutRow(layout, true);
- uiBlockSetNFunc(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap);
- uiDefButF(block, NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
+ UI_block_funcN_set(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap);
+ uiDefButF(block, UI_BTYPE_NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
&cmp->x, bounds.xmin, bounds.xmax, 1, 5, "");
- uiDefButF(block, NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
+ uiDefButF(block, UI_BTYPE_NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
&cmp->y, bounds.ymin, bounds.ymax, 1, 5, "");
}
@@ -2216,12 +2225,12 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
uiItemR(uiLayoutColumn(split, false), ptr, "white_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
uiLayoutRow(layout, false);
- bt = uiDefBut(block, BUT, 0, IFACE_("Reset"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0,
+ bt = uiDefBut(block, UI_BTYPE_BUT, 0, IFACE_("Reset"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0,
TIP_("Reset Black/White point and curves"));
- uiButSetNFunc(bt, curvemap_buttons_reset, MEM_dupallocN(cb), cumap);
+ UI_but_funcN_set(bt, curvemap_buttons_reset, MEM_dupallocN(cb), cumap);
}
- uiBlockSetNFunc(block, NULL, NULL, NULL);
+ UI_block_funcN_set(block, NULL, NULL, NULL);
}
void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propname, int type,
@@ -2254,11 +2263,11 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propn
cb->prop = prop;
id = cptr.id.data;
- uiBlockSetButLock(block, (id && id->lib), ERROR_LIBDATA_MESSAGE);
+ UI_block_lock_set(block, (id && id->lib), ERROR_LIBDATA_MESSAGE);
curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, cb);
- uiBlockClearButLock(block);
+ UI_block_lock_clear(block);
MEM_freeN(cb);
}
@@ -2275,6 +2284,7 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
uiBlock *block = uiLayoutGetBlock(layout);
uiLayout *col, *row;
uiBut *but = NULL;
+ ColorPicker *cpicker = ui_block_colorpicker_create(block);
float softmin, softmax, step, precision;
if (!prop) {
@@ -2289,15 +2299,15 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
switch (U.color_picker_type) {
case USER_CP_SQUARE_SV:
- but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
+ but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
-1, 0.0, 0.0, UI_GRAD_SV, 0, "");
break;
case USER_CP_SQUARE_HS:
- but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
+ but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
-1, 0.0, 0.0, UI_GRAD_HS, 0, "");
break;
case USER_CP_SQUARE_HV:
- but = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
+ but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
-1, 0.0, 0.0, UI_GRAD_HV, 0, "");
break;
@@ -2305,12 +2315,14 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
case USER_CP_CIRCLE_HSV:
case USER_CP_CIRCLE_HSL:
default:
- but = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
+ but = uiDefButR_prop(block, UI_BTYPE_HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
-1, 0.0, 0.0, 0, 0, "");
break;
}
+ but->custom_data = cpicker;
+
if (lock) {
but->flag |= UI_BUT_COLOR_LOCK;
}
@@ -2330,33 +2342,35 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
switch (U.color_picker_type) {
case USER_CP_CIRCLE_HSL:
uiItemS(row);
- uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop,
- -1, softmin, softmax, UI_GRAD_L_ALT, 0, "");
+ but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop,
+ -1, softmin, softmax, UI_GRAD_L_ALT, 0, "");
break;
case USER_CP_SQUARE_SV:
uiItemS(col);
- uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
- -1, softmin, softmax, UI_GRAD_SV + 3, 0, "");
+ but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
+ -1, softmin, softmax, UI_GRAD_SV + 3, 0, "");
break;
case USER_CP_SQUARE_HS:
uiItemS(col);
- uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
- -1, softmin, softmax, UI_GRAD_HS + 3, 0, "");
+ but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
+ -1, softmin, softmax, UI_GRAD_HS + 3, 0, "");
break;
case USER_CP_SQUARE_HV:
uiItemS(col);
- uiDefButR_prop(block, HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
- -1, softmin, softmax, UI_GRAD_HV + 3, 0, "");
+ but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18, ptr, prop,
+ -1, softmin, softmax, UI_GRAD_HV + 3, 0, "");
break;
/* user default */
case USER_CP_CIRCLE_HSV:
default:
uiItemS(row);
- uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop,
- -1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
+ but = uiDefButR_prop(block, UI_BTYPE_HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14, WHEEL_SIZE, ptr, prop,
+ -1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
break;
}
+
+ but->custom_data = cpicker;
}
}
@@ -2391,8 +2405,8 @@ void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname,
col = uiLayoutColumn(layout, true);
uiLayoutRow(col, true);
- uiDefIconButO(block, BUT, "PALETTE_OT_color_add", WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
- uiDefIconButO(block, BUT, "PALETTE_OT_color_delete", WM_OP_INVOKE_DEFAULT, ICON_ZOOMOUT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+ uiDefIconButO(block, UI_BTYPE_BUT, "PALETTE_OT_color_add", WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+ uiDefIconButO(block, UI_BTYPE_BUT, "PALETTE_OT_color_delete", WM_OP_INVOKE_DEFAULT, ICON_ZOOMOUT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
col = uiLayoutColumn(layout, true);
uiLayoutRow(col, true);
@@ -2406,7 +2420,7 @@ void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname,
}
RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &ptr);
- uiDefButR(block, COLOR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, &ptr, "color", -1, 0.0, 1.0,
+ uiDefButR(block, UI_BTYPE_COLOR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, &ptr, "color", -1, 0.0, 1.0,
UI_PALETTE_COLOR, col_id, "");
row_cols++;
col_id++;
@@ -2502,8 +2516,8 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, const char *propname,
icon = ICON_LAYER_USED;
but = uiDefAutoButR(block, ptr, prop, layer, "", icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2);
- uiButSetFunc(but, handle_layer_buttons, but, SET_INT_IN_POINTER(layer));
- but->type = TOG;
+ UI_but_func_set(but, handle_layer_buttons, but, SET_INT_IN_POINTER(layer));
+ but->type = UI_BTYPE_TOGGLE;
}
}
}
@@ -2569,10 +2583,10 @@ void uiTemplateGameStates(uiLayout *layout, PointerRNA *ptr, const char *propnam
else if (used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, state))
icon = ICON_LAYER_USED;
- but = uiDefIconButR_prop(block, ICONTOG, 0, icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2, ptr, prop,
+ but = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2, ptr, prop,
state, 0, 0, -1, -1, sca_state_name_get(ob, state));
- uiButSetFunc(but, handle_layer_buttons, but, SET_INT_IN_POINTER(state));
- but->type = TOG;
+ UI_but_func_set(but, handle_layer_buttons, but, SET_INT_IN_POINTER(state));
+ but->type = UI_BTYPE_TOGGLE;
}
}
}
@@ -2658,7 +2672,7 @@ static void uilist_filter_items_default(struct uiList *ui_list, struct bContext
names = MEM_callocN(sizeof(StringCmp) * len, "StringCmp");
}
if (filter_raw[0]) {
- size_t idx = 0, slen = strlen(filter_raw);
+ size_t slen = strlen(filter_raw);
dyn_data->items_filter_flags = MEM_callocN(sizeof(int) * len, "items_filter_flags");
dyn_data->items_shown = 0;
@@ -2670,15 +2684,7 @@ static void uilist_filter_items_default(struct uiList *ui_list, struct bContext
else {
filter = filter_dyn = MEM_mallocN((slen + 3) * sizeof(char), "filter_dyn");
}
- if (filter_raw[idx] != '*') {
- filter[idx++] = '*';
- }
- memcpy(filter + idx, filter_raw, slen);
- idx += slen;
- if (filter[idx - 1] != '*') {
- filter[idx++] = '*';
- }
- filter[idx] = '\0';
+ BLI_strncpy_ensure_pad(filter, filter_raw, '*', slen + 3);
}
RNA_PROP_BEGIN (dataptr, itemptr, prop)
@@ -2758,7 +2764,7 @@ typedef struct {
int end_idx; /* Index of last item to display + 1. */
} uiListLayoutdata;
-static void prepare_list(uiList *ui_list, int len, int activei, int rows, int maxrows, int columns,
+static void uilist_prepare(uiList *ui_list, int len, int activei, int rows, int maxrows, int columns,
uiListLayoutdata *layoutdata)
{
uiListDyn *dyn_data = ui_list->dyn_data;
@@ -2812,7 +2818,7 @@ static void prepare_list(uiList *ui_list, int len, int activei, int rows, int ma
layoutdata->end_idx = min_ii(layoutdata->start_idx + rows * columns, len);
}
-static void ui_list_resize_update_cb(bContext *UNUSED(C), void *arg1, void *UNUSED(arg2))
+static void uilist_resize_update_cb(bContext *UNUSED(C), void *arg1, void *UNUSED(arg2))
{
uiList *ui_list = arg1;
uiListDyn *dyn_data = ui_list->dyn_data;
@@ -2827,9 +2833,27 @@ static void ui_list_resize_update_cb(bContext *UNUSED(C), void *arg1, void *UNUS
}
}
+static void *uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *propname)
+{
+ if (propname && propname[0] && itemptr && itemptr->data) {
+ PropertyRNA *prop = RNA_struct_find_property(itemptr, propname);
+
+ if (prop && (RNA_property_type(prop) == PROP_STRING)) {
+ return RNA_property_string_get_alloc(itemptr, prop, NULL, 0, NULL);
+ }
+ }
+ return NULL;
+}
+
+static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip)
+{
+ char *dyn_tooltip = argN;
+ return BLI_sprintfN("%s - %s", tip, dyn_tooltip);
+}
+
void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id,
PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname,
- int rows, int maxrows, int layout_type, int columns)
+ const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns)
{
uiListType *ui_list_type;
uiList *ui_list = NULL;
@@ -2856,7 +2880,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
/* validate arguments */
/* Forbid default UI_UL_DEFAULT_CLASS_NAME list class without a custom list_id! */
- if (!strcmp(UI_UL_DEFAULT_CLASS_NAME, listtype_name) && !(list_id && list_id[0])) {
+ if (STREQ(UI_UL_DEFAULT_CLASS_NAME, listtype_name) && !(list_id && list_id[0])) {
RNA_warning("template_list using default '%s' UIList class must provide a custom list_id",
UI_UL_DEFAULT_CLASS_NAME);
return;
@@ -3037,25 +3061,30 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
col = uiLayoutColumn(row, true);
/* init numbers */
- prepare_list(ui_list, len, activei, rows, maxrows, 1, &layoutdata);
+ uilist_prepare(ui_list, len, activei, rows, maxrows, 1, &layoutdata);
if (dataptr->data && prop) {
/* create list items */
for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) {
PointerRNA *itemptr = &items_ptr[i].item;
+ void *dyntip_data;
int org_i = items_ptr[i].org_idx;
int flt_flag = items_ptr[i].flt_flag;
subblock = uiLayoutGetBlock(col);
overlap = uiLayoutOverlap(col);
- uiBlockSetFlag(subblock, UI_BLOCK_LIST_ITEM);
+ UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM);
/* list item behind label & other buttons */
sub = uiLayoutRow(overlap, false);
- but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
- active_dataptr, activeprop, 0, 0, org_i, 0, 0, TIP_("Double click to rename"));
+ but = uiDefButR_prop(subblock, UI_BTYPE_LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ active_dataptr, activeprop, 0, 0, org_i, 0, 0,
+ TIP_("Double click to rename"));
+ if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr, item_dyntip_propname))) {
+ UI_but_func_tooltip_set(but, uilist_item_tooltip_func, dyntip_data);
+ }
sub = uiLayoutRow(overlap, false);
@@ -3070,7 +3099,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
ui_layout_list_set_labels_active(sub);
}
- uiBlockClearFlag(subblock, UI_BLOCK_LIST_ITEM);
+ UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM);
}
}
@@ -3082,7 +3111,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
/* add scrollbar */
if (len > layoutdata.visual_items) {
col = uiLayoutColumn(row, false);
- uiDefButI(block, SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height,
+ uiDefButI(block, UI_BTYPE_SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height,
&ui_list->list_scroll, 0, dyn_data->height - dyn_data->visual_height,
dyn_data->visual_height, 0, "");
}
@@ -3108,10 +3137,10 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
/* next/prev button */
BLI_snprintf(numstr, sizeof(numstr), "%d :", dyn_data->items_shown);
- but = uiDefIconTextButR_prop(block, NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y,
+ but = uiDefIconTextButR_prop(block, UI_BTYPE_NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y,
active_dataptr, activeprop, 0, 0, 0, 0, 0, "");
if (dyn_data->items_shown == 0)
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
break;
case UILST_LAYOUT_GRID:
box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
@@ -3120,7 +3149,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
col = uiLayoutColumn(row, true);
subrow = NULL; /* Quite gcc warning! */
- prepare_list(ui_list, len, activei, rows, maxrows, columns, &layoutdata);
+ uilist_prepare(ui_list, len, activei, rows, maxrows, columns, &layoutdata);
if (dataptr->data && prop) {
/* create list items */
@@ -3136,14 +3165,14 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
subblock = uiLayoutGetBlock(subrow);
overlap = uiLayoutOverlap(subrow);
- uiBlockSetFlag(subblock, UI_BLOCK_LIST_ITEM);
+ UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM);
/* list item behind label & other buttons */
sub = uiLayoutRow(overlap, false);
- but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
+ but = uiDefButR_prop(subblock, UI_BTYPE_LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
active_dataptr, activeprop, 0, 0, org_i, 0, 0, NULL);
- uiButSetDrawFlag(but, UI_BUT_NO_TOOLTIP);
+ UI_but_drawflag_enable(but, UI_BUT_NO_TOOLTIP);
sub = uiLayoutRow(overlap, false);
@@ -3156,7 +3185,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
ui_layout_list_set_labels_active(sub);
}
- uiBlockClearFlag(subblock, UI_BLOCK_LIST_ITEM);
+ UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM);
}
}
@@ -3171,7 +3200,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
/* add scrollbar */
if (len > layoutdata.visual_items) {
col = uiLayoutColumn(row, false);
- uiDefButI(block, SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height,
+ uiDefButI(block, UI_BTYPE_SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height,
&ui_list->list_scroll, 0, dyn_data->height - dyn_data->visual_height,
dyn_data->visual_height, 0, "");
}
@@ -3179,8 +3208,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
}
if (glob) {
- /* About GRIP drag-resize:
- * We can't directly use results from GRIP button, since we have a rather complex behavior here
+ /* About UI_BTYPE_GRIP drag-resize:
+ * We can't directly use results from a grip button, since we have a rather complex behavior here
* (sizing by discrete steps and, overall, autosize feature).
* Since we *never* know whether we are grip-resizing or not (because there is no callback for when a
* button enters/leaves its "edit mode"), we use the fact that grip-controlled value (dyn_data->resize)
@@ -3193,37 +3222,37 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co
row = uiLayoutRow(glob, true);
subblock = uiLayoutGetBlock(row);
- uiBlockSetEmboss(subblock, UI_EMBOSSN);
+ UI_block_emboss_set(subblock, UI_EMBOSS_NONE);
if (ui_list->filter_flag & UILST_FLT_SHOW) {
- but = uiDefIconButBitI(subblock, TOG, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_DOWN, 0, 0,
+ but = uiDefIconButBitI(subblock, UI_BTYPE_TOGGLE, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_DOWN, 0, 0,
UI_UNIT_X, UI_UNIT_Y * 0.5f, &(ui_list->filter_flag), 0, 0, 0, 0,
TIP_("Hide filtering options"));
- uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
+ UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- but = uiDefIconButI(subblock, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f,
+ but = uiDefIconButI(subblock, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f,
&dyn_data->resize, 0.0, 0.0, 0, 0, "");
- uiButSetFunc(but, ui_list_resize_update_cb, ui_list, NULL);
+ UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL);
- uiBlockSetEmboss(subblock, UI_EMBOSS);
+ UI_block_emboss_set(subblock, UI_EMBOSS);
col = uiLayoutColumn(glob, false);
subblock = uiLayoutGetBlock(col);
- uiDefBut(subblock, SEPR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y * 0.05f, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(subblock, UI_BTYPE_SEPR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y * 0.05f, NULL, 0.0, 0.0, 0, 0, "");
draw_filter(ui_list, C, col);
}
else {
- but = uiDefIconButBitI(subblock, TOG, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_RIGHT, 0, 0,
+ but = uiDefIconButBitI(subblock, UI_BTYPE_TOGGLE, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_RIGHT, 0, 0,
UI_UNIT_X, UI_UNIT_Y * 0.5f, &(ui_list->filter_flag), 0, 0, 0, 0,
TIP_("Show filtering options"));
- uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
+ UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- but = uiDefIconButI(subblock, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f,
+ but = uiDefIconButI(subblock, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f,
&dyn_data->resize, 0.0, 0.0, 0, 0, "");
- uiButSetFunc(but, ui_list_resize_update_cb, ui_list, NULL);
+ UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL);
- uiBlockSetEmboss(subblock, UI_EMBOSS);
+ UI_block_emboss_set(subblock, UI_EMBOSS);
}
}
@@ -3244,10 +3273,10 @@ static void operator_call_cb(bContext *C, void *UNUSED(arg1), void *arg2)
static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
{
- GHashIterator *iter = WM_operatortype_iter();
+ GHashIterator iter;
- for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) {
- wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
+ for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0)
continue;
@@ -3269,17 +3298,16 @@ static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char
}
}
- if (false == uiSearchItemAdd(items, name, ot, 0))
+ if (false == UI_search_item_add(items, name, ot, 0))
break;
}
}
}
- BLI_ghashIterator_free(iter);
}
-void uiOperatorSearch_But(uiBut *but)
+void UI_but_func_operator_search(uiBut *but)
{
- uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
+ UI_but_func_search_set(but, operator_search_cb, NULL, operator_call_cb, NULL);
}
void uiTemplateOperatorSearch(uiLayout *layout)
@@ -3289,10 +3317,10 @@ void uiTemplateOperatorSearch(uiLayout *layout)
static char search[256] = "";
block = uiLayoutGetBlock(layout);
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, 0, "");
- uiOperatorSearch_But(but);
+ UI_but_func_operator_search(but);
}
/************************* Running Jobs Template **************************/
@@ -3342,9 +3370,9 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
int handle_event;
block = uiLayoutGetBlock(layout);
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
- uiBlockSetHandleFunc(block, do_running_jobs, NULL);
+ UI_block_func_handle_set(block, do_running_jobs, NULL);
if (sa->spacetype == SPACE_SEQ) {
if (WM_jobs_test(wm, sa, WM_JOB_TYPE_ANY))
@@ -3394,18 +3422,18 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
ui_abs = uiLayoutAbsolute(layout, false);
(void)ui_abs; /* UNUSED */
- uiDefIconBut(block, BUT, handle_event, ICON_PANEL_CLOSE, 0, UI_UNIT_Y * 0.1, UI_UNIT_X * 0.8, UI_UNIT_Y * 0.8,
+ uiDefIconBut(block, UI_BTYPE_BUT, handle_event, ICON_PANEL_CLOSE, 0, UI_UNIT_Y * 0.1, UI_UNIT_X * 0.8, UI_UNIT_Y * 0.8,
NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop this job"));
- uiDefBut(block, PROGRESSBAR, 0, WM_jobs_name(wm, owner),
+ uiDefBut(block, UI_BTYPE_PROGRESS_BAR, 0, WM_jobs_name(wm, owner),
UI_UNIT_X, 0, UI_UNIT_X * 5.0f, UI_UNIT_Y, NULL, 0.0f, 0.0f, WM_jobs_progress(wm, owner), 0, TIP_("Progress"));
uiLayoutRow(layout, false);
}
if (WM_jobs_test(wm, screen, WM_JOB_TYPE_SCREENCAST))
- uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, IFACE_("Capture"), 0, 0, UI_UNIT_X * 4.25f, UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT, B_STOPCAST, ICON_CANCEL, IFACE_("Capture"), 0, 0, UI_UNIT_X * 4.25f, UI_UNIT_Y,
NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop screencast"));
if (screen->animtimer)
- uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, IFACE_("Anim Player"), 0, 0, UI_UNIT_X * 5.0f, UI_UNIT_Y,
+ uiDefIconTextBut(block, UI_BTYPE_BUT, B_STOPANIM, ICON_CANCEL, IFACE_("Anim Player"), 0, 0, UI_UNIT_X * 5.0f, UI_UNIT_Y,
NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop animation playback"));
}
@@ -3420,7 +3448,7 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
uiLayout *ui_abs;
uiBlock *block;
uiBut *but;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
int width;
int icon;
@@ -3439,37 +3467,37 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
width = max_ii(width, 10);
/* make a box around the report to make it stand out */
- uiBlockBeginAlign(block);
- but = uiDefBut(block, ROUNDBOX, 0, "", 0, 0, UI_UNIT_X + 10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
- /* set the report's bg color in but->col - ROUNDBOX feature */
+ UI_block_align_begin(block);
+ but = uiDefBut(block, UI_BTYPE_ROUNDBOX, 0, "", 0, 0, UI_UNIT_X + 10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
+ /* set the report's bg color in but->col - UI_BTYPE_ROUNDBOX feature */
rgb_float_to_uchar(but->col, rti->col);
but->col[3] = 255;
- but = uiDefBut(block, ROUNDBOX, 0, "", UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y,
+ but = uiDefBut(block, UI_BTYPE_ROUNDBOX, 0, "", UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y,
NULL, 0.0f, 0.0f, 0, 0, "");
but->col[0] = but->col[1] = but->col[2] = FTOCHAR(rti->grayscale);
but->col[3] = 255;
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
/* icon and report message on top */
- icon = uiIconFromReportType(report->type);
+ icon = UI_icon_from_report_type(report->type);
/* XXX: temporary operator to dump all reports to a text block, but only if more than 1 report
* to be shown instead of icon when appropriate...
*/
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
if (reports->list.first != reports->list.last)
- uiDefIconButO(block, BUT, "UI_OT_reports_to_textblock", WM_OP_INVOKE_REGION_WIN, icon, 2, 0, UI_UNIT_X,
+ uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_reports_to_textblock", WM_OP_INVOKE_REGION_WIN, icon, 2, 0, UI_UNIT_X,
UI_UNIT_Y, TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
else
- uiDefIconBut(block, LABEL, 0, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
+ uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
- uiDefBut(block, LABEL, 0, report->message, UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y,
+ uiDefBut(block, UI_BTYPE_LABEL, 0, report->message, UI_UNIT_X + 10, 0, UI_UNIT_X + width, UI_UNIT_Y,
NULL, 0.0f, 0.0f, 0, 0, "");
}
@@ -3518,11 +3546,11 @@ static void template_keymap_item_properties(uiLayout *layout, const char *title,
if (is_set) {
/* unset operator */
uiBlock *block = uiLayoutGetBlock(row);
- uiBlockSetEmboss(block, UI_EMBOSSN);
- but = uiDefIconButO(block, BUT, "UI_OT_unset_property_button", WM_OP_EXEC_DEFAULT, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ but = uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_unset_property_button", WM_OP_EXEC_DEFAULT, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
but->rnapoin = *ptr;
but->rnaprop = prop;
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
}
RNA_STRUCT_END;
@@ -3542,7 +3570,7 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr)
for (; but; but = but->next) {
/* operator buttons may store props for use (file selector, [#36492]) */
if (but->rnaprop) {
- uiButSetFunc(but, keymap_item_modified, ptr->data, NULL);
+ UI_but_func_set(but, keymap_item_modified, ptr->data, NULL);
}
}
}
@@ -3565,8 +3593,7 @@ void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char
colorspace_settings_ptr = RNA_property_pointer_get(ptr, prop);
- uiItemL(layout, IFACE_("Input Color Space:"), ICON_NONE);
- uiItemR(layout, &colorspace_settings_ptr, "name", 0, "", ICON_NONE);
+ uiItemR(layout, &colorspace_settings_ptr, "name", 0, IFACE_("Color Space"), ICON_NONE);
}
void uiTemplateColormanagedViewSettings(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr, const char *propname)
@@ -3617,15 +3644,15 @@ static uiBlock *component_menu(bContext *C, ARegion *ar, void *args_v)
uiBlock *block;
uiLayout *layout;
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
- uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN);
- layout = uiLayoutColumn(uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, UI_GetStyle()), 0);
+ layout = uiLayoutColumn(UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, UI_style_get()), 0);
uiItemR(layout, &args->ptr, args->propname, UI_ITEM_R_EXPAND, "", ICON_NONE);
- uiBoundsBlock(block, 6);
- uiBlockSetDirection(block, UI_DOWN);
+ UI_block_bounds_set_normal(block, 6);
+ UI_block_direction_set(block, UI_DIR_DOWN);
return block;
}
@@ -3639,7 +3666,7 @@ void uiTemplateComponentMenu(uiLayout *layout, PointerRNA *ptr, const char *prop
BLI_strncpy(args->propname, propname, sizeof(args->propname));
block = uiLayoutGetBlock(layout);
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
but = uiDefBlockButN(block, component_menu, args, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, "");
/* set rna directly, uiDefBlockButN doesn't do this */
@@ -3647,7 +3674,7 @@ void uiTemplateComponentMenu(uiLayout *layout, PointerRNA *ptr, const char *prop
but->rnaprop = RNA_struct_find_property(ptr, propname);
but->rnaindex = 0;
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
}
/************************* Node Socket Icon **************************/
@@ -3658,14 +3685,14 @@ void uiTemplateNodeSocket(uiLayout *layout, bContext *UNUSED(C), float *color)
uiBut *but;
block = uiLayoutGetBlock(layout);
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
/* XXX using explicit socket colors is not quite ideal.
* Eventually it should be possible to use theme colors for this purpose,
* but this requires a better design for extendable color palettes in user prefs.
*/
- but = uiDefBut(block, NODESOCKET, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ but = uiDefBut(block, UI_BTYPE_NODE_SOCKET, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
rgba_float_to_uchar(but->col, color);
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
}
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 008ea84b607..28bd637ae59 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -70,11 +70,11 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
return NULL;
if (icon && name && name[0] == '\0')
- but = uiDefIconButR_prop(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else if (icon)
- but = uiDefIconTextButR_prop(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefIconTextButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else
- but = uiDefButR_prop(block, OPTION, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefButR_prop(block, UI_BTYPE_CHECKBOX, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
break;
}
case PROP_INT:
@@ -83,30 +83,42 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
int arraylen = RNA_property_array_length(ptr, prop);
if (arraylen && index == -1) {
- if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA))
- but = uiDefButR_prop(block, COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL);
+ if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) {
+ but = uiDefButR_prop(block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL);
+ }
+ else {
+ return NULL;
+ }
}
else if (RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR)
- but = uiDefButR_prop(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else
- but = uiDefButR_prop(block, NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefButR_prop(block, UI_BTYPE_NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+
+ if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
+ UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
+ }
break;
}
case PROP_ENUM:
if (icon && name && name[0] == '\0')
- but = uiDefIconButR_prop(block, MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefIconButR_prop(block, UI_BTYPE_MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else if (icon)
- but = uiDefIconTextButR_prop(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefIconTextButR_prop(block, UI_BTYPE_MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else
- but = uiDefButR_prop(block, MENU, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefButR_prop(block, UI_BTYPE_MENU, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
break;
case PROP_STRING:
if (icon && name && name[0] == '\0')
- but = uiDefIconButR_prop(block, TEX, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefIconButR_prop(block, UI_BTYPE_TEXT, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else if (icon)
- but = uiDefIconTextButR_prop(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefIconTextButR_prop(block, UI_BTYPE_TEXT, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else
- but = uiDefButR_prop(block, TEX, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefButR_prop(block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+
+ if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
+ UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
+ }
break;
case PROP_POINTER:
{
@@ -119,15 +131,15 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
if (icon == ICON_DOT)
icon = 0;
- but = uiDefIconTextButR_prop(block, SEARCH_MENU, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ but = uiDefIconTextButR_prop(block, UI_BTYPE_SEARCH_MENU, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
break;
}
case PROP_COLLECTION:
{
char text[256];
BLI_snprintf(text, sizeof(text), IFACE_("%d items"), RNA_property_collection_length(ptr, prop));
- but = uiDefBut(block, LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
- uiButSetFlag(but, UI_BUT_DISABLED);
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
break;
}
default:
@@ -201,7 +213,7 @@ int uiDefAutoButsRNA(uiLayout *layout, PointerRNA *ptr,
/***************************** ID Utilities *******************************/
-int uiIconFromID(ID *id)
+int UI_icon_from_id(ID *id)
{
Object *ob;
PointerRNA ptr;
@@ -219,7 +231,7 @@ int uiIconFromID(ID *id)
if (ob->type == OB_EMPTY)
return ICON_EMPTY_DATA;
else
- return uiIconFromID(ob->data);
+ return UI_icon_from_id(ob->data);
}
/* otherwise get it through RNA, creating the pointer
@@ -230,7 +242,7 @@ int uiIconFromID(ID *id)
}
/* see: report_type_str */
-int uiIconFromReportType(int type)
+int UI_icon_from_report_type(int type)
{
if (type & RPT_ERROR_ALL)
return ICON_ERROR;
@@ -247,7 +259,7 @@ int uiIconFromReportType(int type)
/**
* Returns the best "UI" precision for given floating value, so that e.g. 10.000001 rather gets drawn as '10'...
*/
-int uiFloatPrecisionCalc(int prec, double value)
+int UI_calc_float_precision(int prec, double value)
{
static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7};
static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */
@@ -390,6 +402,27 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p)
}
/**
+ * Update the pointer for a registered button.
+ */
+bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src)
+{
+ uiButStore *bs_handle;
+ bool found = false;
+
+ for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
+ uiButStoreElem *bs_elem;
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ if (*bs_elem->but_p == but_src) {
+ *bs_elem->but_p = but_dst;
+ found = true;
+ }
+ }
+ }
+
+ return found;
+}
+
+/**
* NULL all pointers, don't free since the owner needs to be able to inspect.
*/
void UI_butstore_clear(uiBlock *block)
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index b7e61400cfa..91186a14b49 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -59,6 +59,10 @@
#include "interface_intern.h"
+#ifdef WITH_INPUT_IME
+# include "WM_types.h"
+#endif
+
/* icons are 80% of height of button (16 pixels inside 20 height) */
#define ICON_SIZE_FROM_BUTRECT(rect) (0.8f * BLI_rcti_size_y(rect))
@@ -222,7 +226,7 @@ void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float m
for (j = 0; j < WIDGET_AA_JITTER; j++) {
glTranslatef(jit[j][0], jit[j][1], 0.0f);
- uiDrawBox(mode, minx, miny, maxx, maxy, rad);
+ UI_draw_roundbox_gl_mode(mode, minx, miny, maxx, maxy, rad);
glTranslatef(-jit[j][0], -jit[j][1], 0.0f);
}
@@ -606,36 +610,36 @@ static void round_box_shade_col4_r(unsigned char r_col[4], const char col1[4], c
r_col[3] = (faci * col1[3] + facm * col2[3]) >> 8;
}
-static void widget_verts_to_quad_strip(uiWidgetBase *wtb, const int totvert, float quad_strip[WIDGET_SIZE_MAX * 2 + 2][2])
+static void widget_verts_to_triangle_strip(uiWidgetBase *wtb, const int totvert, float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2])
{
int a;
for (a = 0; a < totvert; a++) {
- copy_v2_v2(quad_strip[a * 2], wtb->outer_v[a]);
- copy_v2_v2(quad_strip[a * 2 + 1], wtb->inner_v[a]);
+ copy_v2_v2(triangle_strip[a * 2], wtb->outer_v[a]);
+ copy_v2_v2(triangle_strip[a * 2 + 1], wtb->inner_v[a]);
}
- copy_v2_v2(quad_strip[a * 2], wtb->outer_v[0]);
- copy_v2_v2(quad_strip[a * 2 + 1], wtb->inner_v[0]);
+ copy_v2_v2(triangle_strip[a * 2], wtb->outer_v[0]);
+ copy_v2_v2(triangle_strip[a * 2 + 1], wtb->inner_v[0]);
}
-static void widget_verts_to_quad_strip_open(uiWidgetBase *wtb, const int totvert, float quad_strip[WIDGET_SIZE_MAX * 2][2])
+static void widget_verts_to_triangle_strip_open(uiWidgetBase *wtb, const int totvert, float triangle_strip[WIDGET_SIZE_MAX * 2][2])
{
int a;
for (a = 0; a < totvert; a++) {
- quad_strip[a * 2][0] = wtb->outer_v[a][0];
- quad_strip[a * 2][1] = wtb->outer_v[a][1];
- quad_strip[a * 2 + 1][0] = wtb->outer_v[a][0];
- quad_strip[a * 2 + 1][1] = wtb->outer_v[a][1] - 1.0f;
+ triangle_strip[a * 2][0] = wtb->outer_v[a][0];
+ triangle_strip[a * 2][1] = wtb->outer_v[a][1];
+ triangle_strip[a * 2 + 1][0] = wtb->outer_v[a][0];
+ triangle_strip[a * 2 + 1][1] = wtb->outer_v[a][1] - 1.0f;
}
}
static void widgetbase_outline(uiWidgetBase *wtb)
{
- float quad_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */
- widget_verts_to_quad_strip(wtb, wtb->totvert, quad_strip);
+ float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */
+ widget_verts_to_triangle_strip(wtb, wtb->totvert, triangle_strip);
glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, quad_strip);
- glDrawArrays(GL_QUAD_STRIP, 0, wtb->totvert * 2 + 2);
+ glVertexPointer(2, GL_FLOAT, 0, triangle_strip);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, wtb->totvert * 2 + 2);
glDisableClientState(GL_VERTEX_ARRAY);
}
@@ -729,37 +733,42 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
/* for each AA step */
if (wtb->outline) {
- float quad_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */
- float quad_strip_emboss[WIDGET_SIZE_MAX * 2][2]; /* only for emboss */
+ float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */
+ float triangle_strip_emboss[WIDGET_SIZE_MAX * 2][2]; /* only for emboss */
const unsigned char tcol[4] = {wcol->outline[0],
wcol->outline[1],
wcol->outline[2],
wcol->outline[3] / WIDGET_AA_JITTER};
- widget_verts_to_quad_strip(wtb, wtb->totvert, quad_strip);
+ widget_verts_to_triangle_strip(wtb, wtb->totvert, triangle_strip);
if (wtb->emboss) {
- widget_verts_to_quad_strip_open(wtb, wtb->halfwayvert, quad_strip_emboss);
+ widget_verts_to_triangle_strip_open(wtb, wtb->halfwayvert, triangle_strip_emboss);
}
glEnableClientState(GL_VERTEX_ARRAY);
for (j = 0; j < WIDGET_AA_JITTER; j++) {
+ unsigned char emboss[4];
+
glTranslatef(jit[j][0], jit[j][1], 0.0f);
/* outline */
glColor4ubv(tcol);
- glVertexPointer(2, GL_FLOAT, 0, quad_strip);
- glDrawArrays(GL_QUAD_STRIP, 0, wtb->totvert * 2 + 2);
-
+ glVertexPointer(2, GL_FLOAT, 0, triangle_strip);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, wtb->totvert * 2 + 2);
+
/* emboss bottom shadow */
if (wtb->emboss) {
- glColor4f(1.0f, 1.0f, 1.0f, 0.02f);
+ UI_GetThemeColor4ubv(TH_WIDGET_EMBOSS, emboss);
- glVertexPointer(2, GL_FLOAT, 0, quad_strip_emboss);
- glDrawArrays(GL_QUAD_STRIP, 0, wtb->halfwayvert * 2);
+ if (emboss[3]) {
+ glColor4ubv(emboss);
+ glVertexPointer(2, GL_FLOAT, 0, triangle_strip_emboss);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, wtb->halfwayvert * 2);
+ }
}
glTranslatef(-jit[j][0], -jit[j][1], 0.0f);
@@ -824,7 +833,7 @@ static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), const rcti
static int ui_but_draw_menu_icon(const uiBut *but)
{
- return (but->flag & UI_ICON_SUBMENU) && (but->dt == UI_EMBOSSP);
+ return (but->flag & UI_BUT_ICON_SUBMENU) && (but->dt == UI_EMBOSS_PULLDOWN);
}
/* icons have been standardized... and this call draws in untransformed coordinates */
@@ -835,7 +844,7 @@ static void widget_draw_icon(const uiBut *but, BIFIconID icon, float alpha, cons
float xs = 0.0f, ys = 0.0f;
float aspect, height;
- if (but->flag & UI_ICON_PREVIEW) {
+ if (but->flag & UI_BUT_ICON_PREVIEW) {
glEnable(GL_BLEND);
widget_draw_preview(icon, alpha, rect);
glDisable(GL_BLEND);
@@ -843,20 +852,20 @@ static void widget_draw_icon(const uiBut *but, BIFIconID icon, float alpha, cons
}
/* this icon doesn't need draw... */
- if (icon == ICON_BLANK1 && (but->flag & UI_ICON_SUBMENU) == 0) return;
+ if (icon == ICON_BLANK1 && (but->flag & UI_BUT_ICON_SUBMENU) == 0) return;
aspect = but->block->aspect / UI_DPI_FAC;
height = ICON_DEFAULT_HEIGHT / aspect;
/* calculate blend color */
- if (ELEM(but->type, TOG, ROW, TOGN, LISTROW)) {
+ if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_ROW, UI_BTYPE_TOGGLE_N, UI_BTYPE_LISTROW)) {
if (but->flag & UI_SELECT) {}
else if (but->flag & UI_ACTIVE) {}
else alpha = 0.5f;
}
/* extra feature allows more alpha blending */
- if ((but->type == LABEL) && but->a1 == 1.0f)
+ if ((but->type == UI_BTYPE_LABEL) && but->a1 == 1.0f)
alpha *= but->a2;
glEnable(GL_BLEND);
@@ -866,7 +875,7 @@ static void widget_draw_icon(const uiBut *but, BIFIconID icon, float alpha, cons
if (but->drawflag & UI_BUT_ICON_LEFT) {
if (but->block->flag & UI_BLOCK_LOOP) {
- if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK))
+ if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK))
xs = rect->xmin + 4.0f * ofs;
else
xs = rect->xmin + ofs;
@@ -967,7 +976,7 @@ static float ui_text_clip_middle_ex(uiFontStyle *fstyle, char *str, float okwidt
BLI_assert(str[0]);
/* need to set this first */
- uiStyleFontSet(fstyle);
+ UI_fontstyle_set(fstyle);
if (fstyle->kerning == 1) { /* for BLF_width */
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
@@ -1065,7 +1074,7 @@ static float ui_text_clip_middle_ex(uiFontStyle *fstyle, char *str, float okwidt
static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
/* No margin for labels! */
- const int border = ELEM(but->type, LABEL, MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
+ const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0);
const size_t max_len = sizeof(but->drawstr);
const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f;
@@ -1081,7 +1090,7 @@ static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rec
static void ui_text_clip_middle_protect_right(uiFontStyle *fstyle, uiBut *but, const rcti *rect, const char *rsep)
{
/* No margin for labels! */
- const int border = ELEM(but->type, LABEL, MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
+ const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0);
const size_t max_len = sizeof(but->drawstr);
const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f;
@@ -1101,7 +1110,7 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rec
BLI_assert(but->editstr && but->pos >= 0);
/* need to set this first */
- uiStyleFontSet(fstyle);
+ UI_fontstyle_set(fstyle);
if (fstyle->kerning == 1) /* for BLF_width */
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
@@ -1164,7 +1173,7 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti
const char *cpend = but->drawstr + drawstr_len;
/* need to set this first */
- uiStyleFontSet(fstyle);
+ UI_fontstyle_set(fstyle);
if (fstyle->kerning == 1) /* for BLF_width */
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
@@ -1226,6 +1235,50 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti
BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
}
+#ifdef WITH_INPUT_IME
+static void widget_draw_text_ime_underline(
+ uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, const rcti *rect,
+ const wmIMEData *ime_data, const char *drawstr)
+{
+ int ofs_x, width;
+ int rect_x = BLI_rcti_size_x(rect);
+ int sel_start = ime_data->sel_start, sel_end = ime_data->sel_end;
+
+ if (drawstr[0] != 0) {
+ if (but->pos >= but->ofs) {
+ ofs_x = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->pos - but->ofs);
+ }
+ else {
+ ofs_x = 0;
+ }
+
+ width = BLF_width(fstyle->uifont_id, drawstr + but->ofs,
+ ime_data->composite_len + but->pos - but->ofs);
+
+ glColor4ubv((unsigned char *)wcol->text);
+ UI_draw_text_underline(rect->xmin + ofs_x, rect->ymin + 6 * U.pixelsize, min_ii(width, rect_x - 2) - ofs_x, 1);
+
+ /* draw the thick line */
+ if (sel_start != -1 && sel_end != -1) {
+ sel_end -= sel_start;
+ sel_start += but->pos;
+
+ if (sel_start >= but->ofs) {
+ ofs_x = BLF_width(fstyle->uifont_id, drawstr + but->ofs, sel_start - but->ofs);
+ }
+ else {
+ ofs_x = 0;
+ }
+
+ width = BLF_width(fstyle->uifont_id, drawstr + but->ofs,
+ sel_end + sel_start - but->ofs);
+
+ UI_draw_text_underline(rect->xmin + ofs_x, rect->ymin + 6 * U.pixelsize, min_ii(width, rect_x - 2) - ofs_x, 2);
+ }
+ }
+}
+#endif /* WITH_INPUT_IME */
+
static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect)
{
int drawstr_left_len = UI_MAX_DRAW_STR;
@@ -1233,7 +1286,11 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
const char *drawstr_right = NULL;
bool use_right_only = false;
- uiStyleFontSet(fstyle);
+#ifdef WITH_INPUT_IME
+ const wmIMEData *ime_data;
+#endif
+
+ UI_fontstyle_set(fstyle);
if (but->editstr || (but->drawflag & UI_BUT_TEXT_LEFT))
fstyle->align = UI_STYLE_TEXT_LEFT;
@@ -1249,7 +1306,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
/* Special case: when we're entering text for multiple buttons,
* don't draw the text for any of the multi-editing buttons */
if (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI)) {
- uiBut *but_edit = ui_get_but_drag_multi_edit(but);
+ uiBut *but_edit = ui_but_drag_multi_edit_get(but);
if (but_edit) {
drawstr = but_edit->editstr;
fstyle->align = UI_STYLE_TEXT_LEFT;
@@ -1260,13 +1317,30 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
/* max length isn't used in this case,
* we rely on string being NULL terminated. */
drawstr_left_len = INT_MAX;
- drawstr = but->editstr;
+
+#ifdef WITH_INPUT_IME
+ /* FIXME, IME is modifying 'const char *drawstr! */
+ ime_data = ui_but_get_ime_data(but);
+
+ if (ime_data && ime_data->composite_len) {
+ /* insert composite string into cursor pos */
+ BLI_snprintf((char *)drawstr, UI_MAX_DRAW_STR, "%s%s%s",
+ but->editstr, ime_data->str_composite,
+ but->editstr + but->pos);
+ }
+ else
+#endif
+ {
+ drawstr = but->editstr;
+ }
}
}
- /* text button selection and cursor */
+ /* text button selection, cursor, composite underline */
if (but->editstr && but->pos != -1) {
+ int but_pos_ofs;
+ int tx, ty;
/* text button selection */
if ((but->selend - but->selsta) > 0) {
@@ -1292,18 +1366,44 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
}
/* text cursor */
+ but_pos_ofs = but->pos;
+
+#ifdef WITH_INPUT_IME
+ /* if is ime compositing, move the cursor */
+ if (ime_data && ime_data->composite_len && ime_data->cursor_pos != -1) {
+ but_pos_ofs += ime_data->cursor_pos;
+ }
+#endif
+
if (but->pos >= but->ofs) {
int t;
if (drawstr[0] != 0) {
- t = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->pos - but->ofs);
+ t = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but_pos_ofs - but->ofs);
}
else {
t = 0;
}
glColor3f(0.20, 0.6, 0.9);
- glRecti(rect->xmin + t, rect->ymin + 2, rect->xmin + t + 2, rect->ymax - 2);
+
+ tx = rect->xmin + t + 2;
+ ty = rect->ymin + 2;
+
+ /* draw cursor */
+ glRecti(rect->xmin + t, ty, tx, rect->ymax - 2);
}
+
+#ifdef WITH_INPUT_IME
+ if (ime_data && ime_data->composite_len) {
+ /* ime cursor following */
+ if (but->pos >= but->ofs) {
+ ui_but_ime_reposition(but, tx + 5, ty + 3, false);
+ }
+
+ /* composite underline */
+ widget_draw_text_ime_underline(fstyle, wcol, but, rect, ime_data, drawstr);
+ }
+#endif
}
if (fstyle->kerning == 1)
@@ -1328,7 +1428,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
}
#ifdef USE_NUMBUTS_LR_ALIGN
- if (!drawstr_right && ELEM(but->type, NUM, NUMSLI) &&
+ if (!drawstr_right && ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) &&
/* if we're editing or multi-drag (fake editing), then use left alignment */
(but->editstr == NULL) && (drawstr == but->drawstr))
{
@@ -1355,7 +1455,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
/* for underline drawing */
float font_xofs, font_yofs;
- uiStyleFontDrawExt(fstyle, rect, drawstr + but->ofs,
+ UI_fontstyle_draw_ex(fstyle, rect, drawstr + but->ofs,
drawstr_left_len - but->ofs, &font_xofs, &font_yofs);
if (but->menu_key != '\0') {
@@ -1395,7 +1495,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
if (drawstr_right) {
fstyle->align = UI_STYLE_TEXT_RIGHT;
rect->xmax -= UI_TEXT_CLIP_MARGIN;
- uiStyleFontDraw(fstyle, rect, drawstr_right);
+ UI_fontstyle_draw(fstyle, rect, drawstr_right);
}
}
@@ -1406,10 +1506,10 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
float alpha = (float)wcol->text[3] / 255.0f;
char password_str[UI_MAX_DRAW_STR];
- ui_button_text_password_hide(password_str, but, false);
+ ui_but_text_password_hide(password_str, but, false);
/* check for button text label */
- if (but->type == MENU && (but->flag & UI_BUT_NODE_LINK)) {
+ if (but->type == UI_BTYPE_MENU && (but->flag & UI_BUT_NODE_LINK)) {
rcti temp = *rect;
temp.xmin = rect->xmax - BLI_rcti_size_y(rect) - 1;
widget_draw_icon(but, ICON_LAYER_USED, alpha, &temp, false);
@@ -1444,7 +1544,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
}
/* unlink icon for this button type */
- if ((but->type == SEARCH_MENU_UNLINK) && ui_is_but_search_unlink_visible(but)) {
+ if ((but->type == UI_BTYPE_SEARCH_MENU_UNLINK) && ui_but_is_search_unlink_visible(but)) {
rcti temp = *rect;
temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f);
@@ -1461,10 +1561,10 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
but->ofs = 0;
but->strwidth = 0;
}
- else if (ELEM(but->type, NUM, NUMSLI)) {
+ else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {
ui_text_clip_right_label(fstyle, but, rect);
}
- else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) {
+ else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == UI_BTYPE_BUT)) {
/* Clip middle, but protect in all case right part containing the shortcut, if any. */
ui_text_clip_middle_protect_right(fstyle, but, rect, "|");
}
@@ -1475,7 +1575,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
/* always draw text for textbutton cursor */
widget_draw_text(fstyle, wcol, but, rect);
- ui_button_text_password_hide(password_str, but, true);
+ ui_but_text_password_hide(password_str, but, true);
}
#undef UI_TEXT_CLIP_MARGIN
@@ -1808,6 +1908,23 @@ static void widget_state_blend(char cp[3], const char cpstate[3], const float fa
}
}
+/* put all widget colors on half alpha, use local storage */
+static void ui_widget_color_disabled(uiWidgetType *wt)
+{
+ static uiWidgetColors wcol_theme_s;
+
+ wcol_theme_s = *wt->wcol_theme;
+
+ wcol_theme_s.outline[3] *= 0.5;
+ wcol_theme_s.inner[3] *= 0.5;
+ wcol_theme_s.inner_sel[3] *= 0.5;
+ wcol_theme_s.item[3] *= 0.5;
+ wcol_theme_s.text[3] *= 0.5;
+ wcol_theme_s.text_sel[3] *= 0.5;
+
+ wt->wcol_theme = &wcol_theme_s;
+}
+
/* copy colors from theme, and set changes in it based on state */
static void widget_state(uiWidgetType *wt, int state)
{
@@ -1817,6 +1934,10 @@ static void widget_state(uiWidgetType *wt, int state)
/* Override default widget's colors. */
bTheme *btheme = UI_GetTheme();
wt->wcol_theme = &btheme->tui.wcol_list_item;
+
+ if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+ ui_widget_color_disabled(wt);
+ }
}
wt->wcol = *(wt->wcol_theme);
@@ -1998,7 +2119,7 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r
rcti rect1 = *rect;
float alphastep;
int step, totvert;
- float quad_strip[WIDGET_SIZE_MAX * 2 + 2][2];
+ float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2];
const float radout = UI_ThemeMenuShadowWidth();
/* disabled shadow */
@@ -2026,10 +2147,10 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r
glColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac));
- widget_verts_to_quad_strip(&wtb, totvert, quad_strip);
+ widget_verts_to_triangle_strip(&wtb, totvert, triangle_strip);
- glVertexPointer(2, GL_FLOAT, 0, quad_strip);
- glDrawArrays(GL_QUAD_STRIP, 0, totvert * 2); /* add + 2 for getting a complete soft rect. Now it skips top edge to allow transparent menus */
+ glVertexPointer(2, GL_FLOAT, 0, triangle_strip);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, totvert * 2); /* add + 2 for getting a complete soft rect. Now it skips top edge to allow transparent menus */
}
glDisableClientState(GL_VERTEX_ARRAY);
@@ -2047,11 +2168,11 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
//rect->ymin -= 4.0;
//rect->ymax += 4.0;
}
- else if (direction == UI_DOWN) {
+ else if (direction == UI_DIR_DOWN) {
roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
rect->ymin -= 0.1f * U.widget_unit;
}
- else if (direction == UI_TOP) {
+ else if (direction == UI_DIR_UP) {
roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
rect->ymax += 0.1f * U.widget_unit;
}
@@ -2110,10 +2231,10 @@ void ui_hsvcircle_pos_from_vals(uiBut *but, const rcti *rect, float *hsv, float
float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
float ang, radius_t;
- ang = 2.0f * (float)M_PI * hsv[0] + 0.5f * (float)M_PI;
+ ang = 2.0f * (float)M_PI * hsv[0] + (float)M_PI_2;
if ((but->flag & UI_BUT_COLOR_CUBIC) && (U.color_picker_type == USER_CP_CIRCLE_HSV))
- radius_t = (1.0f - powf(1.0f - hsv[1], 3.0f));
+ radius_t = (1.0f - pow3f(1.0f - hsv[1]));
else
radius_t = hsv[1];
@@ -2131,14 +2252,15 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
/* gouraud triangle fan */
- const float *hsv_ptr = ui_block_hsv_get(but->block);
+ ColorPicker *cpicker = but->custom_data;
+ const float *hsv_ptr = cpicker->color_data;
float xpos, ypos, ang = 0.0f;
float rgb[3], hsvo[3], hsv[3], col[3], colcent[3];
int a;
- bool color_profile = ui_color_picker_use_display_colorspace(but);
+ bool color_profile = ui_but_is_colorpicker_display_space(but);
/* color */
- ui_get_but_vectorf(but, rgb);
+ ui_but_v3_get(but, rgb);
/* since we use compat functions on both 'hsv' and 'hsvo', they need to be initialized */
hsvo[0] = hsv[0] = hsv_ptr[0];
@@ -2146,7 +2268,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
hsvo[2] = hsv[2] = hsv_ptr[2];
if (color_profile)
- ui_block_to_display_space_v3(but->block, rgb);
+ ui_block_cm_to_display_space_v3(but->block, rgb);
ui_rgb_to_color_picker_compat_v(rgb, hsv);
copy_v3_v3(hsvo, hsv);
@@ -2347,7 +2469,7 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons
}
-bool ui_color_picker_use_display_colorspace(uiBut *but)
+bool ui_but_is_colorpicker_display_space(uiBut *but)
{
bool color_profile = but->block->color_profile;
@@ -2398,16 +2520,17 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
{
float rgb[3];
float x = 0.0f, y = 0.0f;
- const float *hsv = ui_block_hsv_get(but->block);
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
float hsv_n[3];
- bool use_display_colorspace = ui_color_picker_use_display_colorspace(but);
+ bool use_display_colorspace = ui_but_is_colorpicker_display_space(but);
copy_v3_v3(hsv_n, hsv);
- ui_get_but_vectorf(but, rgb);
+ ui_but_v3_get(but, rgb);
if (use_display_colorspace)
- ui_block_to_display_space_v3(but->block, rgb);
+ ui_block_cm_to_display_space_v3(but->block, rgb);
rgb_to_hsv_compat_v(rgb, hsv_n);
@@ -2436,10 +2559,10 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
color_profile = false;
- ui_get_but_vectorf(but, rgb);
+ ui_but_v3_get(but, rgb);
if (color_profile)
- ui_block_to_display_space_v3(but->block, rgb);
+ ui_block_cm_to_display_space_v3(but->block, rgb);
if (but->a1 == UI_GRAD_L_ALT)
rgb_to_hsl_v(rgb, hsv);
@@ -2585,7 +2708,7 @@ void ui_draw_link_bezier(const rcti *rect)
}
/* function in use for buttons and for view2d sliders */
-void uiWidgetScrollDraw(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state)
+void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state)
{
uiWidgetBase wtb;
int horizontal;
@@ -2671,7 +2794,7 @@ static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
int horizontal;
/* calculate slider part */
- value = ui_get_but_val(but);
+ value = ui_but_value_get(but);
size = (but->softmax + but->a1 - but->softmin);
size = max_ff(size, 2.0f);
@@ -2721,7 +2844,7 @@ static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
state = UI_SCROLL_PRESSED;
else
state = 0;
- uiWidgetScrollDraw(wcol, rect, &rect1, state);
+ UI_draw_widget_scroll(wcol, rect, &rect1, state);
}
static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
@@ -2743,7 +2866,7 @@ static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int
rect_bar.xmax = rect_bar.xmin + w;
- uiWidgetScrollDraw(wcol, &rect_prog, &rect_bar, UI_SCROLL_NO_OUTLINE);
+ UI_draw_widget_scroll(wcol, &rect_prog, &rect_bar, UI_SCROLL_NO_OUTLINE);
/* raise text a bit */
rect->ymin += 6 * UI_DPI_FAC;
@@ -2772,7 +2895,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
uiWidgetBase wtb, wtb1;
rcti rect1;
double value;
- float offs, toffs, fac;
+ float offs, toffs, fac = 0;
char outline[3];
widget_init(&wtb);
@@ -2802,8 +2925,10 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
rect1 = *rect;
- value = ui_get_but_val(but);
- fac = ((float)value - but->softmin) * (BLI_rcti_size_x(&rect1) - offs) / (but->softmax - but->softmin);
+ value = ui_but_value_get(but);
+ if ((but->softmax - but->softmin) > 0) {
+ fac = ((float)value - but->softmin) * (BLI_rcti_size_x(&rect1) - offs) / (but->softmax - but->softmin);
+ }
/* left part of slider, always rounded */
rect1.xmax = rect1.xmin + ceil(offs + U.pixelsize);
@@ -2873,7 +2998,7 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
rad = 0.25f * U.widget_unit;
round_box_edges(&wtb, roundboxalign, rect, rad);
- ui_get_but_vectorf(but, col);
+ ui_but_v3_get(but, col);
if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
/* draw based on state - color for keyed etc */
@@ -2889,7 +3014,7 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
}
if (color_profile)
- ui_block_to_display_space_v3(but->block, col);
+ ui_block_cm_to_display_space_v3(but->block, col);
rgba_float_to_uchar((unsigned char *)wcol->inner, col);
@@ -2903,11 +3028,8 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
float height = rect->ymax - rect->ymin;
/* find color luminance and change it slightly */
float bw = rgb_to_bw(col);
-
- if (bw > 0.5)
- bw -= 0.5;
- else
- bw += 0.5;
+
+ bw += (bw < 0.5f) ? 0.5f : -0.5f;
glColor4f(bw, bw, bw, 1.0);
glBegin(GL_TRIANGLES);
@@ -2918,9 +3040,9 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
}
}
-static void widget_normal(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
+static void widget_unitvec(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
{
- ui_draw_but_NORMAL(but, wcol, rect);
+ ui_draw_but_UNITVEC(but, wcol, rect);
}
static void widget_icon_has_anim(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
@@ -2937,7 +3059,7 @@ static void widget_icon_has_anim(uiBut *but, uiWidgetColors *wcol, rcti *rect, i
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
widgetbase_draw(&wtb, wcol);
}
- else if (but->type == NUM) {
+ else if (but->type == UI_BTYPE_NUM) {
/* Draw number buttons still with left/right
* triangles when field is not embossed */
widget_numbut_embossn(but, wcol, rect, state, roundboxalign);
@@ -3270,7 +3392,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
wt.wcol_theme = &btheme->tui.wcol_toggle;
break;
- case UI_WTYPE_OPTION:
+ case UI_WTYPE_CHECKBOX:
wt.wcol_theme = &btheme->tui.wcol_option;
wt.draw = widget_optionbut;
break;
@@ -3374,8 +3496,8 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
case UI_WTYPE_RGB_PICKER:
break;
- case UI_WTYPE_NORMAL:
- wt.custom = widget_normal;
+ case UI_WTYPE_UNITVEC:
+ wt.custom = widget_unitvec;
break;
case UI_WTYPE_SCROLL:
@@ -3410,7 +3532,7 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
int roundbox = UI_CNR_ALL;
/* alignment */
- if ((but->drawflag & UI_BUT_ALIGN) && but->type != PULLDOWN) {
+ if ((but->drawflag & UI_BUT_ALIGN) && but->type != UI_BTYPE_PULLDOWN) {
/* ui_block_position has this correction too, keep in sync */
if (but->drawflag & UI_BUT_ALIGN_TOP)
@@ -3451,34 +3573,17 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
/* align with open menu */
if (but->active) {
- int direction = ui_button_open_menu_direction(but);
+ int direction = ui_but_menu_direction(but);
- if (direction == UI_TOP) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT);
- else if (direction == UI_DOWN) roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
- else if (direction == UI_LEFT) roundbox &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
- else if (direction == UI_RIGHT) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
+ if (direction == UI_DIR_UP) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT);
+ else if (direction == UI_DIR_DOWN) roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
+ else if (direction == UI_DIR_LEFT) roundbox &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
+ else if (direction == UI_DIR_RIGHT) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
}
return roundbox;
}
-/* put all widget colors on half alpha, use local storage */
-static void ui_widget_color_disabled(uiWidgetType *wt)
-{
- static uiWidgetColors wcol_theme_s;
-
- wcol_theme_s = *wt->wcol_theme;
-
- wcol_theme_s.outline[3] *= 0.5;
- wcol_theme_s.inner[3] *= 0.5;
- wcol_theme_s.inner_sel[3] *= 0.5;
- wcol_theme_s.item[3] *= 0.5;
- wcol_theme_s.text[3] *= 0.5;
- wcol_theme_s.text_sel[3] *= 0.5;
-
- wt->wcol_theme = &wcol_theme_s;
-}
-
/* conversion from old to new buttons, so still messy */
void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rcti *rect)
{
@@ -3488,12 +3593,12 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
uiWidgetType *wt = NULL;
/* handle menus separately */
- if (but->dt == UI_EMBOSSP) {
+ if (but->dt == UI_EMBOSS_PULLDOWN) {
switch (but->type) {
- case LABEL:
+ case UI_BTYPE_LABEL:
widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect);
break;
- case SEPRLINE:
+ case UI_BTYPE_SEPR_LINE:
ui_draw_separator(rect, &tui->wcol_menu_item);
break;
default:
@@ -3501,17 +3606,18 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
break;
}
}
- else if (but->dt == UI_EMBOSSN) {
+ else if (but->dt == UI_EMBOSS_NONE) {
/* "nothing" */
wt = widget_type(UI_WTYPE_ICON);
}
- else if (but->dt == UI_EMBOSSR) {
+ else if (but->dt == UI_EMBOSS_RADIAL) {
wt = widget_type(UI_WTYPE_MENU_ITEM_RADIAL);
}
else {
-
+ BLI_assert(but->dt == UI_EMBOSS);
+
switch (but->type) {
- case LABEL:
+ case UI_BTYPE_LABEL:
if (but->block->flag & UI_BLOCK_LOOP)
widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect);
else {
@@ -3520,51 +3626,51 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
}
break;
- case SEPR:
- case SEPRLINE:
+ case UI_BTYPE_SEPR:
+ case UI_BTYPE_SEPR_LINE:
break;
- case BUT:
+ case UI_BTYPE_BUT:
wt = widget_type(UI_WTYPE_EXEC);
break;
- case NUM:
+ case UI_BTYPE_NUM:
wt = widget_type(UI_WTYPE_NUMBER);
break;
- case NUMSLI:
+ case UI_BTYPE_NUM_SLIDER:
wt = widget_type(UI_WTYPE_SLIDER);
break;
- case ROW:
+ case UI_BTYPE_ROW:
wt = widget_type(UI_WTYPE_RADIO);
break;
- case LISTROW:
+ case UI_BTYPE_LISTROW:
wt = widget_type(UI_WTYPE_LISTITEM);
break;
- case TEX:
+ case UI_BTYPE_TEXT:
wt = widget_type(UI_WTYPE_NAME);
break;
- case SEARCH_MENU_UNLINK:
- case SEARCH_MENU:
+ case UI_BTYPE_SEARCH_MENU_UNLINK:
+ case UI_BTYPE_SEARCH_MENU:
wt = widget_type(UI_WTYPE_NAME);
if (but->block->flag & UI_BLOCK_LOOP)
wt->wcol_theme = &btheme->tui.wcol_menu_back;
break;
- case TOGBUT:
- case TOG:
- case TOGN:
+ case UI_BTYPE_BUT_TOGGLE:
+ case UI_BTYPE_TOGGLE:
+ case UI_BTYPE_TOGGLE_N:
wt = widget_type(UI_WTYPE_TOGGLE);
break;
- case OPTION:
- case OPTIONN:
+ case UI_BTYPE_CHECKBOX:
+ case UI_BTYPE_CHECKBOX_N:
if (!(but->flag & UI_HAS_ICON)) {
- wt = widget_type(UI_WTYPE_OPTION);
+ wt = widget_type(UI_WTYPE_CHECKBOX);
but->drawflag |= UI_BUT_TEXT_LEFT;
}
else
@@ -3576,8 +3682,8 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
break;
- case MENU:
- case BLOCK:
+ case UI_BTYPE_MENU:
+ case UI_BTYPE_BLOCK:
if (but->flag & UI_BUT_NODE_LINK) {
/* new node-link button, not active yet XXX */
wt = widget_type(UI_WTYPE_MENU_NODE_LINK);
@@ -3589,7 +3695,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
* add updown arrows if there is room. */
if ((!but->str[0] && but->icon && (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect) + 2)) ||
/* disable for brushes also */
- (but->flag & UI_ICON_PREVIEW))
+ (but->flag & UI_BUT_ICON_PREVIEW))
{
/* no arrows */
wt = widget_type(UI_WTYPE_MENU_ICON_RADIO);
@@ -3600,35 +3706,35 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
}
break;
- case PULLDOWN:
+ case UI_BTYPE_PULLDOWN:
wt = widget_type(UI_WTYPE_PULLDOWN);
break;
- case BUTM:
+ case UI_BTYPE_BUT_MENU:
wt = widget_type(UI_WTYPE_MENU_ITEM);
break;
- case COLOR:
+ case UI_BTYPE_COLOR:
wt = widget_type(UI_WTYPE_SWATCH);
break;
- case ROUNDBOX:
- case LISTBOX:
+ case UI_BTYPE_ROUNDBOX:
+ case UI_BTYPE_LISTBOX:
wt = widget_type(UI_WTYPE_BOX);
break;
- case LINK:
- case INLINK:
+ case UI_BTYPE_LINK:
+ case UI_BTYPE_INLINK:
wt = widget_type(UI_WTYPE_ICON);
wt->custom = widget_link;
break;
- case BUT_EXTRA:
+ case UI_BTYPE_EXTRA:
widget_draw_extra_mask(C, but, widget_type(UI_WTYPE_BOX), rect);
break;
- case HSVCUBE:
+ case UI_BTYPE_HSVCUBE:
if (ELEM(but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) { /* vertical V slider, uses new widget draw now */
ui_draw_but_HSV_v(but, rect);
}
@@ -3637,56 +3743,56 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
}
break;
- case HSVCIRCLE:
+ case UI_BTYPE_HSVCIRCLE:
ui_draw_but_HSVCIRCLE(but, &tui->wcol_regular, rect);
break;
- case BUT_COLORBAND:
+ case UI_BTYPE_COLORBAND:
ui_draw_but_COLORBAND(but, &tui->wcol_regular, rect);
break;
- case BUT_NORMAL:
- wt = widget_type(UI_WTYPE_NORMAL);
+ case UI_BTYPE_UNITVEC:
+ wt = widget_type(UI_WTYPE_UNITVEC);
break;
- case BUT_IMAGE:
+ case UI_BTYPE_IMAGE:
ui_draw_but_IMAGE(ar, but, &tui->wcol_regular, rect);
break;
- case HISTOGRAM:
+ case UI_BTYPE_HISTOGRAM:
ui_draw_but_HISTOGRAM(ar, but, &tui->wcol_regular, rect);
break;
- case WAVEFORM:
+ case UI_BTYPE_WAVEFORM:
ui_draw_but_WAVEFORM(ar, but, &tui->wcol_regular, rect);
break;
- case VECTORSCOPE:
+ case UI_BTYPE_VECTORSCOPE:
ui_draw_but_VECTORSCOPE(ar, but, &tui->wcol_regular, rect);
break;
- case BUT_CURVE:
+ case UI_BTYPE_CURVE:
ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect);
break;
- case PROGRESSBAR:
+ case UI_BTYPE_PROGRESS_BAR:
wt = widget_type(UI_WTYPE_PROGRESSBAR);
fstyle = &style->widgetlabel;
break;
- case SCROLL:
+ case UI_BTYPE_SCROLL:
wt = widget_type(UI_WTYPE_SCROLL);
break;
- case GRIP:
+ case UI_BTYPE_GRIP:
wt = widget_type(UI_WTYPE_ICON);
break;
- case TRACKPREVIEW:
+ case UI_BTYPE_TRACK_PREVIEW:
ui_draw_but_TRACKPREVIEW(ar, but, &tui->wcol_regular, rect);
break;
- case NODESOCKET:
+ case UI_BTYPE_NODE_SOCKET:
ui_draw_but_NODESOCKET(ar, but, &tui->wcol_regular, rect);
break;
@@ -3706,24 +3812,24 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
state = but->flag;
if ((but->editstr) ||
- (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI) && ui_get_but_drag_multi_edit(but)))
+ (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI) && ui_but_drag_multi_edit_get(but)))
{
state |= UI_TEXTINPUT;
}
if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE))
- if (but->dt != UI_EMBOSSP)
+ if (but->dt != UI_EMBOSS_PULLDOWN)
disabled = true;
if (disabled)
ui_widget_color_disabled(wt);
-
+
wt->state(wt, state);
if (wt->custom)
wt->custom(but, &wt->wcol, rect, state, roundboxalign);
else if (wt->draw)
wt->draw(&wt->wcol, rect, state, roundboxalign);
-
+
if (disabled)
glEnable(GL_BLEND);
wt->text(fstyle, &wt->wcol, but, rect);
@@ -3731,7 +3837,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
glDisable(GL_BLEND);
// if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE))
-// if (but->dt != UI_EMBOSSP)
+// if (but->dt != UI_EMBOSS_PULLDOWN)
// widget_disabled(&disablerect);
}
}
@@ -3750,12 +3856,12 @@ void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
if (block->flag & UI_BLOCK_CLIPTOP) {
/* XXX no scaling for UI here yet */
glColor3ubv((unsigned char *)wt->wcol.text);
- UI_DrawTriIcon(BLI_rcti_cent_x(rect), rect->ymax - 8, 't');
+ UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymax - 8, 't');
}
if (block->flag & UI_BLOCK_CLIPBOTTOM) {
/* XXX no scaling for UI here yet */
glColor3ubv((unsigned char *)wt->wcol.text);
- UI_DrawTriIcon(BLI_rcti_cent_x(rect), rect->ymin + 10, 'v');
+ UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymin + 10, 'v');
}
}
}
@@ -3842,7 +3948,7 @@ void ui_draw_pie_center(uiBlock *block)
int subd = 40;
float angle = atan2f(pie_dir[1], pie_dir[0]);
- float range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? ((float)M_PI / 2.0f) : ((float)M_PI / 4.0f);
+ float range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_2 : M_PI_4;
glPushMatrix();
glTranslatef(cx, cy, 0.0f);
@@ -3929,7 +4035,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
wt->state(wt, state);
wt->draw(&wt->wcol, rect, 0, 0);
- uiStyleFontSet(fstyle);
+ UI_fontstyle_set(fstyle);
fstyle->align = UI_STYLE_TEXT_LEFT;
/* text location offset */
@@ -3943,7 +4049,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
*cpoin = 0;
/* need to set this first */
- uiStyleFontSet(fstyle);
+ UI_fontstyle_set(fstyle);
if (fstyle->kerning == 1) { /* for BLF_width */
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
@@ -3967,7 +4073,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
ui_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, NULL);
glColor4ubv((unsigned char *)wt->wcol.text);
- uiStyleFontDraw(fstyle, rect, drawstr);
+ UI_fontstyle_draw(fstyle, rect, drawstr);
}
/* part text right aligned */
@@ -3975,7 +4081,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
if (cpoin) {
fstyle->align = UI_STYLE_TEXT_RIGHT;
rect->xmax = _rect.xmax - 5;
- uiStyleFontDraw(fstyle, rect, cpoin + 1);
+ UI_fontstyle_draw(fstyle, rect, cpoin + 1);
*cpoin = UI_SEP_CHAR;
}
}
@@ -4042,6 +4148,6 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int
ui_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, NULL);
glColor4ubv((unsigned char *)wt->wcol.text);
- uiStyleFontDraw(fstyle, &trect, drawstr);
+ UI_fontstyle_draw(fstyle, &trect, drawstr);
}
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index bcd85333709..a9cc53852c0 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -45,6 +45,7 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BKE_appdir.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_main.h"
@@ -60,9 +61,16 @@
/* global for themes */
typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
-static bTheme *theme_active = NULL;
-static int theme_spacetype = SPACE_VIEW3D;
-static int theme_regionid = RGN_TYPE_WINDOW;
+/* be sure to keep 'bThemeState' in sync */
+static struct bThemeState g_theme_state = {
+ NULL,
+ SPACE_VIEW3D,
+ RGN_TYPE_WINDOW,
+};
+
+#define theme_active g_theme_state.theme
+#define theme_spacetype g_theme_state.spacetype
+#define theme_regionid g_theme_state.regionid
void ui_resources_init(void)
{
@@ -371,6 +379,10 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->keyborder_select; break;
case TH_CFRAME:
cp = ts->cframe; break;
+ case TH_TIME_KEYFRAME:
+ cp = ts->time_keyframe; break;
+ case TH_TIME_GP_KEYFRAME:
+ cp = ts->time_gp_keyframe; break;
case TH_NURB_ULINE:
cp = ts->nurb_uline; break;
case TH_NURB_VLINE:
@@ -505,6 +517,17 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case TH_HANDLE_VERTEX_SIZE:
cp = &ts->handle_vertex_size;
break;
+
+ case TH_GP_VERTEX:
+ cp = ts->gp_vertex;
+ break;
+ case TH_GP_VERTEX_SELECT:
+ cp = ts->gp_vertex_select;
+ break;
+ case TH_GP_VERTEX_SIZE:
+ cp = &ts->gp_vertex_size;
+ break;
+
case TH_DOPESHEET_CHANNELOB:
cp = ts->ds_channel;
break;
@@ -619,6 +642,9 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->nla_sound_sel;
break;
+ case TH_WIDGET_EMBOSS:
+ cp = btheme->tui.widget_emboss; break;
+
case TH_AXIS_X:
cp = btheme->tui.xaxis; break;
case TH_AXIS_Y:
@@ -656,11 +682,14 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case TH_INFO_DEBUG_TEXT:
cp = ts->info_debug_text;
break;
+ case TH_V3D_CLIPPING_BORDER:
+ cp = ts->clipping_border_3d;
+ break;
}
}
}
- return (unsigned char *)cp;
+ return (const unsigned char *)cp;
}
/* use this call to init new bone color sets in Theme */
@@ -815,6 +844,10 @@ void ui_theme_init_default(void)
btheme->tui.panel.show_header = false;
rgba_char_args_set(btheme->tui.panel.header, 0, 0, 0, 25);
+ rgba_char_args_set(btheme->tui.wcol_tooltip.text, 255, 255, 255, 255);
+
+ rgba_char_args_set_fl(btheme->tui.widget_emboss, 1.0f, 1.0f, 1.0f, 0.02f);
+
rgba_char_args_set(btheme->tui.xaxis, 220, 0, 0, 255);
rgba_char_args_set(btheme->tui.yaxis, 0, 220, 0, 255);
rgba_char_args_set(btheme->tui.zaxis, 0, 0, 220, 255);
@@ -885,6 +918,9 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.freestyle_face_mark, 0x7f, 0xff, 0x7f, 51);
rgba_char_args_set_fl(btheme->tv3d.paint_curve_handle, 0.5f, 1.0f, 0.5f, 0.5f);
rgba_char_args_set_fl(btheme->tv3d.paint_curve_pivot, 1.0f, 0.5f, 0.5f, 0.5f);
+ rgba_char_args_set(btheme->tv3d.gp_vertex, 0, 0, 0, 255);
+ rgba_char_args_set(btheme->tv3d.gp_vertex_select, 255, 133, 0, 255);
+ btheme->tv3d.gp_vertex_size = 3;
btheme->tv3d.facedot_size = 4;
@@ -918,6 +954,7 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.gradients.high_gradient, 58, 58, 58, 255);
btheme->tv3d.gradients.show_grad = false;
+ rgba_char_args_set(btheme->tv3d.clipping_border_3d, 50, 50, 50, 255);
/* space buttons */
/* to have something initialized */
btheme->tbuts = btheme->tv3d;
@@ -1104,6 +1141,9 @@ void ui_theme_init_default(void)
rgba_char_args_set_fl(btheme->ttime.grid, 0.36, 0.36, 0.36, 1.0);
rgba_char_args_set(btheme->ttime.shade1, 173, 173, 173, 255); /* sliders */
+ rgba_char_args_set(btheme->ttime.time_keyframe, 0xDD, 0xD7, 0x00, 1.0);
+ rgba_char_args_set(btheme->ttime.time_gp_keyframe, 0xB5, 0xE6, 0x1D, 1.0);
+
/* space node, re-uses syntax and console color storage */
btheme->tnode = btheme->tv3d;
rgba_char_args_set(btheme->tnode.syntaxr, 115, 115, 115, 255); /* wire inner color */
@@ -1186,6 +1226,18 @@ bTheme *UI_GetTheme(void)
return U.themes.first;
}
+/**
+ * for the rare case we need to temp swap in a different theme (offscreen render)
+ */
+void UI_Theme_Store(struct bThemeState *theme_state)
+{
+ *theme_state = g_theme_state;
+}
+void UI_Theme_Restore(struct bThemeState *theme_state)
+{
+ g_theme_state = *theme_state;
+}
+
/* for space windows only */
void UI_ThemeColor(int colorid)
{
@@ -1476,9 +1528,17 @@ void UI_ThemeClearColor(int colorid)
float col[3];
UI_GetThemeColor3fv(colorid, col);
- glClearColor(col[0], col[1], col[2], 0.0);
+ glClearColor(col[0], col[1], col[2], 0.0f);
+}
+
+void UI_ThemeClearColorAlpha(int colorid, float alpha)
+{
+ float col[3];
+ UI_GetThemeColor3fv(colorid, col);
+ glClearColor(col[0], col[1], col[2], alpha);
}
+
int UI_ThemeMenuShadowWidth(void)
{
bTheme *btheme = UI_GetTheme();
@@ -1526,8 +1586,8 @@ void init_userdef_do_versions(void)
U.tb_rightmouse = 5;
}
if (U.mixbufsize == 0) U.mixbufsize = 2048;
- if (strcmp(U.tempdir, "/") == 0) {
- BLI_system_temporary_dir(U.tempdir);
+ if (STREQ(U.tempdir, "/")) {
+ BKE_tempdir_system_init(U.tempdir);
}
if (U.autokey_mode == 0) {
/* 'add/replace' but not on */
@@ -1859,39 +1919,39 @@ void init_userdef_do_versions(void)
wmKeyMap *km;
for (km = U.user_keymaps.first; km; km = km->next) {
- if (strcmp(km->idname, "Armature_Sketch") == 0)
+ if (STREQ(km->idname, "Armature_Sketch"))
strcpy(km->idname, "Armature Sketch");
- else if (strcmp(km->idname, "View3D") == 0)
+ else if (STREQ(km->idname, "View3D"))
strcpy(km->idname, "3D View");
- else if (strcmp(km->idname, "View3D Generic") == 0)
+ else if (STREQ(km->idname, "View3D Generic"))
strcpy(km->idname, "3D View Generic");
- else if (strcmp(km->idname, "EditMesh") == 0)
+ else if (STREQ(km->idname, "EditMesh"))
strcpy(km->idname, "Mesh");
- else if (strcmp(km->idname, "TimeLine") == 0)
+ else if (STREQ(km->idname, "TimeLine"))
strcpy(km->idname, "Timeline");
- else if (strcmp(km->idname, "UVEdit") == 0)
+ else if (STREQ(km->idname, "UVEdit"))
strcpy(km->idname, "UV Editor");
- else if (strcmp(km->idname, "Animation_Channels") == 0)
+ else if (STREQ(km->idname, "Animation_Channels"))
strcpy(km->idname, "Animation Channels");
- else if (strcmp(km->idname, "GraphEdit Keys") == 0)
+ else if (STREQ(km->idname, "GraphEdit Keys"))
strcpy(km->idname, "Graph Editor");
- else if (strcmp(km->idname, "GraphEdit Generic") == 0)
+ else if (STREQ(km->idname, "GraphEdit Generic"))
strcpy(km->idname, "Graph Editor Generic");
- else if (strcmp(km->idname, "Action_Keys") == 0)
+ else if (STREQ(km->idname, "Action_Keys"))
strcpy(km->idname, "Dopesheet");
- else if (strcmp(km->idname, "NLA Data") == 0)
+ else if (STREQ(km->idname, "NLA Data"))
strcpy(km->idname, "NLA Editor");
- else if (strcmp(km->idname, "Node Generic") == 0)
+ else if (STREQ(km->idname, "Node Generic"))
strcpy(km->idname, "Node Editor");
- else if (strcmp(km->idname, "Logic Generic") == 0)
+ else if (STREQ(km->idname, "Logic Generic"))
strcpy(km->idname, "Logic Editor");
- else if (strcmp(km->idname, "File") == 0)
+ else if (STREQ(km->idname, "File"))
strcpy(km->idname, "File Browser");
- else if (strcmp(km->idname, "FileMain") == 0)
+ else if (STREQ(km->idname, "FileMain"))
strcpy(km->idname, "File Browser Main");
- else if (strcmp(km->idname, "FileButtons") == 0)
+ else if (STREQ(km->idname, "FileButtons"))
strcpy(km->idname, "File Browser Buttons");
- else if (strcmp(km->idname, "Buttons Generic") == 0)
+ else if (STREQ(km->idname, "Buttons Generic"))
strcpy(km->idname, "Property Editor");
}
}
@@ -2491,6 +2551,58 @@ void init_userdef_do_versions(void)
}
}
+ if (U.versionfile < 272 || (U.versionfile == 272 && U.subversionfile < 3)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ rgba_char_args_set_fl(btheme->tui.widget_emboss, 1.0f, 1.0f, 1.0f, 0.02f);
+ }
+ }
+
+ if (U.versionfile < 273 || (U.versionfile == 273 && U.subversionfile < 1)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ /* Grease Pencil vertex settings */
+ rgba_char_args_set(btheme->tv3d.gp_vertex, 0, 0, 0, 255);
+ rgba_char_args_set(btheme->tv3d.gp_vertex_select, 255, 133, 0, 255);
+ btheme->tv3d.gp_vertex_size = 3;
+
+ rgba_char_args_set(btheme->tseq.gp_vertex, 0, 0, 0, 255);
+ rgba_char_args_set(btheme->tseq.gp_vertex_select, 255, 133, 0, 255);
+ btheme->tseq.gp_vertex_size = 3;
+
+ rgba_char_args_set(btheme->tima.gp_vertex, 0, 0, 0, 255);
+ rgba_char_args_set(btheme->tima.gp_vertex_select, 255, 133, 0, 255);
+ btheme->tima.gp_vertex_size = 3;
+
+ rgba_char_args_set(btheme->tnode.gp_vertex, 0, 0, 0, 255);
+ rgba_char_args_set(btheme->tnode.gp_vertex_select, 255, 133, 0, 255);
+ btheme->tnode.gp_vertex_size = 3;
+
+ /* Timeline Keyframe Indicators */
+ rgba_char_args_set(btheme->ttime.time_keyframe, 0xDD, 0xD7, 0x00, 1.0);
+ rgba_char_args_set(btheme->ttime.time_gp_keyframe, 0xB5, 0xE6, 0x1D, 1.0);
+ }
+ }
+
+ if (U.versionfile < 273 || (U.versionfile == 273 && U.subversionfile < 5)) {
+ bTheme *btheme;
+ for (btheme = U.themes.first; btheme; btheme = btheme->next) {
+ unsigned char *cp = (unsigned char *)btheme->tv3d.clipping_border_3d;
+ int c;
+ copy_v4_v4_char((char *)cp, btheme->tv3d.back);
+ c = cp[0] - 8;
+ CLAMP(c, 0, 255);
+ cp[0] = c;
+ c = cp[1] - 8;
+ CLAMP(c, 0, 255);
+ cp[1] = c;
+ c = cp[2] - 8;
+ CLAMP(c, 0, 255);
+ cp[2] = c;
+ cp[3] = 255;
+ }
+ }
+
if (U.pixelsize == 0.0f)
U.pixelsize = 1.0f;
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index d48faa34618..b4a120b2dea 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -206,7 +206,7 @@ static void view2d_masks(View2D *v2d, int check_scrollers)
void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
{
bool tot_changed = false, do_init;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
do_init = (v2d->flag & V2D_IS_INITIALISED) == 0;
@@ -371,7 +371,8 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, int resize, int mask_
float winx, winy;
rctf *cur, *tot;
- /* use mask as size of region that View2D resides in, as it takes into account scrollbars already */
+ /* use mask as size of region that View2D resides in, as it takes into account
+ * scrollbars already - keep in sync with zoomx/zoomy in view_zoomstep_apply_ex! */
winx = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
winy = (float)(BLI_rcti_size_y(&v2d->mask) + 1);
@@ -393,6 +394,7 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, int resize, int mask_
*/
totwidth = BLI_rctf_size_x(tot);
totheight = BLI_rctf_size_y(tot);
+ /* keep in sync with zoomx/zoomy in view_zoomstep_apply_ex! */
curwidth = width = BLI_rctf_size_x(cur);
curheight = height = BLI_rctf_size_y(cur);
@@ -1099,7 +1101,7 @@ void UI_view2d_view_ortho(View2D *v2d)
/* Set view matrices to only use one axis of 'cur' only
* - xaxis = if non-zero, only use cur x-axis, otherwise use cur-yaxis (mostly this will be used for x)
*/
-void UI_view2d_view_orthoSpecial(ARegion *ar, View2D *v2d, short xaxis)
+void UI_view2d_view_orthoSpecial(ARegion *ar, View2D *v2d, const bool xaxis)
{
rctf curmasked;
float xofs, yofs;
@@ -1719,7 +1721,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax);
}
- uiWidgetScrollDraw(&wcol, &hor, &slider, state);
+ UI_draw_widget_scroll(&wcol, &hor, &slider, state);
/* scale indicators */
if ((scroll & V2D_SCROLL_SCALE_HORIZONTAL) && (vs->grid)) {
@@ -1820,7 +1822,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax);
}
- uiWidgetScrollDraw(&wcol, &vert, &slider, state);
+ UI_draw_widget_scroll(&wcol, &vert, &slider, state);
/* scale indiators */
@@ -1851,7 +1853,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* draw vertical steps */
if (dfac > 0.0f) {
- BLF_rotation_default(M_PI / 2);
+ BLF_rotation_default(M_PI_2);
BLF_enable_default(BLF_ROTATION);
for (; fac < vert.ymax - 10; fac += dfac, val += grid->dy) {
@@ -2305,7 +2307,7 @@ void UI_view2d_text_cache_add(View2D *v2d, float x, float y,
BLI_LINKS_PREPEND(g_v2d_strings, v2s);
- v2s->col.pack = *((int *)col);
+ v2s->col.pack = *((const int *)col);
memset(&v2s->rect, 0, sizeof(v2s->rect));
@@ -2336,7 +2338,7 @@ void UI_view2d_text_cache_add_rectf(View2D *v2d, const rctf *rect_view,
BLI_LINKS_PREPEND(g_v2d_strings, v2s);
- v2s->col.pack = *((int *)col);
+ v2s->col.pack = *((const int *)col);
v2s->rect = rect;
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index a396893f8f2..88140d897ae 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -625,6 +625,7 @@ static void view_zoomstep_apply_ex(bContext *C, v2dViewZoomData *vzd, const bool
{
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
+ const rctf cur_old = v2d->cur;
float dx, dy;
/* calculate amount to move view by, ensuring symmetry so the
@@ -651,17 +652,23 @@ static void view_zoomstep_apply_ex(bContext *C, v2dViewZoomData *vzd, const bool
v2d->cur.xmax -= 2 * dx;
}
else {
+
+ v2d->cur.xmin += dx;
+ v2d->cur.xmax -= dx;
+
if (use_mousepos && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
- float mval_fac = (vzd->mx_2d - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
- float mval_faci = 1.0f - mval_fac;
- float ofs = (mval_fac * dx) - (mval_faci * dx);
-
- v2d->cur.xmin += ofs + dx;
- v2d->cur.xmax += ofs - dx;
- }
- else {
- v2d->cur.xmin += dx;
- v2d->cur.xmax -= dx;
+ /* get zoom fac the same way as in ui_view2d_curRect_validate_resize - better keep in sync! */
+ const float zoomx = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
+
+ /* only move view to mouse if zoom fac is inside minzoom/maxzoom */
+ if (IN_RANGE_INCL(zoomx, v2d->minzoom, v2d->maxzoom)) {
+ float mval_fac = (vzd->mx_2d - cur_old.xmin) / BLI_rctf_size_x(&cur_old);
+ float mval_faci = 1.0f - mval_fac;
+ float ofs = (mval_fac * dx) - (mval_faci * dx);
+
+ v2d->cur.xmin += ofs;
+ v2d->cur.xmax += ofs;
+ }
}
}
}
@@ -676,17 +683,23 @@ static void view_zoomstep_apply_ex(bContext *C, v2dViewZoomData *vzd, const bool
v2d->cur.ymax -= 2 * dy;
}
else {
+
+ v2d->cur.ymin += dy;
+ v2d->cur.ymax -= dy;
+
if (use_mousepos && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
- float mval_fac = (vzd->my_2d - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
- float mval_faci = 1.0f - mval_fac;
- float ofs = (mval_fac * dy) - (mval_faci * dy);
-
- v2d->cur.ymin += ofs + dy;
- v2d->cur.ymax += ofs - dy;
- }
- else {
- v2d->cur.ymin += dy;
- v2d->cur.ymax -= dy;
+ /* get zoom fac the same way as in ui_view2d_curRect_validate_resize - better keep in sync! */
+ const float zoomy = (float)(BLI_rcti_size_y(&v2d->mask) + 1) / BLI_rctf_size_y(&v2d->cur);
+
+ /* only move view to mouse if zoom fac is inside minzoom/maxzoom */
+ if (IN_RANGE_INCL(zoomy, v2d->minzoom, v2d->maxzoom)) {
+ float mval_fac = (vzd->my_2d - cur_old.ymin) / BLI_rctf_size_y(&cur_old);
+ float mval_faci = 1.0f - mval_fac;
+ float ofs = (mval_fac * dy) - (mval_faci * dy);
+
+ v2d->cur.ymin += ofs;
+ v2d->cur.ymax += ofs;
+ }
}
}
}
@@ -1726,7 +1739,7 @@ static void scroller_activate_apply(bContext *C, wmOperator *op)
temp = vsm->fac * vsm->delta;
/* round to pixel */
- temp = floorf(temp / vsm->fac_round + 0.5f) * vsm->fac_round;
+ temp = roundf(temp / vsm->fac_round) * vsm->fac_round;
/* type of movement */
switch (vsm->zone) {
@@ -1951,7 +1964,7 @@ static void VIEW2D_OT_scroller_activate(wmOperatorType *ot)
static int reset_exec(bContext *C, wmOperator *UNUSED(op))
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
int winx, winy;
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index bbf4447dd72..93e9a204704 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -298,7 +298,7 @@ void WM_OT_collada_export(wmOperatorType *ot)
ot->ui = wm_collada_export_draw;
- WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_SAVE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_COLLADA, FILE_BLENDER, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
RNA_def_boolean(ot->srna,
@@ -327,11 +327,11 @@ void WM_OT_collada_export(wmOperatorType *ot)
"Only export deforming bones with armatures");
- RNA_def_boolean(ot->srna, "active_uv_only", 0, "Only Active UV layer",
- "Export textures assigned to the object UV maps");
+ RNA_def_boolean(ot->srna, "active_uv_only", 0, "Only Selected UV Map",
+ "Export only the selected UV Map");
RNA_def_boolean(ot->srna, "include_uv_textures", 0, "Include UV Textures",
- "Export textures assigned to the object UV maps");
+ "Export textures assigned to the object UV Maps");
RNA_def_boolean(ot->srna, "include_material_textures", 0, "Include Material Textures",
"Export textures assigned to the object Materials");
@@ -365,6 +365,9 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
{
char filename[FILE_MAX];
int import_units;
+ int find_chains;
+ int fix_orientation;
+ int min_chain_length;
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
BKE_report(op->reports, RPT_ERROR, "No filename given");
@@ -372,10 +375,19 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
}
/* Options panel */
- import_units = RNA_boolean_get(op->ptr, "import_units");
+ import_units = RNA_boolean_get(op->ptr, "import_units");
+ find_chains = RNA_boolean_get(op->ptr, "find_chains");
+ fix_orientation = RNA_boolean_get(op->ptr, "fix_orientation");
+ min_chain_length = RNA_int_get(op->ptr, "min_chain_length");
RNA_string_get(op->ptr, "filepath", filename);
- if (collada_import(C, filename, import_units)) {
+ if (collada_import(
+ C, filename,
+ import_units,
+ find_chains,
+ fix_orientation,
+ min_chain_length))
+ {
return OPERATOR_FINISHED;
}
else {
@@ -395,6 +407,19 @@ static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr)
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "import_units", 0, NULL, ICON_NONE);
+
+ box = uiLayoutBox(layout);
+ row = uiLayoutRow(box, false);
+ uiItemL(row, IFACE_("Armature Options:"), ICON_MESH_DATA);
+
+ row = uiLayoutRow(box, false);
+ uiItemR(row, imfptr, "fix_orientation", 0, NULL, ICON_NONE);
+
+ row = uiLayoutRow(box, false);
+ uiItemR(row, imfptr, "find_chains", 0, NULL, ICON_NONE);
+
+ row = uiLayoutRow(box, false);
+ uiItemR(row, imfptr, "min_chain_length", 0, NULL, ICON_NONE);
}
static void wm_collada_import_draw(bContext *UNUSED(C), wmOperator *op)
@@ -419,13 +444,31 @@ void WM_OT_collada_import(wmOperatorType *ot)
ot->ui = wm_collada_import_draw;
- WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_COLLADA, FILE_BLENDER, FILE_OPENFILE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
RNA_def_boolean(ot->srna,
- "import_units", 0, "Import Units",
- "If disabled match import to Blender's current Unit settings, "
- "otherwise use the settings from the Imported scene");
+ "import_units", 0, "Import Units",
+ "If disabled match import to Blender's current Unit settings, "
+ "otherwise use the settings from the Imported scene");
+
+ RNA_def_boolean(ot->srna,
+ "fix_orientation", 0, "Fix Leaf Bones",
+ "Fix Orientation of Leaf Bones (Collada does only support Joints)");
+
+ RNA_def_boolean(ot->srna,
+ "find_chains", 0, "Find Bone Chains",
+ "Find best matching Bone Chains and ensure bones in chain are connected");
+
+ RNA_def_int(ot->srna,
+ "min_chain_length",
+ 0,
+ 0,
+ INT_MAX,
+ "Minimum Chain Length",
+ "When searching Bone Chains disregard chains of length below this value",
+ 0,
+ INT_MAX);
}
#endif
diff --git a/source/blender/editors/io/io_ops.c b/source/blender/editors/io/io_ops.c
index a33340cc39a..a70a51a60be 100644
--- a/source/blender/editors/io/io_ops.c
+++ b/source/blender/editors/io/io_ops.c
@@ -28,16 +28,13 @@
* \ingroup collada
*/
-
-#include "io_collada.h"
-
-#include "BLI_utildefines.h"
-
-#include "WM_types.h"
-#include "WM_api.h"
-
#include "io_ops.h" /* own include */
+#ifdef WITH_COLLADA
+# include "io_collada.h"
+# include "WM_api.h"
+#endif
+
void ED_operatortypes_io(void)
{
#ifdef WITH_COLLADA
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 93e59f3244e..929c4f74b2f 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -784,7 +784,7 @@ static int slide_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
SlidePointData *slidedata;
if (mask == NULL) {
- return OPERATOR_CANCELLED;
+ return OPERATOR_PASS_THROUGH;
}
slidedata = slide_point_customdata(C, op, event);
@@ -1286,7 +1286,7 @@ static int slide_spline_curvature_invoke(bContext *C, wmOperator *op, const wmEv
SlideSplineCurvatureData *slide_data;
if (mask == NULL) {
- return OPERATOR_CANCELLED;
+ return OPERATOR_PASS_THROUGH;
}
/* Be sure we don't conflict with point slide here. */
diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c
index e02561d839c..4e0aa8f84ae 100644
--- a/source/blender/editors/mask/mask_relationships.c
+++ b/source/blender/editors/mask/mask_relationships.c
@@ -39,7 +39,6 @@
#include "BKE_tracking.h"
#include "DNA_mask_types.h"
-#include "DNA_object_types.h" /* SELECT */
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 87b429f1165..113f0f71b53 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -31,8 +31,6 @@
#include "BLI_math.h"
#include "BLI_bitmap.h"
-#include "BLF_translation.h"
-
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index b288a02a3d1..6ce5e8a304b 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -32,6 +32,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BLI_math.h"
#include "BLF_translation.h"
@@ -71,7 +72,7 @@ static Object *make_prim_init(bContext *C, const char *idname,
*was_editmode = true;
}
- *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, false);
+ *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
return obedit;
}
@@ -421,7 +422,9 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
{
Object *obedit;
BMEditMesh *em;
- float loc[3], rot[3], mat[4][4], dia;
+ float mat[4][4];
+ float loc[3], rot[3];
+ float dia;
bool enter_editmode;
unsigned int layer;
bool was_editmode;
@@ -431,9 +434,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Suzanne"), &dia, mat, &was_editmode, loc, rot, layer);
dia = RNA_float_get(op->ptr, "radius");
- mat[0][0] *= dia;
- mat[1][1] *= dia;
- mat[2][2] *= dia;
+ mul_mat3_m4_fl(mat, dia);
em = BKE_editmesh_from_object(obedit);
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index 3e403387a67..9b1b0b915c1 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -54,18 +54,6 @@
#include "mesh_intern.h" /* own include */
-/* allow accumulated normals to form a new direction but don't
- * accept direct opposite directions else they will cancel each other out */
-static void add_normal_aligned(float nor[3], const float add[3])
-{
- if (dot_v3v3(nor, add) < -0.9999f) {
- sub_v3_v3(nor, add);
- }
- else {
- add_v3_v3(nor, add);
- }
-}
-
static void edbm_extrude_edge_exclude_mirror(
Object *obedit, BMEditMesh *em,
const char hflag,
@@ -137,7 +125,7 @@ static void edbm_extrude_edge_exclude_mirror(
/* individual face extrude */
/* will use vertex normals for extrusion directions, so *nor is unaffected */
-static short edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor))
+static bool edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const char hflag)
{
BMOIter siter;
BMIter liter;
@@ -165,14 +153,14 @@ static short edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const c
}
if (!EDBM_op_finish(em, &bmop, op, true)) {
- return 0;
+ return false;
}
- return 's'; /* s is shrink/fatten */
+ return true;
}
/* extrudes individual edges */
-static short edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor))
+static bool edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag)
{
BMesh *bm = em->bm;
BMOperator bmop;
@@ -191,14 +179,14 @@ static short edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);
if (!EDBM_op_finish(em, &bmop, op, true)) {
- return 0;
+ return false;
}
- return 'n'; /* n is normal grab */
+ return true;
}
/* extrudes individual vertices */
-static short edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor))
+static bool edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char hflag)
{
BMOperator bmop;
@@ -214,27 +202,55 @@ static short edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, true);
if (!EDBM_op_finish(em, &bmop, op, true)) {
- return 0;
+ return false;
+ }
+
+ return true;
+}
+
+static char edbm_extrude_htype_from_em_select(BMEditMesh *em)
+{
+ char htype = BM_ALL_NOLOOP;
+
+ if (em->selectmode & SCE_SELECT_VERTEX) {
+ /* pass */
+ }
+ else if (em->selectmode & SCE_SELECT_EDGE) {
+ htype &= ~BM_VERT;
+ }
+ else {
+ htype &= ~(BM_VERT | BM_EDGE);
+ }
+
+ if (em->bm->totedgesel == 0) {
+ htype &= ~(BM_EDGE | BM_FACE);
+ }
+ else if (em->bm->totfacesel == 0) {
+ htype &= ~BM_FACE;
}
- return 'g'; /* g is grab */
+ return htype;
}
-static short edbm_extrude_edge_ex(
+static bool edbm_extrude_ex(
Object *obedit, BMEditMesh *em,
- const char hflag, float nor[3],
+ char htype, const char hflag,
const bool use_mirror,
const bool use_select_history)
{
BMesh *bm = em->bm;
BMOIter siter;
BMOperator extop;
- BMFace *f;
BMElem *ele;
+ /* needed to remove the faces left behind */
+ if (htype & BM_FACE) {
+ htype |= BM_EDGE;
+ }
+
BMO_op_init(bm, &extop, BMO_FLAG_DEFAULTS, "extrude_face_region");
BMO_slot_bool_set(extop.slots_in, "use_select_history", use_select_history);
- BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", BM_VERT | BM_EDGE | BM_FACE, hflag);
+ BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", htype, hflag);
if (use_mirror) {
BMOpSlot *slot_edges_exclude;
@@ -248,61 +264,14 @@ static short edbm_extrude_edge_ex(
BM_SELECT_HISTORY_RESTORE(bm);
BMO_op_exec(bm, &extop);
-
- zero_v3(nor);
- BMO_ITER (ele, &siter, extop.slots_out, "geom.out", BM_ALL) {
+ BMO_ITER (ele, &siter, extop.slots_out, "geom.out", BM_ALL_NOLOOP) {
BM_elem_select_set(bm, ele, true);
-
- if (ele->head.htype == BM_FACE) {
- f = (BMFace *)ele;
- add_normal_aligned(nor, f->no);
- }
}
- normalize_v3(nor);
-
BMO_op_finish(bm, &extop);
- /* grab / normal constraint */
- return is_zero_v3(nor) ? 'g' : 'n';
-}
-
-static short edbm_extrude_edge(
- Object *obedit, BMEditMesh *em,
- const char hflag, float nor[3])
-{
- return edbm_extrude_edge_ex(obedit, em, hflag, nor, true, true);
-}
-
-static short edbm_extrude_vert(Object *obedit, BMEditMesh *em, const char hflag, float nor[3])
-{
- BMIter iter;
- BMEdge *eed;
-
- /* ensure vert flags are consistent for edge selections */
- BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(eed, hflag)) {
- if (hflag & BM_ELEM_SELECT) {
- BM_vert_select_set(em->bm, eed->v1, true);
- BM_vert_select_set(em->bm, eed->v2, true);
- }
-
- BM_elem_flag_enable(eed->v1, hflag & ~BM_ELEM_SELECT);
- BM_elem_flag_enable(eed->v2, hflag & ~BM_ELEM_SELECT);
- }
- else {
- if (BM_elem_flag_test(eed->v1, hflag) && BM_elem_flag_test(eed->v2, hflag)) {
- if (hflag & BM_ELEM_SELECT) {
- BM_edge_select_set(em->bm, eed, true);
- }
-
- BM_elem_flag_enable(eed, hflag & ~BM_ELEM_SELECT);
- }
- }
- }
-
- return edbm_extrude_edge(obedit, em, hflag, nor);
+ return true;
}
static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
@@ -314,7 +283,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
const int steps = RNA_int_get(op->ptr, "steps");
const float offs = RNA_float_get(op->ptr, "offset");
- float dvec[3], tmat[3][3], bmat[3][3], nor[3] = {0.0, 0.0, 0.0};
+ float dvec[3], tmat[3][3], bmat[3][3];
short a;
/* dvec */
@@ -327,7 +296,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
mul_m3_v3(tmat, dvec);
for (a = 0; a < steps; a++) {
- edbm_extrude_edge_ex(obedit, em, BM_ELEM_SELECT, nor, false, false);
+ edbm_extrude_ex(obedit, em, BM_ALL_NOLOOP, BM_ELEM_SELECT, false, false);
BMO_op_callf(
em->bm, BMO_FLAG_DEFAULTS,
@@ -362,87 +331,58 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot)
}
/* generic extern called extruder */
-static int edbm_extrude_mesh(Scene *scene, Object *obedit, BMEditMesh *em, wmOperator *op, float *norin)
+static bool edbm_extrude_mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
{
- short nr, transmode = 0;
- float stacknor[3] = {0.0f, 0.0f, 0.0f};
- float *nor = norin ? norin : stacknor;
-
- zero_v3(nor);
+ bool changed = false;
+ const char htype = edbm_extrude_htype_from_em_select(em);
+ enum {NONE = 0, ELEM_FLAG, VERT_ONLY, EDGE_ONLY} nr;
if (em->selectmode & SCE_SELECT_VERTEX) {
- if (em->bm->totvertsel == 0) nr = 0;
- else if (em->bm->totvertsel == 1) nr = 4;
- else if (em->bm->totedgesel == 0) nr = 4;
- else if (em->bm->totfacesel == 0)
- nr = 3;
- else if (em->bm->totfacesel == 1)
- nr = 1;
- else
- nr = 1;
+ if (em->bm->totvertsel == 0) nr = NONE;
+ else if (em->bm->totvertsel == 1) nr = VERT_ONLY;
+ else if (em->bm->totedgesel == 0) nr = VERT_ONLY;
+ else nr = ELEM_FLAG;
}
else if (em->selectmode & SCE_SELECT_EDGE) {
- if (em->bm->totedgesel == 0) nr = 0;
-
- nr = 1;
+ if (em->bm->totedgesel == 0) nr = NONE;
+ else if (em->bm->totfacesel == 0) nr = EDGE_ONLY;
+ else nr = ELEM_FLAG;
}
else {
- if (em->bm->totfacesel == 0) nr = 0;
- else if (em->bm->totfacesel == 1) nr = 1;
- else
- nr = 1;
+ if (em->bm->totfacesel == 0) nr = NONE;
+ else nr = ELEM_FLAG;
}
- if (nr < 1) return 'g';
-
- if (nr == 1 && (em->selectmode & SCE_SELECT_VERTEX))
- transmode = edbm_extrude_vert(obedit, em, BM_ELEM_SELECT, nor);
- else if (nr == 1) transmode = edbm_extrude_edge(obedit, em, BM_ELEM_SELECT, nor);
- else if (nr == 4) transmode = edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT, nor);
- else if (nr == 3) transmode = edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, nor);
- else transmode = edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor);
+ switch (nr) {
+ case NONE:
+ return false;
+ case ELEM_FLAG:
+ changed = edbm_extrude_ex(obedit, em, htype, BM_ELEM_SELECT, true, true);
+ break;
+ case VERT_ONLY:
+ changed = edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT);
+ break;
+ case EDGE_ONLY:
+ changed = edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT);
+ break;
+ }
- if (transmode == 0) {
- BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude");
+ if (changed) {
+ return true;
}
else {
-
- /* We need to force immediate calculation here because
- * transform may use derived objects (which are now stale).
- *
- * This shouldn't be necessary, derived queries should be
- * automatically building this data if invalid. Or something.
- */
-// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
- BKE_object_handle_update(G.main->eval_ctx, scene, obedit);
-
- /* individual faces? */
- if (nr == 2) {
-// initTransform(TFM_SHRINKFATTEN, CTX_NO_PET|CTX_NO_MIRROR);
-// Transform();
- }
- else {
-// initTransform(TFM_TRANSLATION, CTX_NO_PET|CTX_NO_MIRROR);
- if (transmode == 'n') {
- mul_m4_v3(obedit->obmat, nor);
- sub_v3_v3v3(nor, nor, obedit->obmat[3]);
-// BIF_setSingleAxisConstraint(nor, "along normal");
- }
-// Transform();
- }
+ BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude");
+ return false;
}
-
- return transmode;
}
/* extrude without transform */
static int edbm_extrude_region_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- edbm_extrude_mesh(scene, obedit, em, op, NULL);
+ edbm_extrude_mesh(obedit, em, op);
/* This normally happens when pushing undo but modal operators
* like this one don't push undo data until after modal mode is
@@ -476,9 +416,8 @@ static int edbm_extrude_verts_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- float nor[3];
- edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT, nor);
+ edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT);
EDBM_update_generic(em, true, true);
@@ -507,9 +446,8 @@ static int edbm_extrude_edges_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- float nor[3];
- edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, nor);
+ edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT);
EDBM_update_generic(em, true, true);
@@ -538,9 +476,8 @@ static int edbm_extrude_faces_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- float nor[3];
- edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor);
+ edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT);
EDBM_update_generic(em, true, true);
@@ -578,7 +515,6 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
-
use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) &&
(vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE));
@@ -593,6 +529,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
/* call extrude? */
if (done) {
+ const char extrude_htype = edbm_extrude_htype_from_em_select(vc.em);
const bool rot_src = RNA_boolean_get(op->ptr, "rotate_source");
BMEdge *eed;
float vec[3], cent[3], mat[3][3];
@@ -686,7 +623,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
EMBM_project_snap_verts(C, vc.ar, vc.em);
}
- edbm_extrude_edge(vc.obedit, vc.em, BM_ELEM_SELECT, nor);
+ edbm_extrude_ex(vc.obedit, vc.em, extrude_htype, BM_ELEM_SELECT, true, true);
EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3",
BM_ELEM_SELECT, cent, mat);
EDBM_op_callf(vc.em, op, "translate verts=%hv vec=%v",
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index df6776950d7..e2e4638254b 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -38,7 +38,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
@@ -334,7 +333,7 @@ static int edbm_face_split_by_edges_exec(bContext *C, wmOperator *UNUSED(op))
BMVert *v_other = BM_edge_other_vert(e, v);
float e_dir[3];
- /* we wan't closest to zero */
+ /* we want closest to zero */
float dot_best = FLT_MAX;
sub_v3_v3v3(e_dir, v_other->co, v->co);
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index f5a7e82a8a8..f3745ed72fb 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -75,10 +75,16 @@
#define KMAXDIST 10 /* max mouse distance from edge before not detecting it */
+/* WARNING: knife float precision is fragile:
+ * be careful before making changes here see: (T43229, T42864, T42459, T41164).
+ */
#define KNIFE_FLT_EPS 0.00001f
#define KNIFE_FLT_EPS_SQUARED (KNIFE_FLT_EPS * KNIFE_FLT_EPS)
#define KNIFE_FLT_EPSBIG 0.0005f
-#define KNIFE_FLT_EPS_PX 0.2f
+
+#define KNIFE_FLT_EPS_PX_VERT 0.5f
+#define KNIFE_FLT_EPS_PX_EDGE 0.05f
+#define KNIFE_FLT_EPS_PX_FACE 0.05f
typedef struct KnifeColors {
unsigned char line[3];
@@ -97,7 +103,7 @@ typedef struct KnifeVert {
float co[3], cageco[3], sco[2]; /* sco is screen coordinates for cageco */
bool is_face, in_space;
- bool draw;
+ bool is_cut; /* along a cut created by user input (will draw too) */
} KnifeVert;
typedef struct Ref {
@@ -111,7 +117,7 @@ typedef struct KnifeEdge {
ListBase faces;
BMEdge *e /* , *e_old */; /* non-NULL if this is an original edge */
- bool draw;
+ bool is_cut; /* along a cut created by user input (will draw too) */
} KnifeEdge;
typedef struct KnifeLineHit {
@@ -152,6 +158,7 @@ typedef struct KnifeTool_OpData {
float mval[2]; /* mouse value with snapping applied */
//bContext *C;
+ Scene *scene;
Object *ob;
BMEditMesh *em;
@@ -174,8 +181,10 @@ typedef struct KnifeTool_OpData {
KnifeLineHit *linehits;
int totlinehit;
- /* Data for mouse-position-derived data (cur) and previous click (prev) */
- KnifePosData curr, prev;
+ /* Data for mouse-position-derived data */
+ KnifePosData curr; /* current point under the cursor */
+ KnifePosData prev; /* last added cut (a line draws from the cursor to this) */
+ KnifePosData init; /* the first point in the cut-list, used for closing the loop */
int totkedge, totkvert;
@@ -206,6 +215,7 @@ typedef struct KnifeTool_OpData {
MODE_CONNECT,
MODE_PANNING
} mode;
+ bool is_drag_hold;
int prevmode;
bool snap_midpoints;
@@ -233,6 +243,8 @@ static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2],
static bool knife_verts_edge_in_face(KnifeVert *v1, KnifeVert *v2, BMFace *f);
+static void knifetool_free_bmbvh(KnifeTool_OpData *kcd);
+
static void knife_update_header(bContext *C, KnifeTool_OpData *kcd)
{
#define HEADER_LENGTH 256
@@ -526,7 +538,7 @@ static KnifeVert *knife_split_edge(
newkfe->v1 = kfe->v1;
newkfe->v2 = new_knife_vert(kcd, co, cageco);
- newkfe->v2->draw = 1;
+ newkfe->v2->is_cut = true;
if (kfe->e) {
knife_add_edge_faces_to_vert(kcd, newkfe->v2, kfe->e);
}
@@ -551,7 +563,7 @@ static KnifeVert *knife_split_edge(
knife_add_to_vert_edges(kcd, newkfe);
- newkfe->draw = kfe->draw;
+ newkfe->is_cut = kfe->is_cut;
newkfe->e = kfe->e;
*r_kfe = newkfe;
@@ -559,6 +571,16 @@ static KnifeVert *knife_split_edge(
return newkfe->v2;
}
+static void linehit_to_knifepos(KnifePosData *kpos, KnifeLineHit *lh)
+{
+ kpos->bmface = lh->f;
+ kpos->vert = lh->v;
+ kpos->edge = lh->kfe;
+ copy_v3_v3(kpos->cage, lh->cagehit);
+ copy_v3_v3(kpos->co, lh->hit);
+ copy_v2_v2(kpos->mval, lh->schit);
+}
+
/* primary key: lambda along cut
* secondary key: lambda along depth
* tertiary key: pointer comparisons of verts if both snapped to verts
@@ -590,6 +612,7 @@ static void prepare_linehits_for_cut(KnifeTool_OpData *kcd)
{
KnifeLineHit *linehits, *lhi, *lhj;
int i, j, n;
+ bool is_double = false;
n = kcd->totlinehit;
linehits = kcd->linehits;
@@ -613,7 +636,11 @@ static void prepare_linehits_for_cut(KnifeTool_OpData *kcd)
{
break;
}
- lhj->l = -1.0f;
+
+ if (lhi->kfe == lhj->kfe) {
+ lhj->l = -1.0f;
+ is_double = true;
+ }
}
for (j = i + 1; j < n; j++) {
lhj = &linehits[j];
@@ -622,37 +649,42 @@ static void prepare_linehits_for_cut(KnifeTool_OpData *kcd)
{
break;
}
- if (lhj->kfe || lhi->v == lhj->v) {
+ if ((lhj->kfe && (lhi->kfe == lhj->kfe)) ||
+ (lhi->v == lhj->v))
+ {
lhj->l = -1.0f;
+ is_double = true;
}
}
}
}
- /* delete-in-place loop: copying from pos j to pos i+1 */
- i = 0;
- j = 1;
- while (j < n) {
- lhi = &linehits[i];
- lhj = &linehits[j];
- if (lhj->l == -1.0f) {
- j++; /* skip copying this one */
- }
- else {
- /* copy unless a no-op */
- if (lhi->l == -1.0f) {
- /* could happen if linehits[0] is being deleted */
- memcpy(&linehits[i], &linehits[j], sizeof(KnifeLineHit));
+ if (is_double) {
+ /* delete-in-place loop: copying from pos j to pos i+1 */
+ i = 0;
+ j = 1;
+ while (j < n) {
+ lhi = &linehits[i];
+ lhj = &linehits[j];
+ if (lhj->l == -1.0f) {
+ j++; /* skip copying this one */
}
else {
- if (i + 1 != j)
- memcpy(&linehits[i + 1], &linehits[j], sizeof(KnifeLineHit));
- i++;
+ /* copy unless a no-op */
+ if (lhi->l == -1.0f) {
+ /* could happen if linehits[0] is being deleted */
+ memcpy(&linehits[i], &linehits[j], sizeof(KnifeLineHit));
+ }
+ else {
+ if (i + 1 != j)
+ memcpy(&linehits[i + 1], &linehits[j], sizeof(KnifeLineHit));
+ i++;
+ }
+ j++;
}
- j++;
}
+ kcd->totlinehit = i + 1;
}
- kcd->totlinehit = i + 1;
}
/* Add hit to list of hits in facehits[f], where facehits is a map, if not already there */
@@ -667,9 +699,38 @@ static void add_hit_to_facehits(KnifeTool_OpData *kcd, GHash *facehits, BMFace *
knife_append_list_no_dup(kcd, lst, hit);
}
+/**
+ * special purpose function, if the linehit is connected to a real edge/vert
+ * return true if \a co is outside the face.
+ */
+static bool knife_add_single_cut__is_linehit_outside_face(BMFace *f, const KnifeLineHit *lh, const float co[3])
+{
+
+ if (lh->v && lh->v->v) {
+ BMLoop *l; /* side-of-loop */
+ if ((l = BM_face_vert_share_loop(f, lh->v->v)) &&
+ (BM_loop_point_side_of_loop_test(l, co) < 0.0f))
+ {
+ return true;
+ }
+ }
+ else if ((lh->kfe && lh->kfe->e)) {
+ BMLoop *l; /* side-of-edge */
+ if ((l = BM_face_edge_share_loop(f, lh->kfe->e)) &&
+ (BM_loop_point_side_of_edge_test(l, co) < 0.0f))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, KnifeLineHit *lh2, BMFace *f)
{
KnifeEdge *kfe, *kfe2;
+ BMEdge *e_base;
if ((lh1->v && lh1->v == lh2->v) ||
(lh1->kfe && lh1->kfe == lh2->kfe))
@@ -677,6 +738,25 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife
return;
}
+ /* if the cut is on an edge, just tag that its a cut and return */
+ if ((lh1->v && lh2->v) &&
+ (lh1->v->v && lh2->v && lh2->v->v) &&
+ (e_base = BM_edge_exists(lh1->v->v, lh2->v->v)))
+ {
+ kfe = get_bm_knife_edge(kcd, e_base);
+ kfe->is_cut = true;
+ kfe->e = e_base;
+ return;
+ }
+ else {
+ if (knife_add_single_cut__is_linehit_outside_face(f, lh1, lh2->hit) ||
+ knife_add_single_cut__is_linehit_outside_face(f, lh2, lh1->hit))
+ {
+ return;
+ }
+ }
+
+
/* Check if edge actually lies within face (might not, if this face is concave) */
if ((lh1->v && !lh1->kfe) && (lh2->v && !lh2->kfe)) {
if (!knife_verts_edge_in_face(lh1->v, lh2->v, f)) {
@@ -685,7 +765,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife
}
kfe = new_knife_edge(kcd);
- kfe->draw = true;
+ kfe->is_cut = true;
kfe->basef = f;
if (lh1->v) {
@@ -698,7 +778,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife
else {
BLI_assert(lh1->f);
kfe->v1 = new_knife_vert(kcd, lh1->hit, lh1->cagehit);
- kfe->v1->draw = true;
+ kfe->v1->is_cut = true;
kfe->v1->is_face = true;
knife_append_list(kcd, &kfe->v1->faces, lh1->f);
lh1->v = kfe->v1; /* record the KnifeVert for this hit */
@@ -714,7 +794,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife
else {
BLI_assert(lh2->f);
kfe->v2 = new_knife_vert(kcd, lh2->hit, lh2->cagehit);
- kfe->v2->draw = true;
+ kfe->v2->is_cut = true;
kfe->v2->is_face = true;
knife_append_list(kcd, &kfe->v2->faces, lh2->f);
lh2->v = kfe->v2; /* record the KnifeVert for this hit */
@@ -735,23 +815,13 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, Knife
static void knife_cut_face(KnifeTool_OpData *kcd, BMFace *f, ListBase *hits)
{
Ref *r;
- KnifeLineHit *lh, *prevlh;
- int n;
-
- (void) kcd;
- n = BLI_countlist(hits);
- if (n < 2)
+ if (BLI_listbase_count_ex(hits, 2) != 2)
return;
- prevlh = NULL;
- for (r = hits->first; r; r = r->next) {
- lh = (KnifeLineHit *)r->ref;
- if (prevlh)
- knife_add_single_cut(kcd, prevlh, lh, f);
- prevlh = lh;
+ for (r = hits->first; r->next; r = r->next) {
+ knife_add_single_cut(kcd, r->ref, r->next->ref, f);
}
-
}
/* User has just left-clicked after the first time.
@@ -771,7 +841,9 @@ static void knife_add_cut(KnifeTool_OpData *kcd)
prepare_linehits_for_cut(kcd);
if (kcd->totlinehit == 0) {
- kcd->prev = kcd->curr;
+ if (kcd->is_drag_hold == false) {
+ kcd->prev = kcd->curr;
+ }
return;
}
@@ -806,10 +878,19 @@ static void knife_add_cut(KnifeTool_OpData *kcd)
/* set up for next cut */
kcd->prev = kcd->curr;
+
+
if (kcd->prev.bmface) {
+ KnifeLineHit *lh;
/* was "in face" but now we have a KnifeVert it is snapped to */
+ lh = &kcd->linehits[kcd->totlinehit - 1];
+ kcd->prev.vert = lh->v;
kcd->prev.bmface = NULL;
- kcd->prev.vert = kcd->linehits[kcd->totlinehit - 1].v;
+ }
+
+ if (kcd->is_drag_hold) {
+ lh = &kcd->linehits[kcd->totlinehit - 1];
+ linehit_to_knifepos(&kcd->prev, lh);
}
BLI_ghash_free(facehits, NULL, NULL);
@@ -1055,7 +1136,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
BLI_mempool_iternew(kcd->kedges, &iter);
for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) {
- if (!kfe->draw)
+ if (!kfe->is_cut)
continue;
glColor3ubv(kcd->colors.line);
@@ -1077,7 +1158,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
glBegin(GL_POINTS);
BLI_mempool_iternew(kcd->kverts, &iter);
for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) {
- if (!kfv->draw)
+ if (!kfv->is_cut)
continue;
glColor3ubv(kcd->colors.point);
@@ -1185,9 +1266,84 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
kcd->ortho_extent = max_xyz;
}
-/* Check if p is visible (not clipped, not occluded by another face).
- * s in screen projection of p. */
-static bool point_is_visible(KnifeTool_OpData *kcd, const float p[3], const float s[2], bglMats *mats)
+static BMElem *bm_elem_from_knife_vert(KnifeVert *kfv, KnifeEdge **r_kfe)
+{
+ BMElem *ele_test;
+ KnifeEdge *kfe = NULL;
+
+ /* vert? */
+ ele_test = (BMElem *)kfv->v;
+
+ if (r_kfe || ele_test == NULL) {
+ if (kfv->v == NULL) {
+ Ref *ref;
+ for (ref = kfv->edges.first; ref; ref = ref->next) {
+ kfe = ref->ref;
+ if (kfe->e) {
+ if (r_kfe) {
+ *r_kfe = kfe;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ /* edge? */
+ if (ele_test == NULL) {
+ if (kfe) {
+ ele_test = (BMElem *)kfe->e;
+ }
+ }
+
+ /* face? */
+ if (ele_test == NULL) {
+ if (BLI_listbase_is_single(&kfe->faces)) {
+ ele_test = ((Ref *)kfe->faces.first)->ref;
+ }
+ }
+
+ return ele_test;
+}
+
+static BMElem *bm_elem_from_knife_edge(KnifeEdge *kfe)
+{
+ BMElem *ele_test;
+
+ ele_test = (BMElem *)kfe->e;
+
+ if (ele_test == NULL) {
+ ele_test = (BMElem *)kfe->basef;
+ }
+
+ return ele_test;
+}
+
+static bool bm_ray_cast_cb_elem_not_in_face_check(BMFace *f, void *user_data)
+{
+ switch (((BMElem *)user_data)->head.htype) {
+ case BM_FACE:
+ return (BMFace *)user_data != f;
+ case BM_EDGE:
+ return !BM_edge_in_face((BMEdge *)user_data, f);
+ case BM_VERT:
+ return !BM_vert_in_face((BMVert *)user_data, f);
+ default:
+ return true;
+ }
+}
+
+
+/**
+ * Check if \a p is visible (not clipped, not occluded by another face).
+ * s in screen projection of p.
+ *
+ * \param ele_test Optional vert/edge/face to use when \a p is on the surface of the geometry,
+ * intersecting faces matching this face (or connected when an vert/edge) will be ignored.
+ */
+static bool point_is_visible(
+ KnifeTool_OpData *kcd, const float p[3], const float s[2], bglMats *mats,
+ BMElem *ele_test)
{
BMFace *f_hit;
@@ -1211,7 +1367,7 @@ static bool point_is_visible(KnifeTool_OpData *kcd, const float p[3], const floa
/* make p_ofs a little towards view, so ray doesn't hit p's face. */
sub_v3_v3(view, p);
dist = normalize_v3(view);
- madd_v3_v3v3fl(p_ofs, p, view, KNIFE_FLT_EPSBIG * 3.0f);
+ copy_v3_v3(p_ofs, p);
/* avoid projecting behind the viewpoint */
if (kcd->is_ortho && (kcd->vc.rv3d->persp != RV3D_CAMOB)) {
@@ -1230,9 +1386,19 @@ static bool point_is_visible(KnifeTool_OpData *kcd, const float p[3], const floa
}
/* see if there's a face hit between p1 and the view */
- f_hit = BKE_bmbvh_ray_cast(kcd->bmbvh, p_ofs, view, KNIFE_FLT_EPS, &dist, NULL, NULL);
- if (f_hit)
+ if (ele_test) {
+ f_hit = BKE_bmbvh_ray_cast_filter(
+ kcd->bmbvh, p_ofs, view, KNIFE_FLT_EPS, &dist, NULL, NULL,
+ bm_ray_cast_cb_elem_not_in_face_check, ele_test);
+ }
+ else {
+ f_hit = BKE_bmbvh_ray_cast(
+ kcd->bmbvh, p_ofs, view, KNIFE_FLT_EPS, &dist, NULL, NULL);
+ }
+
+ if (f_hit) {
return false;
+ }
}
return true;
@@ -1274,6 +1440,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
SmallHashIter hiter;
KnifeLineHit hit;
void *val;
+ void **val_p;
float plane_cos[12];
float s[2], se1[2], se2[2], sint[2];
float r1[3], r2[3];
@@ -1281,10 +1448,11 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
float vert_tol, vert_tol_sq;
float line_tol, line_tol_sq;
float face_tol, face_tol_sq;
- float eps_scale;
int isect_kind;
unsigned int tot;
int i;
+ const bool use_hit_prev = true;
+ const bool use_hit_curr = (kcd->is_drag_hold == false);
bgl_get_mats(&mats);
@@ -1360,6 +1528,11 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
ls = (BMLoop **)kcd->em->looptris[result->indexA];
f = ls[0]->f;
set_lowest_face_tri(kcd, f, result->indexA);
+
+ /* occlude but never cut unselected faces (when only_select is used) */
+ if (kcd->only_select && !BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ continue;
+ }
/* for faces, store index of lowest hit looptri in hash */
if (BLI_smallhash_haskey(&faces, (uintptr_t)f)) {
continue;
@@ -1374,27 +1547,18 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
continue;
BLI_smallhash_insert(&kfes, (uintptr_t)kfe, kfe);
v = kfe->v1;
- if (!BLI_smallhash_haskey(&kfvs, (uintptr_t)v))
- BLI_smallhash_insert(&kfvs, (uintptr_t)v, v);
+ BLI_smallhash_reinsert(&kfvs, (uintptr_t)v, v);
v = kfe->v2;
- if (!BLI_smallhash_haskey(&kfvs, (uintptr_t)v))
- BLI_smallhash_insert(&kfvs, (uintptr_t)v, v);
+ BLI_smallhash_reinsert(&kfvs, (uintptr_t)v, v);
}
}
/* Now go through the candidates and find intersections */
/* These tolerances, in screen space, are for intermediate hits, as ends are already snapped to screen */
- {
- /* Scale the epsilon by the zoom level
- * to compensate for projection imprecision, see T41164 */
- float zoom_xy[2] = {kcd->vc.rv3d->winmat[0][0],
- kcd->vc.rv3d->winmat[1][1]};
- eps_scale = len_v2(zoom_xy);
- }
- vert_tol = KNIFE_FLT_EPS_PX * eps_scale;
- line_tol = KNIFE_FLT_EPS_PX * eps_scale;
- face_tol = max_ff(vert_tol, line_tol);
+ vert_tol = KNIFE_FLT_EPS_PX_VERT;
+ line_tol = KNIFE_FLT_EPS_PX_EDGE;
+ face_tol = KNIFE_FLT_EPS_PX_FACE;
vert_tol_sq = vert_tol * vert_tol;
line_tol_sq = line_tol * line_tol;
@@ -1403,30 +1567,55 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
/* Assume these tolerances swamp floating point rounding errors in calculations below */
/* first look for vertex hits */
- for (val = BLI_smallhash_iternew(&kfvs, &hiter, (uintptr_t *)&v); val;
- val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&v))
+ for (val_p = BLI_smallhash_iternew_p(&kfvs, &hiter, (uintptr_t *)&v); val_p;
+ val_p = BLI_smallhash_iternext_p(&hiter, (uintptr_t *)&v))
{
+ KnifeEdge *kfe_hit = NULL;
+
knife_project_v2(kcd, v->cageco, s);
d = dist_squared_to_line_segment_v2(s, s1, s2);
- if (d <= vert_tol_sq) {
- if (point_is_visible(kcd, v->cageco, s, &mats)) {
- memset(&hit, 0, sizeof(hit));
- hit.v = v;
- copy_v3_v3(hit.hit, v->co);
- copy_v3_v3(hit.cagehit, v->cageco);
- copy_v2_v2(hit.schit, s);
- set_linehit_depth(kcd, &hit);
- BLI_array_append(linehits, hit);
+ if ((d <= vert_tol_sq) &&
+ (point_is_visible(kcd, v->cageco, s, &mats, bm_elem_from_knife_vert(v, &kfe_hit))))
+ {
+ memset(&hit, 0, sizeof(hit));
+ hit.v = v;
+
+ /* If this isn't from an existing BMVert, it may have been added to a BMEdge originally.
+ * knowing if the hit comes from an edge is important for edge-in-face checks later on
+ * see: #knife_add_single_cut -> #knife_verts_edge_in_face, T42611 */
+ if (kfe_hit) {
+ hit.kfe = kfe_hit;
}
+
+ copy_v3_v3(hit.hit, v->co);
+ copy_v3_v3(hit.cagehit, v->cageco);
+ copy_v2_v2(hit.schit, s);
+ set_linehit_depth(kcd, &hit);
+ BLI_array_append(linehits, hit);
+ }
+ else {
+ /* note that these vertes aren't used */
+ *val_p = NULL;
}
}
+
/* now edge hits; don't add if a vertex at end of edge should have hit */
for (val = BLI_smallhash_iternew(&kfes, &hiter, (uintptr_t *)&kfe); val;
val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&kfe))
{
+ int kfe_verts_in_cut;
+ /* if we intersect both verts, don't attempt to intersect the edge */
+
+ kfe_verts_in_cut = (BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v1) != NULL) +
+ (BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v2) != NULL);
+
+ if (kfe_verts_in_cut == 2) {
+ continue;
+ }
+
knife_project_v2(kcd, kfe->v1->cageco, se1);
knife_project_v2(kcd, kfe->v2->cageco, se2);
- isect_kind = isect_seg_seg_v2_point(s1, s2, se1, se2, sint);
+ isect_kind = (kfe_verts_in_cut) ? -1 : isect_seg_seg_v2_point(s1, s2, se1, se2, sint);
if (isect_kind == -1) {
/* isect_seg_seg_v2 doesn't do tolerance test around ends of s1-s2 */
closest_to_line_segment_v2(sint, s1, se1, se2);
@@ -1449,7 +1638,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
* Need to find 3d intersection of ray through sint */
knife_input_ray_segment(kcd, sint, 1.0f, r1, r2);
isect_kind = isect_line_line_v3(kfe->v1->cageco, kfe->v2->cageco, r1, r2, p_cage, p_cage_tmp);
- if (isect_kind >= 1 && point_is_visible(kcd, p_cage, sint, &mats)) {
+ if (isect_kind >= 1 && point_is_visible(kcd, p_cage, sint, &mats, bm_elem_from_knife_edge(kfe))) {
memset(&hit, 0, sizeof(hit));
if (kcd->snap_midpoints) {
/* choose intermediate point snap too */
@@ -1477,8 +1666,8 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
{
float p[3], p_cage[3];
- if (knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) {
- if (point_is_visible(kcd, p_cage, s1, &mats)) {
+ if (use_hit_prev && knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) {
+ if (point_is_visible(kcd, p_cage, s1, &mats, (BMElem *)f)) {
memset(&hit, 0, sizeof(hit));
hit.f = f;
copy_v3_v3(hit.hit, p);
@@ -1488,8 +1677,9 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
BLI_array_append(linehits, hit);
}
}
- if (knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) {
- if (point_is_visible(kcd, p_cage, s2, &mats)) {
+
+ if (use_hit_curr && knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) {
+ if (point_is_visible(kcd, p_cage, s2, &mats, (BMElem *)f)) {
memset(&hit, 0, sizeof(hit));
hit.f = f;
copy_v3_v3(hit.hit, p);
@@ -1551,6 +1741,10 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float
f = BKE_bmbvh_ray_cast(kcd->bmbvh, origin, ray, 0.0f, NULL, co, cageco);
+ if (f && kcd->only_select && BM_elem_flag_test(f, BM_ELEM_SELECT) == 0) {
+ f = NULL;
+ }
+
if (is_space)
*is_space = !f;
@@ -1913,7 +2107,10 @@ static int knife_update_active(KnifeTool_OpData *kcd)
kcd->curr.vert = knife_find_closest_vert(kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space);
- if (!kcd->curr.vert) {
+ if (!kcd->curr.vert &&
+ /* no edge snapping while dragging (edges are too sticky when cuts are immediate) */
+ !kcd->is_drag_hold)
+ {
kcd->curr.edge = knife_find_closest_edge(kcd, kcd->curr.co, kcd->curr.cage,
&kcd->curr.bmface, &kcd->curr.is_space);
}
@@ -1942,34 +2139,17 @@ static int knife_update_active(KnifeTool_OpData *kcd)
return 1;
}
-/* sort list of kverts by fraction along edge e */
-static void sort_by_frac_along(ListBase *lst, BMEdge *e)
+static int sort_verts_by_dist_cb(void *co_p, const void *cur_a_p, const void *cur_b_p)
{
- /* note, since we know the point is along the edge, sort from distance to v1co */
- const float *v1co = e->v1->co;
- Ref *cur = NULL, *prev = NULL, *next = NULL;
-
- if (lst->first == lst->last)
- return;
-
- for (cur = ((Ref *)lst->first)->next; cur; cur = next) {
- KnifeVert *vcur = cur->ref;
- const float vcur_fac_sq = len_squared_v3v3(v1co, vcur->co);
+ const KnifeVert *cur_a = ((const Ref *)cur_a_p)->ref;
+ const KnifeVert *cur_b = ((const Ref *)cur_b_p)->ref;
+ const float *co = co_p;
+ const float a_sq = len_squared_v3v3(co, cur_a->co);
+ const float b_sq = len_squared_v3v3(co, cur_b->co);
- next = cur->next;
- prev = cur->prev;
-
- BLI_remlink(lst, cur);
-
- while (prev) {
- KnifeVert *vprev = prev->ref;
- if (len_squared_v3v3(v1co, vprev->co) <= vcur_fac_sq)
- break;
- prev = prev->prev;
- }
-
- BLI_insertlinkafter(lst, prev, cur);
- }
+ if (a_sq < b_sq) return -1;
+ else if (a_sq > b_sq) return 1;
+ else return 0;
}
/* The chain so far goes from an instantiated vertex to kfv (some may be reversed).
@@ -2063,7 +2243,7 @@ static ListBase *find_chain(KnifeTool_OpData *kcd, ListBase *fedges)
break;
}
if (ans) {
- BLI_assert(BLI_countlist(ans) > 0);
+ BLI_assert(!BLI_listbase_is_empty(ans));
for (r = ans->first; r; r = r->next) {
ref = find_ref(fedges, r->ref);
BLI_assert(ref != NULL);
@@ -2171,7 +2351,7 @@ static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, L
int besti[2], bestj[2];
float dist_sq, dist_best_sq;
- nh = BLI_countlist(hole);
+ nh = BLI_listbase_count(hole);
nf = f->len;
if (nh < 2 || nf < 3)
return false;
@@ -2300,13 +2480,22 @@ static bool knife_verts_edge_in_face(KnifeVert *v1, KnifeVert *v2, BMFace *f)
{
bool v1_inside, v2_inside;
bool v1_inface, v2_inface;
+ BMLoop *l1, *l2;
if (!f || !v1 || !v2)
return false;
+ l1 = v1->v ? BM_face_vert_share_loop(f, v1->v) : NULL;
+ l2 = v2->v ? BM_face_vert_share_loop(f, v2->v) : NULL;
+
+ if ((l1 && l2) && BM_loop_is_adjacent(l1, l2)) {
+ /* boundary-case, always false to avoid edge-in-face checks below */
+ return false;
+ }
+
/* find out if v1 and v2, if set, are part of the face */
- v1_inface = v1->v ? BM_vert_in_face(f, v1->v) : false;
- v2_inface = v2->v ? BM_vert_in_face(f, v2->v) : false;
+ v1_inface = (l1 != NULL);
+ v2_inface = (l2 != NULL);
/* BM_face_point_inside_test uses best-axis projection so this isn't most accurate test... */
v1_inside = v1_inface ? false : BM_face_point_inside_test(f, v1->co);
@@ -2348,7 +2537,7 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha
KnifeVert *kfv, *kfvprev;
BMLoop *l_new, *l_iter;
int i;
- int nco = BLI_countlist(chain) - 1;
+ int nco = BLI_listbase_count(chain) - 1;
float (*cos)[3] = BLI_array_alloca(cos, nco);
KnifeVert **kverts = BLI_array_alloca(kverts, nco);
@@ -2421,7 +2610,7 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe
Ref *ref, *refnext;
int count, oldcount;
- oldcount = BLI_countlist(kfedges);
+ oldcount = BLI_listbase_count(kfedges);
while ((chain = find_chain(kcd, kfedges)) != NULL) {
ListBase fnew_kfedges;
knife_make_chain_cut(kcd, f, chain, &fnew);
@@ -2450,7 +2639,7 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe
/* find_chain should always remove edges if it returns true,
* but guard against infinite loop anyway */
- count = BLI_countlist(kfedges);
+ count = BLI_listbase_count(kfedges);
if (count >= oldcount) {
BLI_assert(!"knife find_chain infinite loop");
return;
@@ -2518,7 +2707,7 @@ static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfe
break;
/* find_hole should always remove edges if it returns true,
* but guard against infinite loop anyway */
- count = BLI_countlist(kfedges);
+ count = BLI_listbase_count(kfedges);
if (count >= oldcount) {
BLI_assert(!"knife find_hole infinite loop");
return;
@@ -2550,6 +2739,14 @@ static void knife_make_cuts(KnifeTool_OpData *kcd)
/* put list of cutting edges for a face into fhash, keyed by face */
BLI_mempool_iternew(kcd->kedges, &iter);
for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) {
+
+ /* select edges that lie directly on the cut */
+ if (kcd->select_result) {
+ if (kfe->e && kfe->is_cut) {
+ BM_edge_select_set(bm, kfe->e, true);
+ }
+ }
+
f = kfe->basef;
if (!f || kfe->e)
continue;
@@ -2586,7 +2783,8 @@ static void knife_make_cuts(KnifeTool_OpData *kcd)
for (lst = BLI_smallhash_iternew(ehash, &hiter, (uintptr_t *)&e); lst;
lst = BLI_smallhash_iternext(&hiter, (uintptr_t *)&e))
{
- sort_by_frac_along(lst, e);
+ BLI_listbase_sort_r(lst, e->v1->co, sort_verts_by_dist_cb);
+
for (ref = lst->first; ref; ref = ref->next) {
kfv = ref->ref;
pct = line_point_factor_v3(kfv->co, e->v1->co, e->v2->co);
@@ -2617,6 +2815,9 @@ static void knifetool_finish_ex(KnifeTool_OpData *kcd)
EDBM_selectmode_flush(kcd->em);
EDBM_mesh_normals_update(kcd->em);
EDBM_update_generic(kcd->em, true, true);
+
+ /* re-tessellating makes this invalid, dont use again by accident */
+ knifetool_free_bmbvh(kcd);
}
static void knifetool_finish(wmOperator *op)
{
@@ -2661,14 +2862,12 @@ static void knifetool_exit_ex(bContext *C, KnifeTool_OpData *kcd)
BLI_ghash_free(kcd->kedgefacemap, NULL, NULL);
BLI_ghash_free(kcd->facetrimap, NULL, NULL);
- BKE_bmbvh_free(kcd->bmbvh);
BLI_memarena_free(kcd->arena);
/* tag for redraw */
ED_region_tag_redraw(kcd->ar);
- if (kcd->cagecos)
- MEM_freeN((void *)kcd->cagecos);
+ knifetool_free_bmbvh(kcd);
if (kcd->linehits)
MEM_freeN(kcd->linehits);
@@ -2699,6 +2898,32 @@ static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2])
knifetool_update_mval(kcd, mval);
}
+static void knifetool_init_bmbvh(KnifeTool_OpData *kcd)
+{
+ BM_mesh_elem_index_ensure(kcd->em->bm, BM_VERT);
+
+ kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(kcd->em, kcd->scene, NULL);
+
+ kcd->bmbvh = BKE_bmbvh_new_from_editmesh(
+ kcd->em,
+ BMBVH_RETURN_ORIG |
+ ((kcd->only_select && kcd->cut_through) ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN),
+ kcd->cagecos, false);
+}
+
+static void knifetool_free_bmbvh(KnifeTool_OpData *kcd)
+{
+ if (kcd->bmbvh) {
+ BKE_bmbvh_free(kcd->bmbvh);
+ kcd->bmbvh = NULL;
+ }
+
+ if (kcd->cagecos) {
+ MEM_freeN((void *)kcd->cagecos);
+ kcd->cagecos = NULL;
+ }
+}
+
/* called when modal loop selection gets set up... */
static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
const bool only_select, const bool cut_through, const bool is_interactive)
@@ -2707,6 +2932,7 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
Object *obedit = CTX_data_edit_object(C);
/* assign the drawing handle for drawing preview line... */
+ kcd->scene = scene;
kcd->ob = obedit;
kcd->ar = CTX_wm_region(C);
@@ -2714,14 +2940,12 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
kcd->em = BKE_editmesh_from_object(kcd->ob);
- BM_mesh_elem_index_ensure(kcd->em->bm, BM_VERT);
-
- kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(kcd->em, scene, NULL);
+ /* cut all the way through the mesh if use_occlude_geometry button not pushed */
+ kcd->is_interactive = is_interactive;
+ kcd->cut_through = cut_through;
+ kcd->only_select = only_select;
- kcd->bmbvh = BKE_bmbvh_new_from_editmesh(kcd->em,
- BMBVH_RETURN_ORIG |
- (only_select ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN),
- kcd->cagecos, false);
+ knifetool_init_bmbvh(kcd);
kcd->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 15), "knife");
kcd->vthresh = KMAXDIST - 1;
@@ -2740,11 +2964,6 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
kcd->kedgefacemap = BLI_ghash_ptr_new("knife kedgefacemap");
kcd->facetrimap = BLI_ghash_ptr_new("knife facetrimap");
- /* cut all the way through the mesh if use_occlude_geometry button not pushed */
- kcd->is_interactive = is_interactive;
- kcd->cut_through = cut_through;
- kcd->only_select = only_select;
-
/* can't usefully select resulting edges in face mode */
kcd->select_result = (kcd->em->selectmode != SCE_SELECT_FACE);
@@ -2809,7 +3028,8 @@ enum {
KNF_MODAL_ADD_CUT,
KNF_MODAL_ANGLE_SNAP_TOGGLE,
KNF_MODAL_CUT_THROUGH_TOGGLE,
- KNF_MODAL_PANNING
+ KNF_MODAL_PANNING,
+ KNF_MODAL_ADD_CUT_CLOSED,
};
wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
@@ -2840,7 +3060,8 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
/* items for modal map */
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, KNF_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_ANY, KM_ANY, 0, KNF_MODAL_PANNING);
- WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, KNF_MODAL_ADD_CUT);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_DBL_CLICK, KM_ANY, 0, KNF_MODAL_ADD_CUT_CLOSED);
+ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, KNF_MODAL_ADD_CUT);
WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, KNF_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, KNF_MODAL_CONFIRM);
WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, KNF_MODAL_CONFIRM);
@@ -2951,16 +3172,53 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
case KNF_MODAL_ADD_CUT:
knife_recalc_projmat(kcd);
- if (kcd->mode == MODE_DRAGGING) {
- knife_add_cut(kcd);
+ /* get the value of the event which triggered this one */
+ if (event->prevval != KM_RELEASE) {
+ if (kcd->mode == MODE_DRAGGING) {
+ knife_add_cut(kcd);
+ }
+ else if (kcd->mode != MODE_PANNING) {
+ knife_start_cut(kcd);
+ kcd->mode = MODE_DRAGGING;
+ kcd->init = kcd->curr;
+ }
+
+ /* freehand drawing is incompatible with cut-through */
+ if (kcd->cut_through == false) {
+ kcd->is_drag_hold = true;
+ }
}
- else if (kcd->mode != MODE_PANNING) {
- knife_start_cut(kcd);
- kcd->mode = MODE_DRAGGING;
+ else {
+ kcd->is_drag_hold = false;
+
+ /* needed because the last face 'hit' is ignored when dragging */
+ knifetool_update_mval(kcd, kcd->curr.mval);
}
ED_region_tag_redraw(kcd->ar);
break;
+ case KNF_MODAL_ADD_CUT_CLOSED:
+ if (kcd->mode == MODE_DRAGGING) {
+
+ /* shouldn't be possible with default key-layout, just incase... */
+ if (kcd->is_drag_hold) {
+ kcd->is_drag_hold = false;
+ knifetool_update_mval(kcd, kcd->curr.mval);
+ }
+
+ kcd->prev = kcd->curr;
+ kcd->curr = kcd->init;
+
+ knife_project_v2(kcd, kcd->curr.cage, kcd->curr.mval);
+ knifetool_update_mval(kcd, kcd->curr.mval);
+
+ knife_add_cut(kcd);
+
+ /* KNF_MODAL_NEW_CUT */
+ knife_finish_cut(kcd);
+ kcd->mode = MODE_IDLE;
+ }
+ break;
case KNF_MODAL_PANNING:
if (event->val != KM_RELEASE) {
if (kcd->mode != MODE_PANNING) {
@@ -2987,6 +3245,12 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
case MOUSEMOVE: /* mouse moved somewhere to select another loop */
if (kcd->mode != MODE_PANNING) {
knifetool_update_mval_i(kcd, event->mval);
+
+ if (kcd->is_drag_hold) {
+ if (kcd->totlinehit >= 2) {
+ knife_add_cut(kcd);
+ }
+ }
}
break;
@@ -3034,16 +3298,14 @@ void MESH_OT_knife_tool(wmOperatorType *ot)
* tessellation here seems way overkill,
* but without this its very hard to know of a point is inside the face
*/
-static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3])
+static void edbm_mesh_knife_face_point(BMFace *f, float r_cent[3])
{
const int tottri = f->len - 2;
BMLoop **loops = BLI_array_alloca(loops, f->len);
unsigned int (*index)[3] = BLI_array_alloca(index, tottri);
int j;
-
- const float *best_co[3] = {NULL};
- float best_area = -1.0f;
- bool ok = false;
+ int j_best = 0; /* use as fallback when unset */
+ float area_best = -1.0f;
BM_face_calc_tessellation(f, loops, index);
@@ -3056,49 +3318,34 @@ static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3])
float cross[3];
cross_v3_v3v3(cross, p2, p3);
area = fabsf(dot_v3v3(p1, cross));
- if (area > best_area) {
- best_co[0] = p1;
- best_co[1] = p2;
- best_co[2] = p3;
- best_area = area;
- ok = true;
+ if (area > area_best) {
+ j_best = j;
+ area_best = area;
}
}
- if (ok) {
- mid_v3_v3v3v3(r_cent, best_co[0], best_co[1], best_co[2]);
- }
- else {
- mid_v3_v3v3v3(r_cent, loops[0]->v->co, loops[1]->v->co, loops[2]->v->co);
- }
+ mid_v3_v3v3v3(
+ r_cent,
+ loops[index[j_best][0]]->v->co,
+ loops[index[j_best][1]]->v->co,
+ loops[index[j_best][2]]->v->co);
}
-static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f, float projmat[4][4])
+static bool edbm_mesh_knife_point_isect(LinkNode *polys, const float cent_ss[2])
{
- float cent_ss[2];
- float cent[3];
-
- edvm_mesh_knife_face_point(f, cent);
-
- ED_view3d_project_float_v2_m4(ar, cent, cent_ss, projmat);
+ LinkNode *p = polys;
+ int isect = 0;
- /* check */
- {
- LinkNode *p = polys;
- int isect = 0;
-
- while (p) {
- const float (*mval_fl)[2] = p->link;
- const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
- isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false);
- p = p->next;
- }
-
- if (isect % 2) {
- return true;
- }
+ while (p) {
+ const float (*mval_fl)[2] = p->link;
+ const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
+ isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false);
+ p = p->next;
}
+ if (isect % 2) {
+ return true;
+ }
return false;
}
@@ -3108,6 +3355,7 @@ static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f,
void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_through)
{
KnifeTool_OpData *kcd;
+ bglMats mats;
view3d_operator_needs_opengl(C);
@@ -3126,6 +3374,10 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
if (use_tag) {
BM_mesh_elem_hflag_enable_all(kcd->em->bm, BM_EDGE, BM_ELEM_TAG, false);
}
+
+ if (kcd->cut_through == false) {
+ bgl_get_mats(&mats);
+ }
}
/* execute */
@@ -3169,6 +3421,11 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
bool keep_search;
+ /* freed on knifetool_finish_ex, but we need again to check if points are visible */
+ if (kcd->cut_through == false) {
+ knifetool_init_bmbvh(kcd);
+ }
+
ED_view3d_ob_project_mat_get(kcd->ar->regiondata, kcd->ob, projmat);
/* use face-loop tag to store if we have intersected */
@@ -3190,7 +3447,10 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
BMFace *f;
BMIter fiter;
BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
- if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+ float cent[3], cent_ss[2];
+ edbm_mesh_knife_face_point(f, cent);
+ knife_project_v2(kcd, cent, cent_ss);
+ if (edbm_mesh_knife_point_isect(polys, cent_ss)) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
}
}
@@ -3223,7 +3483,12 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
} while ((l_iter = l_iter->next) != l_first && (found == false));
if (found) {
- if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+ float cent[3], cent_ss[2];
+ edbm_mesh_knife_face_point(f, cent);
+ knife_project_v2(kcd, cent, cent_ss);
+ if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, &mats, (BMElem *)f)) &&
+ edbm_mesh_knife_point_isect(polys, cent_ss))
+ {
BM_elem_flag_enable(f, BM_ELEM_TAG);
keep_search = true;
}
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index b5508ef8b82..3d93210382c 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -412,7 +412,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT,
smoothness, smooth_falloff, true,
0.0f, 0.0f,
- cuts, seltype, SUBD_PATH, 0, true,
+ cuts, seltype, SUBD_CORNER_PATH, 0, true,
use_only_quads, 0);
/* when used in a macro tessface is already re-recalculated */
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index 44d03da93a2..4eaac6cc1d3 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -32,9 +32,12 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_windowmanager_types.h"
+#ifdef WITH_FREESTYLE
+# include "DNA_meshdata_types.h"
+#endif
+
#include "BLI_math.h"
#include "BLI_linklist.h"
@@ -99,7 +102,7 @@ static bool mouse_mesh_shortest_path_vert(ViewContext *vc)
if (v_act && (v_act != v_dst)) {
if ((path = BM_mesh_calc_path_vert(bm, v_act, v_dst, use_length,
- &user_data, verttag_filter_cb)))
+ verttag_filter_cb, &user_data)))
{
BM_select_history_remove(bm, v_act);
}
@@ -267,7 +270,7 @@ static bool mouse_mesh_shortest_path_edge(ViewContext *vc)
if (e_act && (e_act != e_dst)) {
if ((path = BM_mesh_calc_path_edge(bm, e_act, e_dst, use_length,
- &user_data, edgetag_filter_cb)))
+ edgetag_filter_cb, &user_data)))
{
BM_select_history_remove(bm, e_act);
}
@@ -388,7 +391,7 @@ static bool mouse_mesh_shortest_path_face(ViewContext *vc)
if (f_act) {
if (f_act != f_dst) {
if ((path = BM_mesh_calc_path_face(bm, f_act, f_dst, use_length,
- &user_data, facetag_filter_cb)))
+ facetag_filter_cb, &user_data)))
{
BM_select_history_remove(bm, f_act);
}
@@ -513,11 +516,6 @@ void MESH_OT_shortest_path_pick(wmOperatorType *ot)
/* -------------------------------------------------------------------- */
/* Select path between existing selection */
-static bool ele_filter_visible_cb(BMElem *ele, void *UNUSED(user_data))
-{
- return !BM_elem_flag_test(ele, BM_ELEM_HIDDEN);
-}
-
static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_edit_object(C);
@@ -577,17 +575,17 @@ static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
case BM_VERT:
path = BM_mesh_calc_path_vert(
bm, (BMVert *)ele_src, (BMVert *)ele_dst, use_length,
- NULL, (bool (*)(BMVert *, void *))ele_filter_visible_cb);
+ BM_elem_cb_check_hflag_disabled_simple(BMVert *, BM_ELEM_HIDDEN));
break;
case BM_EDGE:
path = BM_mesh_calc_path_edge(
bm, (BMEdge *)ele_src, (BMEdge *)ele_dst, use_length,
- NULL, (bool (*)(BMEdge *, void *))ele_filter_visible_cb);
+ BM_elem_cb_check_hflag_disabled_simple(BMEdge *, BM_ELEM_HIDDEN));
break;
case BM_FACE:
path = BM_mesh_calc_path_face(
bm, (BMFace *)ele_src, (BMFace *)ele_dst, use_length,
- NULL, (bool (*)(BMFace *, void *))ele_filter_visible_cb);
+ BM_elem_cb_check_hflag_disabled_simple(BMFace *, BM_ELEM_HIDDEN));
break;
}
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 4f149bf2c52..ead243d6de8 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -626,7 +626,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve
* split off vertex if...
* - we cant find an edge - this means we are ripping a faces vert that is connected to other
* geometry only at the vertex.
- * - the boundary edge total is greater then 2,
+ * - the boundary edge total is greater than 2,
* in this case edge split _can_ work but we get far nicer results if we use this special case.
* - there are only 2 edges but we are a wire vert. */
if ((is_wire == false && totboundary_edge > 2) ||
diff --git a/source/blender/editors/mesh/editmesh_rip_edge.c b/source/blender/editors/mesh/editmesh_rip_edge.c
index 5daf33fae3b..a501dfc8c2c 100644
--- a/source/blender/editors/mesh/editmesh_rip_edge.c
+++ b/source/blender/editors/mesh/editmesh_rip_edge.c
@@ -24,8 +24,6 @@
* based on mouse cursor position, split of vertices along the closest edge.
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_object_types.h"
#include "BLI_math.h"
@@ -34,9 +32,6 @@
#include "BKE_report.h"
#include "BKE_editmesh.h"
-#include "RNA_define.h"
-#include "RNA_access.h"
-
#include "WM_types.h"
#include "ED_mesh.h"
@@ -177,7 +172,7 @@ static int edbm_rip_edge_invoke(bContext *C, wmOperator *UNUSED(op), const wmEve
ED_view3d_project_float_v2_m4(ar, v_other->co, v_other_sco, projectMat);
- /* avoid comparing with view-axis aligned edges (less then a pixel) */
+ /* avoid comparing with view-axis aligned edges (less than a pixel) */
if (len_squared_v2v2(v_sco, v_other_sco) > 1.0f) {
float v_dir[2];
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 473da4c9756..d3073d519f6 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -38,7 +38,6 @@
#include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_array.h"
-#include "BLI_smallhash.h"
#include "BKE_context.h"
#include "BKE_report.h"
@@ -62,8 +61,6 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "GPU_extensions.h"
-
#include "UI_resources.h"
#include "bmesh_tools.h"
@@ -386,8 +383,6 @@ static void findnearestvert__doClosest(void *userData, BMVert *eve, const float
}
-
-
static bool findnearestvert__backbufIndextest(void *handle, unsigned int index)
{
BMEditMesh *em = (BMEditMesh *)handle;
@@ -711,6 +706,7 @@ static EnumPropertyItem prop_similar_types[] = {
{SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},
{SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
{SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""},
+ {SIMFACE_SMOOTH, "SMOOTH", 0, "Flat/Smooth", ""},
#ifdef WITH_FREESTYLE
{SIMFACE_FREESTYLE, "FREESTYLE_FACE", 0, "Freestyle Face Marks", ""},
#endif
@@ -888,7 +884,7 @@ static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUS
#ifdef WITH_FREESTYLE
const int a_end = SIMFACE_FREESTYLE;
#else
- const int a_end = SIMFACE_COPLANAR;
+ const int a_end = SIMFACE_SMOOTH;
#endif
for (a = SIMFACE_MATERIAL; a <= a_end; a++) {
RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);
@@ -994,6 +990,7 @@ static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
}
MEM_freeN(groups_array);
+ MEM_freeN(group_index);
if (changed) {
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
@@ -2473,12 +2470,13 @@ void MESH_OT_select_mirror(wmOperatorType *ot)
/* ******************** **************** */
-static int edbm_select_more_exec(bContext *C, wmOperator *UNUSED(op))
+static int edbm_select_more_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ const bool use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
- EDBM_select_more(em);
+ EDBM_select_more(em, use_face_step);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
return OPERATOR_FINISHED;
@@ -2497,14 +2495,17 @@ void MESH_OT_select_more(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "use_face_step", true, "Face Step", "Connected faces (instead of edges)");
}
-static int edbm_select_less_exec(bContext *C, wmOperator *UNUSED(op))
+static int edbm_select_less_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ const bool use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
- EDBM_select_less(em);
+ EDBM_select_less(em, use_face_step);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
return OPERATOR_FINISHED;
@@ -2523,6 +2524,8 @@ void MESH_OT_select_less(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "use_face_step", true, "Face Step", "Connected faces (instead of edges)");
}
/**
@@ -3359,8 +3362,8 @@ static int loop_find_region(BMLoop *l, int flag,
static int verg_radial(const void *va, const void *vb)
{
- BMEdge *e_a = *((BMEdge **)va);
- BMEdge *e_b = *((BMEdge **)vb);
+ const BMEdge *e_a = *((const BMEdge **)va);
+ const BMEdge *e_b = *((const BMEdge **)vb);
int a, b;
a = BM_edge_face_count(e_a);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 20c7f4eb521..93ebbbcf620 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -90,9 +90,9 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
const float along_normal = RNA_float_get(op->ptr, "fractal_along_normal");
if (RNA_boolean_get(op->ptr, "quadtri") &&
- RNA_enum_get(op->ptr, "quadcorner") == SUBD_STRAIGHT_CUT)
+ RNA_enum_get(op->ptr, "quadcorner") == SUBD_CORNER_STRAIGHT_CUT)
{
- RNA_enum_set(op->ptr, "quadcorner", SUBD_INNERVERT);
+ RNA_enum_set(op->ptr, "quadcorner", SUBD_CORNER_INNERVERT);
}
BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT,
@@ -110,10 +110,10 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
/* Note, these values must match delete_mesh() event values */
static EnumPropertyItem prop_mesh_cornervert_types[] = {
- {SUBD_INNERVERT, "INNERVERT", 0, "Inner Vert", ""},
- {SUBD_PATH, "PATH", 0, "Path", ""},
- {SUBD_STRAIGHT_CUT, "STRAIGHT_CUT", 0, "Straight Cut", ""},
- {SUBD_FAN, "FAN", 0, "Fan", ""},
+ {SUBD_CORNER_INNERVERT, "INNERVERT", 0, "Inner Vert", ""},
+ {SUBD_CORNER_PATH, "PATH", 0, "Path", ""},
+ {SUBD_CORNER_STRAIGHT_CUT, "STRAIGHT_CUT", 0, "Straight Cut", ""},
+ {SUBD_CORNER_FAN, "FAN", 0, "Fan", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -141,7 +141,7 @@ void MESH_OT_subdivide(wmOperatorType *ot)
RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, FLT_MAX, "Smoothness", "Smoothness factor", 0.0f, 1.0f);
RNA_def_boolean(ot->srna, "quadtri", 0, "Quad/Tri Mode", "Tries to prevent ngons");
- RNA_def_enum(ot->srna, "quadcorner", prop_mesh_cornervert_types, SUBD_STRAIGHT_CUT,
+ RNA_def_enum(ot->srna, "quadcorner", prop_mesh_cornervert_types, SUBD_CORNER_STRAIGHT_CUT,
"Quad Corner Type", "How to subdivide quad corners (anything other than Straight Cut will prevent ngons)");
RNA_def_float(ot->srna, "fractal", 0.0f, 0.0f, FLT_MAX, "Fractal", "Fractal randomness factor", 0.0f, 1000.0f);
@@ -877,23 +877,49 @@ static int edbm_vert_connect_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
BMOperator bmop;
- const bool is_pair = (bm->totvertsel == 2);
- int len;
-
+ bool is_pair = (bm->totvertsel == 2);
+ int len = 0;
+ bool check_degenerate = true;
+ const int verts_len = bm->totvertsel;
+ BMVert **verts;
+
+ verts = MEM_mallocN(sizeof(*verts) * verts_len, __func__);
+ {
+ BMIter iter;
+ BMVert *v;
+ int i = 0;
+
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ verts[i++] = v;
+ }
+ }
+
+ if (is_pair) {
+ if (BM_vert_pair_share_face_check_cb(
+ verts[0], verts[1],
+ BM_elem_cb_check_hflag_disabled_simple(BMFace *, BM_ELEM_HIDDEN)))
+ {
+ check_degenerate = false;
+ is_pair = false;
+ }
+ }
+ }
+
if (is_pair) {
if (!EDBM_op_init(em, &bmop, op,
- "connect_vert_pair verts=%hv verts_exclude=%hv faces_exclude=%hf",
- BM_ELEM_SELECT, BM_ELEM_HIDDEN, BM_ELEM_HIDDEN))
+ "connect_vert_pair verts=%eb verts_exclude=%hv faces_exclude=%hf",
+ verts, verts_len, BM_ELEM_HIDDEN, BM_ELEM_HIDDEN))
{
- return OPERATOR_CANCELLED;
+ goto finally;
}
}
else {
if (!EDBM_op_init(em, &bmop, op,
- "connect_verts verts=%hv faces_exclude=%hf check_degenerate=%b",
- BM_ELEM_SELECT, BM_ELEM_HIDDEN, true))
+ "connect_verts verts=%eb faces_exclude=%hf check_degenerate=%b",
+ verts, verts_len, BM_ELEM_HIDDEN, check_degenerate))
{
- return OPERATOR_CANCELLED;
+ goto finally;
}
}
@@ -908,15 +934,18 @@ static int edbm_vert_connect_exec(bContext *C, wmOperator *op)
}
if (!EDBM_op_finish(em, &bmop, op, true)) {
- return OPERATOR_CANCELLED;
+ len = 0;
}
else {
EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */
EDBM_update_generic(em, true, true);
-
- return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
+
+
+finally:
+ MEM_freeN(verts);
+ return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void MESH_OT_vert_connect(wmOperatorType *ot)
@@ -924,7 +953,7 @@ void MESH_OT_vert_connect(wmOperatorType *ot)
/* identifiers */
ot->name = "Vertex Connect";
ot->idname = "MESH_OT_vert_connect";
- ot->description = "Connect 2 vertices of a face by an edge, splitting the face in two";
+ ot->description = "Connect selected vertices of faces, splitting the face";
/* api callbacks */
ot->exec = edbm_vert_connect_exec;
@@ -935,6 +964,225 @@ void MESH_OT_vert_connect(wmOperatorType *ot)
}
+/**
+ * check that endpoints are verts and only have a single selected edge connected.
+ */
+static bool bm_vert_is_select_history_open(BMesh *bm)
+{
+ BMEditSelection *ele_a = bm->selected.first;
+ BMEditSelection *ele_b = bm->selected.last;
+ if ((ele_a->htype == BM_VERT) &&
+ (ele_b->htype == BM_VERT))
+ {
+ if ((BM_iter_elem_count_flag(BM_EDGES_OF_VERT, (BMVert *)ele_a->ele, BM_ELEM_SELECT, true) == 1) &&
+ (BM_iter_elem_count_flag(BM_EDGES_OF_VERT, (BMVert *)ele_b->ele, BM_ELEM_SELECT, true) == 1))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool bm_vert_connect_pair(BMesh *bm, BMVert *v_a, BMVert *v_b)
+{
+ BMOperator bmop;
+ BMVert **verts;
+ const int totedge_orig = bm->totedge;
+
+ BMO_op_init(bm, &bmop, BMO_FLAG_DEFAULTS, "connect_vert_pair");
+
+ verts = BMO_slot_buffer_alloc(&bmop, bmop.slots_in, "verts", 2);
+ verts[0] = v_a;
+ verts[1] = v_b;
+
+ BM_vert_normal_update(verts[0]);
+ BM_vert_normal_update(verts[1]);
+
+ BMO_op_exec(bm, &bmop);
+ BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
+ BMO_op_finish(bm, &bmop);
+ return (bm->totedge != totedge_orig);
+}
+
+static bool bm_vert_connect_select_history(BMesh *bm)
+{
+ /* Logic is as follows:
+ *
+ * - If there are any isolated/wire verts - connect as edges.
+ * - Otherwise connect faces.
+ * - If all edges have been created already, closed the loop.
+ */
+ if (BLI_listbase_count_ex(&bm->selected, 2) == 2 && (bm->totvertsel > 2)) {
+ BMEditSelection *ese;
+ int tot = 0;
+ bool changed = false;
+ bool has_wire = false;
+ // bool all_verts;
+
+ /* ensure all verts have history */
+ for (ese = bm->selected.first; ese; ese = ese->next, tot++) {
+ BMVert *v;
+ if (ese->htype != BM_VERT) {
+ break;
+ }
+ v = (BMVert *)ese->ele;
+ if ((has_wire == false) && ((v->e == NULL) || BM_vert_is_wire(v))) {
+ has_wire = true;
+ }
+ }
+ // all_verts = (ese == NULL);
+
+ if (has_wire == false) {
+ /* all verts have faces , connect verts via faces! */
+ if (tot == bm->totvertsel) {
+ BMEditSelection *ese_last;
+ ese_last = bm->selected.first;
+ ese = ese_last->next;
+
+ do {
+
+ if (BM_edge_exists((BMVert *)ese_last->ele, (BMVert *)ese->ele)) {
+ /* pass, edge exists (and will be selected) */
+ }
+ else {
+ changed |= bm_vert_connect_pair(bm, (BMVert *)ese_last->ele, (BMVert *)ese->ele);
+ }
+ } while ((ese_last = ese),
+ (ese = ese->next));
+
+ if (changed) {
+ return true;
+ }
+ }
+
+ if (changed == false) {
+ /* existing loops: close the selection */
+ if (bm_vert_is_select_history_open(bm)) {
+ changed |= bm_vert_connect_pair(
+ bm,
+ (BMVert *)((BMEditSelection *)bm->selected.first)->ele,
+ (BMVert *)((BMEditSelection *)bm->selected.last)->ele);
+
+ if (changed) {
+ return true;
+ }
+ }
+ }
+ }
+
+ else {
+ /* no faces, simply connect the verts by edges */
+ BMEditSelection *ese_prev;
+ ese_prev = bm->selected.first;
+ ese = ese_prev->next;
+
+
+ do {
+ if (BM_edge_exists((BMVert *)ese_prev->ele, (BMVert *)ese->ele)) {
+ /* pass, edge exists (and will be selected) */
+ }
+ else {
+ BMEdge *e;
+ e = BM_edge_create(bm, (BMVert *)ese_prev->ele, (BMVert *)ese->ele, NULL, 0);
+ BM_edge_select_set(bm, e, true);
+ changed = true;
+ }
+ } while ((ese_prev = ese),
+ (ese = ese->next));
+
+ if (changed == false) {
+ /* existing loops: close the selection */
+ if (bm_vert_is_select_history_open(bm)) {
+ BMEdge *e;
+ ese_prev = bm->selected.first;
+ ese = bm->selected.last;
+ e = BM_edge_create(bm, (BMVert *)ese_prev->ele, (BMVert *)ese->ele, NULL, 0);
+ BM_edge_select_set(bm, e, true);
+ }
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+static int edbm_vert_connect_path_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ bool is_pair = (em->bm->totvertsel == 2);
+
+ /* when there is only 2 vertices, we can ignore selection order */
+ if (is_pair) {
+ return edbm_vert_connect_exec(C, op);
+ }
+
+ if (bm_vert_connect_select_history(em->bm)) {
+ EDBM_selectmode_flush(em);
+ EDBM_update_generic(em, true, true);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Invalid selection order");
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void MESH_OT_vert_connect_path(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Vertex Connect Path";
+ ot->idname = "MESH_OT_vert_connect_path";
+ ot->description = "Connect vertices by their selection order, creating edges, splitting faces";
+
+ /* api callbacks */
+ ot->exec = edbm_vert_connect_path_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int edbm_vert_connect_concave_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ if (!EDBM_op_call_and_selectf(
+ em, op,
+ "faces.out", true,
+ "connect_verts_concave faces=%hf",
+ BM_ELEM_SELECT))
+ {
+ return OPERATOR_CANCELLED;
+ }
+
+
+ EDBM_update_generic(em, true, true);
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_vert_connect_concave(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Split Concave Faces";
+ ot->idname = "MESH_OT_vert_connect_concave";
+ ot->description = "Make all faces convex";
+
+ /* api callbacks */
+ ot->exec = edbm_vert_connect_concave_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+
static int edbm_vert_connect_nonplaner_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
@@ -2509,7 +2757,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
if (mode == KNIFE_MIDPOINT) numcuts = 1;
BMO_slot_int_set(bmop.slots_in, "cuts", numcuts);
- BMO_slot_int_set(bmop.slots_in, "quad_corner_type", SUBD_STRAIGHT_CUT);
+ BMO_slot_int_set(bmop.slots_in, "quad_corner_type", SUBD_CORNER_STRAIGHT_CUT);
BMO_slot_bool_set(bmop.slots_in, "use_single_edge", false);
BMO_slot_bool_set(bmop.slots_in, "use_grid_fill", false);
@@ -2681,7 +2929,7 @@ static void mesh_separate_material_assign_mat_nr(Object *ob, const short mat_nr)
}
if (mat_nr < *totcolp) {
- ma_obdata = (*matarar)[mat_nr];
+ ma_obdata = (*matarar)[mat_nr];
}
else {
ma_obdata = NULL;
@@ -2929,7 +3177,14 @@ static int edbm_fill_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
const bool use_beauty = RNA_boolean_get(op->ptr, "use_beauty");
BMOperator bmop;
-
+ const int totface_orig = em->bm->totface;
+ int ret;
+
+ if (em->bm->totedgesel == 0) {
+ BKE_report(op->reports, RPT_WARNING, "No edges selected");
+ return OPERATOR_CANCELLED;
+ }
+
if (!EDBM_op_init(em, &bmop, op,
"triangle_fill edges=%he use_beauty=%b",
BM_ELEM_SELECT, use_beauty))
@@ -2939,17 +3194,24 @@ static int edbm_fill_exec(bContext *C, wmOperator *op)
BMO_op_exec(em->bm, &bmop);
- /* select new geometry */
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_FACE | BM_EDGE, BM_ELEM_SELECT, true);
-
- if (!EDBM_op_finish(em, &bmop, op, true)) {
- return OPERATOR_CANCELLED;
+ if (totface_orig != em->bm->totface) {
+ /* select new geometry */
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_FACE | BM_EDGE, BM_ELEM_SELECT, true);
+
+ EDBM_update_generic(em, true, true);
+
+ ret = OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_WARNING, "No faces filled");
+ ret = OPERATOR_CANCELLED;
}
- EDBM_update_generic(em, true, true);
-
- return OPERATOR_FINISHED;
+ if (!EDBM_op_finish(em, &bmop, op, true)) {
+ ret = OPERATOR_CANCELLED;
+ }
+ return ret;
}
void MESH_OT_fill(wmOperatorType *ot)
@@ -3472,10 +3734,16 @@ void MESH_OT_tris_convert_to_quads(wmOperatorType *ot)
/* -------------------------------------------------------------------- */
/* Dissolve */
-static void edbm_dissolve_prop__use_verts(wmOperatorType *ot)
+static void edbm_dissolve_prop__use_verts(wmOperatorType *ot, bool value, int flag)
{
- RNA_def_boolean(ot->srna, "use_verts", 0, "Dissolve Verts",
- "Dissolve remaining vertices");
+ PropertyRNA *prop;
+
+ prop = RNA_def_boolean(ot->srna, "use_verts", value, "Dissolve Verts",
+ "Dissolve remaining vertices");
+
+ if (flag) {
+ RNA_def_property_flag(prop, flag);
+ }
}
static void edbm_dissolve_prop__use_face_split(wmOperatorType *ot)
{
@@ -3560,7 +3828,7 @@ void MESH_OT_dissolve_edges(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- edbm_dissolve_prop__use_verts(ot);
+ edbm_dissolve_prop__use_verts(ot, true, 0);
edbm_dissolve_prop__use_face_split(ot);
}
@@ -3599,7 +3867,7 @@ void MESH_OT_dissolve_faces(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- edbm_dissolve_prop__use_verts(ot);
+ edbm_dissolve_prop__use_verts(ot, false, 0);
}
@@ -3607,6 +3875,15 @@ static int edbm_dissolve_mode_exec(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ PropertyRNA *prop;
+
+ prop = RNA_struct_find_property(op->ptr, "use_verts");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ /* always enable in edge-mode */
+ if ((em->selectmode & SCE_SELECT_FACE) == 0) {
+ RNA_property_boolean_set(op->ptr, prop, true);
+ }
+ }
if (em->selectmode & SCE_SELECT_VERTEX) {
return edbm_dissolve_verts_exec(C, op);
@@ -3633,7 +3910,7 @@ void MESH_OT_dissolve_mode(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- edbm_dissolve_prop__use_verts(ot);
+ edbm_dissolve_prop__use_verts(ot, false, PROP_SKIP_SAVE);
edbm_dissolve_prop__use_face_split(ot);
edbm_dissolve_prop__use_boundary_tear(ot);
}
@@ -4482,7 +4759,7 @@ static int edbm_noise_exec(bContext *C, wmOperator *op)
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
float tin, dum;
- externtex(ma->mtex[0], eve->co, &tin, &dum, &dum, &dum, &dum, 0, NULL);
+ externtex(ma->mtex[0], eve->co, &tin, &dum, &dum, &dum, &dum, 0, NULL, false);
eve->co[2] += fac * tin;
}
}
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index c7d1d883537..86cd75eed7a 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -33,9 +33,11 @@
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
+#include "DNA_key_types.h"
#include "BLI_math.h"
#include "BLI_alloca.h"
+#include "BLI_listbase.h"
#include "BKE_DerivedMesh.h"
#include "BKE_context.h"
@@ -230,7 +232,7 @@ bool EDBM_op_finish(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const bool
else {
em->emcopyusers--;
if (em->emcopyusers < 0) {
- printf("warning: em->emcopyusers was less then zero.\n");
+ printf("warning: em->emcopyusers was less than zero.\n");
}
if (em->emcopyusers <= 0) {
@@ -381,6 +383,12 @@ void EDBM_mesh_load(Object *ob)
Mesh *me = ob->data;
BMesh *bm = me->edit_btmesh->bm;
+ /* Workaround for T42360, 'ob->shapenr' should be 1 in this case.
+ * however this isn't synchronized between objects at the moment. */
+ if (UNLIKELY((ob->shapenr == 0) && (me->key && !BLI_listbase_is_empty(&me->key->block)))) {
+ bm->shapenr = 1;
+ }
+
BM_mesh_bm_to_me(bm, me, false);
#ifdef USE_TESSFACE_DEFAULT
@@ -432,14 +440,14 @@ void EDBM_select_flush(BMEditMesh *em)
BM_mesh_select_flush(em->bm);
}
-void EDBM_select_more(BMEditMesh *em)
+void EDBM_select_more(BMEditMesh *em, const bool use_face_step)
{
BMOperator bmop;
- int use_faces = em->selectmode == SCE_SELECT_FACE;
+ const bool use_faces = (em->selectmode == SCE_SELECT_FACE);
BMO_op_initf(em->bm, &bmop, BMO_FLAG_DEFAULTS,
- "region_extend geom=%hvef use_constrict=%b use_faces=%b",
- BM_ELEM_SELECT, false, use_faces);
+ "region_extend geom=%hvef use_contract=%b use_faces=%b use_face_step=%b",
+ BM_ELEM_SELECT, false, use_faces, use_face_step);
BMO_op_exec(em->bm, &bmop);
/* don't flush selection in edge/vertex mode */
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? true : false);
@@ -448,14 +456,14 @@ void EDBM_select_more(BMEditMesh *em)
EDBM_selectmode_flush(em);
}
-void EDBM_select_less(BMEditMesh *em)
+void EDBM_select_less(BMEditMesh *em, const bool use_face_step)
{
BMOperator bmop;
- int use_faces = em->selectmode == SCE_SELECT_FACE;
+ const bool use_faces = (em->selectmode == SCE_SELECT_FACE);
BMO_op_initf(em->bm, &bmop, BMO_FLAG_DEFAULTS,
- "region_extend geom=%hvef use_constrict=%b use_faces=%b",
- BM_ELEM_SELECT, true, use_faces);
+ "region_extend geom=%hvef use_contract=%b use_faces=%b use_face_step=%b",
+ BM_ELEM_SELECT, true, use_faces, use_face_step);
BMO_op_exec(em->bm, &bmop);
/* don't flush selection in edge/vertex mode */
BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? true : false);
@@ -524,30 +532,56 @@ static void *editbtMesh_to_undoMesh(void *emv, void *obdata)
return um;
}
-static void undoMesh_to_editbtMesh(void *umv, void *em_v, void *UNUSED(obdata))
+static void undoMesh_to_editbtMesh(void *umv, void *em_v, void *obdata)
{
BMEditMesh *em = em_v, *em_tmp;
Object *ob = em->ob;
UndoMesh *um = umv;
BMesh *bm;
+ Key *key = ((Mesh *) obdata)->key;
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(&um->me);
- ob->shapenr = em->bm->shapenr = um->shapenr;
+ em->bm->shapenr = um->shapenr;
EDBM_mesh_free(em);
bm = BM_mesh_create(&allocsize);
- BM_mesh_bm_from_me(bm, &um->me, true, false, ob->shapenr);
+ BM_mesh_bm_from_me(bm, &um->me, true, false, um->shapenr);
em_tmp = BKE_editmesh_create(bm, true);
*em = *em_tmp;
-
+
em->selectmode = um->selectmode;
bm->selectmode = um->selectmode;
em->ob = ob;
+ /* T35170: Restore the active key on the RealMesh. Otherwise 'fake' offset propagation happens
+ * if the active is a basis for any other. */
+ if (key && (key->type == KEY_RELATIVE)) {
+ /* Since we can't add, remove or reorder keyblocks in editmode, it's safe to assume
+ * shapenr from restored bmesh and keyblock indices are in sync. */
+ const int kb_act_idx = ob->shapenr - 1;
+
+ /* If it is, let's patch the current mesh key block to its restored value.
+ * Else, the offsets won't be computed and it won't matter. */
+ if (BKE_keyblock_is_basis(key, kb_act_idx)) {
+ KeyBlock *kb_act = BLI_findlink(&key->block, kb_act_idx);
+
+ if (kb_act->totelem != um->me.totvert) {
+ /* The current mesh has some extra/missing verts compared to the undo, adjust. */
+ MEM_SAFE_FREE(kb_act->data);
+ kb_act->data = MEM_mallocN((size_t)(key->elemsize * bm->totvert), __func__);
+ kb_act->totelem = um->me.totvert;
+ }
+
+ BKE_keyblock_update_from_mesh(&um->me, kb_act);
+ }
+ }
+
+ ob->shapenr = um->shapenr;
+
MEM_freeN(em_tmp);
}
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 68471bfc2ba..86991d7dfeb 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -43,7 +43,6 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
@@ -51,7 +50,6 @@
#include "BKE_report.h"
#include "BKE_editmesh.h"
-#include "RNA_access.h"
#include "RNA_define.h"
#include "WM_api.h"
@@ -59,6 +57,7 @@
#include "ED_mesh.h"
#include "ED_object.h"
+#include "ED_screen.h"
#include "ED_uvedit.h"
#include "ED_view3d.h"
@@ -336,6 +335,26 @@ int ED_mesh_uv_texture_add(Mesh *me, const char *name, const bool active_set)
return layernum_dst;
}
+void ED_mesh_uv_texture_ensure(struct Mesh *me, const char *name)
+{
+ BMEditMesh *em;
+ int layernum_dst;
+
+ if (me->edit_btmesh) {
+ em = me->edit_btmesh;
+
+ layernum_dst = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
+ if (layernum_dst == 0)
+ ED_mesh_uv_texture_add(me, name, true);
+ }
+ else {
+ layernum_dst = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
+ if (layernum_dst == 0)
+ ED_mesh_uv_texture_add(me, name, true);
+ }
+}
+
+
bool ED_mesh_uv_texture_remove_index(Mesh *me, const int n)
{
CustomData *pdata = GET_CD_DATA(me, pdata), *ldata = GET_CD_DATA(me, ldata);
@@ -551,24 +570,13 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e
return OPERATOR_CANCELLED;
}
- /* check input variables */
- if (RNA_struct_property_is_set(op->ptr, "filepath")) {
- char path[FILE_MAX];
-
- RNA_string_get(op->ptr, "filepath", path);
- ima = BKE_image_load_exists(path);
- }
- else {
- char name[MAX_ID_NAME - 2];
- RNA_string_get(op->ptr, "name", name);
- ima = (Image *)BKE_libblock_find_name(ID_IM, name);
- }
-
+ ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
if (!ima) {
- BKE_report(op->reports, RPT_ERROR, "Not an image");
return OPERATOR_CANCELLED;
}
-
+ /* handled below */
+ id_us_min((ID *)ima);
+
/* put mesh in editmode */
obedit = base->object;
@@ -619,6 +627,7 @@ void MESH_OT_drop_named_image(wmOperatorType *ot)
/* properties */
RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Image name to assign");
RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file");
+ RNA_def_boolean(ot->srna, "relative_path", true, "Relative Path", "Select the file relative to the blend file");
}
static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
@@ -830,6 +839,71 @@ void MESH_OT_customdata_clear_skin(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/* Clear custom loop normals */
+static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ Mesh *me = ob->data;
+
+ if (!BKE_mesh_has_custom_loop_normals(me)) {
+ CustomData *data = GET_CD_DATA(me, ldata);
+
+ if (me->edit_btmesh) {
+ BM_data_layer_add(me->edit_btmesh->bm, data, CD_CUSTOMLOOPNORMAL);
+ }
+ else {
+ CustomData_add_layer(data, CD_CUSTOMLOOPNORMAL, CD_DEFAULT, NULL, me->totloop);
+ }
+
+ DAG_id_tag_update(&me->id, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
+
+ return OPERATOR_FINISHED;
+ }
+ return OPERATOR_CANCELLED;
+}
+
+void MESH_OT_customdata_custom_splitnormals_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Custom Split Normals Data";
+ ot->idname = "MESH_OT_customdata_custom_splitnormals_add";
+ ot->description = "Add a custom split normals layer, if none exists yet";
+
+ /* api callbacks */
+ ot->exec = mesh_customdata_custom_splitnormals_add_exec;
+ ot->poll = ED_operator_object_active_editable_mesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int mesh_customdata_custom_splitnormals_clear_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *ob = ED_object_context(C);
+ Mesh *me = ob->data;
+
+ if (BKE_mesh_has_custom_loop_normals(me)) {
+ return mesh_customdata_clear_exec__internal(C, BM_LOOP, CD_CUSTOMLOOPNORMAL);
+ }
+ return OPERATOR_CANCELLED;
+}
+
+void MESH_OT_customdata_custom_splitnormals_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Clear Custom Split Normals Data";
+ ot->idname = "MESH_OT_customdata_custom_splitnormals_clear";
+ ot->description = "Remove the custom split normals layer, if it exists";
+
+ /* api callbacks */
+ ot->exec = mesh_customdata_custom_splitnormals_clear_exec;
+ ot->poll = ED_operator_object_active_editable_mesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/************************** Add Geometry Layers *************************/
void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges, int calc_tessface)
@@ -1161,7 +1235,7 @@ void ED_mesh_polys_add(Mesh *mesh, ReportList *reports, int count)
mesh_add_polys(mesh, count);
}
-void ED_mesh_calc_tessface(Mesh *mesh)
+void ED_mesh_calc_tessface(Mesh *mesh, bool free_mpoly)
{
if (mesh->edit_btmesh) {
BKE_editmesh_tessface_calc(mesh->edit_btmesh);
@@ -1169,6 +1243,17 @@ void ED_mesh_calc_tessface(Mesh *mesh)
else {
BKE_mesh_tessface_calc(mesh);
}
+ if (free_mpoly) {
+ CustomData_free(&mesh->ldata, mesh->totloop);
+ CustomData_free(&mesh->pdata, mesh->totpoly);
+ mesh->totloop = 0;
+ mesh->totpoly = 0;
+ mesh->mloop = NULL;
+ mesh->mloopcol = NULL;
+ mesh->mloopuv = NULL;
+ mesh->mpoly = NULL;
+ mesh->mtpoly = NULL;
+ }
}
void ED_mesh_report_mirror_ex(wmOperator *op, int totmirr, int totfail,
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 6ba91097ec4..8611872a1a0 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -175,6 +175,8 @@ void MESH_OT_normals_make_consistent(struct wmOperatorType *ot);
void MESH_OT_vertices_smooth(struct wmOperatorType *ot);
void MESH_OT_vertices_smooth_laplacian(struct wmOperatorType *ot);
void MESH_OT_vert_connect(struct wmOperatorType *ot);
+void MESH_OT_vert_connect_path(struct wmOperatorType *ot);
+void MESH_OT_vert_connect_concave(struct wmOperatorType *ot);
void MESH_OT_vert_connect_nonplanar(struct wmOperatorType *ot);
void MESH_OT_edge_split(struct wmOperatorType *ot);
void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot);
@@ -237,6 +239,8 @@ void MESH_OT_vertex_color_remove(struct wmOperatorType *ot);
/* no create_mask yet */
void MESH_OT_customdata_clear_mask(struct wmOperatorType *ot);
void MESH_OT_customdata_clear_skin(struct wmOperatorType *ot);
+void MESH_OT_customdata_custom_splitnormals_add(struct wmOperatorType *ot);
+void MESH_OT_customdata_custom_splitnormals_clear(struct wmOperatorType *ot);
void MESH_OT_drop_named_image(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index e7dc5a69d53..2855af063c0 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -153,6 +153,8 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_vertex_color_remove);
WM_operatortype_append(MESH_OT_customdata_clear_mask);
WM_operatortype_append(MESH_OT_customdata_clear_skin);
+ WM_operatortype_append(MESH_OT_customdata_custom_splitnormals_add);
+ WM_operatortype_append(MESH_OT_customdata_custom_splitnormals_clear);
WM_operatortype_append(MESH_OT_drop_named_image);
WM_operatortype_append(MESH_OT_edgering_select);
@@ -161,6 +163,8 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_solidify);
WM_operatortype_append(MESH_OT_select_nth);
WM_operatortype_append(MESH_OT_vert_connect);
+ WM_operatortype_append(MESH_OT_vert_connect_path);
+ WM_operatortype_append(MESH_OT_vert_connect_concave);
WM_operatortype_append(MESH_OT_vert_connect_nonplanar);
WM_operatortype_append(MESH_OT_knife_tool);
WM_operatortype_append(MESH_OT_knife_project);
@@ -398,7 +402,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_split", YKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "MESH_OT_vert_connect", JKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_vert_connect_path", JKEY, KM_PRESS, 0, 0);
/* Vertex Slide */
WM_keymap_add_item(keymap, "TRANSFORM_OT_vert_slide", VKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 16f4f61f92b..00d79b22e99 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -329,7 +329,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
if (odg) {
/* Search for a match in the new object, and set new index */
for (dg = ob->defbase.first, index = 0; dg; dg = dg->next, index++) {
- if (!strcmp(dg->name, odg->name)) {
+ if (STREQ(dg->name, odg->name)) {
dvert[i].dw[j].def_nr = index;
break;
}
@@ -627,7 +627,7 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
/* first key added, so it was the basis. initialize it with the existing mesh */
kb = BKE_keyblock_add(key, NULL);
- BKE_key_convert_from_mesh(me, kb);
+ BKE_keyblock_convert_from_mesh(me, kb);
}
/* now ready to add new keys from selected meshes */
@@ -895,7 +895,7 @@ int ED_mesh_mirror_get_vert(Object *ob, int index)
index_mirr = eve_mirr ? BM_elem_index_get(eve_mirr) : -1;
}
else {
- index_mirr = mesh_get_x_mirror_vert(ob, index, use_topology);
+ index_mirr = mesh_get_x_mirror_vert(ob, index, use_topology);
}
return index_mirr;
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index f6a54beb8c8..24cac5b9b70 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -47,7 +47,6 @@
#include "RNA_define.h"
#include "RNA_access.h"
-#include "RNA_enum_types.h"
#include "BKE_depsgraph.h"
#include "BKE_context.h"
@@ -584,7 +583,7 @@ bool mouse_mball(bContext *C, const int mval[2], bool extend, bool deselect, boo
MetaBall *mb = (MetaBall *)obedit->data;
MetaElem *ml, *ml_act = NULL;
int a, hits;
- unsigned int buffer[4 * MAXPICKBUF];
+ unsigned int buffer[MAXPICKBUF];
rcti rect;
view3d_set_viewcontext(C, &vc);
diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c
index b7822200d98..3af85c33bcc 100644
--- a/source/blender/editors/metaball/mball_ops.c
+++ b/source/blender/editors/metaball/mball_ops.c
@@ -30,8 +30,6 @@
#include "DNA_scene_types.h"
-#include "BLI_utildefines.h"
-
#include "RNA_access.h"
#include "WM_api.h"
@@ -62,7 +60,7 @@ void ED_operatormacros_metaball(void)
wmOperatorTypeMacro *otmacro;
ot = WM_operatortype_append_macro("MBALL_OT_duplicate_move", "Duplicate",
- "Make copies of the selected bones within the same armature and move them",
+ "Make copies of the selected metaelements and move them",
OPTYPE_UNDO | OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "MBALL_OT_duplicate_metaelems");
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index 9b380ff8d48..79437bb05b9 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -56,6 +56,7 @@ set(SRC
object_relations.c
object_select.c
object_shapekey.c
+ object_data_transfer.c
object_transform.c
object_warp.c
object_vgroup.c
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 8972dd7cf08..99b351561c7 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -69,7 +69,6 @@
#include "BKE_effect.h"
#include "BKE_font.h"
#include "BKE_group.h"
-#include "BKE_image.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
@@ -97,7 +96,6 @@
#include "ED_armature.h"
#include "ED_curve.h"
-#include "ED_lattice.h"
#include "ED_mball.h"
#include "ED_mesh.h"
#include "ED_node.h"
@@ -108,7 +106,6 @@
#include "ED_transform.h"
#include "ED_view3d.h"
-#include "UI_interface.h"
#include "UI_resources.h"
#include "GPU_material.h"
@@ -165,14 +162,13 @@ void ED_object_rotation_from_view(bContext *C, float rot[3], const char align_ax
BLI_assert(align_axis >= 'X' && align_axis <= 'Z');
if (rv3d) {
- const float pi_2 = (float)M_PI / 2.0f;
float quat[4];
switch (align_axis) {
case 'X':
{
float quat_y[4];
- axis_angle_to_quat(quat_y, rv3d->viewinv[1], -pi_2);
+ axis_angle_to_quat(quat_y, rv3d->viewinv[1], -M_PI_2);
mul_qt_qtqt(quat, rv3d->viewquat, quat_y);
quat[0] = -quat[0];
@@ -185,7 +181,7 @@ void ED_object_rotation_from_view(bContext *C, float rot[3], const char align_ax
quat[0] = -quat[0];
quat_to_eul(rot, quat);
- rot[0] -= pi_2;
+ rot[0] -= (float)M_PI_2;
break;
}
case 'Z':
@@ -222,9 +218,9 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3],
/* Uses context to figure out transform for primitive.
* Returns standard diameter. */
-float ED_object_new_primitive_matrix(bContext *C, Object *obedit,
- const float loc[3], const float rot[3], float primmat[4][4],
- bool apply_diameter)
+float ED_object_new_primitive_matrix(
+ bContext *C, Object *obedit,
+ const float loc[3], const float rot[3], float primmat[4][4])
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -249,13 +245,6 @@ float ED_object_new_primitive_matrix(bContext *C, Object *obedit,
{
const float dia = v3d ? ED_view3d_grid_scale(scene, v3d, NULL) : ED_scene_grid_scale(scene, NULL);
-
- if (apply_diameter) {
- primmat[0][0] *= dia;
- primmat[1][1] *= dia;
- primmat[2][2] *= dia;
- }
-
return dia;
}
@@ -308,18 +297,19 @@ bool ED_object_add_generic_get_opts(bContext *C, wmOperator *op, const char view
{
View3D *v3d = CTX_wm_view3d(C);
unsigned int _layer;
+ PropertyRNA *prop;
- /* Switch to Edit mode? */
- if (RNA_struct_find_property(op->ptr, "enter_editmode")) { /* optional */
+ /* Switch to Edit mode? optional prop */
+ if ((prop = RNA_struct_find_property(op->ptr, "enter_editmode"))) {
bool _enter_editmode;
if (!enter_editmode)
enter_editmode = &_enter_editmode;
- if (RNA_struct_property_is_set(op->ptr, "enter_editmode") && enter_editmode)
- *enter_editmode = RNA_boolean_get(op->ptr, "enter_editmode");
+ if (RNA_property_is_set(op->ptr, prop) && enter_editmode)
+ *enter_editmode = RNA_property_boolean_get(op->ptr, prop);
else {
*enter_editmode = (U.flag & USER_ADD_EDITMODE) != 0;
- RNA_boolean_set(op->ptr, "enter_editmode", *enter_editmode);
+ RNA_property_boolean_set(op->ptr, prop, *enter_editmode);
}
}
@@ -329,8 +319,9 @@ bool ED_object_add_generic_get_opts(bContext *C, wmOperator *op, const char view
if (!layer)
layer = &_layer;
- if (RNA_struct_property_is_set(op->ptr, "layers")) {
- RNA_boolean_get_array(op->ptr, "layers", layer_values);
+ prop = RNA_struct_find_property(op->ptr, "layers");
+ if (RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_boolean_get_array(op->ptr, prop, layer_values);
*layer = 0;
for (a = 0; a < 20; a++) {
if (layer_values[a])
@@ -341,9 +332,9 @@ bool ED_object_add_generic_get_opts(bContext *C, wmOperator *op, const char view
Scene *scene = CTX_data_scene(C);
*layer = BKE_screen_view3d_layer_active_ex(v3d, scene, false);
for (a = 0; a < 20; a++) {
- layer_values[a] = *layer & (1 << a);
+ layer_values[a] = (*layer & (1 << a)) != 0;
}
- RNA_boolean_set_array(op->ptr, "layers", layer_values);
+ RNA_property_boolean_set_array(op->ptr, prop, layer_values);
}
/* in local view we additionally add local view layers,
@@ -449,14 +440,23 @@ static int object_add_exec(bContext *C, wmOperator *op)
Object *ob;
bool enter_editmode;
unsigned int layer;
- float loc[3], rot[3];
+ float loc[3], rot[3], radius;
WM_operator_view3d_unit_defaults(C, op);
if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &layer, NULL))
return OPERATOR_CANCELLED;
+ radius = RNA_float_get(op->ptr, "radius");
ob = ED_object_add_type(C, RNA_enum_get(op->ptr, "type"), loc, rot, enter_editmode, layer);
- BKE_object_obdata_size_init(ob, RNA_float_get(op->ptr, "radius"));
+
+ if (ob->type == OB_LATTICE) {
+ /* lattice is a special case!
+ * we never want to scale the obdata since that is the rest-state */
+ copy_v3_fl(ob->size, radius);
+ }
+ else {
+ BKE_object_obdata_size_init(ob, radius);
+ }
return OPERATOR_FINISHED;
}
@@ -510,7 +510,7 @@ static int effector_add_exec(bContext *C, wmOperator *op)
cu = ob->data;
cu->flag |= CU_PATH | CU_3D;
ED_object_editmode_enter(C, 0);
- ED_object_new_primitive_matrix(C, ob, loc, rot, mat, false);
+ ED_object_new_primitive_matrix(C, ob, loc, rot, mat);
BLI_addtail(&cu->editnurb->nurbs, add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, dia));
if (!enter_editmode)
ED_object_editmode_exit(C, EM_FREEDATA);
@@ -633,7 +633,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
}
- ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, false);
+ ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
dia = RNA_float_get(op->ptr, "radius");
add_metaball_primitive(C, obedit, mat, dia, RNA_enum_get(op->ptr, "type"));
@@ -824,24 +824,12 @@ static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEv
Image *ima = NULL;
Object *ob = NULL;
- /* check image input variables */
- if (RNA_struct_property_is_set(op->ptr, "filepath")) {
- char path[FILE_MAX];
-
- RNA_string_get(op->ptr, "filepath", path);
- ima = BKE_image_load_exists(path);
- }
- else if (RNA_struct_property_is_set(op->ptr, "name")) {
- char name[MAX_ID_NAME - 2];
-
- RNA_string_get(op->ptr, "name", name);
- ima = (Image *)BKE_libblock_find_name(ID_IM, name);
- }
-
- if (ima == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Not an image");
+ ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
+ if (!ima) {
return OPERATOR_CANCELLED;
}
+ /* handled below */
+ id_us_min((ID *)ima);
base = ED_view3d_give_base_under_cursor(C, event->mval);
@@ -893,6 +881,8 @@ void OBJECT_OT_drop_named_image(wmOperatorType *ot)
/* properties */
prop = RNA_def_string(ot->srna, "filepath", NULL, FILE_MAX, "Filepath", "Path to image file");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ RNA_def_boolean(ot->srna, "relative_path", true, "Relative Path", "Select the file relative to the blend file");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Image name to assign");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
ED_object_add_generic_props(ot, false);
@@ -981,8 +971,11 @@ static int group_instance_add_exec(bContext *C, wmOperator *op)
if (0 == RNA_struct_property_is_set(op->ptr, "location")) {
wmEvent *event = CTX_wm_window(C)->eventstate;
+ ARegion *ar = CTX_wm_region(C);
+ const int mval[2] = {event->x - ar->winrct.xmin,
+ event->y - ar->winrct.ymin};
ED_object_location_from_view(C, loc);
- ED_view3d_cursor3d_position(C, loc, event->mval);
+ ED_view3d_cursor3d_position(C, loc, mval);
RNA_float_set_array(op->ptr, "location", loc);
}
}
@@ -1290,6 +1283,44 @@ static void copy_object_set_idnew(bContext *C, int dupflag)
/********************* Make Duplicates Real ************************/
+/**
+ * \note regarding hashing dupli-objects, skip the first member of #DupliObject.persistent_id
+ * since its a unique index and we only want to know if the group objects are from the same dupli-group instance.
+ */
+static unsigned int dupliobject_hash(const void *ptr)
+{
+ const DupliObject *dob = ptr;
+ unsigned int hash = BLI_ghashutil_ptrhash(dob->ob);
+ unsigned int i;
+ for (i = 1; (i < MAX_DUPLI_RECUR) && dob->persistent_id[i] != INT_MAX; i++) {
+ hash ^= (dob->persistent_id[i] ^ i);
+ }
+ return hash;
+}
+
+static bool dupliobject_cmp(const void *a_, const void *b_)
+{
+ const DupliObject *a = a_;
+ const DupliObject *b = b_;
+ unsigned int i;
+
+ if (a->ob != b->ob) {
+ return true;
+ }
+
+ for (i = 1; (i < MAX_DUPLI_RECUR); i++) {
+ if (a->persistent_id[i] != b->persistent_id[i]) {
+ return true;
+ }
+ else if (a->persistent_id[i] == INT_MAX) {
+ break;
+ }
+ }
+
+ /* matching */
+ return false;
+}
+
static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
const bool use_base_parent,
const bool use_hierarchy)
@@ -1306,8 +1337,8 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
lb = object_duplilist(bmain->eval_ctx, scene, base->object);
if (use_hierarchy || use_base_parent) {
- dupli_gh = BLI_ghash_ptr_new("make_object_duplilist_real dupli_gh");
- parent_gh = BLI_ghash_pair_new("make_object_duplilist_real parent_gh");
+ dupli_gh = BLI_ghash_ptr_new(__func__);
+ parent_gh = BLI_ghash_new(dupliobject_hash, dupliobject_cmp, __func__);
}
for (dob = lb->first; dob; dob = dob->next) {
@@ -1347,7 +1378,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
if (dupli_gh)
BLI_ghash_insert(dupli_gh, dob, ob);
if (parent_gh)
- BLI_ghash_insert(parent_gh, BLI_ghashutil_pairalloc(dob->ob, SET_INT_IN_POINTER(dob->persistent_id[0])), ob);
+ BLI_ghash_insert(parent_gh, dob, ob);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
@@ -1363,9 +1394,14 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
/* find parent that was also made real */
if (ob_src_par) {
- GHashPair *pair = BLI_ghashutil_pairalloc(ob_src_par, SET_INT_IN_POINTER(dob->persistent_id[0]));
- ob_dst_par = BLI_ghash_lookup(parent_gh, pair);
- BLI_ghashutil_pairfree(pair);
+ /* OK to keep most of the members uninitialized,
+ * they won't be read, this is simply for a hash lookup. */
+ DupliObject dob_key;
+ dob_key.ob = ob_src_par;
+ memcpy(&dob_key.persistent_id[1],
+ &dob->persistent_id[1],
+ sizeof(dob->persistent_id[1]) * (MAX_DUPLI_RECUR - 1));
+ ob_dst_par = BLI_ghash_lookup(parent_gh, &dob_key);
}
if (ob_dst_par) {
@@ -1428,7 +1464,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
if (dupli_gh)
BLI_ghash_free(dupli_gh, NULL, NULL);
if (parent_gh)
- BLI_ghash_free(parent_gh, BLI_ghashutil_pairfree, NULL);
+ BLI_ghash_free(parent_gh, NULL, NULL);
copy_object_set_idnew(C, 0);
@@ -1569,18 +1605,30 @@ static int convert_exec(bContext *C, wmOperator *op)
/* don't forget multiple users! */
- /* reset flags */
- CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
- ob = base->object;
- ob->flag &= ~OB_DONE;
+ Base *base;
+
+ for (base = scene->base.first; base; base = base->next) {
+ ob = base->object;
+ ob->flag &= ~OB_DONE;
- /* flag data thats not been edited (only needed for !keep_original) */
- if (ob->data) {
- ((ID *)ob->data)->flag |= LIB_DOIT;
+ /* flag data thats not been edited (only needed for !keep_original) */
+ if (ob->data) {
+ ((ID *)ob->data)->flag |= LIB_DOIT;
+ }
+
+ /* possible metaball basis is not in this scene */
+ if (ob->type == OB_MBALL && target == OB_MESH) {
+ if (BKE_mball_is_basis(ob) == false) {
+ Object *ob_basis;
+ ob_basis = BKE_mball_basis_find(scene, ob);
+ if (ob_basis) {
+ ob_basis->flag &= ~OB_DONE;
+ }
+ }
+ }
}
}
- CTX_DATA_END;
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
@@ -1652,11 +1700,10 @@ static int convert_exec(bContext *C, wmOperator *op)
dm = mesh_get_derived_final(scene, newob, CD_MASK_MESH);
// dm = mesh_create_derived_no_deform(ob1, NULL); /* this was called original (instead of get_derived). man o man why! (ton) */
- DM_to_mesh(dm, newob->data, newob, CD_MASK_MESH);
+ DM_to_mesh(dm, newob->data, newob, CD_MASK_MESH, true);
/* re-tessellation is called by DM_to_mesh */
- dm->release(dm);
BKE_object_free_modifiers(newob); /* after derivedmesh calls! */
}
else if (ob->type == OB_FONT) {
@@ -1820,14 +1867,21 @@ static int convert_exec(bContext *C, wmOperator *op)
if (!keep_original) {
if (mballConverted) {
- Base *base = scene->base.first, *tmpbase;
- while (base) {
- ob = base->object;
- tmpbase = base;
- base = base->next;
+ Base *base, *base_next;
+
+ for (base = scene->base.first; base; base = base_next) {
+ base_next = base->next;
+ ob = base->object;
if (ob->type == OB_MBALL) {
- ED_base_object_free_and_unlink(bmain, scene, tmpbase);
+ if (ob->flag & OB_DONE) {
+ Object *ob_basis = NULL;
+ if (BKE_mball_is_basis(ob) ||
+ ((ob_basis = BKE_mball_basis_find(scene, ob)) && (ob_basis->flag & OB_DONE)))
+ {
+ ED_base_object_free_and_unlink(bmain, scene, base);
+ }
+ }
}
}
}
@@ -2270,7 +2324,7 @@ static int add_named_exec(bContext *C, wmOperator *op)
MEM_freeN(base);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT | ND_OB_ACTIVE, scene);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index b8957514159..758f4d180b9 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -45,8 +45,6 @@
#include "BLI_blenlib.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
-#include "BLI_math.h"
-#include "BLI_math_geom.h"
#include "BKE_blender.h"
#include "BKE_screen.h"
@@ -71,7 +69,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_colormanagement.h"
#include "GPU_draw.h" /* GPU_free_image */
@@ -438,7 +435,7 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa
MultiresBakeJob *bkj = bkv;
int baked_objects = 0, tot_obj;
- tot_obj = BLI_countlist(&bkj->data);
+ tot_obj = BLI_listbase_count(&bkj->data);
if (bkj->bake_clear) { /* clear images */
for (data = bkj->data.first; data; data = data->next) {
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 5746f9efd56..97cb45daae3 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -379,7 +379,10 @@ static bool bake_object_check(Object *ob, ReportList *reports)
if (node) {
if (BKE_node_is_connected_to_output(ntree, node)) {
- BKE_reportf(reports, RPT_ERROR,
+ /* we don't return false since this may be a false positive
+ * this can't be RPT_ERROR though, otherwise it prevents
+ * multiple highpoly objects to be baked at once */
+ BKE_reportf(reports, RPT_INFO,
"Circular dependency for image \"%s\" from object \"%s\"",
image->id.name + 2, ob->id.name + 2);
}
@@ -768,7 +771,7 @@ static int bake(
normalize_m4_m4(highpoly[i].rotmat, highpoly[i].imat);
zero_v3(highpoly[i].rotmat[3]);
if (is_negative_m4(highpoly[i].rotmat))
- negate_m3(highpoly[i].rotmat);
+ negate_mat3_m4(highpoly[i].rotmat);
i++;
}
@@ -916,7 +919,7 @@ cage_cleanup:
BakeData *bake = &scene->r.bake;
char name[FILE_MAX];
- BKE_makepicstring_from_type(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false);
+ BKE_image_path_from_imtype(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false);
if (is_automatic_name) {
BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_");
@@ -1081,8 +1084,9 @@ static int bake_exec(bContext *C, wmOperator *op)
/* setup new render */
RE_test_break_cb(re, NULL, bake_break);
- if (!bake_objects_check(bkr.main, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active))
- return OPERATOR_CANCELLED;
+ if (!bake_objects_check(bkr.main, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) {
+ goto finally;
+ }
if (bkr.is_clear) {
const bool is_tangent = ((bkr.pass_type == SCE_PASS_NORMAL) && (bkr.normal_space == R_BAKE_SPACE_TANGENT));
@@ -1117,6 +1121,8 @@ static int bake_exec(bContext *C, wmOperator *op)
RE_SetReports(re, NULL);
+
+finally:
BLI_freelistN(&bkr.selected_objects);
return result;
}
@@ -1208,7 +1214,7 @@ static void bake_set_props(wmOperator *op, Scene *scene)
prop = RNA_struct_find_property(op->ptr, "use_selected_to_active");
if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE));
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0);
}
prop = RNA_struct_find_property(op->ptr, "cage_extrusion");
@@ -1248,22 +1254,22 @@ static void bake_set_props(wmOperator *op, Scene *scene)
prop = RNA_struct_find_property(op->ptr, "use_clear");
if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CLEAR));
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CLEAR) != 0);
}
prop = RNA_struct_find_property(op->ptr, "use_cage");
if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CAGE));
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CAGE) != 0);
}
prop = RNA_struct_find_property(op->ptr, "use_split_materials");
if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_SPLIT_MAT));
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_SPLIT_MAT) != 0);
}
prop = RNA_struct_find_property(op->ptr, "use_automatic_name");
if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME));
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME) != 0);
}
}
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 92ed84b7f5e..231d23b481d 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -233,7 +233,7 @@ static void set_constraint_nth_target(bConstraint *con, Object *target, const ch
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
- num_targets = BLI_countlist(&targets);
+ num_targets = BLI_listbase_count(&targets);
if (index < 0) {
if (abs(index) < num_targets)
@@ -471,7 +471,7 @@ static void test_constraints(Object *owner, bPoseChannel *pchan)
/* TODO: clear subtarget? */
curcon->flag |= CONSTRAINT_DISABLE;
}
- else if (strcmp(pchan->name, ct->subtarget) == 0) {
+ else if (STREQ(pchan->name, ct->subtarget)) {
/* cannot target self */
ct->subtarget[0] = '\0';
curcon->flag |= CONSTRAINT_DISABLE;
@@ -1165,7 +1165,17 @@ void ED_object_constraint_dependency_update(Main *bmain, Object *ob)
{
ED_object_constraint_update(ob);
- if (ob->pose) ob->pose->flag |= POSE_RECALC; // checks & sorts pose channels
+ if (ob->pose) {
+ ob->pose->flag |= POSE_RECALC; /* Checks & sort pose channels. */
+ if (ob->proxy && ob->adt) {
+ /* We need to make use of ugly POSE_ANIMATION_WORKAROUND here too, else anim data are not reloaded
+ * after calling `BKE_pose_rebuild()`, which causes T43872.
+ * Note that this is a bit wide here, since we cannot be sure whether there are some locked proxy bones
+ * or not...
+ * XXX Temp hack until new depsgraph hopefully solves this. */
+ ob->adt->recalc |= ADT_RECALC_ANIM;
+ }
+ }
DAG_relations_tag_update(bmain);
}
@@ -1182,20 +1192,13 @@ static int constraint_delete_exec(bContext *C, wmOperator *UNUSED(op))
Object *ob = ptr.id.data;
bConstraint *con = ptr.data;
ListBase *lb = get_constraint_lb(ob, con, NULL);
- const bool is_ik = ELEM(con->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK);
/* free the constraint */
- if (BKE_constraint_remove(lb, con)) {
+ if (BKE_constraint_remove_ex(lb, ob, con, true)) {
/* there's no active constraint now, so make sure this is the case */
- BKE_constraints_active_set(lb, NULL);
-
+ BKE_constraints_active_set(&ob->constraints, NULL);
ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */
- /* ITASC needs to be rebuilt once a constraint is removed [#26920] */
- if (is_ik) {
- BIK_clear_data(ob->pose);
- }
-
/* notifiers */
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob);
@@ -1399,6 +1402,8 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
bPoseChannel *pchan = CTX_data_active_pose_bone(C);
+ ListBase lb;
+ CollectionPointerLink *link;
/* don't do anything if bone doesn't exist or doesn't have any constraints */
if (ELEM(NULL, pchan, pchan->constraints.first)) {
@@ -1407,16 +1412,22 @@ static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
}
/* copy all constraints from active posebone to all selected posebones */
- CTX_DATA_BEGIN (C, bPoseChannel *, chan, selected_pose_bones)
- {
+ CTX_data_selected_pose_bones(C, &lb);
+ for (link = lb.first; link; link = link->next) {
+ Object *ob = link->ptr.id.data;
+ bPoseChannel *chan = link->ptr.data;
+
/* if we're not handling the object we're copying from, copy all constraints over */
if (pchan != chan) {
BKE_constraints_copy(&chan->constraints, &pchan->constraints, true);
/* update flags (need to add here, not just copy) */
chan->constflag |= pchan->constflag;
+
+ ob->pose->flag |= POSE_RECALC;
+ DAG_id_tag_update((ID *)ob, OB_RECALC_DATA);
}
}
- CTX_DATA_END;
+ BLI_freelistN(&lb);
/* force depsgraph to get recalculated since new relationships added */
DAG_relations_tag_update(bmain);
@@ -1724,6 +1735,12 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase
if ((ob->type == OB_ARMATURE) && (pchan)) {
ob->pose->flag |= POSE_RECALC; /* sort pose channels */
+ if (BKE_constraints_proxylocked_owner(ob, pchan) && ob->adt) {
+ /* We need to make use of ugly POSE_ANIMATION_WORKAROUND here too, else anim data are not reloaded
+ * after calling `BKE_pose_rebuild()`, which causes T43872.
+ * XXX Temp hack until new depsgraph hopefully solves this. */
+ ob->adt->recalc |= ADT_RECALC_ANIM;
+ }
DAG_id_tag_update(&ob->id, OB_RECALC_DATA | OB_RECALC_OB);
}
else
@@ -1889,8 +1906,8 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
}
/* prepare popup menu to choose targetting options */
- pup = uiPupMenuBegin(C, IFACE_("Add IK"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("Add IK"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
/* the type of targets we'll set determines the menu entries to show... */
if (get_new_constraint_target(C, CONSTRAINT_TYPE_KINEMATIC, &tar_ob, &tar_pchan, 0)) {
@@ -1909,9 +1926,9 @@ static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
}
/* finish building the menu, and process it (should result in calling self again) */
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
/* call constraint_add_exec() to add the IK constraint */
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
new file mode 100644
index 00000000000..b39e8470a95
--- /dev/null
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -0,0 +1,687 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 by Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Bastien Montagne.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/object/object_data_transfer.c
+ * \ingroup edobj
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_data_transfer.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_remap.h"
+#include "BKE_object.h"
+#include "BKE_report.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_object.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "object_intern.h"
+
+/* All possible data to transfer.
+ * Note some are 'fake' ones, i.e. they are not hold by real CDLayers. */
+/* Not shared with modifier, since we use a usual enum here, not a multi-choice one. */
+static EnumPropertyItem DT_layer_items[] = {
+ {0, "", 0, "Vertex Data", ""},
+ {DT_TYPE_MDEFORMVERT, "VGROUP_WEIGHTS", 0, "Vertex Group(s)", "Transfer active or all vertex groups"},
+#if 0 /* XXX For now, would like to finish/merge work from 2014 gsoc first. */
+ {DT_TYPE_SHAPEKEY, "SHAPEKEYS", 0, "Shapekey(s)", "Transfer active or all shape keys"},
+#endif
+#if 0 /* XXX When SkinModifier is enabled, it seems to erase its own CD_MVERT_SKIN layer from final DM :( */
+ {DT_TYPE_SKIN, "SKIN", 0, "Skin Weight", "Transfer skin weights"},
+#endif
+ {DT_TYPE_BWEIGHT_VERT, "BEVEL_WEIGHT_VERT", 0, "Bevel Weight", "Transfer bevel weights"},
+ {0, "", 0, "Edge Data", ""},
+ {DT_TYPE_SHARP_EDGE, "SHARP_EDGE", 0, "Sharp", "Transfer sharp mark"},
+ {DT_TYPE_SEAM, "SEAM", 0, "UV Seam", "Transfer UV seam mark"},
+ {DT_TYPE_CREASE, "CREASE", 0, "Subsurf Crease", "Transfer crease values"},
+ {DT_TYPE_BWEIGHT_EDGE, "BEVEL_WEIGHT_EDGE", 0, "Bevel Weight", "Transfer bevel weights"},
+ {DT_TYPE_FREESTYLE_EDGE, "FREESTYLE_EDGE", 0, "Freestyle Mark", "Transfer Freestyle edge mark"},
+ {0, "", 0, "Face Corner Data", ""},
+ {DT_TYPE_LNOR, "CUSTOM_NORMAL", 0, "Custom Normals", "Transfer custom normals"},
+ {DT_TYPE_VCOL, "VCOL", 0, "VCol", "Vertex (face corners) colors"},
+ {DT_TYPE_UV, "UV", 0, "UVs", "Transfer UV layers"},
+ {0, "", 0, "Face Data", ""},
+ {DT_TYPE_SHARP_FACE, "SMOOTH", 0, "Smooth", "Transfer flat/smooth mark"},
+ {DT_TYPE_FREESTYLE_FACE, "FREESTYLE_FACE", 0, "Freestyle Mark", "Transfer Freestyle face mark"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+/* Note: DT_layers_select_src_items enum is from rna_modifier.c */
+static EnumPropertyItem *dt_layers_select_src_itemf(
+ bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ EnumPropertyItem *item = NULL, tmp_item = {0};
+ int totitem = 0;
+
+ const int data_type = RNA_enum_get(ptr, "data_type");
+
+ if (!C) { /* needed for docs and i18n tools */
+ return DT_layers_select_src_items;
+ }
+
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_ACTIVE_SRC);
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_ALL_SRC);
+
+ if (data_type == DT_TYPE_MDEFORMVERT) {
+ Object *ob_src = CTX_data_active_object(C);
+
+ if (BKE_object_pose_armature_get(ob_src)) {
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_SELECT);
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_DEFORM);
+ }
+
+ if (ob_src) {
+ bDeformGroup *dg;
+ int i;
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0, dg = ob_src->defbase.first; dg; i++, dg = dg->next) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = dg->name;
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ else if (data_type == DT_TYPE_SHAPEKEY) {
+ /* TODO */
+ }
+ else if (data_type == DT_TYPE_UV) {
+ Object *ob_src = CTX_data_active_object(C);
+ Scene *scene = CTX_data_scene(C);
+
+ if (ob_src) {
+ DerivedMesh *dm_src;
+ CustomData *pdata;
+ int num_data, i;
+
+ /* XXX Is this OK? */
+ dm_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MTEXPOLY);
+ pdata = dm_src->getPolyDataLayout(dm_src);
+ num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ else if (data_type == DT_TYPE_VCOL) {
+ Object *ob_src = CTX_data_active_object(C);
+ Scene *scene = CTX_data_scene(C);
+
+ if (ob_src) {
+ DerivedMesh *dm_src;
+ CustomData *ldata;
+ int num_data, i;
+
+ /* XXX Is this OK? */
+ dm_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL);
+ ldata = dm_src->getLoopDataLayout(dm_src);
+ num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPCOL, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+/* Note: DT_layers_select_dst_items enum is from rna_modifier.c */
+static EnumPropertyItem *dt_layers_select_dst_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
+
+ const int layers_select_src = RNA_enum_get(ptr, "layers_select_src");
+
+ if (!C) { /* needed for docs and i18n tools */
+ return DT_layers_select_dst_items;
+ }
+
+ if (layers_select_src == DT_LAYERS_ACTIVE_SRC || layers_select_src >= 0) {
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_dst_items, DT_LAYERS_ACTIVE_DST);
+ }
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_dst_items, DT_LAYERS_NAME_DST);
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_dst_items, DT_LAYERS_INDEX_DST);
+
+ /* No 'specific' to-layers here, since we may transfer to several objects at once! */
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+/* Note: DT_mix_mode_items enum is from rna_modifier.c */
+static EnumPropertyItem *dt_mix_mode_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
+
+ const int dtdata_type = RNA_enum_get(ptr, "data_type");
+ bool support_advanced_mixing, support_threshold;
+
+ if (!C) { /* needed for docs and i18n tools */
+ return DT_mix_mode_items;
+ }
+
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_TRANSFER);
+
+ BKE_object_data_transfer_get_dttypes_capacity(dtdata_type, &support_advanced_mixing, &support_threshold);
+
+ if (support_threshold) {
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_REPLACE_ABOVE_THRESHOLD);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_REPLACE_BELOW_THRESHOLD);
+ }
+
+ if (support_advanced_mixing) {
+ RNA_enum_item_add_separator(&item, &totitem);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_MIX);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_ADD);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_SUB);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_MUL);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+static bool data_transfer_check(bContext *UNUSED(C), wmOperator *op)
+{
+ const int layers_select_src = RNA_enum_get(op->ptr, "layers_select_src");
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "layers_select_dst");
+ const int layers_select_dst = RNA_property_enum_get(op->ptr, prop);
+
+ /* TODO: check for invalid layers_src select modes too! */
+
+ if ((layers_select_src != DT_LAYERS_ACTIVE_SRC) && (layers_select_dst == DT_LAYERS_ACTIVE_DST)) {
+ RNA_property_enum_set(op->ptr, prop, DT_LAYERS_NAME_DST);
+ return true;
+ }
+
+ return false;
+}
+
+/* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
+static void data_transfer_exec_preprocess_objects(
+ bContext *C, wmOperator *op, Object *ob_src, ListBase *ctx_objects, const bool reverse_transfer)
+{
+ CollectionPointerLink *ctx_ob;
+ CTX_data_selected_editable_objects(C, ctx_objects);
+
+ if (reverse_transfer) {
+ return; /* Nothing else to do in this case... */
+ }
+
+ for (ctx_ob = ctx_objects->first; ctx_ob; ctx_ob = ctx_ob->next) {
+ Object *ob = ctx_ob->ptr.data;
+ Mesh *me;
+ if ((ob == ob_src) || (ob->type != OB_MESH)) {
+ continue;
+ }
+
+ me = ob->data;
+ if (me->id.lib) {
+ /* Do not transfer to linked data, not supported. */
+ BKE_reportf(op->reports, RPT_WARNING, "Skipping object '%s', linked data '%s' cannot be modified",
+ ob->id.name + 2, me->id.name + 2);
+ me->id.flag &= ~LIB_DOIT;
+ continue;
+ }
+
+ me->id.flag |= LIB_DOIT;
+ }
+}
+
+/* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
+static bool data_transfer_exec_is_object_valid(
+ wmOperator *op, Object *ob_src, Object *ob_dst, const bool reverse_transfer)
+{
+ Mesh *me;
+ if ((ob_dst == ob_src) || (ob_src->type != OB_MESH) || (ob_dst->type != OB_MESH)) {
+ return false;
+ }
+
+ if (reverse_transfer) {
+ return true;
+ }
+
+ me = ob_dst->data;
+ if (me->id.flag & LIB_DOIT) {
+ me->id.flag &= ~LIB_DOIT;
+ return true;
+ }
+ else if (me->id.lib == NULL) {
+ /* Do not transfer apply operation more than once. */
+ /* XXX This is not nice regarding vgroups, which are half-Object data... :/ */
+ BKE_reportf(op->reports, RPT_WARNING,
+ "Skipping object '%s', data '%s' has already been processed with a previous object",
+ ob_dst->id.name + 2, me->id.name + 2);
+ }
+ return false;
+}
+
+static int data_transfer_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob_src = CTX_data_active_object(C);
+
+ ListBase ctx_objects;
+ CollectionPointerLink *ctx_ob_dst;
+
+ bool changed = false;
+
+ const bool reverse_transfer = RNA_boolean_get(op->ptr, "use_reverse_transfer");
+
+ const int data_type = RNA_enum_get(op->ptr, "data_type");
+ const bool use_create = RNA_boolean_get(op->ptr, "use_create");
+
+ const int map_vert_mode = RNA_enum_get(op->ptr, "vert_mapping");
+ const int map_edge_mode = RNA_enum_get(op->ptr, "edge_mapping");
+ const int map_loop_mode = RNA_enum_get(op->ptr, "loop_mapping");
+ const int map_poly_mode = RNA_enum_get(op->ptr, "poly_mapping");
+
+ const bool use_object_transform = RNA_boolean_get(op->ptr, "use_object_transform");
+ const bool use_max_distance = RNA_boolean_get(op->ptr, "use_max_distance");
+ const float max_distance = use_max_distance ? RNA_float_get(op->ptr, "max_distance") : FLT_MAX;
+ const float ray_radius = RNA_float_get(op->ptr, "ray_radius");
+ const float islands_precision = RNA_float_get(op->ptr, "islands_precision");
+
+ const int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
+ const int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
+ int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
+ int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
+ const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
+
+ const int mix_mode = RNA_enum_get(op->ptr, "mix_mode");
+ const float mix_factor = RNA_float_get(op->ptr, "mix_factor");
+
+ SpaceTransform space_transform_data;
+ SpaceTransform *space_transform = use_object_transform ? &space_transform_data : NULL;
+
+ if (reverse_transfer && ((ID *)(ob_src->data))->lib) {
+ /* Do not transfer to linked data, not supported. */
+ return OPERATOR_CANCELLED;
+ }
+
+ if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
+ layers_select_src[fromto_idx] = layers_src;
+ layers_select_dst[fromto_idx] = layers_dst;
+ }
+
+ data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, reverse_transfer);
+
+ for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
+ Object *ob_dst = ctx_ob_dst->ptr.data;
+
+ if (reverse_transfer) {
+ SWAP(Object *, ob_src, ob_dst);
+ }
+
+ if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, reverse_transfer)) {
+ if (space_transform) {
+ BLI_SPACE_TRANSFORM_SETUP(space_transform, ob_dst, ob_src);
+ }
+
+ if (BKE_object_data_transfer_mesh(
+ scene, ob_src, ob_dst, data_type, use_create,
+ map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode,
+ space_transform, max_distance, ray_radius, islands_precision,
+ layers_select_src, layers_select_dst,
+ mix_mode, mix_factor, NULL, false, op->reports))
+ {
+ changed = true;
+ }
+ }
+
+ DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
+
+ if (reverse_transfer) {
+ SWAP(Object *, ob_src, ob_dst);
+ }
+ }
+
+ BLI_freelistN(&ctx_objects);
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
+
+#if 0 /* TODO */
+ /* Note: issue with that is that if canceled, operator cannot be redone... Nasty in our case. */
+ return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+#else
+ (void)changed;
+ return OPERATOR_FINISHED;
+#endif
+}
+
+/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
+/* Note this context poll is only really partial, it cannot check for all possible invalid cases. */
+static int data_transfer_poll(bContext *C)
+{
+ Object *ob = ED_object_context(C);
+ ID *data = (ob) ? ob->data : NULL;
+ return (ob && ob->type == OB_MESH && data);
+}
+
+/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
+static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+{
+ PropertyRNA *prop_other;
+
+ const char *prop_id = RNA_property_identifier(prop);
+ const int data_type = RNA_enum_get(ptr, "data_type");
+ bool use_max_distance = false;
+ bool use_modifier = false;
+
+ if ((prop_other = RNA_struct_find_property(ptr, "use_max_distance"))) {
+ use_max_distance = RNA_property_boolean_get(ptr, prop_other);
+ }
+ if ((prop_other = RNA_struct_find_property(ptr, "modifier"))) {
+ use_modifier = RNA_property_is_set(ptr, prop_other);
+ }
+
+ if (STREQ(prop_id, "modifier")) {
+ return use_modifier;
+ }
+
+ if (use_modifier) {
+ /* Hide everything but 'modifier' property, if set. */
+ return false;
+ }
+
+ if (STREQ(prop_id, "max_distance") && !use_max_distance) {
+ return false;
+ }
+ if (STREQ(prop_id, "islands_precision") && !DT_DATATYPE_IS_LOOP(data_type)) {
+ return false;
+ }
+
+ if (STREQ(prop_id, "vert_mapping") && !DT_DATATYPE_IS_VERT(data_type)) {
+ return false;
+ }
+ if (STREQ(prop_id, "edge_mapping") && !DT_DATATYPE_IS_EDGE(data_type)) {
+ return false;
+ }
+ if (STREQ(prop_id, "loop_mapping") && !DT_DATATYPE_IS_LOOP(data_type)) {
+ return false;
+ }
+ if (STREQ(prop_id, "poly_mapping") && !DT_DATATYPE_IS_POLY(data_type)) {
+ return false;
+ }
+
+ if ((STREQ(prop_id, "layers_select_src") || STREQ(prop_id, "layers_select_dst")) &&
+ !DT_DATATYPE_IS_MULTILAYERS(data_type))
+ {
+ return false;
+ }
+
+ /* Else, show it! */
+ return true;
+}
+
+/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
+static void data_transfer_ui(bContext *C, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ PointerRNA ptr;
+
+ RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+
+ /* Main auto-draw call */
+ uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, '\0');
+}
+
+/* transfers weight from active to selected */
+void OBJECT_OT_data_transfer(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* Identifiers.*/
+ ot->name = "Transfer Mesh Data";
+ ot->idname = "OBJECT_OT_data_transfer";
+ ot->description = "Transfer data layer(s) (weights, edge sharp, ...) from active to selected meshes";
+
+ /* API callbacks.*/
+ ot->poll = data_transfer_poll;
+ ot->invoke = WM_menu_invoke;
+ ot->exec = data_transfer_exec;
+ ot->check = data_transfer_check;
+ ot->ui = data_transfer_ui;
+
+ /* Flags.*/
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* Properties.*/
+ prop = RNA_def_boolean(ot->srna, "use_reverse_transfer", false, "Reverse Transfer",
+ "Transfer from selected objects to active one");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+
+ /* Data type to transfer. */
+ ot->prop = RNA_def_enum(ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
+ RNA_def_boolean(ot->srna, "use_create", true, "Create Data", "Add data layers on destination meshes if needed");
+
+ /* Mapping methods. */
+ RNA_def_enum(ot->srna, "vert_mapping", DT_method_vertex_items, MREMAP_MODE_VERT_NEAREST, "Vertex Mapping",
+ "Method used to map source vertices to destination ones");
+ RNA_def_enum(ot->srna, "edge_mapping", DT_method_edge_items, MREMAP_MODE_EDGE_NEAREST, "Edge Mapping",
+ "Method used to map source edges to destination ones");
+ RNA_def_enum(ot->srna, "loop_mapping", DT_method_loop_items, MREMAP_MODE_LOOP_NEAREST_POLYNOR,
+ "Face Corner Mapping", "Method used to map source faces' corners to destination ones");
+ RNA_def_enum(ot->srna, "poly_mapping", DT_method_poly_items, MREMAP_MODE_POLY_NEAREST, "Face Mapping",
+ "Method used to map source faces to destination ones");
+
+ /* Mapping options and filtering. */
+ RNA_def_boolean(ot->srna, "use_object_transform", true, "Object Transform",
+ "Evaluate source and destination meshes in their respective object spaces");
+ RNA_def_boolean(ot->srna, "use_max_distance", false, "Only Neighbor Geometry",
+ "Source elements must be closer than given distance from destination one");
+ prop = RNA_def_float(ot->srna, "max_distance", 1.0f, 0.0f, FLT_MAX, "Max Distance",
+ "Maximum allowed distance between source and destination element, for non-topology mappings",
+ 0.0f, 100.0f);
+ RNA_def_property_subtype(prop, PROP_DISTANCE);
+ prop = RNA_def_float(ot->srna, "ray_radius", 0.0f, 0.0f, FLT_MAX, "Ray Radius",
+ "'Width' of rays (especially useful when raycasting against vertices or edges)",
+ 0.0f, 10.0f);
+ RNA_def_property_subtype(prop, PROP_DISTANCE);
+ prop = RNA_def_float(ot->srna, "islands_precision", 0.1f, 0.0f, 10.0f, "Islands Precision",
+ "Factor controlling precision of islands handling (the higher, the better the results)",
+ 0.0f, 1.0f);
+ RNA_def_property_subtype(prop, PROP_FACTOR);
+
+ /* How to handle multi-layers types of data. */
+ prop = RNA_def_enum(ot->srna, "layers_select_src", DT_layers_select_src_items, DT_LAYERS_ACTIVE_SRC,
+ "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
+ RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_src_itemf);
+
+ prop = RNA_def_enum(ot->srna, "layers_select_dst", DT_layers_select_dst_items, DT_LAYERS_ACTIVE_DST,
+ "Destination Layers Matching", "How to match source and destination layers");
+ RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_dst_itemf);
+
+ prop = RNA_def_enum(ot->srna, "mix_mode", DT_mix_mode_items, CDT_MIX_TRANSFER, "Mix Mode",
+ "How to affect destination elements with source values");
+ RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_mix_mode_itemf);
+ RNA_def_float(ot->srna, "mix_factor", 1.0f, 0.0f, 1.0f, "Mix Factor",
+ "Factor to use when applying data to destination (exact behavior depends on mix mode)", 0.0f, 1.0f);
+}
+
+/******************************************************************************/
+/* Note: This operator is hybrid, it can work as a usual standalone Object operator,
+ * or as a DataTransfer modifier tool.
+ */
+
+static int datalayout_transfer_poll(bContext *C)
+{
+ return (edit_modifier_poll_generic(C, &RNA_DataTransferModifier, (1 << OB_MESH)) || data_transfer_poll(C));
+}
+
+static int datalayout_transfer_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob_act = ED_object_active_context(C);
+ DataTransferModifierData *dtmd;
+
+ dtmd = (DataTransferModifierData *)edit_modifier_property_get(op, ob_act, eModifierType_DataTransfer);
+
+ /* If we have a modifier, we transfer data layout from this modifier's source object to active one.
+ * Else, we transfer data layout from active object to all selected ones. */
+ if (dtmd) {
+ Object *ob_src = dtmd->ob_source;
+ Object *ob_dst = ob_act;
+
+ const bool use_delete = false; /* Never when used from modifier, for now. */
+
+ if (!ob_src) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_object_data_transfer_layout(scene, ob_src, ob_dst, dtmd->data_types, use_delete,
+ dtmd->layers_select_src, dtmd->layers_select_dst);
+
+ DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
+ }
+ else {
+ Object *ob_src = ob_act;
+
+ ListBase ctx_objects;
+ CollectionPointerLink *ctx_ob_dst;
+
+ const int data_type = RNA_enum_get(op->ptr, "data_type");
+ const bool use_delete = RNA_boolean_get(op->ptr, "use_delete");
+
+ const int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
+ const int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
+ int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
+ int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
+ const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
+
+ if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
+ layers_select_src[fromto_idx] = layers_src;
+ layers_select_dst[fromto_idx] = layers_dst;
+ }
+
+ data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, false);
+
+ for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
+ Object *ob_dst = ctx_ob_dst->ptr.data;
+ if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, false)) {
+ BKE_object_data_transfer_layout(scene, ob_src, ob_dst, data_type, use_delete,
+ layers_select_src, layers_select_dst);
+ }
+
+ DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
+ }
+
+ BLI_freelistN(&ctx_objects);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static int datalayout_transfer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ if (edit_modifier_invoke_properties(C, op)) {
+ return datalayout_transfer_exec(C, op);
+ }
+ else {
+ return WM_menu_invoke(C, op, event);
+ }
+}
+
+void OBJECT_OT_datalayout_transfer(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ ot->name = "Transfer Mesh Data Layout";
+ ot->description = "Transfer layout of data layer(s) from active to selected meshes";
+ ot->idname = "OBJECT_OT_datalayout_transfer";
+
+ ot->poll = datalayout_transfer_poll;
+ ot->invoke = datalayout_transfer_invoke;
+ ot->exec = datalayout_transfer_exec;
+ ot->check = data_transfer_check;
+ ot->ui = data_transfer_ui;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* Properties.*/
+ edit_modifier_properties(ot);
+
+ /* Data type to transfer. */
+ ot->prop = RNA_def_enum(ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
+ RNA_def_boolean(ot->srna, "use_delete", false, "Exact Match",
+ "Also delete some data layers from destination if necessary, so that it matches exactly source");
+
+ /* How to handle multi-layers types of data. */
+ prop = RNA_def_enum(ot->srna, "layers_select_src", DT_layers_select_src_items, DT_LAYERS_ACTIVE_SRC,
+ "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
+ RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_src_itemf);
+
+ prop = RNA_def_enum(ot->srna, "layers_select_dst", DT_layers_select_dst_items, DT_LAYERS_ACTIVE_DST,
+ "Destination Layers Matching", "How to match source and destination layers");
+ RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_dst_itemf);
+}
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 93956128b84..e14b3036743 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -42,6 +42,8 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
+#include "BLF_translation.h"
+
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
@@ -64,6 +66,7 @@
#include "BKE_effect.h"
#include "BKE_depsgraph.h"
#include "BKE_image.h"
+#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -1347,7 +1350,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op)
ID *data;
Curve *cu;
Nurb *nu;
- int clear = (strcmp(op->idname, "OBJECT_OT_shade_flat") == 0);
+ int clear = (STREQ(op->idname, "OBJECT_OT_shade_flat"));
bool done = false, linked_data = false;
CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
@@ -1701,7 +1704,7 @@ static int game_property_new_exec(bContext *C, wmOperator *op)
BLI_strncpy(prop->name, name, sizeof(prop->name));
}
- BKE_bproperty_unique(NULL, prop, 0); // make_unique_prop_names(prop->name);
+ BLI_uniquename(&ob->prop, prop, DATA_("Property"), '.', offsetof(bProperty, name), sizeof(prop->name));
WM_event_add_notifier(C, NC_LOGIC, NULL);
return OPERATOR_FINISHED;
@@ -1997,3 +2000,67 @@ void OBJECT_OT_game_physics_copy(struct wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/* generic utility function */
+
+bool ED_object_editmode_calc_active_center(Object *obedit, const bool select_only, float r_center[3])
+{
+ switch (obedit->type) {
+ case OB_MESH:
+ {
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMEditSelection ese;
+
+ if (BM_select_history_active_get(em->bm, &ese)) {
+ BM_editselection_center(&ese, r_center);
+ return true;
+ }
+ break;
+ }
+ case OB_ARMATURE:
+ {
+ bArmature *arm = obedit->data;
+ EditBone *ebo = arm->act_edbone;
+
+ if (ebo && (!select_only || (ebo->flag & (BONE_SELECTED | BONE_ROOTSEL)))) {
+ copy_v3_v3(r_center, ebo->head);
+ return true;
+ }
+
+ break;
+ }
+ case OB_CURVE:
+ case OB_SURF:
+ {
+ Curve *cu = obedit->data;
+
+ if (ED_curve_active_center(cu, r_center)) {
+ return true;
+ }
+ break;
+ }
+ case OB_MBALL:
+ {
+ MetaBall *mb = obedit->data;
+ MetaElem *ml_act = mb->lastelem;
+
+ if (ml_act && (!select_only || (ml_act->flag & SELECT))) {
+ copy_v3_v3(r_center, &ml_act->x);
+ return true;
+ }
+ break;
+ }
+ case OB_LATTICE:
+ {
+ BPoint *actbp = BKE_lattice_active_point_get(obedit->data);
+
+ if (actbp) {
+ copy_v3_v3(r_center, actbp->vec);
+ return true;
+ }
+ break;
+ }
+ }
+
+ return false;
+}
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 20e2e22cdf8..3c43f2729bd 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -61,47 +61,6 @@
/********************* 3d view operators ***********************/
-static bool group_link_early_exit_check(Group *group, Object *object)
-{
- GroupObject *group_object;
-
- for (group_object = group->gobject.first; group_object; group_object = group_object->next) {
- if (group_object->ob == object) {
- return true;
- }
- }
-
- return false;
-}
-
-static bool check_object_instances_group_recursive(Object *object, Group *group)
-{
- if (object->dup_group) {
- Group *dup_group = object->dup_group;
- if ((dup_group->id.flag & LIB_DOIT) == 0) {
- /* Cycle already exists in groups, let's prevent further crappyness */
- return true;
- }
- /* flag the object to identify cyclic dependencies in further dupli groups */
- dup_group->id.flag &= ~LIB_DOIT;
-
- if (dup_group == group)
- return true;
- else {
- GroupObject *gob;
- for (gob = dup_group->gobject.first; gob; gob = gob->next) {
- if (check_object_instances_group_recursive(gob->ob, group))
- return true;
- }
- }
-
- /* un-flag the object, it's allowed to have the same group multiple times in parallel */
- dup_group->id.flag |= LIB_DOIT;
- }
-
- return false;
-}
-
/* can be called with C == NULL */
static EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
{
@@ -185,15 +144,12 @@ static int objects_add_active_exec(bContext *C, wmOperator *op)
if (!BKE_group_object_exists(group, ob))
continue;
- /* for recursive check */
- BKE_main_id_tag_listbase(&bmain->group, true);
-
CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
{
- if (group_link_early_exit_check(group, base->object))
+ if (BKE_group_object_exists(group, base->object))
continue;
- if (!check_object_instances_group_recursive(base->object, group)) {
+ if (!BKE_group_object_cyclic_check(bmain, base->object, group)) {
BKE_group_object_add(group, base->object, scene, base);
updated = true;
}
@@ -486,7 +442,7 @@ static int group_link_exec(bContext *C, wmOperator *op)
* we could sckip all the dependency check and just consider
* operator is finished.
*/
- if (group_link_early_exit_check(group, ob)) {
+ if (BKE_group_object_exists(group, ob)) {
return OPERATOR_FINISHED;
}
@@ -495,8 +451,7 @@ static int group_link_exec(bContext *C, wmOperator *op)
* It is also bad idea to add object to group which is in group which
* contains our current object.
*/
- BKE_main_id_tag_listbase(&bmain->group, true);
- if (check_object_instances_group_recursive(ob, group)) {
+ if (BKE_group_object_cyclic_check(bmain, ob, group)) {
BKE_report(op->reports, RPT_ERROR, "Could not add the group because of dependency cycle detected");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index 9f9a647c9f1..1d764ced524 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -503,6 +503,15 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob
unit_m4(pose_mat);
+ invert_m4_m4(obedit->imat, obedit->obmat);
+ if (mode == OBJECT_ADDHOOK_NEWOB) {
+ /* pass */
+ }
+ else {
+ /* may overwrite with pose-bone location, below */
+ mul_v3_m4v3(cent, obedit->imat, ob->obmat[3]);
+ }
+
if (mode == OBJECT_ADDHOOK_SELOB_BONE) {
bArmature *arm = ob->data;
BLI_assert(ob->type == OB_ARMATURE);
@@ -514,6 +523,8 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob
pchan_act = BKE_pose_channel_active(ob);
if (LIKELY(pchan_act)) {
invert_m4_m4(pose_mat, pchan_act->pose_mat);
+ mul_v3_m4v3(cent, ob->obmat, pchan_act->pose_mat[3]);
+ mul_v3_m4v3(cent, obedit->imat, cent);
}
}
else {
@@ -521,6 +532,9 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob
}
}
+ copy_v3_v3(hmd->cent, cent);
+
+
/* matrix calculus */
/* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
/* (parentinv ) */
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 6fa3caa6172..64fddf1b6a1 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -37,6 +37,11 @@ struct Lattice;
struct Curve;
struct Object;
struct Mesh;
+struct bContext;
+struct StructRNA;
+struct wmOperator;
+
+struct ModifierData;
struct HookModifierData;
/* add hook menu */
@@ -155,6 +160,12 @@ void GROUP_OT_objects_add_active(struct wmOperatorType *ot);
void GROUP_OT_objects_remove_active(struct wmOperatorType *ot);
/* object_modifier.c */
+int edit_modifier_poll_generic(struct bContext *C, struct StructRNA *rna_type, int obtype_flag);
+int edit_modifier_poll(struct bContext *C);
+void edit_modifier_properties(struct wmOperatorType *ot);
+int edit_modifier_invoke_properties(struct bContext *C, struct wmOperator *op);
+struct ModifierData *edit_modifier_property_get(struct wmOperator *op, struct Object *ob, int type);
+
void OBJECT_OT_modifier_add(struct wmOperatorType *ot);
void OBJECT_OT_modifier_remove(struct wmOperatorType *ot);
void OBJECT_OT_modifier_move_up(struct wmOperatorType *ot);
@@ -214,7 +225,6 @@ void OBJECT_OT_vertex_group_remove_from(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot);
-void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot);
@@ -266,5 +276,9 @@ void OBJECT_OT_lod_remove(struct wmOperatorType *ot);
/* object_random.c */
void OBJECT_OT_vertex_random(struct wmOperatorType *ot);
+/* object_transfer_data.c */
+void OBJECT_OT_data_transfer(struct wmOperatorType *ot);
+void OBJECT_OT_datalayout_transfer(struct wmOperatorType *ot);
+
#endif /* __OBJECT_INTERN_H__ */
diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c
index c24a127ed8b..b577dab8a77 100644
--- a/source/blender/editors/object/object_lattice.c
+++ b/source/blender/editors/object/object_lattice.c
@@ -100,7 +100,7 @@ void make_editLatt(Object *obedit)
actkey = BKE_keyblock_from_object(obedit);
if (actkey)
- BKE_key_convert_to_lattice(actkey, lt);
+ BKE_keyblock_convert_to_lattice(actkey, lt);
lt->editlatt = MEM_callocN(sizeof(EditLatt), "editlatt");
lt->editlatt->latt = MEM_dupallocN(lt);
diff --git a/source/blender/editors/object/object_lod.c b/source/blender/editors/object/object_lod.c
index 48e980015a7..ced306178b8 100644
--- a/source/blender/editors/object/object_lod.c
+++ b/source/blender/editors/object/object_lod.c
@@ -32,18 +32,22 @@
#include "DNA_object_types.h"
#include "BKE_context.h"
-#include "BKE_object.h"
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
#include "ED_screen.h"
#include "ED_object.h"
+#ifdef WITH_GAMEENGINE
+# include "BKE_object.h"
+
+# include "RNA_enum_types.h"
+#endif
+
#include "object_intern.h"
static int object_lod_add_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index b05840b5823..710cf2dbdd2 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -68,6 +68,7 @@
#include "BKE_multires.h"
#include "BKE_report.h"
#include "BKE_object.h"
+#include "BKE_object_deform.h"
#include "BKE_ocean.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
@@ -439,9 +440,9 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
for (a = 0; a < totpart; a++) {
key = cache[a];
- if (key->steps > 0) {
- totvert += key->steps + 1;
- totedge += key->steps;
+ if (key->segments > 0) {
+ totvert += key->segments + 1;
+ totedge += key->segments;
}
}
@@ -449,9 +450,9 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
for (a = 0; a < totchild; a++) {
key = cache[a];
- if (key->steps > 0) {
- totvert += key->steps + 1;
- totedge += key->steps;
+ if (key->segments > 0) {
+ totvert += key->segments + 1;
+ totedge += key->segments;
}
}
@@ -475,7 +476,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
cache = psys->pathcache;
for (a = 0; a < totpart; a++) {
key = cache[a];
- kmax = key->steps;
+ kmax = key->segments;
for (k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
copy_v3_v3(mvert->co, key->co);
if (k) {
@@ -494,7 +495,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
cache = psys->childcache;
for (a = 0; a < totchild; a++) {
key = cache[a];
- kmax = key->steps;
+ kmax = key->segments;
for (k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
copy_v3_v3(mvert->co, key->co);
if (k) {
@@ -560,7 +561,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M
/* if that was the first key block added, then it was the basis.
* Initialize it with the mesh, and add another for the modifier */
kb = BKE_keyblock_add(key, NULL);
- BKE_key_convert_from_mesh(me, kb);
+ BKE_keyblock_convert_from_mesh(me, kb);
}
kb = BKE_keyblock_add(key, md->name);
@@ -613,9 +614,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
return 0;
}
- DM_to_mesh(dm, me, ob, CD_MASK_MESH);
-
- dm->release(dm);
+ DM_to_mesh(dm, me, ob, CD_MASK_MESH, true);
if (md->type == eModifierType_Multires)
multires_customdata_delete(me);
@@ -807,7 +806,7 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot)
/************************ generic functions for operators using mod names and data context *********************/
-static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
+int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);
@@ -819,17 +818,17 @@ static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obty
return 1;
}
-static int edit_modifier_poll(bContext *C)
+int edit_modifier_poll(bContext *C)
{
return edit_modifier_poll_generic(C, &RNA_Modifier, 0);
}
-static void edit_modifier_properties(wmOperatorType *ot)
+void edit_modifier_properties(wmOperatorType *ot)
{
RNA_def_string(ot->srna, "modifier", NULL, MAX_NAME, "Modifier", "Name of the modifier to edit");
}
-static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
+int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
{
ModifierData *md;
@@ -848,7 +847,7 @@ static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
return false;
}
-static ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
+ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
{
char modifier_name[MAX_NAME];
ModifierData *md;
@@ -1353,7 +1352,7 @@ void OBJECT_OT_multires_external_save(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
- WM_operator_properties_filesel(ot, FOLDERFILE | BTXFILE, FILE_SPECIAL, FILE_SAVE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_BTX, FILE_SPECIAL, FILE_SAVE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
edit_modifier_properties(ot);
}
@@ -1667,7 +1666,7 @@ static void skin_armature_bone_create(Object *skin_ob,
BLI_snprintf(bone->name, sizeof(bone->name), "Bone.%.2d", endx);
/* add bDeformGroup */
- if ((dg = ED_vgroup_add_name(skin_ob, bone->name))) {
+ if ((dg = BKE_object_defgroup_add_name(skin_ob, bone->name))) {
ED_vgroup_vert_add(skin_ob, dg, parent_v, 1, WEIGHT_REPLACE);
ED_vgroup_vert_add(skin_ob, dg, v, 1, WEIGHT_REPLACE);
}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 7cf661de52c..15eb9090ce5 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -40,7 +40,6 @@
#include "BKE_context.h"
#include "RNA_access.h"
-#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -178,7 +177,6 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_select);
WM_operatortype_append(OBJECT_OT_vertex_group_deselect);
WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked);
- WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight);
WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected);
WM_operatortype_append(OBJECT_OT_vertex_group_copy);
WM_operatortype_append(OBJECT_OT_vertex_group_normalize);
@@ -250,6 +248,9 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_lod_remove);
WM_operatortype_append(OBJECT_OT_vertex_random);
+
+ WM_operatortype_append(OBJECT_OT_data_transfer);
+ WM_operatortype_append(OBJECT_OT_datalayout_transfer);
}
void ED_operatormacros_object(void)
@@ -320,6 +321,7 @@ void ED_keymap_object(wmKeyConfig *keyconf)
ED_keymap_proportional_cycle(keyconf, keymap);
ED_keymap_proportional_obmode(keyconf, keymap);
+ /* game-engine only, leave free for users to define */
WM_keymap_add_item(keymap, "VIEW3D_OT_game_start", PKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_select_all", AKEY, KM_PRESS, 0, 0);
@@ -420,6 +422,10 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "VIEW3D_MT_object_specials", WKEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_data_transfer", TKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
+ /* XXX No more available 'T' shortcuts... :/ */
+ /* WM_keymap_verify_item(keymap, "OBJECT_OT_datalayout_transfer", TKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0); */
+
for (i = 0; i <= 5; i++) {
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", ZEROKEY + i, KM_PRESS, KM_CTRL, 0);
RNA_int_set(kmi->ptr, "level", i);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 8f74278b424..bfa501c3732 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -300,23 +300,25 @@ static int make_proxy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
else if (ob->id.lib) {
- uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("OK?"), ICON_QUESTION);
- uiLayout *layout = uiPupMenuLayout(pup);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("OK?"), ICON_QUESTION);
+ uiLayout *layout = UI_popup_menu_layout(pup);
/* create operator menu item with relevant properties filled in */
uiItemFullO_ptr(layout, op->type, op->type->name, ICON_NONE, NULL,
WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
/* present the menu and be done... */
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
+
+ /* this invoke just calls another instance of this operator... */
+ return OPERATOR_INTERFACE;
}
else {
/* error.. cannot continue */
BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or group");
+ return OPERATOR_CANCELLED;
}
- /* this invoke just calls another instance of this operator... */
- return OPERATOR_CANCELLED;
}
static int make_proxy_exec(bContext *C, wmOperator *op)
@@ -801,6 +803,7 @@ static void parent_set_vert_find(KDTree *tree, Object *child, int vert_par[3], b
tot = BLI_kdtree_find_nearest_n(tree, co_find, nearest, 3);
BLI_assert(tot == 3);
+ UNUSED_VARS(tot);
vert_par[0] = nearest[0].index;
vert_par[1] = nearest[1].index;
@@ -879,8 +882,8 @@ static int parent_set_exec(bContext *C, wmOperator *op)
static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
Object *ob = ED_object_active_context(C);
- uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Set Parent To"), ICON_NONE);
- uiLayout *layout = uiPupMenuLayout(pup);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_parent_set", true);
PointerRNA opptr;
@@ -921,9 +924,9 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_VERTEX_TRI);
}
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
@@ -970,7 +973,7 @@ void OBJECT_OT_parent_set(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
RNA_def_boolean(ot->srna, "xmirror", false, "X Mirror",
"Apply weights symmetrically along X axis, for Envelope/Automatic vertex groups creation");
RNA_def_boolean(ot->srna, "keep_transform", false, "Keep Transform",
@@ -1313,7 +1316,7 @@ static unsigned int move_to_layer_init(bContext *C, wmOperator *op)
CTX_DATA_END;
for (a = 0; a < 20; a++)
- values[a] = (lay & (1 << a));
+ values[a] = (lay & (1 << a)) != 0;
RNA_boolean_set_array(op->ptr, "layers", values);
}
@@ -2341,10 +2344,8 @@ void OBJECT_OT_make_local(wmOperatorType *ot)
}
enum {
- /* Be careful with those values, they are used as bitflags in some cases, in others as bool...
- * See single_object_users, single_obdata_users, single_object_action_users, etc.< */
- MAKE_SINGLE_USER_ALL = 0,
- MAKE_SINGLE_USER_SELECTED = SELECT,
+ MAKE_SINGLE_USER_ALL = 1,
+ MAKE_SINGLE_USER_SELECTED = 2,
};
static int make_single_user_exec(bContext *C, wmOperator *op)
@@ -2352,7 +2353,7 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C); /* ok if this is NULL */
- const int flag = RNA_enum_get(op->ptr, "type");
+ const int flag = (RNA_enum_get(op->ptr, "type") == MAKE_SINGLE_USER_SELECTED) ? SELECT : 0;
const bool copy_groups = false;
bool update_deps = false;
@@ -2418,7 +2419,7 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", type_items, SELECT, "Type", "");
+ ot->prop = RNA_def_enum(ot->srna, "type", type_items, MAKE_SINGLE_USER_SELECTED, "Type", "");
RNA_def_boolean(ot->srna, "object", 0, "Object", "Make single user objects");
RNA_def_boolean(ot->srna, "obdata", 0, "Object Data", "Make single user object data");
@@ -2475,7 +2476,7 @@ static int object_unlink_data_exec(bContext *C, wmOperator *op)
ID *id;
PropertyPointerRNA pprop;
- uiIDContextProperty(C, &pprop.ptr, &pprop.prop);
+ UI_context_active_but_prop_get_templateID(C, &pprop.ptr, &pprop.prop);
if (pprop.prop == NULL) {
BKE_report(op->reports, RPT_ERROR, "Incorrect context for running object data unlink");
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index e295a63848a..65ce0c8d520 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -618,15 +618,15 @@ static bool select_grouped_group(bContext *C, Object *ob) /* Select objects in
}
/* build the menu. */
- pup = uiPupMenuBegin(C, IFACE_("Select Group"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("Select Group"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
for (i = 0; i < group_count; i++) {
group = ob_groups[i];
uiItemStringO(layout, group->id.name + 2, 0, "OBJECT_OT_select_same_group", "group", group->id.name + 2);
}
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
return changed; /* The operator already handle this! */
}
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 4a24ab66721..3fe8c86ef5c 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -75,10 +75,10 @@
/*********************** add shape key ***********************/
-static void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob, const bool from_mix)
+static void ED_object_shape_key_add(bContext *C, Object *ob, const bool from_mix)
{
KeyBlock *kb;
- if ((kb = BKE_object_insert_shape_key(scene, ob, NULL, from_mix))) {
+ if ((kb = BKE_object_insert_shape_key(ob, NULL, from_mix))) {
Key *key = BKE_key_from_object(ob);
/* for absolute shape keys, new keys may not be added last */
ob->shapenr = BLI_findindex(&key->block, kb) + 1;
@@ -133,14 +133,14 @@ static bool ED_object_shape_key_remove(Main *bmain, Object *ob)
/* apply new basis key on original data */
switch (ob->type) {
case OB_MESH:
- BKE_key_convert_to_mesh(key->refkey, ob->data);
+ BKE_keyblock_convert_to_mesh(key->refkey, ob->data);
break;
case OB_CURVE:
case OB_SURF:
- BKE_key_convert_to_curve(key->refkey, ob->data, BKE_curve_nurbs_get(ob->data));
+ BKE_keyblock_convert_to_curve(key->refkey, ob->data, BKE_curve_nurbs_get(ob->data));
break;
case OB_LATTICE:
- BKE_key_convert_to_lattice(key->refkey, ob->data);
+ BKE_keyblock_convert_to_lattice(key->refkey, ob->data);
break;
}
}
@@ -320,11 +320,10 @@ static int shape_key_poll(bContext *C)
static int shape_key_add_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_context(C);
const bool from_mix = RNA_boolean_get(op->ptr, "from_mix");
- ED_object_shape_key_add(C, scene, ob, from_mix);
+ ED_object_shape_key_add(C, ob, from_mix);
return OPERATOR_FINISHED;
}
@@ -379,7 +378,6 @@ void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
ot->description = "Remove shape key from the object";
/* api callbacks */
- ot->poll = shape_key_mode_poll;
ot->poll = shape_key_mode_exists_poll;
ot->exec = shape_key_remove_exec;
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index f19765a5344..92fe5ded4dd 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -33,9 +33,7 @@
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
-#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -69,7 +67,6 @@
#include "ED_armature.h"
#include "ED_keyframing.h"
-#include "ED_mball.h"
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_view3d.h"
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 777bbabb6e8..f885cbbb24f 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -36,16 +36,13 @@
#include "MEM_guardedalloc.h"
-#include "DNA_cloth_types.h"
#include "DNA_curve_types.h"
#include "DNA_lattice_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
#include "DNA_scene_types.h"
-#include "DNA_particle_types.h"
#include "BLI_alloca.h"
#include "BLI_array.h"
@@ -54,7 +51,6 @@
#include "BLI_utildefines.h"
#include "BLI_linklist_stack.h"
-#include "BLF_translation.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
@@ -85,11 +81,6 @@
#include "object_intern.h"
/************************ Exported Functions **********************/
-static void vgroup_remap_update_users(Object *ob, int *map);
-static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup);
-static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg);
-static void vgroup_delete_all(Object *ob);
-
static bool vertex_group_use_vert_sel(Object *ob)
{
if (ob->mode == OB_MODE_EDIT) {
@@ -126,81 +117,6 @@ bool ED_vgroup_sync_from_pose(Object *ob)
return false;
}
-bool ED_vgroup_object_is_edit_mode(Object *ob)
-{
- if (ob->type == OB_MESH)
- return (BKE_editmesh_from_object(ob) != NULL);
- else if (ob->type == OB_LATTICE)
- return (((Lattice *)ob->data)->editlatt != NULL);
-
- return false;
-}
-
-bDeformGroup *ED_vgroup_add_name(Object *ob, const char *name)
-{
- bDeformGroup *defgroup;
-
- if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type))
- return NULL;
-
- defgroup = BKE_defgroup_new(ob, name);
-
- ob->actdef = BLI_countlist(&ob->defbase);
-
- return defgroup;
-}
-
-bDeformGroup *ED_vgroup_add(Object *ob)
-{
- return ED_vgroup_add_name(ob, DATA_("Group"));
-}
-
-void ED_vgroup_delete(Object *ob, bDeformGroup *defgroup)
-{
- BLI_assert(BLI_findindex(&ob->defbase, defgroup) != -1);
-
- if (ED_vgroup_object_is_edit_mode(ob))
- vgroup_delete_edit_mode(ob, defgroup);
- else
- vgroup_delete_object_mode(ob, defgroup);
-}
-
-void ED_vgroup_clear(Object *ob)
-{
- bDeformGroup *dg = (bDeformGroup *)ob->defbase.first;
- int edit_mode = ED_vgroup_object_is_edit_mode(ob);
-
- while (dg) {
- bDeformGroup *next_dg = dg->next;
-
- if (edit_mode)
- vgroup_delete_edit_mode(ob, dg);
- else
- vgroup_delete_object_mode(ob, dg);
-
- dg = next_dg;
- }
-}
-
-bool ED_vgroup_data_create(ID *id)
-{
- /* create deform verts */
-
- if (GS(id->name) == ID_ME) {
- Mesh *me = (Mesh *)id;
- me->dvert = CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
- return true;
- }
- else if (GS(id->name) == ID_LT) {
- Lattice *lt = (Lattice *)id;
- lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert");
- return true;
- }
- else {
- return false;
- }
-}
-
/**
* Removes out of range MDeformWeights
*/
@@ -327,31 +243,6 @@ bool ED_vgroup_parray_alloc(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, co
return false;
}
-static bool ed_vgroup_dm_parray_alloc(DerivedMesh *dm, MDeformVert ***dvert_arr, int *dvert_tot)
-{
- *dvert_tot = 0;
- *dvert_arr = NULL;
-
- if (dm) {
- MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
-
- if (dvert) {
- int i, totvert = dm->getNumVerts(dm);
-
- *dvert_tot = totvert;
- *dvert_arr = MEM_mallocN(sizeof(void *) * totvert, "vgroup parray from me");
-
- for (i = 0; i < totvert; i++) {
- (*dvert_arr)[i] = dvert + i;
- }
-
- return true;
- }
- }
-
- return false;
-}
-
/**
* For use with tools that use ED_vgroup_parray_alloc with \a use_vert_sel == true.
* This finds the unselected mirror deform verts and copys the weights to them from the selected.
@@ -465,34 +356,6 @@ void ED_vgroup_parray_remove_zero(MDeformVert **dvert_array, const int dvert_tot
}
}
-/* returns true if the id type supports weights */
-bool ED_vgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot)
-{
- if (id) {
- switch (GS(id->name)) {
- case ID_ME:
- {
- Mesh *me = (Mesh *)id;
- *dvert_arr = me->dvert;
- *dvert_tot = me->totvert;
- return true;
- }
- case ID_LT:
- {
- Lattice *lt = (Lattice *)id;
- lt = (lt->editlatt) ? lt->editlatt->latt : lt;
- *dvert_arr = lt->dvert;
- *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw;
- return true;
- }
- }
- }
-
- *dvert_arr = NULL;
- *dvert_tot = 0;
- return false;
-}
-
/* matching index only */
bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
{
@@ -501,8 +364,8 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
int dvert_tot_from;
int dvert_tot;
int i;
- int defbase_tot_from = BLI_countlist(&ob_from->defbase);
- int defbase_tot = BLI_countlist(&ob->defbase);
+ int defbase_tot_from = BLI_listbase_count(&ob_from->defbase);
+ int defbase_tot = BLI_listbase_count(&ob->defbase);
bool new_vgroup = false;
if (ob == ob_from)
@@ -511,7 +374,7 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
ED_vgroup_parray_alloc(ob_from->data, &dvert_array_from, &dvert_tot_from, false);
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false);
- if ((dvert_array == NULL) && (dvert_array_from != NULL) && ED_vgroup_data_create(ob->data)) {
+ if ((dvert_array == NULL) && (dvert_array_from != NULL) && BKE_object_defgroup_data_create(ob->data)) {
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false);
new_vgroup = true;
}
@@ -523,7 +386,7 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
if (new_vgroup == true) {
/* free the newly added vgroup since it wasn't compatible */
- vgroup_delete_all(ob);
+ BKE_object_defgroup_remove_all(ob);
}
/* if true: both are 0 and nothing needs changing, consider this a success */
@@ -541,7 +404,7 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
for (i = 0; i <= defbase_tot_from; i++) remap[i] = i;
for (; i <= defbase_tot; i++) remap[i] = 0; /* can't use these, so disable */
- vgroup_remap_update_users(ob, remap);
+ BKE_object_defgroup_remap_update_users(ob, remap);
MEM_freeN(remap);
}
@@ -682,7 +545,7 @@ static void vgroup_normalize_active(Object *ob, eVGroupSelect subset_type)
return;
}
- vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
defvert_normalize_subset(dvert_act, vgroup_validmap, vgroup_tot);
MEM_freeN((void *)vgroup_validmap);
@@ -703,7 +566,7 @@ static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type)
BMEditMesh *em = me->edit_btmesh;
MDeformVert *dvert_act;
int i, vgroup_tot, subset_count;
- const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
if (em) {
@@ -747,51 +610,6 @@ static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type)
/***********************Start weight transfer (WT)*********************************/
-typedef enum WT_VertexGroupMode {
- WT_REPLACE_ACTIVE_VERTEX_GROUP = 1,
- WT_REPLACE_ALL_VERTEX_GROUPS = 2
-} WT_VertexGroupMode;
-
-typedef enum WT_Method {
- WT_BY_INDEX = 1,
- WT_BY_NEAREST_VERTEX = 2,
- WT_BY_NEAREST_FACE = 3,
- WT_BY_NEAREST_VERTEX_IN_FACE = 4
-} WT_Method;
-
-typedef enum WT_ReplaceMode {
- WT_REPLACE_ALL_WEIGHTS = 1,
- WT_REPLACE_EMPTY_WEIGHTS = 2
-} WT_ReplaceMode;
-
-static EnumPropertyItem WT_vertex_group_mode_item[] = {
- {WT_REPLACE_ACTIVE_VERTEX_GROUP,
- "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"},
- {WT_REPLACE_ALL_VERTEX_GROUPS,
- "WT_REPLACE_ALL_VERTEX_GROUPS", 0, "All", "Transfer all vertex groups from selected to active mesh"},
- {0, NULL, 0, NULL, NULL}
-};
-
-static EnumPropertyItem WT_method_item[] = {
- {WT_BY_INDEX,
- "WT_BY_INDEX", 0, "Vertex index", "Copy for identical meshes"},
- {WT_BY_NEAREST_VERTEX,
- "WT_BY_NEAREST_VERTEX", 0, "Nearest vertex", "Copy weight from closest vertex"},
- {WT_BY_NEAREST_FACE,
- "WT_BY_NEAREST_FACE", 0, "Nearest face", "Barycentric interpolation from nearest face"},
- {WT_BY_NEAREST_VERTEX_IN_FACE,
- "WT_BY_NEAREST_VERTEX_IN_FACE", 0, "Nearest vertex in face", "Copy weight from closest vertex in nearest face"},
- {0, NULL, 0, NULL, NULL}
-};
-
-static EnumPropertyItem WT_replace_mode_item[] = {
- {WT_REPLACE_ALL_WEIGHTS,
- "WT_REPLACE_ALL_WEIGHTS", 0, "All", "Overwrite all weights"},
- {WT_REPLACE_EMPTY_WEIGHTS,
- "WT_REPLACE_EMPTY_WEIGHTS", 0, "Empty", "Add weights to vertices with no weight"},
- {0, NULL, 0, NULL, NULL}
-};
-
static EnumPropertyItem WT_vertex_group_select_item[] = {
{WT_VGROUP_ACTIVE,
"ACTIVE", 0, "Active Group", "The active Vertex Group"},
@@ -867,298 +685,6 @@ static void vgroup_operator_subset_select_props(wmOperatorType *ot, bool use_act
ot->prop = prop;
}
-/* Copy weight.*/
-static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, const WT_ReplaceMode replace_mode)
-{
- switch (replace_mode) {
- case WT_REPLACE_ALL_WEIGHTS:
- *r_weight_dst = weight_src;
- break;
-
- case WT_REPLACE_EMPTY_WEIGHTS:
- if (*r_weight_dst == 0.0f) {
- *r_weight_dst = weight_src;
- }
- break;
-
- default:
- BLI_assert(0);
- break;
- }
-}
-
-/* Could be exposed externally by implementing it in header with the rest.
- * Simple refactoring will break something.
- * For now, naming is ed_ instead of ED_*/
-static bool ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene,
- WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op)
-{
- bDeformGroup *dg_dst;
- Mesh *me_dst;
- DerivedMesh *dmesh_src;
- BVHTreeFromMesh tree_mesh_vertices_src, tree_mesh_faces_src = {NULL};
- MDeformVert **dv_array_src, **dv_array_dst, **dv_src, **dv_dst;
- MVert *mv_dst, *mv_src;
- MFace *mface_src, *mf;
- BVHTreeNearest nearest;
- MDeformWeight *dw_dst, *dw_src;
- int dv_tot_src, dv_tot_dst, i, v_index, index_dst, index_src, index_nearest, index_nearest_vertex;
- unsigned int f_index;
- float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4;
- const int use_vert_sel = vertex_group_use_vert_sel(ob_dst);
- bool is_dg_dst_new = false;
-
- /* Ensure vertex group on target.*/
- if ((dg_dst = defgroup_find_name(ob_dst, dg_src->name)) == NULL) {
- dg_dst = BKE_defgroup_new(ob_dst, dg_src->name);
- is_dg_dst_new = true;
- }
-
- /* Get meshes.*/
- dmesh_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MASK_MDEFORMVERT);
- me_dst = ob_dst->data;
-
- /* Get vertex group array from source mesh */
- if (!ed_vgroup_dm_parray_alloc(dmesh_src, &dv_array_src, &dv_tot_src)) {
- BKE_report(op->reports, RPT_ERROR, "Transfer failed (source mesh does not have any vertex groups)");
- return false;
- }
-
- /* Create data in memory when nothing there.*/
- if (!me_dst->dvert) ED_vgroup_data_create(&me_dst->id);
-
- /* Get vertex group for destination mesh */
- ED_vgroup_parray_alloc(&me_dst->id, &dv_array_dst, &dv_tot_dst, use_vert_sel);
-
- /* Get indexes of vertex groups.*/
- index_src = BLI_findindex(&ob_src->defbase, dg_src);
- index_dst = BLI_findindex(&ob_dst->defbase, dg_dst);
-
- /* Get vertices.*/
- mv_dst = me_dst->mvert;
- mv_src = dmesh_src->getVertArray(dmesh_src);
-
- /* Prepare transformation matrix.*/
- invert_m4_m4(ob_src->imat, ob_src->obmat);
- mul_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat);
-
- /* Clear weights.*/
- if (replace_mode == WT_REPLACE_ALL_WEIGHTS) {
- for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) {
-
- if (*dv_dst == NULL) continue;
-
- dw_dst = defvert_find_index(*dv_dst, index_dst);
- /* Remove vertex from group.*/
- if (dw_dst) defvert_remove_group(*dv_dst, dw_dst);
- }
- }
-
- switch (method) {
-
- case WT_BY_INDEX:
- /* Check if indices are matching, delete and return if not.*/
- if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src ||
- dv_array_src == NULL || dv_array_dst == NULL)
- {
- if (is_dg_dst_new) {
- ED_vgroup_delete(ob_dst, dg_dst);
- }
-
- if (dv_array_src) MEM_freeN(dv_array_src);
- if (dv_array_dst) MEM_freeN(dv_array_dst);
- dmesh_src->release(dmesh_src);
- BKE_report(op->reports, RPT_ERROR, "Transfer failed (indices are not matching)");
- return false;
- }
-
- /* Loop through the vertices.*/
- for (i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst;
- i < me_dst->totvert;
- i++, dv_dst++, dv_src++, mv_src++, mv_dst++)
- {
-
- if (*dv_dst == NULL) {
- continue;
- }
-
- /* Copy weight.*/
- dw_src = defvert_find_index(*dv_src, index_src);
- if (dw_src && dw_src->weight) {
- dw_dst = defvert_verify_index(*dv_dst, index_dst);
- vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode);
- }
- }
- break;
-
- case WT_BY_NEAREST_VERTEX:
- /* Make node tree.*/
- bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6);
-
- /* Loop trough vertices.*/
- for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
-
- if (*dv_dst == NULL) {
- continue;
- }
-
- /* Reset nearest.*/
- nearest.dist_sq = FLT_MAX;
- /* It is faster to start searching at the top of the tree instead of previous search result.*/
- nearest.index = -1;
-
- /* Transform into target space.*/
- mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
-
- /* Node tree accelerated search for closest vetex.*/
- BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co,
- &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src);
-
- /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are
- * overwritten prior to this. See the "Clear weights." step above.*/
- dw_src = defvert_find_index(dv_array_src[nearest.index], index_src);
- if (dw_src && dw_src->weight) {
- dw_dst = defvert_verify_index(*dv_dst, index_dst);
- vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode);
- }
- }
-
- /* Free memory.*/
- free_bvhtree_from_mesh(&tree_mesh_vertices_src);
- break;
-
- case WT_BY_NEAREST_FACE:
- /* Get faces.*/
- DM_ensure_tessface(dmesh_src);
- mface_src = dmesh_src->getTessFaceArray(dmesh_src);
-
- /* Make node tree.*/
- bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
-
- /* Loop through the vertices.*/
- for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
-
- if (*dv_dst == NULL) {
- continue;
- }
-
- /* Reset nearest.*/
- nearest.dist_sq = FLT_MAX;
- /* It is faster to start searching at the top of the tree instead of previous search result.*/
- nearest.index = -1;
-
- /* Transform into target space.*/
- mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
-
- /* Node tree accelerated search for closest face.*/
- BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co,
- &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src);
- index_nearest = nearest.index;
-
- /* Project onto face.*/
- mf = &mface_src[index_nearest];
- normal_tri_v3(normal, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co);
- project_v3_plane(tmp_co, normal, mv_src[mf->v1].co);
-
- /* Interpolate weights over face.*/
- interp_weights_face_v3(tmp_weight,
- mv_src[mf->v1].co,
- mv_src[mf->v2].co,
- mv_src[mf->v3].co,
- mf->v4 ? mv_src[mf->v4].co : NULL,
- tmp_co);
-
- /* Get weights from face.*/
- f_index = mf->v4 ? 3 : 2;
- weight = 0.0f;
- do {
- v_index = (&mf->v1)[f_index];
- weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src);
- } while (f_index--);
-
- /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are
- * overwritten prior to this. See the "Clear weights." step above.*/
- if (weight > 0.0f) {
- dw_dst = defvert_verify_index(*dv_dst, index_dst);
- vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode);
- }
- }
-
- /* Free memory.*/
- free_bvhtree_from_mesh(&tree_mesh_faces_src);
- break;
-
- case WT_BY_NEAREST_VERTEX_IN_FACE:
- /* Get faces.*/
- DM_ensure_tessface(dmesh_src);
- mface_src = dmesh_src->getTessFaceArray(dmesh_src);
-
- /* Make node tree.*/
- bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
-
- /* Loop through the vertices.*/
- for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
-
- if (*dv_dst == NULL) {
- continue;
- }
-
- /* Reset nearest.*/
- nearest.dist_sq = FLT_MAX;
- /* It is faster to start searching at the top of the tree instead of previous search result.*/
- nearest.index = -1;
-
- /* Transform into target space.*/
- mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
-
- /* Node tree accelerated search for closest face.*/
- BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co,
- &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src);
- index_nearest = nearest.index;
-
- /* Get distances.*/
- mf = &mface_src[index_nearest];
- dist_v1 = len_squared_v3v3(tmp_co, mv_src[mf->v1].co);
- dist_v2 = len_squared_v3v3(tmp_co, mv_src[mf->v2].co);
- dist_v3 = len_squared_v3v3(tmp_co, mv_src[mf->v3].co);
-
- /* Get closest vertex.*/
- f_index = mf->v4 ? 3 : 2;
- if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mf->v1;
- else if (dist_v2 < dist_v3) index_nearest_vertex = mf->v2;
- else index_nearest_vertex = mf->v3;
- if (f_index == 3) {
- dist_v4 = len_squared_v3v3(tmp_co, mv_src[mf->v4].co);
- if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) {
- index_nearest_vertex = mf->v4;
- }
- }
-
- /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are
- * overwritten prior to this. See the "Clear weights." step above.*/
- dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src);
- if (dw_src && dw_src->weight) {
- dw_dst = defvert_verify_index(*dv_dst, index_dst);
- vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode);
- }
- }
-
- /* Free memory.*/
- free_bvhtree_from_mesh(&tree_mesh_faces_src);
- break;
-
- default:
- BLI_assert(0);
- break;
- }
-
- /* Free memory.*/
- if (dv_array_src) MEM_freeN(dv_array_src);
- if (dv_array_dst) MEM_freeN(dv_array_dst);
- dmesh_src->release(dmesh_src);
-
- return true;
-}
/***********************End weight transfer (WT)***********************************/
@@ -1175,7 +701,7 @@ static void ED_vgroup_nr_vert_add(Object *ob,
int tot;
/* get the vert */
- ED_vgroup_array_get(ob->data, &dvert, &tot);
+ BKE_object_defgroup_array_get(ob->data, &dvert, &tot);
if (dvert == NULL)
return;
@@ -1208,7 +734,7 @@ static void ED_vgroup_nr_vert_add(Object *ob,
break;
case WEIGHT_SUBTRACT:
dw->weight -= weight;
- /* if the weight is zero or less then
+ /* if the weight is zero or less than
* remove the vert from the deform group
*/
if (dw->weight <= 0.0f) {
@@ -1261,8 +787,8 @@ void ED_vgroup_vert_add(Object *ob, bDeformGroup *dg, int vertnum, float weight,
/* if there's no deform verts then create some,
*/
- if (ED_vgroup_array_get(ob->data, &dv, &tot) && dv == NULL)
- ED_vgroup_data_create(ob->data);
+ if (BKE_object_defgroup_array_get(ob->data, &dv, &tot) && dv == NULL)
+ BKE_object_defgroup_data_create(ob->data);
/* call another function to do the work
*/
@@ -1287,7 +813,7 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum)
/* get the deform vertices corresponding to the
* vertnum
*/
- ED_vgroup_array_get(ob->data, &dvert, &tot);
+ BKE_object_defgroup_array_get(ob->data, &dvert, &tot);
if (dvert) {
MDeformVert *dv = &dvert[vertnum];
@@ -1476,7 +1002,7 @@ static void vgroup_duplicate(Object *ob)
BLI_addtail(&ob->defbase, cdg);
idg = (ob->actdef - 1);
- ob->actdef = BLI_countlist(&ob->defbase);
+ ob->actdef = BLI_listbase_count(&ob->defbase);
icdg = (ob->actdef - 1);
/* TODO, we might want to allow only copy selected verts here? - campbell */
@@ -1498,86 +1024,6 @@ static void vgroup_duplicate(Object *ob)
}
}
-/**
- * Return the subset type of the Vertex Group Selection
- */
-bool *ED_vgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, int *r_vgroup_tot, int *r_subset_count)
-{
- bool *vgroup_validmap = NULL;
- *r_vgroup_tot = BLI_countlist(&ob->defbase);
-
- switch (subset_type) {
- case WT_VGROUP_ACTIVE:
- {
- const int def_nr_active = ob->actdef - 1;
- vgroup_validmap = MEM_mallocN(*r_vgroup_tot * sizeof(*vgroup_validmap), __func__);
- memset(vgroup_validmap, false, *r_vgroup_tot * sizeof(*vgroup_validmap));
- if ((def_nr_active >= 0) && (def_nr_active < *r_vgroup_tot)) {
- *r_subset_count = 1;
- vgroup_validmap[def_nr_active] = true;
- }
- else {
- *r_subset_count = 0;
- }
- break;
- }
- case WT_VGROUP_BONE_SELECT:
- {
- vgroup_validmap = BKE_objdef_selected_get(ob, *r_vgroup_tot, r_subset_count);
- break;
- }
- case WT_VGROUP_BONE_DEFORM:
- {
- int i;
- vgroup_validmap = BKE_objdef_validmap_get(ob, *r_vgroup_tot);
- *r_subset_count = 0;
- for (i = 0; i < *r_vgroup_tot; i++) {
- if (vgroup_validmap[i] == true) {
- *r_subset_count += 1;
- }
- }
- break;
- }
- case WT_VGROUP_BONE_DEFORM_OFF:
- {
- int i;
- vgroup_validmap = BKE_objdef_validmap_get(ob, *r_vgroup_tot);
- *r_subset_count = 0;
- for (i = 0; i < *r_vgroup_tot; i++) {
- vgroup_validmap[i] = !vgroup_validmap[i];
- if (vgroup_validmap[i] == true) {
- *r_subset_count += 1;
- }
- }
- break;
- }
- case WT_VGROUP_ALL:
- default:
- {
- vgroup_validmap = MEM_mallocN(*r_vgroup_tot * sizeof(*vgroup_validmap), __func__);
- memset(vgroup_validmap, true, *r_vgroup_tot * sizeof(*vgroup_validmap));
- *r_subset_count = *r_vgroup_tot;
- break;
- }
- }
-
- return vgroup_validmap;
-}
-
-/**
- * store indices from the vgroup_validmap (faster lookups in some cases)
- */
-void ED_vgroup_subset_to_index_array(const bool *vgroup_validmap, const int vgroup_tot,
- int *r_vgroup_subset_map)
-{
- int i, j = 0;
- for (i = 0; i < vgroup_tot; i++) {
- if (vgroup_validmap[i]) {
- r_vgroup_subset_map[j++] = i;
- }
- }
-}
-
static void vgroup_normalize(Object *ob)
{
MDeformWeight *dw;
@@ -2051,8 +1497,8 @@ static void vgroup_normalize_all(Object *ob,
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
if (dvert_array) {
- const int defbase_tot = BLI_countlist(&ob->defbase);
- bool *lock_flags = BKE_objdef_lock_flags_get(ob, defbase_tot);
+ const int defbase_tot = BLI_listbase_count(&ob->defbase);
+ bool *lock_flags = BKE_object_defgroup_lock_flags_get(ob, defbase_tot);
if ((lock_active == true) &&
(lock_flags != NULL) &&
@@ -2200,12 +1646,12 @@ static void vgroup_blend_subset(Object *ob, const bool *vgroup_validmap, const i
BMesh *bm = em ? em->bm : NULL;
Mesh *me = em ? NULL : ob->data;
- MeshElemMap *emap ;
+ MeshElemMap *emap;
int *emap_mem;
BLI_SMALLSTACK_DECLARE(dv_stack, MDeformVert *);
- ED_vgroup_subset_to_index_array(vgroup_validmap, vgroup_tot, vgroup_subset_map);
+ BKE_object_defgroup_subset_to_index_array(vgroup_validmap, vgroup_tot, vgroup_subset_map);
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false);
memset(vgroup_subset_weights, 0, sizeof(*vgroup_subset_weights) * subset_count);
@@ -2725,298 +2171,13 @@ cleanup:
}
-static void vgroup_remap_update_users(Object *ob, int *map)
-{
- ExplodeModifierData *emd;
- ModifierData *md;
- ParticleSystem *psys;
- ClothModifierData *clmd;
- ClothSimSettings *clsim;
- int a;
-
- /* these cases don't use names to refer to vertex groups, so when
- * they get deleted the numbers get out of sync, this corrects that */
-
- if (ob->soft)
- ob->soft->vertgroup = map[ob->soft->vertgroup];
-
- for (md = ob->modifiers.first; md; md = md->next) {
- if (md->type == eModifierType_Explode) {
- emd = (ExplodeModifierData *)md;
- emd->vgroup = map[emd->vgroup];
- }
- else if (md->type == eModifierType_Cloth) {
- clmd = (ClothModifierData *)md;
- clsim = clmd->sim_parms;
-
- if (clsim) {
- clsim->vgroup_mass = map[clsim->vgroup_mass];
- clsim->vgroup_bend = map[clsim->vgroup_bend];
- clsim->vgroup_struct = map[clsim->vgroup_struct];
- }
- }
- }
-
- for (psys = ob->particlesystem.first; psys; psys = psys->next) {
- for (a = 0; a < PSYS_TOT_VG; a++)
- psys->vgroup[a] = map[psys->vgroup[a]];
- }
-}
-
-
-static void vgroup_delete_update_users(Object *ob, int id)
-{
- int i, defbase_tot = BLI_countlist(&ob->defbase) + 1;
- int *map = MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del");
-
- map[id] = map[0] = 0;
- for (i = 1; i < id; i++) map[i] = i;
- for (i = id + 1; i < defbase_tot; i++) map[i] = i - 1;
-
- vgroup_remap_update_users(ob, map);
- MEM_freeN(map);
-}
-
-
-static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg)
-{
- MDeformVert *dvert_array = NULL;
- int dvert_tot = 0;
- const int def_nr = BLI_findindex(&ob->defbase, dg);
-
- BLI_assert(def_nr != -1);
-
- ED_vgroup_array_get(ob->data, &dvert_array, &dvert_tot);
-
- if (dvert_array) {
- int i, j;
- MDeformVert *dv;
- for (i = 0, dv = dvert_array; i < dvert_tot; i++, dv++) {
- MDeformWeight *dw;
-
- dw = defvert_find_index(dv, def_nr);
- defvert_remove_group(dv, dw); /* dw can be NULL */
-
- /* inline, make into a function if anything else needs to do this */
- for (j = 0; j < dv->totweight; j++) {
- if (dv->dw[j].def_nr > def_nr) {
- dv->dw[j].def_nr--;
- }
- }
- /* done */
- }
- }
-
- vgroup_delete_update_users(ob, def_nr + 1);
-
- /* Remove the group */
- BLI_freelinkN(&ob->defbase, dg);
-
- /* Update the active deform index if necessary */
- if (ob->actdef > def_nr)
- ob->actdef--;
- if (ob->actdef < 1 && ob->defbase.first)
- ob->actdef = 1;
-
- /* remove all dverts */
- if (BLI_listbase_is_empty(&ob->defbase)) {
- if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
- CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
- me->dvert = NULL;
- }
- else if (ob->type == OB_LATTICE) {
- Lattice *lt = ob->data;
- if (lt->dvert) {
- MEM_freeN(lt->dvert);
- lt->dvert = NULL;
- }
- }
- }
-}
-
-/* only in editmode */
-/* removes from active defgroup, if allverts==0 only selected vertices */
-static bool vgroup_active_remove_verts(Object *ob, const bool allverts, bDeformGroup *dg)
-{
- MDeformVert *dv;
- const int def_nr = BLI_findindex(&ob->defbase, dg);
- bool changed = false;
-
- if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
-
- if (me->edit_btmesh) {
- BMEditMesh *em = me->edit_btmesh;
- const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
-
- if (cd_dvert_offset != -1) {
- BMVert *eve;
- BMIter iter;
-
- BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
- dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
-
- if (dv && dv->dw && (allverts || BM_elem_flag_test(eve, BM_ELEM_SELECT))) {
- MDeformWeight *dw = defvert_find_index(dv, def_nr);
- defvert_remove_group(dv, dw); /* dw can be NULL */
- changed = true;
- }
- }
- }
- }
- else {
- if (me->dvert) {
- MVert *mv;
- int i;
-
- mv = me->mvert;
- dv = me->dvert;
-
- for (i = 0; i < me->totvert; i++, mv++, dv++) {
- if (mv->flag & SELECT) {
- if (dv->dw && (allverts || (mv->flag & SELECT))) {
- MDeformWeight *dw = defvert_find_index(dv, def_nr);
- defvert_remove_group(dv, dw); /* dw can be NULL */
- changed = true;
- }
- }
- }
- }
- }
- }
- else if (ob->type == OB_LATTICE) {
- Lattice *lt = vgroup_edit_lattice(ob);
-
- if (lt->dvert) {
- BPoint *bp;
- int i, tot = lt->pntsu * lt->pntsv * lt->pntsw;
-
- for (i = 0, bp = lt->def; i < tot; i++, bp++) {
- if (allverts || (bp->f1 & SELECT)) {
- MDeformWeight *dw;
-
- dv = &lt->dvert[i];
-
- dw = defvert_find_index(dv, def_nr);
- defvert_remove_group(dv, dw); /* dw can be NULL */
- changed = true;
- }
- }
- }
- }
-
- return changed;
-}
-
-static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *dg)
-{
- int i;
- const int dg_index = BLI_findindex(&ob->defbase, dg);
-
- BLI_assert(dg_index != -1);
-
- /* Make sure that no verts are using this group */
- if (vgroup_active_remove_verts(ob, true, dg) == false) {
- /* do nothing */
- }
- /* Make sure that any verts with higher indices are adjusted accordingly */
- else if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_btmesh;
- const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
-
- BMIter iter;
- BMVert *eve;
- MDeformVert *dvert;
-
- BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
- dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
-
- if (dvert)
- for (i = 0; i < dvert->totweight; i++)
- if (dvert->dw[i].def_nr > dg_index)
- dvert->dw[i].def_nr--;
- }
- }
- else if (ob->type == OB_LATTICE) {
- Lattice *lt = vgroup_edit_lattice(ob);
- BPoint *bp;
- MDeformVert *dvert = lt->dvert;
- int a, tot;
-
- if (dvert) {
- tot = lt->pntsu * lt->pntsv * lt->pntsw;
- for (a = 0, bp = lt->def; a < tot; a++, bp++, dvert++) {
- for (i = 0; i < dvert->totweight; i++) {
- if (dvert->dw[i].def_nr > dg_index)
- dvert->dw[i].def_nr--;
- }
- }
- }
- }
-
- vgroup_delete_update_users(ob, dg_index + 1);
-
- /* Remove the group */
- BLI_freelinkN(&ob->defbase, dg);
-
- /* Update the active deform index if necessary */
- if (ob->actdef > dg_index)
- ob->actdef--;
- if (ob->actdef < 1 && ob->defbase.first)
- ob->actdef = 1;
-
- /* remove all dverts */
- if (BLI_listbase_is_empty(&ob->defbase)) {
- if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
- CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
- me->dvert = NULL;
- }
- else if (ob->type == OB_LATTICE) {
- Lattice *lt = vgroup_edit_lattice(ob);
- if (lt->dvert) {
- MEM_freeN(lt->dvert);
- lt->dvert = NULL;
- }
- }
- }
-}
-
-static void vgroup_delete(Object *ob)
+static void vgroup_delete_active(Object *ob)
{
bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
if (!dg)
return;
- if (BKE_object_is_in_editmode_vgroup(ob))
- vgroup_delete_edit_mode(ob, dg);
- else
- vgroup_delete_object_mode(ob, dg);
-}
-
-static void vgroup_delete_all(Object *ob)
-{
- /* Remove all DVerts */
- if (ob->type == OB_MESH) {
- Mesh *me = ob->data;
- CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
- me->dvert = NULL;
- }
- else if (ob->type == OB_LATTICE) {
- Lattice *lt = vgroup_edit_lattice(ob);
- if (lt->dvert) {
- MEM_freeN(lt->dvert);
- lt->dvert = NULL;
- }
- }
-
- /* Remove all DefGroups */
- BLI_freelistN(&ob->defbase);
-
- /* Fix counters/indices */
- ob->actdef = 0;
+ BKE_object_defgroup_remove(ob, dg);
}
/* only in editmode */
@@ -3061,7 +2222,7 @@ static void vgroup_assign_verts(Object *ob, const float weight)
int i;
if (!me->dvert) {
- ED_vgroup_data_create(&me->id);
+ BKE_object_defgroup_data_create(&me->id);
}
mv = me->mvert;
@@ -3085,7 +2246,7 @@ static void vgroup_assign_verts(Object *ob, const float weight)
int a, tot;
if (lt->dvert == NULL)
- ED_vgroup_data_create(&lt->id);
+ BKE_object_defgroup_data_create(&lt->id);
dv = lt->dvert;
@@ -3103,22 +2264,6 @@ static void vgroup_assign_verts(Object *ob, const float weight)
}
}
-/* only in editmode */
-/* removes from all defgroup, if allverts==0 only selected vertices */
-static bool vgroup_remove_verts(Object *ob, int allverts)
-{
- bool changed = false;
- /* To prevent code redundancy, we just use vgroup_active_remove_verts, but that
- * only operates on the active vgroup. So we iterate through all groups, by changing
- * active group index
- */
- bDeformGroup *dg;
- for (dg = ob->defbase.first; dg; dg = dg->next) {
- changed |= vgroup_active_remove_verts(ob, allverts, dg);
- }
- return changed;
-}
-
/********************** vertex group operators *********************/
static int vertex_group_poll(bContext *C)
@@ -3150,7 +2295,7 @@ static int vertex_group_mesh_poll(bContext *C)
ob->defbase.first);
}
-static int vertex_group_mesh_supported_poll(bContext *C)
+static int UNUSED_FUNCTION(vertex_group_mesh_supported_poll)(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
@@ -3226,7 +2371,7 @@ static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
- ED_vgroup_add(ob);
+ BKE_object_defgroup_add(ob);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@@ -3254,9 +2399,9 @@ static int vertex_group_remove_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_context(C);
if (RNA_boolean_get(op->ptr, "all"))
- vgroup_delete_all(ob);
+ BKE_object_defgroup_remove_all(ob);
else
- vgroup_delete(ob);
+ vgroup_delete_active(ob);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data);
@@ -3321,7 +2466,7 @@ static int vertex_group_assign_new_exec(bContext *C, wmOperator *op)
{
/* create new group... */
Object *ob = ED_object_context(C);
- ED_vgroup_add(ob);
+ BKE_object_defgroup_add(ob);
/* assign selection to new group */
return vertex_group_assign_exec(C, op);
@@ -3353,14 +2498,14 @@ static int vertex_group_remove_from_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_context(C);
if (use_all_groups) {
- if (vgroup_remove_verts(ob, 0) == false) {
+ if (BKE_object_defgroup_clear_all(ob, true) == false) {
return OPERATOR_CANCELLED;
}
}
else {
bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
- if ((dg == NULL) || (vgroup_active_remove_verts(ob, use_all_verts, dg) == false)) {
+ if ((dg == NULL) || (BKE_object_defgroup_clear(ob, dg, !use_all_verts) == false)) {
return OPERATOR_CANCELLED;
}
}
@@ -3486,7 +2631,7 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_levels_subset(ob, vgroup_validmap, vgroup_tot, subset_count, offset, gain);
MEM_freeN((void *)vgroup_validmap);
@@ -3552,7 +2697,7 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_normalize_all(ob, vgroup_validmap, vgroup_tot, subset_count, lock_active);
MEM_freeN((void *)vgroup_validmap);
@@ -3674,7 +2819,7 @@ static int vertex_group_invert_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_invert_subset(ob, vgroup_validmap, vgroup_tot, subset_count, auto_assign, auto_remove);
MEM_freeN((void *)vgroup_validmap);
@@ -3715,7 +2860,7 @@ static int vertex_group_blend_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_blend_subset(ob, vgroup_validmap, vgroup_tot, subset_count, fac);
MEM_freeN((void *)vgroup_validmap);
@@ -3791,7 +2936,7 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single);
MEM_freeN((void *)vgroup_validmap);
@@ -3832,7 +2977,7 @@ static int vertex_group_quantize_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
vgroup_quantize_subset(ob, vgroup_validmap, vgroup_tot, subset_count, steps);
MEM_freeN((void *)vgroup_validmap);
@@ -3870,7 +3015,7 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op)
int subset_count, vgroup_tot;
- const bool *vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
int remove_tot = vgroup_limit_total_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit);
MEM_freeN((void *)vgroup_validmap);
@@ -3934,7 +3079,7 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
/* identifiers */
ot->name = "Mirror Vertex Group";
ot->idname = "OBJECT_OT_vertex_group_mirror";
- ot->description = "Mirror all vertex groups, flip weights and/or names, editing only selected vertices, "
+ ot->description = "Mirror vertex group, flip weights and/or names, editing only selected vertices, "
"flipping when both sides are selected otherwise copy from unselected";
/* api callbacks */
@@ -3983,7 +3128,7 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot)
/* identifiers */
ot->name = "Copy Vertex Groups to Linked";
ot->idname = "OBJECT_OT_vertex_group_copy_to_linked";
- ot->description = "Copy vertex groups to all users of the same geometry data";
+ ot->description = "Replace vertex groups of all users of the same geometry data by vertex groups of active object";
/* api callbacks */
ot->poll = vertex_group_poll;
@@ -4022,7 +3167,7 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot)
/* identifiers */
ot->name = "Copy Vertex Group to Selected";
ot->idname = "OBJECT_OT_vertex_group_copy_to_selected";
- ot->description = "Copy vertex groups to other selected objects with matching indices";
+ ot->description = "Replace vertex groups of selected objects by vertex groups of active object";
/* api callbacks */
ot->poll = vertex_group_poll;
@@ -4032,143 +3177,6 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
-{
- Scene *scene = CTX_data_scene(C);
- Object *ob_act = CTX_data_active_object(C);
-
- bDeformGroup *dg_act = BLI_findlink(&ob_act->defbase, (ob_act->actdef - 1));
- char dg_act_name[MAX_VGROUP_NAME]; /* may be freed so copy */
-
- int fail = 0;
- bool changed = false;
-
- WT_VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "group_select_mode");
- WT_Method method = RNA_enum_get(op->ptr, "method");
- WT_ReplaceMode replace_mode = RNA_enum_get(op->ptr, "replace_mode");
-
- if (vertex_group_mode == WT_REPLACE_ACTIVE_VERTEX_GROUP) {
- if (!dg_act) {
- BKE_report(op->reports, RPT_WARNING, "Failed, active object has no active groups");
- return OPERATOR_FINISHED; /* to get the chance to make changes in the redo panel*/
- }
- }
-
- if (dg_act) {
- BLI_strncpy(dg_act_name, dg_act->name, sizeof(dg_act_name));
- }
-
- /* Macro to loop through selected objects and perform operation depending on function, option and method.*/
- CTX_DATA_BEGIN (C, Object *, ob_src, selected_editable_objects)
- {
- if (ob_act != ob_src) {
-
- if (BLI_listbase_is_empty(&ob_src->defbase)) {
- BKE_reportf(op->reports, RPT_WARNING,
- "Skipping object '%s' it has no vertex groups", ob_src->id.name + 2);
- continue;
- }
- else if (ob_src->type != OB_MESH) {
- /* armatures can be in pose mode so ignore them */
- if (ob_src->type != OB_ARMATURE) {
- BKE_reportf(op->reports, RPT_WARNING,
- "Skipping object '%s' only copying from meshes is supported", ob_src->id.name + 2);
- }
- continue;
- }
-
- switch (vertex_group_mode) {
-
- case WT_REPLACE_ACTIVE_VERTEX_GROUP:
- {
- bDeformGroup *dg_src;
- dg_src = defgroup_find_name(ob_src, dg_act_name);
-
- if (dg_src == NULL) {
- BKE_reportf(op->reports, RPT_WARNING,
- "Skipping object '%s' no group '%s' found", ob_src->id.name + 2, dg_act_name);
- continue;
- }
-
- if (ed_vgroup_transfer_weight(ob_act, ob_src, dg_src, scene, method, replace_mode, op)) {
- changed = true;
- }
- else {
- fail++;
- }
- break;
- }
- case WT_REPLACE_ALL_VERTEX_GROUPS:
- {
- bDeformGroup *dg_src;
- for (dg_src = ob_src->defbase.first; dg_src; dg_src = dg_src->next) {
- if (ed_vgroup_transfer_weight(ob_act, ob_src, dg_src, scene, method, replace_mode, op)) {
- changed = true;
- }
- else {
- fail++;
- }
- }
- break;
- }
- default:
- BLI_assert(0);
- break;
- }
- }
- }
- CTX_DATA_END;
-
- if (changed) {
-
- /* possible the active vertex group changed because of adding/removing */
- /* note!, dg_act may be realloc'd, only check its not NULL */
- if (dg_act) {
- ED_vgroup_select_by_name(ob_act, dg_act_name);
- }
- else {
- ED_vgroup_sync_from_pose(ob_act);
- }
-
- /* Event notifiers for correct display of data.*/
-
-
- DAG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_act); /* for buttons */
- WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob_act);
- return OPERATOR_FINISHED;
- }
- else {
- if (BLI_listbase_is_empty(&op->reports->list)) {
- BKE_report(op->reports, RPT_WARNING, "Failed, no other selected objects with vertex groups found");
- }
-
- return OPERATOR_FINISHED; /* to get the chance to make changes in the redo panel */
- }
-}
-
-/* transfers weight from active to selected */
-void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot)
-{
- /* Identifiers.*/
- ot->name = "Transfer Weights";
- ot->idname = "OBJECT_OT_vertex_group_transfer_weight";
- ot->description = "Transfer weight paint to active from selected mesh";
-
- /* API callbacks.*/
- ot->poll = vertex_group_mesh_supported_poll;
- ot->exec = vertex_group_transfer_weight_exec;
-
- /* Flags.*/
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* Properties.*/
- /* TODO, use vgroup_operator_subset_select_props for group_select_mode */
- ot->prop = RNA_def_enum(ot->srna, "group_select_mode", WT_vertex_group_mode_item, WT_REPLACE_ALL_VERTEX_GROUPS, "Group", "");
- ot->prop = RNA_def_enum(ot->srna, "method", WT_method_item, WT_BY_NEAREST_FACE, "Method", "");
- ot->prop = RNA_def_enum(ot->srna, "replace_mode", WT_replace_mode_item, WT_REPLACE_ALL_WEIGHTS, "Replace", "");
-}
-
static int set_active_group_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
@@ -4237,7 +3245,7 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
static char *vgroup_init_remap(Object *ob)
{
bDeformGroup *def;
- int defbase_tot = BLI_countlist(&ob->defbase);
+ int defbase_tot = BLI_listbase_count(&ob->defbase);
char *name_array = MEM_mallocN(MAX_VGROUP_NAME * sizeof(char) * defbase_tot, "sort vgroups");
char *name;
@@ -4254,7 +3262,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
{
MDeformVert *dvert = NULL;
bDeformGroup *def;
- int defbase_tot = BLI_countlist(&ob->defbase);
+ int defbase_tot = BLI_listbase_count(&ob->defbase);
/* needs a dummy index at the start*/
int *sort_map_update = MEM_mallocN(sizeof(int) * (defbase_tot + 1), "sort vgroups");
@@ -4297,7 +3305,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
else {
int dvert_tot = 0;
- ED_vgroup_array_get(ob->data, &dvert, &dvert_tot);
+ BKE_object_defgroup_array_get(ob->data, &dvert, &dvert_tot);
/*create as necessary*/
if (dvert) {
@@ -4314,7 +3322,7 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
sort_map[i]++;
sort_map_update[0] = 0;
- vgroup_remap_update_users(ob, sort_map_update);
+ BKE_object_defgroup_remap_update_users(ob, sort_map_update);
BLI_assert(sort_map_update[ob->actdef] >= 0);
ob->actdef = sort_map_update[ob->actdef];
@@ -4378,7 +3386,7 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op)
/*sort vgroup names*/
switch (sort_type) {
case SORT_TYPE_NAME:
- BLI_sortlist(&ob->defbase, vgroup_sort_name);
+ BLI_listbase_sort(&ob->defbase, vgroup_sort_name);
break;
case SORT_TYPE_BONEHIERARCHY:
vgroup_sort_bone_hierarchy(ob, NULL);
diff --git a/source/blender/editors/object/object_warp.c b/source/blender/editors/object/object_warp.c
index 8016dabf3a3..7413bb07c4c 100644
--- a/source/blender/editors/object/object_warp.c
+++ b/source/blender/editors/object/object_warp.c
@@ -31,7 +31,6 @@
#include "BLI_math.h"
-#include "BKE_utildefines.h"
#include "BKE_context.h"
#include "RNA_access.h"
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 637af5d6536..d864934171b 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -40,6 +40,7 @@
#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_deform.h"
+#include "BKE_object_deform.h"
#include "BKE_depsgraph.h"
#include "BKE_dynamicpaint.h"
#include "BKE_global.h"
@@ -235,11 +236,11 @@ static int output_toggle_exec(bContext *C, wmOperator *op)
/* Vertex Weight Layer */
else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
if (!exists) {
- ED_vgroup_add_name(ob, name);
+ BKE_object_defgroup_add_name(ob, name);
}
else {
bDeformGroup *defgroup = defgroup_find_name(ob, name);
- if (defgroup) ED_vgroup_delete(ob, defgroup);
+ if (defgroup) BKE_object_defgroup_remove(ob, defgroup);
}
}
}
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 9a3433b0ccf..6c90e319bc6 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -61,7 +61,7 @@
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_report.h"
-
+#include "BKE_bvhutils.h"
#include "BKE_pointcache.h"
#include "BIF_gl.h"
@@ -83,9 +83,11 @@
#include "physics_intern.h"
-static void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys);
-static void PTCacheUndo_clear(PTCacheEdit *edit);
-static void recalc_emitter_field(Object *ob, ParticleSystem *psys);
+void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys);
+void PTCacheUndo_clear(PTCacheEdit *edit);
+void recalc_lengths(PTCacheEdit *edit);
+void recalc_emitter_field(Object *ob, ParticleSystem *psys);
+void update_world_cos(Object *ob, PTCacheEdit *edit);
#define KEY_K PTCacheEditKey *key; int k
#define POINT_P PTCacheEditPoint *point; int p
@@ -355,6 +357,7 @@ typedef struct PEData {
Object *ob;
DerivedMesh *dm;
PTCacheEdit *edit;
+ BVHTreeFromMesh shape_bvh;
const int *mval;
rcti *rect;
@@ -411,6 +414,25 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
}
}
+static void PE_create_shape_tree(PEData *data, Object *shapeob)
+{
+ DerivedMesh *dm = shapeob->derivedFinal;
+
+ memset(&data->shape_bvh, 0, sizeof(data->shape_bvh));
+
+ if (!dm) {
+ return;
+ }
+
+ DM_ensure_tessface(dm);
+ bvhtree_from_mesh_faces(&data->shape_bvh, dm, 0.0f, 4, 8);
+}
+
+static void PE_free_shape_tree(PEData *data)
+{
+ free_bvhtree_from_mesh(&data->shape_bvh);
+}
+
/*************************** selection utilities *******************************/
static bool key_test_depth(PEData *data, const float co[3], const int screen_co[2])
@@ -1055,7 +1077,7 @@ static void pe_iterate_lengths(Scene *scene, PTCacheEdit *edit)
}
}
/* set current distances to be kept between neighbouting keys */
-static void recalc_lengths(PTCacheEdit *edit)
+void recalc_lengths(PTCacheEdit *edit)
{
POINT_P; KEY_K;
@@ -1071,7 +1093,7 @@ static void recalc_lengths(PTCacheEdit *edit)
}
/* calculate a tree for finding nearest emitter's vertice */
-static void recalc_emitter_field(Object *ob, ParticleSystem *psys)
+void recalc_emitter_field(Object *ob, ParticleSystem *psys)
{
DerivedMesh *dm=psys_get_modifier(ob, psys)->dm;
PTCacheEdit *edit= psys->edit;
@@ -1159,7 +1181,7 @@ static void PE_update_selection(Scene *scene, Object *ob, int useflag)
point->flag &= ~PEP_EDIT_RECALC;
}
-static void update_world_cos(Object *ob, PTCacheEdit *edit)
+void update_world_cos(Object *ob, PTCacheEdit *edit)
{
ParticleSystem *psys = edit->psys;
ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
@@ -3229,7 +3251,7 @@ static void brush_puff(PEData *data, int point_index)
static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[4][4]), float UNUSED(imat[4][4]), int point_index, int key_index, PTCacheEditKey *UNUSED(key))
{
- /* roots have full weight allways */
+ /* roots have full weight always */
if (key_index) {
PTCacheEdit *edit = data->edit;
ParticleSystem *psys = edit->psys;
@@ -4032,6 +4054,180 @@ void PARTICLE_OT_brush_edit(wmOperatorType *ot)
RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
}
+/*********************** cut shape ***************************/
+
+static int shape_cut_poll(bContext *C)
+{
+ if (PE_hair_poll(C)) {
+ Scene *scene= CTX_data_scene(C);
+ ParticleEditSettings *pset= PE_settings(scene);
+
+ if (pset->shape_object)
+ return true;
+ }
+
+ return false;
+}
+
+typedef struct PointInsideBVH {
+ BVHTreeFromMesh bvhdata;
+ int num_hits;
+} PointInsideBVH;
+
+static void point_inside_bvh_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+{
+ PointInsideBVH *data = userdata;
+
+ data->bvhdata.raycast_callback(&data->bvhdata, index, ray, hit);
+
+ if (hit->index != -1)
+ ++data->num_hits;
+}
+
+/* true if the point is inside the shape mesh */
+static bool shape_cut_test_point(PEData *data, ParticleCacheKey *key)
+{
+ BVHTreeFromMesh *shape_bvh = &data->shape_bvh;
+ const float dir[3] = {1.0f, 0.0f, 0.0f};
+ PointInsideBVH userdata;
+
+ userdata.bvhdata = data->shape_bvh;
+ userdata.num_hits = 0;
+
+ BLI_bvhtree_ray_cast_all(shape_bvh->tree, key->co, dir, 0.0f, point_inside_bvh_cb, &userdata);
+
+ /* for any point inside a watertight mesh the number of hits is uneven */
+ return (userdata.num_hits % 2) == 1;
+}
+
+static void shape_cut(PEData *data, int pa_index)
+{
+ PTCacheEdit *edit = data->edit;
+ Object *ob = data->ob;
+ ParticleEditSettings *pset = PE_settings(data->scene);
+ ParticleCacheKey *key;
+
+ bool cut;
+ float cut_time = 1.0;
+ int k, totkeys = 1 << pset->draw_step;
+
+ /* don't cut hidden */
+ if (edit->points[pa_index].flag & PEP_HIDE)
+ return;
+
+ cut = false;
+
+ /* check if root is inside the cut shape */
+ key = edit->pathcache[pa_index];
+ if (!shape_cut_test_point(data, key)) {
+ cut_time = -1.0f;
+ cut = true;
+ }
+ else {
+ for (k = 0; k < totkeys; k++, key++) {
+ BVHTreeRayHit hit;
+ float dir[3];
+ float len;
+
+ sub_v3_v3v3(dir, (key+1)->co, key->co);
+ len = normalize_v3(dir);
+
+ memset(&hit, 0, sizeof(hit));
+ hit.index = -1;
+ hit.dist = len;
+ BLI_bvhtree_ray_cast(data->shape_bvh.tree, key->co, dir, 0.0f, &hit, data->shape_bvh.raycast_callback, &data->shape_bvh);
+ if (hit.index >= 0) {
+ if (hit.dist < len) {
+ cut_time = (hit.dist / len + (float)k) / (float)totkeys;
+ cut = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (cut) {
+ if (cut_time < 0.0f) {
+ edit->points[pa_index].flag |= PEP_TAG;
+ }
+ else {
+ rekey_particle_to_time(data->scene, ob, pa_index, cut_time);
+ edit->points[pa_index].flag |= PEP_EDIT_RECALC;
+ }
+ }
+}
+
+static int shape_cut_exec(bContext *C, wmOperator *UNUSED(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);
+ Object *shapeob = pset->shape_object;
+ int selected = count_selected_keys(scene, edit);
+ int lock_root = pset->flag & PE_LOCK_FIRST;
+
+ if (!PE_start_edit(edit))
+ return OPERATOR_CANCELLED;
+
+ /* disable locking temporatily for disconnected hair */
+ if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR)
+ pset->flag &= ~PE_LOCK_FIRST;
+
+ if (edit->psys && edit->pathcache) {
+ PEData data;
+ int removed;
+
+ PE_set_data(C, &data);
+ PE_create_shape_tree(&data, shapeob);
+
+ if (selected)
+ foreach_selected_point(&data, shape_cut);
+ else
+ foreach_point(&data, shape_cut);
+
+ removed = remove_tagged_particles(ob, edit->psys, pe_x_mirror(ob));
+ recalc_lengths(edit);
+
+ if (removed) {
+ update_world_cos(ob, edit);
+ psys_free_path_cache(NULL, edit);
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ }
+ else
+ PE_update_object(scene, ob, 1);
+
+ if (edit->psys) {
+ WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
+ }
+ else {
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+ }
+
+ PE_free_shape_tree(&data);
+ }
+
+ pset->flag |= lock_root;
+
+ return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_shape_cut(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Shape Cut";
+ ot->idname = "PARTICLE_OT_shape_cut";
+ ot->description = "Cut hair to conform to the set shape object";
+
+ /* api callbacks */
+ ot->exec = shape_cut_exec;
+ ot->poll = shape_cut_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
/*********************** undo ***************************/
static void free_PTCacheUndo(PTCacheUndo *undo)
@@ -4259,7 +4455,7 @@ int PE_undo_valid(Scene *scene)
return 0;
}
-static void PTCacheUndo_clear(PTCacheEdit *edit)
+void PTCacheUndo_clear(PTCacheEdit *edit)
{
PTCacheUndo *undo;
@@ -4360,7 +4556,7 @@ int PE_minmax(Scene *scene, float min[3], float max[3])
/************************ particle edit toggle operator ************************/
/* initialize needed data for bake edit */
-static void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys)
+void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys)
{
PTCacheEdit *edit;
ParticleSystemModifierData *psmd = (psys) ? psys_get_modifier(ob, psys) : NULL;
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 5a61f77e5a8..dba6d6f5085 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -40,18 +40,21 @@
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
+#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
+#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_report.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
@@ -62,8 +65,37 @@
#include "ED_screen.h"
#include "ED_object.h"
+#include "UI_resources.h"
+
#include "physics_intern.h"
+extern void PE_create_particle_edit(Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys);
+extern void PTCacheUndo_clear(PTCacheEdit *edit);
+extern void recalc_lengths(PTCacheEdit *edit);
+extern void recalc_emitter_field(Object *ob, ParticleSystem *psys);
+extern void update_world_cos(Object *ob, PTCacheEdit *edit);
+
+#define KEY_K PTCacheEditKey *key; int k
+#define POINT_P PTCacheEditPoint *point; int p
+#define LOOP_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++)
+#if 0
+#define LOOP_VISIBLE_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (!(point->flag & PEP_HIDE))
+#define LOOP_SELECTED_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (point_is_selected(point))
+#define LOOP_UNSELECTED_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (!point_is_selected(point))
+#define LOOP_EDITED_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (point->flag & PEP_EDIT_RECALC)
+#define LOOP_TAGGED_POINTS for (p=0, point=edit->points; p<edit->totpoint; p++, point++) if (point->flag & PEP_TAG)
+#endif
+#define LOOP_KEYS for (k=0, key=point->keys; k<point->totkey; k++, key++)
+#if 0
+#define LOOP_VISIBLE_KEYS for (k=0, key=point->keys; k<point->totkey; k++, key++) if (!(key->flag & PEK_HIDE))
+#define LOOP_SELECTED_KEYS for (k=0, key=point->keys; k<point->totkey; k++, key++) if ((key->flag & PEK_SELECT) && !(key->flag & PEK_HIDE))
+#define LOOP_TAGGED_KEYS for (k=0, key=point->keys; k<point->totkey; k++, key++) if (key->flag & PEK_TAG)
+
+#define KEY_WCO (key->flag & PEK_USE_WCO ? key->world_co : key->co)
+#endif
+
+static float I[4][4] = {{1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 1.0f}};
+
/********************** particle system slot operators *********************/
static int particle_system_add_exec(bContext *C, wmOperator *UNUSED(op))
@@ -623,38 +655,50 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh");
}
-static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
+/* from/to_world_space : whether from/to particles are in world or hair space
+ * from/to_mat : additional transform for from/to particles (e.g. for using object space copying)
+ */
+static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
+ Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit,
+ float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global)
{
- ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
- ParticleData *pa;
- PTCacheEdit *edit;
- PTCacheEditPoint *point;
- PTCacheEditKey *ekey = NULL;
- HairKey *key;
+ ParticleSystemModifierData *target_psmd = psys_get_modifier(target_ob, target_psys);
+ ParticleData *pa, *tpa;
+ PTCacheEditPoint *edit_point;
+ PTCacheEditKey *ekey;
BVHTreeFromMesh bvhtree= {NULL};
- BVHTreeNearest nearest;
MFace *mface = NULL, *mf;
MEdge *medge = NULL, *me;
MVert *mvert;
- DerivedMesh *dm = NULL;
+ DerivedMesh *dm, *target_dm;
int numverts;
int i, k;
- float hairmat[4][4], imat[4][4];
- float v[4][3], vec[3];
+ float from_ob_imat[4][4], to_ob_imat[4][4];
+ float from_imat[4][4], to_imat[4][4];
- if (!psys || !psys->part || psys->part->type != PART_HAIR || !psmd->dm)
+ if (!target_psmd->dm)
+ return false;
+ if (!psys->part || psys->part->type != PART_HAIR)
return false;
+ if (!target_psys->part || target_psys->part->type != PART_HAIR)
+ return false;
+
+ edit_point = target_edit ? target_edit->points : NULL;
- edit= psys->edit;
- point= edit ? edit->points : NULL;
+ invert_m4_m4(from_ob_imat, ob->obmat);
+ invert_m4_m4(to_ob_imat, target_ob->obmat);
+ invert_m4_m4(from_imat, from_mat);
+ invert_m4_m4(to_imat, to_mat);
- if (psmd->dm->deformedOnly) {
- /* we don't want to mess up psmd->dm when converting to global coordinates below */
- dm = psmd->dm;
+ if (target_psmd->dm->deformedOnly) {
+ /* we don't want to mess up target_psmd->dm when converting to global coordinates below */
+ dm = target_psmd->dm;
}
else {
- dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+ /* warning: this rebuilds target_psmd->dm! */
+ dm = mesh_get_derived_deform(scene, target_ob, CD_MASK_BAREMESH);
}
+ target_dm = target_psmd->dm;
/* don't modify the original vertices */
dm = CDDM_copy(dm);
@@ -662,12 +706,11 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
DM_ensure_tessface(dm);
numverts = dm->getNumVerts(dm);
-
mvert = dm->getVertArray(dm);
/* convert to global coordinates */
for (i=0; i<numverts; i++)
- mul_m4_v3(ob->obmat, mvert[i].co);
+ mul_m4_v3(to_mat, mvert[i].co);
if (dm->getNumTessFaces(dm) != 0) {
mface = dm->getTessFaceArray(dm);
@@ -682,13 +725,23 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
return false;
}
- for (i=0, pa= psys->particles; i<psys->totpart; i++, pa++) {
- key = pa->hair;
+ for (i = 0, tpa = target_psys->particles, pa = psys->particles;
+ i < target_psys->totpart;
+ i++, tpa++, pa++) {
+
+ float from_co[3];
+ BVHTreeNearest nearest;
+
+ if (from_global)
+ mul_v3_m4v3(from_co, from_ob_imat, pa->hair[0].co);
+ else
+ mul_v3_m4v3(from_co, from_ob_imat, pa->hair[0].world_co);
+ mul_m4_v3(from_mat, from_co);
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
- BLI_bvhtree_find_nearest(bvhtree.tree, key->co, &nearest, bvhtree.nearest_callback, &bvhtree);
+ BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index == -1) {
if (G.debug & G_DEBUG)
@@ -697,6 +750,8 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
}
if (mface) {
+ float v[4][3];
+
mf = &mface[nearest.index];
copy_v3_v3(v[0], mvert[mf->v1].co);
@@ -704,44 +759,80 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
copy_v3_v3(v[2], mvert[mf->v3].co);
if (mf->v4) {
copy_v3_v3(v[3], mvert[mf->v4].co);
- interp_weights_poly_v3(pa->fuv, v, 4, nearest.co);
+ interp_weights_poly_v3(tpa->fuv, v, 4, nearest.co);
}
else
- interp_weights_poly_v3(pa->fuv, v, 3, nearest.co);
+ interp_weights_poly_v3(tpa->fuv, v, 3, nearest.co);
+ tpa->foffset = 0.0f;
- pa->num = nearest.index;
- pa->num_dmcache = psys_particle_dm_face_lookup(ob, psmd->dm, pa->num, pa->fuv, NULL);
+ tpa->num = nearest.index;
+ tpa->num_dmcache = psys_particle_dm_face_lookup(target_ob, target_dm, tpa->num, tpa->fuv, NULL);
}
else {
me = &medge[nearest.index];
- pa->fuv[1] = line_point_factor_v3(nearest.co,
- mvert[me->v2].co,
- mvert[me->v2].co);
- pa->fuv[0] = 1.0f - pa->fuv[1];
- pa->fuv[2] = pa->fuv[3] = 0.0f;
+ tpa->fuv[1] = line_point_factor_v3(nearest.co,
+ mvert[me->v1].co,
+ mvert[me->v2].co);
+ tpa->fuv[0] = 1.0f - tpa->fuv[1];
+ tpa->fuv[2] = tpa->fuv[3] = 0.0f;
+ tpa->foffset = 0.0f;
- pa->num = nearest.index;
- pa->num_dmcache = -1;
+ tpa->num = nearest.index;
+ tpa->num_dmcache = -1;
}
- psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
- invert_m4_m4(imat, hairmat);
-
- sub_v3_v3v3(vec, nearest.co, key->co);
-
- if (point) {
- ekey = point->keys;
- point++;
- }
-
- for (k=0, key=pa->hair; k<pa->totkey; k++, key++) {
- add_v3_v3(key->co, vec);
- mul_m4_v3(imat, key->co);
-
- if (ekey) {
- ekey->flag |= PEK_USE_WCO;
- ekey++;
+ /* translate hair keys */
+ {
+ HairKey *key, *tkey;
+ float hairmat[4][4], imat[4][4];
+ float offset[3];
+
+ if (to_global)
+ copy_m4_m4(imat, target_ob->obmat);
+ else {
+ /* note: using target_dm here, which is in target_ob object space and has full modifiers */
+ psys_mat_hair_to_object(target_ob, target_dm, target_psys->part->from, tpa, hairmat);
+ invert_m4_m4(imat, hairmat);
+ }
+ mul_m4_m4m4(imat, imat, to_imat);
+
+ /* offset in world space */
+ sub_v3_v3v3(offset, nearest.co, from_co);
+
+ if (edit_point) {
+ for (k=0, key=pa->hair, tkey=tpa->hair, ekey = edit_point->keys; k<tpa->totkey; k++, key++, tkey++, ekey++) {
+ float co_orig[3];
+
+ if (from_global)
+ mul_v3_m4v3(co_orig, from_ob_imat, key->co);
+ else
+ mul_v3_m4v3(co_orig, from_ob_imat, key->world_co);
+ mul_m4_v3(from_mat, co_orig);
+
+ add_v3_v3v3(tkey->co, co_orig, offset);
+
+ mul_m4_v3(imat, tkey->co);
+
+ ekey->flag |= PEK_USE_WCO;
+ }
+
+ edit_point++;
+ }
+ else {
+ for (k=0, key=pa->hair, tkey=tpa->hair; k<tpa->totkey; k++, key++, tkey++) {
+ float co_orig[3];
+
+ if (from_global)
+ mul_v3_m4v3(co_orig, from_ob_imat, key->co);
+ else
+ mul_v3_m4v3(co_orig, from_ob_imat, key->world_co);
+ mul_m4_v3(from_mat, co_orig);
+
+ add_v3_v3v3(tkey->co, co_orig, offset);
+
+ mul_m4_v3(imat, tkey->co);
+ }
}
}
}
@@ -749,15 +840,26 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
free_bvhtree_from_mesh(&bvhtree);
dm->release(dm);
- psys_free_path_cache(psys, psys->edit);
+ psys_free_path_cache(target_psys, target_edit);
- psys->flag &= ~PSYS_GLOBAL_HAIR;
-
- PE_update_object(scene, ob, 0);
+ PE_update_object(scene, target_ob, 0);
return true;
}
+static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
+{
+ bool ok;
+
+ if (!psys)
+ return false;
+
+ ok = remap_hair_emitter(scene, ob, psys, ob, psys, psys->edit, ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false);
+ psys->flag &= ~PSYS_GLOBAL_HAIR;
+
+ return ok;
+}
+
static int connect_hair_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
@@ -805,3 +907,284 @@ void PARTICLE_OT_connect_hair(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh");
}
+/************************ particle system copy operator *********************/
+
+typedef enum eCopyParticlesSpace {
+ PAR_COPY_SPACE_OBJECT = 0,
+ PAR_COPY_SPACE_WORLD = 1,
+} eCopyParticlesSpace;
+
+static void copy_particle_edit(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from)
+{
+ PTCacheEdit *edit_from = psys_from->edit, *edit;
+ ParticleData *pa;
+ KEY_K;
+ POINT_P;
+
+ if (!edit_from)
+ return;
+
+ edit = MEM_dupallocN(edit_from);
+ edit->psys = psys;
+ psys->edit = edit;
+
+ edit->pathcache = NULL;
+ BLI_listbase_clear(&edit->pathcachebufs);
+
+ edit->emitter_field = NULL;
+ edit->emitter_cosnos = NULL;
+
+ BLI_listbase_clear(&edit->undo);
+ edit->curundo = NULL;
+
+ edit->points = MEM_dupallocN(edit_from->points);
+ pa = psys->particles;
+ LOOP_POINTS {
+ HairKey *hkey = pa->hair;
+
+ point->keys= MEM_dupallocN(point->keys);
+ LOOP_KEYS {
+ key->co = hkey->co;
+ key->time = &hkey->time;
+ key->flag = hkey->editflag;
+ if (!(psys->flag & PSYS_GLOBAL_HAIR)) {
+ key->flag |= PEK_USE_WCO;
+ hkey->editflag |= PEK_USE_WCO;
+ }
+
+ hkey++;
+ }
+
+ pa++;
+ }
+ update_world_cos(ob, edit);
+
+ UI_GetThemeColor3ubv(TH_EDGE_SELECT, edit->sel_col);
+ UI_GetThemeColor3ubv(TH_WIRE, edit->nosel_col);
+
+ recalc_lengths(edit);
+ recalc_emitter_field(ob, psys);
+ PE_update_object(scene, ob, true);
+
+ PTCacheUndo_clear(edit);
+ PE_undo_push(scene, "Original");
+}
+
+static void remove_particle_systems_from_object(Object *ob_to)
+{
+ ModifierData *md, *md_next;
+
+ if (ob_to->type != OB_MESH)
+ return;
+ if (!ob_to->data || ((ID *)ob_to->data)->lib)
+ return;
+
+ for (md = ob_to->modifiers.first; md; md = md_next) {
+ md_next = md->next;
+
+ /* remove all particle system modifiers as well,
+ * these need to sync to the particle system list
+ */
+ if (ELEM(md->type, eModifierType_ParticleSystem, eModifierType_DynamicPaint, eModifierType_Smoke)) {
+ BLI_remlink(&ob_to->modifiers, md);
+ modifier_free(md);
+ }
+ }
+
+ BKE_object_free_particlesystems(ob_to);
+}
+
+/* single_psys_from is optional, if NULL all psys of ob_from are copied */
+static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, ParticleSystem *single_psys_from, Object *ob_to, int space)
+{
+ ModifierData *md;
+ ParticleSystem *psys_start, *psys, *psys_from;
+ ParticleSystem **tmp_psys;
+ DerivedMesh *final_dm;
+ CustomDataMask cdmask;
+ int i, totpsys;
+
+ if (ob_to->type != OB_MESH)
+ return false;
+ if (!ob_to->data || ((ID *)ob_to->data)->lib)
+ return false;
+
+ /* For remapping we need a valid DM.
+ * Because the modifiers are appended at the end it's safe to use
+ * the final DM of the object without particles.
+ * However, when evaluating the DM all the particle modifiers must be valid,
+ * i.e. have the psys assigned already.
+ * To break this hen/egg problem we create all psys separately first (to collect required customdata masks),
+ * then create the DM, then add them to the object and make the psys modifiers ...
+ */
+ #define PSYS_FROM_FIRST (single_psys_from ? single_psys_from : ob_from->particlesystem.first)
+ #define PSYS_FROM_NEXT(cur) (single_psys_from ? NULL : (cur)->next)
+ totpsys = single_psys_from ? 1 : BLI_listbase_count(&ob_from->particlesystem);
+
+ tmp_psys = MEM_mallocN(sizeof(ParticleSystem*) * totpsys, "temporary particle system array");
+
+ cdmask = 0;
+ for (psys_from = PSYS_FROM_FIRST, i = 0;
+ psys_from;
+ psys_from = PSYS_FROM_NEXT(psys_from), ++i) {
+
+ psys = BKE_object_copy_particlesystem(psys_from);
+ tmp_psys[i] = psys;
+
+ if (psys_start == NULL)
+ psys_start = psys;
+
+ cdmask |= psys_emitter_customdata_mask(psys);
+ }
+ /* to iterate source and target psys in sync,
+ * we need to know where the newly added psys start
+ */
+ psys_start = totpsys > 0 ? tmp_psys[0] : NULL;
+
+ /* get the DM (psys and their modifiers have not been appended yet) */
+ final_dm = mesh_get_derived_final(scene, ob_to, cdmask);
+
+ /* now append psys to the object and make modifiers */
+ for (i = 0, psys_from = PSYS_FROM_FIRST;
+ i < totpsys;
+ ++i, psys_from = PSYS_FROM_NEXT(psys_from)) {
+
+ ParticleSystemModifierData *psmd;
+
+ psys = tmp_psys[i];
+
+ /* append to the object */
+ BLI_addtail(&ob_to->particlesystem, psys);
+
+ /* add a particle system modifier for each system */
+ md = modifier_new(eModifierType_ParticleSystem);
+ psmd = (ParticleSystemModifierData *)md;
+ /* push on top of the stack, no use trying to reproduce old stack order */
+ BLI_addtail(&ob_to->modifiers, md);
+
+ BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", i);
+ modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd);
+
+ psmd->psys = psys;
+ psmd->dm = CDDM_copy(final_dm);
+ CDDM_calc_normals(psmd->dm);
+ DM_ensure_tessface(psmd->dm);
+
+ if (psys_from->edit)
+ copy_particle_edit(scene, ob_to, psys, psys_from);
+ }
+ MEM_freeN(tmp_psys);
+
+ /* note: do this after creating DM copies for all the particle system modifiers,
+ * the remapping otherwise makes final_dm invalid!
+ */
+ for (psys = psys_start, psys_from = PSYS_FROM_FIRST, i = 0;
+ psys;
+ psys = psys->next, psys_from = PSYS_FROM_NEXT(psys_from), ++i) {
+
+ float (*from_mat)[4], (*to_mat)[4];
+
+ switch (space) {
+ case PAR_COPY_SPACE_OBJECT:
+ from_mat = I;
+ to_mat = I;
+ break;
+ case PAR_COPY_SPACE_WORLD:
+ from_mat = ob_from->obmat;
+ to_mat = ob_to->obmat;
+ break;
+ default:
+ /* should not happen */
+ BLI_assert(false);
+ break;
+ }
+
+ remap_hair_emitter(scene, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
+
+ /* tag for recalc */
+// psys->recalc |= PSYS_RECALC_RESET;
+ }
+
+ #undef PSYS_FROM_FIRST
+ #undef PSYS_FROM_NEXT
+
+ DAG_id_tag_update(&ob_to->id, OB_RECALC_DATA);
+ WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, ob_to);
+ return true;
+}
+
+static int copy_particle_systems_poll(bContext *C)
+{
+ Object *ob;
+ if (!ED_operator_object_active_editable(C))
+ return false;
+
+ ob = ED_object_active_context(C);
+ if (BLI_listbase_is_empty(&ob->particlesystem))
+ return false;
+
+ return true;
+}
+
+static int copy_particle_systems_exec(bContext *C, wmOperator *op)
+{
+ const int space = RNA_enum_get(op->ptr, "space");
+ const bool remove_target_particles = RNA_boolean_get(op->ptr, "remove_target_particles");
+ const bool use_active = RNA_boolean_get(op->ptr, "use_active");
+ Scene *scene = CTX_data_scene(C);
+ Object *ob_from = ED_object_active_context(C);
+ ParticleSystem *psys_from = use_active ? CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data : NULL;
+
+ int changed_tot = 0;
+ int fail = 0;
+
+ CTX_DATA_BEGIN (C, Object *, ob_to, selected_editable_objects)
+ {
+ if (ob_from != ob_to) {
+ bool changed = false;
+ if (remove_target_particles) {
+ remove_particle_systems_from_object(ob_to);
+ changed = true;
+ }
+ if (copy_particle_systems_to_object(scene, ob_from, psys_from, ob_to, space))
+ changed = true;
+ else
+ fail++;
+
+ if (changed)
+ changed_tot++;
+ }
+ }
+ CTX_DATA_END;
+
+ if ((changed_tot == 0 && fail == 0) || fail) {
+ BKE_reportf(op->reports, RPT_ERROR,
+ "Copy particle systems to selected: %d done, %d failed",
+ changed_tot, fail);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_copy_particle_systems(wmOperatorType *ot)
+{
+ static EnumPropertyItem space_items[] = {
+ {PAR_COPY_SPACE_OBJECT, "OBJECT", 0, "Object", "Copy inside each object's local space"},
+ {PAR_COPY_SPACE_WORLD, "WORLD", 0, "World", "Copy in world space"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ ot->name = "Copy Particle Systems";
+ ot->description = "Copy particle systems from the active object to selected objects";
+ ot->idname = "PARTICLE_OT_copy_particle_systems";
+
+ ot->poll = copy_particle_systems_poll;
+ ot->exec = copy_particle_systems_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "space", space_items, PAR_COPY_SPACE_OBJECT, "Space", "Space transform for copying from one object to another");
+ RNA_def_boolean(ot->srna, "remove_target_particles", true, "Remove Target Particles", "Remove particle systems on the target objects");
+ RNA_def_boolean(ot->srna, "use_active", false, "Use Active", "Use the active particle system from the context");
+}
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 5478ad28aed..d96bba4da45 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -78,8 +78,6 @@
#include "DNA_scene_types.h"
#include "DNA_mesh_types.h"
-#include "PIL_time.h"
-
static float get_fluid_viscosity(FluidsimSettings *settings)
{
return (1.0f/powf(10.0f, settings->viscosityExponent)) * settings->viscosityValue;
diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h
index 7668a850951..3bb87b80333 100644
--- a/source/blender/editors/physics/physics_intern.h
+++ b/source/blender/editors/physics/physics_intern.h
@@ -56,6 +56,8 @@ void PARTICLE_OT_mirror(struct wmOperatorType *ot);
void PARTICLE_OT_brush_edit(struct wmOperatorType *ot);
+void PARTICLE_OT_shape_cut(struct wmOperatorType *ot);
+
void PARTICLE_OT_particle_edit_toggle(struct wmOperatorType *ot);
void PARTICLE_OT_edited_clear(struct wmOperatorType *ot);
@@ -70,6 +72,7 @@ void PARTICLE_OT_target_move_up(struct wmOperatorType *ot);
void PARTICLE_OT_target_move_down(struct wmOperatorType *ot);
void PARTICLE_OT_connect_hair(struct wmOperatorType *ot);
void PARTICLE_OT_disconnect_hair(struct wmOperatorType *ot);
+void PARTICLE_OT_copy_particle_systems(struct wmOperatorType *ot);
void PARTICLE_OT_dupliob_copy(struct wmOperatorType *ot);
void PARTICLE_OT_dupliob_remove(struct wmOperatorType *ot);
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index 1038e8b64e3..cc87e61ff61 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -29,10 +29,6 @@
#include <stdlib.h>
-#include "DNA_scene_types.h"
-
-#include "BLI_utildefines.h"
-
#include "RNA_access.h"
#include "WM_api.h"
@@ -68,6 +64,8 @@ static void operatortypes_particle(void)
WM_operatortype_append(PARTICLE_OT_brush_edit);
+ WM_operatortype_append(PARTICLE_OT_shape_cut);
+
WM_operatortype_append(PARTICLE_OT_particle_edit_toggle);
WM_operatortype_append(PARTICLE_OT_edited_clear);
@@ -82,6 +80,7 @@ static void operatortypes_particle(void)
WM_operatortype_append(PARTICLE_OT_target_move_down);
WM_operatortype_append(PARTICLE_OT_connect_hair);
WM_operatortype_append(PARTICLE_OT_disconnect_hair);
+ WM_operatortype_append(PARTICLE_OT_copy_particle_systems);
WM_operatortype_append(PARTICLE_OT_dupliob_copy);
WM_operatortype_append(PARTICLE_OT_dupliob_remove);
diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c
index dd0816e509d..85b059d5574 100644
--- a/source/blender/editors/physics/rigidbody_constraint.c
+++ b/source/blender/editors/physics/rigidbody_constraint.c
@@ -37,8 +37,6 @@
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
-#include "BLI_math.h"
-
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index 13a3d7a523f..9b4f128ef86 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -33,16 +33,12 @@
#include <stdlib.h>
#include <string.h>
-#include "MEM_guardedalloc.h"
-#include "DNA_group_types.h"
#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLF_translation.h"
@@ -50,7 +46,6 @@
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_group.h"
-#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_rigidbody.h"
diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c
index 1c893992cf2..f7a2c83bc49 100644
--- a/source/blender/editors/physics/rigidbody_world.c
+++ b/source/blender/editors/physics/rigidbody_world.c
@@ -37,8 +37,6 @@
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
-#include "BLI_math.h"
-
#ifdef WITH_BULLET
# include "RBI_api.h"
#endif
@@ -48,8 +46,6 @@
#include "BKE_rigidbody.h"
#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -171,7 +167,7 @@ static int rigidbody_world_export_exec(bContext *C, wmOperator *op)
static int rigidbody_world_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!RNA_struct_property_is_set(op->ptr, "relative_path"))
- RNA_boolean_set(op->ptr, "relative_path", (U.flag & USER_RELPATHS));
+ RNA_boolean_set(op->ptr, "relative_path", (U.flag & USER_RELPATHS) != 0);
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return rigidbody_world_export_exec(C, op);
@@ -199,5 +195,5 @@ void RIGIDBODY_OT_world_export(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE, FILE_SPECIAL, FILE_SAVE, FILE_RELPATH, FILE_DEFAULTDISPLAY);
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER, FILE_SPECIAL, FILE_SAVE, FILE_RELPATH, FILE_DEFAULTDISPLAY);
}
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index baf25a49f7c..1c9f32697d4 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -75,10 +75,8 @@
#include "RE_engine.h"
#include "IMB_colormanagement.h"
-#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "GPU_extensions.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -86,7 +84,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "wm_window.h"
#include "render_intern.h"
@@ -343,7 +340,11 @@ static void render_freejob(void *rjv)
}
/* str is IMA_MAX_RENDER_TEXT in size */
-static void make_renderinfo_string(RenderStats *rs, Scene *scene, bool v3d_override, char *str)
+static void make_renderinfo_string(const RenderStats *rs,
+ const Scene *scene,
+ const bool v3d_override,
+ const char *error,
+ char *str)
{
char info_time_str[32]; // used to be extern to header_info.c
uintptr_t mem_in_use, mmap_in_use, peak_memory;
@@ -416,8 +417,12 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, bool v3d_overr
spos += sprintf(spos, IFACE_("| Full Sample %d "), rs->curfsa);
/* extra info */
- if (rs->infostr && rs->infostr[0])
+ if (rs->infostr && rs->infostr[0]) {
spos += sprintf(spos, "| %s ", rs->infostr);
+ }
+ else if (error && error[0]) {
+ spos += sprintf(spos, "| %s ", error);
+ }
/* very weak... but 512 characters is quite safe */
if (spos >= str + IMA_MAX_RENDER_TEXT)
@@ -438,7 +443,8 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs)
if (rr->text == NULL)
rr->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
- make_renderinfo_string(rs, rj->scene, rj->v3d_override, rr->text);
+ make_renderinfo_string(rs, rj->scene, rj->v3d_override,
+ rr->error, rr->text);
}
RE_ReleaseResult(rj->re);
@@ -1121,7 +1127,7 @@ static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs)
*rp->stop = 1;
}
else {
- make_renderinfo_string(rs, rp->scene, false, rp->engine->text);
+ make_renderinfo_string(rs, rp->scene, false, NULL, rp->engine->text);
/* make jobs timer to send notifier */
*(rp->do_update) = true;
@@ -1140,8 +1146,8 @@ BLI_INLINE void rcti_scale_coords(rcti *scaled_rect, const rcti *rect,
static void render_update_resolution(Render *re, const RenderPreview *rp,
bool use_border, const rcti *clip_rect)
{
- int winx = rp->ar->winx / rp->resolution_divider,
- winy = rp->ar->winy / rp->resolution_divider;
+ int winx = rp->ar->winx / rp->resolution_divider;
+ int winy = rp->ar->winy / rp->resolution_divider;
if (use_border) {
rcti scaled_cliprct;
rcti_scale_coords(&scaled_cliprct, clip_rect,
@@ -1439,7 +1445,7 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C)
rp->bmain = CTX_data_main(C);
rp->resolution_divider = divider;
rp->start_resolution_divider = divider;
- rp->has_freestyle = scene->r.mode & R_EDGE_FRS;
+ rp->has_freestyle = (scene->r.mode & R_EDGE_FRS) != 0;
copy_m4_m4(rp->viewmat, rp->rv3d->viewmat);
/* clear info text */
@@ -1455,7 +1461,7 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C)
engine->flag &= ~RE_ENGINE_DO_UPDATE;
}
-/* callback for render engine , on changes */
+/* callback for render engine, on changes */
void render_view3d_update(RenderEngine *engine, const bContext *C)
{
/* this shouldn't be needed and causes too many database rebuilds, but we
@@ -1551,10 +1557,10 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
RE_ReleaseResultImage(re);
}
-void ED_viewport_render_kill_jobs(const bContext *C, bool free_database)
+void ED_viewport_render_kill_jobs(wmWindowManager *wm,
+ Main *bmain,
+ bool free_database)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- Main *bmain = CTX_data_main(C);
bScreen *sc;
ScrArea *sa;
ARegion *ar;
@@ -1611,7 +1617,17 @@ Scene *ED_render_job_get_scene(const bContext *C)
RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
if (rj)
- return rj->current_scene;
+ return rj->scene;
return NULL;
}
+
+Scene *ED_render_job_get_current_scene(const bContext *C)
+{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
+ if (rj) {
+ return rj->current_scene;
+ }
+ return NULL;
+}
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 559c86bf48c..402e72db217 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -33,6 +33,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_camera_types.h"
#include "BLI_math.h"
#include "BLI_math_color_blend.h"
#include "BLI_blenlib.h"
@@ -42,6 +43,7 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
+#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_image.h"
@@ -68,8 +70,8 @@
#include "GPU_extensions.h"
#include "GPU_glew.h"
+#include "GPU_compositing.h"
-#include "wm_window.h"
#include "render_intern.h"
@@ -93,6 +95,7 @@ typedef struct OGLRender {
ImageUser iuser;
GPUOffScreen *ofs;
+ GPUFX *fx;
int sizex, sizey;
int write_still;
@@ -144,8 +147,10 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
int chanshown = sseq ? sseq->chanshown : 0;
struct bGPdata *gpd = (sseq && (sseq->flag & SEQ_SHOW_GPENCIL)) ? sseq->gpd : NULL;
- context = BKE_sequencer_new_render_data(oglrender->bmain->eval_ctx, oglrender->bmain,
- scene, oglrender->sizex, oglrender->sizey, 100.0f);
+ BKE_sequencer_new_render_data(
+ oglrender->bmain->eval_ctx, oglrender->bmain, scene,
+ oglrender->sizex, oglrender->sizey, 100.0f,
+ &context);
ibuf = BKE_sequencer_give_ibuf(&context, CFRA, chanshown);
@@ -179,7 +184,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
int i;
unsigned char *gp_rect;
- GPU_offscreen_bind(oglrender->ofs);
+ GPU_offscreen_bind(oglrender->ofs, true);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -187,7 +192,9 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
wmOrtho2(0, sizex, 0, sizey);
glTranslatef(sizex / 2, sizey / 2, 0.0f);
- ED_gpencil_draw_ex(gpd, sizex, sizey, scene->r.cfra);
+ G.f |= G_RENDER_OGL;
+ ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ);
+ G.f &= ~G_RENDER_OGL;
gp_rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect");
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect);
@@ -197,22 +204,27 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
rgba_uchar_to_float(col_src, &gp_rect[i]);
blend_color_mix_float(&rr->rectf[i], &rr->rectf[i], col_src);
}
- GPU_offscreen_unbind(oglrender->ofs);
+ GPU_offscreen_unbind(oglrender->ofs, true);
MEM_freeN(gp_rect);
}
}
else if (view_context) {
+ bool is_persp;
+ /* full copy */
+ GPUFXSettings fx_settings = v3d->fx_settings;
+
ED_view3d_draw_offscreen_init(scene, v3d);
- GPU_offscreen_bind(oglrender->ofs); /* bind */
+ GPU_offscreen_bind(oglrender->ofs, true); /* bind */
/* render 3d view */
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
/*int is_ortho = scene->r.mode & R_ORTHO;*/
camera = v3d->camera;
RE_GetCameraWindow(oglrender->re, camera, scene->r.cfra, winmat);
-
+ is_persp = true;
+ BKE_camera_to_gpu_dof(camera, &fx_settings);
}
else {
rctf viewplane;
@@ -221,12 +233,17 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
bool is_ortho = ED_view3d_viewplane_get(v3d, rv3d, sizex, sizey, &viewplane, &clipsta, &clipend, NULL);
if (is_ortho) orthographic_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, -clipend, clipend);
else perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend);
+
+ is_persp = !is_ortho;
}
rect = MEM_mallocN(sizex * sizey * sizeof(unsigned char) * 4, "offscreen rect");
if ((scene->r.mode & R_OSA) == 0) {
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, draw_bgpic, draw_sky);
+ ED_view3d_draw_offscreen(
+ scene, v3d, ar, sizex, sizey, NULL, winmat,
+ draw_bgpic, draw_sky, is_persp,
+ oglrender->ofs, oglrender->fx, &fx_settings);
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
}
else {
@@ -239,7 +256,10 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
BLI_jitter_init(jit_ofs, scene->r.osa);
/* first sample buffer, also initializes 'rv3d->persmat' */
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, draw_bgpic, draw_sky);
+ ED_view3d_draw_offscreen(
+ scene, v3d, ar, sizex, sizey, NULL, winmat,
+ draw_bgpic, draw_sky, is_persp,
+ oglrender->ofs, oglrender->fx, &fx_settings);
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
for (i = 0; i < sizex * sizey * 4; i++)
@@ -252,7 +272,10 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
(jit_ofs[j][0] * 2.0f) / sizex,
(jit_ofs[j][1] * 2.0f) / sizey);
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, draw_bgpic, draw_sky);
+ ED_view3d_draw_offscreen(
+ scene, v3d, ar, sizex, sizey, NULL, winmat_jitter,
+ draw_bgpic, draw_sky, is_persp,
+ oglrender->ofs, oglrender->fx, &fx_settings);
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
for (i = 0; i < sizex * sizey * 4; i++)
@@ -265,13 +288,13 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
MEM_freeN(accum_buffer);
}
- GPU_offscreen_unbind(oglrender->ofs); /* unbind */
+ GPU_offscreen_unbind(oglrender->ofs, true); /* unbind */
}
else {
/* shouldnt suddenly give errors mid-render but possible */
char err_out[256] = "unknown";
ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey,
- IB_rect, OB_SOLID, false, true,
+ IB_rect, OB_SOLID, false, true, true,
(draw_sky) ? R_ADDSKY : R_ALPHAPREMUL, err_out);
camera = scene->camera;
@@ -312,8 +335,9 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
/* rr->rectf is now filled with image data */
- if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW))
- BKE_stamp_buf(scene, camera, rect, rr->rectf, rr->rectx, rr->recty, 4);
+ if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) {
+ BKE_image_stamp_buf(scene, camera, rect, rr->rectf, rr->rectx, rr->recty, 4);
+ }
RE_ReleaseResult(oglrender->re);
@@ -332,8 +356,9 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
IMB_color_to_bw(ibuf);
}
- BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
- &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false);
+ BKE_image_path_from_imformat(
+ name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false);
ok = BKE_imbuf_write_as(ibuf, name, &scene->r.im_format, true); /* no need to stamp here */
if (ok) printf("OpenGL Render written to '%s'\n", name);
else printf("OpenGL Render failed to write '%s'\n", name);
@@ -443,6 +468,9 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
* running notifiers again will overwrite */
oglrender->scene->customdata_mask |= oglrender->scene->customdata_mask_modal;
+ if (oglrender->v3d->fx_settings.fx_flag & (GPU_FX_FLAG_DOF | GPU_FX_FLAG_SSAO)) {
+ oglrender->fx = GPU_fx_compositor_create();
+ }
}
/* create render */
@@ -492,6 +520,9 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
+ if (oglrender->fx)
+ GPU_fx_compositor_destroy(oglrender->fx);
+
GPU_offscreen_free(oglrender->ofs);
oglrender->scene->customdata_mask_modal = 0;
@@ -561,8 +592,9 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
if (!is_movie) {
- BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
- &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true);
+ BKE_image_path_from_imformat(
+ name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true);
if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 450a3b19889..99edaff759e 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -60,6 +60,7 @@
#include "DNA_brush_types.h"
#include "DNA_screen_types.h"
+#include "BKE_appdir.h"
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_colortools.h"
@@ -78,14 +79,11 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "IMB_colormanagement.h"
-#include "GPU_extensions.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
-#include "PIL_time.h"
#include "RE_pipeline.h"
#include "RE_engine.h"
@@ -96,9 +94,7 @@
#include "ED_datafiles.h"
#include "ED_render.h"
-#include "UI_interface.h"
-#include "render_intern.h"
ImBuf *get_brush_icon(Brush *brush)
{
@@ -121,7 +117,7 @@ ImBuf *get_brush_icon(Brush *brush)
// otherwise lets try to find it in other directories
if (!(brush->icon_imbuf)) {
- folder = BLI_get_folder(BLENDER_DATAFILES, "brushicons");
+ folder = BKE_appdir_folder_id(BLENDER_DATAFILES, "brushicons");
BLI_make_file_string(G.main->name, path, folder, brush->icon_filepath);
@@ -311,7 +307,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
* seems commonly used render engines does not support
* such kind of rendering.
*/
- BLI_strncpy(sce->r.engine, "BLENDER_RENDER", sizeof(sce->r.engine));
+ BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_RENDER, sizeof(sce->r.engine));
}
else {
BLI_strncpy(sce->r.engine, scene->r.engine, sizeof(sce->r.engine));
@@ -363,7 +359,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
for (base = sce->base.first; base; base = base->next) {
if (base->object->type == OB_LAMP) {
/* if doesn't match 'Lamp.002' --> main key light */
- if (strcmp(base->object->id.name + 2, "Lamp.002") != 0) {
+ if (!STREQ(base->object->id.name + 2, "Lamp.002")) {
if (mat->material_type == MA_TYPE_VOLUME)
base->object->restrictflag |= OB_RESTRICT_RENDER;
else
@@ -525,7 +521,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
}
/* new UI convention: draw is in pixel space already. */
-/* uses ROUNDBOX button in block to get the rect */
+/* uses UI_BTYPE_ROUNDBOX button in block to get the rect */
static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect, rcti *newrect)
{
Render *re;
@@ -565,8 +561,9 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect,
unsigned char *rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect");
float fx = rect->xmin + offx;
float fy = rect->ymin;
+ if (re)
+ RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte);
- RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte);
glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte);
MEM_freeN(rect_byte);
@@ -1101,6 +1098,25 @@ static void icon_preview_free(void *customdata)
MEM_freeN(ip);
}
+void ED_preview_icon_render(Scene *scene, ID *id, unsigned int *rect, int sizex, int sizey)
+{
+ IconPreview ip = {NULL};
+ short stop = false, update = false;
+ float progress = 0.0f;
+
+ ip.scene = scene;
+ ip.owner = id;
+ ip.id = id;
+
+ icon_preview_add_size(&ip, rect, sizex, sizey);
+
+ icon_preview_startjob_all_sizes(&ip, &stop, &update, &progress);
+
+ icon_preview_endjob(&ip);
+
+ BLI_freelistN(&ip.sizes);
+}
+
void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *rect, int sizex, int sizey)
{
wmJob *wm_job;
@@ -1180,12 +1196,11 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
-void ED_preview_kill_jobs(const struct bContext *C)
+void ED_preview_kill_jobs(wmWindowManager *wm, Main *bmain)
{
- wmWindowManager *wm = CTX_wm_manager(C);
if (wm)
WM_jobs_kill(wm, NULL, common_preview_startjob);
-
- ED_viewport_render_kill_jobs(C, false);
+
+ ED_viewport_render_kill_jobs(wm, bmain, false);
}
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 6c996bcbd67..ff90f48d705 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -51,7 +51,6 @@
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
#include "BKE_font.h"
-#include "BKE_freestyle.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_library.h"
@@ -65,17 +64,15 @@
#include "BKE_world.h"
#include "BKE_editmesh.h"
-#include "IMB_imbuf.h"
-#include "IMB_imbuf_types.h"
-#include "GPU_material.h"
#ifdef WITH_FREESTYLE
+# include "BKE_freestyle.h"
# include "FRS_freestyle.h"
+# include "RNA_enum_types.h"
#endif
#include "RNA_access.h"
-#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -408,7 +405,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
}
/* hook into UI */
- uiIDContextProperty(C, &ptr, &prop);
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
if (prop) {
/* when creating new ID blocks, use is already 1, but RNA
@@ -457,7 +454,7 @@ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
}
/* hook into UI */
- uiIDContextProperty(C, &ptr, &prop);
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
if (prop) {
/* when creating new ID blocks, use is already 1, but RNA
@@ -520,7 +517,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
}
/* hook into UI */
- uiIDContextProperty(C, &ptr, &prop);
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
if (prop) {
/* when creating new ID blocks, use is already 1, but RNA
@@ -558,7 +555,7 @@ static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
BKE_scene_add_render_layer(scene, NULL);
- scene->r.actlay = BLI_countlist(&scene->r.layers) - 1;
+ scene->r.actlay = BLI_listbase_count(&scene->r.layers) - 1;
DAG_id_tag_update(&scene->id, 0);
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
@@ -1389,11 +1386,15 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot)
static int save_envmap(wmOperator *op, Scene *scene, EnvMap *env, char *path, const char imtype)
{
+ PropertyRNA *prop;
float layout[12];
- if (RNA_struct_find_property(op->ptr, "layout") )
- RNA_float_get_array(op->ptr, "layout", layout);
- else
+
+ if ((prop = RNA_struct_find_property(op->ptr, "layout"))) {
+ RNA_property_float_get_array(op->ptr, prop, layout);
+ }
+ else {
memcpy(layout, default_envmap_layout, sizeof(layout));
+ }
if (RE_WriteEnvmapResult(op->reports, scene, env, path, imtype, layout)) {
return OPERATOR_FINISHED;
@@ -1415,7 +1416,7 @@ static int envmap_save_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", path);
if (scene->r.scemode & R_EXTENSION) {
- BKE_add_image_extension(path, &scene->r.im_format);
+ BKE_image_path_ensure_ext_from_imformat(path, &scene->r.im_format);
}
WM_cursor_wait(1);
@@ -1481,7 +1482,7 @@ void TEXTURE_OT_envmap_save(wmOperatorType *ot)
"(use -1 to skip a face)", 0.0f, 0.0f);
RNA_def_property_flag(prop, PROP_HIDDEN);
- WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_SAVE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
}
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index df7ca9f11b2..be42e2ed518 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -41,11 +41,11 @@
#include "DNA_world_types.h"
#include "DNA_windowmanager_types.h"
+#include "BLI_listbase.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_icons.h"
#include "BKE_main.h"
@@ -85,7 +85,11 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
/* don't call this recursively for frame updates */
if (recursive_check)
return;
-
+
+ /* Do not call if no WM available, see T42688. */
+ if (BLI_listbase_is_empty(&bmain->wm))
+ return;
+
recursive_check = true;
C = CTX_create();
@@ -276,7 +280,7 @@ static void material_changed(Main *bmain, Material *ma)
/* glsl */
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
/* find node materials using this */
for (parent = bmain->mat.first; parent; parent = parent->id.next) {
@@ -290,7 +294,7 @@ static void material_changed(Main *bmain, Material *ma)
BKE_icon_changed(BKE_icon_getid(&parent->id));
if (parent->gpumaterial.first)
- GPU_material_free(parent);
+ GPU_material_free(&parent->gpumaterial);
}
/* find if we have a scene with textured display */
@@ -336,10 +340,10 @@ static void lamp_changed(Main *bmain, Lamp *la)
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
if (defmaterial.gpumaterial.first)
- GPU_material_free(&defmaterial);
+ GPU_material_free(&defmaterial.gpumaterial);
}
static int material_uses_texture(Material *ma, Tex *tex)
@@ -377,7 +381,7 @@ static void texture_changed(Main *bmain, Tex *tex)
BKE_icon_changed(BKE_icon_getid(&ma->id));
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
}
/* find lamps */
@@ -406,6 +410,9 @@ static void texture_changed(Main *bmain, Tex *tex)
}
BKE_icon_changed(BKE_icon_getid(&wo->id));
+
+ if (wo->gpumaterial.first)
+ GPU_material_free(&wo->gpumaterial);
}
/* find compositing nodes */
@@ -451,14 +458,17 @@ static void world_changed(Main *bmain, World *wo)
/* icons */
BKE_icon_changed(BKE_icon_getid(&wo->id));
-
+
/* glsl */
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
if (defmaterial.gpumaterial.first)
- GPU_material_free(&defmaterial);
+ GPU_material_free(&defmaterial.gpumaterial);
+
+ if (wo->gpumaterial.first)
+ GPU_material_free(&wo->gpumaterial);
}
static void image_changed(Main *bmain, Image *ima)
@@ -478,6 +488,7 @@ static void scene_changed(Main *bmain, Scene *scene)
{
Object *ob;
Material *ma;
+ World *wo;
/* glsl */
for (ob = bmain->object.first; ob; ob = ob->id.next) {
@@ -487,16 +498,20 @@ static void scene_changed(Main *bmain, Scene *scene)
if (ob->mode & OB_MODE_TEXTURE_PAINT) {
BKE_texpaint_slots_refresh_object(scene, ob);
BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
- GPU_drawobject_free(ob->derivedFinal);
+ GPU_drawobject_free(ob->derivedFinal);
}
}
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
+ for (wo = bmain->world.first; wo; wo = wo->id.next)
+ if (wo->gpumaterial.first)
+ GPU_material_free(&wo->gpumaterial);
+
if (defmaterial.gpumaterial.first)
- GPU_material_free(&defmaterial);
+ GPU_material_free(&defmaterial.gpumaterial);
}
void ED_render_id_flush_update(Main *bmain, ID *id)
@@ -538,7 +553,7 @@ void ED_render_id_flush_update(Main *bmain, ID *id)
void ED_render_internal_init(void)
{
- RenderEngineType *ret = RE_engines_find("BLENDER_RENDER");
+ RenderEngineType *ret = RE_engines_find(RE_engine_id_BLENDER_RENDER);
ret->view_update = render_view3d_update;
ret->view_draw = render_view3d_draw;
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index ab28f5fa675..fe357a7a0e2 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -161,11 +161,19 @@ ScrArea *render_view_open(bContext *C, int mx, int my)
}
else if (scene->r.displaymode == R_OUTPUT_SCREEN) {
sa = CTX_wm_area(C);
- if (sa && sa->spacetype == SPACE_IMAGE)
- area_was_image = true;
- /* this function returns with changed context */
- sa = ED_screen_full_newspace(C, sa, SPACE_IMAGE);
+ /* if the active screen is already in fullscreen mode, skip this and
+ * unset the area, so that the fullscreen area is just changed later */
+ if (sa && sa->full) {
+ sa = NULL;
+ }
+ else {
+ if (sa && sa->spacetype == SPACE_IMAGE)
+ area_was_image = true;
+
+ /* this function returns with changed context */
+ sa = ED_screen_full_newspace(C, sa, SPACE_IMAGE);
+ }
}
if (!sa) {
@@ -186,10 +194,15 @@ ScrArea *render_view_open(bContext *C, int mx, int my)
/* makes ESC go back to prev space */
sima->flag |= SI_PREVSPACE;
+
+ /* we already had a fullscreen here -> mark new space as a stacked fullscreen */
+ if (sa->full) {
+ sa->flag |= AREA_FLAG_STACKED_FULLSCREEN;
+ }
}
else {
/* use any area of decent size */
- sa = BKE_screen_find_big_area(CTX_wm_screen(C), -1, 0);
+ sa = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TYPE_ANY, 0);
if (sa->spacetype != SPACE_IMAGE) {
// XXX newspace(sa, SPACE_IMAGE);
sima = sa->spacedata.first;
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index e38f3b5bee6..c423d81bfe2 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -41,7 +41,6 @@
#include "BLI_utildefines.h"
#include "BLI_linklist_stack.h"
-#include "BLF_translation.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -271,21 +270,21 @@ static void region_draw_azone_tab_plus(AZone *az)
/* add code to draw region hidden as 'too small' */
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
- uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
break;
case AE_BOTTOM_TO_TOPLEFT:
- uiSetRoundBox(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
+ UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
break;
case AE_LEFT_TO_TOPRIGHT:
- uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
break;
case AE_RIGHT_TO_TOPLEFT:
- uiSetRoundBox(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
break;
}
glColor4f(0.05f, 0.05f, 0.05f, 0.4f);
- uiRoundBox((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
+ UI_draw_roundbox((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
glEnable(GL_BLEND);
@@ -306,32 +305,32 @@ static void region_draw_azone_tab(AZone *az)
/* add code to draw region hidden as 'too small' */
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT:
- uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_RB_ALPHA);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT | UI_RB_ALPHA);
- uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
+ UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
glColor4ub(0, 0, 0, 255);
- uiRoundRect((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f);
+ UI_draw_roundbox_unfilled((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f);
break;
case AE_BOTTOM_TO_TOPLEFT:
- uiSetRoundBox(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA);
+ UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA);
- uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
+ UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
glColor4ub(0, 0, 0, 255);
- uiRoundRect((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f);
+ UI_draw_roundbox_unfilled((float)az->x1, 0.3f + (float)az->y1, (float)az->x2, 0.3f + (float)az->y2, 4.0f);
break;
case AE_LEFT_TO_TOPRIGHT:
- uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT | UI_RB_ALPHA);
- uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
+ UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
glColor4ub(0, 0, 0, 255);
- uiRoundRect((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
+ UI_draw_roundbox_unfilled((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
break;
case AE_RIGHT_TO_TOPLEFT:
- uiSetRoundBox(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT | UI_RB_ALPHA);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT | UI_RB_ALPHA);
- uiDrawBoxShade(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
+ UI_draw_roundbox_shade_x(GL_POLYGON, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, -0.3f, 0.05f);
glColor4ub(0, 0, 0, 255);
- uiRoundRect((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
+ UI_draw_roundbox_unfilled((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
break;
}
@@ -497,7 +496,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
ar->do_draw = 0;
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
- uiFreeInactiveBlocks(C, &ar->uiblocks);
+ UI_blocklist_free_inactive(C, &ar->uiblocks);
if (sa && (win->screen->state != SCREENFULL)) {
region_draw_emboss(ar, &ar->winrct);
@@ -896,7 +895,7 @@ static void region_azone_tria(ScrArea *sa, AZone *az, ARegion *ar)
static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge, const bool is_fullscreen)
{
- AZone *az;
+ AZone *az = NULL;
const bool is_hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) == 0;
if (is_hidden || !is_fullscreen) {
@@ -907,7 +906,7 @@ static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge, const
az->edge = edge;
}
- if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) {
+ if (!is_hidden) {
if (!is_fullscreen) {
if (G.debug_value == 3)
region_azone_icon(sa, az, ar);
@@ -1315,7 +1314,7 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
/* XXX it would be good to have boundbox checks for some of these... */
if (flag & ED_KEYMAP_UI) {
/* user interface widgets */
- UI_add_region_handlers(handlers);
+ UI_region_handlers_add(handlers);
}
if (flag & ED_KEYMAP_VIEW2D) {
/* 2d-viewport handling+manipulation */
@@ -1331,7 +1330,7 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
ARegion *ar;
/* same local check for all areas */
static rcti rect = {0, 10000, 0, -1};
- rect.ymax = (30 * UI_DPI_FAC);
+ rect.ymax = UI_MARKER_MARGIN_Y;
ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
if (ar) {
WM_event_add_keymap_handler_bb(handlers, keymap, &rect, &ar->winrct);
@@ -1352,8 +1351,18 @@ static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *hand
}
if (flag & ED_KEYMAP_GPENCIL) {
/* grease pencil */
- wmKeyMap *keymap = WM_keymap_find(wm->defaultconf, "Grease Pencil", 0, 0);
- WM_event_add_keymap_handler(handlers, keymap);
+ /* NOTE: This is now 2 keymaps - One for basic functionality,
+ * and one that only applies when "Edit Mode" is enabled
+ * for strokes.
+ *
+ * For now, it's easier to just include both,
+ * since you hardly want one without the other.
+ */
+ wmKeyMap *keymap_general = WM_keymap_find(wm->defaultconf, "Grease Pencil", 0, 0);
+ wmKeyMap *keymap_edit = WM_keymap_find(wm->defaultconf, "Grease Pencil Stroke Edit Mode", 0, 0);
+
+ WM_event_add_keymap_handler(handlers, keymap_general);
+ WM_event_add_keymap_handler(handlers, keymap_edit);
}
if (flag & ED_KEYMAP_HEADER) {
/* standard keymap for headers regions */
@@ -1409,7 +1418,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
}
else {
/* prevent uiblocks to run */
- uiFreeBlocks(NULL, &ar->uiblocks);
+ UI_blocklist_free(NULL, &ar->uiblocks);
}
}
}
@@ -1469,7 +1478,7 @@ void region_toggle_hidden(bContext *C, ARegion *ar, const bool do_fade)
/* exported to all editors, uses fading default */
void ED_region_toggle_hidden(bContext *C, ARegion *ar)
{
- region_toggle_hidden(C, ar, 1);
+ region_toggle_hidden(C, ar, true);
}
/**
@@ -1513,10 +1522,10 @@ void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free)
void ED_area_data_swap(ScrArea *sa_dst, ScrArea *sa_src)
{
- sa_dst->headertype = sa_src->headertype;
- sa_dst->spacetype = sa_src->spacetype;
- sa_dst->type = sa_src->type;
- sa_dst->butspacetype = sa_src->butspacetype;
+ SWAP(short, sa_dst->headertype, sa_src->headertype);
+ SWAP(char, sa_dst->spacetype, sa_src->spacetype);
+ SWAP(SpaceType *, sa_dst->type, sa_src->type);
+ SWAP(char, sa_dst->butspacetype, sa_src->butspacetype);
SWAP(ListBase, sa_dst->spacedata, sa_src->spacedata);
@@ -1622,7 +1631,7 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type)
void ED_area_prevspace(bContext *C, ScrArea *sa)
{
- SpaceLink *sl = (sa) ? sa->spacedata.first : CTX_wm_space_data(C);
+ SpaceLink *sl = sa->spacedata.first;
if (sl && sl->next) {
/* workaround for case of double prevspace, render window
@@ -1636,6 +1645,8 @@ void ED_area_prevspace(bContext *C, ScrArea *sa)
/* no change */
return;
}
+ sa->flag &= ~AREA_FLAG_STACKED_FULLSCREEN;
+
ED_area_tag_redraw(sa);
/* send space change notifier */
@@ -1652,7 +1663,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco)
RNA_pointer_create(&(scr->id), &RNA_Area, sa, &areaptr);
- uiDefButR(block, MENU, 0, "", xco, yco, 1.5 * U.widget_unit, U.widget_unit,
+ uiDefButR(block, UI_BTYPE_MENU, 0, "", xco, yco, 1.5 * U.widget_unit, U.widget_unit,
&areaptr, "type", 0, 0.0f, 0.0f, 0.0f, 0.0f, "");
return xco + 1.7 * U.widget_unit;
@@ -1663,7 +1674,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco)
void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *context, int contextnr)
{
ScrArea *sa = CTX_wm_area(C);
- uiStyle *style = UI_GetStyleDraw();
+ uiStyle *style = UI_style_get_dpi();
uiBlock *block;
PanelType *pt;
Panel *panel;
@@ -1761,16 +1772,16 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
w -= margin_x;
/* create panels */
- uiBeginPanels(C, ar);
+ UI_panels_begin(C, ar);
- /* set view2d view matrix - uiBeginBlock() stores it */
+ /* set view2d view matrix - UI_block_begin() stores it */
UI_view2d_view_ortho(v2d);
BLI_SMALLSTACK_ITER_BEGIN(pt_stack, pt)
{
bool open;
- panel = uiPanelFindByType(ar, pt);
+ panel = UI_panel_find_by_type(ar, pt);
if (use_category_tabs && pt->category[0] && !STREQ(category, pt->category)) {
if ((panel == NULL) || ((panel->flag & PNL_PIN) == 0)) {
@@ -1779,20 +1790,21 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
}
/* draw panel */
- block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS);
- panel = uiBeginPanel(sa, ar, block, pt, panel, &open);
+ block = UI_block_begin(C, ar, pt->idname, UI_EMBOSS);
+ panel = UI_panel_begin(sa, ar, block, pt, panel, &open);
/* bad fixed values */
triangle = (int)(UI_UNIT_Y * 1.1f);
if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
/* for enabled buttons */
- panel->layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
- triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, 0, style);
+ panel->layout = UI_block_layout(
+ block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
+ triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, 0, style);
pt->draw_header(C, panel);
- uiBlockLayoutResolve(block, &xco, &yco);
+ UI_block_layout_resolve(block, &xco, &yco);
panel->labelofs = xco - triangle;
panel->layout = NULL;
}
@@ -1809,28 +1821,29 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
else
panelContext = UI_LAYOUT_PANEL;
- panel->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, panelContext,
- style->panelspace, 0, w - 2 * style->panelspace, em, 0, style);
+ panel->layout = UI_block_layout(
+ block, UI_LAYOUT_VERTICAL, panelContext,
+ style->panelspace, 0, w - 2 * style->panelspace, em, 0, style);
pt->draw(C, panel);
- uiBlockLayoutResolve(block, &xco, &yco);
+ UI_block_layout_resolve(block, &xco, &yco);
panel->layout = NULL;
yco -= 2 * style->panelspace;
- uiEndPanel(block, w, -yco);
+ UI_panel_end(block, w, -yco);
}
else {
yco = 0;
- uiEndPanel(block, w, 0);
+ UI_panel_end(block, w, 0);
}
- uiEndBlock(C, block);
+ UI_block_end(C, block);
}
BLI_SMALLSTACK_ITER_END;
/* align panels and return size */
- uiEndPanels(C, ar, &x, &y);
+ UI_panels_end(C, ar, &x, &y);
/* before setting the view */
if (vertical) {
@@ -1855,7 +1868,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
* flip +1 or -1 pixel compared to redoing the entire layout again.
* Leaving in commented code for future tests */
#if 0
- uiScalePanels(ar, BLI_rctf_size_x(&v2d->cur));
+ UI_panels_scale(ar, BLI_rctf_size_x(&v2d->cur));
break;
#endif
}
@@ -1883,7 +1896,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
UI_view2d_view_ortho(v2d);
/* draw panels */
- uiDrawPanels(C, ar);
+ UI_panels_draw(C, ar);
/* restore view matrix */
UI_view2d_view_restore(C);
@@ -1910,7 +1923,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
void ED_region_header(const bContext *C, ARegion *ar)
{
- uiStyle *style = UI_GetStyleDraw();
+ uiStyle *style = UI_style_get_dpi();
uiBlock *block;
uiLayout *layout;
HeaderType *ht;
@@ -1930,8 +1943,8 @@ void ED_region_header(const bContext *C, ARegion *ar)
/* draw all headers types */
for (ht = ar->type->headertypes.first; ht; ht = ht->next) {
- block = uiBeginBlock(C, ar, ht->idname, UI_EMBOSS);
- layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, UI_UNIT_Y, 1, 0, style);
+ block = UI_block_begin(C, ar, ht->idname, UI_EMBOSS);
+ layout = UI_block_layout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, UI_UNIT_Y, 1, 0, style);
if (ht->draw) {
header.type = ht;
@@ -1944,14 +1957,14 @@ void ED_region_header(const bContext *C, ARegion *ar)
maxco = xco;
}
- uiBlockLayoutResolve(block, &xco, &yco);
+ UI_block_layout_resolve(block, &xco, &yco);
/* for view2d */
if (xco > maxco)
maxco = xco;
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
}
/* always as last */
@@ -1975,7 +1988,7 @@ int ED_area_headersize(void)
void ED_region_info_draw(ARegion *ar, const char *text, int block, float fill_color[4])
{
const int header_height = UI_UNIT_Y;
- uiStyle *style = UI_GetStyleDraw();
+ uiStyle *style = UI_style_get_dpi();
int fontid = style->widget.uifont_id;
GLint scissor[4];
rcti rect;
@@ -2115,7 +2128,7 @@ void ED_region_cache_draw_background(const ARegion *ar)
void ED_region_cache_draw_curfra_label(const int framenr, const float x, const float y)
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
int fontid = style->widget.uifont_id;
char numstr[32];
float font_dims[2] = {0.0f, 0.0f};
@@ -2150,4 +2163,3 @@ void ED_region_cache_draw_cached_segments(const ARegion *ar, const int num_segme
}
}
}
-
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index c095dfe7792..6001534e88d 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -45,7 +45,6 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
-#include "GPU_extensions.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
@@ -840,7 +839,7 @@ void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *r_sc_x
}
/**
- * Translate the \a world point from world coordiantes into screen space.
+ * Translate the \a world point from world coordinates into screen space.
*/
void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int screen_r[2])
{
@@ -849,7 +848,7 @@ void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int screen_r[2])
}
/**
- * Restores the previous OpenGL state and free's the auxilary gla data.
+ * Restores the previous OpenGL state and frees the auxiliary gla data.
*/
void glaEnd2DDraw(gla2DDrawInfo *di)
{
@@ -1137,9 +1136,9 @@ void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int
void cpack(unsigned int x)
{
- glColor3ub( ( (x) & 0xFF),
- (((x) >> 8) & 0xFF),
- (((x) >> 16) & 0xFF) );
+ glColor3ub(( (x) & 0xFF),
+ (((x) >> 8) & 0xFF),
+ (((x) >> 16) & 0xFF));
}
void glaDrawBorderCorners(const rcti *border, float zoomx, float zoomy)
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 7c8987ae778..3431ce9f50a 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -26,12 +26,13 @@
* \ingroup edscr
*/
-
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DNA_object_types.h"
#include "DNA_armature_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_sequence_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -45,11 +46,13 @@
#include "BKE_object.h"
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_gpencil.h"
#include "BKE_sequencer.h"
#include "RNA_access.h"
#include "ED_armature.h"
+#include "ED_gpencil.h"
#include "WM_api.h"
#include "UI_interface.h"
@@ -66,12 +69,16 @@ const char *screen_context_dir[] = {
"sculpt_object", "vertex_paint_object", "weight_paint_object",
"image_paint_object", "particle_edit_object",
"sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */
+ "gpencil_data", "gpencil_data_owner", /* grease pencil data */
+ "visible_gpencil_layers", "editable_gpencil_layers", "editable_gpencil_strokes",
+ "active_gpencil_layer", "active_gpencil_frame",
"active_operator",
NULL};
int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
{
bScreen *sc = CTX_wm_screen(C);
+ ScrArea *sa = CTX_wm_area(C);
Scene *scene = sc->scene;
Base *base;
unsigned int lay = scene->lay;
@@ -392,6 +399,114 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
}
+ else if (CTX_data_equals(member, "gpencil_data")) {
+ /* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these situations
+ * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when
+ * called from context. For that reason, we end up using an alternative where we pass everything in!
+ */
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+
+ if (gpd) {
+ CTX_data_id_pointer_set(result, &gpd->id);
+ return 1;
+ }
+ }
+ else if (CTX_data_equals(member, "gpencil_data_owner")) {
+ /* pointer to which data/datablock owns the reference to the Grease Pencil data being used (as gpencil_data)
+ * XXX: see comment for gpencil_data case...
+ */
+ bGPdata **gpd_ptr = NULL;
+ PointerRNA ptr;
+
+ /* get pointer to Grease Pencil Data */
+ gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, scene, sa, obact, &ptr);
+
+ if (gpd_ptr) {
+ CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data);
+ return 1;
+ }
+ }
+ else if (CTX_data_equals(member, "active_gpencil_layer")) {
+ /* XXX: see comment for gpencil_data case... */
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+
+ if (gpd) {
+ bGPDlayer *gpl = gpencil_layer_getactive(gpd);
+
+ if (gpl) {
+ CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl);
+ return 1;
+ }
+ }
+ }
+ else if (CTX_data_equals(member, "active_gpencil_frame")) {
+ /* XXX: see comment for gpencil_data case... */
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+
+ if (gpd) {
+ bGPDlayer *gpl = gpencil_layer_getactive(gpd);
+
+ if (gpl) {
+ CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl->actframe);
+ return 1;
+ }
+ }
+ }
+ else if (CTX_data_equals(member, "visible_gpencil_layers")) {
+ /* XXX: see comment for gpencil_data case... */
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+
+ if (gpd) {
+ bGPDlayer *gpl;
+
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if ((gpl->flag & GP_LAYER_HIDE) == 0) {
+ CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
+ }
+ }
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ }
+ else if (CTX_data_equals(member, "editable_gpencil_layers")) {
+ /* XXX: see comment for gpencil_data case... */
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+
+ if (gpd) {
+ bGPDlayer *gpl;
+
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0) {
+ CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl);
+ }
+ }
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ }
+ else if (CTX_data_equals(member, "editable_gpencil_strokes")) {
+ /* XXX: see comment for gpencil_data case... */
+ bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, scene, sa, obact);
+
+ if (gpd) {
+ bGPDlayer *gpl;
+
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0 && (gpl->actframe)) {
+ bGPDframe *gpf = gpl->actframe;
+ bGPDstroke *gps;
+
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ if (ED_gpencil_stroke_can_use_direct(sa, gps)) {
+ CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps);
+ }
+ }
+ }
+ }
+ CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
+ return 1;
+ }
+ }
else if (CTX_data_equals(member, "active_operator")) {
wmOperator *op = NULL;
@@ -399,8 +514,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
if (sfile) {
op = sfile->op;
}
- else if ((op = uiContextActiveOperator(C))) {
- /* do nothign */
+ else if ((op = UI_context_active_operator_get(C))) {
+ /* do nothing */
}
else {
/* note, this checks poll, could be a problem, but this also
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 9463a702b76..aadfa9e6608 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1439,7 +1439,7 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
/* this used to be a notifier, but needs to be done immediate
* because it can undo setting the right button as active due
* to delayed notifier handling */
- uiFreeActiveButtons(C, win->screen);
+ UI_screen_free_active_but(C, win->screen);
}
else
region_cursor_set(win, scr->subwinactive, false);
@@ -1748,6 +1748,13 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
}
}
+ if (sa && (sa->spacetype != type)) {
+ newsa->flag |= AREA_FLAG_TEMP_TYPE;
+ }
+ else {
+ newsa->flag &= ~AREA_FLAG_TEMP_TYPE;
+ }
+
ED_area_newspace(C, newsa, type);
return newsa;
@@ -1755,12 +1762,28 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
void ED_screen_full_prevspace(bContext *C, ScrArea *sa)
{
- wmWindow *win = CTX_wm_window(C);
+ if (sa->flag & AREA_FLAG_STACKED_FULLSCREEN) {
+ /* stacked fullscreen -> only go back to previous screen and don't toggle out of fullscreen */
+ ED_area_prevspace(C, sa);
+ }
+ else {
+ ED_screen_restore_temp_type(C, sa);
+ }
+}
- ED_area_prevspace(C, sa);
-
- if (sa->full)
- ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED);
+void ED_screen_restore_temp_type(bContext *C, ScrArea *sa)
+{
+ /* incase nether functions below run */
+ ED_area_tag_redraw(sa);
+
+ if (sa->flag & AREA_FLAG_TEMP_TYPE) {
+ ED_area_prevspace(C, sa);
+ sa->flag &= ~AREA_FLAG_TEMP_TYPE;
+ }
+
+ if (sa->full) {
+ ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENMAXIMIZED);
+ }
}
/* restore a screen / area back to default operation, after temp fullscreen modes */
@@ -1771,30 +1794,18 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa)
bScreen *screen = CTX_wm_screen(C);
short state = (screen ? screen->state : SCREENMAXIMIZED);
- /* if fullscreen area has a secondary space (such as a file browser or fullscreen render
- * overlaid on top of a existing setup) then return to the previous space */
+ /* if fullscreen area has a temporary space (such as a file browser or fullscreen render
+ * overlaid on top of an existing setup) then return to the previous space */
if (sl->next) {
- /* specific checks for space types */
-
- /* Special check added for non-render image window (back from fullscreen through "Back to Previous" button) */
- if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = sa->spacedata.first;
-
- if (sima->flag & (SI_PREVSPACE | SI_FULLWINDOW)) {
- sima->flag &= ~SI_PREVSPACE;
- sima->flag &= ~SI_FULLWINDOW;
- ED_screen_full_prevspace(C, sa);
- }
- else
- ED_screen_state_toggle(C, win, sa, state);
- }
- else if (sl->spacetype == SPACE_FILE) {
+ if (sa->flag & AREA_FLAG_TEMP_TYPE) {
ED_screen_full_prevspace(C, sa);
}
else {
ED_screen_state_toggle(C, win, sa, state);
}
+
+ sa->flag &= ~AREA_FLAG_TEMP_TYPE;
}
/* otherwise just tile the area again */
else {
@@ -1813,7 +1824,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
* switching screens with tooltip open because region and tooltip
* are no longer in the same screen */
for (ar = sa->regionbase.first; ar; ar = ar->next)
- uiFreeBlocks(C, &ar->uiblocks);
+ UI_blocklist_free(C, &ar->uiblocks);
/* prevent hanging header prints */
ED_area_headerprint(sa, NULL);
@@ -1857,6 +1868,11 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
BKE_screen_free(oldscreen);
BKE_libblock_free(CTX_data_main(C), oldscreen);
+ /* After we've restored back to SCREENNORMAL, we have to wait with
+ * screen handling as it uses the area coords which aren't updated yet.
+ * Without doing so, the screen handling gets wrong area coords,
+ * which in worst case can lead to crashes (see T43139) */
+ sc->skip_handling = true;
}
else {
/* change from SCREENNORMAL to new state */
@@ -1869,6 +1885,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "nonnormal");
sc = ED_screen_add(win, oldscreen->scene, newname);
sc->state = state;
+ sc->redraws_flag = oldscreen->redraws_flag;
/* timer */
sc->animtimer = oldscreen->animtimer;
@@ -2077,7 +2094,7 @@ void ED_update_for_newframe(Main *bmain, Scene *scene, int UNUSED(mute))
/* this function applies the changes too */
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, layers);
- //if ( (CFRA>1) && (!mute) && (scene->r.audio.flag & AUDIO_SCRUB))
+ //if ((CFRA > 1) && (!mute) && (scene->r.audio.flag & AUDIO_SCRUB))
// audiostream_scrub( CFRA );
/* 3d window, preview */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index a4a7580c058..48d39020236 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -43,6 +43,7 @@
#include "DNA_lattice_types.h"
#include "DNA_object_types.h"
#include "DNA_curve_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_scene_types.h"
#include "DNA_meta_types.h"
#include "DNA_mask_types.h"
@@ -81,8 +82,6 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "wm_window.h"
-
#include "screen_intern.h" /* own module include */
#define KM_MODAL_CANCEL 1
@@ -392,7 +391,7 @@ int ED_operator_editarmature(bContext *C)
* \brief check for pose mode (no mixed modes)
*
* We want to enable most pose operations in weight paint mode,
- * when it comes to transforming bones, but managing bomes layers/groups
+ * when it comes to transforming bones, but managing bones layers/groups
* can be left for pose mode only. (not weight paint mode)
*/
int ED_operator_posemode_exclusive(bContext *C)
@@ -412,7 +411,7 @@ int ED_operator_posemode_exclusive(bContext *C)
}
/* allows for pinned pose objects to be used in the object buttons
- * and the the non-active pose object to be used in the 3D view */
+ * and the non-active pose object to be used in the 3D view */
int ED_operator_posemode_context(bContext *C)
{
Object *obpose = ED_pose_object_from_context(C);
@@ -599,19 +598,6 @@ typedef struct sActionzoneData {
int x, y, gesture_dir, modifier;
} sActionzoneData;
-/* used by other operators too */
-static ScrArea *screen_areahascursor(bScreen *scr, int x, int y)
-{
- ScrArea *sa = NULL;
- sa = scr->areabase.first;
- while (sa) {
- if (BLI_rcti_isect_pt(&sa->totrct, x, y)) break;
- sa = sa->next;
- }
-
- return sa;
-}
-
/* quick poll to save operators to be created and handled */
static int actionzone_area_poll(bContext *C)
{
@@ -809,7 +795,7 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* gesture is large enough? */
if (is_gesture) {
/* second area, for join when (sa1 != sa2) */
- sad->sa2 = screen_areahascursor(sc, event->x, event->y);
+ sad->sa2 = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, event->x, event->y);
/* apply sends event */
actionzone_apply(C, op, sad->az->type);
actionzone_exit(op);
@@ -930,7 +916,7 @@ static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
switch (event->type) {
case MOUSEMOVE:
/* second area, for join */
- sad->sa2 = screen_areahascursor(CTX_wm_screen(C), event->x, event->y);
+ sad->sa2 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, event->x, event->y);
break;
case LEFTMOUSE: /* release LMB */
if (event->val == KM_RELEASE) {
@@ -1680,7 +1666,8 @@ static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
sd->sarea->flag &= ~(AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V);
ED_area_tag_redraw(sd->sarea);
}
- sd->sarea = screen_areahascursor(CTX_wm_screen(C), event->x, event->y); /* area context not set */
+ /* area context not set */
+ sd->sarea = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, event->x, event->y);
if (sd->sarea) {
ED_area_tag_redraw(sd->sarea);
@@ -2055,6 +2042,48 @@ static void SCREEN_OT_region_scale(wmOperatorType *ot)
/* ************** frame change operator ***************************** */
+static void areas_do_frame_follow(bContext *C, bool middle)
+{
+ bScreen *scr = CTX_wm_screen(C);
+ Scene *scene = CTX_data_scene(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *window;
+ for (window = wm->windows.first; window; window = window->next) {
+ ScrArea *sa;
+ for (sa = window->screen->areabase.first; sa; sa = sa->next) {
+ ARegion *ar;
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ /* do follow here if editor type supports it */
+ if ((scr->redraws_flag & TIME_FOLLOW)) {
+ if ((ar->regiontype == RGN_TYPE_WINDOW &&
+ ELEM(sa->spacetype, SPACE_SEQ, SPACE_TIME, SPACE_IPO, SPACE_ACTION, SPACE_NLA)) ||
+ (sa->spacetype == SPACE_CLIP && ar->regiontype == RGN_TYPE_PREVIEW))
+ {
+ float w = BLI_rctf_size_x(&ar->v2d.cur);
+
+ if (middle) {
+ if ((scene->r.cfra < ar->v2d.cur.xmin) || (scene->r.cfra > ar->v2d.cur.xmax)) {
+ ar->v2d.cur.xmax = scene->r.cfra + (w / 2);
+ ar->v2d.cur.xmin = scene->r.cfra - (w / 2);
+ }
+ }
+ else {
+ if (scene->r.cfra < ar->v2d.cur.xmin) {
+ ar->v2d.cur.xmax = scene->r.cfra;
+ ar->v2d.cur.xmin = ar->v2d.cur.xmax - w;
+ }
+ else if (scene->r.cfra > ar->v2d.cur.xmax) {
+ ar->v2d.cur.xmin = scene->r.cfra;
+ ar->v2d.cur.xmax = ar->v2d.cur.xmin + w;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
/* function to be called outside UI context, or for redo */
static int frame_offset_exec(bContext *C, wmOperator *op)
{
@@ -2068,6 +2097,8 @@ static int frame_offset_exec(bContext *C, wmOperator *op)
FRAMENUMBER_MIN_CLAMP(CFRA);
SUBFRA = 0.f;
+ areas_do_frame_follow(C, false);
+
sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
@@ -2118,6 +2149,8 @@ static int frame_jump_exec(bContext *C, wmOperator *op)
else
CFRA = PSFRA;
+ areas_do_frame_follow(C, true);
+
sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
@@ -2150,6 +2183,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = CTX_data_gpencil_data(C);
bDopeSheet ads = {NULL};
DLRBT_Tree keys;
ActKeyColumn *ak;
@@ -2177,7 +2211,9 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
if (ob)
ob_to_keylist(&ads, ob, &keys, NULL);
-
+
+ gpencil_to_keylist(&ads, gpd, &keys);
+
{
Mask *mask = CTX_data_edit_mask(C);
if (mask) {
@@ -2219,6 +2255,8 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
+ areas_do_frame_follow(C, true);
+
sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
@@ -2279,6 +2317,8 @@ static int marker_jump_exec(bContext *C, wmOperator *op)
else {
CFRA = closest;
+ areas_do_frame_follow(C, true);
+
sound_seek_scene(bmain, scene);
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
@@ -2320,7 +2360,7 @@ static int screen_set_exec(bContext *C, wmOperator *op)
bScreen *screen_prev = screen;
ScrArea *sa = CTX_wm_area(C);
- int tot = BLI_countlist(&bmain->screen);
+ int tot = BLI_listbase_count(&bmain->screen);
int delta = RNA_int_get(op->ptr, "delta");
/* temp screens are for userpref or render display */
@@ -2480,8 +2520,8 @@ static int area_join_init(bContext *C, wmOperator *op)
x2 = RNA_int_get(op->ptr, "max_x");
y2 = RNA_int_get(op->ptr, "max_y");
- sa1 = screen_areahascursor(CTX_wm_screen(C), x1, y1);
- sa2 = screen_areahascursor(CTX_wm_screen(C), x2, y2);
+ sa1 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, x1, y1);
+ sa2 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, x2, y2);
if (sa1 == NULL || sa2 == NULL || sa1 == sa2)
return 0;
@@ -2614,7 +2654,7 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
case MOUSEMOVE:
{
- ScrArea *sa = screen_areahascursor(sc, event->x, event->y);
+ ScrArea *sa = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, event->x, event->y);
int dir;
if (sa) {
@@ -2737,8 +2777,8 @@ static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent
if (actedge == NULL) return OPERATOR_CANCELLED;
- pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
WM_operator_properties_create(&ptr1, "SCREEN_OT_area_join");
@@ -2757,9 +2797,9 @@ static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent
uiItemFullO(layout, "SCREEN_OT_area_split", NULL, ICON_NONE, ptr2.data, WM_OP_INVOKE_DEFAULT, 0);
uiItemFullO(layout, "SCREEN_OT_area_join", NULL, ICON_NONE, ptr1.data, WM_OP_INVOKE_DEFAULT, 0);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
static void SCREEN_OT_area_options(wmOperatorType *ot)
@@ -2795,7 +2835,7 @@ static int spacedata_cleanup_exec(bContext *C, wmOperator *op)
SpaceLink *sl = sa->spacedata.first;
BLI_remlink(&sa->spacedata, sl);
- tot += BLI_countlist(&sa->spacedata);
+ tot += BLI_listbase_count(&sa->spacedata);
BKE_spacedata_freelist(&sa->spacedata);
BLI_addtail(&sa->spacedata, sl);
}
@@ -2853,20 +2893,20 @@ static int repeat_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNU
uiLayout *layout;
int items, i;
- items = BLI_countlist(&wm->operators);
+ items = BLI_listbase_count(&wm->operators);
if (items == 0)
return OPERATOR_CANCELLED;
- pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
for (i = items - 1, lastop = wm->operators.last; lastop; lastop = lastop->prev, i--)
if (WM_operator_repeat_check(C, lastop))
uiItemIntO(layout, RNA_struct_ui_name(lastop->type->srna), ICON_NONE, op->type->idname, "index", i);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
static int repeat_history_exec(bContext *C, wmOperator *op)
@@ -3255,14 +3295,14 @@ static int header_toolbox_invoke(bContext *C, wmOperator *UNUSED(op), const wmEv
uiPopupMenu *pup;
uiLayout *layout;
- pup = uiPupMenuBegin(C, IFACE_("Header"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("Header"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
ED_screens_header_tools_menu_create(C, layout, NULL);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
static void SCREEN_OT_header_toolbox(wmOperatorType *ot)
@@ -3397,7 +3437,12 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
(sad->flag & ANIMPLAY_FLAG_REVERSE) == false &&
finite(time = sound_sync_scene(scene)))
{
- scene->r.cfra = (double)time * FPS + 0.5;
+ double newfra = (double)time * FPS;
+ /* give some space here to avoid jumps */
+ if (newfra + 0.5 > scene->r.cfra && newfra - 0.5 < scene->r.cfra)
+ scene->r.cfra++;
+ else
+ scene->r.cfra = newfra + 0.5;
}
else {
if (sync) {
@@ -3474,11 +3519,33 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv
for (sa = window->screen->areabase.first; sa; sa = sa->next) {
ARegion *ar;
for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ bool redraw = false;
if (ar == sad->ar) {
- ED_region_tag_redraw(ar);
+ redraw = true;
}
else if (match_region_with_redraws(sa->spacetype, ar->regiontype, sad->redraws)) {
+ redraw = true;
+ }
+
+ if (redraw) {
ED_region_tag_redraw(ar);
+ /* do follow here if editor type supports it */
+ if ((sad->redraws & TIME_FOLLOW)) {
+ if ((ar->regiontype == RGN_TYPE_WINDOW &&
+ ELEM(sa->spacetype, SPACE_SEQ, SPACE_TIME, SPACE_IPO, SPACE_ACTION, SPACE_NLA)) ||
+ (sa->spacetype == SPACE_CLIP && ar->regiontype == RGN_TYPE_PREVIEW))
+ {
+ float w = BLI_rctf_size_x(&ar->v2d.cur);
+ if (scene->r.cfra < ar->v2d.cur.xmin) {
+ ar->v2d.cur.xmax = scene->r.cfra;
+ ar->v2d.cur.xmin = ar->v2d.cur.xmax - w;
+ }
+ else if (scene->r.cfra > ar->v2d.cur.xmax) {
+ ar->v2d.cur.xmin = scene->r.cfra;
+ ar->v2d.cur.xmax = ar->v2d.cur.xmin + w;
+ }
+ }
+ }
}
}
@@ -3523,12 +3590,14 @@ static void SCREEN_OT_animation_step(wmOperatorType *ot)
/* find window that owns the animation timer */
bScreen *ED_screen_animation_playing(const wmWindowManager *wm)
{
- wmWindow *window;
+ wmWindow *win;
+
+ for (win = wm->windows.first; win; win = win->next) {
+ if (win->screen->animtimer) {
+ return win->screen;
+ }
+ }
- for (window = wm->windows.first; window; window = window->next)
- if (window->screen->animtimer)
- return window->screen;
-
return NULL;
}
@@ -3542,6 +3611,8 @@ int ED_screen_animation_play(bContext *C, int sync, int mode)
/* stop playback now */
ED_screen_animation_timer(C, 0, 0, 0, 0);
sound_stop_scene(scene);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
else {
int refresh = SPACE_TIME; /* these settings are currently only available from a menu in the TimeLine */
@@ -3703,9 +3774,9 @@ static int fullscreen_back_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No fullscreen areas were found");
return OPERATOR_CANCELLED;
}
-
- ED_screen_full_restore(C, sa);
-
+
+ ED_screen_full_prevspace(C, sa);
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index be5fd48b41a..9c05f1d4780 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -65,7 +65,6 @@
#include "PIL_time.h"
-#include "ED_screen_types.h"
#include "screen_intern.h"
@@ -287,7 +286,7 @@ void SCREEN_OT_screenshot(wmOperatorType *ot)
ot->flag = 0;
- WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_SAVE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE, FILE_SPECIAL, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
RNA_def_boolean(ot->srna, "full", 1, "Full Screen",
"Capture the whole window (otherwise only capture the active area)");
@@ -378,8 +377,9 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
char name[FILE_MAX];
int ok;
- BKE_makepicstring(name, rd.pic, sj->bmain->name, rd.cfra,
- &rd.im_format, (rd.scemode & R_EXTENSION) != 0, true);
+ BKE_image_path_from_imformat(
+ name, rd.pic, sj->bmain->name, rd.cfra,
+ &rd.im_format, (rd.scemode & R_EXTENSION) != 0, true);
ibuf->rect = sj->dumprect;
ok = BKE_imbuf_write(ibuf, name, &rd.im_format);
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index e27ef705fad..886e4e5ef8c 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -426,7 +426,7 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
len = sqrtf(x * x + y * y);
if (len <= 1) {
- float avg = BKE_brush_curve_strength_clamp(br, len, 1.0f); /* Falloff curve */
+ float avg = BKE_brush_curve_strength(br, len, 1.0f); /* Falloff curve */
buffer[index] = 255 - (GLubyte)(255 * avg);
@@ -595,7 +595,7 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush,
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
/* brush rotation */
glTranslatef(0.5, 0.5, 0);
- glRotatef((double)RAD2DEGF(ups->brush_rotation),
+ glRotatef((double)RAD2DEGF((primary) ? ups->brush_rotation : ups->brush_rotation_sec),
0.0, 0.0, 1.0);
glTranslatef(-0.5f, -0.5f, 0);
@@ -652,16 +652,12 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush,
}
/* set quad color. Colored overlay does not get blending */
- if (col)
- glColor4f(1.0,
- 1.0,
- 1.0,
- overlay_alpha / 100.0f);
- else
- glColor4f(U.sculpt_paint_overlay_col[0],
- U.sculpt_paint_overlay_col[1],
- U.sculpt_paint_overlay_col[2],
- overlay_alpha / 100.0f);
+ if (col) {
+ glColor4f(1.0, 1.0, 1.0, overlay_alpha / 100.0f);
+ }
+ else {
+ glColor4f(UNPACK3(U.sculpt_paint_overlay_col), overlay_alpha / 100.0f);
+ }
/* draw textured quad */
glBegin(GL_QUADS);
@@ -786,7 +782,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
}
else {
- if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY))
+ if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY) && (mode != PAINT_WEIGHT))
paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, false, true);
if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR))
paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
@@ -1000,9 +996,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
/* don't calculate rake angles while a stroke is active because the rake variables are global and
* we may get interference with the stroke itself. For line strokes, such interference is visible */
if (!ups->stroke_active) {
- if (brush->flag & BRUSH_RAKE)
- /* here, translation contains the mouse coordinates. */
- paint_calculate_rake_rotation(ups, translation);
+ paint_calculate_rake_rotation(ups, brush, translation);
}
/* draw overlay */
diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c
index 8c7c3b102e3..439c2a639bd 100644
--- a/source/blender/editors/sculpt_paint/paint_curve.c
+++ b/source/blender/editors/sculpt_paint/paint_curve.c
@@ -108,7 +108,7 @@ static void paintcurve_undo_restore(bContext *C, ListBase *lb)
uc = (UndoCurve *)lb->first;
- if (strncmp(uc->idname, pc->id.name, BLI_strnlen(uc->idname, sizeof(uc->idname))) == 0) {
+ if (STREQLEN(uc->idname, pc->id.name, BLI_strnlen(uc->idname, sizeof(uc->idname)))) {
SWAP(PaintCurvePoint *, pc->points, uc->points);
SWAP(int, pc->tot_points, uc->tot_points);
SWAP(int, pc->add_index, uc->active_point);
@@ -329,7 +329,7 @@ void PAINTCURVE_OT_add_point(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add New Paint Curve Point";
- ot->description = "Add new paint curve point";
+ ot->description = ot->name;
ot->idname = "PAINTCURVE_OT_add_point";
/* api callbacks */
@@ -410,8 +410,8 @@ static int paintcurve_delete_point_exec(bContext *C, wmOperator *op)
void PAINTCURVE_OT_delete_point(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Add New Paint Curve Point";
- ot->description = "Add new paint curve point";
+ ot->name = "Remove Paint Curve Point";
+ ot->description = ot->name;
ot->idname = "PAINTCURVE_OT_delete_point";
/* api callbacks */
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 021822793ff..5cfbd164153 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -45,13 +45,11 @@
#include "BLI_utildefines.h"
#include "BLI_threads.h"
-#include "PIL_time.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "DNA_brush_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
@@ -62,15 +60,9 @@
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_material.h"
-#include "BKE_mesh.h"
#include "BKE_node.h"
#include "BKE_paint.h"
-#include "BKE_report.h"
-#include "BKE_scene.h"
#include "BKE_texture.h"
-#include "BKE_colortools.h"
-
-#include "BKE_editmesh.h"
#include "UI_view2d.h"
@@ -85,7 +77,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
#include "GPU_draw.h"
#include "GPU_buffers.h"
@@ -167,9 +158,10 @@ static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, Cop
}
}
else {
- if (mode == RESTORE_COPY)
+ if (mode == RESTORE_COPY) {
IMB_rectcpy(tmpibuf, ibuf, 0, 0, tile->x * IMAPAINT_TILE_SIZE,
- tile->y * IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
+ tile->y * IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
+ }
/* swap to the tmpbuf for easy copying */
if (ibuf->rect_float) {
SWAP(float *, tmpibuf->rect_float, tile->rect.fp);
@@ -201,7 +193,7 @@ void *image_undo_find_tile(Image *ima, ImBuf *ibuf, int x_tile, int y_tile, unsi
for (tile = lb->first; tile; tile = tile->next) {
if (tile->x == x_tile && tile->y == y_tile && ima->gen_type == tile->gen_type && ima->source == tile->source) {
if (tile->use_float == use_float) {
- if (strcmp(tile->idname, ima->id.name) == 0 && strcmp(tile->ibufname, ibuf->name) == 0) {
+ if (STREQ(tile->idname, ima->id.name) && STREQ(tile->ibufname, ibuf->name)) {
if (mask) {
/* allocate mask if requested */
if (!tile->mask) {
@@ -336,7 +328,7 @@ void ED_image_undo_restore(bContext *C, ListBase *lb)
short use_float;
/* find image based on name, pointer becomes invalid with global undo */
- if (ima && strcmp(tile->idname, ima->id.name) == 0) {
+ if (ima && STREQ(tile->idname, ima->id.name)) {
/* ima is valid */
}
else {
@@ -345,7 +337,7 @@ void ED_image_undo_restore(bContext *C, ListBase *lb)
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- if (ima && ibuf && strcmp(tile->ibufname, ibuf->name) != 0) {
+ if (ima && ibuf && !STREQ(tile->ibufname, ibuf->name)) {
/* current ImBuf filename was changed, probably current frame
* was changed when painting on image sequence, rather than storing
* full image user (which isn't so obvious, btw) try to find ImBuf with
@@ -671,22 +663,24 @@ void paint_brush_color_get(struct Scene *scene, struct Brush *br, bool color_cor
copy_v3_v3(color, BKE_brush_secondary_color_get(scene, br));
else {
if (br->flag & BRUSH_USE_GRADIENT) {
+ float color_gr[4];
switch (br->gradient_stroke_mode) {
case BRUSH_GRADIENT_PRESSURE:
- do_colorband(br->gradient, pressure, color);
+ do_colorband(br->gradient, pressure, color_gr);
break;
case BRUSH_GRADIENT_SPACING_REPEAT:
{
float coord = fmod(distance / br->gradient_spacing, 1.0);
- do_colorband(br->gradient, coord, color);
+ do_colorband(br->gradient, coord, color_gr);
break;
}
case BRUSH_GRADIENT_SPACING_CLAMP:
{
- do_colorband(br->gradient, distance / br->gradient_spacing, color);
+ do_colorband(br->gradient, distance / br->gradient_spacing, color_gr);
break;
}
}
+ copy_v3_v3(color, color_gr);
}
else
copy_v3_v3(color, BKE_brush_color_get(scene, br));
@@ -1065,7 +1059,7 @@ void ED_space_image_paint_update(wmWindowManager *wm, ToolSettings *settings)
enabled = true;
if (enabled) {
- BKE_paint_init(&imapaint->paint, PAINT_CURSOR_TEXTURE_PAINT);
+ BKE_paint_init(&settings->unified_paint_settings, &imapaint->paint, PAINT_CURSOR_TEXTURE_PAINT);
paint_cursor_start_explicit(&imapaint->paint, wm, image_paint_poll);
}
@@ -1422,7 +1416,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
ob->mode |= mode_flag;
- BKE_paint_init(&scene->toolsettings->imapaint.paint, PAINT_CURSOR_TEXTURE_PAINT);
+ BKE_paint_init(&scene->toolsettings->unified_paint_settings, &imapaint->paint, PAINT_CURSOR_TEXTURE_PAINT);
if (U.glreslimit != 0)
GPU_free_images();
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index ea0e30a6635..eb96d1d20d5 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -38,9 +38,7 @@
#include "DNA_space_types.h"
#include "DNA_object_types.h"
-#include "BLI_math.h"
-#include "BLI_rect.h"
#include "BLI_math_color_blend.h"
#include "BLI_stack.h"
#include "BLI_bitmap.h"
@@ -65,7 +63,6 @@
#include "UI_view2d.h"
-#include "RE_shader_ext.h"
#include "GPU_draw.h"
@@ -348,8 +345,8 @@ static unsigned short *brush_painter_curve_mask_new(BrushPainter *painter, int d
{
Brush *brush = painter->brush;
- int xoff = -diameter * 0.5f + 0.5f;
- int yoff = -diameter * 0.5f + 0.5f;
+ int xoff = -radius;
+ int yoff = -radius;
unsigned short *mask, *m;
int x, y;
@@ -362,7 +359,7 @@ static unsigned short *brush_painter_curve_mask_new(BrushPainter *painter, int d
float xy[2] = {x + xoff, y + yoff};
float len = len_v2(xy);
- *m = (unsigned short)(65535.0f * BKE_brush_curve_strength_clamp(brush, len, radius));
+ *m = (unsigned short)(65535.0f * BKE_brush_curve_strength(brush, len, radius));
}
}
@@ -411,11 +408,11 @@ static ImBuf *brush_painter_imbuf_new(BrushPainter *painter, int size, float pre
if (is_texbrush) {
brush_imbuf_tex_co(&tex_mapping, x, y, texco);
BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
- mul_v3_v3(rgba, brush_rgb);
/* TODO(sergey): Support texture paint color space. */
if (!use_float) {
IMB_colormanagement_scene_linear_to_display_v3(rgba, display);
}
+ mul_v3_v3(rgba, brush_rgb);
}
else {
copy_v3_v3(rgba, brush_rgb);
@@ -485,11 +482,11 @@ static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf,
if (is_texbrush) {
brush_imbuf_tex_co(&tex_mapping, x, y, texco);
BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
- mul_v3_v3(rgba, brush_rgb);
/* TODO(sergey): Support texture paint color space. */
if (!use_float) {
IMB_colormanagement_scene_linear_to_display_v3(rgba, display);
}
+ mul_v3_v3(rgba, brush_rgb);
}
else {
copy_v3_v3(rgba, brush_rgb);
@@ -689,7 +686,7 @@ static void brush_painter_2d_refresh_cache(ImagePaintState *s, BrushPainter *pai
bool do_partial_update_mask = false;
/* invalidate case for all mapping modes */
if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
- mask_rotation += ups->brush_rotation;
+ mask_rotation += ups->brush_rotation_sec;
}
else if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM) {
renew_maxmask = true;
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 791c1b3ada1..098f0d04d78 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -50,7 +50,6 @@
#include "BLF_translation.h"
-#include "PIL_time.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -62,8 +61,8 @@
#include "DNA_object_types.h"
#include "BKE_camera.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
+#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_idprop.h"
@@ -80,10 +79,8 @@
#include "BKE_scene.h"
#include "BKE_texture.h"
-#include "UI_view2d.h"
#include "UI_interface.h"
-#include "ED_image.h"
#include "ED_mesh.h"
#include "ED_node.h"
#include "ED_paint.h"
@@ -101,10 +98,12 @@
#include "RNA_enum_types.h"
#include "GPU_draw.h"
-#include "GPU_buffers.h"
#include "IMB_colormanagement.h"
+#include "bmesh.h"
+//#include "bmesh_tools.h"
+
#include "paint_intern.h"
/* Defines and Structs */
@@ -189,7 +188,7 @@ typedef struct ProjPaintImage {
ImagePaintPartialRedraw *partRedrawRect;
volatile void **undoRect; /* only used to build undo tiles during painting */
unsigned short **maskRect; /* the mask accumulation must happen on canvas, not on space screen bucket.
- * Here we store the mask rectangle */
+ * Here we store the mask rectangle */
bool **valid; /* store flag to enforce validation of undo rectangle */
int touch;
} ProjPaintImage;
@@ -205,6 +204,7 @@ typedef struct ProjPaintState {
/* the paint color. It can change depending of inverted mode or not */
float paint_color[3];
float paint_color_linear[3];
+ float dither;
Brush *brush;
short tool, blend, mode;
@@ -215,10 +215,12 @@ typedef struct ProjPaintState {
DerivedMesh *dm;
int dm_totface;
+ int dm_totedge;
int dm_totvert;
int dm_release;
MVert *dm_mvert;
+ MEdge *dm_medge;
MFace *dm_mface;
MTFace **dm_mtface;
MTFace **dm_mtface_clone; /* other UV map, use for cloning between layers */
@@ -251,7 +253,7 @@ typedef struct ProjPaintState {
int image_tot; /* size of projectImages array */
float (*screenCoords)[4]; /* verts projected into floating point screen space */
-
+ float *cavities; /* cavity amount for vertices */
float screenMin[2]; /* 2D bounds for mesh verts on the screen's plane (screenspace) */
float screenMax[2];
float screen_width; /* Calculated from screenMin & screenMax */
@@ -268,6 +270,7 @@ typedef struct ProjPaintState {
bool do_occlude; /* Use raytraced occlusion? - ortherwise will paint right through to the back*/
bool do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
bool do_mask_normal; /* mask out pixels based on their normals */
+ bool do_mask_cavity; /* mask out pixels based on cavity */
bool do_new_shading_nodes; /* cache BKE_scene_use_new_shading_nodes value */
float normal_angle; /* what angle to mask at*/
float normal_angle_inner;
@@ -302,6 +305,7 @@ typedef struct ProjPaintState {
/* redraw */
bool need_redraw;
+ struct CurveMapping *cavity_curve;
BlurKernel *blurkernel;
SpinLock *tile_lock;
@@ -424,17 +428,19 @@ static int project_bucket_offset_safe(const ProjPaintState *ps, const float proj
}
}
-static float VecZDepthOrtho(const float pt[2],
- const float v1[3], const float v2[3], const float v3[3],
- float w[3])
+static float VecZDepthOrtho(
+ const float pt[2],
+ const float v1[3], const float v2[3], const float v3[3],
+ float w[3])
{
barycentric_weights_v2(v1, v2, v3, pt, w);
return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]);
}
-static float VecZDepthPersp(const float pt[2],
- const float v1[4], const float v2[4], const float v3[4],
- float w[3])
+static float VecZDepthPersp(
+ const float pt[2],
+ const float v1[4], const float v2[4], const float v3[4],
+ float w[3])
{
float wtot_inv, wtot;
float w_tmp[3];
@@ -544,8 +550,9 @@ static void uvco_to_wrapped_pxco(const float uv[2], int ibuf_x, int ibuf_y, floa
}
/* Set the top-most face color that the screen space coord 'pt' touches (or return 0 if none touch) */
-static bool project_paint_PickColor(const ProjPaintState *ps, const float pt[2],
- float *rgba_fp, unsigned char *rgba, const bool interp)
+static bool project_paint_PickColor(
+ const ProjPaintState *ps, const float pt[2],
+ float *rgba_fp, unsigned char *rgba, const bool interp)
{
float w[3], uv[2];
int side;
@@ -639,9 +646,10 @@ static bool project_paint_PickColor(const ProjPaintState *ps, const float pt[2],
* 1 : occluded
* 2 : occluded with w[3] weights set (need to know in some cases) */
-static int project_paint_occlude_ptv(const float pt[3],
- const float v1[4], const float v2[4], const float v3[4],
- float w[3], const bool is_ortho)
+static int project_paint_occlude_ptv(
+ const float pt[3],
+ const float v1[4], const float v2[4], const float v3[4],
+ float w[3], const bool is_ortho)
{
/* if all are behind us, return false */
if (v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
@@ -671,9 +679,10 @@ static int project_paint_occlude_ptv(const float pt[3],
}
-static int project_paint_occlude_ptv_clip(const ProjPaintState *ps, const MFace *mf,
- const float pt[3], const float v1[4], const float v2[4], const float v3[4],
- const int side)
+static int project_paint_occlude_ptv_clip(
+ const ProjPaintState *ps, const MFace *mf,
+ const float pt[3], const float v1[4], const float v2[4], const float v3[4],
+ const int side)
{
float w[3], wco[3];
int ret = project_paint_occlude_ptv(pt, v1, v2, v3, w, ps->is_ortho);
@@ -701,8 +710,9 @@ static int project_paint_occlude_ptv_clip(const ProjPaintState *ps, const MFace
/* Check if a screenspace location is occluded by any other faces
* check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison
* and doesn't need to be correct in relation to X and Y coords (this is the case in perspective view) */
-static bool project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *bucketFace,
- const int orig_face, const float pixelScreenCo[4])
+static bool project_bucket_point_occluded(
+ const ProjPaintState *ps, LinkNode *bucketFace,
+ const int orig_face, const float pixelScreenCo[4])
{
MFace *mf;
int face_index;
@@ -914,9 +924,10 @@ static void project_face_winding_init(const ProjPaintState *ps, const int face_i
/* This function returns 1 if this face has a seam along the 2 face-vert indices
* 'orig_i1_fidx' and 'orig_i2_fidx' */
-static bool check_seam(const ProjPaintState *ps,
- const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx,
- int *other_face, int *orig_fidx)
+static bool check_seam(
+ const ProjPaintState *ps,
+ const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx,
+ int *other_face, int *orig_fidx)
{
LinkNode *node;
int face_index;
@@ -994,11 +1005,20 @@ static bool check_seam(const ProjPaintState *ps,
return 1;
}
+#define SMALL_NUMBER 1.e-6f
+BLI_INLINE float shell_v2v2_normal_dir_to_dist(float n[2], float d[2])
+{
+ const float angle_cos = (normalize_v2(n) < SMALL_NUMBER) ? fabsf(dot_v2v2(d, n)) : 0.0f;
+ return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
+}
+#undef SMALL_NUMBER
+
/* Calculate outset UV's, this is not the same as simply scaling the UVs,
* since the outset coords are a margin that keep an even distance from the original UV's,
* note that the image aspect is taken into account */
-static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const float scaler,
- const int ibuf_x, const int ibuf_y, const bool is_quad)
+static void uv_image_outset(
+ float (*orig_uv)[2], float (*outset_uv)[2], const float scaler,
+ const int ibuf_x, const int ibuf_y, const bool is_quad, const bool cw)
{
float a1, a2, a3, a4 = 0.0f;
float puv[4][2]; /* pixelspace uv's */
@@ -1042,26 +1062,34 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl
}
if (is_quad) {
- a1 = shell_v2v2_mid_normalized_to_dist(dir4, dir1);
- a2 = shell_v2v2_mid_normalized_to_dist(dir1, dir2);
- a3 = shell_v2v2_mid_normalized_to_dist(dir2, dir3);
- a4 = shell_v2v2_mid_normalized_to_dist(dir3, dir4);
- }
- else {
- a1 = shell_v2v2_mid_normalized_to_dist(dir3, dir1);
- a2 = shell_v2v2_mid_normalized_to_dist(dir1, dir2);
- a3 = shell_v2v2_mid_normalized_to_dist(dir2, dir3);
- }
+ /* here we just use the orthonormality property (a1, a2) dot (a2, -a1) = 0
+ * to get normals from the edge directions based on the winding */
+ if (cw) {
+ no1[0] = -dir4[1] - dir1[1];
+ no1[1] = dir4[0] + dir1[0];
+ no2[0] = -dir1[1] - dir2[1];
+ no2[1] = dir1[0] + dir2[0];
+ no3[0] = -dir2[1] - dir3[1];
+ no3[1] = dir2[0] + dir3[0];
+ no4[0] = -dir3[1] - dir4[1];
+ no4[1] = dir3[0] + dir4[0];
+ }
+ else {
+ no1[0] = dir4[1] + dir1[1];
+ no1[1] = -dir4[0] - dir1[0];
+ no2[0] = dir1[1] + dir2[1];
+ no2[1] = -dir1[0] - dir2[0];
+ no3[0] = dir2[1] + dir3[1];
+ no3[1] = -dir2[0] - dir3[0];
+ no4[0] = dir3[1] + dir4[1];
+ no4[1] = -dir3[0] - dir4[0];
+ }
+
+ a1 = shell_v2v2_normal_dir_to_dist(no1, dir4);
+ a2 = shell_v2v2_normal_dir_to_dist(no2, dir1);
+ a3 = shell_v2v2_normal_dir_to_dist(no3, dir2);
+ a4 = shell_v2v2_normal_dir_to_dist(no4, dir3);
- if (is_quad) {
- sub_v2_v2v2(no1, dir4, dir1);
- sub_v2_v2v2(no2, dir1, dir2);
- sub_v2_v2v2(no3, dir2, dir3);
- sub_v2_v2v2(no4, dir3, dir4);
- normalize_v2(no1);
- normalize_v2(no2);
- normalize_v2(no3);
- normalize_v2(no4);
mul_v2_fl(no1, a1 * scaler);
mul_v2_fl(no2, a2 * scaler);
mul_v2_fl(no3, a3 * scaler);
@@ -1076,12 +1104,27 @@ static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const fl
mul_v2_v2(outset_uv[3], ibuf_inv);
}
else {
- sub_v2_v2v2(no1, dir3, dir1);
- sub_v2_v2v2(no2, dir1, dir2);
- sub_v2_v2v2(no3, dir2, dir3);
- normalize_v2(no1);
- normalize_v2(no2);
- normalize_v2(no3);
+ if (cw) {
+ no1[0] = -dir3[1] - dir1[1];
+ no1[1] = dir3[0] + dir1[0];
+ no2[0] = -dir1[1] - dir2[1];
+ no2[1] = dir1[0] + dir2[0];
+ no3[0] = -dir2[1] - dir3[1];
+ no3[1] = dir2[0] + dir3[0];
+ }
+ else {
+ no1[0] = dir3[1] + dir1[1];
+ no1[1] = -dir3[0] - dir1[0];
+ no2[0] = dir1[1] + dir2[1];
+ no2[1] = -dir1[0] - dir2[0];
+ no3[0] = dir2[1] + dir3[1];
+ no3[1] = -dir2[0] - dir3[0];
+ }
+
+ a1 = shell_v2v2_normal_dir_to_dist(no1, dir3);
+ a2 = shell_v2v2_normal_dir_to_dist(no2, dir1);
+ a3 = shell_v2v2_normal_dir_to_dist(no3, dir2);
+
mul_v2_fl(no1, a1 * scaler);
mul_v2_fl(no2, a2 * scaler);
mul_v2_fl(no3, a3 * scaler);
@@ -1183,8 +1226,9 @@ static void screen_px_from_persp(
}
-static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3],
- int side, unsigned char rgba_ub[4], float rgba_f[4])
+static void project_face_pixel(
+ const MTFace *tf_other, ImBuf *ibuf_other, const float w[3],
+ int side, unsigned char rgba_ub[4], float rgba_f[4])
{
const float *uvCo1, *uvCo2, *uvCo3;
float uv_other[2], x, y;
@@ -1261,6 +1305,25 @@ static float project_paint_uvpixel_mask(
mask = 1.0f;
}
+ if (ps->do_mask_cavity) {
+ MFace *mf = &ps->dm_mface[face_index];
+ float ca1, ca2, ca3, ca_mask;
+ ca1 = ps->cavities[mf->v1];
+ if (side == 1) {
+ ca2 = ps->cavities[mf->v3];
+ ca3 = ps->cavities[mf->v4];
+ }
+ else {
+ ca2 = ps->cavities[mf->v2];
+ ca3 = ps->cavities[mf->v3];
+ }
+
+ ca_mask = w[0] * ca1 + w[1] * ca2 + w[2] * ca3;
+ ca_mask = curvemapping_evaluateF(ps->cavity_curve, 0, ca_mask);
+ CLAMP(ca_mask, 0.0f, 1.0f);
+ mask *= ca_mask;
+ }
+
/* calculate mask */
if (ps->do_mask_normal) {
MFace *mf = &ps->dm_mface[face_index];
@@ -1305,7 +1368,7 @@ static float project_paint_uvpixel_mask(
/* now we can use the normal as a mask */
if (ps->is_ortho) {
- angle = angle_normalized_v3v3((float *)ps->viewDir, no);
+ angle = angle_normalized_v3v3(ps->viewDir, no);
}
else {
/* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */
@@ -1425,7 +1488,7 @@ static ProjPixel *project_paint_uvpixel_init(
y_px = mod_i(y_px, ibuf->y);
BLI_assert(ps->pixel_sizeof == project_paint_pixel_sizeof(ps->tool));
- projPixel = (ProjPixel *)BLI_memarena_alloc(arena, ps->pixel_sizeof);
+ projPixel = BLI_memarena_alloc(arena, ps->pixel_sizeof);
/* calculate the undo tile offset of the pixel, used to store the original
* pixel color and accumulated mask if any */
@@ -1556,7 +1619,7 @@ static ProjPixel *project_paint_uvpixel_init(
}
static bool line_clip_rect2f(
- rctf *rect,
+ const rctf *rect,
const float l1[2], const float l2[2],
float l1_clip[2], float l2_clip[2])
{
@@ -1771,7 +1834,7 @@ static float len_squared_v2v2_alt(const float v1[2], const float v2_1, const flo
/* note, use a squared value so we can use len_squared_v2v2
* be sure that you have done a bounds check first or this may fail */
/* only give bucket_bounds as an arg because we need it elsewhere */
-static bool project_bucket_isect_circle(const float cent[2], const float radius_squared, rctf *bucket_bounds)
+static bool project_bucket_isect_circle(const float cent[2], const float radius_squared, const rctf *bucket_bounds)
{
/* Would normally to a simple intersection test, however we know the bounds of these 2 already intersect
@@ -1826,7 +1889,7 @@ static bool project_bucket_isect_circle(const float cent[2], const float radius_
* however switching back to this for ortho is always an option */
static void rect_to_uvspace_ortho(
- rctf *bucket_bounds,
+ const rctf *bucket_bounds,
const float *v1coSS, const float *v2coSS, const float *v3coSS,
const float *uv1co, const float *uv2co, const float *uv3co,
float bucket_bounds_uv[4][2],
@@ -1859,7 +1922,7 @@ static void rect_to_uvspace_ortho(
/* same as above but use barycentric_weights_v2_persp */
static void rect_to_uvspace_persp(
- rctf *bucket_bounds,
+ const rctf *bucket_bounds,
const float *v1coSS, const float *v2coSS, const float *v3coSS,
const float *uv1co, const float *uv2co, const float *uv3co,
float bucket_bounds_uv[4][2],
@@ -1933,27 +1996,86 @@ static int float_z_sort(const void *p1, const void *p2)
return (((float *)p1)[2] < ((float *)p2)[2] ? -1 : 1);
}
+/* assumes one point is within the rectangle */
+static bool line_rect_clip(
+ const rctf *rect,
+ const float l1[4], const float l2[4],
+ const float uv1[2], const float uv2[2],
+ float uv[2], bool is_ortho)
+{
+ float min = FLT_MAX, tmp;
+ float xlen = l2[0] - l1[0];
+ float ylen = l2[1] - l1[1];
+
+ /* 0.1 might seem too much, but remember, this is pixels! */
+ if (xlen > 0.1f) {
+ if ((l1[0] - rect->xmin) * (l2[0] - rect->xmin) <= 0) {
+ tmp = rect->xmin;
+ min = min_ff((tmp - l1[0]) / xlen, min);
+ }
+ else if ((l1[0] - rect->xmax) * (l2[0] - rect->xmax) < 0) {
+ tmp = rect->xmax;
+ min = min_ff((tmp - l1[0]) / xlen, min);
+ }
+ }
+
+ if (ylen > 0.1f) {
+ if ((l1[1] - rect->ymin) * (l2[1] - rect->ymin) <= 0) {
+ tmp = rect->ymin;
+ min = min_ff((tmp - l1[1]) / ylen, min);
+ }
+ else if ((l1[1] - rect->ymax) * (l2[1] - rect->ymax) < 0) {
+ tmp = rect->ymax;
+ min = min_ff((tmp - l1[1]) / ylen, min);
+ }
+ }
+
+ if (min == FLT_MAX)
+ return false;
+
+ tmp = (is_ortho) ? 1.0f : (l1[3] + min * (l2[3] - l1[3]));
+
+ uv[0] = (uv1[0] + min / tmp * (uv2[0] - uv1[0]));
+ uv[1] = (uv1[1] + min / tmp * (uv2[1] - uv1[1]));
+
+ return true;
+}
+
+
static void project_bucket_clip_face(
const bool is_ortho,
- rctf *bucket_bounds,
+ const rctf *bucket_bounds,
float *v1coSS, float *v2coSS, float *v3coSS,
const float *uv1co, const float *uv2co, const float *uv3co,
float bucket_bounds_uv[8][2],
- int *tot)
+ int *tot, bool cull)
{
int inside_bucket_flag = 0;
int inside_face_flag = 0;
- const int flip = ((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) != (line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
-
+ int flip;
+ bool colinear = false;
+
float bucket_bounds_ss[4][2];
+ /* detect pathological case where face the three vertices are almost colinear in screen space.
+ * mostly those will be culled but when flood filling or with smooth shading it's a possibility */
+ if (dist_squared_to_line_v2(v1coSS, v2coSS, v3coSS) < 0.5f ||
+ dist_squared_to_line_v2(v2coSS, v3coSS, v1coSS) < 0.5f)
+ {
+ colinear = true;
+ }
+
/* get the UV space bounding box */
inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v1coSS);
inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v2coSS) << 1;
inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v3coSS) << 2;
-
+
if (inside_bucket_flag == ISECT_ALL3) {
- /* all screenspace points are inside the bucket bounding box, this means we don't need to clip and can simply return the UVs */
+ flip = ((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) !=
+ (line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
+
+ /* all screenspace points are inside the bucket bounding box,
+ * this means we don't need to clip and can simply return the UVs */
if (flip) { /* facing the back? */
copy_v2_v2(bucket_bounds_uv[0], uv3co);
copy_v2_v2(bucket_bounds_uv[1], uv2co);
@@ -1963,9 +2085,55 @@ static void project_bucket_clip_face(
copy_v2_v2(bucket_bounds_uv[0], uv1co);
copy_v2_v2(bucket_bounds_uv[1], uv2co);
copy_v2_v2(bucket_bounds_uv[2], uv3co);
+ }
+
+ *tot = 3;
+ return;
+ }
+ /* handle pathological case here, no need for further intersections below since tringle area is almost zero */
+ if (colinear) {
+ int flag;
+
+ (*tot) = 0;
+
+ if (cull)
+ return;
+
+ if (inside_bucket_flag & ISECT_1) { copy_v2_v2(bucket_bounds_uv[*tot], uv1co); (*tot)++; }
+
+ flag = inside_bucket_flag & (ISECT_1 | ISECT_2);
+ if (flag && flag != (ISECT_1 | ISECT_2)) {
+ if (line_rect_clip(bucket_bounds, v1coSS, v2coSS, uv1co, uv2co, bucket_bounds_uv[*tot], is_ortho))
+ (*tot)++;
+ }
+
+ if (inside_bucket_flag & ISECT_2) { copy_v2_v2(bucket_bounds_uv[*tot], uv2co); (*tot)++; }
+
+ flag = inside_bucket_flag & (ISECT_2 | ISECT_3);
+ if (flag && flag != (ISECT_2 | ISECT_3)) {
+ if (line_rect_clip(bucket_bounds, v2coSS, v3coSS, uv2co, uv3co, bucket_bounds_uv[*tot], is_ortho))
+ (*tot)++;
+ }
+
+ if (inside_bucket_flag & ISECT_3) { copy_v2_v2(bucket_bounds_uv[*tot], uv3co); (*tot)++; }
+
+ flag = inside_bucket_flag & (ISECT_3 | ISECT_1);
+ if (flag && flag != (ISECT_3 | ISECT_1)) {
+ if (line_rect_clip(bucket_bounds, v3coSS, v1coSS, uv3co, uv1co, bucket_bounds_uv[*tot], is_ortho))
+ (*tot)++;
+ }
+
+ if ((*tot) < 3) {
+ /* no intersections to speak of, but more probable is that all face is just outside the
+ * rectangle and culled due to float precision issues. Since above teste have failed,
+ * just dump triangle as is for painting */
+ *tot = 0;
+ copy_v2_v2(bucket_bounds_uv[*tot], uv1co); (*tot)++;
+ copy_v2_v2(bucket_bounds_uv[*tot], uv2co); (*tot)++;
+ copy_v2_v2(bucket_bounds_uv[*tot], uv3co); (*tot)++;
+ return;
}
- *tot = 3;
return;
}
@@ -1987,6 +2155,9 @@ static void project_bucket_clip_face(
bucket_bounds_ss[3][1] = bucket_bounds->ymin;
inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[3], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_4 : 0);
+ flip = ((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) !=
+ (line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
+
if (inside_face_flag == ISECT_ALL4) {
/* bucket is totally inside the screenspace face, we can safely use weights */
@@ -2088,53 +2259,39 @@ static void project_bucket_clip_face(
for (i = 0; i < (*tot); i++) {
v2_clipSS[0] = isectVCosSS[i][0] - cent[0];
v2_clipSS[1] = isectVCosSS[i][1] - cent[1];
- isectVCosSS[i][2] = atan2f(v1_clipSS[0] * v2_clipSS[1] - v1_clipSS[1] * v2_clipSS[0], v1_clipSS[0] * v2_clipSS[0] + v1_clipSS[1] * v2_clipSS[1]);
+ isectVCosSS[i][2] = atan2f(v1_clipSS[0] * v2_clipSS[1] - v1_clipSS[1] * v2_clipSS[0],
+ v1_clipSS[0] * v2_clipSS[0] + v1_clipSS[1] * v2_clipSS[1]);
}
if (flip) qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort_flip);
else qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort);
- /* remove doubles */
- /* first/last check */
- if (fabsf(isectVCosSS[0][0] - isectVCosSS[(*tot) - 1][0]) < PROJ_PIXEL_TOLERANCE &&
- fabsf(isectVCosSS[0][1] - isectVCosSS[(*tot) - 1][1]) < PROJ_PIXEL_TOLERANCE)
- {
- (*tot)--;
- }
-
- /* its possible there is only a few left after remove doubles */
- if ((*tot) < 3) {
- // printf("removed too many doubles A\n");
- *tot = 0;
- return;
- }
-
doubles = true;
while (doubles == true) {
doubles = false;
- for (i = 1; i < (*tot); i++) {
- if (fabsf(isectVCosSS[i - 1][0] - isectVCosSS[i][0]) < PROJ_PIXEL_TOLERANCE &&
- fabsf(isectVCosSS[i - 1][1] - isectVCosSS[i][1]) < PROJ_PIXEL_TOLERANCE)
+
+ for (i = 0; i < (*tot); i++) {
+ if (fabsf(isectVCosSS[(i + 1) % *tot][0] - isectVCosSS[i][0]) < PROJ_PIXEL_TOLERANCE &&
+ fabsf(isectVCosSS[(i + 1) % *tot][1] - isectVCosSS[i][1]) < PROJ_PIXEL_TOLERANCE)
{
int j;
- for (j = i + 1; j < (*tot); j++) {
- isectVCosSS[j - 1][0] = isectVCosSS[j][0];
- isectVCosSS[j - 1][1] = isectVCosSS[j][1];
+ for (j = i; j < (*tot) - 1; j++) {
+ isectVCosSS[j][0] = isectVCosSS[j + 1][0];
+ isectVCosSS[j][1] = isectVCosSS[j + 1][1];
}
doubles = true; /* keep looking for more doubles */
(*tot)--;
}
}
+
+ /* its possible there is only a few left after remove doubles */
+ if ((*tot) < 3) {
+ // printf("removed too many doubles B\n");
+ *tot = 0;
+ return;
+ }
}
- /* its possible there is only a few left after remove doubles */
- if ((*tot) < 3) {
- // printf("removed too many doubles B\n");
- *tot = 0;
- return;
- }
-
-
if (is_ortho) {
for (i = 0; i < (*tot); i++) {
barycentric_weights_v2(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
@@ -2158,7 +2315,9 @@ static void project_bucket_clip_face(
int i;
if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
- printf("( [(%f,%f), (%f,%f), (%f,%f), (%f,%f)], ", test_uv[0][0], test_uv[0][1], test_uv[1][0], test_uv[1][1], test_uv[2][0], test_uv[2][1], test_uv[3][0], test_uv[3][1]);
+ printf("( [(%f,%f), (%f,%f), (%f,%f), (%f,%f)], ",
+ test_uv[0][0], test_uv[0][1], test_uv[1][0], test_uv[1][1],
+ test_uv[2][0], test_uv[2][1], test_uv[3][0], test_uv[3][1]);
printf(" [(%f,%f), (%f,%f), (%f,%f)], ", uv1co[0], uv1co[1], uv2co[0], uv2co[1], uv3co[0], uv3co[1]);
@@ -2256,9 +2415,15 @@ static bool IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot
return 1;
}
-/* One of the most important function for projection painting, since it selects the pixels to be added into each bucket.
- * initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */
-static void project_paint_face_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const int face_index, const int image_index, rctf *bucket_bounds, ImBuf *ibuf, ImBuf **tmpibuf, const short clamp_u, const short clamp_v)
+/* One of the most important function for projection painting,
+ * since it selects the pixels to be added into each bucket.
+ *
+ * initialize pixels from this face where it intersects with the bucket_index,
+ * optionally initialize pixels for removing seams */
+static void project_paint_face_init(
+ const ProjPaintState *ps,
+ const int thread_index, const int bucket_index, const int face_index, const int image_index,
+ const rctf *bucket_bounds, ImBuf *ibuf, ImBuf **tmpibuf, const short clamp_u, const short clamp_v)
{
/* Projection vars, to get the 3D locations into screen space */
MemArena *arena = ps->arena_mt[thread_index];
@@ -2372,8 +2537,8 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
is_ortho, bucket_bounds,
v1coSS, v2coSS, v3coSS,
uv1co, uv2co, uv3co,
- uv_clip, &uv_clip_tot
- );
+ uv_clip, &uv_clip_tot,
+ ps->do_backfacecull || ps->do_occlude);
/* sometimes this happens, better just allow for 8 intersectiosn even though there should be max 6 */
#if 0
@@ -2394,10 +2559,10 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
CLAMP(bounds_px.ymax, 0, ibuf->y);
}
- /*
+#if 0
project_paint_undo_tiles_init(&bounds_px, ps->projImages + image_index, tmpibuf,
tile_width, threaded, ps->do_masking);
- */
+#endif
/* clip face and */
has_isect = 0;
@@ -2511,9 +2676,8 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
float seam_subsection[4][2];
float fac1, fac2, ftot;
-
if (outset_uv[0][0] == FLT_MAX) /* first time initialize */
- uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4 != 0);
+ uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4 != 0, (ps->faceWindingFlags[face_index] & PROJ_FACE_WINDING_CW) == 0);
/* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */
if (threaded)
@@ -2723,7 +2887,7 @@ static void project_bucket_bounds(const ProjPaintState *ps, const int bucket_x,
/* Fill this bucket with pixels from the faces that intersect it.
*
* have bucket_bounds as an argument so we don't need to give bucket_x/y the rect function needs */
-static void project_bucket_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, rctf *bucket_bounds)
+static void project_bucket_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const rctf *bucket_bounds)
{
LinkNode *node;
int face_index, image_index = 0;
@@ -2788,7 +2952,7 @@ static bool project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int buck
int fidx;
project_bucket_bounds(ps, bucket_x, bucket_y, &bucket_bounds);
-
+
/* Is one of the faces verts in the bucket bounds? */
fidx = mf->v4 ? 3 : 2;
@@ -2899,145 +3063,9 @@ static void project_paint_delayed_face_init(ProjPaintState *ps, const MFace *mf,
#endif
}
-/* run once per stroke before projection painting */
-static void project_paint_begin(ProjPaintState *ps)
+/* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */
+static void proj_paint_state_non_cddm_init(ProjPaintState *ps)
{
- /* Viewport vars */
- float mat[3][3];
-
- float no[3];
-
- float *projScreenCo; /* Note, we could have 4D vectors are only needed for */
- float projMargin;
-
- /* Image Vars - keep track of images we have used */
- LinkNode *image_LinkList = NULL;
- LinkNode *node;
-
- ProjPaintImage *projIma;
- Image *tpage_last = NULL, *tpage;
- TexPaintSlot *slot_last = NULL, *slot = NULL;
- TexPaintSlot *slot_last_clone = NULL, *slot_clone;
-
- /* Face vars */
- MPoly *mpoly_orig;
- MFace *mf;
- MTFace **tf;
- MTFace *tf_base;
-
- MTFace **tf_clone;
- MTFace *tf_clone_base = NULL;
-
- int a, i; /* generic looping vars */
- int image_index = -1, face_index;
-
- /* double lookup */
- const int *index_mf_to_mpoly = NULL;
- const int *index_mp_to_orig = NULL;
-
- MVert *mv;
-
- MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
-
- const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
-
- bool reset_threads = false;
-
- /* ---- end defines ---- */
-
- if (ps->source == PROJ_SRC_VIEW)
- ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat); /* faster clipping lookups */
-
- ps->do_face_sel = ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) != 0);
-
- /* paint onto the derived mesh */
-
- /* Workaround for subsurf selection, try the display mesh first */
- if (ps->source == PROJ_SRC_IMAGE_CAM) {
- /* using render mesh, assume only camera was rendered from */
- ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
- ps->dm_release = true;
- }
- else if (ps->ob->derivedFinal &&
- CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE) &&
- (ps->do_face_sel == false || CustomData_has_layer(&ps->ob->derivedFinal->polyData, CD_ORIGINDEX)))
- {
- ps->dm = ps->ob->derivedFinal;
- ps->dm_release = false;
- }
- else {
- ps->dm = mesh_get_derived_final(
- ps->scene, ps->ob,
- ps->scene->customdata_mask | CD_MASK_MTFACE | (ps->do_face_sel ? CD_ORIGINDEX : 0));
- ps->dm_release = true;
- }
-
- if (!CustomData_has_layer(&ps->dm->faceData, CD_MTFACE)) {
-
- if (ps->dm_release)
- ps->dm->release(ps->dm);
-
- ps->dm = NULL;
- return;
- }
-
- DM_update_materials(ps->dm, ps->ob);
-
- ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
- ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
-
- ps->dm_mvert = ps->dm->getVertArray(ps->dm);
- ps->dm_mface = ps->dm->getTessFaceArray(ps->dm);
- ps->dm_mtface = MEM_mallocN(ps->dm_totface * sizeof(MTFace *), "proj_paint_mtfaces");
-
- if (ps->do_face_sel) {
- index_mf_to_mpoly = ps->dm->getTessFaceDataArray(ps->dm, CD_ORIGINDEX);
- index_mp_to_orig = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX);
- if (index_mf_to_mpoly == NULL) {
- index_mp_to_orig = NULL;
- }
- else {
- mpoly_orig = ((Mesh *)ps->ob->data)->mpoly;
- }
- }
- else {
- mpoly_orig = NULL;
- }
-
- /* use clone mtface? */
- if (ps->do_layer_clone) {
- ps->dm_mtface_clone = MEM_mallocN(ps->dm_totface * sizeof(MTFace *), "proj_paint_mtfaces");
- }
-
- if (ps->do_layer_stencil || ps->do_stencil_brush) {
- //int layer_num = CustomData_get_stencil_layer(&ps->dm->faceData, CD_MTFACE);
- int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY);
- if (layer_num != -1)
- ps->dm_mtface_stencil = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
-
- if (ps->dm_mtface_stencil == NULL) {
- /* get active instead */
- ps->dm_mtface_stencil = CustomData_get_layer(&ps->dm->faceData, CD_MTFACE);
- }
-
- if (ps->do_stencil_brush)
- tf_base = ps->dm_mtface_stencil;
- }
-
- if (ps->do_layer_clone) {
- int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY);
-
- if (layer_num != -1)
- tf_clone_base = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
-
- if (tf_clone_base == NULL) {
- /* get active instead */
- tf_clone_base = CustomData_get_layer(&ps->dm->faceData, CD_MTFACE);
- }
-
- }
-
- /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */
if (ps->dm->type != DM_TYPE_CDDM) {
ps->dm_mvert = MEM_dupallocN(ps->dm_mvert);
ps->dm_mface = MEM_dupallocN(ps->dm_mface);
@@ -3048,97 +3076,108 @@ static void project_paint_begin(ProjPaintState *ps)
ps->dm_mtface_stencil = MEM_dupallocN(ps->dm_mtface_stencil);
#endif
}
+}
+
+static void proj_paint_state_viewport_init(ProjPaintState *ps)
+{
+ float mat[3][3];
+ float viewmat[4][4];
+ float viewinv[4][4];
ps->viewDir[0] = 0.0f;
ps->viewDir[1] = 0.0f;
ps->viewDir[2] = 1.0f;
- {
- float viewmat[4][4];
- float viewinv[4][4];
+ invert_m4_m4(ps->ob->imat, ps->ob->obmat);
- invert_m4_m4(ps->ob->imat, ps->ob->obmat);
+ if (ELEM(ps->source, PROJ_SRC_VIEW, PROJ_SRC_VIEW_FILL)) {
+ /* normal drawing */
+ ps->winx = ps->ar->winx;
+ ps->winy = ps->ar->winy;
- if (ps->source == PROJ_SRC_VIEW) {
- /* normal drawing */
- ps->winx = ps->ar->winx;
- ps->winy = ps->ar->winy;
+ copy_m4_m4(viewmat, ps->rv3d->viewmat);
+ copy_m4_m4(viewinv, ps->rv3d->viewinv);
- copy_m4_m4(viewmat, ps->rv3d->viewmat);
- copy_m4_m4(viewinv, ps->rv3d->viewinv);
+ ED_view3d_ob_project_mat_get(ps->rv3d, ps->ob, ps->projectMat);
- ED_view3d_ob_project_mat_get(ps->rv3d, ps->ob, ps->projectMat);
+ ps->is_ortho = ED_view3d_clip_range_get(ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend, true);
+ }
+ else {
+ /* re-projection */
+ float winmat[4][4];
+ float vmat[4][4];
- ps->is_ortho = ED_view3d_clip_range_get(ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend, true);
- }
- else {
- /* re-projection */
- float winmat[4][4];
- float vmat[4][4];
+ ps->winx = ps->reproject_ibuf->x;
+ ps->winy = ps->reproject_ibuf->y;
- ps->winx = ps->reproject_ibuf->x;
- ps->winy = ps->reproject_ibuf->y;
+ if (ps->source == PROJ_SRC_IMAGE_VIEW) {
+ /* image stores camera data, tricky */
+ IDProperty *idgroup = IDP_GetProperties(&ps->reproject_image->id, 0);
+ IDProperty *view_data = IDP_GetPropertyFromGroup(idgroup, PROJ_VIEW_DATA_ID);
- if (ps->source == PROJ_SRC_IMAGE_VIEW) {
- /* image stores camera data, tricky */
- IDProperty *idgroup = IDP_GetProperties(&ps->reproject_image->id, 0);
- IDProperty *view_data = IDP_GetPropertyFromGroup(idgroup, PROJ_VIEW_DATA_ID);
+ const float *array = (float *)IDP_Array(view_data);
- const float *array = (float *)IDP_Array(view_data);
+ /* use image array, written when creating image */
+ memcpy(winmat, array, sizeof(winmat)); array += sizeof(winmat) / sizeof(float);
+ memcpy(viewmat, array, sizeof(viewmat)); array += sizeof(viewmat) / sizeof(float);
+ ps->clipsta = array[0];
+ ps->clipend = array[1];
+ ps->is_ortho = array[2] ? 1 : 0;
- /* use image array, written when creating image */
- memcpy(winmat, array, sizeof(winmat)); array += sizeof(winmat) / sizeof(float);
- memcpy(viewmat, array, sizeof(viewmat)); array += sizeof(viewmat) / sizeof(float);
- ps->clipsta = array[0];
- ps->clipend = array[1];
- ps->is_ortho = array[2] ? 1 : 0;
+ invert_m4_m4(viewinv, viewmat);
+ }
+ else if (ps->source == PROJ_SRC_IMAGE_CAM) {
+ Object *cam_ob = ps->scene->camera;
+ CameraParams params;
+
+ /* viewmat & viewinv */
+ copy_m4_m4(viewinv, cam_ob->obmat);
+ normalize_m4(viewinv);
+ invert_m4_m4(viewmat, viewinv);
+
+ /* window matrix, clipping and ortho */
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_object(&params, cam_ob);
+ BKE_camera_params_compute_viewplane(&params, ps->winx, ps->winy, 1.0f, 1.0f);
+ BKE_camera_params_compute_matrix(&params);
+
+ copy_m4_m4(winmat, params.winmat);
+ ps->clipsta = params.clipsta;
+ ps->clipend = params.clipend;
+ ps->is_ortho = params.is_ortho;
+ }
+ else {
+ BLI_assert(0);
+ }
- invert_m4_m4(viewinv, viewmat);
- }
- else if (ps->source == PROJ_SRC_IMAGE_CAM) {
- Object *cam_ob = ps->scene->camera;
- CameraParams params;
-
- /* viewmat & viewinv */
- copy_m4_m4(viewinv, cam_ob->obmat);
- normalize_m4(viewinv);
- invert_m4_m4(viewmat, viewinv);
-
- /* window matrix, clipping and ortho */
- BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, cam_ob);
- BKE_camera_params_compute_viewplane(&params, ps->winx, ps->winy, 1.0f, 1.0f);
- BKE_camera_params_compute_matrix(&params);
-
- copy_m4_m4(winmat, params.winmat);
- ps->clipsta = params.clipsta;
- ps->clipend = params.clipend;
- ps->is_ortho = params.is_ortho;
- }
+ /* same as #ED_view3d_ob_project_mat_get */
+ mul_m4_m4m4(vmat, viewmat, ps->ob->obmat);
+ mul_m4_m4m4(ps->projectMat, winmat, vmat);
+ }
- /* same as #ED_view3d_ob_project_mat_get */
- mul_m4_m4m4(vmat, viewmat, ps->ob->obmat);
- mul_m4_m4m4(ps->projectMat, winmat, vmat);
- }
+ /* viewDir - object relative */
+ invert_m4_m4(ps->ob->imat, ps->ob->obmat);
+ copy_m3_m4(mat, viewinv);
+ mul_m3_v3(mat, ps->viewDir);
+ copy_m3_m4(mat, ps->ob->imat);
+ mul_m3_v3(mat, ps->viewDir);
+ normalize_v3(ps->viewDir);
- /* viewDir - object relative */
- invert_m4_m4(ps->ob->imat, ps->ob->obmat);
- copy_m3_m4(mat, viewinv);
- mul_m3_v3(mat, ps->viewDir);
- copy_m3_m4(mat, ps->ob->imat);
- mul_m3_v3(mat, ps->viewDir);
- normalize_v3(ps->viewDir);
+ /* viewPos - object relative */
+ copy_v3_v3(ps->viewPos, viewinv[3]);
+ copy_m3_m4(mat, ps->ob->imat);
+ mul_m3_v3(mat, ps->viewPos);
+ add_v3_v3(ps->viewPos, ps->ob->imat[3]);
+}
- /* viewPos - object relative */
- copy_v3_v3(ps->viewPos, viewinv[3]);
- copy_m3_m4(mat, ps->ob->imat);
- mul_m3_v3(mat, ps->viewPos);
- add_v3_v3(ps->viewPos, ps->ob->imat[3]);
- }
+static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int diameter)
+{
+ MVert *mv;
+ float *projScreenCo;
+ float projMargin;
+ int a;
- /* calculate vert screen coords
- * run this early so we can calculate the x/y resolution of our bucket rect */
INIT_MINMAX2(ps->screenMin, ps->screenMax);
ps->screenCoords = MEM_mallocN(sizeof(float) * ps->dm_totvert * 4, "ProjectPaint ScreenVerts");
@@ -3179,7 +3218,7 @@ static void project_paint_begin(ProjPaintState *ps)
}
/* If this border is not added we get artifacts for faces that
- * have a parallel edge and at the bounds of the the 2D projected verts eg
+ * have a parallel edge and at the bounds of the 2D projected verts eg
* - a single screen aligned quad */
projMargin = (ps->screenMax[0] - ps->screenMin[0]) * 0.000001f;
ps->screenMax[0] += projMargin;
@@ -3197,45 +3236,70 @@ static void project_paint_begin(ProjPaintState *ps)
CLAMP(ps->screenMax[1], (float)(-diameter), (float)(ps->winy + diameter));
#endif
}
- else { /* re-projection, use bounds */
+ else if (ps->source != PROJ_SRC_VIEW_FILL) { /* re-projection, use bounds */
ps->screenMin[0] = 0;
ps->screenMax[0] = (float)(ps->winx);
ps->screenMin[1] = 0;
ps->screenMax[1] = (float)(ps->winy);
}
+}
- /* only for convenience */
- ps->screen_width = ps->screenMax[0] - ps->screenMin[0];
- ps->screen_height = ps->screenMax[1] - ps->screenMin[1];
-
- ps->buckets_x = (int)(ps->screen_width / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
- ps->buckets_y = (int)(ps->screen_height / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
+static void proj_paint_state_cavity_init(ProjPaintState *ps)
+{
+ MVert *mv;
+ MEdge *me;
+ float *cavities;
+ int a;
- /* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */
+ if (ps->do_mask_cavity) {
+ int *counter = MEM_callocN(sizeof(int) * ps->dm_totvert, "counter");
+ float (*edges)[3] = MEM_callocN(sizeof(float) * 3 * ps->dm_totvert, "edges");
+ ps->cavities = MEM_mallocN(sizeof(float) * ps->dm_totvert, "ProjectPaint Cavities");
+ cavities = ps->cavities;
+
+ for (a = 0, me = ps->dm_medge; a < ps->dm_totedge; a++, me++) {
+ float e[3];
+ sub_v3_v3v3(e, ps->dm_mvert[me->v1].co, ps->dm_mvert[me->v2].co);
+ normalize_v3(e);
+ add_v3_v3(edges[me->v2], e);
+ counter[me->v2]++;
+ sub_v3_v3(edges[me->v1], e);
+ counter[me->v1]++;
+ }
+ for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++) {
+ if (counter[a] > 0) {
+ float no[3];
+ mul_v3_fl(edges[a], 1.0f / counter[a]);
+ normal_short_to_float_v3(no, mv->no);
+ /* augment the diffe*/
+ cavities[a] = saacos(10.0f * dot_v3v3(no, edges[a])) * (float)M_1_PI;
+ }
+ else
+ cavities[a] = 0.0;
+ }
- if (ps->buckets_x > PROJ_BUCKET_RECT_MAX || ps->buckets_y > PROJ_BUCKET_RECT_MAX) {
- reset_threads = true;
+ MEM_freeN(counter);
+ MEM_freeN(edges);
}
+}
- /* really high values could cause problems since it has to allocate a few
- * (ps->buckets_x*ps->buckets_y) sized arrays */
- CLAMP(ps->buckets_x, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
- CLAMP(ps->buckets_y, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
-
- ps->bucketRect = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketRect");
- ps->bucketFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
-
- ps->bucketFlags = (unsigned char *)MEM_callocN(sizeof(char) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
#ifndef PROJ_DEBUG_NOSEAMBLEED
+static void proj_paint_state_seam_bleed_init(ProjPaintState *ps)
+{
if (ps->seam_bleed_px > 0.0f) {
- ps->vertFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->dm_totvert, "paint-vertFaces");
- ps->faceSeamFlags = (char *)MEM_callocN(sizeof(char) * ps->dm_totface, "paint-faceSeamFlags");
- ps->faceWindingFlags = (char *)MEM_callocN(sizeof(char) * ps->dm_totface, "paint-faceWindindFlags");
+ ps->vertFaces = MEM_callocN(sizeof(LinkNode *) * ps->dm_totvert, "paint-vertFaces");
+ ps->faceSeamFlags = MEM_callocN(sizeof(char) * ps->dm_totface, "paint-faceSeamFlags");
+ ps->faceWindingFlags = MEM_callocN(sizeof(char) * ps->dm_totface, "paint-faceWindindFlags");
ps->faceSeamUVs = MEM_mallocN(sizeof(float) * ps->dm_totface * 8, "paint-faceSeamUVs");
}
+}
#endif
+static void proj_paint_state_thread_init(ProjPaintState *ps, const bool reset_threads)
+{
+ int a;
+
/* Thread stuff
*
* very small brushes run a lot slower multithreaded since the advantage with
@@ -3259,11 +3323,15 @@ static void project_paint_begin(ProjPaintState *ps)
for (a = 0; a < ps->thread_tot; a++) {
ps->arena_mt[a] = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "project paint arena");
}
+}
- arena = ps->arena_mt[0];
-
+static void proj_paint_state_vert_flags_init(ProjPaintState *ps)
+{
if (ps->do_backfacecull && ps->do_mask_normal) {
float viewDirPersp[3];
+ MVert *mv;
+ float no[3];
+ int a;
ps->vertFlags = MEM_callocN(sizeof(char) * ps->dm_totvert, "paint-vertFlags");
@@ -3284,38 +3352,344 @@ static void project_paint_begin(ProjPaintState *ps)
}
}
}
-
- for (face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) {
- bool is_face_sel;
+ else {
+ ps->vertFlags = NULL;
+ }
+}
#ifndef PROJ_DEBUG_NOSEAMBLEED
- /* add face user if we have bleed enabled, set the UV seam flags later */
- /* annoying but we need to add all faces even ones we never use elsewhere */
- if (ps->seam_bleed_px > 0.0f) {
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v1], SET_INT_IN_POINTER(face_index), arena);
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v2], SET_INT_IN_POINTER(face_index), arena);
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v3], SET_INT_IN_POINTER(face_index), arena);
- if (mf->v4) {
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v4], SET_INT_IN_POINTER(face_index), arena);
- }
+static void project_paint_bleed_add_face_user(
+ const ProjPaintState *ps, MemArena *arena,
+ const MFace *mf, const int face_index)
+{
+ /* add face user if we have bleed enabled, set the UV seam flags later */
+ /* annoying but we need to add all faces even ones we never use elsewhere */
+ if (ps->seam_bleed_px > 0.0f) {
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v1], SET_INT_IN_POINTER(face_index), arena);
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v2], SET_INT_IN_POINTER(face_index), arena);
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v3], SET_INT_IN_POINTER(face_index), arena);
+ if (mf->v4) {
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v4], SET_INT_IN_POINTER(face_index), arena);
}
+ }
+}
#endif
- if (ps->do_face_sel) {
- int orig_index;
- if (index_mp_to_orig && ((orig_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig,
- face_index))) != ORIGINDEX_NONE)
- {
- MPoly *mp = &mpoly_orig[orig_index];
- is_face_sel = ((mp->flag & ME_FACE_SEL) != 0);
+/* Return true if DM can be painted on, false otherwise */
+static bool proj_paint_state_dm_init(ProjPaintState *ps)
+{
+ /* Workaround for subsurf selection, try the display mesh first */
+ if (ps->source == PROJ_SRC_IMAGE_CAM) {
+ /* using render mesh, assume only camera was rendered from */
+ ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
+ ps->dm_release = true;
+ }
+ else if (ps->ob->derivedFinal &&
+ CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE) &&
+ (ps->do_face_sel == false || CustomData_has_layer(&ps->ob->derivedFinal->polyData, CD_ORIGINDEX)))
+ {
+ ps->dm = ps->ob->derivedFinal;
+ ps->dm_release = false;
+ }
+ else {
+ ps->dm = mesh_get_derived_final(
+ ps->scene, ps->ob,
+ ps->scene->customdata_mask | CD_MASK_MTFACE | (ps->do_face_sel ? CD_ORIGINDEX : 0));
+ ps->dm_release = true;
+ }
+
+ if (!CustomData_has_layer(&ps->dm->faceData, CD_MTFACE)) {
+
+ if (ps->dm_release)
+ ps->dm->release(ps->dm);
+
+ ps->dm = NULL;
+ return false;
+ }
+
+ DM_update_materials(ps->dm, ps->ob);
+
+ ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
+ ps->dm_totedge = ps->dm->getNumEdges(ps->dm);
+ ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
+
+ ps->dm_mvert = ps->dm->getVertArray(ps->dm);
+
+ if (ps->do_mask_cavity)
+ ps->dm_medge = ps->dm->getEdgeArray(ps->dm);
+
+ ps->dm_mface = ps->dm->getTessFaceArray(ps->dm);
+ ps->dm_mtface = MEM_mallocN(ps->dm_totface * sizeof(MTFace *), "proj_paint_mtfaces");
+
+ return true;
+}
+
+typedef struct {
+ MTFace *tf_clone_base;
+ MTFace **tf_clone;
+ TexPaintSlot *slot_last_clone;
+ TexPaintSlot *slot_clone;
+} ProjPaintLayerClone;
+
+static void proj_paint_layer_clone_init(
+ ProjPaintState *ps,
+ ProjPaintLayerClone *layer_clone)
+{
+ MTFace *tf_clone_base = NULL;
+
+ /* use clone mtface? */
+ if (ps->do_layer_clone) {
+ const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY);
+
+ ps->dm_mtface_clone = MEM_mallocN(ps->dm_totface * sizeof(MTFace *), "proj_paint_mtfaces");
+
+ if (layer_num != -1)
+ tf_clone_base = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
+
+ if (tf_clone_base == NULL) {
+ /* get active instead */
+ tf_clone_base = CustomData_get_layer(&ps->dm->faceData, CD_MTFACE);
+ }
+
+ }
+
+ memset(layer_clone, 0, sizeof(*layer_clone));
+ layer_clone->tf_clone_base = tf_clone_base;
+}
+
+/* Return true if face should be skipped, false otherwise */
+static bool project_paint_clone_face_skip(
+ ProjPaintState *ps,
+ ProjPaintLayerClone *lc,
+ const TexPaintSlot *slot,
+ const int face_index)
+{
+ if (ps->do_layer_clone) {
+ if (ps->do_material_slots) {
+ lc->slot_clone = project_paint_face_clone_slot(ps, face_index);
+ /* all faces should have a valid slot, reassert here */
+ if (ELEM(lc->slot_clone, NULL, slot))
+ return true;
+ }
+ else if (ps->clone_ima == ps->canvas_ima)
+ return true;
+
+ lc->tf_clone = ps->dm_mtface_clone + face_index;
+
+ if (ps->do_material_slots) {
+ if (lc->slot_clone != lc->slot_last_clone) {
+ if (!slot->uvname ||
+ !(lc->tf_clone_base = CustomData_get_layer_named(
+ &ps->dm->faceData, CD_MTFACE,
+ lc->slot_clone->uvname)))
+ {
+ lc->tf_clone_base = CustomData_get_layer(&ps->dm->faceData, CD_MTFACE);
+ }
+ lc->slot_last_clone = lc->slot_clone;
}
- else {
- is_face_sel = ((mf->flag & ME_FACE_SEL) != 0);
+ }
+
+ *lc->tf_clone = lc->tf_clone_base + face_index;
+ }
+ return false;
+}
+
+typedef struct {
+ MPoly *mpoly_orig;
+
+ /* double lookup */
+ const int *index_mf_to_mpoly;
+ const int *index_mp_to_orig;
+} ProjPaintFaceLookup;
+
+static void proj_paint_face_lookup_init(
+ const ProjPaintState *ps,
+ ProjPaintFaceLookup *face_lookup)
+{
+ memset(face_lookup, 0, sizeof(*face_lookup));
+ if (ps->do_face_sel) {
+ face_lookup->index_mf_to_mpoly = ps->dm->getTessFaceDataArray(ps->dm, CD_ORIGINDEX);
+ face_lookup->index_mp_to_orig = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX);
+ if (face_lookup->index_mf_to_mpoly == NULL) {
+ face_lookup->index_mp_to_orig = NULL;
+ }
+ else {
+ face_lookup->mpoly_orig = ((Mesh *)ps->ob->data)->mpoly;
+ }
+ }
+}
+
+/* Return true if face should be considered selected, false otherwise */
+static bool project_paint_check_face_sel(
+ const ProjPaintState *ps,
+ const ProjPaintFaceLookup *face_lookup,
+ const MFace *mf, const int face_index)
+{
+ if (ps->do_face_sel) {
+ int orig_index;
+ if (face_lookup->index_mp_to_orig &&
+ ((orig_index = DM_origindex_mface_mpoly(
+ face_lookup->index_mf_to_mpoly,
+ face_lookup->index_mp_to_orig,
+ face_index))) != ORIGINDEX_NONE)
+ {
+ MPoly *mp = &face_lookup->mpoly_orig[orig_index];
+ return ((mp->flag & ME_FACE_SEL) != 0);
+ }
+ else {
+ return ((mf->flag & ME_FACE_SEL) != 0);
+ }
+ }
+ else {
+ return true;
+ }
+}
+
+typedef struct {
+ const float *v1;
+ const float *v2;
+ const float *v3;
+ const float *v4;
+} ProjPaintFaceCoSS;
+
+static void proj_paint_face_coSS_init(
+ const ProjPaintState *ps, const MFace *mf,
+ ProjPaintFaceCoSS *coSS)
+{
+ coSS->v1 = ps->screenCoords[mf->v1];
+ coSS->v2 = ps->screenCoords[mf->v2];
+ coSS->v3 = ps->screenCoords[mf->v3];
+ coSS->v4 = mf->v4 ? ps->screenCoords[mf->v4] : NULL;
+}
+
+/* Return true if face should be culled, false otherwise */
+static bool project_paint_flt_max_cull(
+ const ProjPaintState *ps,
+ const ProjPaintFaceCoSS *coSS)
+{
+ if (!ps->is_ortho) {
+ if (coSS->v1[0] == FLT_MAX ||
+ coSS->v2[0] == FLT_MAX ||
+ coSS->v3[0] == FLT_MAX ||
+ (coSS->v4 && coSS->v4[0] == FLT_MAX))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+#ifdef PROJ_DEBUG_WINCLIP
+/* Return true if face should be culled, false otherwise */
+static bool project_paint_winclip(
+ const ProjPaintState *ps, const MFace *mf,
+ const ProjPaintFaceCoSS *coSS)
+{
+ /* ignore faces outside the view */
+ return ((ps->source != PROJ_SRC_VIEW_FILL) &&
+ ((coSS->v1[0] < ps->screenMin[0] &&
+ coSS->v2[0] < ps->screenMin[0] &&
+ coSS->v3[0] < ps->screenMin[0] &&
+ (mf->v4 && coSS->v4[0] < ps->screenMin[0])) ||
+
+ (coSS->v1[0] > ps->screenMax[0] &&
+ coSS->v2[0] > ps->screenMax[0] &&
+ coSS->v3[0] > ps->screenMax[0] &&
+ (mf->v4 && coSS->v4[0] > ps->screenMax[0])) ||
+
+ (coSS->v1[1] < ps->screenMin[1] &&
+ coSS->v2[1] < ps->screenMin[1] &&
+ coSS->v3[1] < ps->screenMin[1] &&
+ (mf->v4 && coSS->v4[1] < ps->screenMin[1])) ||
+
+ (coSS->v1[1] > ps->screenMax[1] &&
+ coSS->v2[1] > ps->screenMax[1] &&
+ coSS->v3[1] > ps->screenMax[1] &&
+ (mf->v4 && coSS->v4[1] > ps->screenMax[1]))));
+}
+#endif //PROJ_DEBUG_WINCLIP
+
+/* Return true if face should be culled, false otherwise */
+static bool project_paint_backface_cull(
+ const ProjPaintState *ps, const MFace *mf,
+ const ProjPaintFaceCoSS *coSS)
+{
+ if (ps->do_backfacecull) {
+ if (ps->do_mask_normal) {
+ /* Since we are interpolating the normals of faces, we want to make
+ * sure all the verts are pointing away from the view,
+ * not just the face */
+ if ((ps->vertFlags[mf->v1] & PROJ_VERT_CULL) &&
+ (ps->vertFlags[mf->v2] & PROJ_VERT_CULL) &&
+ (ps->vertFlags[mf->v3] & PROJ_VERT_CULL) &&
+ (mf->v4 == 0 || ps->vertFlags[mf->v4] & PROJ_VERT_CULL))
+ {
+ return true;
}
}
else {
- is_face_sel = true;
+ if (line_point_side_v2(coSS->v1, coSS->v2, coSS->v3) < 0.0f) {
+ return true;
+ }
+
}
+ }
+
+ return false;
+}
+
+static void project_paint_build_proj_ima(
+ ProjPaintState *ps, MemArena *arena,
+ LinkNode *image_LinkList)
+{
+ ProjPaintImage *projIma;
+ LinkNode *node;
+ int i;
+
+ /* build an array of images we use */
+ projIma = ps->projImages = BLI_memarena_alloc(arena, sizeof(ProjPaintImage) * ps->image_tot);
+
+ for (node = image_LinkList, i = 0; node; node = node->next, i++, projIma++) {
+ int size;
+ projIma->ima = node->link;
+ projIma->touch = 0;
+ projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, NULL, NULL);
+ size = sizeof(void **) * IMAPAINT_TILE_NUMBER(projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(projIma->ibuf->y);
+ projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ projIma->undoRect = (volatile void **) BLI_memarena_alloc(arena, size);
+ memset(projIma->undoRect, 0, size);
+ projIma->maskRect = BLI_memarena_alloc(arena, size);
+ memset(projIma->maskRect, 0, size);
+ projIma->valid = BLI_memarena_alloc(arena, size);
+ memset(projIma->valid, 0, size);
+ }
+}
+
+static void project_paint_prepare_all_faces(
+ ProjPaintState *ps, MemArena *arena,
+ const ProjPaintFaceLookup *face_lookup,
+ ProjPaintLayerClone *layer_clone,
+ MTFace *tf_base)
+{
+ /* Image Vars - keep track of images we have used */
+ LinkNode *image_LinkList = NULL;
+
+ Image *tpage_last = NULL, *tpage;
+ TexPaintSlot *slot_last = NULL;
+ TexPaintSlot *slot = NULL;
+ MTFace **tf;
+ MFace *mf;
+ int image_index = -1, face_index;
+
+ for (face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) {
+ bool is_face_sel;
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ project_paint_bleed_add_face_user(ps, arena, mf, face_index);
+#endif
+
+ is_face_sel = project_paint_check_face_sel(ps, face_lookup, mf, face_index);
if (!ps->do_stencil_brush) {
slot = project_paint_face_paint_slot(ps, face_index);
@@ -3344,103 +3718,31 @@ static void project_paint_begin(ProjPaintState *ps)
*tf = tf_base + face_index;
- if (ps->do_layer_clone) {
- if (ps->do_material_slots) {
- slot_clone = project_paint_face_clone_slot(ps, face_index);
- /* all faces should have a valid slot, reassert here */
- if (ELEM(slot_clone, NULL, slot))
- continue;
- }
- else if (ps->clone_ima == ps->canvas_ima)
- continue;
-
- tf_clone = ps->dm_mtface_clone + face_index;
-
- if (ps->do_material_slots) {
- if (slot_clone != slot_last_clone) {
- if (!slot->uvname || !(tf_clone_base = CustomData_get_layer_named(&ps->dm->faceData, CD_MTFACE, slot_clone->uvname)))
- tf_clone_base = CustomData_get_layer(&ps->dm->faceData, CD_MTFACE);
- slot_last_clone = slot_clone;
- }
- }
-
- *tf_clone = tf_clone_base + face_index;
+ if (project_paint_clone_face_skip(ps, layer_clone, slot, face_index)) {
+ continue;
}
/* tfbase here should be non-null! */
BLI_assert (tf_base != NULL);
if (is_face_sel && tpage) {
- const float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
-
- v1coSS = ps->screenCoords[mf->v1];
- v2coSS = ps->screenCoords[mf->v2];
- v3coSS = ps->screenCoords[mf->v3];
- if (mf->v4) {
- v4coSS = ps->screenCoords[mf->v4];
- }
+ ProjPaintFaceCoSS coSS;
+ proj_paint_face_coSS_init(ps, mf, &coSS);
-
- if (!ps->is_ortho) {
- if (v1coSS[0] == FLT_MAX ||
- v2coSS[0] == FLT_MAX ||
- v3coSS[0] == FLT_MAX ||
- (mf->v4 && v4coSS[0] == FLT_MAX))
- {
- continue;
- }
+ if (project_paint_flt_max_cull(ps, &coSS)) {
+ continue;
}
#ifdef PROJ_DEBUG_WINCLIP
- /* ignore faces outside the view */
- if (
- (v1coSS[0] < ps->screenMin[0] &&
- v2coSS[0] < ps->screenMin[0] &&
- v3coSS[0] < ps->screenMin[0] &&
- (mf->v4 && v4coSS[0] < ps->screenMin[0])) ||
-
- (v1coSS[0] > ps->screenMax[0] &&
- v2coSS[0] > ps->screenMax[0] &&
- v3coSS[0] > ps->screenMax[0] &&
- (mf->v4 && v4coSS[0] > ps->screenMax[0])) ||
-
- (v1coSS[1] < ps->screenMin[1] &&
- v2coSS[1] < ps->screenMin[1] &&
- v3coSS[1] < ps->screenMin[1] &&
- (mf->v4 && v4coSS[1] < ps->screenMin[1])) ||
-
- (v1coSS[1] > ps->screenMax[1] &&
- v2coSS[1] > ps->screenMax[1] &&
- v3coSS[1] > ps->screenMax[1] &&
- (mf->v4 && v4coSS[1] > ps->screenMax[1]))
- )
- {
+ if (project_paint_winclip(ps, mf, &coSS)) {
continue;
}
#endif //PROJ_DEBUG_WINCLIP
- if (ps->do_backfacecull) {
- if (ps->do_mask_normal) {
- /* Since we are interpolating the normals of faces, we want to make
- * sure all the verts are pointing away from the view,
- * not just the face */
- if ((ps->vertFlags[mf->v1] & PROJ_VERT_CULL) &&
- (ps->vertFlags[mf->v2] & PROJ_VERT_CULL) &&
- (ps->vertFlags[mf->v3] & PROJ_VERT_CULL) &&
- (mf->v4 == 0 || ps->vertFlags[mf->v4] & PROJ_VERT_CULL)
- )
- {
- continue;
- }
- }
- else {
- if (line_point_side_v2(v1coSS, v2coSS, v3coSS) < 0.0f) {
- continue;
- }
-
- }
+ if (project_paint_backface_cull(ps, mf, &coSS)) {
+ continue;
}
if (tpage_last != tpage) {
@@ -3465,28 +3767,100 @@ static void project_paint_begin(ProjPaintState *ps)
}
/* build an array of images we use*/
- projIma = ps->projImages = (ProjPaintImage *)BLI_memarena_alloc(arena, sizeof(ProjPaintImage) * ps->image_tot);
-
- for (node = image_LinkList, i = 0; node; node = node->next, i++, projIma++) {
- int size;
- projIma->ima = node->link;
- projIma->touch = 0;
- projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, NULL, NULL);
- size = sizeof(void **) * IMAPAINT_TILE_NUMBER(projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(projIma->ibuf->y);
- projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
- memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
- projIma->undoRect = (volatile void **) BLI_memarena_alloc(arena, size);
- memset(projIma->undoRect, 0, size);
- projIma->maskRect = (unsigned short **) BLI_memarena_alloc(arena, size);
- memset(projIma->maskRect, 0, size);
- projIma->valid = (bool **) BLI_memarena_alloc(arena, size);
- memset(projIma->valid, 0, size);
- }
+ project_paint_build_proj_ima(ps, arena, image_LinkList);
/* we have built the array, discard the linked list */
BLI_linklist_free(image_LinkList, NULL);
}
+/* run once per stroke before projection painting */
+static void project_paint_begin(ProjPaintState *ps)
+{
+ ProjPaintLayerClone layer_clone;
+ ProjPaintFaceLookup face_lookup;
+ MTFace *tf_base;
+
+ MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
+
+ const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
+
+ bool reset_threads = false;
+
+ /* ---- end defines ---- */
+
+ if (ps->source == PROJ_SRC_VIEW)
+ ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat); /* faster clipping lookups */
+
+ ps->do_face_sel = ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) != 0);
+
+ /* paint onto the derived mesh */
+ if (!proj_paint_state_dm_init(ps)) {
+ return;
+ }
+
+ proj_paint_face_lookup_init(ps, &face_lookup);
+ proj_paint_layer_clone_init(ps, &layer_clone);
+
+ if (ps->do_layer_stencil || ps->do_stencil_brush) {
+ //int layer_num = CustomData_get_stencil_layer(&ps->dm->faceData, CD_MTFACE);
+ int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY);
+ if (layer_num != -1)
+ ps->dm_mtface_stencil = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
+
+ if (ps->dm_mtface_stencil == NULL) {
+ /* get active instead */
+ ps->dm_mtface_stencil = CustomData_get_layer(&ps->dm->faceData, CD_MTFACE);
+ }
+
+ if (ps->do_stencil_brush)
+ tf_base = ps->dm_mtface_stencil;
+ }
+
+ /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */
+ proj_paint_state_non_cddm_init(ps);
+
+ proj_paint_state_cavity_init(ps);
+
+ proj_paint_state_viewport_init(ps);
+
+ /* calculate vert screen coords
+ * run this early so we can calculate the x/y resolution of our bucket rect */
+ proj_paint_state_screen_coords_init(ps, diameter);
+
+ /* only for convenience */
+ ps->screen_width = ps->screenMax[0] - ps->screenMin[0];
+ ps->screen_height = ps->screenMax[1] - ps->screenMin[1];
+
+ ps->buckets_x = (int)(ps->screen_width / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
+ ps->buckets_y = (int)(ps->screen_height / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
+
+ /* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */
+
+ if (ps->buckets_x > PROJ_BUCKET_RECT_MAX || ps->buckets_y > PROJ_BUCKET_RECT_MAX) {
+ reset_threads = true;
+ }
+
+ /* really high values could cause problems since it has to allocate a few
+ * (ps->buckets_x*ps->buckets_y) sized arrays */
+ CLAMP(ps->buckets_x, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
+ CLAMP(ps->buckets_y, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
+
+ ps->bucketRect = MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketRect");
+ ps->bucketFaces = MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
+
+ ps->bucketFlags = MEM_callocN(sizeof(char) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ proj_paint_state_seam_bleed_init(ps);
+#endif
+
+ proj_paint_state_thread_init(ps, reset_threads);
+ arena = ps->arena_mt[0];
+
+ proj_paint_state_vert_flags_init(ps);
+
+ project_paint_prepare_all_faces(ps, arena, &face_lookup, &layer_clone, tf_base);
+}
+
static void paint_proj_begin_clone(ProjPaintState *ps, const float mouse[2])
{
/* setup clone offset */
@@ -3544,6 +3918,10 @@ static void project_paint_end(ProjPaintState *ps)
MEM_freeN(ps->blurkernel);
}
+ if (ps->do_mask_cavity) {
+ MEM_freeN(ps->cavities);
+ }
+
if (ps->vertFlags) MEM_freeN(ps->vertFlags);
for (a = 0; a < ps->thread_tot; a++) {
@@ -3672,7 +4050,9 @@ static bool project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
}
-static bool project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf *bucket_bounds, const float mval[2])
+static bool project_bucket_iter_next(
+ ProjPaintState *ps, int *bucket_index,
+ rctf *bucket_bounds, const float mval[2])
{
const int diameter = 2 * ps->brush_size;
@@ -3762,10 +4142,9 @@ static void do_projectpaint_clone_f(ProjPaintState *ps, ProjPixel *projPixel, fl
}
}
-/* do_projectpaint_smear*
- *
- * note, mask is used to modify the alpha here, this is not correct since it allows
- * accumulation of color greater then 'projPixel->mask' however in the case of smear its not
+/**
+ * \note mask is used to modify the alpha here, this is not correct since it allows
+ * accumulation of color greater than 'projPixel->mask' however in the case of smear its not
* really that important to be correct as it is with clone and painting
*/
static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, float mask,
@@ -3911,20 +4290,26 @@ static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, flo
}
}
-static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const float texrgb[3], float mask)
+static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const float texrgb[3], float mask, float dither, float u, float v)
{
float rgb[3];
unsigned char rgba_ub[4];
- copy_v3_v3(rgb, ps->paint_color);
-
if (ps->is_texbrush) {
- mul_v3_v3(rgb, texrgb);
+ mul_v3_v3v3(rgb, texrgb, ps->paint_color_linear);
/* TODO(sergey): Support texture paint color space. */
linearrgb_to_srgb_v3_v3(rgb, rgb);
}
+ else {
+ copy_v3_v3(rgb, ps->paint_color);
+ }
- rgb_float_to_uchar(rgba_ub, rgb);
+ if (dither > 0.0f) {
+ float_to_byte_dither_v3(rgba_ub, rgb, dither, u, v);
+ }
+ else {
+ F3TOCHAR3(rgb, rgba_ub);
+ }
rgba_ub[3] = f_to_char(mask);
if (ps->do_masking) {
@@ -3983,6 +4368,15 @@ static void do_projectpaint_mask_f(ProjPaintState *ps, ProjPixel *projPixel, flo
}
}
+static void image_paint_partial_redraw_expand(ImagePaintPartialRedraw *cell,
+ const ProjPixel *projPixel)
+{
+ cell->x1 = min_ii(cell->x1, (int)projPixel->x_px);
+ cell->y1 = min_ii(cell->y1, (int)projPixel->y_px);
+
+ cell->x2 = max_ii(cell->x2, (int)projPixel->x_px + 1);
+ cell->y2 = max_ii(cell->y2, (int)projPixel->y_px + 1);
+}
/* run this for single and multithreaded painting */
static void *do_projectpaint_thread(void *ph_v)
@@ -4105,7 +4499,14 @@ static void *do_projectpaint_thread(void *ph_v)
}
else {
linearrgb_to_srgb_v3_v3(color_f, color_f);
- rgba_float_to_uchar(projPixel->newColor.ch, color_f);
+
+ if (ps->dither > 0.0f) {
+ float_to_byte_dither_v3(projPixel->newColor.ch, color_f, ps->dither, projPixel->x_px, projPixel->y_px);
+ }
+ else {
+ F3TOCHAR3(color_f, projPixel->newColor.ch);
+ }
+ projPixel->newColor.ch[3] = FTOCHAR(color_f[3]);
IMB_blend_color_byte(projPixel->pixel.ch_pt, projPixel->origColor.ch_pt,
projPixel->newColor.ch, ps->blend);
}
@@ -4135,11 +4536,7 @@ static void *do_projectpaint_thread(void *ph_v)
}
last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index;
- last_partial_redraw_cell->x1 = min_ii(last_partial_redraw_cell->x1, (int)projPixel->x_px);
- last_partial_redraw_cell->y1 = min_ii(last_partial_redraw_cell->y1, (int)projPixel->y_px);
-
- last_partial_redraw_cell->x2 = max_ii(last_partial_redraw_cell->x2, (int)projPixel->x_px + 1);
- last_partial_redraw_cell->y2 = max_ii(last_partial_redraw_cell->y2, (int)projPixel->y_px + 1);
+ image_paint_partial_redraw_expand(last_partial_redraw_cell, projPixel);
}
else {
if (is_floatbuf) {
@@ -4186,7 +4583,7 @@ static void *do_projectpaint_thread(void *ph_v)
if (dist_sq <= brush_radius_sq) {
dist = sqrtf(dist_sq);
- falloff = BKE_brush_curve_strength_clamp(ps->brush, dist, brush_radius);
+ falloff = BKE_brush_curve_strength(ps->brush, dist, brush_radius);
if (falloff > 0.0f) {
float texrgb[3];
@@ -4273,11 +4670,7 @@ static void *do_projectpaint_thread(void *ph_v)
*projPixel->valid = true;
last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index;
- last_partial_redraw_cell->x1 = min_ii(last_partial_redraw_cell->x1, (int)projPixel->x_px);
- last_partial_redraw_cell->y1 = min_ii(last_partial_redraw_cell->y1, (int)projPixel->y_px);
-
- last_partial_redraw_cell->x2 = max_ii(last_partial_redraw_cell->x2, (int)projPixel->x_px + 1);
- last_partial_redraw_cell->y2 = max_ii(last_partial_redraw_cell->y2, (int)projPixel->y_px + 1);
+ image_paint_partial_redraw_expand(last_partial_redraw_cell, projPixel);
/* texrgb is not used for clone, smear or soften */
switch (tool) {
@@ -4301,7 +4694,7 @@ static void *do_projectpaint_thread(void *ph_v)
break;
default:
if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, texrgb, mask);
- else do_projectpaint_draw(ps, projPixel, texrgb, mask);
+ else do_projectpaint_draw(ps, projPixel, texrgb, mask, ps->dither, projPixel->x_px, projPixel->y_px);
break;
}
}
@@ -4385,13 +4778,13 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po
/* thread specific */
handles[a].thread_index = a;
- handles[a].projImages = (ProjPaintImage *)BLI_memarena_alloc(ps->arena_mt[a], ps->image_tot * sizeof(ProjPaintImage));
+ handles[a].projImages = BLI_memarena_alloc(ps->arena_mt[a], ps->image_tot * sizeof(ProjPaintImage));
memcpy(handles[a].projImages, ps->projImages, ps->image_tot * sizeof(ProjPaintImage));
/* image bounds */
for (i = 0; i < ps->image_tot; i++) {
- handles[a].projImages[i].partRedrawRect = (ImagePaintPartialRedraw *)BLI_memarena_alloc(ps->arena_mt[a], sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ handles[a].projImages[i].partRedrawRect = BLI_memarena_alloc(ps->arena_mt[a], sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
memcpy(handles[a].projImages[i].partRedrawRect, ps->projImages[i].partRedrawRect, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
}
@@ -4421,7 +4814,35 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po
touch_any = 1;
}
}
+
+ /* calculate pivot for rotation around seletion if needed */
+ if (U.uiflag & USER_ORBIT_SELECTION) {
+ float w[3];
+ int side, index;
+
+ index = project_paint_PickFace(ps, pos, w, &side);
+
+ if (index != -1) {
+ MFace *mf;
+ float world[3];
+ UnifiedPaintSettings *ups = &ps->scene->toolsettings->unified_paint_settings;
+
+ mf = ps->dm_mface + index;
+ if (side == 0) {
+ interp_v3_v3v3v3(world, ps->dm_mvert[(*(&mf->v1))].co, ps->dm_mvert[(*(&mf->v2))].co, ps->dm_mvert[(*(&mf->v3))].co, w);
+ }
+ else {
+ interp_v3_v3v3v3(world, ps->dm_mvert[(*(&mf->v1))].co, ps->dm_mvert[(*(&mf->v3))].co, ps->dm_mvert[(*(&mf->v4))].co, w);
+ }
+
+ ups->average_stroke_counter++;
+ mul_m4_v3(ps->ob->obmat, world);
+ add_v3_v3(ups->average_stroke_accum, world);
+ ups->last_stroke_valid = true;
+ }
+ }
+
return touch_any;
}
@@ -4536,11 +4957,14 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int
ps->clone_ima = (!ps->do_material_slots) ?
settings->imapaint.clone : NULL;
+ ps->do_mask_cavity = (settings->imapaint.paint.flags & PAINT_USE_CAVITY_MASK) ? true : false;
+ ps->cavity_curve = settings->imapaint.paint.cavity_curve;
+
/* setup projection painting data */
if (ps->tool != PAINT_TOOL_FILL) {
- ps->do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? 0 : 1;
- ps->do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? 0 : 1;
- ps->do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? 0 : 1;
+ ps->do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? false : true;
+ ps->do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? false : true;
+ ps->do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? false : true;
}
else {
ps->do_backfacecull = ps->do_occlude = ps->do_mask_normal = 0;
@@ -4577,6 +5001,8 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int
if (ps->normal_angle_range <= 0.0f)
ps->do_mask_normal = false; /* no need to do blending */
+ ps->dither = settings->imapaint.dither;
+
return;
}
@@ -4593,7 +5019,7 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m
paint_brush_init_tex(ps->brush);
- ps->source = PROJ_SRC_VIEW;
+ ps->source = (ps->tool == PAINT_TOOL_FILL) ? PROJ_SRC_VIEW_FILL : PROJ_SRC_VIEW;
if (ps->ob == NULL || !(ps->ob->lay & ps->v3d->lay)) {
MEM_freeN(ps);
@@ -4604,7 +5030,7 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m
/* Don't allow brush size below 2 */
if (BKE_brush_size_get(ps->scene, ps->brush) < 2)
- BKE_brush_size_set(ps->scene, ps->brush, 2);
+ BKE_brush_size_set(ps->scene, ps->brush, 2 * U.pixelsize);
/* allocate and initialize spatial data structures */
project_paint_begin(ps);
@@ -4616,10 +5042,6 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m
paint_proj_begin_clone(ps, mouse);
- /* special full screen draw mode for fill tool */
- if (ps->tool == PAINT_TOOL_FILL)
- ps->source = PROJ_SRC_VIEW_FILL;
-
return ps;
}
@@ -4727,7 +5149,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
ps.is_maskbrush = false;
ps.do_masking = false;
orig_brush_size = BKE_brush_size_get(scene, ps.brush);
- BKE_brush_size_set(scene, ps.brush, 32); /* cover the whole image */
+ BKE_brush_size_set(scene, ps.brush, 32 * U.pixelsize); /* cover the whole image */
ps.tool = PAINT_TOOL_DRAW; /* so pixels are initialized with minimal info */
@@ -4821,6 +5243,9 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
image = BKE_image_add_from_imbuf(ibuf);
+ /* Drop reference to ibuf so that the image owns it */
+ IMB_freeImBuf(ibuf);
+
if (image) {
/* now for the trickyness. store the view projection here!
* re-projection will reuse this */
@@ -4841,7 +5266,9 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
memcpy(array, rv3d->winmat, sizeof(rv3d->winmat)); array += sizeof(rv3d->winmat) / sizeof(float);
memcpy(array, rv3d->viewmat, sizeof(rv3d->viewmat)); array += sizeof(rv3d->viewmat) / sizeof(float);
is_ortho = ED_view3d_clip_range_get(v3d, rv3d, &array[0], &array[1], true);
- array[2] = is_ortho ? 1.0f : 0.0f; /* using float for a bool is dodgy but since its an extra member in the array... easier then adding a single bool prop */
+ /* using float for a bool is dodgy but since its an extra member in the array...
+ * easier then adding a single bool prop */
+ array[2] = is_ortho ? 1.0f : 0.0f;
IDP_AddToGroup(idgroup, view_data);
@@ -4917,17 +5344,17 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m
hasmat = true;
if (!ma->texpaintslot) {
/* refresh here just in case */
- BKE_texpaint_slot_refresh_cache(scene, ma);
+ BKE_texpaint_slot_refresh_cache(scene, ma);
/* if still no slots, we have to add */
- if (ma->texpaintslot) {
+ if (ma->texpaintslot) {
hastex = true;
- break;
+ break;
}
}
else {
hastex = true;
- break;
+ break;
}
}
}
@@ -4936,7 +5363,7 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m
else if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) {
if (imapaint->canvas == NULL) {
hastex = false;
- }
+ }
}
me = BKE_mesh_from_object(ob);
@@ -5017,7 +5444,7 @@ static Image *proj_paint_image_create(wmOperator *op, Main *bmain)
RNA_string_get(op->ptr, "name", imagename);
}
ima = BKE_image_add_generated(bmain, width, height, imagename, alpha ? 32 : 24, use_float,
- gen_type, color);
+ gen_type, color);
return ima;
}
@@ -5027,7 +5454,7 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
Material *ma;
- bool is_bi = BKE_scene_uses_blender_internal(scene);
+ bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene);
Image *ima = NULL;
if (!ob)
@@ -5097,6 +5524,8 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
DAG_id_tag_update(&ma->id, 0);
ED_area_tag_redraw(CTX_wm_area(C));
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+
return true;
}
}
@@ -5125,7 +5554,7 @@ static int texture_paint_add_texture_paint_slot_invoke(bContext *C, wmOperator *
if (!ma) {
ma = BKE_material_add(CTX_data_main(C), "Material");
/* no material found, just assign to first slot */
- assign_material(ob, ma, ob->actcol, BKE_MAT_ASSIGN_USERPREF);
+ assign_material(ob, ma, ob->actcol, BKE_MAT_ASSIGN_USERPREF);
}
type = RNA_enum_from_value(layer_type_items, type);
@@ -5183,7 +5612,7 @@ static int texture_paint_delete_texture_paint_slot_exec(bContext *C, wmOperator
Object *ob = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
Material *ma;
- bool is_bi = BKE_scene_uses_blender_internal(scene);
+ bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene);
TexPaintSlot *slot;
/* not supported for node-based engines */
@@ -5197,16 +5626,21 @@ static int texture_paint_delete_texture_paint_slot_exec(bContext *C, wmOperator
slot = ma->texpaintslot + ma->paint_active_slot;
- if (ma->mtex[slot->index]->tex)
+ if (ma->mtex[slot->index]->tex) {
id_us_min(&ma->mtex[slot->index]->tex->id);
+
+ if (ma->mtex[slot->index]->tex->ima) {
+ id_us_min(&ma->mtex[slot->index]->tex->ima->id);
+ }
+ }
MEM_freeN(ma->mtex[slot->index]);
ma->mtex[slot->index] = NULL;
BKE_texpaint_slot_refresh_cache(scene, ma);
DAG_id_tag_update(&ma->id, 0);
- WM_event_add_notifier(C, NC_MATERIAL, CTX_data_scene(C));
+ WM_event_add_notifier(C, NC_MATERIAL, ma);
/* we need a notifier for data change since we change the displayed modifier uvs */
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
return OPERATOR_FINISHED;
}
@@ -5225,3 +5659,66 @@ void PAINT_OT_delete_texture_paint_slot(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ /* no checks here, poll function does them for us */
+ Object *ob = CTX_data_active_object(C);
+ Scene *scene = CTX_data_scene(C);
+ Mesh *me = ob->data;
+ bool synch_selection = (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
+
+ BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default);
+
+ /* turn synch selection off, since we are not in edit mode we need to ensure only the uv flags are tested */
+ scene->toolsettings->uv_flag &= ~UV_SYNC_SELECTION;
+
+ ED_mesh_uv_texture_ensure(me, NULL);
+
+ BM_mesh_bm_from_me(bm, me, true, false, 0);
+
+ /* select all uv loops first - pack parameters needs this to make sure charts are registered */
+ ED_uvedit_select_all(bm);
+ ED_uvedit_unwrap_cube_project(ob, bm, 1.0, false);
+ /* set the margin really quickly before the packing operation*/
+ scene->toolsettings->uvcalc_margin = 0.001f;
+ ED_uvedit_pack_islands(scene, ob, bm, false, false, true);
+ BM_mesh_bm_to_me(bm, me, false);
+ BM_mesh_free(bm);
+
+ if (synch_selection)
+ scene->toolsettings->uv_flag |= UV_SYNC_SELECTION;
+
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+
+ DAG_id_tag_update(ob->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, scene);
+ return OPERATOR_FINISHED;
+}
+
+static int add_simple_uvs_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+
+ if (!ob || ob->type != OB_MESH || ob->mode != OB_MODE_TEXTURE_PAINT)
+ return false;
+
+ return true;
+}
+
+void PAINT_OT_add_simple_uvs(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add simple UVs";
+ ot->description = "Add cube map uvs on mesh";
+ ot->idname = "PAINT_OT_add_simple_uvs";
+
+ /* api callbacks */
+ ot->exec = add_simple_uvs_exec;
+ ot->poll = add_simple_uvs_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index c3b7ec60e71..9e558092f73 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -184,6 +184,7 @@ void PAINT_OT_image_from_view(struct wmOperatorType *ot);
void PAINT_OT_add_texture_paint_slot(struct wmOperatorType *ot);
void PAINT_OT_delete_texture_paint_slot(struct wmOperatorType *ot);
void PAINT_OT_image_paint(struct wmOperatorType *ot);
+void PAINT_OT_add_simple_uvs(struct wmOperatorType *ot);
/* uv sculpting */
int uv_sculpt_poll(struct bContext *C);
@@ -244,6 +245,18 @@ typedef enum BrushStrokeMode {
BRUSH_STROKE_SMOOTH
} BrushStrokeMode;
+/* paint_ops.c */
+typedef enum {
+ RC_COLOR = 1,
+ RC_ROTATION = 2,
+ RC_ZOOM = 4,
+ RC_WEIGHT = 8,
+ RC_SECONDARY_ROTATION = 16
+} RCFlags;
+
+void set_brush_rc_props(struct PointerRNA *ptr, const char *paint, const char *prop, const char *secondary_prop,
+ RCFlags flags);
+
/* paint_undo.c */
struct ListBase *undo_paint_push_get_list(int type);
void undo_paint_push_count_alloc(int type, int size);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index dc6be9caa53..121b0b83a4b 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -106,15 +106,14 @@ static int brush_scale_size_exec(bContext *C, wmOperator *op)
const int old_size = BKE_brush_size_get(scene, brush);
int size = (int)(scalar * old_size);
- if (old_size == size) {
+ if (abs(old_size - size) < U.pixelsize) {
if (scalar > 1) {
- size++;
+ size += U.pixelsize;
}
else if (scalar < 1) {
- size--;
+ size -= U.pixelsize;
}
}
- CLAMP(size, 1, 2000); // XXX magic number
BKE_brush_size_set(scene, brush, size);
}
@@ -128,6 +127,8 @@ static int brush_scale_size_exec(bContext *C, wmOperator *op)
BKE_brush_unprojected_radius_set(scene, brush, unprojected_radius);
}
+
+ WM_main_add_notifier(NC_BRUSH | NA_EDITED, brush);
}
return OPERATOR_FINISHED;
@@ -1085,6 +1086,7 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_brush_colors_flip);
WM_operatortype_append(PAINT_OT_add_texture_paint_slot);
WM_operatortype_append(PAINT_OT_delete_texture_paint_slot);
+ WM_operatortype_append(PAINT_OT_add_simple_uvs);
/* weight */
WM_operatortype_append(PAINT_OT_weight_paint_toggle);
@@ -1148,14 +1150,6 @@ static void ed_keymap_paint_brush_size(wmKeyMap *keymap, const char *UNUSED(path
RNA_float_set(kmi->ptr, "scalar", 10.0 / 9.0); // 1.1111....
}
-typedef enum {
- RC_COLOR = 1,
- RC_ROTATION = 2,
- RC_ZOOM = 4,
- RC_WEIGHT = 8,
- RC_SECONDARY_ROTATION = 16
-} RCFlags;
-
static void set_brush_rc_path(PointerRNA *ptr, const char *brush_path,
const char *output_name, const char *input_name)
{
@@ -1166,9 +1160,9 @@ static void set_brush_rc_path(PointerRNA *ptr, const char *brush_path,
MEM_freeN(path);
}
-static void set_brush_rc_props(PointerRNA *ptr, const char *paint,
- const char *prop, const char *secondary_prop,
- RCFlags flags)
+void set_brush_rc_props(PointerRNA *ptr, const char *paint,
+ const char *prop, const char *secondary_prop,
+ RCFlags flags)
{
const char *ups_path = "tool_settings.unified_paint_settings";
char *brush_path;
@@ -1324,9 +1318,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
*
* This should be improved further, perhaps by showing a triangle
* grid rather than brush alpha */
- kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", DKEY, KM_PRESS, KM_SHIFT, 0);
- set_brush_rc_props(kmi->ptr, "sculpt", "detail_size", NULL, 0);
- RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.sculpt.detail_size");
+ kmi = WM_keymap_add_item(keymap, "SCULPT_OT_set_detail_size", DKEY, KM_PRESS, KM_SHIFT, 0);
/* multires switch */
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_subdivision_set", PAGEUPKEY, KM_PRESS, 0, 0);
@@ -1364,8 +1356,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.use_smooth_stroke");
- kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0);
- RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.texture_angle_source_random");
+ WM_keymap_add_menu(keymap, "VIEW3D_MT_angle_control", RKEY, KM_PRESS, 0, 0);
/* Vertex Paint mode */
keymap = WM_keymap_find(keyconf, "Vertex Paint", 0, 0);
@@ -1389,8 +1380,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.use_smooth_stroke");
- kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0);
- RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.texture_angle_source_random");
+ WM_keymap_add_menu(keymap, "VIEW3D_MT_angle_control", RKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", EKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.stroke_method");
@@ -1466,8 +1456,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.use_smooth_stroke");
- kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0);
- RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.texture_angle_source_random");
+ WM_keymap_add_menu(keymap, "VIEW3D_MT_angle_control", RKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", EKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.stroke_method");
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 9c4701d0a01..bfd429d0924 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -122,6 +122,10 @@ typedef struct PaintStroke {
float zoom_2d;
int pen_flip;
+
+ /* line constraint */
+ bool constrain_line;
+ float constrained_pos[2];
StrokeGetLocation get_location;
StrokeTestStart test_start;
@@ -161,13 +165,25 @@ static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata)
glColor4ub(0, 0, 0, paint->paint_cursor_col[3]);
glLineWidth(3.0);
- sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
- x, y);
+ if (stroke->constrain_line) {
+ sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
+ stroke->constrained_pos[0], stroke->constrained_pos[1]);
+ }
+ else {
+ sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
+ x, y);
+ }
glColor4ub(255, 255, 255, paint->paint_cursor_col[3]);
glLineWidth(1.0);
- sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
- x, y);
+ if (stroke->constrain_line) {
+ sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
+ stroke->constrained_pos[0], stroke->constrained_pos[1]);
+ }
+ else {
+ sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
+ x, y);
+ }
glDisable(GL_LINE_STIPPLE);
@@ -207,6 +223,7 @@ static bool paint_brush_update(bContext *C,
UnifiedPaintSettings *ups = stroke->ups;
bool location_sampled = false;
bool location_success = false;
+ bool do_random = false;
/* XXX: Use pressure value from first brush step for brushes which don't
* support strokes (grab, thumb). They depends on initial state and
* brush coord/pressure/etc.
@@ -256,17 +273,13 @@ static bool paint_brush_update(bContext *C,
if (paint_supports_dynamic_tex_coords(brush, mode)) {
if (((brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) ||
(brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) ||
- (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)) &&
- !(brush->flag & BRUSH_RAKE))
+ (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)))
{
- if (brush->flag & BRUSH_RANDOM_ROTATION)
- ups->brush_rotation = 2.0f * (float)M_PI * BLI_frand();
- else
- ups->brush_rotation = 0.0f;
+ do_random = true;
}
if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)
- BKE_brush_randomize_texture_coordinates(ups, false);
+ BKE_brush_randomize_texture_coords(ups, false);
else {
copy_v2_v2(ups->tex_mouse, mouse);
}
@@ -274,7 +287,7 @@ static bool paint_brush_update(bContext *C,
/* take care of mask texture, if any */
if (brush->mask_mtex.tex) {
if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)
- BKE_brush_randomize_texture_coordinates(ups, true);
+ BKE_brush_randomize_texture_coords(ups, true);
else {
copy_v2_v2(ups->mask_tex_mouse, mouse);
}
@@ -291,7 +304,7 @@ static bool paint_brush_update(bContext *C,
ups->anchored_size = ups->pixel_radius = sqrtf(dx * dx + dy * dy);
- ups->brush_rotation = atan2f(dx, dy) + M_PI;
+ ups->brush_rotation = ups->brush_rotation_sec = atan2f(dx, dy) + (float)M_PI;
if (brush->flag & BRUSH_EDGE_TO_EDGE) {
halfway[0] = dx * 0.5f + stroke->initial_mouse[0];
@@ -328,13 +341,27 @@ static bool paint_brush_update(bContext *C,
ups->pixel_radius /= stroke->zoom_2d;
ups->draw_anchored = true;
}
- else if (brush->flag & BRUSH_RAKE) {
+ else {
/* here we are using the initial mouse coordinate because we do not want the rake
* result to depend on jittering */
- if (!stroke->brush_init)
+ if (!stroke->brush_init) {
copy_v2_v2(ups->last_rake, mouse_init);
- else
- paint_calculate_rake_rotation(ups, mouse_init);
+ }
+ else {
+ paint_calculate_rake_rotation(ups, brush, mouse_init);
+ }
+ }
+
+ if (do_random) {
+ if (brush->mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) {
+ ups->brush_rotation += -brush->mtex.random_angle / 2.0f +
+ brush->mtex.random_angle * BLI_frand();
+ }
+
+ if (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) {
+ ups->brush_rotation_sec += -brush->mask_mtex.random_angle / 2.0f +
+ brush->mask_mtex.random_angle * BLI_frand();
+ }
}
if (!location_sampled) {
@@ -624,7 +651,8 @@ PaintStroke *paint_stroke_new(bContext *C,
PaintStroke *stroke = MEM_callocN(sizeof(PaintStroke), "PaintStroke");
ToolSettings *toolsettings = CTX_data_tool_settings(C);
UnifiedPaintSettings *ups = &toolsettings->unified_paint_settings;
- Brush *br = stroke->brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
+ Paint *p = BKE_paint_get_active_from_context(C);
+ Brush *br = stroke->brush = BKE_paint_brush(p);
float zoomx, zoomy;
view3d_set_viewcontext(C, &stroke->vc);
@@ -643,18 +671,24 @@ PaintStroke *paint_stroke_new(bContext *C,
get_imapaint_zoom(C, &zoomx, &zoomy);
stroke->zoom_2d = max_ff(zoomx, zoomy);
- if ((br->flag & BRUSH_CURVE) &&
- RNA_struct_property_is_set(op->ptr, "mode"))
+ if (stroke->stroke_mode == BRUSH_STROKE_INVERT)
{
- RNA_enum_set(op->ptr, "mode", BRUSH_STROKE_NORMAL);
+ if (br->flag & (BRUSH_CURVE | BRUSH_LINE)) {
+ RNA_enum_set(op->ptr, "mode", BRUSH_STROKE_NORMAL);
+ }
}
/* initialize here */
ups->overlap_factor = 1.0;
ups->stroke_active = true;
-
+
+ zero_v3(ups->average_stroke_accum);
+ ups->average_stroke_counter = 0;
+
/* initialize here to avoid initialization conflict with threaded strokes */
curvemapping_initialize(br->curve);
-
+ if (p->flags & PAINT_USE_CAVITY_MASK)
+ curvemapping_initialize(p->cavity_curve);
+
BKE_paint_set_overlay_override(br->overlay_flags);
return stroke;
@@ -675,9 +709,12 @@ static void stroke_done(struct bContext *C, struct wmOperator *op)
ups->stroke_active = false;
/* reset rotation here to avoid doing so in cursor display */
- if (!(stroke->brush->flag & BRUSH_RAKE))
+ if (!(stroke->brush->mtex.brush_angle_mode & MTEX_ANGLE_RAKE))
ups->brush_rotation = 0.0f;
+ if (!(stroke->brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE))
+ ups->brush_rotation_sec = 0.0f;
+
if (stroke->stroke_started) {
if (stroke->redraw)
stroke->redraw(C, stroke, true);
@@ -978,6 +1015,34 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str
return false;
}
+static void paint_stroke_line_constrain (PaintStroke *stroke, float mouse[2])
+{
+ if (stroke->constrain_line) {
+ float line[2];
+ float angle, len, res;
+
+ sub_v2_v2v2(line, mouse, stroke->last_mouse_position);
+ angle = atan2(line[1], line[0]);
+ len = len_v2(line);
+
+ /* divide angle by PI/4 */
+ angle = 4.0f * angle / (float)M_PI;
+
+ /* now take residue */
+ res = angle - floorf(angle);
+
+ /* residue decides how close we are at a certain angle */
+ if (res <= 0.5f) {
+ angle = floorf(angle) * (float)M_PI_4;
+ }
+ else {
+ angle = (floorf(angle) + 1.0f) * (float)M_PI_4;
+ }
+
+ mouse[0] = stroke->constrained_pos[0] = len * cosf(angle) + stroke->last_mouse_position[0];
+ mouse[1] = stroke->constrained_pos[1] = len * sinf(angle) + stroke->last_mouse_position[1];
+ }
+}
int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
@@ -1051,7 +1116,9 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->type == stroke->event_type && !first_modal) {
if (event->val == KM_RELEASE) {
- paint_stroke_line_end (C, op, stroke, sample_average.mouse);
+ copy_v2_fl2(mouse, event->mval[0], event->mval[1]);
+ paint_stroke_line_constrain(stroke, mouse);
+ paint_stroke_line_end (C, op, stroke, mouse);
stroke_done(C, op);
return OPERATOR_FINISHED;
}
@@ -1061,12 +1128,21 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
stroke_done(C, op);
return OPERATOR_FINISHED;
}
- else if ((br->flag & BRUSH_LINE) && stroke->stroke_started &&
- (first_modal || (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))))
- {
- if (br->flag & BRUSH_RAKE) {
- copy_v2_v2(stroke->ups->last_rake, stroke->last_mouse_position);
- paint_calculate_rake_rotation(stroke->ups, sample_average.mouse);
+ else if (br->flag & BRUSH_LINE) {
+ if (event->ctrl)
+ stroke->constrain_line = true;
+ else
+ stroke->constrain_line = false;
+
+ copy_v2_fl2(mouse, event->mval[0], event->mval[1]);
+ paint_stroke_line_constrain(stroke, mouse);
+
+ if (stroke->stroke_started && (first_modal || (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))))
+ {
+ if ((br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) || (br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) {
+ copy_v2_v2(stroke->ups->last_rake, stroke->last_mouse_position);
+ }
+ paint_calculate_rake_rotation(stroke->ups, br, mouse);
}
}
else if (first_modal ||
diff --git a/source/blender/editors/sculpt_paint/paint_undo.c b/source/blender/editors/sculpt_paint/paint_undo.c
index 20e3155c01d..0293a0bfc00 100644
--- a/source/blender/editors/sculpt_paint/paint_undo.c
+++ b/source/blender/editors/sculpt_paint/paint_undo.c
@@ -210,7 +210,7 @@ static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char *
/* pass */
}
else {
- if (!name || strcmp(stack->current->name, name) == 0) {
+ if (!name || STREQ(stack->current->name, name)) {
if (G.debug & G_DEBUG_WM) {
printf("%s: undo '%s'\n", __func__, stack->current->name);
}
@@ -225,7 +225,7 @@ static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char *
/* pass */
}
else {
- if (!name || strcmp(stack->current->name, name) == 0) {
+ if (!name || STREQ(stack->current->name, name)) {
undo = (stack->current && stack->current->next) ? stack->current->next : stack->elems.first;
undo_restore(C, stack, undo);
stack->current = undo;
@@ -394,7 +394,7 @@ int ED_undo_paint_valid(int type, const char *name)
/* pass */
}
else {
- if (name && strcmp(stack->current->name, name) == 0)
+ if (name && STREQ(stack->current->name, name))
return 1;
else
return stack->elems.first != stack->elems.last;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index e03c8a5f106..c0ed5005397 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -48,15 +48,13 @@
#include "BLF_translation.h"
-#include "BKE_scene.h"
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_material.h"
#include "BKE_image.h"
+#include "BKE_material.h"
#include "BKE_paint.h"
#include "BKE_report.h"
-#include "BKE_image.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -66,16 +64,12 @@
#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
-#include "RE_shader_ext.h"
#include "RE_render_ext.h"
#include "ED_view3d.h"
#include "ED_screen.h"
-#include "ED_uvedit.h"
-
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
#include "BLI_sys_types.h"
#include "ED_mesh.h" /* for face mask functions */
@@ -183,7 +177,7 @@ float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool,
float co[3] = {u, v, 0.0f};
externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false);
return intensity;
}
@@ -195,7 +189,7 @@ void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct
float intensity;
hasrgb = externtex(mtex, co, &intensity,
- rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool, false);
if (!hasrgb) {
rgba[0] = intensity;
rgba[1] = intensity;
@@ -292,6 +286,7 @@ static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, c
MVert mv[4];
float matrix[4][4], proj[4][4];
GLint view[4];
+ ImagePaintMode mode = scene->toolsettings->imapaint.mode;
/* compute barycentric coordinates */
@@ -320,19 +315,25 @@ static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, c
if (findex == faceindex) {
dm->getTessFace(dm, a, &mf);
- ma = dm->mat[mf.mat_nr];
- slot = &ma->texpaintslot[ma->paint_active_slot];
-
dm->getVert(dm, mf.v1, &mv[0]);
dm->getVert(dm, mf.v2, &mv[1]);
dm->getVert(dm, mf.v3, &mv[2]);
if (mf.v4)
dm->getVert(dm, mf.v4, &mv[3]);
- if (!(slot && slot->uvname && (tf_base = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, slot->uvname))))
- tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE);
+ if (mode == IMAGEPAINT_MODE_MATERIAL) {
+ ma = dm->mat[mf.mat_nr];
+ slot = &ma->texpaintslot[ma->paint_active_slot];
- tf = &tf_base[a];
+ if (!(slot && slot->uvname && (tf_base = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, slot->uvname))))
+ tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE);
+
+ tf = &tf_base[a];
+ }
+ else {
+ tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE);
+ tf = &tf_base[a];
+ }
p[0] = xy[0];
p[1] = xy[1];
@@ -372,15 +373,15 @@ static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, c
}
/* returns 0 if not found, otherwise 1 */
-static int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *r_index, unsigned int totface)
+static int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *r_index, unsigned int totpoly)
{
- if (totface == 0)
+ if (totpoly == 0)
return 0;
/* sample only on the exact position */
*r_index = view3d_sample_backbuf(vc, mval[0], mval[1]);
- if ((*r_index) == 0 || (*r_index) > (unsigned int)totface) {
+ if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) {
return 0;
}
@@ -390,12 +391,12 @@ static int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *
}
-static Image *imapaint_face_image(DerivedMesh *dm, int face_index)
+static Image *imapaint_face_image(Object *ob, Mesh *me, int face_index)
{
Image *ima;
- MFace *mf = dm->getTessFaceArray(dm) + face_index;
- Material *ma = dm->mat[mf->mat_nr];
- ima = ma ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
+ MPoly *mp = me->mpoly + face_index;
+ Material *ma = give_current_material(ob, mp->mat_nr + 1);;
+ ima = ma && ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
return ima;
}
@@ -449,26 +450,25 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
bool use_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
if (ob) {
+ Mesh *me = (Mesh *)ob->data;
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
ViewContext vc;
const int mval[2] = {x, y};
unsigned int faceindex;
- unsigned int totface = dm->getNumTessFaces(dm);
+ unsigned int totpoly = me->totpoly;
MTFace *dm_mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
- DM_update_materials(dm, ob);
-
if (dm_mtface) {
view3d_set_viewcontext(C, &vc);
view3d_operator_needs_opengl(C);
- if (imapaint_pick_face(&vc, mval, &faceindex, totface)) {
+ if (imapaint_pick_face(&vc, mval, &faceindex, totpoly)) {
Image *image;
if (use_material)
- image = imapaint_face_image(dm, faceindex);
+ image = imapaint_face_image(ob, me, faceindex);
else
image = imapaint->canvas;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 431dd54b3c0..e87dd6c2810 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -66,8 +66,6 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "GPU_buffers.h"
-
#include "ED_armature.h"
#include "ED_object.h"
#include "ED_mesh.h"
@@ -382,12 +380,12 @@ static int wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active)
mirrdef = defgroup_name_index(ob, name_flip);
if (mirrdef == -1) {
if (BKE_defgroup_new(ob, name_flip)) {
- mirrdef = BLI_countlist(&ob->defbase) - 1;
+ mirrdef = BLI_listbase_count(&ob->defbase) - 1;
}
}
/* curdef should never be NULL unless this is
- * a lamp and ED_vgroup_add_name fails */
+ * a lamp and BKE_object_defgroup_add_name fails */
return mirrdef;
}
@@ -937,7 +935,7 @@ static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const float co
else {
factor = 1.0f;
}
- return factor * BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure);
+ return factor * BKE_brush_curve_strength(brush, dist, brush_size_pressure);
}
}
if (rgba)
@@ -1177,7 +1175,7 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA
me = BKE_mesh_from_object(vc.obact);
if (me && me->dvert && vc.v3d && vc.rv3d && vc.obact->defbase.first) {
- const int defbase_tot = BLI_countlist(&vc.obact->defbase);
+ const int defbase_tot = BLI_listbase_count(&vc.obact->defbase);
const int use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int *groups = MEM_callocN(defbase_tot * sizeof(int), "groups");
bool found = false;
@@ -1577,8 +1575,8 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv,
change_status[i] = 1; /* can be altered while redistributing */
}
}
- /* if there was any change, redistribute it */
- if (total_changed) {
+ /* if there was any change, and somewhere to redistribute it, do it */
+ if (total_changed && total_valid) {
/* auto normalize will allow weights to temporarily go above 1 in redistribution */
if (vgroup_validmap && total_changed < 0 && total_valid) {
totchange_allowed = total_valid;
@@ -1742,7 +1740,8 @@ static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi,
}
clamp_weights(dv);
- enforce_locks(&dv_test, dv, wpi->defbase_tot, wpi->defbase_sel, wpi->lock_flags, wpi->vgroup_validmap, wpi->do_auto_normalize, wpi->do_multipaint);
+ enforce_locks(&dv_test, dv, wpi->defbase_tot, wpi->defbase_sel, wpi->lock_flags, wpi->vgroup_validmap,
+ wpi->do_auto_normalize, wpi->do_multipaint);
if (wpi->do_auto_normalize) {
/* XXX - should we pass the active group? - currently '-1' */
@@ -2074,7 +2073,7 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
paint_cursor_start(C, weight_paint_poll);
- BKE_paint_init(&wp->paint, PAINT_CURSOR_WEIGHT_PAINT);
+ BKE_paint_init(&scene->toolsettings->unified_paint_settings, &wp->paint, PAINT_CURSOR_WEIGHT_PAINT);
/* weight paint specific */
ED_mesh_mirror_spatial_table(ob, NULL, NULL, 's');
@@ -2159,7 +2158,7 @@ static bool wpaint_ensure_data(bContext *C, wmOperator *op)
/* if nothing was added yet, we make dverts and a vertex deform group */
if (!me->dvert) {
- ED_vgroup_data_create(&me->id);
+ BKE_object_defgroup_data_create(&me->id);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
}
@@ -2174,7 +2173,7 @@ static bool wpaint_ensure_data(bContext *C, wmOperator *op)
if (pchan) {
bDeformGroup *dg = defgroup_find_name(ob, pchan->name);
if (dg == NULL) {
- dg = ED_vgroup_add_name(ob, pchan->name); /* sets actdef */
+ dg = BKE_object_defgroup_add_name(ob, pchan->name); /* sets actdef */
}
else {
int actdef = 1 + BLI_findindex(&ob->defbase, dg);
@@ -2186,7 +2185,7 @@ static bool wpaint_ensure_data(bContext *C, wmOperator *op)
}
}
if (BLI_listbase_is_empty(&ob->defbase)) {
- ED_vgroup_add(ob);
+ BKE_object_defgroup_add(ob);
}
/* ensure we don't try paint onto an invalid group */
@@ -2235,10 +2234,10 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UN
/* set up auto-normalize, and generate map for detecting which
* vgroups affect deform bones */
- wpd->defbase_tot = BLI_countlist(&ob->defbase);
- wpd->lock_flags = BKE_objdef_lock_flags_get(ob, wpd->defbase_tot);
+ wpd->defbase_tot = BLI_listbase_count(&ob->defbase);
+ wpd->lock_flags = BKE_object_defgroup_lock_flags_get(ob, wpd->defbase_tot);
if (ts->auto_normalize || ts->multipaint || wpd->lock_flags) {
- wpd->vgroup_validmap = BKE_objdef_validmap_get(ob, wpd->defbase_tot);
+ wpd->vgroup_validmap = BKE_object_defgroup_validmap_get(ob, wpd->defbase_tot);
}
/* painting on subsurfs should give correct points too, this returns me->totvert amount */
@@ -2318,7 +2317,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* *** setup WeightPaintInfo - pass onto do_weight_paint_vertex *** */
wpi.defbase_tot = wpd->defbase_tot;
- wpi.defbase_sel = BKE_objdef_selected_get(ob, wpi.defbase_tot, &wpi.defbase_tot_sel);
+ wpi.defbase_sel = BKE_object_defgroup_selected_get(ob, wpi.defbase_tot, &wpi.defbase_tot_sel);
if (wpi.defbase_tot_sel == 0 && ob->actdef > 0) {
wpi.defbase_tot_sel = 1;
}
@@ -2682,7 +2681,7 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
paint_cursor_start(C, vertex_paint_poll);
- BKE_paint_init(&vp->paint, PAINT_CURSOR_VERTEX_PAINT);
+ BKE_paint_init(&scene->toolsettings->unified_paint_settings, &vp->paint, PAINT_CURSOR_VERTEX_PAINT);
}
/* update modifier stack for mapping requirements */
@@ -3024,7 +3023,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
* avoid this if we can! */
DAG_id_tag_update(ob->data, 0);
}
- else if (!GPU_buffer_legacy(ob->derivedFinal)) {
+ else {
/* If using new VBO drawing, mark mcol as dirty to force colors gpu buffer refresh! */
ob->derivedFinal->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW;
}
@@ -3217,7 +3216,7 @@ static void gradientVert_update(DMGradient_userData *grad_data, int index)
/* no need to clamp 'alpha' yet */
/* adjust weight */
- alpha = BKE_brush_curve_strength_clamp(grad_data->brush, alpha, 1.0f);
+ alpha = BKE_brush_curve_strength(grad_data->brush, alpha, 1.0f);
if (alpha != 0.0f) {
MDeformVert *dv = &me->dvert[index];
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 0e0012c198f..ea046b7d4d5 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -40,7 +40,6 @@
#include "BLI_dial.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
-#include "BLI_threads.h"
#include "BLF_translation.h"
@@ -56,8 +55,8 @@
#include "BKE_brush.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
-#include "BKE_crazyspace.h"
#include "BKE_depsgraph.h"
+#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_library.h"
@@ -85,9 +84,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RE_render_ext.h"
-
#include "GPU_buffers.h"
+#include "GPU_extensions.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -106,6 +104,8 @@
#if defined(__APPLE__) && defined _OPENMP
#include <sys/sysctl.h>
+#include "BLI_threads.h"
+
/* Query how many cores not counting HT aka physical cores we've got. */
static int system_physical_thread_count(void)
{
@@ -116,33 +116,6 @@ static int system_physical_thread_count(void)
}
#endif /* __APPLE__ */
-void ED_sculpt_stroke_get_average(Object *ob, float stroke[3])
-{
- if (ob->sculpt->last_stroke_valid && ob->sculpt->average_stroke_counter > 0) {
- float fac = 1.0f / ob->sculpt->average_stroke_counter;
- mul_v3_v3fl(stroke, ob->sculpt->average_stroke_accum, fac);
- }
- else {
- copy_v3_v3(stroke, ob->obmat[3]);
- }
-}
-
-bool ED_sculpt_minmax(bContext *C, float min[3], float max[3])
-{
- Object *ob = CTX_data_active_object(C);
-
- if (ob && ob->sculpt && ob->sculpt->last_stroke_valid) {
- copy_v3_v3(min, ob->sculpt->last_stroke);
- copy_v3_v3(max, ob->sculpt->last_stroke);
-
- return 1;
- }
- else {
- return 0;
- }
-}
-
-
/* Check if there are any active modifiers in stack (used for flushing updates at enter/exit sculpt mode) */
static bool sculpt_has_active_modifiers(Scene *scene, Object *ob)
{
@@ -2917,19 +2890,13 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
{
Mesh *me = (Mesh *)ob->data;
float (*ofs)[3] = NULL;
- int a, is_basis = 0;
+ int a;
+ const int kb_act_idx = ob->shapenr - 1;
KeyBlock *currkey;
/* for relative keys editing of base should update other keys */
- if (me->key->type == KEY_RELATIVE)
- for (currkey = me->key->block.first; currkey; currkey = currkey->next)
- if (ob->shapenr - 1 == currkey->relative) {
- is_basis = 1;
- break;
- }
-
- if (is_basis) {
- ofs = BKE_key_convert_to_vertcos(ob, kb);
+ if (BKE_keyblock_is_basis(me->key, kb_act_idx)) {
+ ofs = BKE_keyblock_convert_to_vertcos(ob, kb);
/* calculate key coord offsets (from previous location) */
for (a = 0; a < me->totvert; a++) {
@@ -2937,14 +2904,10 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
}
/* apply offsets on other keys */
- currkey = me->key->block.first;
- while (currkey) {
- int apply_offset = ((currkey != kb) && (ob->shapenr - 1 == currkey->relative));
-
- if (apply_offset)
- BKE_key_convert_from_offset(ob, currkey, ofs);
-
- currkey = currkey->next;
+ for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
+ if ((currkey != kb) && (currkey->relative == kb_act_idx)) {
+ BKE_keyblock_update_from_offset(ob, currkey, ofs);
+ }
}
MEM_freeN(ofs);
@@ -2960,14 +2923,14 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
BKE_mesh_calc_normals(me);
}
- /* apply new coords on active key block */
- BKE_key_convert_from_vertcos(ob, kb, vertCos);
+ /* apply new coords on active key block, no need to re-allocate kb->data here! */
+ BKE_keyblock_update_from_vertcos(ob, kb, vertCos);
}
/* Note: we do the topology update before any brush actions to avoid
* issues with the proxies. The size of the proxy can't change, so
* topology must be updated first. */
-static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush)
+static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *UNUSED(ups))
{
SculptSession *ss = ob->sculpt;
SculptSearchSphereData data;
@@ -3028,13 +2991,10 @@ static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush)
/* update average stroke position */
copy_v3_v3(location, ss->cache->true_location);
mul_m4_v3(ob->obmat, location);
-
- add_v3_v3(ob->sculpt->average_stroke_accum, location);
- ob->sculpt->average_stroke_counter++;
}
}
-static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
+static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups)
{
SculptSession *ss = ob->sculpt;
SculptSearchSphereData data;
@@ -3148,8 +3108,10 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
copy_v3_v3(location, ss->cache->true_location);
mul_m4_v3(ob->obmat, location);
- add_v3_v3(ob->sculpt->average_stroke_accum, location);
- ob->sculpt->average_stroke_counter++;
+ add_v3_v3(ups->average_stroke_accum, location);
+ ups->average_stroke_counter++;
+ /* update last stroke position */
+ ups->last_stroke_valid = true;
}
}
@@ -3358,9 +3320,9 @@ static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm,
}
}
-typedef void (*BrushActionFunc)(Sculpt *sd, Object *ob, Brush *brush);
+typedef void (*BrushActionFunc)(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups);
-static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush,
+static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups,
BrushActionFunc action,
const char symm, const int axis,
const float feather)
@@ -3372,7 +3334,7 @@ static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush,
const float angle = 2 * M_PI * i / sd->radial_symm[axis - 'X'];
ss->cache->radial_symmetry_pass = i;
calc_brushdata_symm(sd, ss->cache, symm, axis, angle, feather);
- action(sd, ob, brush);
+ action(sd, ob, brush, ups);
}
}
@@ -3410,11 +3372,11 @@ static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob,
cache->radial_symmetry_pass = 0;
calc_brushdata_symm(sd, cache, i, 0, 0, feather);
- action(sd, ob, brush);
+ action(sd, ob, brush, ups);
- do_radial_symmetry(sd, ob, brush, action, i, 'X', feather);
- do_radial_symmetry(sd, ob, brush, action, i, 'Y', feather);
- do_radial_symmetry(sd, ob, brush, action, i, 'Z', feather);
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather);
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'Y', feather);
+ do_radial_symmetry(sd, ob, brush, ups, action, i, 'Z', feather);
}
}
}
@@ -4166,9 +4128,6 @@ static bool sculpt_brush_stroke_init(bContext *C, wmOperator *op)
is_smooth = sculpt_any_smooth_mode(brush, NULL, mode);
BKE_sculpt_update_mesh_elements(scene, sd, ob, is_smooth, need_mask);
- zero_v3(ob->sculpt->average_stroke_accum);
- ob->sculpt->average_stroke_counter = 0;
-
return 1;
}
@@ -4290,14 +4249,14 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st
sculpt_restore_mesh(sd, ob);
if (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT) {
- BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
- sd->constant_detail / 100.0f);
+ BKE_pbvh_bmesh_detail_size_set(ss->pbvh, sd->constant_detail / 100.0f);
}
else {
- BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
- (ss->cache->radius /
- (float)ups->pixel_radius) *
- (float)sd->detail_size / 0.4f);
+ BKE_pbvh_bmesh_detail_size_set(
+ ss->pbvh,
+ (ss->cache->radius /
+ (float)ups->pixel_radius) *
+ (float)(sd->detail_size * U.pixelsize) / 0.4f);
}
if (sculpt_stroke_dynamic_topology(ss, brush)) {
@@ -4375,10 +4334,6 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
}
}
- /* update last stroke position */
- ob->sculpt->last_stroke_valid = 1;
- ED_sculpt_stroke_get_average(ob, ob->sculpt->last_stroke);
-
sculpt_cache_free(ss->cache);
ss->cache = NULL;
@@ -4696,6 +4651,10 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(o
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
+ if (!G.background && !GPU_vertex_buffer_support()) {
+ return OPERATOR_CANCELLED;
+ }
+
if (ss->bm) {
sculpt_undo_push_begin("Dynamic topology disable");
sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END);
@@ -4712,33 +4671,45 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(o
}
-static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, bool vdata, bool modifiers)
+static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, bool vdata, bool modifiers, bool novertexbuf)
{
- uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Warning!"), ICON_ERROR);
- uiLayout *layout = uiPupMenuLayout(pup);
+ if (novertexbuf) {
+ uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Error!"), ICON_ERROR);
+ uiLayout *layout = UI_popup_menu_layout(pup);
- if (vdata) {
- const char *msg_error = TIP_("Vertex Data Detected!");
- const char *msg = TIP_("Dyntopo will not preserve vertex colors, UVs, or other customdata");
- uiItemL(layout, msg_error, ICON_INFO);
- uiItemL(layout, msg, ICON_NONE);
- uiItemS(layout);
- }
+ uiItemL(layout, "Dyntopo is not supported on this system", ICON_INFO);
+ uiItemL(layout, "No vertex buffer support detected", ICON_NONE);
- if (modifiers) {
- const char *msg_error = TIP_("Generative Modifiers Detected!");
- const char *msg = TIP_("Keeping the modifiers will increase polycount when returning to object mode");
+ uiItemFullO_ptr(layout, ot, IFACE_("OK"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0);
- uiItemL(layout, msg_error, ICON_INFO);
- uiItemL(layout, msg, ICON_NONE);
- uiItemS(layout);
+ UI_popup_menu_end(C, pup);
}
+ else {
+ uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Warning!"), ICON_ERROR);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+
+ if (vdata) {
+ const char *msg_error = TIP_("Vertex Data Detected!");
+ const char *msg = TIP_("Dyntopo will not preserve vertex colors, UVs, or other customdata");
+ uiItemL(layout, msg_error, ICON_INFO);
+ uiItemL(layout, msg, ICON_NONE);
+ uiItemS(layout);
+ }
- uiItemFullO_ptr(layout, ot, IFACE_("OK"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0);
+ if (modifiers) {
+ const char *msg_error = TIP_("Generative Modifiers Detected!");
+ const char *msg = TIP_("Keeping the modifiers will increase polycount when returning to object mode");
- uiPupMenuEnd(C, pup);
+ uiItemL(layout, msg_error, ICON_INFO);
+ uiItemL(layout, msg, ICON_NONE);
+ uiItemS(layout);
+ }
- return OPERATOR_CANCELLED;
+ uiItemFullO_ptr(layout, ot, IFACE_("OK"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0);
+
+ UI_popup_menu_end(C, pup);
+ }
+ return OPERATOR_INTERFACE;
}
@@ -4748,6 +4719,10 @@ static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op, co
Mesh *me = ob->data;
SculptSession *ss = ob->sculpt;
+ if (!GPU_vertex_buffer_support()) {
+ dyntopo_warning_popup(C, op->type, false, false, true);
+ }
+
if (!ss->bm) {
Scene *scene = CTX_data_scene(C);
ModifierData *md;
@@ -4782,7 +4757,7 @@ static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op, co
if (vdata || modifiers) {
/* The mesh has customdata that will be lost, let the user confirm this is OK */
- return dyntopo_warning_popup(C, op->type, vdata, modifiers);
+ return dyntopo_warning_popup(C, op->type, vdata, modifiers, false);
}
}
@@ -4995,7 +4970,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
"Object has negative scale, sculpting may be unpredictable");
}
- BKE_paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT);
+ BKE_paint_init(&ts->unified_paint_settings, &ts->sculpt->paint, PAINT_CURSOR_SCULPT);
paint_cursor_start(C, sculpt_poll_view3d);
}
@@ -5188,6 +5163,46 @@ static void SCULPT_OT_sample_detail_size(wmOperatorType *ot)
RNA_def_int_array(ot->srna, "location", 2, NULL, 0, SHRT_MAX, "Location", "Screen Coordinates of sampling", 0, SHRT_MAX);
}
+
+static int sculpt_set_detail_size_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+
+ PointerRNA props_ptr;
+ wmOperatorType *ot = WM_operatortype_find("WM_OT_radial_control", true);
+
+ WM_operator_properties_create_ptr(&props_ptr, ot);
+
+ if (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT) {
+ set_brush_rc_props(&props_ptr, "sculpt", "constant_detail", NULL, 0);
+ RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.constant_detail");
+ }
+ else {
+ set_brush_rc_props(&props_ptr, "sculpt", "detail_size", NULL, 0);
+ RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_size");
+ }
+
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
+
+ WM_operator_properties_free(&props_ptr);
+
+ return OPERATOR_FINISHED;
+}
+
+static void SCULPT_OT_set_detail_size(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Detail Size";
+ ot->idname = "SCULPT_OT_set_detail_size";
+ ot->description = "Set the mesh detail (either relative or constant one, depending on current dyntopo mode)";
+
+ /* api callbacks */
+ ot->exec = sculpt_set_detail_size_exec;
+ ot->poll = sculpt_and_dynamic_topology_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
void ED_operatortypes_sculpt(void)
{
WM_operatortype_append(SCULPT_OT_brush_stroke);
@@ -5198,4 +5213,5 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_symmetrize);
WM_operatortype_append(SCULPT_OT_detail_flood_fill);
WM_operatortype_append(SCULPT_OT_sample_detail_size);
+ WM_operatortype_append(SCULPT_OT_set_detail_size);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 91f80a4fc40..a4adbc6bca8 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -104,7 +104,7 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
if (unode->maxvert) {
/* regular mesh restore */
- if (ss->kb && strcmp(ss->kb->name, unode->shapeName)) {
+ if (ss->kb && !STREQ(ss->kb->name, unode->shapeName)) {
/* shape key has been changed before calling undo operator */
Key *key = BKE_key_from_object(ob);
@@ -127,7 +127,7 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
if (ss->kb) {
float (*vertCos)[3];
- vertCos = BKE_key_convert_to_vertcos(ob, ss->kb);
+ vertCos = BKE_keyblock_convert_to_vertcos(ob, ss->kb);
for (i = 0; i < unode->totvert; i++) {
if (ss->modifiers_active) {
@@ -404,7 +404,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
bool need_mask = false;
for (unode = lb->first; unode; unode = unode->next) {
- if (strcmp(unode->idname, ob->id.name) == 0) {
+ if (STREQ(unode->idname, ob->id.name)) {
if (unode->type == SCULPT_UNDO_MASK) {
/* is possible that we can't do the mask undo (below)
* because of the vertex count */
@@ -423,7 +423,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
return;
for (unode = lb->first; unode; unode = unode->next) {
- if (!(strcmp(unode->idname, ob->id.name) == 0))
+ if (!STREQ(unode->idname, ob->id.name))
continue;
/* check if undo data matches current data well enough to
@@ -550,7 +550,7 @@ static bool sculpt_undo_cleanup(bContext *C, ListBase *lb)
unode = lb->first;
- if (unode && strcmp(unode->idname, ob->id.name) != 0) {
+ if (unode && !STREQ(unode->idname, ob->id.name)) {
if (unode->bm_entry)
BM_log_cleanup_entry(unode->bm_entry);
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index d90eaafa379..a9feb9f48de 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -60,7 +60,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
#include "paint_intern.h"
#include "uvedit_intern.h"
@@ -237,7 +236,7 @@ void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings
settings->uvsculpt->paint.flags |= PAINT_SHOW_BRUSH;
}
- BKE_paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT);
+ BKE_paint_init(&settings->unified_paint_settings, &settings->uvsculpt->paint, PAINT_CURSOR_SCULPT);
settings->uvsculpt->paint.paint_cursor = WM_paint_cursor_activate(wm, uv_sculpt_brush_poll,
brush_drawcursor_uvsculpt, NULL);
@@ -558,15 +557,15 @@ static int uv_element_offset_from_face_get(UvElementMap *map, BMFace *efa, BMLoo
static unsigned int uv_edge_hash(const void *key)
{
- UvEdge *edge = (UvEdge *)key;
+ const UvEdge *edge = key;
return (BLI_ghashutil_uinthash(edge->uv2) +
BLI_ghashutil_uinthash(edge->uv1));
}
static bool uv_edge_compare(const void *a, const void *b)
{
- UvEdge *edge1 = (UvEdge *)a;
- UvEdge *edge2 = (UvEdge *)b;
+ const UvEdge *edge1 = a;
+ const UvEdge *edge2 = b;
if ((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)) {
return 0;
@@ -599,7 +598,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
UvEdge *edges;
GHash *edgeHash;
- GHashIterator *ghi;
+ GHashIterator gh_iter;
bool do_island_optimization = !(ts->uv_sculpt_settings & UV_SCULPT_ALL_ISLANDS);
int island_index = 0;
@@ -755,21 +754,15 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
uv_sculpt_stroke_exit(C, op);
return NULL;
}
- ghi = BLI_ghashIterator_new(edgeHash);
- if (!ghi) {
- BLI_ghash_free(edgeHash, NULL, NULL);
- MEM_freeN(edges);
- uv_sculpt_stroke_exit(C, op);
- return NULL;
- }
+
/* fill the edges with data */
- for (i = 0; !BLI_ghashIterator_done(ghi); BLI_ghashIterator_step(ghi)) {
- data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
+ i = 0;
+ GHASH_ITER (gh_iter, edgeHash) {
+ data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter));
}
data->totalUvEdges = BLI_ghash_size(edgeHash);
/* cleanup temporary stuff */
- BLI_ghashIterator_free(ghi);
BLI_ghash_free(edgeHash, NULL, NULL);
MEM_freeN(edges);
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 619fbd7f4c8..f3c6781b0fa 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -72,7 +72,6 @@
#include "ED_sound.h"
#include "ED_util.h"
-#include "sound_intern.h"
/******************** open sound operator ********************/
@@ -87,7 +86,7 @@ static void sound_open_init(bContext *C, wmOperator *op)
PropertyPointerRNA *pprop;
op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
- uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
+ UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop);
}
#ifdef WITH_AUDASPACE
@@ -143,7 +142,7 @@ static int sound_open_exec(bContext *C, wmOperator *op)
RNA_property_update(C, &pprop->ptr, pprop->prop);
}
- if (op->customdata) MEM_freeN(op->customdata);
+ MEM_freeN(op->customdata);
return OPERATOR_FINISHED;
}
@@ -184,7 +183,7 @@ static void SOUND_OT_open(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_SOUND | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
RNA_def_boolean(ot->srna, "mono", false, "Mono", "Mixdown the sound to mono");
@@ -206,7 +205,7 @@ static void SOUND_OT_open_mono(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_SOUND | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
RNA_def_boolean(ot->srna, "mono", true, "Mono", "Mixdown the sound to mono");
@@ -243,7 +242,7 @@ static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op)
}
SEQ_END
- fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven);
+ fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven);
if (fcu || driven)
scene->audio.flag |= AUDIO_VOLUME_ANIMATED;
else
@@ -400,7 +399,7 @@ static bool sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
if (item->value == container) {
const char **ext = snd_ext_sound;
while (*ext != NULL) {
- if (!strcmp(*ext + 1, item->name)) {
+ if (STREQ(*ext + 1, item->name)) {
extension = *ext;
break;
}
@@ -450,9 +449,9 @@ static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *even
static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
- return !(strcmp(prop_id, "filepath") == 0 ||
- strcmp(prop_id, "directory") == 0 ||
- strcmp(prop_id, "filename") == 0);
+ return !(STREQ(prop_id, "filepath") ||
+ STREQ(prop_id, "directory") ||
+ STREQ(prop_id, "filename"));
}
static void sound_mixdown_draw(bContext *C, wmOperator *op)
@@ -651,7 +650,7 @@ static void SOUND_OT_mixdown(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE, FILE_SPECIAL, FILE_SAVE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_SOUND, FILE_SPECIAL, FILE_SAVE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
#ifdef WITH_AUDASPACE
RNA_def_int(ot->srna, "accuracy", 1024, 1, 16777216, "Accuracy", "Sample accuracy, important for animation data (the lower the value, the more accurate)", 1, 16777216);
diff --git a/source/blender/editors/space_action/CMakeLists.txt b/source/blender/editors/space_action/CMakeLists.txt
index 96a1e74c882..50cf84079d2 100644
--- a/source/blender/editors/space_action/CMakeLists.txt
+++ b/source/blender/editors/space_action/CMakeLists.txt
@@ -22,6 +22,7 @@ set(INC
../include
../../blenkernel
../../blenlib
+ ../../blenfont
../../gpu
../../makesdna
../../makesrna
diff --git a/source/blender/editors/space_action/SConscript b/source/blender/editors/space_action/SConscript
index 2e2081b3c6e..20f31dd6399 100644
--- a/source/blender/editors/space_action/SConscript
+++ b/source/blender/editors/space_action/SConscript
@@ -38,6 +38,7 @@ incs = [
'../include',
'../../blenkernel',
'../../blenlib',
+ '../../blenfont',
'../../gpu',
'../../makesdna',
'../../makesrna',
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 335949e8495..a17cfa4d87c 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -112,7 +112,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
}
}
{ /* second pass: widgets */
- uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
+ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
size_t channel_index = 0;
y = (float)ACHANNEL_FIRST;
@@ -134,8 +134,8 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
channel_index++;
}
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
}
/* free tempolary channels */
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 091d3fe56b4..76c955d8bca 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -40,8 +40,12 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "DNA_anim_types.h"
#include "DNA_gpencil_types.h"
+#include "DNA_key_types.h"
+#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_mask_types.h"
@@ -52,6 +56,8 @@
#include "BKE_action.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_nla.h"
#include "BKE_context.h"
@@ -77,43 +83,167 @@
/* ************************************************************************** */
/* ACTION MANAGEMENT */
-/* ******************** New Action Operator *********************** */
+/* Helper function to find the active AnimData block from the Action Editor context */
+static AnimData *actedit_animdata_from_context(bContext *C)
+{
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ Object *ob = CTX_data_active_object(C);
+ AnimData *adt = NULL;
+
+ /* Get AnimData block to use */
+ if (saction->mode == SACTCONT_ACTION) {
+ /* Currently, "Action Editor" means object-level only... */
+ adt = ob->adt;
+ }
+ else if (saction->mode == SACTCONT_SHAPEKEY) {
+ Key *key = BKE_key_from_object(ob);
+ adt = key->adt;
+ }
+
+ return adt;
+}
-static int act_new_exec(bContext *C, wmOperator *UNUSED(op))
+/* Create new action */
+static bAction *action_create_new(bContext *C, bAction *oldact)
{
+ ScrArea *sa = CTX_wm_area(C);
+ bAction *action;
+
+ /* create action - the way to do this depends on whether we've got an
+ * existing one there already, in which case we make a copy of it
+ * (which is useful for "versioning" actions within the same file)
+ */
+ if (oldact && GS(oldact->id.name) == ID_AC) {
+ /* make a copy of the existing action */
+ action = BKE_action_copy(oldact);
+ }
+ else {
+ /* just make a new (empty) action */
+ action = add_empty_action(CTX_data_main(C), "Action");
+ }
+
+ /* when creating new ID blocks, there is already 1 user (as for all new datablocks),
+ * but the RNA pointer code will assign all the proper users instead, so we compensate
+ * for that here
+ */
+ BLI_assert(action->id.us == 1);
+ action->id.us--;
+
+ /* set ID-Root type */
+ if (sa->spacetype == SPACE_ACTION) {
+ SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
+
+ if (saction->mode == SACTCONT_SHAPEKEY)
+ action->idroot = ID_KE;
+ else
+ action->idroot = ID_OB;
+ }
+
+ return action;
+}
+
+/* Change the active action used by the action editor */
+static void actedit_change_action(bContext *C, bAction *act)
+{
+ bScreen *screen = CTX_wm_screen(C);
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+
PointerRNA ptr, idptr;
PropertyRNA *prop;
+
+ /* create RNA pointers and get the property */
+ RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, saction, &ptr);
+ prop = RNA_struct_find_property(&ptr, "action");
+
+ /* NOTE: act may be NULL here, so better to just use a cast here */
+ RNA_id_pointer_create((ID *)act, &idptr);
+
+ /* set the new pointer, and force a refresh */
+ RNA_property_pointer_set(&ptr, prop, idptr);
+ RNA_property_update(C, &ptr, prop);
+}
+
+/* ******************** New Action Operator *********************** */
+
+/* Criteria:
+ * 1) There must be an dopesheet/action editor, and it must be in a mode which uses actions...
+ * OR
+ * The NLA Editor is active (i.e. Animation Data panel -> new action)
+ * 2) The associated AnimData block must not be in tweakmode
+ */
+static int action_new_poll(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+
+ /* Check tweakmode is off (as you don't want to be tampering with the action in that case) */
+ /* NOTE: unlike for pushdown, this operator needs to be run when creating an action from nothing... */
+ if (!(scene->flag & SCE_NLA_EDIT_ON)) {
+ if (ED_operator_action_active(C)) {
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+
+ /* For now, actions are only for the active object, and on object and shapekey levels... */
+ return ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY);
+ }
+ else if (ED_operator_nla_active(C)) {
+ return true;
+ }
+ }
+
+ /* something failed... */
+ return false;
+}
+static int action_new_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ PointerRNA ptr, idptr;
+ PropertyRNA *prop;
+
/* hook into UI */
- uiIDContextProperty(C, &ptr, &prop);
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
if (prop) {
bAction *action = NULL, *oldact = NULL;
+ AnimData *adt = NULL;
PointerRNA oldptr;
- /* create action - the way to do this depends on whether we've got an
- * existing one there already, in which case we make a copy of it
- * (which is useful for "versioning" actions within the same file)
- */
oldptr = RNA_property_pointer_get(&ptr, prop);
oldact = (bAction *)oldptr.id.data;
- if (oldact && GS(oldact->id.name) == ID_AC) {
- /* make a copy of the existing action */
- action = BKE_action_copy(oldact);
+ /* stash the old action to prevent it from being lost */
+ if (ptr.type == &RNA_AnimData) {
+ adt = ptr.data;
}
- else {
- Main *bmain = CTX_data_main(C);
-
- /* just make a new (empty) action */
- action = add_empty_action(bmain, "Action");
+ else if (ptr.type == &RNA_SpaceDopeSheetEditor) {
+ adt = actedit_animdata_from_context(C);
}
- /* when creating new ID blocks, use is already 1 (fake user),
- * but RNA pointer use also increases user, so this compensates it
- */
- action->id.us--;
+ /* Perform stashing operation - But only if there is an action */
+ if (adt && oldact) {
+ /* stash the action */
+ if (BKE_nla_action_stash(adt)) {
+ /* The stash operation will remove the user already
+ * (and unlink the action from the AnimData action slot).
+ * Hence, we must unset the ref to the action in the
+ * action editor too (if this is where we're being called from)
+ * first before setting the new action once it is created,
+ * or else the user gets decremented twice!
+ */
+ if (ptr.type == &RNA_SpaceDopeSheetEditor) {
+ SpaceAction *saction = (SpaceAction *)ptr.data;
+ saction->action = NULL;
+ }
+ }
+ else {
+ //printf("WARNING: Failed to stash %s. It may already exist in the NLA stack though\n", oldact->id.name);
+ }
+ }
+ /* create action */
+ action = action_create_new(C, oldact);
+
+ /* set this new action
+ * NOTE: we can't use actedit_change_action, as this function is also called from the NLA
+ */
RNA_id_pointer_create(&action->id, &idptr);
RNA_property_pointer_set(&ptr, prop, idptr);
RNA_property_update(C, &ptr, prop);
@@ -133,9 +263,231 @@ void ACTION_OT_new(wmOperatorType *ot)
ot->description = "Create new action";
/* api callbacks */
- ot->exec = act_new_exec;
- /* NOTE: this is used in the NLA too... */
- //ot->poll = ED_operator_action_active;
+ ot->exec = action_new_exec;
+ ot->poll = action_new_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ******************* Action Push-Down Operator ******************** */
+
+/* Criteria:
+ * 1) There must be an dopesheet/action editor, and it must be in a mode which uses actions
+ * 2) There must be an action active
+ * 3) The associated AnimData block must not be in tweakmode
+ */
+static int action_pushdown_poll(bContext *C)
+{
+ if (ED_operator_action_active(C)) {
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+
+ /* Check for actions and that tweakmode is off */
+ if ((saction->action) && !(scene->flag & SCE_NLA_EDIT_ON)) {
+ /* For now, actions are only for the active object, and on object and shapekey levels... */
+ if (saction->mode == SACTCONT_ACTION) {
+ return (ob->adt != NULL);
+ }
+ else if (saction->mode == SACTCONT_SHAPEKEY) {
+ Key *key = BKE_key_from_object(ob);
+
+ return (key && key->adt);
+ }
+ }
+ }
+
+ /* something failed... */
+ return false;
+}
+
+static int action_pushdown_exec(bContext *C, wmOperator *op)
+{
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ AnimData *adt = actedit_animdata_from_context(C);
+
+ /* Do the deed... */
+ if (adt) {
+ /* Perform the pushdown operation
+ * - This will deal with all the AnimData-side usercounts
+ */
+ if (action_has_motion(adt->action) == 0) {
+ /* action may not be suitable... */
+ BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* action can be safely added */
+ BKE_nla_action_pushdown(adt);
+ }
+
+ /* Stop displaying this action in this editor
+ * NOTE: The editor itself doesn't set a user...
+ */
+ saction->action = NULL;
+ }
+
+ /* Send notifiers that stuff has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void ACTION_OT_push_down(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Push Down Action";
+ ot->idname = "ACTION_OT_push_down";
+ ot->description = "Push action down on to the NLA stack as a new strip";
+
+ /* callbacks */
+ ot->exec = action_pushdown_exec;
+ ot->poll = action_pushdown_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ******************* Action Stash Operator ******************** */
+
+static int action_stash_exec(bContext *C, wmOperator *op)
+{
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ AnimData *adt = actedit_animdata_from_context(C);
+
+ /* Perform stashing operation */
+ if (adt) {
+ /* don't do anything if this action is empty... */
+ if (action_has_motion(adt->action) == 0) {
+ /* action may not be suitable... */
+ BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* stash the action */
+ if (BKE_nla_action_stash(adt)) {
+ /* The stash operation will remove the user already,
+ * so the flushing step later shouldn't double up
+ * the usercount fixes. Hence, we must unset this ref
+ * first before setting the new action.
+ */
+ saction->action = NULL;
+ }
+ else {
+ /* action has already been added - simply warn about this, and clear */
+ BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
+ }
+
+ /* clear action refs from editor, and then also the backing data (not necessary) */
+ actedit_change_action(C, NULL);
+ }
+ }
+
+ /* Send notifiers that stuff has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void ACTION_OT_stash(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Stash Action";
+ ot->idname = "ACTION_OT_stash";
+ ot->description = "Store this action in the NLA stack as a non-contributing strip for later use";
+
+ /* callbacks */
+ ot->exec = action_stash_exec;
+ ot->poll = action_pushdown_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_boolean(ot->srna, "create_new", true, "Create New Action",
+ "Create a new action once the existing one has been safely stored");
+}
+
+/* ----------------- */
+
+/* Criteria:
+ * 1) There must be an dopesheet/action editor, and it must be in a mode which uses actions
+ * 2) The associated AnimData block must not be in tweakmode
+ */
+static int action_stash_create_poll(bContext *C)
+{
+ if (ED_operator_action_active(C)) {
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ Scene *scene = CTX_data_scene(C);
+
+ /* Check tweakmode is off (as you don't want to be tampering with the action in that case) */
+ /* NOTE: unlike for pushdown, this operator needs to be run when creating an action from nothing... */
+ if (!(scene->flag & SCE_NLA_EDIT_ON)) {
+ /* For now, actions are only for the active object, and on object and shapekey levels... */
+ return ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY);
+ }
+ }
+
+ /* something failed... */
+ return false;
+}
+
+static int action_stash_create_exec(bContext *C, wmOperator *op)
+{
+ SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
+ AnimData *adt = actedit_animdata_from_context(C);
+
+ /* Check for no action... */
+ if (saction->action == NULL) {
+ /* just create a new action */
+ bAction *action = action_create_new(C, NULL);
+ actedit_change_action(C, action);
+ }
+ else if (adt) {
+ /* Perform stashing operation */
+ if (action_has_motion(adt->action) == 0) {
+ /* don't do anything if this action is empty... */
+ BKE_report(op->reports, RPT_WARNING, "Action must have at least one keyframe or F-Modifier");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* stash the action */
+ if (BKE_nla_action_stash(adt)) {
+ bAction *new_action = NULL;
+
+ /* create new action not based on the old one (since the "new" operator already does that) */
+ new_action = action_create_new(C, NULL);
+
+ /* The stash operation will remove the user already,
+ * so the flushing step later shouldn't double up
+ * the usercount fixes. Hence, we must unset this ref
+ * first before setting the new action.
+ */
+ saction->action = NULL;
+ actedit_change_action(C, new_action);
+ }
+ else {
+ /* action has already been added - simply warn about this, and clear */
+ BKE_report(op->reports, RPT_ERROR, "Action has already been stashed");
+ actedit_change_action(C, NULL);
+ }
+ }
+ }
+
+ /* Send notifiers that stuff has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void ACTION_OT_stash_and_create(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Stash Action";
+ ot->idname = "ACTION_OT_stash_and_create";
+ ot->description = "Store this action in the NLA stack as a non-contributing strip for later use, and create a new action";
+
+ /* callbacks */
+ ot->exec = action_stash_create_exec;
+ ot->poll = action_stash_create_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -545,7 +897,7 @@ static short copy_action_keys(bAnimContext *ac)
static short paste_action_keys(bAnimContext *ac,
- const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode)
+ const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
{
ListBase anim_data = {NULL, NULL};
int filter, ok = 0;
@@ -562,7 +914,7 @@ static short paste_action_keys(bAnimContext *ac,
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* paste keyframes */
- ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode);
+ ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
/* clean up */
ANIM_animdata_freelist(&anim_data);
@@ -622,6 +974,7 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op)
const eKeyPasteOffset offset_mode = RNA_enum_get(op->ptr, "offset");
const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge");
+ const bool flipped = RNA_boolean_get(op->ptr, "flipped");
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
@@ -638,7 +991,7 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op)
}
else {
/* non-zero return means an error occurred while trying to paste */
- if (paste_action_keys(&ac, offset_mode, merge_mode)) {
+ if (paste_action_keys(&ac, offset_mode, merge_mode, flipped)) {
return OPERATOR_CANCELLED;
}
}
@@ -651,6 +1004,7 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op)
void ACTION_OT_paste(wmOperatorType *ot)
{
+ PropertyRNA *prop;
/* identifiers */
ot->name = "Paste Keyframes";
ot->idname = "ACTION_OT_paste";
@@ -667,6 +1021,8 @@ void ACTION_OT_paste(wmOperatorType *ot)
/* props */
RNA_def_enum(ot->srna, "offset", keyframe_paste_offset_items, KEYFRAME_PASTE_OFFSET_CFRA_START, "Offset", "Paste time offset of keys");
RNA_def_enum(ot->srna, "merge", keyframe_paste_merge_items, KEYFRAME_PASTE_MERGE_MIX, "Type", "Method of merging pasted keys and existing");
+ prop = RNA_def_boolean(ot->srna, "flipped", false, "Flipped", "Paste keyframes from mirrored bones if they exist");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ******************** Insert Keyframes Operator ************************* */
@@ -965,8 +1321,11 @@ static int actkeys_clean_exec(bContext *C, wmOperator *op)
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
+
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented");
return OPERATOR_PASS_THROUGH;
+ }
/* get cleaning threshold */
thresh = RNA_float_get(op->ptr, "threshold");
@@ -1025,15 +1384,18 @@ static void sample_action_keys(bAnimContext *ac)
/* ------------------- */
-static int actkeys_sample_exec(bContext *C, wmOperator *UNUSED(op))
+static int actkeys_sample_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
+
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented");
return OPERATOR_PASS_THROUGH;
+ }
/* sample keyframes */
sample_action_keys(&ac);
@@ -1138,8 +1500,11 @@ static int actkeys_expo_exec(bContext *C, wmOperator *op)
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
+
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented");
return OPERATOR_PASS_THROUGH;
+ }
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
@@ -1209,8 +1574,11 @@ static int actkeys_ipo_exec(bContext *C, wmOperator *op)
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
+
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented");
return OPERATOR_PASS_THROUGH;
+ }
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
@@ -1288,8 +1656,11 @@ static int actkeys_handletype_exec(bContext *C, wmOperator *op)
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
+
+ if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented");
return OPERATOR_PASS_THROUGH;
+ }
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
@@ -1324,7 +1695,7 @@ void ACTION_OT_handle_type(wmOperatorType *ot)
/* ******************** Set Keyframe-Type Operator *********************** */
-/* this function is responsible for setting interpolation mode for keyframes */
+/* this function is responsible for setting keyframe type for keyframes */
static void setkeytype_action_keys(bAnimContext *ac, short mode)
{
ListBase anim_data = {NULL, NULL};
@@ -1349,6 +1720,29 @@ static void setkeytype_action_keys(bAnimContext *ac, short mode)
ANIM_animdata_freelist(&anim_data);
}
+/* this function is responsible for setting the keyframe type for Grease Pencil frames */
+static void setkeytype_gpencil_keys(bAnimContext *ac, short mode)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through each layer */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ ED_gplayer_frames_keytype_set(ale->data, mode);
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
+}
+
/* ------------------- */
static int actkeys_keytype_exec(bContext *C, wmOperator *op)
@@ -1359,14 +1753,22 @@ static int actkeys_keytype_exec(bContext *C, wmOperator *op)
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
- if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK))
+
+ if (ac.datatype == ANIMCONT_MASK) {
+ BKE_report(op->reports, RPT_ERROR, "Not implemented for Masks");
return OPERATOR_PASS_THROUGH;
+ }
/* get handle setting mode */
mode = RNA_enum_get(op->ptr, "type");
/* set handle type */
- setkeytype_action_keys(&ac, mode);
+ if (ac.datatype == ANIMCONT_GPENCIL) {
+ setkeytype_gpencil_keys(&ac, mode);
+ }
+ else {
+ setkeytype_action_keys(&ac, mode);
+ }
/* set notifier that keyframe properties have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index 8f39a38157a..61d4249ae20 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -101,6 +101,9 @@ void ACTION_OT_snap(struct wmOperatorType *ot);
void ACTION_OT_mirror(struct wmOperatorType *ot);
void ACTION_OT_new(struct wmOperatorType *ot);
+void ACTION_OT_push_down(struct wmOperatorType *ot);
+void ACTION_OT_stash(struct wmOperatorType *ot);
+void ACTION_OT_stash_and_create(struct wmOperatorType *ot);
void ACTION_OT_markers_make_local(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index b99419dec20..8c706d8da57 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -35,7 +35,6 @@
#include "DNA_space_types.h"
-#include "BLI_utildefines.h"
#include "ED_anim_api.h"
#include "ED_markers.h"
@@ -44,7 +43,6 @@
#include "action_intern.h"
#include "RNA_access.h"
-#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -79,7 +77,11 @@ void action_operatortypes(void)
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);
+ WM_operatortype_append(ACTION_OT_push_down);
+ WM_operatortype_append(ACTION_OT_stash);
+ WM_operatortype_append(ACTION_OT_stash_and_create);
WM_operatortype_append(ACTION_OT_previewrange_set);
WM_operatortype_append(ACTION_OT_view_all);
@@ -207,9 +209,13 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* copy/paste */
WM_keymap_add_item(keymap, "ACTION_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ACTION_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
+ kmi = WM_keymap_add_item(keymap, "ACTION_OT_paste", VKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "flipped", true);
#ifdef __APPLE__
WM_keymap_add_item(keymap, "ACTION_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "ACTION_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
+ kmi = WM_keymap_add_item(keymap, "ACTION_OT_paste", VKEY, KM_PRESS, KM_OSKEY | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "flipped", true);
#endif
/* auto-set range */
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 7ca8968a705..5d0b34a2e0c 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -197,8 +197,8 @@ static void action_main_area_draw(const bContext *C, ARegion *ar)
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
- flag = (ac.markers && (ac.markers != &ac.scene->markers)) ? DRAW_MARKERS_LOCAL : 0;
- draw_markers_time(C, flag);
+ flag = ((ac.markers && (ac.markers != &ac.scene->markers)) ? DRAW_MARKERS_LOCAL : 0) | DRAW_MARKERS_MARGIN;
+ ED_markers_draw(C, flag);
/* preview range */
UI_view2d_view_ortho(v2d);
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index c8431d58bf5..01f0d1ae54f 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -32,7 +32,6 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_windowmanager_types.h"
@@ -61,7 +60,6 @@
#include "ED_space_api.h"
#include "ED_sound.h"
#include "ED_uvedit.h"
-#include "ED_view3d.h"
#include "ED_mball.h"
#include "ED_logic.h"
#include "ED_clip.h"
@@ -122,7 +120,7 @@ void ED_spacetypes_init(void)
ED_operatortypes_io();
ED_operatortypes_view2d();
- UI_buttons_operatortypes();
+ ED_button_operatortypes();
/* register operators */
spacetypes = BKE_spacetypes_list();
@@ -155,6 +153,7 @@ void ED_spacemacros_init(void)
ED_operatormacros_mask();
ED_operatormacros_sequencer();
ED_operatormacros_paint();
+ ED_operatormacros_gpencil();
/* register dropboxes (can use macros) */
spacetypes = BKE_spacetypes_list();
@@ -318,7 +317,3 @@ void ED_spacetype_xxx(void)
}
/* ****************************** end template *********************** */
-
-
-
-
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 524a42ba388..73091e7f261 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -1103,11 +1103,11 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
block = uiLayoutGetBlock(row);
- uiBlockSetEmboss(block, UI_EMBOSSN);
- but = uiDefIconButBitC(block, ICONTOG, SB_PIN_CONTEXT, 0, ICON_UNPINNED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &sbuts->flag,
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ but = uiDefIconButBitC(block, UI_BTYPE_ICON_TOGGLE, SB_PIN_CONTEXT, 0, ICON_UNPINNED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &sbuts->flag,
0, 0, 0, 0, TIP_("Follow context or keep fixed datablock displayed"));
- uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- uiButSetFunc(but, pin_cb, NULL, NULL);
+ UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
+ UI_but_func_set(but, pin_cb, NULL, NULL);
for (a = 0; a < path->len; a++) {
ptr = &path->ptr[a];
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index b651d684bf6..ba0c22a4ade 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -72,12 +72,12 @@ static int toolbox_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UN
RNA_pointer_create(&sc->id, &RNA_SpaceProperties, sbuts, &ptr);
- pup = uiPupMenuBegin(C, IFACE_("Align"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("Align"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiItemsEnumR(layout, &ptr, "align");
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
void BUTTONS_OT_toolbox(wmOperatorType *ot)
@@ -176,7 +176,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
- uiFileBrowseContextProperty(C, &ptr, &prop);
+ UI_context_active_but_prop_get_filebrowser(C, &ptr, &prop);
if (!prop)
return OPERATOR_CANCELLED;
@@ -186,6 +186,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* useful yet irritating feature, Shift+Click to open the file
* Alt+Click to browse a folder in the OS's browser */
if (event->shift || event->alt) {
+ wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
PointerRNA props_ptr;
if (event->alt) {
@@ -195,15 +196,16 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
- WM_operator_properties_create(&props_ptr, "WM_OT_path_open");
+ WM_operator_properties_create_ptr(&props_ptr, ot);
RNA_string_set(&props_ptr, "filepath", str);
- WM_operator_name_call(C, "WM_OT_path_open", WM_OP_EXEC_DEFAULT, &props_ptr);
+ WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr);
WM_operator_properties_free(&props_ptr);
MEM_freeN(str);
return OPERATOR_CANCELLED;
}
else {
+ PropertyRNA *prop_relpath;
const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath";
fbo = MEM_callocN(sizeof(FileBrowseOp), "FileBrowseOp");
fbo->ptr = ptr;
@@ -215,10 +217,10 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* normally ED_fileselect_get_params would handle this but we need to because of stupid
* user-prefs exception - campbell */
- if (RNA_struct_find_property(op->ptr, "relative_path")) {
- if (!RNA_struct_property_is_set(op->ptr, "relative_path")) {
+ if ((prop_relpath = RNA_struct_find_property(op->ptr, "relative_path"))) {
+ if (!RNA_property_is_set(op->ptr, prop_relpath)) {
/* annoying exception!, if were dealing with the user prefs, default relative to be off */
- RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS && (ptr.data != &U));
+ RNA_property_boolean_set(op->ptr, prop_relpath, U.flag & USER_RELPATHS && (ptr.data != &U));
}
}
WM_event_add_fileselect(C, op);
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 020d477fc39..a263f22e072 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -61,7 +61,9 @@
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
-#include "BKE_freestyle.h"
+#ifdef WITH_FREESTYLE
+# include "BKE_freestyle.h"
+#endif
#include "RNA_access.h"
@@ -256,7 +258,7 @@ static void buttons_texture_user_property_add(ListBase *users, ID *id,
user->category = category;
user->icon = icon;
user->name = name;
- user->index = BLI_countlist(users);
+ user->index = BLI_listbase_count(users);
BLI_addtail(users, user);
}
@@ -273,7 +275,7 @@ static void buttons_texture_user_node_add(ListBase *users, ID *id,
user->category = category;
user->icon = icon;
user->name = name;
- user->index = BLI_countlist(users);
+ user->index = BLI_listbase_count(users);
BLI_addtail(users, user);
}
@@ -468,7 +470,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
}
else {
/* set one user as active based on active index */
- if (ct->index >= BLI_countlist(&ct->users))
+ if (ct->index == BLI_listbase_count_ex(&ct->users, ct->index + 1))
ct->index = 0;
ct->user = BLI_findlink(&ct->users, ct->index);
@@ -557,7 +559,7 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUS
char name[UI_MAX_NAME_STR];
/* add label per category */
- if (!last_category || strcmp(last_category, user->category) != 0) {
+ if (!last_category || !STREQ(last_category, user->category)) {
uiItemL(layout, user->category, ICON_NONE);
but = block->buttons.last;
but->drawflag = UI_BUT_TEXT_LEFT;
@@ -576,9 +578,9 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUS
else
BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name);
- but = uiDefIconTextBut(block, BUT, 0, user->icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, user->icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, "");
- uiButSetNFunc(but, template_texture_select, MEM_dupallocN(user), NULL);
+ UI_but_funcN_set(but, template_texture_select, MEM_dupallocN(user), NULL);
last_category = user->category;
}
@@ -620,9 +622,9 @@ void uiTemplateTextureUser(uiLayout *layout, bContext *C)
}
/* some cosmetic tweaks */
- uiButSetMenuFromPulldown(but);
+ UI_but_type_set_menu_from_pulldown(but);
- but->flag &= ~UI_ICON_SUBMENU;
+ but->flag &= ~UI_BUT_ICON_SUBMENU;
}
/************************* Texture Show **************************/
@@ -675,9 +677,9 @@ void uiTemplateTextureShow(uiLayout *layout, bContext *C, PointerRNA *ptr, Prope
uiBlock *block = uiLayoutGetBlock(layout);
uiBut *but;
- but = uiDefIconBut(block, BUT, 0, ICON_BUTS, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_BUTS, 0, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, "Show texture in texture tab");
- uiButSetFunc(but, template_texture_show, user->ptr.data, user->prop);
+ UI_but_func_set(but, template_texture_show, user->ptr.data, user->prop);
}
}
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 4d62f528915..a778df4b783 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -28,7 +28,6 @@
* \ingroup spbuttons
*/
-
#include <string.h>
#include <stdio.h>
@@ -46,10 +45,6 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "UI_resources.h"
-#include "UI_view2d.h"
-
-
#include "buttons_intern.h" /* own include */
/* ******************** default callbacks for buttons space ***************** */
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 889613b5d13..c32d06cf9b1 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -69,26 +69,9 @@
/* Panels */
-static int clip_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt))
+void ED_clip_buttons_register(ARegionType *UNUSED(art))
{
- SpaceClip *sc = CTX_wm_space_clip(C);
- return sc->view == SC_VIEW_CLIP;
-}
-
-void ED_clip_buttons_register(ARegionType *art)
-{
- PanelType *pt;
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype clip panel gpencil");
- strcpy(pt->idname, "CLIP_PT_gpencil");
- strcpy(pt->label, N_("Grease Pencil"));
- strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw_header = ED_gpencil_panel_standard_header;
- pt->draw = ED_gpencil_panel_standard;
- pt->flag |= PNL_DEFAULT_CLOSED;
- pt->poll = clip_grease_pencil_panel_poll;
- BLI_addtail(&art->paneltypes, pt);
}
/********************* MovieClip Template ************************/
@@ -130,7 +113,7 @@ void uiTemplateMovieClip(uiLayout *layout, bContext *C, PointerRNA *ptr, const c
row = uiLayoutRow(layout, false);
block = uiLayoutGetBlock(row);
- uiDefBut(block, LABEL, 0, IFACE_("File Path:"), 0, 19, 145, 19, NULL, 0, 0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("File Path:"), 0, 19, 145, 19, NULL, 0, 0, 0, 0, "");
row = uiLayoutRow(layout, false);
split = uiLayoutSplit(row, 0.0f, false);
@@ -183,10 +166,10 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname)
col = uiLayoutColumn(layout, true);
block = uiLayoutGetBlock(col);
- uiDefBut(block, TRACKPREVIEW, 0, "", 0, 0, UI_UNIT_X * 10, scopes->track_preview_height, scopes, 0, 0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_TRACK_PREVIEW, 0, "", 0, 0, UI_UNIT_X * 10, scopes->track_preview_height, scopes, 0, 0, 0, 0, "");
/* Resize grip. */
- uiDefIconButI(block, GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.8f),
+ uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.8f),
&scopes->track_preview_height, UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
}
@@ -403,9 +386,9 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P
else
tip = TIP_("Marker is enabled at current frame");
- bt = uiDefIconButBitI(block, TOGN, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ bt = uiDefIconButBitI(block, UI_BTYPE_TOGGLE_N, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, UI_UNIT_X, UI_UNIT_Y,
&cb->marker_flag, 0, 0, 1, 0, tip);
- uiButSetNFunc(bt, marker_update_cb, cb, NULL);
+ UI_but_funcN_set(bt, marker_update_cb, cb, NULL);
}
else {
int width, height, step, digits;
@@ -417,7 +400,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P
if (track->flag & TRACK_LOCKED) {
uiLayoutSetActive(layout, false);
block = uiLayoutAbsoluteBlock(layout);
- uiDefBut(block, LABEL, 0, IFACE_("Track is locked"), 0, 0, UI_UNIT_X * 15.0f, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Track is locked"), 0, 0, UI_UNIT_X * 15.0f, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
return;
}
@@ -442,53 +425,53 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P
cb->marker_flag = marker->flag;
block = uiLayoutAbsoluteBlock(layout);
- uiBlockSetHandleFunc(block, marker_block_handler, cb);
- uiBlockSetNFunc(block, marker_update_cb, cb, NULL);
+ UI_block_func_handle_set(block, marker_block_handler, cb);
+ UI_block_funcN_set(block, marker_update_cb, cb, NULL);
if (cb->marker_flag & MARKER_DISABLED)
tip = TIP_("Marker is disabled at current frame");
else
tip = TIP_("Marker is enabled at current frame");
- uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, IFACE_("Enabled"), 0.5 * UI_UNIT_X, 9.5 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y,
+ uiDefButBitI(block, UI_BTYPE_CHECKBOX_N, MARKER_DISABLED, B_MARKER_FLAG, IFACE_("Enabled"), 0.5 * UI_UNIT_X, 9.5 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y,
&cb->marker_flag, 0, 0, 0, 0, tip);
col = uiLayoutColumn(layout, true);
uiLayoutSetActive(col, (cb->marker_flag & MARKER_DISABLED) == 0);
block = uiLayoutAbsoluteBlock(col);
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
- uiDefBut(block, LABEL, 0, IFACE_("Position:"), 0, 10 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_MARKER_POS, IFACE_("X:"), 0.5 * UI_UNIT_X, 9 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pos[0],
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Position:"), 0, 10 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, UI_BTYPE_NUM, B_MARKER_POS, IFACE_("X:"), 0.5 * UI_UNIT_X, 9 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pos[0],
-10 * width, 10.0 * width, step, digits, TIP_("X-position of marker at frame in screen coordinates"));
- uiDefButF(block, NUM, B_MARKER_POS, IFACE_("Y:"), 8.25 * UI_UNIT_X, 9 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pos[1],
+ uiDefButF(block, UI_BTYPE_NUM, B_MARKER_POS, IFACE_("Y:"), 8.25 * UI_UNIT_X, 9 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pos[1],
-10 * height, 10.0 * height, step, digits,
TIP_("Y-position of marker at frame in screen coordinates"));
- uiDefBut(block, LABEL, 0, IFACE_("Offset:"), 0, 8 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_MARKER_OFFSET, IFACE_("X:"), 0.5 * UI_UNIT_X, 7 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->track_offset[0],
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Offset:"), 0, 8 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, UI_BTYPE_NUM, B_MARKER_OFFSET, IFACE_("X:"), 0.5 * UI_UNIT_X, 7 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->track_offset[0],
-10 * width, 10.0 * width, step, digits, TIP_("X-offset to parenting point"));
- uiDefButF(block, NUM, B_MARKER_OFFSET, IFACE_("Y:"), 8.25 * UI_UNIT_X, 7 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->track_offset[1],
+ uiDefButF(block, UI_BTYPE_NUM, B_MARKER_OFFSET, IFACE_("Y:"), 8.25 * UI_UNIT_X, 7 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->track_offset[1],
-10 * height, 10.0 * height, step, digits, TIP_("Y-offset to parenting point"));
- uiDefBut(block, LABEL, 0, IFACE_("Pattern Area:"), 0, 6 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_MARKER_PAT_DIM, IFACE_("Width:"), 0.5 * UI_UNIT_X, 5 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pat[0], 3.0f,
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Pattern Area:"), 0, 6 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, UI_BTYPE_NUM, B_MARKER_PAT_DIM, IFACE_("Width:"), 0.5 * UI_UNIT_X, 5 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pat[0], 3.0f,
10.0 * width, step, digits, TIP_("Width of marker's pattern in screen coordinates"));
- uiDefButF(block, NUM, B_MARKER_PAT_DIM, IFACE_("Height:"), 0.5 * UI_UNIT_X, 4 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pat[1], 3.0f,
+ uiDefButF(block, UI_BTYPE_NUM, B_MARKER_PAT_DIM, IFACE_("Height:"), 0.5 * UI_UNIT_X, 4 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_pat[1], 3.0f,
10.0 * height, step, digits, TIP_("Height of marker's pattern in screen coordinates"));
- uiDefBut(block, LABEL, 0, IFACE_("Search Area:"), 0, 3 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiDefButF(block, NUM, B_MARKER_SEARCH_POS, IFACE_("X:"), 0.5 * UI_UNIT_X, 2 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search_pos[0],
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Search Area:"), 0, 3 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ uiDefButF(block, UI_BTYPE_NUM, B_MARKER_SEARCH_POS, IFACE_("X:"), 0.5 * UI_UNIT_X, 2 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search_pos[0],
-width, width, step, digits, TIP_("X-position of search at frame relative to marker's position"));
- uiDefButF(block, NUM, B_MARKER_SEARCH_POS, IFACE_("Y:"), 8.25 * UI_UNIT_X, 2 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search_pos[1],
+ uiDefButF(block, UI_BTYPE_NUM, B_MARKER_SEARCH_POS, IFACE_("Y:"), 8.25 * UI_UNIT_X, 2 * UI_UNIT_Y, 7.25 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search_pos[1],
-height, height, step, digits, TIP_("Y-position of search at frame relative to marker's position"));
- uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, IFACE_("Width:"), 0.5 * UI_UNIT_X, 1 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search[0], 3.0f,
+ uiDefButF(block, UI_BTYPE_NUM, B_MARKER_SEARCH_DIM, IFACE_("Width:"), 0.5 * UI_UNIT_X, 1 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search[0], 3.0f,
10.0 * width, step, digits, TIP_("Width of marker's search in screen coordinates"));
- uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, IFACE_("Height:"), 0.5 * UI_UNIT_X, 0 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search[1], 3.0f,
+ uiDefButF(block, UI_BTYPE_NUM, B_MARKER_SEARCH_DIM, IFACE_("Height:"), 0.5 * UI_UNIT_X, 0 * UI_UNIT_Y, 15 * UI_UNIT_X, UI_UNIT_Y, &cb->marker_search[1], 3.0f,
10.0 * height, step, digits, TIP_("Height of marker's search in screen coordinates"));
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
}
}
@@ -557,7 +540,7 @@ void uiTemplateMovieclipInformation(uiLayout *layout, PointerRNA *ptr, const cha
uiItemL(col, str, ICON_NONE);
/* Display current frame number. */
- framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr) ;
+ framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
if (framenr <= clip->len)
BLI_snprintf(str, sizeof(str), IFACE_("Frame: %d / %d"), framenr, clip->len);
else
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
index 2a457bf503f..4bf4c1e7baa 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_draw.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -30,7 +30,6 @@
*/
#include "DNA_movieclip_types.h"
-#include "DNA_object_types.h" /* SELECT */
#include "DNA_scene_types.h"
#include "BLI_utildefines.h"
@@ -283,7 +282,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
MovieTracking *tracking;
MovieTrackingDopesheet *dopesheet;
MovieTrackingDopesheetChannel *channel;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
uiBlock *block;
int fontid = style->widget.uifont_id;
int height;
@@ -348,7 +347,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
}
/* second pass: widgets */
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
y = (float) CHANNEL_FIRST;
/* get RNA properties (once) */
@@ -370,11 +369,11 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, &ptr);
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconButR_prop(block, ICONTOG, 1, icon,
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 1, icon,
v2d->cur.xmax - UI_UNIT_X - CHANNEL_PAD, y - UI_UNIT_Y / 2.0f,
UI_UNIT_X, UI_UNIT_Y, &ptr, chan_prop_lock, 0, 0, 0, 0, 0, NULL);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
/* adjust y-position for next one */
@@ -382,6 +381,6 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar)
}
glDisable(GL_BLEND);
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
}
diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c
index 7ae5eda7139..d2f2fdd0b46 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_ops.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c
@@ -29,7 +29,6 @@
* \ingroup spclip
*/
-#include "DNA_object_types.h" /* SELECT */
#include "DNA_scene_types.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index a35251e71ef..6c55d8d034e 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -63,7 +63,6 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "RNA_access.h"
#include "BLF_api.h"
@@ -1123,7 +1122,7 @@ static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlane
bool draw_outline, int width, int height)
{
bool tiny = (sc->flag & SC_SHOW_TINY_MARKER) != 0;
- bool is_selected_track = plane_track->flag & SELECT;
+ bool is_selected_track = (plane_track->flag & SELECT) != 0;
bool draw_plane_quad = plane_track->image == NULL || plane_track->image_opacity == 0.0f;
float px[2];
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index f25f035db32..89693a403fe 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -57,7 +57,6 @@
#include "BKE_tracking.h"
#include "BKE_library.h"
-#include "GPU_extensions.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c
index 723c8bd144a..2c3b8acf672 100644
--- a/source/blender/editors/space_clip/clip_graph_draw.c
+++ b/source/blender/editors/space_clip/clip_graph_draw.c
@@ -50,7 +50,6 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "BLF_api.h"
#include "clip_intern.h" // own include
diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c
index d1e2c770ade..2a2f15c94bb 100644
--- a/source/blender/editors/space_clip/clip_graph_ops.c
+++ b/source/blender/editors/space_clip/clip_graph_ops.c
@@ -45,8 +45,6 @@
#include "ED_screen.h"
#include "ED_clip.h"
-#include "UI_interface.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 9f7bcae800a..322825ccc84 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -168,7 +168,7 @@ static void open_init(bContext *C, wmOperator *op)
PropertyPointerRNA *pprop;
op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
- uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
+ UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop);
}
static void open_cancel(bContext *UNUSED(C), wmOperator *op)
@@ -274,7 +274,7 @@ static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)
return open_exec(C, op);
if (!RNA_struct_property_is_set(op->ptr, "relative_path"))
- RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
+ RNA_boolean_set(op->ptr, "relative_path", (U.flag & USER_RELPATHS) != 0);
open_init(C, op);
@@ -299,7 +299,7 @@ void CLIP_OT_open(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_RELPATH | WM_FILESEL_FILES | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY);
}
@@ -1307,7 +1307,14 @@ static void proxy_endjob(void *pjv)
if (pj->index_context)
IMB_anim_index_rebuild_finish(pj->index_context, pj->stop);
- BKE_movieclip_reload(pj->clip);
+ if (pj->clip->source == MCLIP_SRC_MOVIE) {
+ /* Timecode might have changed, so do a full reload to deal with this. */
+ BKE_movieclip_reload(pj->clip);
+ }
+ else {
+ /* For image sequences we'll preserve original cache. */
+ BKE_movieclip_clear_proxy_cache(pj->clip);
+ }
WM_main_add_notifier(NC_MOVIECLIP | ND_DISPLAY, pj->clip);
}
@@ -1335,7 +1342,8 @@ static int clip_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
if (clip->anim) {
pj->index_context = IMB_anim_index_rebuild_context(clip->anim, clip->proxy.build_tc_flag,
- clip->proxy.build_size_flag, clip->proxy.quality);
+ clip->proxy.build_size_flag, clip->proxy.quality,
+ true, NULL);
}
WM_jobs_customdata_set(wm_job, pj, proxy_freejob);
diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c
index 55b78219770..608c1136070 100644
--- a/source/blender/editors/space_clip/clip_toolbar.c
+++ b/source/blender/editors/space_clip/clip_toolbar.c
@@ -242,7 +242,7 @@ static void clip_panel_operator_redo(const bContext *C, Panel *pa)
uiLayoutSetEnabled(pa->layout, false);
/* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */
- uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op);
+ UI_block_func_handle_set(block, ED_undo_operator_repeat_cb_evt, op);
clip_panel_operator_redo_operator(C, pa, op);
}
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index a79ac1f7b82..5f919c9b51d 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -30,12 +30,10 @@
*/
#include "DNA_scene_types.h"
-#include "DNA_object_types.h" /* SELECT */
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@@ -54,8 +52,6 @@
#include "ED_screen.h"
#include "ED_clip.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
#include "UI_interface.h"
#include "UI_resources.h"
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index a797a60f74c..fc2c0d3d45c 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -55,7 +55,7 @@
#include "ED_screen.h"
#include "ED_clip.h"
#include "ED_transform.h"
-#include "ED_uvedit.h" /* just for draw_image_cursor */
+#include "ED_uvedit.h" /* just for ED_image_draw_cursor */
#include "IMB_imbuf.h"
@@ -420,6 +420,9 @@ static void clip_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
clip_scopes_check_gpencil_change(sa);
ED_area_tag_redraw(sa);
}
+ else if (wmn->data & ND_GPENCIL_EDITMODE) {
+ ED_area_tag_redraw(sa);
+ }
break;
}
}
@@ -1159,7 +1162,7 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
/* if tracking is in progress, we should synchronize framenr from clipuser
* so latest tracked frame would be shown */
if (clip && clip->tracking_context)
- BKE_tracking_context_sync_user(clip->tracking_context, &sc->user);
+ BKE_autotrack_context_sync_user(clip->tracking_context, &sc->user);
if (sc->flag & SC_LOCK_SELECTION) {
ImBuf *tmpibuf = NULL;
@@ -1218,7 +1221,7 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar)
glScalef(zoomx, zoomy, 0);
glMultMatrixf(sc->stabmat);
glScalef(width, height, 0);
- draw_image_cursor(ar, sc->cursor);
+ ED_image_draw_cursor(ar, sc->cursor);
glPopMatrix();
}
@@ -1245,6 +1248,8 @@ static void clip_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AR
case NC_GPENCIL:
if (wmn->action == NA_EDITED)
ED_region_tag_redraw(ar);
+ else if (wmn->data & ND_GPENCIL_EDITMODE)
+ ED_region_tag_redraw(ar);
break;
}
}
@@ -1495,7 +1500,7 @@ static void clip_properties_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(s
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
- if (wmn->data == ND_DATA)
+ if (ELEM(wmn->data, ND_DATA, ND_GPENCIL_EDITMODE))
ED_region_tag_redraw(ar);
break;
case NC_BRUSH:
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index fb6b1a0033c..742e58d80dd 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -41,7 +41,6 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
-#include "BLI_rect.h"
#include "BLI_blenlib.h"
#include "BKE_main.h"
@@ -65,7 +64,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "UI_interface.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -74,7 +72,6 @@
#include "PIL_time.h"
-#include "UI_view2d.h"
#include "clip_intern.h" // own include
@@ -1083,7 +1080,7 @@ void CLIP_OT_slide_marker(wmOperatorType *ot)
/********************** track operator *********************/
typedef struct TrackMarkersJob {
- struct MovieTrackingContext *context; /* tracking context */
+ struct AutoTrackContext *context; /* tracking context */
int sfra, efra, lastfra; /* Start, end and recently tracked frames */
int backwards; /* Backwards tracking flag */
MovieClip *clip; /* Clip which is tracking */
@@ -1231,7 +1228,7 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward
tmj->delay /= 2;
}
- tmj->context = BKE_tracking_context_new(clip, &sc->user, backwards, 1);
+ tmj->context = BKE_autotrack_context_new(clip, &sc->user, backwards, 1);
clip->tracking_context = tmj->context;
@@ -1265,14 +1262,14 @@ static void track_markers_startjob(void *tmv, short *stop, short *do_update, flo
double start_time = PIL_check_seconds_timer(), exec_time;
- if (!BKE_tracking_context_step(tmj->context))
+ if (!BKE_autotrack_context_step(tmj->context))
break;
exec_time = PIL_check_seconds_timer() - start_time;
if (tmj->delay > (float)exec_time)
PIL_sleep_ms(tmj->delay - (float)exec_time);
}
- else if (!BKE_tracking_context_step(tmj->context))
+ else if (!BKE_autotrack_context_step(tmj->context))
break;
*do_update = true;
@@ -1296,7 +1293,7 @@ static void track_markers_updatejob(void *tmv)
{
TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
- BKE_tracking_context_sync(tmj->context);
+ BKE_autotrack_context_sync(tmj->context);
}
static void track_markers_endjob(void *tmv)
@@ -1310,8 +1307,8 @@ static void track_markers_endjob(void *tmv)
ED_update_for_newframe(tmj->main, tmj->scene, 0);
}
- BKE_tracking_context_sync(tmj->context);
- BKE_tracking_context_finish(tmj->context);
+ BKE_autotrack_context_sync(tmj->context);
+ BKE_autotrack_context_finish(tmj->context);
WM_main_add_notifier(NC_SCENE | ND_FRAME, tmj->scene);
}
@@ -1319,7 +1316,7 @@ static void track_markers_endjob(void *tmv)
static void track_markers_freejob(void *tmv)
{
TrackMarkersJob *tmj = (TrackMarkersJob *)tmv;
- BKE_tracking_context_free(tmj->context);
+ BKE_autotrack_context_free(tmj->context);
MEM_freeN(tmj);
}
@@ -1328,7 +1325,7 @@ static int track_markers_exec(bContext *C, wmOperator *op)
SpaceClip *sc;
MovieClip *clip;
Scene *scene = CTX_data_scene(C);
- struct MovieTrackingContext *context;
+ struct AutoTrackContext *context;
MovieClipUser *user, fake_user = {0};
int framenr, sfra, efra;
const bool backwards = RNA_boolean_get(op->ptr, "backwards");
@@ -1388,10 +1385,10 @@ static int track_markers_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
/* do not disable tracks due to threshold when tracking frame-by-frame */
- context = BKE_tracking_context_new(clip, user, backwards, sequence);
+ context = BKE_autotrack_context_new(clip, user, backwards, sequence);
while (framenr != efra) {
- if (!BKE_tracking_context_step(context))
+ if (!BKE_autotrack_context_step(context))
break;
if (backwards) framenr--;
@@ -1401,9 +1398,9 @@ static int track_markers_exec(bContext *C, wmOperator *op)
break;
}
- BKE_tracking_context_sync(context);
- BKE_tracking_context_finish(context);
- BKE_tracking_context_free(context);
+ BKE_autotrack_context_sync(context);
+ BKE_autotrack_context_finish(context);
+ BKE_autotrack_context_free(context);
/* update scene current frame to the lastes tracked frame */
scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(clip, framenr);
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index 860d9dc6b3c..0b29c253f3a 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -36,7 +36,6 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
-#include "BLI_listbase.h"
#include "BLI_rect.h"
#include "BLI_lasso.h"
@@ -49,16 +48,9 @@
#include "ED_screen.h"
#include "ED_clip.h"
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-
-#include "UI_interface.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
-#include "PIL_time.h"
-
#include "UI_view2d.h"
#include "clip_intern.h" // own include
@@ -70,7 +62,6 @@ static float dist_to_crns(float co[2], float pos[2], float crns[4][2]);
static int mouse_on_side(float co[2], float x1, float y1, float x2, float y2, float epsx, float epsy)
{
if (x1 > x2)
-
SWAP(float, x1, x2);
if (y1 > y2)
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index 635d5ea07fd..d206ce4699e 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -30,7 +30,6 @@
#include <sys/stat.h>
#include <limits.h>
-#include "BLF_api.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index b44e942527c..8263268898f 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -95,7 +95,7 @@ static void console_scrollback_limit(SpaceConsole *sc)
if (U.scrollback < 32) U.scrollback = 256; // XXX - save in user defaults
- for (tot = BLI_countlist(&sc->scrollback); tot > U.scrollback; tot--)
+ for (tot = BLI_listbase_count(&sc->scrollback); tot > U.scrollback; tot--)
console_scrollback_free(sc, sc->scrollback.first);
}
@@ -107,7 +107,7 @@ static ConsoleLine *console_history_find(SpaceConsole *sc, const char *str, Cons
if (cl == cl_ignore)
continue;
- if (strcmp(str, cl->line) == 0)
+ if (STREQ(str, cl->line))
return cl;
}
@@ -136,7 +136,7 @@ static void console_lb_debug__internal(ListBase *lb)
{
ConsoleLine *cl;
- printf("%d: ", BLI_countlist(lb));
+ printf("%d: ", BLI_listbase_count(lb));
for (cl = lb->first; cl; cl = cl->next)
printf("<%s> ", cl->line);
printf("\n");
@@ -722,7 +722,7 @@ static int console_history_cycle_exec(bContext *C, wmOperator *op)
if (ci->prev) {
ConsoleLine *ci_prev = (ConsoleLine *)ci->prev;
- if (strcmp(ci->line, ci_prev->line) == 0)
+ if (STREQ(ci->line, ci_prev->line))
console_history_free(sc, ci_prev);
}
@@ -791,7 +791,7 @@ static int console_history_append_exec(bContext *C, wmOperator *op)
while ((cl = console_history_find(sc, ci->line, ci)))
console_history_free(sc, cl);
- if (strcmp(str, ci->line) == 0) {
+ if (STREQ(str, ci->line)) {
MEM_freeN(str);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 3e099b43a4b..98c7ddeff77 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -47,7 +47,6 @@
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BLF_api.h"
#include "BLF_translation.h"
#include "IMB_imbuf_types.h"
@@ -67,7 +66,6 @@
#include "WM_types.h"
-#include "fsmenu.h"
#include "filelist.h"
#include "file_intern.h" // own include
@@ -113,31 +111,37 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_params(sfile);
ARegion *artmp;
+ const bool is_browse_only = (sfile->op == NULL);
/* Initialize UI block. */
BLI_snprintf(uiblockstr, sizeof(uiblockstr), "win %p", (void *)ar);
- block = uiBeginBlock(C, ar, uiblockstr, UI_EMBOSS);
+ block = UI_block_begin(C, ar, uiblockstr, UI_EMBOSS);
/* exception to make space for collapsed region icon */
for (artmp = CTX_wm_area(C)->regionbase.first; artmp; artmp = artmp->next) {
- if (artmp->regiontype == RGN_TYPE_CHANNELS && artmp->flag & RGN_FLAG_HIDDEN) {
+ if (artmp->regiontype == RGN_TYPE_TOOLS && artmp->flag & RGN_FLAG_HIDDEN) {
chan_offs = 16;
min_x += chan_offs;
available_w -= chan_offs;
}
}
-
+
/* Is there enough space for the execute / cancel buttons? */
- loadbutton = UI_GetStringWidth(sfile->params->title) + btn_margin;
- if (loadbutton < btn_minw) {
- loadbutton = MAX2(btn_minw,
- btn_margin + UI_GetStringWidth(params->title));
- }
-
- if (available_w <= loadbutton + separator + input_minw || params->title[0] == 0) {
+
+
+ if (is_browse_only) {
loadbutton = 0;
}
else {
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ loadbutton = UI_fontstyle_string_width(fstyle, params->title) + btn_margin;
+ CLAMP_MIN(loadbutton, btn_minw);
+ if (available_w <= loadbutton + separator + input_minw) {
+ loadbutton = 0;
+ }
+ }
+
+ if (loadbutton) {
line1_w -= (loadbutton + separator);
line2_w = line1_w;
}
@@ -150,121 +154,121 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
else {
line2_w -= (fnumbuttons + separator);
}
-
+
/* Text input fields for directory and file. */
if (available_w > 0) {
int overwrite_alert = file_draw_check_exists(sfile);
/* callbacks for operator check functions */
- uiBlockSetFunc(block, file_draw_check_cb, NULL, NULL);
+ UI_block_func_set(block, file_draw_check_cb, NULL, NULL);
- but = uiDefBut(block, TEX, -1, "",
+ but = uiDefBut(block, UI_BTYPE_TEXT, -1, "",
min_x, line1_y, line1_w - chan_offs, btn_h,
params->dir, 0.0, (float)FILE_MAX, 0, 0,
TIP_("File path"));
- uiButSetCompleteFunc(but, autocomplete_directory, NULL);
- uiButSetFlag(but, UI_BUT_NO_UTF8);
- uiButClearFlag(but, UI_BUT_UNDO);
- uiButSetNFunc(but, file_directory_enter_handle, NULL, but);
+ UI_but_func_complete_set(but, autocomplete_directory, NULL);
+ UI_but_flag_enable(but, UI_BUT_NO_UTF8);
+ UI_but_flag_disable(but, UI_BUT_UNDO);
+ UI_but_funcN_set(but, file_directory_enter_handle, NULL, but);
/* TODO, directory editing is non-functional while a library is loaded
* until this is properly supported just disable it. */
if (sfile->files && filelist_lib(sfile->files))
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
if ((params->flag & FILE_DIRSEL_ONLY) == 0) {
- but = uiDefBut(block, TEX, -1, "",
+ but = uiDefBut(block, UI_BTYPE_TEXT, -1, "",
min_x, line2_y, line2_w - chan_offs, btn_h,
params->file, 0.0, (float)FILE_MAXFILE, 0, 0,
TIP_(overwrite_alert ? N_("File name, overwrite existing") : N_("File name")));
- uiButSetCompleteFunc(but, autocomplete_file, NULL);
- uiButSetFlag(but, UI_BUT_NO_UTF8);
- uiButClearFlag(but, UI_BUT_UNDO);
+ UI_but_func_complete_set(but, autocomplete_file, NULL);
+ UI_but_flag_enable(but, UI_BUT_NO_UTF8);
+ UI_but_flag_disable(but, UI_BUT_UNDO);
/* silly workaround calling NFunc to ensure this does not get called
* immediate ui_apply_but_func but only after button deactivates */
- uiButSetNFunc(but, file_filename_enter_handle, NULL, but);
+ UI_but_funcN_set(but, file_filename_enter_handle, NULL, but);
/* check if this overrides a file and if the operator option is used */
if (overwrite_alert) {
- uiButSetFlag(but, UI_BUT_REDALERT);
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
}
}
/* clear func */
- uiBlockSetFunc(block, NULL, NULL, NULL);
+ UI_block_func_set(block, NULL, NULL, NULL);
}
/* Filename number increment / decrement buttons. */
if (fnumbuttons && (params->flag & FILE_DIRSEL_ONLY) == 0) {
- uiBlockBeginAlign(block);
- but = uiDefIconButO(block, BUT, "FILE_OT_filenum", 0, ICON_ZOOMOUT,
+ UI_block_align_begin(block);
+ but = uiDefIconButO(block, UI_BTYPE_BUT, "FILE_OT_filenum", 0, ICON_ZOOMOUT,
min_x + line2_w + separator - chan_offs, line2_y,
btn_fn_w, btn_h,
TIP_("Decrement the filename number"));
- RNA_int_set(uiButGetOperatorPtrRNA(but), "increment", -1);
+ RNA_int_set(UI_but_operator_ptr_get(but), "increment", -1);
- but = uiDefIconButO(block, BUT, "FILE_OT_filenum", 0, ICON_ZOOMIN,
+ but = uiDefIconButO(block, UI_BTYPE_BUT, "FILE_OT_filenum", 0, ICON_ZOOMIN,
min_x + line2_w + separator + btn_fn_w - chan_offs, line2_y,
btn_fn_w, btn_h,
TIP_("Increment the filename number"));
- RNA_int_set(uiButGetOperatorPtrRNA(but), "increment", 1);
- uiBlockEndAlign(block);
+ RNA_int_set(UI_but_operator_ptr_get(but), "increment", 1);
+ UI_block_align_end(block);
}
/* Execute / cancel buttons. */
if (loadbutton) {
/* params->title is already translated! */
- uiDefButO(block, BUT, "FILE_OT_execute", WM_OP_EXEC_REGION_WIN, params->title,
+ uiDefButO(block, UI_BTYPE_BUT, "FILE_OT_execute", WM_OP_EXEC_REGION_WIN, params->title,
max_x - loadbutton, line1_y, loadbutton, btn_h, "");
- uiDefButO(block, BUT, "FILE_OT_cancel", WM_OP_EXEC_REGION_WIN, IFACE_("Cancel"),
+ uiDefButO(block, UI_BTYPE_BUT, "FILE_OT_cancel", WM_OP_EXEC_REGION_WIN, IFACE_("Cancel"),
max_x - loadbutton, line2_y, loadbutton, btn_h, "");
}
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
}
static void draw_tile(int sx, int sy, int width, int height, int colorid, int shade)
{
UI_ThemeColorShade(colorid, shade);
- uiSetRoundBox(UI_CNR_ALL);
- uiRoundBox((float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox((float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f);
}
static int get_file_icon(struct direntry *file)
{
if (file->type & S_IFDIR) {
- if (strcmp(file->relname, "..") == 0) {
+ if (FILENAME_IS_PARENT(file->relname)) {
return ICON_FILE_PARENT;
}
- if (file->flags & APPLICATIONBUNDLE) {
+ if (file->flags & FILE_TYPE_APPLICATIONBUNDLE) {
return ICON_UGLYPACKAGE;
}
- if (file->flags & BLENDERFILE) {
+ if (file->flags & FILE_TYPE_BLENDER) {
return ICON_FILE_BLEND;
}
return ICON_FILE_FOLDER;
}
- else if (file->flags & BLENDERFILE)
+ else if (file->flags & FILE_TYPE_BLENDER)
return ICON_FILE_BLEND;
- else if (file->flags & BLENDERFILE_BACKUP)
+ else if (file->flags & FILE_TYPE_BLENDER_BACKUP)
return ICON_FILE_BACKUP;
- else if (file->flags & IMAGEFILE)
+ else if (file->flags & FILE_TYPE_IMAGE)
return ICON_FILE_IMAGE;
- else if (file->flags & MOVIEFILE)
+ else if (file->flags & FILE_TYPE_MOVIE)
return ICON_FILE_MOVIE;
- else if (file->flags & PYSCRIPTFILE)
+ else if (file->flags & FILE_TYPE_PYSCRIPT)
return ICON_FILE_SCRIPT;
- else if (file->flags & SOUNDFILE)
+ else if (file->flags & FILE_TYPE_SOUND)
return ICON_FILE_SOUND;
- else if (file->flags & FTFONTFILE)
+ else if (file->flags & FILE_TYPE_FTFONT)
return ICON_FILE_FONT;
- else if (file->flags & BTXFILE)
+ else if (file->flags & FILE_TYPE_BTX)
return ICON_FILE_BLANK;
- else if (file->flags & COLLADAFILE)
+ else if (file->flags & FILE_TYPE_COLLADA)
return ICON_FILE_BLANK;
- else if (file->flags & TEXTFILE)
+ else if (file->flags & FILE_TYPE_TEXT)
return ICON_FILE_TEXT;
else
return ICON_FILE_BLANK;
@@ -281,16 +285,17 @@ static void file_draw_icon(uiBlock *block, char *path, int sx, int sy, int icon,
/*if (icon == ICON_FILE_BLANK) alpha = 0.375f;*/
- but = uiDefIconBut(block, LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "");
+ but = uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "");
- if (drag)
- uiButSetDragPath(but, path);
+ if (drag) {
+ UI_but_drag_set_path(but, path);
+ }
}
static void file_draw_string(int sx, int sy, const char *string, float width, int height, short align)
{
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
uiFontStyle fs = style->widgetlabel;
rcti rect;
char fname[FILE_MAXFILE];
@@ -300,13 +305,13 @@ static void file_draw_string(int sx, int sy, const char *string, float width, in
BLI_strncpy(fname, string, FILE_MAXFILE);
file_shorten_string(fname, width + 1.0f, 0);
- /* no text clipping needed, uiStyleFontDraw does it but is a bit too strict (for buttons it works) */
+ /* no text clipping needed, UI_fontstyle_draw does it but is a bit too strict (for buttons it works) */
rect.xmin = sx;
rect.xmax = (int)(sx + ceil(width + 4.0f));
rect.ymin = sy - height;
rect.ymax = sy;
- uiStyleFontDraw(&fs, &rect, fname);
+ UI_fontstyle_draw(&fs, &rect, fname);
}
void file_calc_previews(const bContext *C, ARegion *ar)
@@ -320,70 +325,70 @@ void file_calc_previews(const bContext *C, ARegion *ar)
static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int sy, ImBuf *imb, FileLayout *layout, bool dropshadow, bool drag)
{
- if (imb) {
- uiBut *but;
- float fx, fy;
- float dx, dy;
- int xco, yco;
- float scaledx, scaledy;
- float scale;
- int ex, ey;
-
- if ((imb->x * UI_DPI_FAC > layout->prv_w) ||
- (imb->y * UI_DPI_FAC > layout->prv_h))
- {
- if (imb->x > imb->y) {
- scaledx = (float)layout->prv_w;
- scaledy = ( (float)imb->y / (float)imb->x) * layout->prv_w;
- scale = scaledx / imb->x;
- }
- else {
- scaledy = (float)layout->prv_h;
- scaledx = ( (float)imb->x / (float)imb->y) * layout->prv_h;
- scale = scaledy / imb->y;
- }
+ uiBut *but;
+ float fx, fy;
+ float dx, dy;
+ int xco, yco;
+ float scaledx, scaledy;
+ float scale;
+ int ex, ey;
+
+ BLI_assert(imb != NULL);
+
+ if ((imb->x * UI_DPI_FAC > layout->prv_w) ||
+ (imb->y * UI_DPI_FAC > layout->prv_h))
+ {
+ if (imb->x > imb->y) {
+ scaledx = (float)layout->prv_w;
+ scaledy = ( (float)imb->y / (float)imb->x) * layout->prv_w;
+ scale = scaledx / imb->x;
}
else {
- scaledx = (float)imb->x * UI_DPI_FAC;
- scaledy = (float)imb->y * UI_DPI_FAC;
- scale = UI_DPI_FAC;
+ scaledy = (float)layout->prv_h;
+ scaledx = ( (float)imb->x / (float)imb->y) * layout->prv_h;
+ scale = scaledy / imb->y;
}
+ }
+ else {
+ scaledx = (float)imb->x * UI_DPI_FAC;
+ scaledy = (float)imb->y * UI_DPI_FAC;
+ scale = UI_DPI_FAC;
+ }
- ex = (int)scaledx;
- ey = (int)scaledy;
- fx = ((float)layout->prv_w - (float)ex) / 2.0f;
- fy = ((float)layout->prv_h - (float)ey) / 2.0f;
- dx = (fx + 0.5f + layout->prv_border_x);
- dy = (fy + 0.5f - layout->prv_border_y);
- xco = sx + (int)dx;
- yco = sy - layout->prv_h + (int)dy;
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- /* shadow */
- if (dropshadow)
- uiDrawBoxShadow(220, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
+ ex = (int)scaledx;
+ ey = (int)scaledy;
+ fx = ((float)layout->prv_w - (float)ex) / 2.0f;
+ fy = ((float)layout->prv_h - (float)ey) / 2.0f;
+ dx = (fx + 0.5f + layout->prv_border_x);
+ dy = (fy + 0.5f - layout->prv_border_y);
+ xco = sx + (int)dx;
+ yco = sy - layout->prv_h + (int)dy;
- glEnable(GL_BLEND);
-
- /* the image */
- glColor4f(1.0, 1.0, 1.0, 1.0);
- glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, imb->rect, scale, scale);
-
- /* border */
- if (dropshadow) {
- glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
- fdrawbox((float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
- }
-
- /* dragregion */
- if (drag) {
- but = uiDefBut(block, LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, "");
- uiButSetDragImage(but, file->path, get_file_icon(file), imb, scale);
- }
-
- glDisable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* shadow */
+ if (dropshadow)
+ UI_draw_box_shadow(220, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
+
+ glEnable(GL_BLEND);
+
+ /* the image */
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, imb->rect, scale, scale);
+
+ /* border */
+ if (dropshadow) {
+ glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+ fdrawbox((float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
+ }
+
+ /* dragregion */
+ if (drag) {
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, "");
+ UI_but_drag_set_image(but, file->path, get_file_icon(file), imb, scale);
}
+
+ glDisable(GL_BLEND);
}
static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
@@ -399,7 +404,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
BLI_strncpy(filename, sfile->params->renameedit, sizeof(filename));
BLI_make_file_string(G.main->name, newname, sfile->params->dir, filename);
- if (strcmp(orgname, newname) != 0) {
+ if (!STREQ(orgname, newname)) {
if (!BLI_exists(newname)) {
BLI_rename(orgname, newname);
/* to make sure we show what is on disk */
@@ -470,7 +475,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
struct FileList *files = sfile->files;
struct direntry *file;
ImBuf *imb;
- uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
+ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
int numfiles;
int numfiles_layout;
int sx, sy;
@@ -515,21 +520,26 @@ void file_draw_list(const bContext *C, ARegion *ar)
sy = (int)(v2d->tot.ymax - sy);
file = filelist_file(files, i);
-
+
UI_ThemeColor4(TH_TEXT);
- if (!(file->selflag & EDITING_FILE)) {
- if ((params->active_file == i) || (file->selflag & HILITED_FILE) || (file->selflag & SELECTED_FILE)) {
- int colorid = (file->selflag & SELECTED_FILE) ? TH_HILITE : TH_BACK;
- int shade = (params->active_file == i) || (file->selflag & HILITED_FILE) ? 20 : 0;
+ if (!(file->selflag & FILE_SEL_EDITING)) {
+ if ((params->active_file == i) || (file->selflag & FILE_SEL_HIGHLIGHTED) || (file->selflag & FILE_SEL_SELECTED)) {
+ int colorid = (file->selflag & FILE_SEL_SELECTED) ? TH_HILITE : TH_BACK;
+ int shade = (params->active_file == i) || (file->selflag & FILE_SEL_HIGHLIGHTED) ? 20 : 0;
+
+ /* readonly files (".." and ".") must not be drawn as selected - set color back to normal */
+ if (FILENAME_IS_CURRPAR(file->relname)) {
+ colorid = TH_BACK;
+ }
draw_tile(sx, sy - 1, layout->tile_w + 4, sfile->layout->tile_h + layout->tile_border_y, colorid, shade);
}
}
- uiSetRoundBox(UI_CNR_NONE);
+ UI_draw_roundbox_corner_set(UI_CNR_NONE);
/* don't drag parent or refresh items */
- do_drag = !(STREQ(file->relname, "..") || STREQ(file->relname, "."));
+ do_drag = !(FILENAME_IS_CURRPAR(file->relname));
if (FILE_IMGDISPLAY == params->display) {
is_icon = 0;
@@ -538,8 +548,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
imb = filelist_geticon(files, i);
is_icon = 1;
}
-
- file_draw_preview(block, file, sx, sy, imb, layout, !is_icon && (file->flags & IMAGEFILE), do_drag);
+
+ file_draw_preview(block, file, sx, sy, imb, layout, !is_icon && (file->flags & FILE_TYPE_IMAGE), do_drag);
}
else {
file_draw_icon(block, file->path, sx, sy - (UI_UNIT_Y / 6), get_file_icon(file), ICON_DEFAULT_WIDTH_SCALE, ICON_DEFAULT_HEIGHT_SCALE, do_drag);
@@ -548,18 +558,34 @@ void file_draw_list(const bContext *C, ARegion *ar)
UI_ThemeColor4(TH_TEXT);
- if (file->selflag & EDITING_FILE) {
- uiBut *but = uiDefBut(block, TEX, 1, "", sx, sy - layout->tile_h - 0.15f * UI_UNIT_X,
- textwidth, textheight, sfile->params->renameedit, 1.0f, (float)sizeof(sfile->params->renameedit), 0, 0, "");
- uiButSetRenameFunc(but, renamebutton_cb, file);
- uiButSetFlag(but, UI_BUT_NO_UTF8); /* allow non utf8 names */
- uiButClearFlag(but, UI_BUT_UNDO);
- if (false == uiButActiveOnly(C, ar, block, but)) {
- file->selflag &= ~EDITING_FILE;
+ if (file->selflag & FILE_SEL_EDITING) {
+ uiBut *but;
+ short width;
+
+ if (params->display == FILE_SHORTDISPLAY) {
+ width = layout->tile_w - (ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X);
+ }
+ else if (params->display == FILE_LONGDISPLAY) {
+ width = layout->column_widths[COLUMN_NAME] + layout->column_widths[COLUMN_MODE1] +
+ layout->column_widths[COLUMN_MODE2] + layout->column_widths[COLUMN_MODE3] +
+ (column_space * 3.5f);
+ }
+ else {
+ BLI_assert(params->display == FILE_IMGDISPLAY);
+ width = textwidth;
+ }
+
+ but = uiDefBut(block, UI_BTYPE_TEXT, 1, "", sx, sy - layout->tile_h - 0.15f * UI_UNIT_X,
+ width, textheight, sfile->params->renameedit, 1.0f, (float)sizeof(sfile->params->renameedit), 0, 0, "");
+ UI_but_func_rename_set(but, renamebutton_cb, file);
+ UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */
+ UI_but_flag_disable(but, UI_BUT_UNDO);
+ if (false == UI_but_active_only(C, ar, block, but)) {
+ file->selflag &= ~FILE_SEL_EDITING;
}
}
- if (!(file->selflag & EDITING_FILE)) {
+ if (!(file->selflag & FILE_SEL_EDITING)) {
int tpos = (FILE_IMGDISPLAY == params->display) ? sy - layout->tile_h + layout->textheight : sy;
file_draw_string(sx + 1, tpos, file->relname, (float)textwidth, textheight, align);
}
@@ -602,7 +628,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
}
}
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
}
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index 7147353b3f1..e7a6cd62a33 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -38,7 +38,7 @@ struct ARegionType;
struct SpaceFile;
/* file_ops.c */
-struct ARegion *file_buttons_region(struct ScrArea *sa);
+struct ARegion *file_tools_region(struct ScrArea *sa);
/* file_draw.c */
#define TILE_BORDER_X (UI_UNIT_X / 4)
@@ -52,6 +52,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar);
void file_calc_previews(const bContext *C, ARegion *ar);
void file_draw_list(const bContext *C, ARegion *ar);
+void file_draw_check(bContext *C);
void file_draw_check_cb(bContext *C, void *arg1, void *arg2);
bool file_draw_check_exists(SpaceFile *sfile);
@@ -66,6 +67,8 @@ void FILE_OT_select_border(struct wmOperatorType *ot);
void FILE_OT_select_bookmark(struct wmOperatorType *ot);
void FILE_OT_bookmark_add(struct wmOperatorType *ot);
void FILE_OT_bookmark_delete(struct wmOperatorType *ot);
+void FILE_OT_bookmark_cleanup(struct wmOperatorType *ot);
+void FILE_OT_bookmark_move(struct wmOperatorType *ot);
void FILE_OT_reset_recent(wmOperatorType *ot);
void FILE_OT_hidedot(struct wmOperatorType *ot);
void FILE_OT_execute(struct wmOperatorType *ot);
@@ -103,7 +106,6 @@ float file_shorten_string(char *string, float w, int front);
float file_string_width(const char *str);
float file_font_pointsize(void);
-void file_change_dir(bContext *C, int checkdir);
int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file);
int autocomplete_directory(struct bContext *C, char *str, void *arg_v);
int autocomplete_file(struct bContext *C, char *str, void *arg_v);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 27d6fabba4e..f8d13bb6adb 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -31,9 +31,11 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_fileops_types.h"
+#include "BLI_linklist.h"
#include "BLO_readfile.h"
+#include "BKE_appdir.h"
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_global.h"
@@ -177,16 +179,18 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
params->active_file = selected_idx;
if (S_ISDIR(file->type)) {
+ const bool is_parent_dir = FILENAME_IS_PARENT(file->relname);
+
if (do_diropen == false) {
params->file[0] = '\0';
retval = FILE_SELECT_DIR;
}
/* the path is too long and we are not going up! */
- else if (strcmp(file->relname, "..") && strlen(params->dir) + strlen(file->relname) >= FILE_MAX) {
+ else if (!is_parent_dir && strlen(params->dir) + strlen(file->relname) >= FILE_MAX) {
// XXX error("Path too long, cannot enter this directory");
}
else {
- if (strcmp(file->relname, "..") == 0) {
+ if (is_parent_dir) {
/* avoids /../../ */
BLI_parent_dir(params->dir);
}
@@ -196,7 +200,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
BLI_add_slash(params->dir);
}
- file_change_dir(C, 0);
+ ED_file_change_dir(C, false);
retval = FILE_SELECT_DIR;
}
}
@@ -219,7 +223,7 @@ static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select,
const FileCheckType check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_ALL;
/* flag the files as selected in the filelist */
- filelist_select(sfile->files, &sel, select, SELECTED_FILE, check_type);
+ filelist_select(sfile->files, &sel, select, FILE_SEL_SELECTED, check_type);
/* Don't act on multiple selected files */
if (sel.first != sel.last) select = 0;
@@ -233,7 +237,7 @@ static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select,
}
/* update operator for name change event */
- file_draw_check_cb(C, NULL, NULL);
+ file_draw_check(C);
return retval;
}
@@ -258,9 +262,25 @@ static int file_border_select_modal(bContext *C, wmOperator *op, const wmEvent *
sel = file_selection_get(C, &rect, 0);
if ( (sel.first != params->sel_first) || (sel.last != params->sel_last) ) {
- file_deselect_all(sfile, HILITED_FILE);
- filelist_select(sfile->files, &sel, FILE_SEL_ADD, HILITED_FILE, CHECK_ALL);
+ int idx;
+
+ file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
+ filelist_select(sfile->files, &sel, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
+
+ /* dont highlight readonly file (".." or ".") on border select */
+ for (idx = sel.last; idx >= 0; idx--) {
+ struct direntry *file = filelist_file(sfile->files, idx);
+
+ if (FILENAME_IS_CURRPAR(file->relname)) {
+ file->selflag &= ~FILE_SEL_HIGHLIGHTED;
+ }
+
+ /* active_file gets highlighted as well - make sure it is no readonly file */
+ if (sel.last == idx) {
+ params->active_file = idx;
+ }
+ }
}
params->sel_first = sel.first; params->sel_last = sel.last;
@@ -268,7 +288,7 @@ static int file_border_select_modal(bContext *C, wmOperator *op, const wmEvent *
else {
params->active_file = -1;
params->sel_first = params->sel_last = -1;
- file_deselect_all(sfile, HILITED_FILE);
+ file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
@@ -288,7 +308,7 @@ static int file_border_select_exec(bContext *C, wmOperator *op)
if (!extend) {
SpaceFile *sfile = CTX_wm_space_file(C);
- file_deselect_all(sfile, SELECTED_FILE);
+ file_deselect_all(sfile, FILE_SEL_SELECTED);
}
BLI_rcti_isect(&(ar->v2d.mask), &rect, &rect);
@@ -340,8 +360,20 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (!BLI_rcti_isect_pt(&ar->v2d.mask, rect.xmin, rect.ymin))
return OPERATOR_CANCELLED;
- /* single select, deselect all selected first */
- if (!extend) file_deselect_all(sfile, SELECTED_FILE);
+ if (sfile && sfile->params) {
+ int idx = sfile->params->active_file;
+
+ if (idx >= 0) {
+ struct direntry *file = filelist_file(sfile->files, idx);
+ if (FILENAME_IS_CURRPAR(file->relname)) {
+ /* skip - If a readonly file (".." or ".") is selected, skip deselect all! */
+ }
+ else {
+ /* single select, deselect all selected first */
+ if (!extend) file_deselect_all(sfile, FILE_SEL_SELECTED);
+ }
+ }
+ }
ret = file_select(C, &rect, extend ? FILE_SEL_TOGGLE : FILE_SEL_ADD, fill, do_diropen);
if (FILE_SELECT_DIR == ret)
@@ -398,12 +430,13 @@ static int file_select_all_exec(bContext *C, wmOperator *UNUSED(op))
}
/* select all only if previously no file was selected */
if (is_selected) {
- filelist_select(sfile->files, &sel, FILE_SEL_REMOVE, SELECTED_FILE, CHECK_ALL);
+ filelist_select(sfile->files, &sel, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
}
else {
const FileCheckType check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_FILES;
- filelist_select(sfile->files, &sel, FILE_SEL_ADD, SELECTED_FILE, check_type);
+ filelist_select(sfile->files, &sel, FILE_SEL_ADD, FILE_SEL_SELECTED, check_type);
}
+ file_draw_check(C);
ED_area_tag_redraw(sa);
return OPERATOR_FINISHED;
}
@@ -424,18 +457,20 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot)
/* ---------- BOOKMARKS ----------- */
+/* Note we could get rid of this one, but it's used by some addon so... Does not hurt keeping it around for now. */
static int bookmark_select_exec(bContext *C, wmOperator *op)
{
SpaceFile *sfile = CTX_wm_space_file(C);
+ PropertyRNA *prop;
- if (RNA_struct_find_property(op->ptr, "dir")) {
+ if ((prop = RNA_struct_find_property(op->ptr, "dir"))) {
char entry[256];
FileSelectParams *params = sfile->params;
- RNA_string_get(op->ptr, "dir", entry);
+ RNA_property_string_get(op->ptr, prop, entry);
BLI_strncpy(params->dir, entry, sizeof(params->dir));
BLI_cleanup_dir(G.main->name, params->dir);
- file_change_dir(C, 1);
+ ED_file_change_dir(C, true);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
@@ -465,17 +500,18 @@ static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
- struct FSMenu *fsmenu = fsmenu_get();
+ struct FSMenu *fsmenu = ED_fsmenu_get();
struct FileSelectParams *params = ED_fileselect_get_params(sfile);
if (params->dir[0] != '\0') {
char name[FILE_MAX];
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, FS_INSERT_SAVE);
- BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, NULL, FS_INSERT_SAVE);
+ BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, name);
}
+ ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
return OPERATOR_FINISHED;
}
@@ -495,17 +531,27 @@ void FILE_OT_bookmark_add(wmOperatorType *ot)
static int bookmark_delete_exec(bContext *C, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
- struct FSMenu *fsmenu = fsmenu_get();
- int nentries = fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
-
- if (RNA_struct_find_property(op->ptr, "index")) {
- int index = RNA_int_get(op->ptr, "index");
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+ int nentries = ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
+
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "index");
+
+ if (prop) {
+ int index;
+ if (RNA_property_is_set(op->ptr, prop)) {
+ index = RNA_property_int_get(op->ptr, prop);
+ }
+ else { /* if index unset, use active bookmark... */
+ index = sfile->bookmarknr;
+ }
if ((index > -1) && (index < nentries)) {
char name[FILE_MAX];
fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index);
- BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
+ BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, name);
+ ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
}
}
@@ -531,19 +577,150 @@ void FILE_OT_bookmark_delete(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
+static int bookmark_cleanup_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ ScrArea *sa = CTX_wm_area(C);
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+ struct FSMenuEntry *fsme_next, *fsme = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS);
+ int index;
+ bool changed = false;
+
+ for (index = 0; fsme; fsme = fsme_next) {
+ fsme_next = fsme->next;
+
+ if (!BLI_is_dir(fsme->path)) {
+ fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index);
+ changed = true;
+ }
+ else {
+ index++;
+ }
+ }
+
+ if (changed) {
+ char name[FILE_MAX];
+
+ BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
+ fsmenu_write_file(fsmenu, name);
+ fsmenu_refresh_bookmarks_status(fsmenu);
+ ED_area_tag_refresh(sa);
+ ED_area_tag_redraw(sa);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void FILE_OT_bookmark_cleanup(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Cleanup Bookmarks";
+ ot->description = "Delete all invalid bookmarks";
+ ot->idname = "FILE_OT_bookmark_cleanup";
+
+ /* api callbacks */
+ ot->exec = bookmark_cleanup_exec;
+ ot->poll = ED_operator_file_active;
+
+ /* properties */
+}
+
+enum {
+ FILE_BOOKMARK_MOVE_TOP = -2,
+ FILE_BOOKMARK_MOVE_UP = -1,
+ FILE_BOOKMARK_MOVE_DOWN = 1,
+ FILE_BOOKMARK_MOVE_BOTTOM = 2,
+};
+
+static int bookmark_move_exec(bContext *C, wmOperator *op)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+ struct FSMenuEntry *fsmentry = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS);
+ const struct FSMenuEntry *fsmentry_org = fsmentry;
+
+ char fname[FILE_MAX];
+
+ const int direction = RNA_enum_get(op->ptr, "direction");
+ const int totitems = ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
+ const int act_index = sfile->bookmarknr;
+ int new_index;
+
+ if (totitems < 2) {
+ return OPERATOR_CANCELLED;
+ }
+
+ switch (direction) {
+ case FILE_BOOKMARK_MOVE_TOP:
+ new_index = 0;
+ break;
+ case FILE_BOOKMARK_MOVE_BOTTOM:
+ new_index = totitems - 1;
+ break;
+ case FILE_BOOKMARK_MOVE_UP:
+ case FILE_BOOKMARK_MOVE_DOWN:
+ default:
+ new_index = (totitems + act_index + direction) % totitems;
+ break;
+ }
+
+ if (new_index == act_index) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BLI_linklist_move_item((LinkNode **)&fsmentry, act_index, new_index);
+ if (fsmentry != fsmentry_org) {
+ ED_fsmenu_set_category(fsmenu, FS_CATEGORY_BOOKMARKS, fsmentry);
+ }
+
+ /* Need to update active bookmark number. */
+ sfile->bookmarknr = new_index;
+
+ BLI_make_file_string("/", fname, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
+ fsmenu_write_file(fsmenu, fname);
+
+ ED_area_tag_redraw(sa);
+ return OPERATOR_FINISHED;
+}
+
+void FILE_OT_bookmark_move(wmOperatorType *ot)
+{
+ static EnumPropertyItem slot_move[] = {
+ {FILE_BOOKMARK_MOVE_TOP, "TOP", 0, "Top", "Top of the list"},
+ {FILE_BOOKMARK_MOVE_UP, "UP", 0, "Up", ""},
+ {FILE_BOOKMARK_MOVE_DOWN, "DOWN", 0, "Down", ""},
+ {FILE_BOOKMARK_MOVE_BOTTOM, "BOTTOM", 0, "Bottom", "Bottom of the list"},
+ { 0, NULL, 0, NULL, NULL }
+ };
+
+ /* identifiers */
+ ot->name = "Move Bookmark";
+ ot->idname = "FILE_OT_bookmark_move";
+ ot->description = "Move the active bookmark up/down in the list";
+
+ /* api callbacks */
+ ot->poll = ED_operator_file_active;
+ ot->exec = bookmark_move_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER; /* No undo! */
+
+ RNA_def_enum(ot->srna, "direction", slot_move, 0, "Direction", "Direction to move, UP or DOWN");
+}
+
static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op))
{
ScrArea *sa = CTX_wm_area(C);
char name[FILE_MAX];
- struct FSMenu *fsmenu = fsmenu_get();
+ struct FSMenu *fsmenu = ED_fsmenu_get();
- while (fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) {
+ while (ED_fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) {
fsmenu_remove_entry(fsmenu, FS_CATEGORY_RECENT, 0);
}
- BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
+ BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu, name);
ED_area_tag_redraw(sa);
-
+
return OPERATOR_FINISHED;
}
@@ -658,57 +835,59 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath)
{
+ PropertyRNA *prop;
+
BLI_join_dirfile(filepath, FILE_MAX, sfile->params->dir, sfile->params->file); /* XXX, not real length */
- if (RNA_struct_find_property(op->ptr, "relative_path")) {
- if (RNA_boolean_get(op->ptr, "relative_path")) {
+
+ if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
BLI_path_rel(filepath, G.main->name);
}
}
- if (RNA_struct_find_property(op->ptr, "filename")) {
- RNA_string_set(op->ptr, "filename", sfile->params->file);
+ if ((prop = RNA_struct_find_property(op->ptr, "filename"))) {
+ RNA_property_string_set(op->ptr, prop, sfile->params->file);
}
- if (RNA_struct_find_property(op->ptr, "directory")) {
- RNA_string_set(op->ptr, "directory", sfile->params->dir);
+ if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
+ RNA_property_string_set(op->ptr, prop, sfile->params->dir);
}
- if (RNA_struct_find_property(op->ptr, "filepath")) {
- RNA_string_set(op->ptr, "filepath", filepath);
+ if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
+ RNA_property_string_set(op->ptr, prop, filepath);
}
/* some ops have multiple files to select */
/* this is called on operators check() so clear collections first since
* they may be already set. */
{
- PointerRNA itemptr;
- PropertyRNA *prop_files = RNA_struct_find_property(op->ptr, "files");
- PropertyRNA *prop_dirs = RNA_struct_find_property(op->ptr, "dirs");
int i, numfiles = filelist_numfiles(sfile->files);
- if (prop_files) {
+ if ((prop = RNA_struct_find_property(op->ptr, "files"))) {
+ PointerRNA itemptr;
int num_files = 0;
- RNA_property_collection_clear(op->ptr, prop_files);
+ RNA_property_collection_clear(op->ptr, prop);
for (i = 0; i < numfiles; i++) {
if (filelist_is_selected(sfile->files, i, CHECK_FILES)) {
struct direntry *file = filelist_file(sfile->files, i);
- RNA_property_collection_add(op->ptr, prop_files, &itemptr);
+ RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", file->relname);
num_files++;
}
}
/* make sure the file specified in the filename button is added even if no files selected */
if (0 == num_files) {
- RNA_property_collection_add(op->ptr, prop_files, &itemptr);
+ RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", sfile->params->file);
}
}
- if (prop_dirs) {
+ if ((prop = RNA_struct_find_property(op->ptr, "dirs"))) {
+ PointerRNA itemptr;
int num_dirs = 0;
- RNA_property_collection_clear(op->ptr, prop_dirs);
+ RNA_property_collection_clear(op->ptr, prop);
for (i = 0; i < numfiles; i++) {
if (filelist_is_selected(sfile->files, i, CHECK_DIRS)) {
struct direntry *file = filelist_file(sfile->files, i);
- RNA_property_collection_add(op->ptr, prop_dirs, &itemptr);
+ RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", file->relname);
num_dirs++;
}
@@ -716,7 +895,7 @@ void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath)
/* make sure the directory specified in the button is added even if no directory selected */
if (0 == num_dirs) {
- RNA_property_collection_add(op->ptr, prop_dirs, &itemptr);
+ RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", sfile->params->dir);
}
}
@@ -751,7 +930,7 @@ void file_operator_to_sfile(SpaceFile *sfile, wmOperator *op)
/* XXX, files and dirs updates missing, not really so important though */
}
-void file_draw_check_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
+void file_draw_check(bContext *C)
{
SpaceFile *sfile = CTX_wm_space_file(C);
wmOperator *op = sfile->op;
@@ -771,11 +950,18 @@ void file_draw_check_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
}
}
+/* for use with; UI_block_func_set */
+void file_draw_check_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
+{
+ file_draw_check(C);
+}
+
bool file_draw_check_exists(SpaceFile *sfile)
{
if (sfile->op) { /* fails on reload */
- if (RNA_struct_find_property(sfile->op->ptr, "check_existing")) {
- if (RNA_boolean_get(sfile->op->ptr, "check_existing")) {
+ PropertyRNA *prop;
+ if ((prop = RNA_struct_find_property(sfile->op->ptr, "check_existing"))) {
+ if (RNA_property_boolean_get(sfile->op->ptr, prop)) {
char filepath[FILE_MAX];
BLI_join_dirfile(filepath, sizeof(filepath), sfile->params->dir, sfile->params->file);
if (BLI_is_file(filepath)) {
@@ -818,11 +1004,13 @@ int file_exec(bContext *C, wmOperator *exec_op)
file_sfile_to_operator(op, sfile, filepath);
if (BLI_exists(sfile->params->dir)) {
- fsmenu_insert_entry(fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, FS_INSERT_SAVE | FS_INSERT_FIRST);
+ fsmenu_insert_entry(ED_fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, NULL,
+ FS_INSERT_SAVE | FS_INSERT_FIRST);
}
- BLI_make_file_string(G.main->name, filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
- fsmenu_write_file(fsmenu_get(), filepath);
+ BLI_make_file_string(G.main->name, filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL),
+ BLENDER_BOOKMARK_FILE);
+ fsmenu_write_file(ED_fsmenu_get(), filepath);
WM_event_fileselect_event(wm, op, EVT_FILESELECT_EXEC);
}
@@ -861,14 +1049,14 @@ int file_parent_exec(bContext *C, wmOperator *UNUSED(unused))
if (sfile->params->type == FILE_LOADLIB) {
char tdir[FILE_MAX], tgroup[FILE_MAX];
if (BLO_is_a_library(sfile->params->dir, tdir, tgroup)) {
- file_change_dir(C, 0);
+ ED_file_change_dir(C, false);
}
else {
- file_change_dir(C, 1);
+ ED_file_change_dir(C, true);
}
}
else {
- file_change_dir(C, 1);
+ ED_file_change_dir(C, true);
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
@@ -896,7 +1084,7 @@ static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
- struct FSMenu *fsmenu = fsmenu_get();
+ struct FSMenu *fsmenu = ED_fsmenu_get();
ED_fileselect_clear(wm, sfile);
@@ -933,7 +1121,7 @@ int file_previous_exec(bContext *C, wmOperator *UNUSED(unused))
folderlist_popdir(sfile->folders_prev, sfile->params->dir);
folderlist_pushdir(sfile->folders_next, sfile->params->dir);
- file_change_dir(C, 1);
+ ED_file_change_dir(C, true);
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
@@ -965,7 +1153,7 @@ int file_next_exec(bContext *C, wmOperator *UNUSED(unused))
// update folders_prev so we can check for it in folderlist_clear_next()
folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
- file_change_dir(C, 1);
+ ED_file_change_dir(C, true);
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
@@ -1111,6 +1299,7 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
char name[FILE_MAXFILE];
char path[FILE_MAX];
int generate_name = 1;
+ PropertyRNA *prop;
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -1122,8 +1311,8 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
path[0] = '\0';
- if (RNA_struct_find_property(op->ptr, "directory")) {
- RNA_string_get(op->ptr, "directory", path);
+ if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
+ RNA_property_string_get(op->ptr, prop, path);
if (path[0] != '\0') generate_name = 0;
}
@@ -1155,7 +1344,7 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
if (RNA_boolean_get(op->ptr, "open")) {
BLI_strncpy(sfile->params->dir, path, sizeof(sfile->params->dir));
- file_change_dir(C, 1);
+ ED_file_change_dir(C, true);
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
@@ -1197,7 +1386,7 @@ static void file_expand_directory(bContext *C)
else if (sfile->params->dir[0] == '~') {
char tmpstr[sizeof(sfile->params->dir) - 1];
BLI_strncpy(tmpstr, sfile->params->dir + 1, sizeof(tmpstr));
- BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BLI_getDefaultDocumentFolder(), tmpstr);
+ BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BKE_appdir_folder_default(), tmpstr);
}
else if (sfile->params->dir[0] == '\0')
@@ -1260,7 +1449,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN
if (BLI_exists(sfile->params->dir)) {
/* if directory exists, enter it immediately */
- file_change_dir(C, 1);
+ ED_file_change_dir(C, true);
/* don't do for now because it selects entire text instead of
* placing cursor at the end */
@@ -1329,7 +1518,7 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
BLI_cleanup_dir(G.main->name, filepath);
BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir));
sfile->params->file[0] = '\0';
- file_change_dir(C, 1);
+ ED_file_change_dir(C, true);
UI_textbutton_activate_but(C, but);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
}
@@ -1340,12 +1529,15 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg
BLI_cleanup_dir(G.main->name, filepath);
BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir));
sfile->params->file[0] = '\0';
- file_change_dir(C, 0);
+ ED_file_change_dir(C, false);
UI_textbutton_activate_but(C, but);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
}
}
+ else if (matches > 1) {
+ file_draw_check(C);
+ }
}
}
@@ -1388,37 +1580,37 @@ void FILE_OT_hidedot(struct wmOperatorType *ot)
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
}
-ARegion *file_buttons_region(ScrArea *sa)
+ARegion *file_tools_region(ScrArea *sa)
{
ARegion *ar, *arnew;
-
- for (ar = sa->regionbase.first; ar; ar = ar->next)
- if (ar->regiontype == RGN_TYPE_CHANNELS)
- return ar;
+
+ if ((ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS)) != NULL)
+ return ar;
/* add subdiv level; after header */
- for (ar = sa->regionbase.first; ar; ar = ar->next)
- if (ar->regiontype == RGN_TYPE_HEADER)
- break;
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
/* is error! */
- if (ar == NULL) return NULL;
-
- arnew = MEM_callocN(sizeof(ARegion), "buttons for file panels");
+ if (ar == NULL)
+ return NULL;
+ arnew = MEM_callocN(sizeof(ARegion), "tools for file");
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
- arnew->regiontype = RGN_TYPE_CHANNELS;
+ arnew->regiontype = RGN_TYPE_TOOLS;
arnew->alignment = RGN_ALIGN_LEFT;
-
- arnew->flag = RGN_FLAG_HIDDEN;
-
+
+ ar = MEM_callocN(sizeof(ARegion), "tool props for file");
+ BLI_insertlinkafter(&sa->regionbase, arnew, ar);
+ ar->regiontype = RGN_TYPE_TOOL_PROPS;
+ ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
+
return arnew;
}
static int file_bookmark_toggle_exec(bContext *C, wmOperator *UNUSED(unused))
{
ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = file_buttons_region(sa);
+ ARegion *ar = file_tools_region(sa);
if (ar)
ED_region_toggle_hidden(C, ar);
@@ -1448,7 +1640,7 @@ static int file_filenum_exec(bContext *C, wmOperator *op)
if (sfile->params && (inc != 0)) {
BLI_newname(sfile->params->file, inc);
ED_area_tag_redraw(sa);
- file_draw_check_cb(C, NULL, NULL);
+ file_draw_check(C);
// WM_event_add_notifier(C, NC_WINDOW, NULL);
}
@@ -1481,7 +1673,7 @@ static int file_rename_exec(bContext *C, wmOperator *UNUSED(op))
int numfiles = filelist_numfiles(sfile->files);
if ( (0 <= idx) && (idx < numfiles) ) {
struct direntry *file = filelist_file(sfile->files, idx);
- filelist_select_file(sfile->files, idx, FILE_SEL_ADD, EDITING_FILE, CHECK_ALL);
+ filelist_select_file(sfile->files, idx, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
BLI_strncpy(sfile->params->renameedit, file->relname, FILE_MAXFILE);
sfile->params->renamefile[0] = '\0';
}
@@ -1498,6 +1690,15 @@ static int file_rename_poll(bContext *C)
SpaceFile *sfile = CTX_wm_space_file(C);
if (sfile && sfile->params) {
+ int idx = sfile->params->active_file;
+
+ if (idx >= 0) {
+ struct direntry *file = filelist_file(sfile->files, idx);
+ if (FILENAME_IS_CURRPAR(file->relname)) {
+ poll = 0;
+ }
+ }
+
if (sfile->params->active_file < 0) {
poll = 0;
}
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
index 8fad17e1210..3da83aa6028 100644
--- a/source/blender/editors/space_file/file_panels.c
+++ b/source/blender/editors/space_file/file_panels.c
@@ -44,6 +44,8 @@
#include "RNA_access.h"
+#include "ED_fileselect.h"
+
#include "UI_interface.h"
#include "UI_resources.h"
@@ -55,140 +57,6 @@
#include <string.h>
-static void file_panel_cb(bContext *C, void *arg_entry, void *UNUSED(arg_v))
-{
- wmOperatorType *ot = WM_operatortype_find("FILE_OT_select_bookmark", false);
- PointerRNA ptr;
- const char *entry = (char *)arg_entry;
-
- WM_operator_properties_create_ptr(&ptr, ot);
- RNA_string_set(&ptr, "dir", entry);
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_REGION_WIN, &ptr);
- WM_operator_properties_free(&ptr);
-}
-
-static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory category, short *nr, int icon, int allow_delete)
-{
- SpaceFile *sfile = CTX_wm_space_file(C);
- uiBlock *block;
- uiBut *but;
- uiLayout *box, *col;
- struct FSMenu *fsmenu = fsmenu_get();
- int i, nentries = fsmenu_get_nentries(fsmenu, category);
-
- /* reset each time */
- *nr = -1;
-
- /* hide if no entries */
- if (nentries == 0)
- return;
-
- /* layout */
- uiLayoutSetAlignment(pa->layout, UI_LAYOUT_ALIGN_LEFT);
- block = uiLayoutGetBlock(pa->layout);
- box = uiLayoutBox(pa->layout);
- col = uiLayoutColumn(box, true);
-
- for (i = 0; i < nentries; ++i) {
- char dir[FILE_MAX];
- char temp[FILE_MAX];
- uiLayout *layout = uiLayoutRow(col, false);
- char *entry;
-
- entry = fsmenu_get_entry(fsmenu, category, i);
-
- /* set this list item as active if we have a match */
- if (sfile->params) {
- if (BLI_path_cmp(sfile->params->dir, entry) == 0) {
- *nr = i;
- }
- }
-
- /* create nice bookmark name, shows last directory in the full path currently */
- BLI_strncpy(temp, entry, FILE_MAX);
- BLI_add_slash(temp);
- BLI_getlastdir(temp, dir, FILE_MAX);
- BLI_del_slash(dir);
-
- if (dir[0] == 0)
- BLI_strncpy(dir, entry, FILE_MAX);
-
- /* create list item */
- but = uiDefIconTextButS(block, LISTROW, 0, icon, dir, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nr, 0, i, 0, 0, entry);
- uiButSetFunc(but, file_panel_cb, entry, NULL);
- uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
- uiButSetDrawFlag(but, UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT);
-
- /* create delete button */
- if (allow_delete && fsmenu_can_save(fsmenu, category, i)) {
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiItemIntO(layout, "", ICON_X, "FILE_OT_bookmark_delete", "index", i);
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- }
-}
-
-static void file_panel_system(const bContext *C, Panel *pa)
-{
- SpaceFile *sfile = CTX_wm_space_file(C);
-
- if (sfile)
- file_panel_category(C, pa, FS_CATEGORY_SYSTEM, &sfile->systemnr, ICON_DISK_DRIVE, 0);
-}
-
-static int file_panel_system_bookmarks_poll(const bContext *C, PanelType *UNUSED(pt))
-{
- SpaceFile *sfile = CTX_wm_space_file(C);
- return (sfile && !(U.uiflag & USER_HIDE_SYSTEM_BOOKMARKS));
-}
-
-static void file_panel_system_bookmarks(const bContext *C, Panel *pa)
-{
- SpaceFile *sfile = CTX_wm_space_file(C);
-
- if (sfile && !(U.uiflag & USER_HIDE_SYSTEM_BOOKMARKS)) {
- file_panel_category(C, pa, FS_CATEGORY_SYSTEM_BOOKMARKS, &sfile->systemnr, ICON_BOOKMARKS, 0);
- }
-
-}
-
-static void file_panel_bookmarks(const bContext *C, Panel *pa)
-{
- SpaceFile *sfile = CTX_wm_space_file(C);
- uiLayout *row;
-
- if (sfile) {
- row = uiLayoutRow(pa->layout, false);
- uiItemO(row, IFACE_("Add"), ICON_ZOOMIN, "file.bookmark_add");
- uiItemL(row, NULL, ICON_NONE);
-
- file_panel_category(C, pa, FS_CATEGORY_BOOKMARKS, &sfile->bookmarknr, ICON_BOOKMARKS, 1);
- }
-}
-
-static int file_panel_recent_poll(const bContext *C, PanelType *UNUSED(pt))
-{
- SpaceFile *sfile = CTX_wm_space_file(C);
- return (sfile && !(U.uiflag & USER_HIDE_RECENT));
-}
-
-static void file_panel_recent(const bContext *C, Panel *pa)
-{
- SpaceFile *sfile = CTX_wm_space_file(C);
- uiLayout *row;
-
- if (sfile) {
- if (!(U.uiflag & USER_HIDE_RECENT)) {
- row = uiLayoutRow(pa->layout, false);
- uiItemO(row, IFACE_("Reset"), ICON_X, "file.reset_recent");
- uiItemL(row, NULL, ICON_NONE);
-
- file_panel_category(C, pa, FS_CATEGORY_RECENT, &sfile->recentnr, ICON_FILE_FOLDER, 0);
- }
- }
-}
-
-
static int file_panel_operator_poll(const bContext *C, PanelType *UNUSED(pt))
{
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -217,48 +85,18 @@ static void file_panel_operator(const bContext *C, Panel *pa)
SpaceFile *sfile = CTX_wm_space_file(C);
wmOperator *op = sfile->op;
// int empty = 1, flag;
-
- uiBlockSetFunc(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL);
+
+ UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL);
uiLayoutOperatorButs(C, pa->layout, op, file_panel_check_prop, '\0', UI_LAYOUT_OP_SHOW_EMPTY);
- uiBlockSetFunc(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL);
+ UI_block_func_set(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL);
}
void file_panels_register(ARegionType *art)
{
PanelType *pt;
- pt = MEM_callocN(sizeof(PanelType), "spacetype file system directories");
- strcpy(pt->idname, "FILE_PT_system");
- strcpy(pt->label, N_("System"));
- strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = file_panel_system;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype file system bookmarks");
- strcpy(pt->idname, "FILE_PT_system_bookmarks");
- strcpy(pt->label, N_("System Bookmarks"));
- strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = file_panel_system_bookmarks;
- pt->poll = file_panel_system_bookmarks_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype file bookmarks");
- strcpy(pt->idname, "FILE_PT_bookmarks");
- strcpy(pt->label, N_("Bookmarks"));
- strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = file_panel_bookmarks;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype file recent directories");
- strcpy(pt->idname, "FILE_PT_recent");
- strcpy(pt->label, N_("Recent"));
- strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = file_panel_recent;
- pt->poll = file_panel_recent_poll;
- BLI_addtail(&art->paneltypes, pt);
-
pt = MEM_callocN(sizeof(PanelType), "spacetype file operator properties");
strcpy(pt->idname, "FILE_PT_operator");
strcpy(pt->label, N_("Operator"));
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 871abbda48a..66acd7d05e3 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -37,17 +37,18 @@
#include <string.h>
#ifndef WIN32
-#include <unistd.h>
+# include <unistd.h>
#else
-#include <io.h>
-#include <direct.h>
+# include <io.h>
+# include <direct.h>
#endif
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_fileops_types.h"
+#include "BLI_fnmatch.h"
#include "BLI_linklist.h"
#include "BLI_utildefines.h"
-#include "BLI_fileops_types.h"
#ifdef WIN32
# include "BLI_winstuff.h"
@@ -57,15 +58,15 @@
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_icons.h"
+#include "BKE_idcode.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BLO_readfile.h"
-#include "BKE_idcode.h"
#include "DNA_space_types.h"
-#include "ED_fileselect.h"
#include "ED_datafiles.h"
+#include "ED_fileselect.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -80,6 +81,119 @@
#include "filelist.h"
+
+/* ----------------- FOLDERLIST (previous/next) -------------- */
+
+typedef struct FolderList {
+ struct FolderList *next, *prev;
+ char *foldername;
+} FolderList;
+
+ListBase *folderlist_new(void)
+{
+ ListBase *p = MEM_callocN(sizeof(*p), __func__);
+ return p;
+}
+
+void folderlist_popdir(struct ListBase *folderlist, char *dir)
+{
+ const char *prev_dir;
+ struct FolderList *folder;
+ folder = folderlist->last;
+
+ if (folder) {
+ /* remove the current directory */
+ MEM_freeN(folder->foldername);
+ BLI_freelinkN(folderlist, folder);
+
+ folder = folderlist->last;
+ if (folder) {
+ prev_dir = folder->foldername;
+ BLI_strncpy(dir, prev_dir, FILE_MAXDIR);
+ }
+ }
+ /* delete the folder next or use setdir directly before PREVIOUS OP */
+}
+
+void folderlist_pushdir(ListBase *folderlist, const char *dir)
+{
+ struct FolderList *folder, *previous_folder;
+ previous_folder = folderlist->last;
+
+ /* check if already exists */
+ if (previous_folder && previous_folder->foldername) {
+ if (BLI_path_cmp(previous_folder->foldername, dir) == 0) {
+ return;
+ }
+ }
+
+ /* create next folder element */
+ folder = MEM_mallocN(sizeof(*folder), __func__);
+ folder->foldername = BLI_strdup(dir);
+
+ /* add it to the end of the list */
+ BLI_addtail(folderlist, folder);
+}
+
+const char *folderlist_peeklastdir(ListBase *folderlist)
+{
+ struct FolderList *folder;
+
+ if (!folderlist->last)
+ return NULL;
+
+ folder = folderlist->last;
+ return folder->foldername;
+}
+
+int folderlist_clear_next(struct SpaceFile *sfile)
+{
+ struct FolderList *folder;
+
+ /* if there is no folder_next there is nothing we can clear */
+ if (!sfile->folders_next)
+ return 0;
+
+ /* if previous_folder, next_folder or refresh_folder operators are executed it doesn't clear folder_next */
+ folder = sfile->folders_prev->last;
+ if ((!folder) || (BLI_path_cmp(folder->foldername, sfile->params->dir) == 0))
+ return 0;
+
+ /* eventually clear flist->folders_next */
+ return 1;
+}
+
+/* not listbase itself */
+void folderlist_free(ListBase *folderlist)
+{
+ if (folderlist) {
+ FolderList *folder;
+ for (folder = folderlist->first; folder; folder = folder->next)
+ MEM_freeN(folder->foldername);
+ BLI_freelistN(folderlist);
+ }
+}
+
+ListBase *folderlist_duplicate(ListBase *folderlist)
+{
+
+ if (folderlist) {
+ ListBase *folderlistn = MEM_callocN(sizeof(*folderlistn), __func__);
+ FolderList *folder;
+
+ BLI_duplicatelist(folderlistn, folderlist);
+
+ for (folder = folderlistn->first; folder; folder = folder->next) {
+ folder->foldername = MEM_dupallocN(folder->foldername);
+ }
+ return folderlistn;
+ }
+ return NULL;
+}
+
+
+/* ------------------FILELIST------------------------ */
+
struct FileList;
typedef struct FileImage {
@@ -91,166 +205,155 @@ typedef struct FileImage {
ImBuf *img;
} FileImage;
-typedef struct ThumbnailJob {
- ListBase loadimages;
- const short *stop;
- const short *do_update;
- struct FileList *filelist;
- ReportList reports;
-} ThumbnailJob;
+typedef struct FileListFilter {
+ bool hide_dot;
+ bool hide_parent;
+ unsigned int filter;
+ char filter_glob[64];
+ char filter_search[66]; /* + 2 for heading/trailing implicit '*' wildcards. */
+} FileListFilter;
typedef struct FileList {
struct direntry *filelist;
- int *fidx;
int numfiles;
- int numfiltered;
char dir[FILE_MAX];
short prv_w;
short prv_h;
- short hide_dot;
- unsigned int filter;
- char filter_glob[64];
- short changed;
+
+ bool changed;
+
+ short sort;
+ bool need_sorting;
+
+ FileListFilter filter_data;
+ int *fidx; /* Also used to detect when we need to filter! */
+ int numfiltered;
+
+ bool need_thumbnails;
struct BlendHandle *libfiledata;
- short hide_parent;
void (*readf)(struct FileList *);
- bool (*filterf)(struct direntry *file, const char *dir, unsigned int filter, short hide_dot);
-
+ bool (*filterf)(struct direntry *, const char *, FileListFilter *);
} FileList;
-typedef struct FolderList {
- struct FolderList *next, *prev;
- char *foldername;
-} FolderList;
-
#define SPECIAL_IMG_SIZE 48
#define SPECIAL_IMG_ROWS 4
#define SPECIAL_IMG_COLS 4
-#define SPECIAL_IMG_FOLDER 0
-#define SPECIAL_IMG_PARENT 1
-#define SPECIAL_IMG_REFRESH 2
-#define SPECIAL_IMG_BLENDFILE 3
-#define SPECIAL_IMG_SOUNDFILE 4
-#define SPECIAL_IMG_MOVIEFILE 5
-#define SPECIAL_IMG_PYTHONFILE 6
-#define SPECIAL_IMG_TEXTFILE 7
-#define SPECIAL_IMG_FONTFILE 8
-#define SPECIAL_IMG_UNKNOWNFILE 9
-#define SPECIAL_IMG_LOADING 10
-#define SPECIAL_IMG_BACKUP 11
-#define SPECIAL_IMG_MAX SPECIAL_IMG_BACKUP + 1
+enum {
+ SPECIAL_IMG_FOLDER = 0,
+ SPECIAL_IMG_PARENT = 1,
+ SPECIAL_IMG_REFRESH = 2,
+ SPECIAL_IMG_BLENDFILE = 3,
+ SPECIAL_IMG_SOUNDFILE = 4,
+ SPECIAL_IMG_MOVIEFILE = 5,
+ SPECIAL_IMG_PYTHONFILE = 6,
+ SPECIAL_IMG_TEXTFILE = 7,
+ SPECIAL_IMG_FONTFILE = 8,
+ SPECIAL_IMG_UNKNOWNFILE = 9,
+ SPECIAL_IMG_LOADING = 10,
+ SPECIAL_IMG_BACKUP = 11,
+ SPECIAL_IMG_MAX
+};
static ImBuf *gSpecialFileImages[SPECIAL_IMG_MAX];
-/* ******************* SORT ******************* */
+static void filelist_from_main(struct FileList *filelist);
+static void filelist_from_library(struct FileList *filelist);
+
+static void filelist_read_main(struct FileList *filelist);
+static void filelist_read_library(struct FileList *filelist);
+static void filelist_read_dir(struct FileList *filelist);
+
+static void filelist_filter_clear(FileList *filelist);
+
+/* ********** Sort helpers ********** */
static bool compare_is_directory(const struct direntry *entry)
{
/* for library browse .blend files may be treated as directories, but
* for sorting purposes they should be considered regular files */
if (S_ISDIR(entry->type))
- return !(entry->flags & (BLENDERFILE | BLENDERFILE_BACKUP));
+ return !(entry->flags & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP));
return false;
}
-static int compare_name(const void *a1, const void *a2)
+static int compare_direntry_generic(const struct direntry *entry1, const struct direntry *entry2)
{
- const struct direntry *entry1 = a1, *entry2 = a2;
-
/* type is equal to stat.st_mode */
if (compare_is_directory(entry1)) {
- if (compare_is_directory(entry2) == 0) return (-1);
+ if (compare_is_directory(entry2) == 0) {
+ return -1;
+ }
}
- else {
- if (compare_is_directory(entry2)) return (1);
+ else if (compare_is_directory(entry2)) {
+ return 1;
}
+
if (S_ISREG(entry1->type)) {
- if (S_ISREG(entry2->type) == 0) return (-1);
+ if (!S_ISREG(entry2->type)) {
+ return -1;
+ }
}
- else {
- if (S_ISREG(entry2->type)) return (1);
+ else if (S_ISREG(entry2->type)) {
+ return 1;
}
- if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
- if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
+ if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return -1;
+ if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return 1;
/* make sure "." and ".." are always first */
- if (strcmp(entry1->relname, ".") == 0) return (-1);
- if (strcmp(entry2->relname, ".") == 0) return (1);
- if (strcmp(entry1->relname, "..") == 0) return (-1);
- if (strcmp(entry2->relname, "..") == 0) return (1);
+ if (FILENAME_IS_CURRENT(entry1->relname)) return -1;
+ if (FILENAME_IS_CURRENT(entry2->relname)) return 1;
+ if (FILENAME_IS_PARENT(entry1->relname)) return -1;
+ if (FILENAME_IS_PARENT(entry2->relname)) return 1;
+ return 0;
+}
+
+static int compare_name(const void *a1, const void *a2)
+{
+ const struct direntry *entry1 = a1, *entry2 = a2;
+ int ret;
+
+ if ((ret = compare_direntry_generic(entry1, entry2))) {
+ return ret;
+ }
+
return (BLI_natstrcmp(entry1->relname, entry2->relname));
}
static int compare_date(const void *a1, const void *a2)
{
const struct direntry *entry1 = a1, *entry2 = a2;
-
- /* type is equal to stat.st_mode */
+ int ret;
- if (compare_is_directory(entry1)) {
- if (compare_is_directory(entry2) == 0) return (-1);
- }
- else {
- if (compare_is_directory(entry2)) return (1);
- }
- if (S_ISREG(entry1->type)) {
- if (S_ISREG(entry2->type) == 0) return (-1);
- }
- else {
- if (S_ISREG(entry2->type)) return (1);
+ if ((ret = compare_direntry_generic(entry1, entry2))) {
+ return ret;
}
- if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
- if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
-
- /* make sure "." and ".." are always first */
- if (strcmp(entry1->relname, ".") == 0) return (-1);
- if (strcmp(entry2->relname, ".") == 0) return (1);
- if (strcmp(entry1->relname, "..") == 0) return (-1);
- if (strcmp(entry2->relname, "..") == 0) return (1);
if (entry1->s.st_mtime < entry2->s.st_mtime) return 1;
if (entry1->s.st_mtime > entry2->s.st_mtime) return -1;
-
- else return BLI_natstrcmp(entry1->relname, entry2->relname);
+
+ return BLI_natstrcmp(entry1->relname, entry2->relname);
}
static int compare_size(const void *a1, const void *a2)
{
const struct direntry *entry1 = a1, *entry2 = a2;
+ int ret;
- /* type is equal to stat.st_mode */
-
- if (compare_is_directory(entry1)) {
- if (compare_is_directory(entry2) == 0) return (-1);
+ if ((ret = compare_direntry_generic(entry1, entry2))) {
+ return ret;
}
- else {
- if (compare_is_directory(entry2)) return (1);
- }
- if (S_ISREG(entry1->type)) {
- if (S_ISREG(entry2->type) == 0) return (-1);
- }
- else {
- if (S_ISREG(entry2->type)) return (1);
- }
- if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
- if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
-
- /* make sure "." and ".." are always first */
- if (strcmp(entry1->relname, ".") == 0) return (-1);
- if (strcmp(entry2->relname, ".") == 0) return (1);
- if (strcmp(entry1->relname, "..") == 0) return (-1);
- if (strcmp(entry2->relname, "..") == 0) return (1);
if (entry1->s.st_size < entry2->s.st_size) return 1;
if (entry1->s.st_size > entry2->s.st_size) return -1;
- else return BLI_natstrcmp(entry1->relname, entry2->relname);
+
+ return BLI_natstrcmp(entry1->relname, entry2->relname);
}
static int compare_extension(const void *a1, const void *a2)
@@ -258,6 +361,11 @@ static int compare_extension(const void *a1, const void *a2)
const struct direntry *entry1 = a1, *entry2 = a2;
const char *sufix1, *sufix2;
const char *nil = "";
+ int ret;
+
+ if ((ret = compare_direntry_generic(entry1, entry2))) {
+ return ret;
+ }
if (!(sufix1 = strstr(entry1->relname, ".blend.gz")))
sufix1 = strrchr(entry1->relname, '.');
@@ -266,126 +374,191 @@ static int compare_extension(const void *a1, const void *a2)
if (!sufix1) sufix1 = nil;
if (!sufix2) sufix2 = nil;
- /* type is equal to stat.st_mode */
+ return BLI_strcasecmp(sufix1, sufix2);
+}
- if (compare_is_directory(entry1)) {
- if (compare_is_directory(entry2) == 0) return (-1);
- }
- else {
- if (compare_is_directory(entry2)) return (1);
- }
- if (S_ISREG(entry1->type)) {
- if (S_ISREG(entry2->type) == 0) return (-1);
+bool filelist_need_sorting(struct FileList *filelist)
+{
+ return filelist->need_sorting && (filelist->sort != FILE_SORT_NONE);
+}
+
+void filelist_sort(struct FileList *filelist)
+{
+ if (filelist_need_sorting(filelist)) {
+ filelist->need_sorting = false;
+
+ switch (filelist->sort) {
+ case FILE_SORT_ALPHA:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_name);
+ break;
+ case FILE_SORT_TIME:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_date);
+ break;
+ case FILE_SORT_SIZE:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_size);
+ break;
+ case FILE_SORT_EXTENSION:
+ qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension);
+ break;
+ case FILE_SORT_NONE: /* Should never reach this point! */
+ default:
+ BLI_assert(0);
+ return;
+ }
+
+ filelist_filter_clear(filelist);
}
- else {
- if (S_ISREG(entry2->type)) return (1);
+}
+
+void filelist_setsorting(struct FileList *filelist, const short sort)
+{
+ if (filelist->sort != sort) {
+ filelist->sort = sort;
+ filelist->need_sorting = true;
}
- if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
- if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
-
- /* make sure "." and ".." are always first */
- if (strcmp(entry1->relname, ".") == 0) return (-1);
- if (strcmp(entry2->relname, ".") == 0) return (1);
- if (strcmp(entry1->relname, "..") == 0) return (-1);
- if (strcmp(entry2->relname, "..") == 0) return (1);
-
- return (BLI_strcasecmp(sufix1, sufix2));
}
-static bool is_hidden_file(const char *filename, short hide_dot)
+/* ********** Filter helpers ********** */
+
+static bool is_hidden_file(const char *filename, FileListFilter *filter)
{
bool is_hidden = false;
- if (hide_dot) {
- if (filename[0] == '.' && filename[1] != '.' && filename[1] != 0) {
- is_hidden = 1; /* ignore .file */
- }
- else if (((filename[0] == '.') && (filename[1] == 0))) {
- is_hidden = 1; /* ignore . */
+ if (filter->hide_dot) {
+ if (filename[0] == '.' && filename[1] != '.' && filename[1] != '\0') {
+ is_hidden = true; /* ignore .file */
}
else {
int len = strlen(filename);
if ((len > 0) && (filename[len - 1] == '~')) {
- is_hidden = 1; /* ignore file~ */
+ is_hidden = true; /* ignore file~ */
}
}
}
- else {
- if (((filename[0] == '.') && (filename[1] == 0))) {
- is_hidden = 1; /* ignore . */
+ if (!is_hidden && filter->hide_parent) {
+ if (filename[0] == '.' && filename[1] == '.' && filename[2] == '\0') {
+ is_hidden = true; /* ignore .. */
}
}
+ if (!is_hidden && ((filename[0] == '.') && (filename[1] == '\0'))) {
+ is_hidden = true; /* ignore . */
+ }
return is_hidden;
}
-static bool is_filtered_file(struct direntry *file, const char *UNUSED(dir), unsigned int filter, short hide_dot)
+static bool is_filtered_file(struct direntry *file, const char *UNUSED(root), FileListFilter *filter)
{
- bool is_filtered = false;
- if (filter) {
- if (file->flags & filter) {
- is_filtered = 1;
+ bool is_filtered = !is_hidden_file(file->relname, filter);
+
+ if (is_filtered && filter->filter && !FILENAME_IS_CURRPAR(file->relname)) {
+ if ((file->type & S_IFDIR) && !(filter->filter & FILE_TYPE_FOLDER)) {
+ is_filtered = false;
+ }
+ if (!(file->type & S_IFDIR) && !(file->flags & filter->filter)) {
+ is_filtered = false;
}
- else if (file->type & S_IFDIR) {
- if (filter & FOLDERFILE) {
- is_filtered = 1;
+ if (is_filtered && (filter->filter_search[0] != '\0')) {
+ if (fnmatch(filter->filter_search, file->relname, FNM_CASEFOLD) != 0) {
+ is_filtered = false;
}
}
}
- else {
- is_filtered = 1;
- }
- return is_filtered && !is_hidden_file(file->relname, hide_dot);
+
+ return is_filtered;
}
-static bool is_filtered_lib(struct direntry *file, const char *dir, unsigned int filter, short hide_dot)
+static bool is_filtered_lib(struct direntry *file, const char *root, FileListFilter *filter)
{
- bool is_filtered = false;
- char tdir[FILE_MAX], tgroup[BLO_GROUP_MAX];
- if (BLO_is_a_library(dir, tdir, tgroup)) {
- is_filtered = !is_hidden_file(file->relname, hide_dot);
+ bool is_filtered = !is_hidden_file(file->relname, filter);
+ char dir[FILE_MAXDIR], group[BLO_GROUP_MAX];
+
+ if (BLO_is_a_library(root, dir, group)) {
+ is_filtered = !is_hidden_file(file->relname, filter);
+ if (is_filtered && filter->filter && !FILENAME_IS_CURRPAR(file->relname)) {
+ if (is_filtered && (filter->filter_search[0] != '\0')) {
+ if (fnmatch(filter->filter_search, file->relname, FNM_CASEFOLD) != 0) {
+ is_filtered = false;
+ }
+ }
+ }
}
else {
- is_filtered = is_filtered_file(file, dir, filter, hide_dot);
+ is_filtered = is_filtered_file(file, root, filter);
}
+
return is_filtered;
}
-static bool is_filtered_main(struct direntry *file, const char *UNUSED(dir), unsigned int UNUSED(filter), short hide_dot)
+static bool is_filtered_main(struct direntry *file, const char *UNUSED(dir), FileListFilter *filter)
+{
+ return !is_hidden_file(file->relname, filter);
+}
+
+static void filelist_filter_clear(FileList *filelist)
{
- return !is_hidden_file(file->relname, hide_dot);
+ MEM_SAFE_FREE(filelist->fidx);
+ filelist->numfiltered = 0;
}
void filelist_filter(FileList *filelist)
{
int num_filtered = 0;
- int i, j;
+ int *fidx_tmp;
+ int i;
- if (!filelist->filelist)
+ if (!filelist->filelist) {
return;
+ }
- /* How many files are left after filter ? */
+ if (filelist->fidx) {
+ /* Assume it has already been filtered, nothing else to do! */
+ return;
+ }
+
+ fidx_tmp = MEM_mallocN(sizeof(*fidx_tmp) * (size_t)filelist->numfiles, __func__);
+
+ /* Filter remap & count how many files are left after filter in a single loop. */
for (i = 0; i < filelist->numfiles; ++i) {
struct direntry *file = &filelist->filelist[i];
- if (filelist->filterf(file, filelist->dir, filelist->filter, filelist->hide_dot)) {
- num_filtered++;
+
+ if (filelist->filterf(file, filelist->dir, &filelist->filter_data)) {
+ fidx_tmp[num_filtered++] = i;
}
}
-
- if (filelist->fidx) {
- MEM_freeN(filelist->fidx);
- filelist->fidx = NULL;
- }
- filelist->fidx = (int *)MEM_callocN(num_filtered * sizeof(int), "filteridx");
+
+ /* Note: maybe we could even accept filelist->fidx to be filelist->numfiles -len allocated? */
+ filelist->fidx = MEM_mallocN(sizeof(*filelist->fidx) * (size_t)num_filtered, __func__);
+ memcpy(filelist->fidx, fidx_tmp, sizeof(*filelist->fidx) * (size_t)num_filtered);
filelist->numfiltered = num_filtered;
- for (i = 0, j = 0; i < filelist->numfiles; ++i) {
- struct direntry *file = &filelist->filelist[i];
- if (filelist->filterf(file, filelist->dir, filelist->filter, filelist->hide_dot)) {
- filelist->fidx[j++] = i;
- }
+ MEM_freeN(fidx_tmp);
+}
+
+void filelist_setfilter_options(FileList *filelist, const bool hide_dot, const bool hide_parent,
+ const unsigned int filter,
+ const char *filter_glob, const char *filter_search)
+{
+ if ((filelist->filter_data.hide_dot != hide_dot) ||
+ (filelist->filter_data.hide_parent != hide_parent) ||
+ (filelist->filter_data.filter != filter) ||
+ !STREQ(filelist->filter_data.filter_glob, filter_glob) ||
+ (BLI_strcmp_ignore_pad(filelist->filter_data.filter_search, filter_search, '*') != 0))
+ {
+ filelist->filter_data.hide_dot = hide_dot;
+ filelist->filter_data.hide_parent = hide_parent;
+
+ filelist->filter_data.filter = filter;
+ BLI_strncpy(filelist->filter_data.filter_glob, filter_glob, sizeof(filelist->filter_data.filter_glob));
+ BLI_strncpy_ensure_pad(filelist->filter_data.filter_search, filter_search, '*',
+ sizeof(filelist->filter_data.filter_search));
+
+ /* And now, free filtered data so that we now we have to filter again. */
+ filelist_filter_clear(filelist);
}
}
+/* ********** Icon/image helpers ********** */
+
void filelist_init_icons(void)
{
short x, y, k;
@@ -428,118 +601,90 @@ void filelist_free_icons(void)
}
}
-/* -----------------FOLDERLIST (previous/next) -------------- */
-ListBase *folderlist_new(void)
-{
- ListBase *p = MEM_callocN(sizeof(ListBase), "folderlist");
- return p;
-}
-
-void folderlist_popdir(struct ListBase *folderlist, char *dir)
+void filelist_imgsize(struct FileList *filelist, short w, short h)
{
- const char *prev_dir;
- struct FolderList *folder;
- folder = folderlist->last;
-
- if (folder) {
- /* remove the current directory */
- MEM_freeN(folder->foldername);
- BLI_freelinkN(folderlist, folder);
-
- folder = folderlist->last;
- if (folder) {
- prev_dir = folder->foldername;
- BLI_strncpy(dir, prev_dir, FILE_MAXDIR);
- }
- }
- /* delete the folder next or use setdir directly before PREVIOUS OP */
+ filelist->prv_w = w;
+ filelist->prv_h = h;
}
-void folderlist_pushdir(ListBase *folderlist, const char *dir)
+ImBuf *filelist_getimage(struct FileList *filelist, const int index)
{
- struct FolderList *folder, *previous_folder;
- previous_folder = folderlist->last;
-
- /* check if already exists */
- if (previous_folder && previous_folder->foldername) {
- if (BLI_path_cmp(previous_folder->foldername, dir) == 0) {
- return;
- }
- }
-
- /* create next folder element */
- folder = (FolderList *)MEM_mallocN(sizeof(FolderList), "FolderList");
- folder->foldername = BLI_strdup(dir);
-
- /* add it to the end of the list */
- BLI_addtail(folderlist, folder);
-}
+ ImBuf *ibuf = NULL;
+ int fidx = 0;
-const char *folderlist_peeklastdir(ListBase *folderlist)
-{
- struct FolderList *folder;
+ BLI_assert(G.background == false);
- if (!folderlist->last)
+ if ((index < 0) || (index >= filelist->numfiltered)) {
return NULL;
+ }
+ fidx = filelist->fidx[index];
+ ibuf = filelist->filelist[fidx].image;
- folder = folderlist->last;
- return folder->foldername;
+ return ibuf;
}
-int folderlist_clear_next(struct SpaceFile *sfile)
+ImBuf *filelist_geticon(struct FileList *filelist, const int index)
{
- struct FolderList *folder;
-
- /* if there is no folder_next there is nothing we can clear */
- if (!sfile->folders_next)
- return 0;
-
- /* if previous_folder, next_folder or refresh_folder operators are executed it doesn't clear folder_next */
- folder = sfile->folders_prev->last;
- if ((!folder) || (BLI_path_cmp(folder->foldername, sfile->params->dir) == 0))
- return 0;
+ ImBuf *ibuf = NULL;
+ struct direntry *file = NULL;
+ int fidx = 0;
- /* eventually clear flist->folders_next */
- return 1;
-}
+ BLI_assert(G.background == false);
-/* not listbase itself */
-void folderlist_free(ListBase *folderlist)
-{
- if (folderlist) {
- FolderList *folder;
- for (folder = folderlist->first; folder; folder = folder->next)
- MEM_freeN(folder->foldername);
- BLI_freelistN(folderlist);
+ if ((index < 0) || (index >= filelist->numfiltered)) {
+ return NULL;
}
-}
-
-ListBase *folderlist_duplicate(ListBase *folderlist)
-{
-
- if (folderlist) {
- ListBase *folderlistn = MEM_callocN(sizeof(ListBase), "copy folderlist");
- FolderList *folder;
-
- BLI_duplicatelist(folderlistn, folderlist);
-
- for (folder = folderlistn->first; folder; folder = folder->next) {
- folder->foldername = MEM_dupallocN(folder->foldername);
+ fidx = filelist->fidx[index];
+ file = &filelist->filelist[fidx];
+ if (file->type & S_IFDIR) {
+ if (FILENAME_IS_PARENT(filelist->filelist[fidx].relname)) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT];
+ }
+ else if (FILENAME_IS_CURRENT(filelist->filelist[fidx].relname)) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_REFRESH];
+ }
+ else {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_FOLDER];
}
- return folderlistn;
}
- return NULL;
-}
+ else {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE];
+ }
+
+ if (file->flags & FILE_TYPE_BLENDER) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_BLENDFILE];
+ }
+ else if ((file->flags & FILE_TYPE_MOVIE) || (file->flags & FILE_TYPE_MOVIE_ICON)) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_MOVIEFILE];
+ }
+ else if (file->flags & FILE_TYPE_SOUND) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_SOUNDFILE];
+ }
+ else if (file->flags & FILE_TYPE_PYSCRIPT) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_PYTHONFILE];
+ }
+ else if (file->flags & FILE_TYPE_FTFONT) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_FONTFILE];
+ }
+ else if (file->flags & FILE_TYPE_TEXT) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_TEXTFILE];
+ }
+ else if (file->flags & FILE_TYPE_IMAGE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_LOADING];
+ }
+ else if (file->flags & FILE_TYPE_BLENDER_BACKUP) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_BACKUP];
+ }
+ return ibuf;
+}
-static void filelist_read_main(struct FileList *filelist);
-static void filelist_read_library(struct FileList *filelist);
-static void filelist_read_dir(struct FileList *filelist);
+/* ********** Main ********** */
-/* ------------------FILELIST------------------------ */
FileList *filelist_new(short type)
{
- FileList *p = MEM_callocN(sizeof(FileList), "filelist");
+ FileList *p = MEM_callocN(sizeof(*p), __func__);
+
switch (type) {
case FILE_MAIN:
p->readf = filelist_read_main;
@@ -553,12 +698,10 @@ FileList *filelist_new(short type)
p->readf = filelist_read_dir;
p->filterf = is_filtered_file;
break;
-
}
return p;
}
-
void filelist_free(struct FileList *filelist)
{
if (!filelist) {
@@ -566,18 +709,16 @@ void filelist_free(struct FileList *filelist)
return;
}
- if (filelist->fidx) {
- MEM_freeN(filelist->fidx);
- filelist->fidx = NULL;
- }
+ MEM_SAFE_FREE(filelist->fidx);
+ filelist->numfiltered = 0;
+ memset(&filelist->filter_data, 0, sizeof(filelist->filter_data));
+
+ filelist->need_sorting = false;
+ filelist->sort = FILE_SORT_NONE;
- BLI_free_filelist(filelist->filelist, filelist->numfiles);
+ BLI_filelist_free(filelist->filelist, filelist->numfiles, NULL);
filelist->numfiles = 0;
filelist->filelist = NULL;
- filelist->filter = 0;
- filelist->filter_glob[0] = '\0';
- filelist->numfiltered = 0;
- filelist->hide_dot = 0;
}
void filelist_freelib(struct FileList *filelist)
@@ -607,89 +748,11 @@ void filelist_setdir(struct FileList *filelist, const char *dir)
BLI_strncpy(filelist->dir, dir, sizeof(filelist->dir));
}
-void filelist_imgsize(struct FileList *filelist, short w, short h)
-{
- filelist->prv_w = w;
- filelist->prv_h = h;
-}
-
short filelist_changed(struct FileList *filelist)
{
return filelist->changed;
}
-ImBuf *filelist_getimage(struct FileList *filelist, int index)
-{
- ImBuf *ibuf = NULL;
- int fidx = 0;
-
- BLI_assert(G.background == false);
-
- if ((index < 0) || (index >= filelist->numfiltered)) {
- return NULL;
- }
- fidx = filelist->fidx[index];
- ibuf = filelist->filelist[fidx].image;
-
- return ibuf;
-}
-
-ImBuf *filelist_geticon(struct FileList *filelist, int index)
-{
- ImBuf *ibuf = NULL;
- struct direntry *file = NULL;
- int fidx = 0;
-
- BLI_assert(G.background == false);
-
- if ((index < 0) || (index >= filelist->numfiltered)) {
- return NULL;
- }
- fidx = filelist->fidx[index];
- file = &filelist->filelist[fidx];
- if (file->type & S_IFDIR) {
- if (strcmp(filelist->filelist[fidx].relname, "..") == 0) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT];
- }
- else if (strcmp(filelist->filelist[fidx].relname, ".") == 0) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_REFRESH];
- }
- else {
- ibuf = gSpecialFileImages[SPECIAL_IMG_FOLDER];
- }
- }
- else {
- ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE];
- }
-
- if (file->flags & BLENDERFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_BLENDFILE];
- }
- else if ((file->flags & MOVIEFILE) || (file->flags & MOVIEFILE_ICON)) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_MOVIEFILE];
- }
- else if (file->flags & SOUNDFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_SOUNDFILE];
- }
- else if (file->flags & PYSCRIPTFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_PYTHONFILE];
- }
- else if (file->flags & FTFONTFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_FONTFILE];
- }
- else if (file->flags & TEXTFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_TEXTFILE];
- }
- else if (file->flags & IMAGEFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_LOADING];
- }
- else if (file->flags & BLENDERFILE_BACKUP) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_BACKUP];
- }
-
- return ibuf;
-}
-
struct direntry *filelist_file(struct FileList *filelist, int index)
{
int fidx = 0;
@@ -704,43 +767,20 @@ struct direntry *filelist_file(struct FileList *filelist, int index)
int filelist_find(struct FileList *filelist, const char *filename)
{
- int index = -1;
- int i;
int fidx = -1;
if (!filelist->fidx)
return fidx;
-
- for (i = 0; i < filelist->numfiles; ++i) {
- if (strcmp(filelist->filelist[i].relname, filename) == 0) { /* not dealing with user input so don't need BLI_path_cmp */
- index = i;
- break;
- }
- }
+ for (fidx = 0; fidx < filelist->numfiltered; fidx++) {
+ int index = filelist->fidx[fidx];
- for (i = 0; i < filelist->numfiltered; ++i) {
- if (filelist->fidx[i] == index) {
- fidx = i;
- break;
+ if (STREQ(filelist->filelist[index].relname, filename)) {
+ return fidx;
}
}
- return fidx;
-}
-
-void filelist_hidedot(struct FileList *filelist, short hide)
-{
- filelist->hide_dot = hide;
-}
-void filelist_setfilter(struct FileList *filelist, unsigned int filter)
-{
- filelist->filter = filter;
-}
-
-void filelist_setfilter_types(struct FileList *filelist, const char *filter_glob)
-{
- BLI_strncpy(filelist->filter_glob, filter_glob, sizeof(filelist->filter_glob));
+ return -1;
}
/* would recognize .blend as well */
@@ -772,47 +812,47 @@ static bool file_is_blend_backup(const char *str)
static int path_extension_type(const char *path)
{
if (BLO_has_bfile_extension(path)) {
- return BLENDERFILE;
+ return FILE_TYPE_BLENDER;
}
else if (file_is_blend_backup(path)) {
- return BLENDERFILE_BACKUP;
+ return FILE_TYPE_BLENDER_BACKUP;
}
else if (BLI_testextensie(path, ".app")) {
- return APPLICATIONBUNDLE;
+ return FILE_TYPE_APPLICATIONBUNDLE;
}
else if (BLI_testextensie(path, ".py")) {
- return PYSCRIPTFILE;
+ return FILE_TYPE_PYSCRIPT;
}
else if (BLI_testextensie_n(path, ".txt", ".glsl", ".osl", ".data", NULL)) {
- return TEXTFILE;
+ return FILE_TYPE_TEXT;
}
else if (BLI_testextensie_n(path, ".ttf", ".ttc", ".pfb", ".otf", ".otc", NULL)) {
- return FTFONTFILE;
+ return FILE_TYPE_FTFONT;
}
else if (BLI_testextensie(path, ".btx")) {
- return BTXFILE;
+ return FILE_TYPE_BTX;
}
else if (BLI_testextensie(path, ".dae")) {
- return COLLADAFILE;
+ return FILE_TYPE_COLLADA;
}
else if (BLI_testextensie_array(path, imb_ext_image) ||
(G.have_quicktime && BLI_testextensie_array(path, imb_ext_image_qt)))
{
- return IMAGEFILE;
+ return FILE_TYPE_IMAGE;
}
else if (BLI_testextensie(path, ".ogg")) {
if (IMB_isanim(path)) {
- return MOVIEFILE;
+ return FILE_TYPE_MOVIE;
}
else {
- return SOUNDFILE;
+ return FILE_TYPE_SOUND;
}
}
else if (BLI_testextensie_array(path, imb_ext_movie)) {
- return MOVIEFILE;
+ return FILE_TYPE_MOVIE;
}
else if (BLI_testextensie_array(path, imb_ext_audio)) {
- return SOUNDFILE;
+ return FILE_TYPE_SOUND;
}
return 0;
}
@@ -828,25 +868,25 @@ int ED_file_extension_icon(const char *path)
{
int type = path_extension_type(path);
- if (type == BLENDERFILE)
+ if (type == FILE_TYPE_BLENDER)
return ICON_FILE_BLEND;
- else if (type == BLENDERFILE_BACKUP)
+ else if (type == FILE_TYPE_BLENDER_BACKUP)
return ICON_FILE_BACKUP;
- else if (type == IMAGEFILE)
+ else if (type == FILE_TYPE_IMAGE)
return ICON_FILE_IMAGE;
- else if (type == MOVIEFILE)
+ else if (type == FILE_TYPE_MOVIE)
return ICON_FILE_MOVIE;
- else if (type == PYSCRIPTFILE)
+ else if (type == FILE_TYPE_PYSCRIPT)
return ICON_FILE_SCRIPT;
- else if (type == SOUNDFILE)
+ else if (type == FILE_TYPE_SOUND)
return ICON_FILE_SOUND;
- else if (type == FTFONTFILE)
+ else if (type == FILE_TYPE_FTFONT)
return ICON_FILE_FONT;
- else if (type == BTXFILE)
+ else if (type == FILE_TYPE_BTX)
return ICON_FILE_BLANK;
- else if (type == COLLADAFILE)
+ else if (type == FILE_TYPE_COLLADA)
return ICON_FILE_BLANK;
- else if (type == TEXTFILE)
+ else if (type == FILE_TYPE_TEXT)
return ICON_FILE_TEXT;
return ICON_FILE_BLANK;
@@ -856,9 +896,9 @@ static void filelist_setfiletypes(struct FileList *filelist)
{
struct direntry *file;
int num;
-
+
file = filelist->filelist;
-
+
for (num = 0; num < filelist->numfiles; num++, file++) {
file->type = file->s.st_mode; /* restore the mess below */
#ifndef __APPLE__
@@ -867,14 +907,14 @@ static void filelist_setfiletypes(struct FileList *filelist)
continue;
}
#endif
- file->flags = file_extension_type(filelist->dir, file->relname);
-
- if (filelist->filter_glob[0] &&
- BLI_testextensie_glob(file->relname, filelist->filter_glob))
+ if (filelist->filter_data.filter_glob[0] &&
+ BLI_testextensie_glob(file->relname, filelist->filter_data.filter_glob))
{
- file->flags = OPERATORFILE;
+ file->flags = FILE_TYPE_OPERATOR;
+ }
+ else {
+ file->flags = file_extension_type(filelist->dir, file->relname);
}
-
}
}
@@ -885,11 +925,15 @@ static void filelist_read_dir(struct FileList *filelist)
filelist->fidx = NULL;
filelist->filelist = NULL;
+ BLI_make_exist(filelist->dir);
BLI_cleanup_dir(G.main->name, filelist->dir);
- filelist->numfiles = BLI_dir_contents(filelist->dir, &(filelist->filelist));
+ filelist->numfiles = BLI_filelist_dir_contents(filelist->dir, &(filelist->filelist));
+
+ /* We shall *never* get an empty list here, since we now the dir exists and is readable
+ * (ensured by BLI_make_exist()). So we expect at the very least the parent '..' entry. */
+ BLI_assert(filelist->numfiles != 0);
filelist_setfiletypes(filelist);
- filelist_filter(filelist);
}
static void filelist_read_main(struct FileList *filelist)
@@ -907,7 +951,6 @@ static void filelist_read_library(struct FileList *filelist)
int num;
struct direntry *file;
- BLI_make_exist(filelist->dir);
filelist_read_dir(filelist);
file = filelist->filelist;
for (num = 0; num < filelist->numfiles; num++, file++) {
@@ -929,18 +972,15 @@ static void filelist_read_library(struct FileList *filelist)
void filelist_readdir(struct FileList *filelist)
{
filelist->readf(filelist);
-}
-int filelist_empty(struct FileList *filelist)
-{
- return filelist->filelist == NULL;
+ filelist->need_sorting = true;
+ filelist->need_thumbnails = true;
+ filelist_filter_clear(filelist);
}
-void filelist_parent(struct FileList *filelist)
+int filelist_empty(struct FileList *filelist)
{
- BLI_parent_dir(filelist->dir);
- BLI_make_exist(filelist->dir);
- filelist_readdir(filelist);
+ return filelist->filelist == NULL;
}
void filelist_select_file(struct FileList *filelist, int index, FileSelType select, unsigned int flag, FileCheckType check)
@@ -995,33 +1035,13 @@ bool filelist_is_selected(struct FileList *filelist, int index, FileCheckType ch
}
switch (check) {
case CHECK_DIRS:
- return S_ISDIR(file->type) && (file->selflag & SELECTED_FILE);
+ return S_ISDIR(file->type) && (file->selflag & FILE_SEL_SELECTED);
case CHECK_FILES:
- return S_ISREG(file->type) && (file->selflag & SELECTED_FILE);
+ return S_ISREG(file->type) && (file->selflag & FILE_SEL_SELECTED);
case CHECK_ALL:
default:
- return (file->selflag & SELECTED_FILE) != 0;
- }
-}
-
-void filelist_sort(struct FileList *filelist, short sort)
-{
- switch (sort) {
- case FILE_SORT_ALPHA:
- qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_name);
- break;
- case FILE_SORT_TIME:
- qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_date);
- break;
- case FILE_SORT_SIZE:
- qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_size);
- break;
- case FILE_SORT_EXTENSION:
- qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension);
- break;
+ return (file->selflag & FILE_SEL_SELECTED) != 0;
}
-
- filelist_filter(filelist);
}
@@ -1034,7 +1054,7 @@ static int groupname_to_code(const char *group)
{
char buf[BLO_GROUP_MAX];
char *lslash;
-
+
BLI_strncpy(buf, group, sizeof(buf));
lslash = (char *)BLI_last_slash(buf);
if (lslash)
@@ -1042,15 +1062,15 @@ static int groupname_to_code(const char *group)
return buf[0] ? BKE_idcode_from_name(buf) : 0;
}
-
-void filelist_from_library(struct FileList *filelist)
+
+static void filelist_from_library(struct FileList *filelist)
{
LinkNode *l, *names, *previews;
struct ImBuf *ima;
int ok, i, nprevs, nnames, idcode;
char filename[FILE_MAX];
char dir[FILE_MAX], group[BLO_GROUP_MAX];
-
+
/* name test */
ok = filelist_islibrary(filelist, dir, group);
if (!ok) {
@@ -1089,10 +1109,10 @@ void filelist_from_library(struct FileList *filelist)
}
filelist->numfiles = nnames + 1;
- filelist->filelist = malloc(filelist->numfiles * sizeof(*filelist->filelist));
+ filelist->filelist = MEM_mallocN(filelist->numfiles * sizeof(*filelist->filelist), __func__);
memset(filelist->filelist, 0, filelist->numfiles * sizeof(*filelist->filelist));
- filelist->filelist[0].relname = BLI_strdup("..");
+ filelist->filelist[0].relname = BLI_strdup(FILENAME_PARENT);
filelist->filelist[0].type |= S_IFDIR;
for (i = 0, l = names; i < nnames; i++, l = l->next) {
@@ -1106,14 +1126,14 @@ void filelist_from_library(struct FileList *filelist)
filelist->filelist[i + 1].type |= S_IFDIR;
}
}
-
+
if (previews && (nnames != nprevs)) {
printf("filelist_from_library: error, found %d items, %d previews\n", nnames, nprevs);
}
else if (previews) {
for (i = 0, l = previews; i < nnames; i++, l = l->next) {
PreviewImage *img = l->link;
-
+
if (img) {
unsigned int w = img->w[ICON_SIZE_PREVIEW];
unsigned int h = img->h[ICON_SIZE_PREVIEW];
@@ -1124,142 +1144,126 @@ void filelist_from_library(struct FileList *filelist)
ima = IMB_allocImBuf(w, h, 32, IB_rect);
memcpy(ima->rect, rect, w * h * sizeof(unsigned int));
filelist->filelist[i + 1].image = ima;
- filelist->filelist[i + 1].flags = IMAGEFILE;
+ filelist->filelist[i + 1].flags = FILE_TYPE_IMAGE;
}
}
}
}
BLI_linklist_free(names, free);
- if (previews) BLI_linklist_free(previews, BKE_previewimg_freefunc);
-
- filelist_sort(filelist, FILE_SORT_ALPHA);
+ if (previews) {
+ BLI_linklist_free(previews, BKE_previewimg_freefunc);
+ }
BLI_strncpy(G.main->name, filename, sizeof(filename)); /* prevent G.main->name to change */
-
- filelist->filter = 0;
- filelist_filter(filelist);
-}
-
-void filelist_hideparent(struct FileList *filelist, short hide)
-{
- filelist->hide_parent = hide;
}
-void filelist_from_main(struct FileList *filelist)
+static void filelist_from_main(struct FileList *filelist)
{
ID *id;
struct direntry *files, *firstlib = NULL;
ListBase *lb;
int a, fake, idcode, ok, totlib, totbl;
-
+
// filelist->type = FILE_MAIN; // XXXXX TODO: add modes to filebrowser
if (filelist->dir[0] == '/') filelist->dir[0] = 0;
-
+
if (filelist->dir[0]) {
idcode = groupname_to_code(filelist->dir);
if (idcode == 0) filelist->dir[0] = 0;
}
-
+
if (filelist->dir[0] == 0) {
-
/* make directories */
#ifdef WITH_FREESTYLE
- filelist->numfiles = 25;
-#else
filelist->numfiles = 24;
+#else
+ filelist->numfiles = 23;
#endif
- filelist->filelist = (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
-
+ filelist->filelist = MEM_mallocN(sizeof(*filelist->filelist) * filelist->numfiles, __func__);
+
for (a = 0; a < filelist->numfiles; a++) {
memset(&(filelist->filelist[a]), 0, sizeof(struct direntry));
filelist->filelist[a].type |= S_IFDIR;
}
-
- filelist->filelist[0].relname = BLI_strdup("..");
- filelist->filelist[2].relname = BLI_strdup("Scene");
- filelist->filelist[3].relname = BLI_strdup("Object");
- filelist->filelist[4].relname = BLI_strdup("Mesh");
- filelist->filelist[5].relname = BLI_strdup("Curve");
- filelist->filelist[6].relname = BLI_strdup("Metaball");
- filelist->filelist[7].relname = BLI_strdup("Material");
- filelist->filelist[8].relname = BLI_strdup("Texture");
- filelist->filelist[9].relname = BLI_strdup("Image");
- filelist->filelist[10].relname = BLI_strdup("Ika");
- filelist->filelist[11].relname = BLI_strdup("Wave");
- filelist->filelist[12].relname = BLI_strdup("Lattice");
- filelist->filelist[13].relname = BLI_strdup("Lamp");
- filelist->filelist[14].relname = BLI_strdup("Camera");
- filelist->filelist[15].relname = BLI_strdup("Ipo");
- filelist->filelist[16].relname = BLI_strdup("World");
- filelist->filelist[17].relname = BLI_strdup("Screen");
- filelist->filelist[18].relname = BLI_strdup("VFont");
- filelist->filelist[19].relname = BLI_strdup("Text");
- filelist->filelist[20].relname = BLI_strdup("Armature");
- filelist->filelist[21].relname = BLI_strdup("Action");
- filelist->filelist[22].relname = BLI_strdup("NodeTree");
- filelist->filelist[23].relname = BLI_strdup("Speaker");
+
+ filelist->filelist[0].relname = BLI_strdup(FILENAME_PARENT);
+ filelist->filelist[1].relname = BLI_strdup("Scene");
+ filelist->filelist[2].relname = BLI_strdup("Object");
+ filelist->filelist[3].relname = BLI_strdup("Mesh");
+ filelist->filelist[4].relname = BLI_strdup("Curve");
+ filelist->filelist[5].relname = BLI_strdup("Metaball");
+ filelist->filelist[6].relname = BLI_strdup("Material");
+ filelist->filelist[7].relname = BLI_strdup("Texture");
+ filelist->filelist[8].relname = BLI_strdup("Image");
+ filelist->filelist[9].relname = BLI_strdup("Ika");
+ filelist->filelist[10].relname = BLI_strdup("Wave");
+ filelist->filelist[11].relname = BLI_strdup("Lattice");
+ filelist->filelist[12].relname = BLI_strdup("Lamp");
+ filelist->filelist[13].relname = BLI_strdup("Camera");
+ filelist->filelist[14].relname = BLI_strdup("Ipo");
+ filelist->filelist[15].relname = BLI_strdup("World");
+ filelist->filelist[16].relname = BLI_strdup("Screen");
+ filelist->filelist[17].relname = BLI_strdup("VFont");
+ filelist->filelist[18].relname = BLI_strdup("Text");
+ filelist->filelist[19].relname = BLI_strdup("Armature");
+ filelist->filelist[20].relname = BLI_strdup("Action");
+ filelist->filelist[21].relname = BLI_strdup("NodeTree");
+ filelist->filelist[22].relname = BLI_strdup("Speaker");
#ifdef WITH_FREESTYLE
- filelist->filelist[24].relname = BLI_strdup("FreestyleLineStyle");
+ filelist->filelist[23].relname = BLI_strdup("FreestyleLineStyle");
#endif
- filelist_sort(filelist, FILE_SORT_ALPHA);
}
else {
-
/* make files */
idcode = groupname_to_code(filelist->dir);
-
+
lb = which_libbase(G.main, idcode);
if (lb == NULL) return;
-
- id = lb->first;
+
filelist->numfiles = 0;
- while (id) {
- if (!filelist->hide_dot || id->name[2] != '.') {
+ for (id = lb->first; id; id = id->next) {
+ if (!filelist->filter_data.hide_dot || id->name[2] != '.') {
filelist->numfiles++;
}
-
- id = id->next;
}
-
+
/* XXXXX TODO: if databrowse F4 or append/link filelist->hide_parent has to be set */
- if (!filelist->hide_parent) filelist->numfiles += 1;
- filelist->filelist = filelist->numfiles > 0 ? (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry)) : NULL;
+ if (!filelist->filter_data.hide_parent) filelist->numfiles += 1;
+ filelist->filelist = filelist->numfiles > 0 ? MEM_mallocN(sizeof(*filelist->filelist) * filelist->numfiles, __func__) : NULL;
files = filelist->filelist;
-
- if (!filelist->hide_parent) {
+
+ if (!filelist->filter_data.hide_parent) {
memset(&(filelist->filelist[0]), 0, sizeof(struct direntry));
- filelist->filelist[0].relname = BLI_strdup("..");
+ filelist->filelist[0].relname = BLI_strdup(FILENAME_PARENT);
filelist->filelist[0].type |= S_IFDIR;
-
+
files++;
}
-
- id = lb->first;
+
totlib = totbl = 0;
-
- while (id) {
+ for (id = lb->first; id; id = id->next) {
ok = 1;
if (ok) {
- if (!filelist->hide_dot || id->name[2] != '.') {
+ if (!filelist->filter_data.hide_dot || id->name[2] != '.') {
memset(files, 0, sizeof(struct direntry));
if (id->lib == NULL) {
files->relname = BLI_strdup(id->name + 2);
}
else {
- files->relname = MEM_mallocN(FILE_MAX + (MAX_ID_NAME - 2), "filename for lib");
+ files->relname = MEM_mallocN(sizeof(*files->relname) * (FILE_MAX + (MAX_ID_NAME - 2)), __func__);
BLI_snprintf(files->relname, FILE_MAX + (MAX_ID_NAME - 2) + 3, "%s | %s", id->lib->name, id->name + 2);
}
files->type |= S_IFREG;
#if 0 /* XXXXX TODO show the selection status of the objects */
if (!filelist->has_func) { /* F4 DATA BROWSE */
if (idcode == ID_OB) {
- if ( ((Object *)id)->flag & SELECT) files->selflag |= SELECTED_FILE;
+ if ( ((Object *)id)->flag & SELECT) files->selflag |= FILE_SEL_SELECTED;
}
else if (idcode == ID_SCE) {
- if ( ((Scene *)id)->r.scemode & R_BG_RENDER) files->selflag |= SELECTED_FILE;
+ if ( ((Scene *)id)->r.scemode & R_BG_RENDER) files->selflag |= FILE_SEL_SELECTED;
}
}
#endif
@@ -1267,33 +1271,45 @@ void filelist_from_main(struct FileList *filelist)
files->poin = id;
fake = id->flag & LIB_FAKEUSER;
if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
- files->flags |= IMAGEFILE;
+ files->flags |= FILE_TYPE_IMAGE;
}
if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us);
else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us);
else if (fake) BLI_snprintf(files->extra, sizeof(files->extra), "F %d", id->us);
else BLI_snprintf(files->extra, sizeof(files->extra), " %d", id->us);
-
+
if (id->lib) {
if (totlib == 0) firstlib = files;
totlib++;
}
-
+
files++;
}
totbl++;
}
-
- id = id->next;
}
-
+
/* only qsort of library blocks */
if (totlib > 1) {
qsort(firstlib, totlib, sizeof(struct direntry), compare_name);
}
}
- filelist->filter = 0;
- filelist_filter(filelist);
+}
+
+/* ********** Thumbnails job ********** */
+
+typedef struct ThumbnailJob {
+ ListBase loadimages;
+ ImBuf *static_icons_buffers[BIFICONID_LAST];
+ const short *stop;
+ const short *do_update;
+ struct FileList *filelist;
+ ReportList reports;
+} ThumbnailJob;
+
+bool filelist_need_thumbnails(FileList *filelist)
+{
+ return filelist->need_thumbnails;
}
static void thumbnail_joblist_free(ThumbnailJob *tj)
@@ -1318,18 +1334,18 @@ static void thumbnails_startjob(void *tjv, short *stop, short *do_update, float
tj->do_update = do_update;
while ((*stop == 0) && (limg)) {
- if (limg->flags & IMAGEFILE) {
+ if (limg->flags & FILE_TYPE_IMAGE) {
limg->img = IMB_thumb_manage(limg->path, THB_NORMAL, THB_SOURCE_IMAGE);
}
- else if (limg->flags & (BLENDERFILE | BLENDERFILE_BACKUP)) {
+ else if (limg->flags & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
limg->img = IMB_thumb_manage(limg->path, THB_NORMAL, THB_SOURCE_BLEND);
}
- else if (limg->flags & MOVIEFILE) {
+ else if (limg->flags & FILE_TYPE_MOVIE) {
limg->img = IMB_thumb_manage(limg->path, THB_NORMAL, THB_SOURCE_MOVIE);
if (!limg->img) {
/* remember that file can't be loaded via IMB_open_anim */
- limg->flags &= ~MOVIEFILE;
- limg->flags |= MOVIEFILE_ICON;
+ limg->flags &= ~FILE_TYPE_MOVIE;
+ limg->flags |= FILE_TYPE_MOVIE_ICON;
}
}
*do_update = true;
@@ -1346,19 +1362,30 @@ static void thumbnails_update(void *tjv)
FileImage *limg = tj->loadimages.first;
while (limg) {
if (!limg->done && limg->img) {
- tj->filelist->filelist[limg->index].image = limg->img;
+ tj->filelist->filelist[limg->index].image = IMB_dupImBuf(limg->img);
/* update flag for movie files where thumbnail can't be created */
- if (limg->flags & MOVIEFILE_ICON) {
- tj->filelist->filelist[limg->index].flags &= ~MOVIEFILE;
- tj->filelist->filelist[limg->index].flags |= MOVIEFILE_ICON;
+ if (limg->flags & FILE_TYPE_MOVIE_ICON) {
+ tj->filelist->filelist[limg->index].flags &= ~FILE_TYPE_MOVIE;
+ tj->filelist->filelist[limg->index].flags |= FILE_TYPE_MOVIE_ICON;
}
limg->done = true;
+ IMB_freeImBuf(limg->img);
+ limg->img = NULL;
}
limg = limg->next;
}
}
}
+static void thumbnails_endjob(void *tjv)
+{
+ ThumbnailJob *tj = tjv;
+
+ if (!*tj->stop) {
+ tj->filelist->need_thumbnails = false;
+ }
+}
+
static void thumbnails_free(void *tjv)
{
ThumbnailJob *tj = tjv;
@@ -1372,15 +1399,20 @@ void thumbnails_start(FileList *filelist, const bContext *C)
wmJob *wm_job;
ThumbnailJob *tj;
int idx;
-
+
/* prepare job data */
- tj = MEM_callocN(sizeof(ThumbnailJob), "thumbnails\n");
+ tj = MEM_callocN(sizeof(*tj), __func__);
tj->filelist = filelist;
for (idx = 0; idx < filelist->numfiles; idx++) {
+ if (!filelist->filelist[idx].path) {
+ continue;
+ }
if (!filelist->filelist[idx].image) {
- if ((filelist->filelist[idx].flags & (IMAGEFILE | MOVIEFILE | BLENDERFILE | BLENDERFILE_BACKUP))) {
- FileImage *limg = MEM_callocN(sizeof(FileImage), "loadimage");
- BLI_strncpy(limg->path, filelist->filelist[idx].path, FILE_MAX);
+ if (filelist->filelist[idx].flags & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE |
+ FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))
+ {
+ FileImage *limg = MEM_callocN(sizeof(*limg), __func__);
+ BLI_strncpy(limg->path, filelist->filelist[idx].path, sizeof(limg->path));
limg->index = idx;
limg->flags = filelist->filelist[idx].flags;
BLI_addtail(&tj->loadimages, limg);
@@ -1395,7 +1427,7 @@ void thumbnails_start(FileList *filelist, const bContext *C)
0, WM_JOB_TYPE_FILESEL_THUMBNAIL);
WM_jobs_customdata_set(wm_job, tj, thumbnails_free);
WM_jobs_timer(wm_job, 0.5, NC_WINDOW, NC_WINDOW);
- WM_jobs_callbacks(wm_job, thumbnails_startjob, NULL, thumbnails_update, NULL);
+ WM_jobs_callbacks(wm_job, thumbnails_startjob, NULL, thumbnails_update, thumbnails_endjob);
/* start the job */
WM_jobs_start(CTX_wm_manager(C), wm_job);
@@ -1403,7 +1435,7 @@ void thumbnails_start(FileList *filelist, const bContext *C)
void thumbnails_stop(wmWindowManager *wm, FileList *filelist)
{
- WM_jobs_kill(wm, filelist, NULL);
+ WM_jobs_kill_type(wm, filelist, WM_JOB_TYPE_FILESEL_THUMBNAIL);
}
int thumbnails_running(wmWindowManager *wm, FileList *filelist)
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index c37bb882168..797d54a89b1 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -60,47 +60,53 @@ typedef enum FileCheckType {
CHECK_ALL = 3
} FileCheckType;
-struct FileList * filelist_new(short type);
+struct ListBase * folderlist_new(void);
+void folderlist_free(struct ListBase *folderlist);
+struct ListBase * folderlist_duplicate(ListBase *folderlist);
+void folderlist_popdir(struct ListBase *folderlist, char *dir);
+void folderlist_pushdir(struct ListBase *folderlist, const char *dir);
+const char * folderlist_peeklastdir(struct ListBase *folderdist);
+int folderlist_clear_next(struct SpaceFile *sfile);
+
+
+void filelist_setsorting(struct FileList *filelist, const short sort);
+bool filelist_need_sorting(struct FileList *filelist);
+void filelist_sort(struct FileList *filelist);
+
+void filelist_setfilter_options(struct FileList *filelist, const bool hide_dot, const bool hide_parent,
+ const unsigned int filter,
+ const char *filter_glob, const char *filter_search);
+void filelist_filter(struct FileList *filelist);
+
void filelist_init_icons(void);
void filelist_free_icons(void);
-int filelist_find(struct FileList *filelist, const char *file);
+void filelist_imgsize(struct FileList *filelist, short w, short h);
+struct ImBuf * filelist_getimage(struct FileList *filelist, const int index);
+struct ImBuf * filelist_geticon(struct FileList *filelist, const int index);
+
+struct FileList * filelist_new(short type);
void filelist_free(struct FileList *filelist);
-void filelist_sort(struct FileList *filelist, short sort);
-int filelist_numfiles(struct FileList *filelist);
+
const char * filelist_dir(struct FileList *filelist);
+void filelist_readdir(struct FileList *filelist);
void filelist_setdir(struct FileList *filelist, const char *dir);
+
+int filelist_empty(struct FileList *filelist);
+int filelist_numfiles(struct FileList *filelist);
struct direntry * filelist_file(struct FileList *filelist, int index);
+int filelist_find(struct FileList *filelist, const char *file);
+
+short filelist_changed(struct FileList *filelist);
+
void filelist_select(struct FileList *filelist, FileSelection *sel, FileSelType select, unsigned int flag, FileCheckType check);
void filelist_select_file(struct FileList *filelist, int index, FileSelType select, unsigned int flag, FileCheckType check);
bool filelist_is_selected(struct FileList *filelist, int index, FileCheckType check);
-void filelist_hidedot(struct FileList *filelist, short hide);
-void filelist_setfilter(struct FileList *filelist, unsigned int filter);
-void filelist_setfilter_types(struct FileList *filelist, const char *filter_glob);
-void filelist_filter(struct FileList *filelist);
-void filelist_imgsize(struct FileList *filelist, short w, short h);
-struct ImBuf * filelist_getimage(struct FileList *filelist, int index);
-struct ImBuf * filelist_geticon(struct FileList *filelist, int index);
-short filelist_changed(struct FileList *filelist);
-void filelist_readdir(struct FileList *filelist);
-
-int filelist_empty(struct FileList *filelist);
-void filelist_parent(struct FileList *filelist);
struct BlendHandle *filelist_lib(struct FileList *filelist);
bool filelist_islibrary(struct FileList *filelist, char *dir, char *group);
-void filelist_from_main(struct FileList *filelist);
-void filelist_from_library(struct FileList *filelist);
void filelist_freelib(struct FileList *filelist);
-void filelist_hideparent(struct FileList *filelist, short hide);
-
-struct ListBase * folderlist_new(void);
-void folderlist_free(struct ListBase *folderlist);
-struct ListBase * folderlist_duplicate(ListBase *folderlist);
-void folderlist_popdir(struct ListBase *folderlist, char *dir);
-void folderlist_pushdir(struct ListBase *folderlist, const char *dir);
-const char * folderlist_peeklastdir(struct ListBase *folderdist);
-int folderlist_clear_next(struct SpaceFile *sfile);
+bool filelist_need_thumbnails(struct FileList *filelist);
void thumbnails_start(struct FileList *filelist, const struct bContext *C);
void thumbnails_stop(struct wmWindowManager *wm, struct FileList *filelist);
int thumbnails_running(struct wmWindowManager *wm, struct FileList *filelist);
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index afe3f29e9bc..14b72eb8f6d 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -58,6 +58,7 @@
#include "BLI_fileops_types.h"
#include "BLI_fnmatch.h"
+#include "BKE_appdir.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
@@ -116,10 +117,12 @@ short ED_fileselect_set_params(SpaceFile *sfile)
BLI_strncpy_utf8(params->title, RNA_struct_ui_name(op->type->srna), sizeof(params->title));
- if (RNA_struct_find_property(op->ptr, "filemode"))
- params->type = RNA_int_get(op->ptr, "filemode");
- else
+ if ((prop = RNA_struct_find_property(op->ptr, "filemode"))) {
+ params->type = RNA_property_int_get(op->ptr, prop);
+ }
+ else {
params->type = FILE_SPECIAL;
+ }
if (is_filepath && RNA_struct_property_is_set_ex(op->ptr, "filepath", false)) {
char name[FILE_MAX];
@@ -157,30 +160,30 @@ short ED_fileselect_set_params(SpaceFile *sfile)
params->filter = 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_blender")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? BLENDERFILE : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_backup")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? BLENDERFILE_BACKUP : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER_BACKUP : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_image")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? IMAGEFILE : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_IMAGE : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_movie")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? MOVIEFILE : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_MOVIE : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_python")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? PYSCRIPTFILE : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_PYSCRIPT : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_font")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FTFONTFILE : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_FTFONT : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_sound")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? SOUNDFILE : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_SOUND : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_text")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? TEXTFILE : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_TEXT : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_folder")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FOLDERFILE : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_FOLDER : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_btx")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? BTXFILE : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BTX : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_collada")))
- params->filter |= RNA_property_boolean_get(op->ptr, prop) ? COLLADAFILE : 0;
+ params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_COLLADA : 0;
if ((prop = RNA_struct_find_property(op->ptr, "filter_glob"))) {
RNA_property_string_get(op->ptr, prop, params->filter_glob);
- params->filter |= (OPERATORFILE | FOLDERFILE);
+ params->filter |= (FILE_TYPE_OPERATOR | FILE_TYPE_FOLDER);
}
else {
params->filter_glob[0] = '\0';
@@ -209,12 +212,13 @@ short ED_fileselect_set_params(SpaceFile *sfile)
params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0;
}
- if (RNA_struct_find_property(op->ptr, "display_type"))
- params->display = RNA_enum_get(op->ptr, "display_type");
+ if ((prop = RNA_struct_find_property(op->ptr, "display_type"))) {
+ params->display = RNA_property_enum_get(op->ptr, prop);
+ }
if (params->display == FILE_DEFAULTDISPLAY) {
if (U.uiflag & USER_SHOW_THUMBNAILS) {
- if (params->filter & (IMAGEFILE | MOVIEFILE))
+ if (params->filter & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE))
params->display = FILE_IMGDISPLAY;
else
params->display = FILE_SHORTDISPLAY;
@@ -225,8 +229,10 @@ short ED_fileselect_set_params(SpaceFile *sfile)
}
if (is_relative_path) {
- if (!RNA_struct_property_is_set_ex(op->ptr, "relative_path", false)) {
- RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS);
+ if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) {
+ if (!RNA_property_is_set_ex(op->ptr, prop, false)) {
+ RNA_property_boolean_set(op->ptr, prop, (U.flag & USER_RELPATHS) != 0);
+ }
}
}
}
@@ -253,7 +259,7 @@ short ED_fileselect_set_params(SpaceFile *sfile)
BLI_split_dir_part(G.main->name, sfile->params->dir, sizeof(sfile->params->dir));
}
else {
- const char *doc_path = BLI_getDefaultDocumentFolder();
+ const char *doc_path = BKE_appdir_folder_default();
if (doc_path) {
BLI_strncpy(sfile->params->dir, doc_path, sizeof(sfile->params->dir));
}
@@ -444,8 +450,8 @@ float file_shorten_string(char *string, float w, int front)
float file_string_width(const char *str)
{
- uiStyle *style = UI_GetStyle();
- uiStyleFontSet(&style->widget);
+ uiStyle *style = UI_style_get();
+ UI_fontstyle_set(&style->widget);
return BLF_width(style->widget.uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
}
@@ -454,13 +460,13 @@ float file_font_pointsize(void)
#if 0
float s;
char tmp[2] = "X";
- uiStyle *style = UI_GetStyle();
- uiStyleFontSet(&style->widget);
+ uiStyle *style = UI_style_get();
+ UI_fontstyle_set(&style->widget);
s = BLF_height(style->widget.uifont_id, tmp);
return style->widget.points;
#else
- uiStyle *style = UI_GetStyle();
- uiStyleFontSet(&style->widget);
+ uiStyle *style = UI_style_get();
+ UI_fontstyle_set(&style->widget);
return style->widget.points * UI_DPI_FAC;
#endif
}
@@ -596,15 +602,18 @@ FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *ar)
return sfile->layout;
}
-void file_change_dir(bContext *C, int checkdir)
+void ED_file_change_dir(bContext *C, const bool checkdir)
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
if (sfile->params) {
-
ED_fileselect_clear(wm, sfile);
+ /* Clear search string, it is very rare to want to keep that filter while changing dir,
+ * and usually very annoying to keep it actually! */
+ sfile->params->filter_search[0] = '\0';
+
if (checkdir && !BLI_is_dir(sfile->params->dir)) {
BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir));
/* could return but just refresh the current dir */
@@ -616,7 +625,7 @@ void file_change_dir(bContext *C, int checkdir)
folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
- file_draw_check_cb(C, NULL, NULL);
+ file_draw_check(C);
}
}
@@ -633,8 +642,9 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche
*/
for (i = 0; i < n; i++) {
file = filelist_file(sfile->files, i);
- if (fnmatch(pattern, file->relname, 0) == 0) {
- file->selflag |= SELECTED_FILE;
+ /* use same rule as 'FileCheckType.CHECK_FILES' */
+ if (S_ISREG(file->type) && (fnmatch(pattern, file->relname, 0) == 0)) {
+ file->selflag |= FILE_SEL_SELECTED;
if (!match) {
BLI_strncpy(matched_file, file->relname, FILE_MAX);
}
@@ -662,10 +672,10 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
dir = opendir(dirname);
if (dir) {
- AutoComplete *autocpl = autocomplete_begin(str, FILE_MAX);
+ AutoComplete *autocpl = UI_autocomplete_begin(str, FILE_MAX);
while ((de = readdir(dir)) != NULL) {
- if (strcmp(".", de->d_name) == 0 || strcmp("..", de->d_name) == 0) {
+ if (FILENAME_IS_CURRPAR(de->d_name)) {
/* pass */
}
else {
@@ -676,14 +686,14 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v))
if (BLI_stat(path, &status) == 0) {
if (S_ISDIR(status.st_mode)) { /* is subdir */
- autocomplete_do_name(autocpl, path);
+ UI_autocomplete_update_name(autocpl, path);
}
}
}
}
closedir(dir);
- match = autocomplete_end(autocpl, str);
+ match = UI_autocomplete_end(autocpl, str);
if (match) {
if (match == AUTOCOMPLETE_FULL_MATCH) {
BLI_add_slash(str);
@@ -705,17 +715,17 @@ int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
/* search if str matches the beginning of name */
if (str[0] && sfile->files) {
- AutoComplete *autocpl = autocomplete_begin(str, FILE_MAX);
+ AutoComplete *autocpl = UI_autocomplete_begin(str, FILE_MAX);
int nentries = filelist_numfiles(sfile->files);
int i;
for (i = 0; i < nentries; ++i) {
struct direntry *file = filelist_file(sfile->files, i);
if (file && (S_ISREG(file->type) || S_ISDIR(file->type))) {
- autocomplete_do_name(autocpl, file->relname);
+ UI_autocomplete_update_name(autocpl, file->relname);
}
}
- match = autocomplete_end(autocpl, str);
+ match = UI_autocomplete_end(autocpl, str);
}
return match;
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 09cbd0a317b..c6ee6875403 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -40,6 +40,12 @@
#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
+#include "BKE_appdir.h"
+
+#include "DNA_space_types.h"
+
+#include "ED_fileselect.h"
+
#ifdef WIN32
# include <windows.h> /* need to include windows.h so _WIN32_IE is defined */
# ifndef _WIN32_IE
@@ -63,15 +69,6 @@
/* FSMENU HANDLING */
-/* FSMenuEntry's without paths indicate seperators */
-typedef struct _FSMenuEntry FSMenuEntry;
-struct _FSMenuEntry {
- FSMenuEntry *next;
-
- char *path;
- short save;
-};
-
typedef struct FSMenu {
FSMenuEntry *fsmenu_system;
FSMenuEntry *fsmenu_system_bookmarks;
@@ -81,7 +78,7 @@ typedef struct FSMenu {
static FSMenu *g_fsmenu = NULL;
-FSMenu *fsmenu_get(void)
+FSMenu *ED_fsmenu_get(void)
{
if (!g_fsmenu) {
g_fsmenu = MEM_callocN(sizeof(struct FSMenu), "fsmenu");
@@ -89,7 +86,7 @@ FSMenu *fsmenu_get(void)
return g_fsmenu;
}
-static FSMenuEntry *fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category)
+struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category)
{
FSMenuEntry *fsm_head = NULL;
@@ -110,7 +107,7 @@ static FSMenuEntry *fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory ca
return fsm_head;
}
-static void fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head)
+void ED_fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head)
{
switch (category) {
case FS_CATEGORY_SYSTEM:
@@ -128,47 +125,141 @@ static void fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category,
}
}
-int fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category)
+int ED_fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category)
{
FSMenuEntry *fsm_iter;
int count = 0;
- for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter; fsm_iter = fsm_iter->next) {
+ for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter; fsm_iter = fsm_iter->next) {
count++;
}
return count;
}
-char *fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx)
+FSMenuEntry *ED_fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index)
{
FSMenuEntry *fsm_iter;
- for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) {
- idx--;
+ for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter && index; fsm_iter = fsm_iter->next) {
+ index--;
}
- return fsm_iter ? fsm_iter->path : NULL;
+ return fsm_iter;
+}
+
+char *ED_fsmenu_entry_get_path(struct FSMenuEntry *fsentry)
+{
+ return fsentry->path;
+}
+
+void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *path)
+{
+ if ((!fsentry->path || !path || !STREQ(path, fsentry->path)) && (fsentry->path != path)) {
+ char tmp_name[FILE_MAXFILE];
+
+ MEM_SAFE_FREE(fsentry->path);
+
+ fsentry->path = (path && path[0]) ? BLI_strdup(path) : NULL;
+
+ BLI_make_file_string("/", tmp_name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
+ fsmenu_write_file(ED_fsmenu_get(), tmp_name);
+ }
+}
+
+static void fsmenu_entry_generate_name(struct FSMenuEntry *fsentry, char *name, size_t name_size)
+{
+ char temp[FILE_MAX];
+
+ BLI_strncpy(temp, fsentry->path, FILE_MAX);
+ BLI_add_slash(temp);
+ BLI_getlastdir(temp, name, name_size);
+ BLI_del_slash(name);
+ if (!name[0]) {
+ name[0] = '/';
+ name[1] = '\0';
+ }
+}
+
+char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry)
+{
+ if (fsentry->name[0]) {
+ return fsentry->name;
+ }
+ else {
+ /* Here we abuse fsm_iter->name, keeping first char NULL. */
+ char *name = fsentry->name + 1;
+ size_t name_size = sizeof(fsentry->name) - 1;
+
+ fsmenu_entry_generate_name(fsentry, name, name_size);
+ return name;
+ }
+}
+
+void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name)
+{
+ if (!STREQ(name, fsentry->name)) {
+ char tmp_name[FILE_MAXFILE];
+ size_t tmp_name_size = sizeof(tmp_name);
+
+ fsmenu_entry_generate_name(fsentry, tmp_name, tmp_name_size);
+ if (!name[0] || STREQ(tmp_name, name)) {
+ /* reset name to default behavior. */
+ fsentry->name[0] = '\0';
+ }
+ else {
+ BLI_strncpy(fsentry->name, name, sizeof(fsentry->name));
+ }
+
+ BLI_make_file_string("/", tmp_name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
+ fsmenu_write_file(ED_fsmenu_get(), tmp_name);
+ }
+}
+
+void fsmenu_entry_refresh_valid(struct FSMenuEntry *fsentry)
+{
+ if (fsentry->path && fsentry->path[0]) {
+#ifdef WIN32
+ /* XXX Special case, always consider those as valid.
+ * Thanks to Windows, which can spend five seconds to perform a mere stat() call on those paths...
+ * See T43684.
+ */
+ const char *exceptions[] = {"A:\\", "B:\\", NULL};
+ const size_t exceptions_len[] = {strlen(exceptions[0]), strlen(exceptions[1]), 0};
+ int i;
+
+ for (i = 0; exceptions[i]; i++) {
+ if (STRCASEEQLEN(fsentry->path, exceptions[i], exceptions_len[i])) {
+ fsentry->valid = true;
+ return;
+ }
+ }
+#endif
+ fsentry->valid = BLI_is_dir(fsentry->path);
+ }
+ else {
+ fsentry->valid = false;
+ }
}
short fsmenu_can_save(struct FSMenu *fsmenu, FSMenuCategory category, int idx)
{
FSMenuEntry *fsm_iter;
- for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) {
+ for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) {
idx--;
}
return fsm_iter ? fsm_iter->save : 0;
}
-void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, FSMenuInsert flag)
+void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, const char *name, FSMenuInsert flag)
{
FSMenuEntry *fsm_prev;
FSMenuEntry *fsm_iter;
FSMenuEntry *fsm_head;
- fsm_head = fsmenu_get_category(fsmenu, category);
+ fsm_head = ED_fsmenu_get_category(fsmenu, category);
fsm_prev = fsm_head; /* this is odd and not really correct? */
for (fsm_iter = fsm_head; fsm_iter; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next) {
@@ -179,7 +270,7 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c
if (fsm_iter != fsm_head) {
fsm_prev->next = fsm_iter->next;
fsm_iter->next = fsm_head;
- fsmenu_set_category(fsmenu, category, fsm_iter);
+ ED_fsmenu_set_category(fsmenu, category, fsm_iter);
}
}
return;
@@ -201,11 +292,18 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c
fsm_iter = MEM_mallocN(sizeof(*fsm_iter), "fsme");
fsm_iter->path = BLI_strdup(path);
fsm_iter->save = (flag & FS_INSERT_SAVE) != 0;
+ if (name && name[0]) {
+ BLI_strncpy(fsm_iter->name, name, sizeof(fsm_iter->name));
+ }
+ else {
+ fsm_iter->name[0] = '\0';
+ }
+ fsmenu_entry_refresh_valid(fsm_iter);
if (fsm_prev) {
if (flag & FS_INSERT_FIRST) {
fsm_iter->next = fsm_head;
- fsmenu_set_category(fsmenu, category, fsm_iter);
+ ED_fsmenu_set_category(fsmenu, category, fsm_iter);
}
else {
fsm_iter->next = fsm_prev->next;
@@ -214,7 +312,7 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c
}
else {
fsm_iter->next = fsm_head;
- fsmenu_set_category(fsmenu, category, fsm_iter);
+ ED_fsmenu_set_category(fsmenu, category, fsm_iter);
}
}
@@ -224,7 +322,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx
FSMenuEntry *fsm_iter;
FSMenuEntry *fsm_head;
- fsm_head = fsmenu_get_category(fsmenu, category);
+ fsm_head = ED_fsmenu_get_category(fsmenu, category);
for (fsm_iter = fsm_head; fsm_iter && idx; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next)
idx--;
@@ -241,7 +339,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx
}
else {
fsm_head = fsm_iter->next;
- fsmenu_set_category(fsmenu, category, fsm_head);
+ ED_fsmenu_set_category(fsmenu, category, fsm_head);
}
/* free entry */
MEM_freeN(fsm_iter->path);
@@ -253,20 +351,29 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx
void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename)
{
FSMenuEntry *fsm_iter = NULL;
+ char fsm_name[FILE_MAX];
int nwritten = 0;
FILE *fp = BLI_fopen(filename, "w");
if (!fp) return;
-
+
fprintf(fp, "[Bookmarks]\n");
- for (fsm_iter = fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter; fsm_iter = fsm_iter->next) {
+ for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter; fsm_iter = fsm_iter->next) {
if (fsm_iter->path && fsm_iter->save) {
+ fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name));
+ if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) {
+ fprintf(fp, "!%s\n", fsm_iter->name);
+ }
fprintf(fp, "%s\n", fsm_iter->path);
}
}
fprintf(fp, "[Recent]\n");
- for (fsm_iter = fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsm_iter && (nwritten < FSMENU_RECENT_MAX); fsm_iter = fsm_iter->next, ++nwritten) {
+ for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsm_iter && (nwritten < FSMENU_RECENT_MAX); fsm_iter = fsm_iter->next, ++nwritten) {
if (fsm_iter->path && fsm_iter->save) {
+ fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name));
+ if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) {
+ fprintf(fp, "!%s\n", fsm_iter->name);
+ }
fprintf(fp, "%s\n", fsm_iter->path);
}
}
@@ -276,19 +383,31 @@ void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename)
void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename)
{
char line[FILE_MAXDIR];
+ char name[FILE_MAXFILE];
FSMenuCategory category = FS_CATEGORY_BOOKMARKS;
FILE *fp;
fp = BLI_fopen(filename, "r");
if (!fp) return;
+ name[0] = '\0';
+
while (fgets(line, sizeof(line), fp) != NULL) { /* read a line */
- if (strncmp(line, "[Bookmarks]", 11) == 0) {
+ if (STREQLEN(line, "[Bookmarks]", 11)) {
category = FS_CATEGORY_BOOKMARKS;
}
- else if (strncmp(line, "[Recent]", 8) == 0) {
+ else if (STREQLEN(line, "[Recent]", 8)) {
category = FS_CATEGORY_RECENT;
}
+ else if (line[0] == '!') {
+ int len = strlen(line);
+ if (len > 0) {
+ if (line[len - 1] == '\n') {
+ line[len - 1] = '\0';
+ }
+ BLI_strncpy(name, line + 1, sizeof(name));
+ }
+ }
else {
int len = strlen(line);
if (len > 0) {
@@ -302,9 +421,11 @@ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename)
if (BLI_exists(line))
#endif
{
- fsmenu_insert_entry(fsmenu, category, line, FS_INSERT_SAVE);
+ fsmenu_insert_entry(fsmenu, category, line, name, FS_INSERT_SAVE);
}
}
+ /* always reset name. */
+ name[0] = '\0';
}
}
fclose(fp);
@@ -316,6 +437,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
#ifdef WIN32
/* Add the drive names to the listing */
{
+ wchar_t wline[FILE_MAXDIR];
__int64 tmp;
char tmps[4];
int i;
@@ -329,16 +451,18 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
tmps[2] = '\\';
tmps[3] = 0;
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, NULL, FS_INSERT_SORTED);
}
}
/* Adding Desktop and My Documents */
if (read_bookmarks) {
- SHGetSpecialFolderPath(0, line, CSIDL_PERSONAL, 0);
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
- SHGetSpecialFolderPath(0, line, CSIDL_DESKTOPDIRECTORY, 0);
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
+ SHGetSpecialFolderPathW(0, wline, CSIDL_PERSONAL, 0);
+ BLI_strncpy_wchar_as_utf8(line, wline, FILE_MAXDIR);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
+ SHGetSpecialFolderPathW(0, wline, CSIDL_DESKTOPDIRECTORY, 0);
+ BLI_strncpy_wchar_as_utf8(line, wline, FILE_MAXDIR);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
}
}
#else
@@ -359,38 +483,38 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
continue;
FSRefMakePath(&dir, path, FILE_MAX);
- if (strcmp((char *)path, "/home") && strcmp((char *)path, "/net")) {
+ if (!STREQ((char *)path, "/home") && !STREQ((char *)path, "/net")) {
/* /net and /home are meaningless on OSX, home folders are stored in /Users */
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, NULL, FS_INSERT_SORTED);
}
}
/* As 10.4 doesn't provide proper API to retrieve the favorite places,
* assume they are the standard ones
- * TODO : replace hardcoded paths with proper BLI_get_folder calls */
+ * TODO : replace hardcoded paths with proper BKE_appdir_folder_id calls */
home = getenv("HOME");
if (read_bookmarks && home) {
BLI_snprintf(line, sizeof(line), "%s/", home);
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
BLI_snprintf(line, sizeof(line), "%s/Desktop/", home);
if (BLI_exists(line)) {
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
}
BLI_snprintf(line, sizeof(line), "%s/Documents/", home);
if (BLI_exists(line)) {
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
}
BLI_snprintf(line, sizeof(line), "%s/Pictures/", home);
if (BLI_exists(line)) {
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
}
BLI_snprintf(line, sizeof(line), "%s/Music/", home);
if (BLI_exists(line)) {
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
}
BLI_snprintf(line, sizeof(line), "%s/Movies/", home);
if (BLI_exists(line)) {
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
}
}
#else /* OSX 10.6+ */
@@ -410,7 +534,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
continue;
CFURLGetFileSystemRepresentation(cfURL, false, (UInt8 *)defPath, FILE_MAX);
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, NULL, FS_INSERT_SORTED);
}
CFRelease(volEnum);
@@ -447,7 +571,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
/* Exclude "all my files" as it makes no sense in blender fileselector */
/* Exclude "airdrop" if wlan not active as it would show "" ) */
if (!strstr(line, "myDocuments.cannedSearch") && (*line != '\0')) {
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, 0);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_LAST);
}
CFRelease(pathString);
@@ -466,10 +590,10 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
if (read_bookmarks && home) {
BLI_snprintf(line, sizeof(line), "%s/", home);
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
BLI_snprintf(line, sizeof(line), "%s/Desktop/", home);
if (BLI_exists(line)) {
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED);
}
}
@@ -488,16 +612,16 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
else {
while ((mnt = getmntent(fp))) {
/* not sure if this is right, but seems to give the relevant mnts */
- if (strncmp(mnt->mnt_fsname, "/dev", 4))
+ if (!STREQLEN(mnt->mnt_fsname, "/dev", 4))
continue;
len = strlen(mnt->mnt_dir);
if (len && mnt->mnt_dir[len - 1] != '/') {
BLI_snprintf(line, sizeof(line), "%s/", mnt->mnt_dir);
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, NULL, FS_INSERT_SORTED);
}
else {
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, NULL, FS_INSERT_SORTED);
}
found = 1;
@@ -510,7 +634,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
/* fallback */
if (!found)
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", NULL, FS_INSERT_SORTED);
}
}
#endif
@@ -520,7 +644,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category)
{
- FSMenuEntry *fsm_iter = fsmenu_get_category(fsmenu, category);
+ FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category);
while (fsm_iter) {
FSMenuEntry *fsm_next = fsm_iter->next;
@@ -537,15 +661,28 @@ static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category)
void fsmenu_refresh_system_category(struct FSMenu *fsmenu)
{
fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM);
- fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM, NULL);
+ ED_fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM, NULL);
fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS);
- fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, NULL);
+ ED_fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, NULL);
/* Add all entries to system category */
fsmenu_read_system(fsmenu, true);
}
+void fsmenu_refresh_bookmarks_status(struct FSMenu *fsmenu)
+{
+ int categories[] = {FS_CATEGORY_SYSTEM, FS_CATEGORY_SYSTEM_BOOKMARKS, FS_CATEGORY_BOOKMARKS, FS_CATEGORY_RECENT};
+ int i;
+
+ for (i = sizeof(categories) / sizeof(*categories); i--; ) {
+ FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, categories[i]);
+ for ( ; fsm_iter; fsm_iter = fsm_iter->next) {
+ fsmenu_entry_refresh_valid(fsm_iter);
+ }
+ }
+}
+
void fsmenu_free(void)
{
if (g_fsmenu) {
@@ -559,3 +696,16 @@ void fsmenu_free(void)
g_fsmenu = NULL;
}
+int fsmenu_get_active_indices(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *dir)
+{
+ FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category);
+ int i;
+
+ for (i = 0; fsm_iter; fsm_iter = fsm_iter->next, i++) {
+ if (BLI_path_cmp(dir, fsm_iter->path) == 0) {
+ return i;
+ }
+ }
+
+ return -1;
+}
diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h
index 01bd4e95afa..81014874fb5 100644
--- a/source/blender/editors/space_file/fsmenu.h
+++ b/source/blender/editors/space_file/fsmenu.h
@@ -37,42 +37,26 @@
/* XXX could become UserPref */
#define FSMENU_RECENT_MAX 10
-typedef enum FSMenuCategory {
- FS_CATEGORY_SYSTEM,
- FS_CATEGORY_SYSTEM_BOOKMARKS,
- FS_CATEGORY_BOOKMARKS,
- FS_CATEGORY_RECENT
-} FSMenuCategory;
-
-typedef enum FSMenuInsert {
- FS_INSERT_SORTED = (1 << 0),
- FS_INSERT_SAVE = (1 << 1),
- FS_INSERT_FIRST = (1 << 2) /* moves the item to the front of the list when its not already there */
-} FSMenuInsert;
+enum FSMenuCategory;
+enum FSMenuInsert;
struct FSMenu;
-
-struct FSMenu *fsmenu_get(void);
-
-/** Returns the number of entries in the Fileselect Menu */
-int fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category);
-
-/** Returns the fsmenu entry at \a index (or NULL if a bad index)
- * or a separator.
- */
-char *fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index);
+struct FSMenuEntry;
/** Inserts a new fsmenu entry with the given \a path.
* Duplicate entries are not added.
* \param flag Options for inserting the entry.
*/
-void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, const FSMenuInsert flag);
+void fsmenu_insert_entry(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *path, const char *name, const enum FSMenuInsert flag);
+
+/** Refresh 'valid' status of given menu entry */
+void fsmenu_entry_refresh_valid(struct FSMenuEntry *fsentry);
/** Return whether the entry was created by the user and can be saved and deleted */
-short fsmenu_can_save(struct FSMenu *fsmenu, FSMenuCategory category, int index);
+short fsmenu_can_save(struct FSMenu *fsmenu, enum FSMenuCategory category, int index);
/** Removes the fsmenu entry at the given \a index. */
-void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index);
+void fsmenu_remove_entry(struct FSMenu *fsmenu, enum FSMenuCategory category, int index);
/** saves the 'bookmarks' to the specified file */
void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename);
@@ -89,5 +73,11 @@ void fsmenu_free(void);
/** Refresh system directory menu */
void fsmenu_refresh_system_category(struct FSMenu *fsmenu);
+/** Refresh 'valid' status of all menu entries */
+void fsmenu_refresh_bookmarks_status(struct FSMenu *fsmenu);
+
+/** Get active index based on given directory. */
+int fsmenu_get_active_indices(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *dir);
+
#endif
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index d5be04cff20..782b318b8a2 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -39,8 +39,8 @@
#include "BLI_utildefines.h"
#include "BLI_fileops_types.h"
-#include "BLO_readfile.h"
+#include "BKE_appdir.h"
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_global.h"
@@ -71,7 +71,7 @@ static SpaceLink *file_new(const bContext *UNUSED(C))
{
ARegion *ar;
SpaceFile *sfile;
-
+
sfile = MEM_callocN(sizeof(SpaceFile), "initfile");
sfile->spacetype = SPACE_FILE;
@@ -81,12 +81,18 @@ static SpaceLink *file_new(const bContext *UNUSED(C))
ar->regiontype = RGN_TYPE_HEADER;
ar->alignment = RGN_ALIGN_TOP;
- /* channel list region */
- ar = MEM_callocN(sizeof(ARegion), "channel area for file");
+ /* Tools region */
+ ar = MEM_callocN(sizeof(ARegion), "tools area for file");
BLI_addtail(&sfile->regionbase, ar);
- ar->regiontype = RGN_TYPE_CHANNELS;
+ ar->regiontype = RGN_TYPE_TOOLS;
ar->alignment = RGN_ALIGN_LEFT;
+ /* Tool props (aka operator) region */
+ ar = MEM_callocN(sizeof(ARegion), "tool props area for file");
+ BLI_addtail(&sfile->regionbase, ar);
+ ar->regiontype = RGN_TYPE_TOOL_PROPS;
+ ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
+
/* ui list region */
ar = MEM_callocN(sizeof(ARegion), "ui area for file");
BLI_addtail(&sfile->regionbase, ar);
@@ -149,7 +155,13 @@ static void file_init(wmWindowManager *UNUSED(wm), ScrArea *sa)
SpaceFile *sfile = (SpaceFile *)sa->spacedata.first;
/* refresh system directory list */
- fsmenu_refresh_system_category(fsmenu_get());
+ fsmenu_refresh_system_category(ED_fsmenu_get());
+
+ /* Update bookmarks 'valid' state.
+ * Done here, because it seems BLI_is_dir() can have huge impact on performances
+ * in some cases, on win systems... See T43684.
+ */
+ fsmenu_refresh_bookmarks_status(ED_fsmenu_get());
if (sfile->layout) sfile->layout->dirty = true;
}
@@ -187,70 +199,81 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
return (SpaceLink *)sfilen;
}
-static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
+static void file_refresh(const bContext *C, ScrArea *sa)
{
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_params(sfile);
+ struct FSMenu *fsmenu = ED_fsmenu_get();
- if (!sfile->folders_prev)
+ if (!sfile->folders_prev) {
sfile->folders_prev = folderlist_new();
+ }
if (!sfile->files) {
sfile->files = filelist_new(params->type);
filelist_setdir(sfile->files, params->dir);
- params->active_file = -1; // added this so it opens nicer (ton)
+ params->active_file = -1; /* added this so it opens nicer (ton) */
}
- filelist_hidedot(sfile->files, params->flag & FILE_HIDE_DOT);
- filelist_setfilter(sfile->files, params->flag & FILE_FILTER ? params->filter : 0);
- filelist_setfilter_types(sfile->files, params->filter_glob);
+ filelist_setsorting(sfile->files, params->sort);
+ filelist_setfilter_options(sfile->files, params->flag & FILE_HIDE_DOT,
+ false, /* TODO hide_parent, should be controllable? */
+ params->flag & FILE_FILTER ? params->filter : 0,
+ params->filter_glob,
+ params->filter_search);
+
+ /* Update the active indices of bookmarks & co. */
+ sfile->systemnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_SYSTEM, params->dir);
+ sfile->system_bookmarknr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, params->dir);
+ sfile->bookmarknr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir);
+ sfile->recentnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_RECENT, params->dir);
if (filelist_empty(sfile->files)) {
thumbnails_stop(wm, sfile->files);
filelist_readdir(sfile->files);
- if (params->sort != FILE_SORT_NONE) {
- filelist_sort(sfile->files, params->sort);
- }
+ filelist_sort(sfile->files);
BLI_strncpy(params->dir, filelist_dir(sfile->files), FILE_MAX);
- if (params->display == FILE_IMGDISPLAY) {
+ }
+ else if (filelist_need_sorting(sfile->files)) {
+ thumbnails_stop(wm, sfile->files);
+ filelist_sort(sfile->files);
+ }
+
+ if ((params->display == FILE_IMGDISPLAY) && filelist_need_thumbnails(sfile->files)) {
+ if (!thumbnails_running(wm, sfile->files)) {
thumbnails_start(sfile->files, C);
}
}
else {
- if (params->sort != FILE_SORT_NONE) {
- thumbnails_stop(wm, sfile->files);
- filelist_sort(sfile->files, params->sort);
- if (params->display == FILE_IMGDISPLAY) {
- thumbnails_start(sfile->files, C);
- }
- }
- else {
- if (params->display == FILE_IMGDISPLAY) {
- if (!thumbnails_running(wm, sfile->files)) {
- thumbnails_start(sfile->files, C);
- }
- }
- else {
- /* stop any running thumbnail jobs if we're not
- * displaying them - speedup for NFS */
- thumbnails_stop(wm, sfile->files);
- }
- filelist_filter(sfile->files);
- }
+ /* stop any running thumbnail jobs if we're not displaying them - speedup for NFS */
+ thumbnails_stop(wm, sfile->files);
}
-
+
+ filelist_filter(sfile->files);
+
if (params->renamefile[0] != '\0') {
int idx = filelist_find(sfile->files, params->renamefile);
if (idx >= 0) {
struct direntry *file = filelist_file(sfile->files, idx);
if (file) {
- file->selflag |= EDITING_FILE;
+ file->selflag |= FILE_SEL_EDITING;
}
}
BLI_strncpy(sfile->params->renameedit, sfile->params->renamefile, sizeof(sfile->params->renameedit));
params->renamefile[0] = '\0';
}
- if (sfile->layout) sfile->layout->dirty = true;
+ if (sfile->layout) {
+ sfile->layout->dirty = true;
+ }
+
+ /* Might be called with NULL sa, see file_main_area_draw() below. */
+ if (sa && BKE_area_find_region_type(sa, RGN_TYPE_TOOLS) == NULL) {
+ /* Create TOOLS/TOOL_PROPS regions. */
+ file_tools_region(sa);
+
+ ED_area_initialize(wm, CTX_wm_window(C), sa);
+ ED_area_tag_redraw(sa);
+ }
}
static void file_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
@@ -387,6 +410,8 @@ static void file_operatortypes(void)
WM_operatortype_append(FILE_OT_bookmark_toggle);
WM_operatortype_append(FILE_OT_bookmark_add);
WM_operatortype_append(FILE_OT_bookmark_delete);
+ WM_operatortype_append(FILE_OT_bookmark_cleanup);
+ WM_operatortype_append(FILE_OT_bookmark_move);
WM_operatortype_append(FILE_OT_reset_recent);
WM_operatortype_append(FILE_OT_hidedot);
WM_operatortype_append(FILE_OT_filenum);
@@ -478,7 +503,7 @@ static void file_keymap(struct wmKeyConfig *keyconf)
}
-static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
+static void file_tools_area_init(wmWindowManager *wm, ARegion *ar)
{
wmKeyMap *keymap;
@@ -490,12 +515,12 @@ static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
-static void file_channel_area_draw(const bContext *C, ARegion *ar)
+static void file_tools_area_draw(const bContext *C, ARegion *ar)
{
ED_region_panels(C, ar, 1, NULL, -1);
}
-static void file_channel_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
+static void file_tools_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
{
#if 0
/* context changes */
@@ -621,12 +646,24 @@ void ED_spacetype_file(void)
/* regions: channels (directories) */
art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
- art->regionid = RGN_TYPE_CHANNELS;
+ art->regionid = RGN_TYPE_TOOLS;
art->prefsizex = 240;
+ art->prefsizey = 60;
+ art->keymapflag = ED_KEYMAP_UI;
+ art->listener = file_tools_area_listener;
+ art->init = file_tools_area_init;
+ art->draw = file_tools_area_draw;
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: tool properties */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype file operator region");
+ art->regionid = RGN_TYPE_TOOL_PROPS;
+ art->prefsizex = 0;
+ art->prefsizey = 360;
art->keymapflag = ED_KEYMAP_UI;
- art->listener = file_channel_area_listener;
- art->init = file_channel_area_init;
- art->draw = file_channel_area_draw;
+ art->listener = file_tools_area_listener;
+ art->init = file_tools_area_init;
+ art->draw = file_tools_area_draw;
BLI_addhead(&st->regiontypes, art);
file_panels_register(art);
@@ -656,16 +693,16 @@ void ED_file_exit(void)
void ED_file_read_bookmarks(void)
{
- const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
+ const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
fsmenu_free();
- fsmenu_read_system(fsmenu_get(), true);
+ fsmenu_read_system(ED_fsmenu_get(), true);
if (cfgdir) {
char name[FILE_MAX];
BLI_make_file_string("/", name, cfgdir, BLENDER_BOOKMARK_FILE);
- fsmenu_read_bookmarks(fsmenu_get(), name);
+ fsmenu_read_bookmarks(ED_fsmenu_get(), name);
}
}
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index b59030d3c12..a2b64afdb15 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -159,7 +159,7 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
// UNUSED
// block = uiLayoutGetBlock(layout);
- // uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
+ // UI_block_func_handle_set(block, do_graph_region_buttons, NULL);
/* F-Curve pointer */
RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
@@ -315,7 +315,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
return;
block = uiLayoutGetBlock(layout);
- /* uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); */
+ /* UI_block_func_handle_set(block, do_graph_region_buttons, NULL); */
/* only show this info if there are keyframes to edit */
if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
@@ -366,33 +366,33 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
{
uiItemL(col, IFACE_("Key:"), ICON_NONE);
- but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "co", 0, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt);
+ UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
- but = uiDefButR(block, NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "co", 1, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt);
- uiButSetUnitType(but, unit);
+ UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
+ UI_but_unit_type_set(but, unit);
}
/* previous handle - only if previous was Bezier interpolation */
if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);
- but = uiDefButR(block, NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
+ UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
- but = uiDefButR(block, NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
- uiButSetUnitType(but, unit);
+ UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
+ UI_but_unit_type_set(but, unit);
/* XXX: with label? */
- but = uiDefButR(block, MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_left_type", 0, 0, 0, -1, -1, "Type of left handle");
- uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
+ UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
}
/* next handle - only if current is Bezier interpolation */
@@ -400,19 +400,19 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
/* NOTE: special update callbacks are needed on the coords here due to T39911 */
uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);
- but = uiDefButR(block, NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
+ UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
- but = uiDefButR(block, NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL);
- uiButSetFunc(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
- uiButSetUnitType(but, unit);
+ UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
+ UI_but_unit_type_set(but, unit);
/* XXX: with label? */
- but = uiDefButR(block, MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_right_type", 0, 0, 0, -1, -1, "Type of right handle");
- uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
+ UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
}
}
else {
@@ -671,22 +671,22 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
/* set event handler for panel */
block = uiLayoutGetBlock(pa->layout); // xxx?
- uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL);
+ UI_block_func_handle_set(block, do_graph_region_driver_buttons, NULL);
/* general actions - management */
col = uiLayoutColumn(pa->layout, false);
block = uiLayoutGetBlock(col);
- but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"),
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"),
0, 0, 10 * UI_UNIT_X, 22,
NULL, 0.0, 0.0, 0, 0,
TIP_("Force updates of dependencies"));
- uiButSetFunc(but, driver_update_flags_cb, fcu, NULL);
+ UI_but_func_set(but, driver_update_flags_cb, fcu, NULL);
- but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"),
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"),
0, 0, 10 * UI_UNIT_X, 18,
NULL, 0.0, 0.0, 0, 0,
TIP_("Remove this driver"));
- uiButSetNFunc(but, driver_remove_cb, MEM_dupallocN(ale), NULL);
+ UI_but_funcN_set(but, driver_remove_cb, MEM_dupallocN(ale), NULL);
/* driver-level settings - type, expressions, and errors */
RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr);
@@ -763,11 +763,11 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
/* add driver variables */
col = uiLayoutColumn(pa->layout, false);
block = uiLayoutGetBlock(col);
- but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"),
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"),
0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0, 0,
TIP_("Driver variables ensure that all dependencies will be accounted for and that drivers will update correctly"));
- uiButSetFunc(but, driver_add_var_cb, driver, NULL);
+ UI_but_func_set(but, driver_add_var_cb, driver, NULL);
/* loop over targets, drawing them */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
@@ -788,11 +788,11 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
uiItemR(row, &dvar_ptr, "name", 0, "", ICON_NONE);
/* remove button */
- uiBlockSetEmboss(block, UI_EMBOSSN);
- but = uiDefIconBut(block, BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y,
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable"));
- uiButSetFunc(but, driver_delete_var_cb, driver, dvar);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_but_func_set(but, driver_delete_var_cb, driver, dvar);
+ UI_block_emboss_set(block, UI_EMBOSS);
/* variable type */
row = uiLayoutRow(box, false);
@@ -869,7 +869,7 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa)
return;
block = uiLayoutGetBlock(pa->layout);
- uiBlockSetHandleFunc(block, do_graph_region_modifier_buttons, NULL);
+ UI_block_func_handle_set(block, do_graph_region_modifier_buttons, NULL);
/* 'add modifier' button at top of panel */
{
@@ -879,7 +879,7 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa)
/* this is an operator button which calls a 'add modifier' operator...
* a menu might be nicer but would be tricky as we need some custom filtering
*/
- uiDefButO(block, BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"),
+ uiDefButO(block, UI_BTYPE_BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"),
0.5 * UI_UNIT_X, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, TIP_("Adds a new F-Curve Modifier for the active F-Curve"));
/* copy/paste (as sub-row)*/
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index ed7cfe7da99..a5c04ce2cb4 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -33,6 +33,7 @@
#include <float.h>
#include "BLI_blenlib.h"
+#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_anim_types.h"
@@ -42,6 +43,7 @@
#include "DNA_userdef_types.h"
#include "BKE_context.h"
+#include "BKE_curve.h"
#include "BKE_fcurve.h"
@@ -475,6 +477,7 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
/* helper func - just draw the F-Curve by sampling the visible region (for drawing curves with modifiers) */
static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, View2DGrid *grid)
{
+ SpaceIpo *sipo = (SpaceIpo *)ac->sl;
ChannelDriver *driver;
float samplefreq;
float stime, etime;
@@ -502,7 +505,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
* which means that our curves can be as smooth as possible. However,
* this does mean that curves may not be fully accurate (i.e. if they have
* sudden spikes which happen at the sampling point, we may have problems).
- * Also, this may introduce lower performance on less densely detailed curves,'
+ * Also, this may introduce lower performance on less densely detailed curves,
* though it is impossible to predict this from the modifiers!
*
* If the automatically determined sampling frequency is likely to cause an infinite
@@ -512,7 +515,25 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
/* grid->dx represents the number of 'frames' between gridlines, but we divide by U.v2d_min_gridsize to get pixels-steps */
/* TODO: perhaps we should have 1.0 frames as upper limit so that curves don't get too distorted? */
samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize);
- if (samplefreq < 0.00001f) samplefreq = 0.00001f;
+
+ if (sipo->flag & SIPO_BEAUTYDRAW_OFF) {
+ /* Low Precision = coarse lower-bound clamping
+ *
+ * Although the "Beauty Draw" flag was originally for AA'd
+ * line drawing, the sampling rate here has a much greater
+ * impact on performance (e.g. for T40372)!
+ *
+ * This one still amounts to 10 sample-frames for each 1-frame interval
+ * which should be quite a decent approximation in many situations.
+ */
+ if (samplefreq < 0.1f)
+ samplefreq = 0.1f;
+ }
+ else {
+ /* "Higher Precision" but slower - especially on larger windows (e.g. T40372) */
+ if (samplefreq < 0.00001f)
+ samplefreq = 0.00001f;
+ }
/* the start/end times are simply the horizontal extents of the 'cur' rect */
@@ -525,12 +546,13 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
* the displayed values appear correctly in the viewport
*/
glBegin(GL_LINE_STRIP);
-
- for (i = 0, n = (etime - stime) / samplefreq + 0.5f; i < n; ++i) {
+
+ n = (etime - stime) / samplefreq + 0.5f;
+ for (i = 0; i <= n; i++) {
float ctime = stime + i * samplefreq;
glVertex2f(ctime, evaluate_fcurve(fcu, ctime) * unitFac);
}
-
+
glEnd();
/* restore driver */
@@ -616,8 +638,24 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
glPopMatrix();
}
-#if 0
-/* helper func - draw one repeat of an F-Curve */
+/* helper func - check if the F-Curve only contains easily drawable segments
+ * (i.e. no easing equation interpolations)
+ */
+static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu)
+{
+ BezTriple *bezt;
+ int i;
+
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ if (ELEM(bezt->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN, BEZT_IPO_BEZ) == false) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* helper func - draw one repeat of an F-Curve (using Bezier curve approximations) */
static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d)
{
BezTriple *prevbezt = fcu->bezt;
@@ -629,12 +667,12 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
int resol;
float unit_scale;
short mapping_flag = ANIM_get_normalization_flags(ac);
-
+
/* apply unit mapping */
glPushMatrix();
unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag);
glScalef(1.0f, unit_scale, 1.0f);
-
+
glBegin(GL_LINE_STRIP);
/* extrapolate to left? */
@@ -689,17 +727,19 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
v1[1] = prevbezt->vec[1][1];
glVertex2fv(v1);
}
- else {
+ else if (prevbezt->ipo == BEZT_IPO_BEZ) {
/* Bezier-Interpolation: draw curve as series of segments between keyframes
* - resol determines number of points to sample in between keyframes
*/
/* resol depends on distance between points (not just horizontal) OR is a fixed high res */
/* TODO: view scale should factor into this someday too... */
- if (fcu->driver)
+ if (fcu->driver) {
resol = 32;
- else
+ }
+ else {
resol = (int)(5.0f * len_v2v2(bezt->vec[1], prevbezt->vec[1]));
+ }
if (resol < 2) {
/* only draw one */
@@ -773,7 +813,6 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
glEnd();
glPopMatrix();
}
-#endif
/* Debugging -------------------------------- */
@@ -809,11 +848,13 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
* NOTE: we need to scale the y-values to be valid for the units
*/
glBegin(GL_LINES);
+ {
t = v2d->cur.xmin;
glVertex2f(t, t * unitfac);
t = v2d->cur.xmax;
glVertex2f(t, t * unitfac);
+ }
glEnd();
/* cleanup line drawing */
@@ -836,6 +877,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
setlinestyle(5);
glBegin(GL_LINES);
+ {
/* x-axis lookup */
co[0] = x;
@@ -855,6 +897,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
co[0] = x;
glVertex2fv(co);
+ }
glEnd();
setlinestyle(0);
@@ -865,7 +908,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
glPointSize(7.0);
glBegin(GL_POINTS);
- glVertex2f(x, y);
+ glVertex2f(x, y);
glEnd();
/* inner frame */
@@ -873,7 +916,7 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
glPointSize(3.0);
glBegin(GL_POINTS);
- glVertex2f(x, y);
+ glVertex2f(x, y);
glEnd();
glPointSize(1.0f);
@@ -989,11 +1032,15 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
}
else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
/* just draw curve based on defined data (i.e. no modifiers) */
- if (fcu->bezt)
- //draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d);
- draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid); // XXX: better to do an optimised integration here instead, but for now, this works
- else if (fcu->fpt)
+ if (fcu->bezt) {
+ if (fcurve_can_use_simple_bezt_drawing(fcu))
+ draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d);
+ else
+ draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid);
+ }
+ else if (fcu->fpt) {
draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d);
+ }
}
/* restore settings */
@@ -1109,7 +1156,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
}
}
{ /* second pass: widgets */
- uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
+ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
size_t channel_index = 0;
y = (float)ACHANNEL_FIRST;
@@ -1135,8 +1182,8 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
channel_index++;
}
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
glDisable(GL_BLEND);
}
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index c8298927f7d..2944901663b 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -60,8 +60,6 @@
#include "BKE_context.h"
#include "BKE_report.h"
-#include "UI_interface.h"
-#include "UI_resources.h"
#include "UI_view2d.h"
#include "ED_anim_api.h"
@@ -699,7 +697,7 @@ static short copy_graph_keys(bAnimContext *ac)
}
static short paste_graph_keys(bAnimContext *ac,
- const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode)
+ const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
{
ListBase anim_data = {NULL, NULL};
int filter, ok = 0;
@@ -716,7 +714,7 @@ static short paste_graph_keys(bAnimContext *ac,
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* paste keyframes */
- ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode);
+ ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
/* clean up */
ANIM_animdata_freelist(&anim_data);
@@ -767,6 +765,7 @@ static int graphkeys_paste_exec(bContext *C, wmOperator *op)
const eKeyPasteOffset offset_mode = RNA_enum_get(op->ptr, "offset");
const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge");
+ const bool flipped = RNA_boolean_get(op->ptr, "flipped");
/* get editor data */
if (ANIM_animdata_get_context(C, &ac) == 0)
@@ -776,7 +775,7 @@ static int graphkeys_paste_exec(bContext *C, wmOperator *op)
ac.reports = op->reports;
/* paste keyframes - non-zero return means an error occurred while trying to paste */
- if (paste_graph_keys(&ac, offset_mode, merge_mode)) {
+ if (paste_graph_keys(&ac, offset_mode, merge_mode, flipped)) {
return OPERATOR_CANCELLED;
}
@@ -788,6 +787,8 @@ static int graphkeys_paste_exec(bContext *C, wmOperator *op)
void GRAPH_OT_paste(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Paste Keyframes";
ot->idname = "GRAPH_OT_paste";
@@ -804,6 +805,8 @@ void GRAPH_OT_paste(wmOperatorType *ot)
/* props */
RNA_def_enum(ot->srna, "offset", keyframe_paste_offset_items, KEYFRAME_PASTE_OFFSET_CFRA_START, "Offset", "Paste time offset of keys");
RNA_def_enum(ot->srna, "merge", keyframe_paste_merge_items, KEYFRAME_PASTE_MERGE_MIX, "Type", "Method of merging pasted keys and existing");
+ prop = RNA_def_boolean(ot->srna, "flipped", false, "Flipped", "Paste keyframes from mirrored bones if they exist");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ******************** Duplicate Keyframes Operator ************************* */
@@ -1241,7 +1244,7 @@ void GRAPH_OT_sound_bake(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_SOUND | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
RNA_def_float(ot->srna, "low", 0.0f, 0.0, 100000.0, "Lowest frequency",
"Cutoff frequency of a high-pass filter that is applied to the audio data", 0.1, 1000.00);
@@ -1718,7 +1721,7 @@ static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
* so if the paths or the ID's don't match up, then a curve needs to be added
* to a new group
*/
- if ((euf) && (euf->id == ale->id) && (strcmp(euf->rna_path, fcu->rna_path) == 0)) {
+ if ((euf) && (euf->id == ale->id) && (STREQ(euf->rna_path, fcu->rna_path))) {
/* this should be fine to add to the existing group then */
euf->fcurves[fcu->array_index] = fcu;
}
@@ -1888,7 +1891,7 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
ked.f1 += current_ked.f1;
ked.i1 += current_ked.i1;
- ked.f2 += current_ked.f2 / unit_scale;
+ ked.f2 += current_ked.f2 * unit_scale;
ked.i2 += current_ked.i2;
}
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 408c78d194e..50412952139 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -62,6 +62,7 @@ void graph_draw_ghost_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, str
void GRAPH_OT_select_all_toggle(struct wmOperatorType *ot);
void GRAPH_OT_select_border(struct wmOperatorType *ot);
void GRAPH_OT_select_lasso(struct wmOperatorType *ot);
+void GRAPH_OT_select_circle(struct wmOperatorType *ot);
void GRAPH_OT_select_column(struct wmOperatorType *ot);
void GRAPH_OT_select_linked(struct wmOperatorType *ot);
void GRAPH_OT_select_more(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 62b6b59df29..da308d0b1f1 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -34,6 +34,7 @@
#include "DNA_scene_types.h"
+#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_math_base.h"
@@ -200,6 +201,174 @@ static void GRAPH_OT_cursor_set(wmOperatorType *ot)
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Value", "", -100.0f, 100.0f);
}
+/* Hide/Reveal ------------------------------------------------------------ */
+
+static int graphview_curves_hide_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ ListBase all_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ const bool unselected = RNA_boolean_get(op->ptr, "unselected");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get list of all channels that selection may need to be flushed to
+ * - hierarchy must not affect what we have access to here...
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
+
+ /* filter data
+ * - of the remaining visible curves, we want to hide the ones that are
+ * selected/unselected (depending on "unselected" prop)
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ if (unselected)
+ filter |= ANIMFILTER_UNSEL;
+ else
+ filter |= ANIMFILTER_SEL;
+
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */
+ /* TODO: find out why this is the case, and fix that */
+ if (ale->type == ANIMTYPE_OBJECT)
+ continue;
+
+ /* change the hide setting, and unselect it... */
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR);
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_CLEAR);
+
+ /* now, also flush selection status up/down as appropriate */
+ ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR);
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+ BLI_freelistN(&all_data);
+
+ /* unhide selected */
+ if (unselected) {
+ /* turn off requirement for visible */
+ filter = ANIMFILTER_SEL | ANIMFILTER_NODUPLIS | ANIMFILTER_LIST_CHANNELS;
+
+ /* flushing has been done */
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */
+ /* TODO: find out why this is the case, and fix that */
+ if (ale->type == ANIMTYPE_OBJECT)
+ continue;
+
+ /* change the hide setting, and unselect it... */
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_ADD);
+
+ /* now, also flush selection status up/down as appropriate */
+ ANIM_flush_setting_anim_channels(&ac, &anim_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
+ }
+ ANIM_animdata_freelist(&anim_data);
+ }
+
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static void GRAPH_OT_hide(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Hide Curves";
+ ot->idname = "GRAPH_OT_hide";
+ ot->description = "Hide selected curves from Graph Editor view";
+
+ /* api callbacks */
+ ot->exec = graphview_curves_hide_exec;
+ ot->poll = ED_operator_graphedit_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected curves");
+}
+
+/* ........ */
+
+static int graphview_curves_reveal_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ ListBase all_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get list of all channels that selection may need to be flushed to
+ * - hierarchy must not affect what we have access to here...
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
+
+ /* filter data
+ * - just go through all visible channels, ensuring that everything is set to be curve-visible
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */
+ /* TODO: find out why this is the case, and fix that */
+ if (ale->type == ANIMTYPE_OBJECT)
+ continue;
+
+ /* select if it is not visible */
+ if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE) == 0)
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_ADD);
+
+ /* change the visibility setting */
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
+
+ /* now, also flush selection status up/down as appropriate */
+ ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, true);
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+ BLI_freelistN(&all_data);
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static void GRAPH_OT_reveal(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Reveal Curves";
+ ot->idname = "GRAPH_OT_reveal";
+ ot->description = "Make previously hidden curves visible again in Graph Editor view";
+
+ /* api callbacks */
+ ot->exec = graphview_curves_reveal_exec;
+ ot->poll = ED_operator_graphedit_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/* ************************** registration - operator types **********************************/
void graphedit_operatortypes(void)
@@ -215,12 +384,16 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_ghost_curves_create);
WM_operatortype_append(GRAPH_OT_ghost_curves_clear);
+ WM_operatortype_append(GRAPH_OT_hide);
+ WM_operatortype_append(GRAPH_OT_reveal);
+
/* keyframes */
/* selection */
WM_operatortype_append(GRAPH_OT_clickselect);
WM_operatortype_append(GRAPH_OT_select_all_toggle);
WM_operatortype_append(GRAPH_OT_select_border);
WM_operatortype_append(GRAPH_OT_select_lasso);
+ WM_operatortype_append(GRAPH_OT_select_circle);
WM_operatortype_append(GRAPH_OT_select_column);
WM_operatortype_append(GRAPH_OT_select_linked);
WM_operatortype_append(GRAPH_OT_select_more);
@@ -359,6 +532,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "deselect", true);
+ WM_keymap_add_item(keymap, "GRAPH_OT_select_circle", CKEY, KM_PRESS, 0, 0);
+
/* column select */
RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_KEYS);
RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_CFRA);
@@ -405,9 +580,13 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* copy/paste */
WM_keymap_add_item(keymap, "GRAPH_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
+ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_paste", VKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "flipped", true);
#ifdef __APPLE__
WM_keymap_add_item(keymap, "GRAPH_OT_copy", CKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_paste", VKEY, KM_PRESS, KM_OSKEY, 0);
+ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_paste", VKEY, KM_PRESS, KM_OSKEY | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "flipped", true);
#endif
/* auto-set range */
@@ -429,6 +608,19 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* transform system */
transform_keymap_for_space(keyconf, keymap, SPACE_IPO);
+ /* pivot point settings */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
+ RNA_string_set(kmi->ptr, "value", "BOUNDING_BOX_CENTER");
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
+ RNA_string_set(kmi->ptr, "value", "CURSOR");
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
+ RNA_string_set(kmi->ptr, "value", "INDIVIDUAL_ORIGINS");
+
/* special markers hotkeys for anim editors: see note in definition of this function */
ED_marker_keymap_animedit_conflictfree(keymap);
}
@@ -438,6 +630,7 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
void graphedit_keymap(wmKeyConfig *keyconf)
{
wmKeyMap *keymap;
+ wmKeyMapItem *kmi;
/* keymap for all regions */
keymap = WM_keymap_find(keyconf, "Graph Editor Generic", SPACE_IPO, 0);
@@ -448,7 +641,17 @@ void graphedit_keymap(wmKeyConfig *keyconf)
/* find (i.e. a shortcut for setting the name filter) */
WM_keymap_add_item(keymap, "ANIM_OT_channels_find", FKEY, KM_PRESS, KM_CTRL, 0);
-
+
+ /* hide/reveal selected curves */
+ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_hide", HKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "unselected", false);
+
+ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "unselected", true);
+
+ WM_keymap_add_item(keymap, "GRAPH_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
+
+
/* channels */
/* Channels are not directly handled by the Graph Editor module, but are inherited from the Animation module.
* All the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as these
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 378139accbc..78dbae7618b 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -219,7 +219,7 @@ void GRAPH_OT_select_all_toggle(wmOperatorType *ot)
*/
static void borderselect_graphkeys(
bAnimContext *ac, const rctf *rectf_view, short mode, short selectmode, bool incl_handles,
- struct KeyframeEdit_LassoData *data_lasso)
+ void *data)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
@@ -244,10 +244,16 @@ static void borderselect_graphkeys(
/* init editing data */
memset(&ked, 0, sizeof(KeyframeEditData));
- if (data_lasso) {
+ if (mode == BEZT_OK_REGION_LASSO) {
+ struct KeyframeEdit_LassoData *data_lasso = data;
data_lasso->rectf_scaled = &scaled_rectf;
ked.data = data_lasso;
}
+ else if (mode == BEZT_OK_REGION_CIRCLE) {
+ struct KeyframeEdit_CircleData *data_circle = data;
+ data_circle->rectf_scaled = &scaled_rectf;
+ ked.data = data;
+ }
else {
ked.data = &scaled_rectf;
}
@@ -485,6 +491,81 @@ void GRAPH_OT_select_lasso(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection instead of deselecting everything first");
}
+static int graph_circle_select_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ const int gesture_mode = RNA_int_get(op->ptr, "gesture_mode");
+ short selectmode;
+ bool incl_handles;
+ rctf rect_fl;
+ struct KeyframeEdit_CircleData data;
+ float x = RNA_int_get(op->ptr, "x");
+ float y = RNA_int_get(op->ptr, "y");
+ float radius = RNA_int_get(op->ptr, "radius");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ data.mval[0] = x;
+ data.mval[1] = y;
+ data.radius_squared = radius * radius;
+ data.rectf_view = &rect_fl;
+
+ if (gesture_mode == GESTURE_MODAL_SELECT)
+ selectmode = SELECT_ADD;
+ else
+ selectmode = SELECT_SUBTRACT;
+
+ rect_fl.xmin = x - radius;
+ rect_fl.xmax = x + radius;
+ rect_fl.ymin = y - radius;
+ rect_fl.ymax = y + radius;
+
+ if (ac.spacetype == SPACE_IPO) {
+ SpaceIpo *sipo = (SpaceIpo *)ac.sl;
+ if (selectmode == SELECT_ADD) {
+ incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) ||
+ (sipo->flag & SIPO_NOHANDLES)) == 0;
+ }
+ else {
+ incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0;
+ }
+ }
+ else {
+ incl_handles = false;
+ }
+
+ /* apply borderselect action */
+ borderselect_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data);
+
+ /* send notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GRAPH_OT_select_circle(wmOperatorType *ot)
+{
+ ot->name = "Circle Select";
+ ot->description = "Select keyframe points using circle selection";
+ ot->idname = "GRAPH_OT_select_circle";
+
+ ot->invoke = WM_gesture_circle_invoke;
+ ot->modal = WM_gesture_circle_modal;
+ ot->exec = graph_circle_select_exec;
+ ot->poll = graphop_visible_keyframes_poll;
+ ot->cancel = WM_gesture_circle_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "radius", 1, 1, INT_MAX, "Radius", "", 1, INT_MAX);
+ RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX);
+}
+
/* ******************** Column Select Operator **************************** */
/* This operator works in one of four ways:
* - 1) select all keyframes in the same frame as a selected one (KKEY)
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index e9c8ae95acd..eea360ced45 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -40,7 +40,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BKE_context.h"
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 6dba706b241..ad6f3ff5c7e 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -182,7 +182,7 @@ static void graph_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
{
SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first;
- /* init dopesheet data if non-existant (i.e. for old files) */
+ /* init dopesheet data if non-existent (i.e. for old files) */
if (sipo->ads == NULL) {
sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
sipo->ads->source = (ID *)(G.main->scene.first); // FIXME: this is a really nasty hack here for now...
@@ -293,7 +293,7 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar)
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
- draw_markers_time(C, 0);
+ ED_markers_draw(C, DRAW_MARKERS_MARGIN);
/* preview range */
UI_view2d_view_ortho(v2d);
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 154437ab53a..fb3c140fddf 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -64,6 +64,7 @@
#include "image_intern.h"
#define B_NOP -1
+#define MAX_IMAGE_INFO_LEN 128
/* proto */
@@ -268,7 +269,7 @@ static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PRE
return;
}
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
uiSetPanelHandler(IMAGE_HANDLER_PREVIEW); // for close and esc
@@ -276,7 +277,7 @@ static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PRE
ofsy = -100 + (sa->winy / 2) / sima->blockscale;
if (uiNewPanel(C, ar, block, "Preview", "Image", ofsx, ofsy, 300, 200) == 0) return;
- uiBlockSetDrawExtraFunc(block, preview_cb);
+ UI_but_func_drawextra_set(block, preview_cb);
}
#endif
@@ -290,7 +291,7 @@ static void ui_imageuser_slot_menu(bContext *UNUSED(C), uiLayout *layout, void *
Image *image = image_p;
int slot;
- uiDefBut(block, LABEL, 0, IFACE_("Slot"),
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Slot"),
0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
uiItemS(layout);
@@ -303,7 +304,7 @@ static void ui_imageuser_slot_menu(bContext *UNUSED(C), uiLayout *layout, void *
else {
BLI_snprintf(str, sizeof(str), IFACE_("Slot %d"), slot + 1);
}
- uiDefButS(block, BUTM, B_NOP, str, 0, 0,
+ uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, str, 0, 0,
UI_UNIT_X * 5, UI_UNIT_X, &image->render_slot, (float) slot, 0.0, 0, -1, "");
}
}
@@ -340,14 +341,14 @@ static void ui_imageuser_layer_menu(bContext *UNUSED(C), uiLayout *layout, void
return;
}
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
uiLayoutColumn(layout, false);
- uiDefBut(block, LABEL, 0, IFACE_("Layer"),
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Layer"),
0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
uiItemS(layout);
- nr = BLI_countlist(&rr->layers) - 1;
+ nr = BLI_listbase_count(&rr->layers) - 1;
fake_name = ui_imageuser_layer_fake_name(rr);
if (fake_name) {
@@ -357,7 +358,7 @@ static void ui_imageuser_layer_menu(bContext *UNUSED(C), uiLayout *layout, void
for (rl = rr->layers.last; rl; rl = rl->prev, nr--) {
final:
- uiDefButS(block, BUTM, B_NOP, IFACE_(rl->name), 0, 0,
+ uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rl->name), 0, 0,
UI_UNIT_X * 5, UI_UNIT_X, &iuser->layer, (float) nr, 0.0, 0, -1, "");
}
@@ -406,15 +407,15 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *
rl = BLI_findlink(&rr->layers, rpass_index);
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
uiLayoutColumn(layout, false);
- uiDefBut(block, LABEL, 0, IFACE_("Pass"),
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Pass"),
0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
uiItemS(layout);
- nr = (rl ? BLI_countlist(&rl->passes) : 0) - 1;
+ nr = (rl ? BLI_listbase_count(&rl->passes) : 0) - 1;
fake_name = ui_imageuser_pass_fake_name(rl);
if (fake_name) {
@@ -425,7 +426,7 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *
/* rendered results don't have a Combined pass */
for (rpass = rl ? rl->passes.last : NULL; rpass; rpass = rpass->prev, nr--) {
final:
- uiDefButS(block, BUTM, B_NOP, IFACE_(rpass->name), 0, 0,
+ uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass->name), 0, 0,
UI_UNIT_X * 5, UI_UNIT_X, &iuser->pass, (float) nr, 0.0, 0, -1, "");
}
@@ -452,7 +453,7 @@ static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v)
{
RenderResult *rr = rr_v;
ImageUser *iuser = iuser_v;
- int tot = BLI_countlist(&rr->layers);
+ int tot = BLI_listbase_count(&rr->layers);
if (rr->rectf || rr->rect32)
tot++; /* fake compo/sequencer layer */
@@ -480,7 +481,7 @@ static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v)
RenderLayer *rl = BLI_findlink(&rr->layers, iuser->layer);
if (rl) {
- int tot = BLI_countlist(&rl->passes);
+ int tot = BLI_listbase_count(&rl->passes);
if (rr->rectf || rr->rect32)
tot++; /* fake compo/sequencer layer */
@@ -551,8 +552,8 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes
BLI_snprintf(str, sizeof(str), IFACE_("Slot %d"), *render_slot + 1);
}
but = uiDefMenuBut(block, ui_imageuser_slot_menu, image, str, 0, 0, wmenu1, UI_UNIT_Y, TIP_("Select Slot"));
- uiButSetFunc(but, image_multi_cb, rr, iuser);
- uiButSetMenuFromPulldown(but);
+ UI_but_func_set(but, image_multi_cb, rr, iuser);
+ UI_but_type_set_menu_from_pulldown(but);
}
if (rr) {
@@ -567,8 +568,8 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes
display_name = rl ? rl->name : (fake_name ? fake_name : "");
but = uiDefMenuBut(block, ui_imageuser_layer_menu, rnd_pt, display_name, 0, 0, wmenu2, UI_UNIT_Y, TIP_("Select Layer"));
- uiButSetFunc(but, image_multi_cb, rr, iuser);
- uiButSetMenuFromPulldown(but);
+ UI_but_func_set(but, image_multi_cb, rr, iuser);
+ UI_but_type_set_menu_from_pulldown(but);
/* pass */
@@ -577,8 +578,8 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes
display_name = rpass ? rpass->name : (fake_name ? fake_name : "");
but = uiDefMenuBut(block, ui_imageuser_pass_menu, rnd_pt, display_name, 0, 0, wmenu3, UI_UNIT_Y, TIP_("Select Pass"));
- uiButSetFunc(but, image_multi_cb, rr, iuser);
- uiButSetMenuFromPulldown(but);
+ UI_but_func_set(but, image_multi_cb, rr, iuser);
+ UI_but_type_set_menu_from_pulldown(but);
}
}
@@ -599,20 +600,20 @@ static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, Image *image, Ren
}
/* decrease, increase arrows */
- but = uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0, 0, 0.85f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Previous Layer"));
- uiButSetFunc(but, image_multi_declay_cb, rr, iuser);
- but = uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0, 0, 0.90f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Next Layer"));
- uiButSetFunc(but, image_multi_inclay_cb, rr, iuser);
+ but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_TRIA_LEFT, 0, 0, 0.85f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Previous Layer"));
+ UI_but_func_set(but, image_multi_declay_cb, rr, iuser);
+ but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_TRIA_RIGHT, 0, 0, 0.90f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Next Layer"));
+ UI_but_func_set(but, image_multi_inclay_cb, rr, iuser);
uiblock_layer_pass_buttons(row, image, rr, iuser, 230 * dpi_fac, render_slot);
/* decrease, increase arrows */
- but = uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT, 0, 0, 0.85f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Previous Pass"));
- uiButSetFunc(but, image_multi_decpass_cb, rr, iuser);
- but = uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT, 0, 0, 0.90f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Next Pass"));
- uiButSetFunc(but, image_multi_incpass_cb, rr, iuser);
+ but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_TRIA_LEFT, 0, 0, 0.85f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Previous Pass"));
+ UI_but_func_set(but, image_multi_decpass_cb, rr, iuser);
+ but = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_TRIA_RIGHT, 0, 0, 0.90f * UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Next Pass"));
+ UI_but_func_set(but, image_multi_incpass_cb, rr, iuser);
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
}
// XXX HACK!
@@ -640,8 +641,6 @@ static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *userptr, int compact)
{
-#define MAX_INFO_LEN 128
-
PropertyRNA *prop;
PointerRNA imaptr;
RNAUpdateCb *cb;
@@ -650,7 +649,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
Scene *scene = CTX_data_scene(C);
uiLayout *row, *split, *col;
uiBlock *block;
- char str[MAX_INFO_LEN];
+ char str[MAX_IMAGE_INFO_LEN];
void *lock;
@@ -687,14 +686,14 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
uiLayoutSetContextPointer(layout, "edit_image_user", userptr);
if (!compact)
- uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL);
+ uiTemplateID(layout, C, ptr, propname, ima ? NULL : "IMAGE_OT_new", "IMAGE_OT_open", NULL);
if (ima) {
- uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL);
+ UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL);
if (ima->source == IMA_SRC_VIEWER) {
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
- image_info(scene, iuser, ima, ibuf, str, MAX_INFO_LEN);
+ image_info(scene, iuser, ima, ibuf, str, MAX_IMAGE_INFO_LEN);
BKE_image_release_ibuf(ima, ibuf, lock);
uiItemL(layout, ima->id.name + 2, ICON_NONE);
@@ -705,18 +704,18 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
#if 0
iuser = ntree_get_active_iuser(scene->nodetree);
if (iuser) {
- uiBlockBeginAlign(block);
- uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10, 120, 100, 20, 0, 0, 0, 0, 0, "");
- uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110, 120, 100, 20, 0, 0, 0, 0, 0, "");
- but = uiDefBut(block, BUT, B_NOP, "Free Cache", 210, 120, 100, 20, 0, 0, 0, 0, 0, "");
- uiButSetFunc(but, image_freecache_cb, ima, NULL);
+ UI_block_align_begin(block);
+ uiDefIconTextBut(block, UI_BTYPE_BUT, B_SIMA_RECORD, ICON_REC, "Record", 10, 120, 100, 20, 0, 0, 0, 0, 0, "");
+ uiDefIconTextBut(block, UI_BTYPE_BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110, 120, 100, 20, 0, 0, 0, 0, 0, "");
+ but = uiDefBut(block, UI_BTYPE_BUT, B_NOP, "Free Cache", 210, 120, 100, 20, 0, 0, 0, 0, 0, "");
+ UI_but_func_set(but, image_freecache_cb, ima, NULL);
if (iuser->frames)
BLI_snprintf(str, sizeof(str), "(%d) Frames:", iuser->framenr);
else strcpy(str, "Frames:");
- uiBlockBeginAlign(block);
- uiDefButI(block, NUM, imagechanged, str, 10, 90, 150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Number of images of a movie to use");
- uiDefButI(block, NUM, imagechanged, "StartFr:", 160, 90, 150, 20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Global starting frame of the movie");
+ UI_block_align_begin(block);
+ uiDefButI(block, UI_BTYPE_NUM, imagechanged, str, 10, 90, 150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Number of images of a movie to use");
+ uiDefButI(block, UI_BTYPE_NUM, imagechanged, "StartFr:", 160, 90, 150, 20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Global starting frame of the movie");
}
#endif
}
@@ -763,10 +762,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
}
else if (ima->source != IMA_SRC_GENERATED) {
if (compact == 0) {
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
- image_info(scene, iuser, ima, ibuf, str, MAX_INFO_LEN);
- BKE_image_release_ibuf(ima, ibuf, lock);
- uiItemL(layout, str, ICON_NONE);
+ uiTemplateImageInfo(layout, C, ima, iuser);
}
}
@@ -780,7 +776,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
bool has_alpha = true;
if (ibuf) {
- int imtype = BKE_ftype_to_imtype(ibuf->ftype);
+ int imtype = BKE_image_ftype_to_imtype(ibuf->ftype);
char valid_channels = BKE_imtype_valid_channels(imtype, false);
has_alpha = (valid_channels & IMA_CHAN_FLAG_ALPHA) != 0;
@@ -791,7 +787,14 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (has_alpha) {
col = uiLayoutColumn(layout, false);
uiItemR(col, &imaptr, "use_alpha", 0, NULL, ICON_NONE);
- uiItemR(col, &imaptr, "alpha_mode", 0, IFACE_("Alpha"), ICON_NONE);
+ row = uiLayoutRow(col, false);
+ uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_alpha"));
+ uiItemR(row, &imaptr, "alpha_mode", 0, IFACE_("Alpha"), ICON_NONE);
+ }
+
+ if (ima->source == IMA_SRC_MOVIE) {
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, &imaptr, "use_deinterlace", 0, IFACE_("Deinterlace"), ICON_NONE);
}
uiItemS(layout);
@@ -852,12 +855,10 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
}
- uiBlockSetNFunc(block, NULL, NULL, NULL);
+ UI_block_funcN_set(block, NULL, NULL, NULL);
}
MEM_freeN(cb);
-
-#undef MAX_INFO_LEN
}
void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_management)
@@ -977,19 +978,27 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser
}
}
-void image_buttons_register(ARegionType *art)
+void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser)
{
- PanelType *pt;
- const char *category = "Grease Pencil";
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil");
- strcpy(pt->idname, "IMAGE_PT_gpencil");
- strcpy(pt->label, N_("Grease Pencil"));
- strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw_header = ED_gpencil_panel_standard_header;
- pt->draw = ED_gpencil_panel_standard;
- BLI_strncpy(pt->category, category, BLI_strlen_utf8(category));
- BLI_addtail(&art->paneltypes, pt);
+ ImBuf *ibuf;
+ char str[MAX_IMAGE_INFO_LEN];
+ void *lock;
+
+ if (!ima || !iuser)
+ return;
+
+ ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
+
+ image_info(CTX_data_scene(C), iuser, ima, ibuf, str, MAX_IMAGE_INFO_LEN);
+ BKE_image_release_ibuf(ima, ibuf, lock);
+ uiItemL(layout, str, ICON_NONE);
+}
+
+#undef MAX_IMAGE_INFO_LEN
+
+void image_buttons_register(ARegionType *UNUSED(art))
+{
+
}
static int image_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index f41e237beb4..d03f3c157a9 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -68,6 +68,7 @@
#include "ED_gpencil.h"
#include "ED_image.h"
#include "ED_mask.h"
+#include "ED_render.h"
#include "ED_screen.h"
#include "UI_interface.h"
@@ -79,20 +80,29 @@
#include "image_intern.h"
-static void draw_render_info(Scene *scene, Image *ima, ARegion *ar, float zoomx, float zoomy)
+static void draw_render_info(const bContext *C,
+ Scene *scene,
+ Image *ima,
+ ARegion *ar,
+ float zoomx,
+ float zoomy)
{
RenderResult *rr;
Render *re = RE_GetRender(scene->id.name);
RenderData *rd = RE_engine_get_render_data(re);
+ Scene *stats_scene = ED_render_job_get_scene(C);
+ if (stats_scene == NULL) {
+ stats_scene = CTX_data_scene(C);
+ }
- rr = BKE_image_acquire_renderresult(scene, ima);
+ rr = BKE_image_acquire_renderresult(stats_scene, ima);
if (rr && rr->text) {
float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
ED_region_info_draw(ar, rr->text, 1, fill_color);
}
- BKE_image_release_renderresult(scene, ima);
+ BKE_image_release_renderresult(stats_scene, ima);
if (re) {
int total_tiles;
@@ -851,11 +861,16 @@ void draw_image_main(const bContext *C, ARegion *ar)
/* render info */
if (ima && show_render)
- draw_render_info(sima->iuser.scene, ima, ar, zoomx, zoomy);
+ draw_render_info(C, sima->iuser.scene, ima, ar, zoomx, zoomy);
}
-static bool show_image_cache(Image *image, Mask *mask)
+bool ED_space_image_show_cache(SpaceImage *sima)
{
+ Image *image = ED_space_image(sima);
+ Mask *mask = NULL;
+ if (sima->mode == SI_MODE_MASK) {
+ mask = ED_space_image_get_mask(sima);
+ }
if (image == NULL && mask == NULL) {
return false;
}
@@ -873,12 +888,12 @@ void draw_image_cache(const bContext *C, ARegion *ar)
float x, cfra = CFRA, sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
Mask *mask = NULL;
- if (sima->mode == SI_MODE_MASK) {
- mask = ED_space_image_get_mask(sima);
+ if (!ED_space_image_show_cache(sima)) {
+ return;
}
- if (!show_image_cache(image, mask)) {
- return;
+ if (sima->mode == SI_MODE_MASK) {
+ mask = ED_space_image_get_mask(sima);
}
glEnable(GL_BLEND);
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 757059ebc29..8e2c6b97a5b 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -35,6 +35,7 @@
#include "BLI_rect.h"
+#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_image.h"
@@ -290,6 +291,20 @@ void ED_image_point_pos__reverse(SpaceImage *sima, ARegion *ar, const float co[2
r_co[1] = (co[1] * height * zoomy) + (float)sy;
}
+void ED_space_image_scopes_update(const struct bContext *C, struct SpaceImage *sima, struct ImBuf *ibuf, bool use_view_settings)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+
+ /* scope update can be expensive, don't update during paint modes */
+ if (sima->mode == SI_MODE_PAINT)
+ return;
+ if (ob && ((ob->mode & OB_MODE_TEXTURE_PAINT) != 0))
+ return;
+
+ scopes_update(&sima->scopes, ibuf, use_view_settings ? &scene->view_settings : NULL, &scene->display_settings);
+}
+
bool ED_space_image_show_render(SpaceImage *sima)
{
return (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE));
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index df556f94f28..61667b02140 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -92,6 +92,8 @@
#include "PIL_time.h"
+#include "RE_engine.h"
+
#include "image_intern.h"
/******************** view navigation utilities *********************/
@@ -583,7 +585,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
ot->poll = space_image_main_area_poll;
/* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_LOCK_BYPASS;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER | OPTYPE_LOCK_BYPASS;
/* properties */
prop = RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Factor",
@@ -947,7 +949,7 @@ static void image_open_init(bContext *C, wmOperator *op)
op->customdata = iod = MEM_callocN(sizeof(ImageOpenData), __func__);
iod->iuser = CTX_data_pointer_get_type(C, "image_user", &RNA_ImageUser).data;
- uiIDContextProperty(C, &iod->pprop.ptr, &iod->pprop.prop);
+ UI_context_active_but_prop_get_templateID(C, &iod->pprop.ptr, &iod->pprop.prop);
}
static void image_open_cancel(bContext *UNUSED(C), wmOperator *op)
@@ -1024,7 +1026,7 @@ static int image_sequence_get_len(ListBase *frames, int *ofs)
{
ImageFrame *frame;
- BLI_sortlist(frames, image_cmp_frame);
+ BLI_listbase_sort(frames, image_cmp_frame);
frame = frames->first;
if (frame) {
@@ -1052,6 +1054,7 @@ static int image_open_exec(bContext *C, wmOperator *op)
char path[FILE_MAX];
int frame_seq_len = 0;
int frame_ofs = 1;
+ bool exists = false;
const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
@@ -1070,7 +1073,7 @@ static int image_open_exec(bContext *C, wmOperator *op)
errno = 0;
- ima = BKE_image_load_exists(path);
+ ima = BKE_image_load_exists_ex(path, &exists);
if (!ima) {
if (op->customdata) MEM_freeN(op->customdata);
@@ -1084,8 +1087,9 @@ static int image_open_exec(bContext *C, wmOperator *op)
/* only image path after save, never ibuf */
if (is_relative_path) {
- const char *relbase = ID_BLEND_PATH(bmain, &ima->id);
- BLI_path_rel(ima->name, relbase);
+ if (!exists) {
+ BLI_path_rel(ima->name, bmain->name);
+ }
}
/* hook into UI */
@@ -1127,7 +1131,7 @@ static int image_open_exec(bContext *C, wmOperator *op)
}
/* XXX unpackImage frees image buffers */
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
BKE_image_signal(ima, iuser, IMA_SIGNAL_RELOAD);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
@@ -1158,7 +1162,7 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
PropertyRNA *prop;
/* hook into UI */
- uiIDContextProperty(C, &ptr, &prop);
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
if (prop) {
PointerRNA oldptr;
@@ -1203,7 +1207,7 @@ void IMAGE_OT_open(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
}
@@ -1279,7 +1283,7 @@ static int image_replace_exec(bContext *C, wmOperator *op)
sima->image->source = IMA_SRC_FILE;
/* XXX unpackImage frees image buffers */
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
BKE_icon_changed(BKE_icon_getid(&sima->image->id));
BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_RELOAD);
@@ -1322,7 +1326,7 @@ void IMAGE_OT_replace(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
}
@@ -1732,7 +1736,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "save_as_render", 0, "Save As Render", "Apply render part of display transform when saving byte image");
RNA_def_boolean(ot->srna, "copy", 0, "Copy", "Create a new image file without modifying the current image in blender");
- WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_SAVE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_SAVE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
}
@@ -1880,7 +1884,7 @@ static int image_reload_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
/* XXX unpackImage frees image buffers */
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
// XXX other users?
BKE_image_signal(ima, (sima) ? &sima->iuser : NULL, IMA_SIGNAL_RELOAD);
@@ -1958,7 +1962,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
/* hook into UI */
- uiIDContextProperty(C, &ptr, &prop);
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
if (prop) {
/* when creating new ID blocks, use is already 1, but RNA
@@ -2024,7 +2028,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
}
/* XXX, Ton is not a fan of OK buttons but using this function to avoid undo/redo bug while in mesh-editmode, - campbell */
-/* XXX Note: the WM_operator_props_dialog_popup() doesn't work for uiIDContextProperty(), image is not being that way */
+/* XXX Note: the WM_operator_props_dialog_popup() doesn't work for UI_context_active_but_prop_get_templateID(), image is not being that way */
static int image_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* Better for user feedback. */
@@ -2248,15 +2252,15 @@ static int image_pack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (!as_png && (ibuf && (ibuf->userflags & IB_BITMAPDIRTY))) {
- pup = uiPupMenuBegin(C, IFACE_("OK"), ICON_QUESTION);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("OK"), ICON_QUESTION);
+ layout = UI_popup_menu_layout(pup);
uiItemBooleanO(layout, IFACE_("Can't pack edited image from disk, pack as internal PNG?"), ICON_NONE,
op->idname, "as_png", 1);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
BKE_image_release_ibuf(ima, ibuf, NULL);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
BKE_image_release_ibuf(ima, ibuf, NULL);
@@ -2309,7 +2313,7 @@ static int image_unpack_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save");
/* XXX unpackImage frees image buffers */
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
unpackImage(op->reports, ima, method);
@@ -2580,8 +2584,9 @@ static int image_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event
ImageSampleInfo *info;
if (ar->regiontype == RGN_TYPE_WINDOW) {
- if (event->mval[1] <= 16)
+ if (event->mval[1] <= 16 && ED_space_image_show_cache(sima)) {
return OPERATOR_PASS_THROUGH;
+ }
}
if (!ED_space_image_has_buffer(sima))
@@ -3015,8 +3020,10 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event
ARegion *ar = CTX_wm_region(C);
if (ar->regiontype == RGN_TYPE_WINDOW) {
- if (event->mval[1] > 16)
+ SpaceImage *sima = CTX_wm_space_image(C);
+ if (event->mval[1] > 16 || !ED_space_image_show_cache(sima)) {
return OPERATOR_PASS_THROUGH;
+ }
}
RNA_int_set(op->ptr, "frame", frame_from_event(C, event));
@@ -3108,8 +3115,21 @@ static int render_border_exec(bContext *C, wmOperator *op)
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
+ Render *re = RE_GetRender(scene->id.name);
+ RenderData *rd;
rctf border;
+ if (re == NULL) {
+ /* Shouldn't happen, but better be safe close to the release. */
+ return OPERATOR_CANCELLED;
+ }
+
+ rd = RE_engine_get_render_data(re);
+ if ((rd->mode & (R_BORDER | R_CROP)) == (R_BORDER | R_CROP)) {
+ BKE_report(op->reports, RPT_INFO, "Can not set border from a cropped render");
+ return OPERATOR_CANCELLED;
+ }
+
/* get rectangle from operator */
WM_operator_properties_border_to_rctf(op, &border);
UI_view2d_region_to_view_rctf(&ar->v2d, &border, &border);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 9cfd2e645f9..bd3d76bbaba 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -33,6 +33,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_image_types.h"
#include "MEM_guardedalloc.h"
@@ -355,7 +356,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH)
- if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */
+ if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */
return 1;
return 0;
}
@@ -692,7 +693,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
/* put scene context variable in iuser */
if (sima->image && sima->image->type == IMA_TYPE_R_RESULT) {
/* for render result, try to use the currently rendering scene */
- Scene *render_scene = ED_render_job_get_scene(C);
+ Scene *render_scene = ED_render_job_get_current_scene(C);
if (render_scene)
sima->iuser.scene = render_scene;
else
@@ -712,7 +713,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
- draw_uvedit_main(sima, ar, scene, obedit, obact);
+ ED_uvedit_draw_main(sima, ar, scene, obedit, obact);
/* check for mask (delay draw) */
if (ED_space_image_show_uvedit(sima, obedit)) {
@@ -772,12 +773,12 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
NULL, C);
UI_view2d_view_ortho(v2d);
- draw_image_cursor(ar, sima->cursor);
+ ED_image_draw_cursor(ar, sima->cursor);
UI_view2d_view_restore(C);
}
else if (curve) {
UI_view2d_view_ortho(v2d);
- draw_image_cursor(ar, sima->cursor);
+ ED_image_draw_cursor(ar, sima->cursor);
UI_view2d_view_restore(C);
}
@@ -791,18 +792,28 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
#endif
}
-static void image_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn)
+static void image_main_area_listener(bScreen *UNUSED(sc), ScrArea *sa, ARegion *ar, wmNotifier *wmn)
{
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
- if (wmn->action == NA_EDITED)
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED))
+ ED_region_tag_redraw(ar);
+ else if (wmn->data & ND_GPENCIL_EDITMODE)
ED_region_tag_redraw(ar);
break;
case NC_IMAGE:
if (wmn->action == NA_PAINTING)
ED_region_tag_redraw(ar);
break;
+ case NC_MATERIAL:
+ if (wmn->data == ND_SHADING_LINKS) {
+ SpaceImage *sima = sa->spacedata.first;
+
+ if (sima->iuser.scene && (sima->iuser.scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE))
+ ED_region_tag_redraw(ar);
+ }
+ break;
}
}
@@ -851,6 +862,10 @@ static void image_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa)
case NC_NODE:
ED_region_tag_redraw(ar);
break;
+ case NC_GPENCIL:
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED))
+ ED_region_tag_redraw(ar);
+ break;
}
}
@@ -884,9 +899,9 @@ static void image_tools_area_draw(const bContext *C, ARegion *ar)
BKE_histogram_update_sample_line(&sima->sample_line_hist, ibuf, &scene->view_settings, &scene->display_settings);
}
if (sima->image->flag & IMA_VIEW_AS_RENDER)
- scopes_update(&sima->scopes, ibuf, &scene->view_settings, &scene->display_settings);
+ ED_space_image_scopes_update(C, sima, ibuf, true);
else
- scopes_update(&sima->scopes, ibuf, NULL, &scene->display_settings);
+ ED_space_image_scopes_update(C, sima, ibuf, false);
}
}
ED_space_image_release_buffer(sima, ibuf, lock);
@@ -899,7 +914,7 @@ static void image_tools_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa),
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
- if (wmn->data == ND_DATA)
+ if (wmn->data == ND_DATA || ELEM(wmn->action, NA_EDITED, NA_SELECTED))
ED_region_tag_redraw(ar);
break;
case NC_BRUSH:
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index 86af89bd6a9..e2895109b48 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -33,7 +33,6 @@
#include <sys/stat.h>
#include <limits.h>
-#include "BLF_api.h"
#include "BLI_utildefines.h"
@@ -45,8 +44,6 @@
#include "BIF_gl.h"
-#include "ED_datafiles.h"
-#include "ED_types.h"
#include "UI_resources.h"
#include "UI_interface.h"
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 25fa31407ff..240d8baa6f2 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -253,15 +253,15 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
else
BLI_snprintf(title, sizeof(title), IFACE_("Unpack %d Files"), count);
- pup = uiPupMenuBegin(C, title, ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, title, ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
uiItemsEnumO(layout, "FILE_OT_unpack_all", "method");
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
void FILE_OT_unpack_all(wmOperatorType *ot)
@@ -322,15 +322,15 @@ static int unpack_item_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED
uiPopupMenu *pup;
uiLayout *layout;
- pup = uiPupMenuBegin(C, IFACE_("Unpack"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("Unpack"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
uiItemsFullEnumO(layout, op->type->idname, "method", op->ptr->data, WM_OP_EXEC_REGION_WIN, 0);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
void FILE_OT_unpack_item(wmOperatorType *ot)
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 33333e4c992..ebce13389c9 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -155,7 +155,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
MEM_freeN(offsets);
return 1;
}
- else if (y_next - cdc->lheight < cdc->ymin) {
+ else if (y_next < cdc->ymin) {
/* have not reached the drawable area so don't break */
cdc->xy[1] = y_next;
diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c
index 2c521532484..e0cbc1c9539 100644
--- a/source/blender/editors/space_logic/logic_buttons.c
+++ b/source/blender/editors/space_logic/logic_buttons.c
@@ -34,7 +34,6 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
-#include "BKE_screen.h"
#include "ED_screen.h"
@@ -124,12 +123,12 @@ static int cut_links_exec(bContext *C, wmOperator *op)
for (block = ar->uiblocks.first; block; block = block->next) {
but = block->buttons.first;
while (but) {
- if (but->type==LINK && but->link) {
+ if (but->type==UI_BTYPE_LINK && but->link) {
for (line = but->link->lines.first; line; line = nline) {
nline = line->next;
if (cut_links_intersect(line, mcoords, i)) {
- ui_delete_linkline(line, but);
+ ui_linkline_remove(line, but);
}
}
}
diff --git a/source/blender/editors/space_logic/logic_ops.c b/source/blender/editors/space_logic/logic_ops.c
index 62703ba517e..2c6280f5670 100644
--- a/source/blender/editors/space_logic/logic_ops.c
+++ b/source/blender/editors/space_logic/logic_ops.c
@@ -39,6 +39,8 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_sca.h"
@@ -298,7 +300,7 @@ static int sensor_add_exec(bContext *C, wmOperator *op)
BLI_strncpy(sens->name, sens_name, sizeof(sens->name));
}
- make_unique_prop_names(C, sens->name);
+ BLI_uniquename(&ob->sensors, sens, DATA_("Sensor"), '.', offsetof(bSensor, name), sizeof(sens->name));
ob->scaflag |= OB_SHOWSENS;
WM_event_add_notifier(C, NC_LOGIC, NULL);
@@ -405,7 +407,8 @@ static int controller_add_exec(bContext *C, wmOperator *op)
BLI_strncpy(cont->name, cont_name, sizeof(cont->name));
}
- make_unique_prop_names(C, cont->name);
+ BLI_uniquename(&ob->controllers, cont, DATA_("Controller"), '.', offsetof(bController, name), sizeof(cont->name));
+
/* set the controller state mask from the current object state.
* A controller is always in a single state, so select the lowest bit set
* from the object state */
@@ -523,7 +526,7 @@ static int actuator_add_exec(bContext *C, wmOperator *op)
BLI_strncpy(act->name, act_name, sizeof(act->name));
}
- make_unique_prop_names(C, act->name);
+ BLI_uniquename(&ob->actuators, act, DATA_("Actuator"), '.', offsetof(bActuator, name), sizeof(act->name));
ob->scaflag |= OB_SHOWACT;
WM_event_add_notifier(C, NC_LOGIC, NULL);
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index dd152022762..7204144ce85 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -48,6 +48,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_path_util.h"
#include "BKE_action.h"
#include "BKE_context.h"
@@ -94,91 +95,6 @@
/* proto */
static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisflag);
-static int vergname(const void *v1, const void *v2)
-{
- char **x1, **x2;
-
- x1 = (char **)v1;
- x2 = (char **)v2;
-
- return BLI_natstrcmp(*x1, *x2);
-}
-
-void make_unique_prop_names(bContext *C, char *str)
-{
- Object *ob;
- bProperty *prop;
- bSensor *sens;
- bController *cont;
- bActuator *act;
- ID **idar;
- short a, obcount, propcount=0, nr;
- const char **names;
-
- /* this function is called by a Button, and gives the current
- * stringpointer as an argument, this is the one that can change
- */
-
- idar= get_selected_and_linked_obs(C, &obcount, BUTS_SENS_SEL|BUTS_SENS_ACT|BUTS_ACT_SEL|BUTS_ACT_ACT|BUTS_CONT_SEL|BUTS_CONT_ACT);
-
- /* for each object, make properties and sca names unique */
-
- /* count total names */
- for (a=0; a<obcount; a++) {
- ob= (Object *)idar[a];
- propcount+= BLI_countlist(&ob->prop);
- propcount+= BLI_countlist(&ob->sensors);
- propcount+= BLI_countlist(&ob->controllers);
- propcount+= BLI_countlist(&ob->actuators);
- }
- if (propcount==0) {
- if (idar) MEM_freeN(idar);
- return;
- }
-
- /* make names array for sorting */
- names= MEM_callocN(propcount*sizeof(void *), "names");
-
- /* count total names */
- nr= 0;
- for (a=0; a<obcount; a++) {
- ob= (Object *)idar[a];
- prop= ob->prop.first;
- while (prop) {
- names[nr++] = prop->name;
- prop= prop->next;
- }
- sens= ob->sensors.first;
- while (sens) {
- names[nr++] = sens->name;
- sens= sens->next;
- }
- cont= ob->controllers.first;
- while (cont) {
- names[nr++] = cont->name;
- cont= cont->next;
- }
- act= ob->actuators.first;
- while (act) {
- names[nr++] = act->name;
- act= act->next;
- }
- }
-
- qsort(names, propcount, sizeof(void *), vergname);
-
- /* now we check for double names, and change them */
-
- for (nr=0; nr<propcount; nr++) {
- if (names[nr]!=str && strcmp( names[nr], str )==0 ) {
- BLI_newname(str, +1);
- }
- }
-
- MEM_freeN(idar);
- MEM_freeN(names);
-}
-
static void do_logic_buts(bContext *C, void *UNUSED(arg), int event)
{
Main *bmain= CTX_data_main(C);
@@ -210,7 +126,7 @@ static void do_logic_buts(bContext *C, void *UNUSED(arg), int event)
ob->scaflag &= ~OB_ADDSENS;
sens= new_sensor(SENS_ALWAYS);
BLI_addtail(&(ob->sensors), sens);
- make_unique_prop_names(C, sens->name);
+ BLI_uniquename(&ob->sensors, sens, DATA_("Sensor"), '.', offsetof(bSensor, name), sizeof(sens->name));
ob->scaflag |= OB_SHOWSENS;
}
}
@@ -252,7 +168,7 @@ static void do_logic_buts(bContext *C, void *UNUSED(arg), int event)
if (ob->scaflag & OB_ADDCONT) {
ob->scaflag &= ~OB_ADDCONT;
cont= new_controller(CONT_LOGIC_AND);
- make_unique_prop_names(C, cont->name);
+ BLI_uniquename(&ob->controllers, cont, DATA_("Controller"), '.', offsetof(bController, name), sizeof(cont->name));
ob->scaflag |= OB_SHOWCONT;
BLI_addtail(&(ob->controllers), cont);
/* set the controller state mask from the current object state.
@@ -328,7 +244,7 @@ static void do_logic_buts(bContext *C, void *UNUSED(arg), int event)
if (ob->scaflag & OB_ADDACT) {
ob->scaflag &= ~OB_ADDACT;
act= new_actuator(ACT_OBJECT);
- make_unique_prop_names(C, act->name);
+ BLI_uniquename(&ob->actuators, act, DATA_("Actuator"), '.', offsetof(bActuator, name), sizeof(act->name));
BLI_addtail(&(ob->actuators), act);
ob->scaflag |= OB_SHOWACT;
}
@@ -761,17 +677,17 @@ static uiBlock *sensor_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
uiBlock *block;
int yco=0;
- block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP);
- uiBlockSetButmFunc(block, do_sensor_menu, NULL);
+ block= UI_block_begin(C, ar, __func__, UI_EMBOSS_PULLDOWN);
+ UI_block_func_butmenu_set(block, do_sensor_menu, NULL);
- uiDefBut(block, BUTM, 1, IFACE_("Show Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, 1, IFACE_("Hide Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefBut(block, SEPRLINE, 0, "", 0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefBut(block, BUTM, 1, IFACE_("Show Sensors"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefBut(block, BUTM, 1, IFACE_("Hide Sensors"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefBut(block, UI_BTYPE_SEPR_LINE, 0, "", 0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Sensors"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Sensors"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
- uiBlockSetDirection(block, UI_TOP);
- uiEndBlock(C, block);
+ UI_block_direction_set(block, UI_DIR_UP);
+ UI_block_end(C, block);
return block;
}
@@ -810,17 +726,17 @@ static uiBlock *controller_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
uiBlock *block;
int yco=0;
- block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP);
- uiBlockSetButmFunc(block, do_controller_menu, NULL);
+ block= UI_block_begin(C, ar, __func__, UI_EMBOSS_PULLDOWN);
+ UI_block_func_butmenu_set(block, do_controller_menu, NULL);
- uiDefBut(block, BUTM, 1, IFACE_("Show Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, 1, IFACE_("Hide Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefBut(block, SEPRLINE, 0, "", 0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefBut(block, BUTM, 1, IFACE_("Show Controllers"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 2, 2, "");
- uiDefBut(block, BUTM, 1, IFACE_("Hide Controllers"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 3, 3, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Objects"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefBut(block, UI_BTYPE_SEPR_LINE, 0, "", 0, (short)(yco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Controllers"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 2, 2, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Controllers"), 0, (short)(yco-=20), 160, 19, NULL, 0.0, 0.0, 3, 3, "");
- uiBlockSetDirection(block, UI_TOP);
- uiEndBlock(C, block);
+ UI_block_direction_set(block, UI_DIR_UP);
+ UI_block_end(C, block);
return block;
}
@@ -859,17 +775,17 @@ static uiBlock *actuator_menu(bContext *C, ARegion *ar, void *UNUSED(arg))
uiBlock *block;
int xco=0;
- block= uiBeginBlock(C, ar, __func__, UI_EMBOSSP);
- uiBlockSetButmFunc(block, do_actuator_menu, NULL);
+ block= UI_block_begin(C, ar, __func__, UI_EMBOSS_PULLDOWN);
+ UI_block_func_butmenu_set(block, do_actuator_menu, NULL);
- uiDefBut(block, BUTM, 1, IFACE_("Show Objects"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
- uiDefBut(block, BUTM, 1, IFACE_("Hide Objects"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefBut(block, SEPRLINE, 0, "", 0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefBut(block, BUTM, 1, IFACE_("Show Actuators"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefBut(block, BUTM, 1, IFACE_("Hide Actuators"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Objects"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Objects"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefBut(block, UI_BTYPE_SEPR_LINE, 0, "", 0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Show Actuators"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefBut(block, UI_BTYPE_BUT_MENU, 1, IFACE_("Hide Actuators"), 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 3, "");
- uiBlockSetDirection(block, UI_TOP);
- uiEndBlock(C, block);
+ UI_block_direction_set(block, UI_DIR_UP);
+ UI_block_end(C, block);
return block;
}
@@ -892,26 +808,26 @@ static uiBlock *controller_state_mask_menu(bContext *C, ARegion *ar, void *arg_c
short yco = 12, xco = 0, stbit, offset;
- block= uiBeginBlock(C, ar, __func__, UI_EMBOSS);
+ block= UI_block_begin(C, ar, __func__, UI_EMBOSS);
/* use this for a fake extra empy space around the buttons */
- uiDefBut(block, LABEL, 0, "", -5, -5, 200, 34, NULL, 0, 0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", -5, -5, 200, 34, NULL, 0, 0, 0, 0, "");
for (offset=0; offset<15; offset += 5) {
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
for (stbit=0; stbit<5; stbit++) {
- but = uiDefButBitI(block, TOG, (1<<(stbit+offset)), (stbit+offset), "", (short)(xco+12*stbit+13*offset), yco, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
- uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
+ but = uiDefButBitI(block, UI_BTYPE_TOGGLE, (1<<(stbit+offset)), (stbit+offset), "", (short)(xco+12*stbit+13*offset), yco, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
+ UI_but_func_set(but, check_controller_state_mask, but, &(cont->state_mask));
}
for (stbit=0; stbit<5; stbit++) {
- but = uiDefButBitI(block, TOG, (1<<(stbit+offset+15)), (stbit+offset+15), "", (short)(xco+12*stbit+13*offset), yco-12, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
- uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
+ but = uiDefButBitI(block, UI_BTYPE_TOGGLE, (1<<(stbit+offset+15)), (stbit+offset+15), "", (short)(xco+12*stbit+13*offset), yco-12, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
+ UI_but_func_set(but, check_controller_state_mask, but, &(cont->state_mask));
}
}
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
- uiBlockSetDirection(block, UI_TOP);
- uiEndBlock(C, block);
+ UI_block_direction_set(block, UI_DIR_UP);
+ UI_block_end(C, block);
return block;
}
@@ -923,7 +839,7 @@ static bool is_sensor_linked(uiBlock *block, bSensor *sens)
for (i=0; i<sens->totlinks; i++) {
cont = sens->links[i];
- if (uiFindInlink(block, cont) != NULL)
+ if (UI_block_links_find_inlink(block, cont) != NULL)
return 1;
}
return 0;
@@ -2189,12 +2105,15 @@ static void draw_actuator_steering(uiLayout *layout, PointerRNA *ptr)
}
row = uiLayoutRow(layout, false);
- uiItemR(row, ptr, "self_terminated", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(row, false);
+ uiItemR(col, ptr, "self_terminated", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "mode")==ACT_STEERING_PATHFOLLOWING) {
- uiItemR(row, ptr, "update_period", 0, NULL, ICON_NONE);
- row = uiLayoutRow(layout, false);
+ col = uiLayoutColumn(row, false);
+ uiItemR(col, ptr, "update_period", 0, NULL, ICON_NONE);
}
row = uiLayoutRow(layout, false);
+ uiItemR(row, ptr, "lock_z_velocity", 1, NULL, ICON_NONE);
+ row = uiLayoutRow(layout, false);
uiItemR(row, ptr, "show_visualization", 0, NULL, ICON_NONE);
if (RNA_enum_get(ptr, "mode") != ACT_STEERING_PATHFOLLOWING) {
uiLayoutSetActive(row, false);
@@ -2353,9 +2272,9 @@ void logic_buttons(bContext *C, ARegion *ar)
idar= get_selected_and_linked_obs(C, &count, slogic->scaflag);
BLI_snprintf(uiblockstr, sizeof(uiblockstr), "buttonswin %p", (void *)ar);
- block= uiBeginBlock(C, ar, uiblockstr, UI_EMBOSS);
- uiBlockSetHandleFunc(block, do_logic_buts, NULL);
- uiBoundsBlock(block, U.widget_unit/2);
+ block= UI_block_begin(C, ar, uiblockstr, UI_EMBOSS);
+ UI_block_func_handle_set(block, do_logic_buts, NULL);
+ UI_block_bounds_set_normal(block, U.widget_unit/2);
/* loop over all objects and set visible/linked flags for the logic bricks */
for (a=0; a<count; a++) {
@@ -2401,7 +2320,7 @@ void logic_buttons(bContext *C, ARegion *ar)
/* ****************** Controllers ****************** */
xco= 21 * U.widget_unit; yco= - U.widget_unit / 2; width= 15 * U.widget_unit;
- layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle());
+ layout= UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_style_get());
row = uiLayoutRow(layout, true);
uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco - U.widget_unit / 2, yco, width, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
@@ -2431,7 +2350,7 @@ void logic_buttons(bContext *C, ARegion *ar)
uiItemR(split, &settings_ptr, "show_state_panel", UI_ITEM_R_NO_BG, "", ICON_DISCLOSURE_TRI_RIGHT);
row = uiLayoutRow(split, true);
- uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers"));
+ uiDefButBitS(block, UI_BTYPE_TOGGLE, OB_SHOWCONT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
uiLayoutSetContextPointer(row, "object", &object_ptr);
@@ -2479,9 +2398,9 @@ void logic_buttons(bContext *C, ARegion *ar)
col = uiLayoutColumn(split, false);
uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT);
- but = uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
+ but = uiDefIconBut(block, UI_BTYPE_INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, cont, LINK_CONTROLLER, 0, 0, 0, "");
if (!RNA_boolean_get(&ptr, "active")) {
- uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
+ UI_but_flag_enable(but, UI_BUT_SCA_LINK_GREY);
}
//col = uiLayoutColumn(split, true);
@@ -2502,22 +2421,22 @@ void logic_buttons(bContext *C, ARegion *ar)
col = uiLayoutColumn(subsplit, false);
uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_LEFT);
- but = uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ but = uiDefIconBut(block, UI_BTYPE_LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
if (!RNA_boolean_get(&ptr, "active")) {
- uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
+ UI_but_flag_enable(but, UI_BUT_SCA_LINK_GREY);
}
- uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
+ UI_but_link_set(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
}
}
- uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */
+ UI_block_layout_resolve(block, NULL, &yco); /* stores final height in yco */
height = yco;
/* ****************** Sensors ****************** */
xco= U.widget_unit / 2; yco= -U.widget_unit / 2; width= 17 * U.widget_unit;
- layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle());
+ layout= UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_style_get());
row = uiLayoutRow(layout, true);
uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
@@ -2537,7 +2456,7 @@ void logic_buttons(bContext *C, ARegion *ar)
if ((ob->scavisflag & OB_VIS_SENS) == 0) continue;
row = uiLayoutRow(layout, true);
- uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors"));
+ uiDefButBitS(block, UI_BTYPE_TOGGLE, OB_SHOWSENS, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
uiLayoutSetContextPointer(row, "object", &object_ptr);
@@ -2575,23 +2494,23 @@ void logic_buttons(bContext *C, ARegion *ar)
/* put link button to the right */
col = uiLayoutColumn(split, false);
uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
- but = uiDefIconBut(block, LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ but = uiDefIconBut(block, UI_BTYPE_LINK, 0, ICON_LINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
if (!RNA_boolean_get(&ptr, "active")) {
- uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
+ UI_but_flag_enable(but, UI_BUT_SCA_LINK_GREY);
}
/* use old-school uiButtons for links for now */
- uiSetButLink(but, NULL, (void ***)&sens->links, &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
+ UI_but_link_set(but, NULL, (void ***)&sens->links, &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
}
}
}
- uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */
+ UI_block_layout_resolve(block, NULL, &yco); /* stores final height in yco */
height = MIN2(height, yco);
/* ****************** Actuators ****************** */
xco= 40 * U.widget_unit; yco= -U.widget_unit / 2; width= 17 * U.widget_unit;
- layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_GetStyle());
+ layout= UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, 0, UI_style_get());
row = uiLayoutRow(layout, true);
uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */
@@ -2613,7 +2532,7 @@ void logic_buttons(bContext *C, ARegion *ar)
}
row = uiLayoutRow(layout, true);
- uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators"));
+ uiDefButBitS(block, UI_BTYPE_TOGGLE, OB_SHOWACT, B_REDR, ob->id.name + 2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators"));
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr);
uiLayoutSetContextPointer(row, "object", &object_ptr);
@@ -2644,9 +2563,9 @@ void logic_buttons(bContext *C, ARegion *ar)
/* put inlink button to the left */
col = uiLayoutColumn(split, false);
uiLayoutSetActive(col, RNA_boolean_get(&ptr, "active"));
- but = uiDefIconBut(block, INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
+ but = uiDefIconBut(block, UI_BTYPE_INLINK, 0, ICON_INLINK, 0, 0, UI_UNIT_X, UI_UNIT_Y, act, LINK_ACTUATOR, 0, 0, 0, "");
if (!RNA_boolean_get(&ptr, "active")) {
- uiButSetFlag(but, UI_BUT_SCA_LINK_GREY);
+ UI_but_flag_enable(but, UI_BUT_SCA_LINK_GREY);
}
col = uiLayoutColumn(split, true);
@@ -2661,7 +2580,7 @@ void logic_buttons(bContext *C, ARegion *ar)
}
}
}
- uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */
+ UI_block_layout_resolve(block, NULL, &yco); /* stores final height in yco */
height = MIN2(height, yco);
UI_view2d_totRect_set(&ar->v2d, 57.5f * U.widget_unit, height - U.widget_unit);
@@ -2669,10 +2588,10 @@ void logic_buttons(bContext *C, ARegion *ar)
/* set the view */
UI_view2d_view_ortho(&ar->v2d);
- uiComposeLinks(block);
+ UI_block_links_compose(block);
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
/* restore view matrix */
UI_view2d_view_restore(C);
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 1090106d79f..66023ce1243 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -143,6 +143,7 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p
case ANIMTYPE_DSLAT:
case ANIMTYPE_DSLINESTYLE:
case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
{
/* for these channels, we only do AnimData */
if (ale->adt && adt_ptr) {
@@ -254,7 +255,7 @@ static void nla_panel_animdata(const bContext *C, Panel *pa)
/* adt = adt_ptr.data; */
block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
+ UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
/* AnimData Source Properties ----------------------------------- */
@@ -309,7 +310,7 @@ static void nla_panel_track(const bContext *C, Panel *pa)
return;
block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
+ UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
/* Info - Active NLA-Context:Track ---------------------- */
row = uiLayoutRow(layout, true);
@@ -329,7 +330,7 @@ static void nla_panel_properties(const bContext *C, Panel *pa)
return;
block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
+ UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
/* Strip Properties ------------------------------------- */
/* strip type */
@@ -394,7 +395,7 @@ static void nla_panel_actclip(const bContext *C, Panel *pa)
return;
block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
+ UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
/* Strip Properties ------------------------------------- */
/* action pointer */
@@ -434,7 +435,7 @@ static void nla_panel_evaluation(const bContext *C, Panel *pa)
return;
block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
+ UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
col = uiLayoutColumn(layout, true);
uiItemR(col, &strip_ptr, "use_animated_influence", 0, NULL, ICON_NONE);
@@ -468,7 +469,7 @@ static void nla_panel_modifiers(const bContext *C, Panel *pa)
strip = strip_ptr.data;
block = uiLayoutGetBlock(pa->layout);
- uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
+ UI_block_func_handle_set(block, do_nla_region_buttons, NULL);
/* 'add modifier' button at top of panel */
{
@@ -477,7 +478,7 @@ static void nla_panel_modifiers(const bContext *C, Panel *pa)
// XXX for now, this will be a operator button which calls a temporary 'add modifier' operator
// FIXME: we need to set the only-active property so that this will only add modifiers for the active strip (not all selected)
- uiDefButO(block, BUT, "NLA_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), 10, 0, 150, 20,
+ uiDefButO(block, UI_BTYPE_BUT, "NLA_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), 10, 0, 150, 20,
TIP_("Adds a new F-Modifier for the active NLA Strip"));
/* copy/paste (as sub-row)*/
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index fbb4d273626..5476d1c2683 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -182,6 +182,7 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
case ANIMTYPE_DSLAT:
case ANIMTYPE_DSLINESTYLE:
case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
{
/* sanity checking... */
if (ale->adt) {
@@ -649,7 +650,7 @@ static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
/* get a list of the AnimData blocks being shown in the NLA */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
/* delete tracks */
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index ac8dca6e83a..aae0e38696c 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -59,7 +59,6 @@
#include "WM_types.h"
#include "UI_interface.h"
-#include "UI_interface_icons.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -341,9 +340,9 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
if (nonSolo == 0) {
/* strip is in normal track */
glColor3fv(color);
- uiSetRoundBox(UI_CNR_ALL); /* all corners rounded */
+ UI_draw_roundbox_corner_set(UI_CNR_ALL); /* all corners rounded */
- uiDrawBoxShade(GL_POLYGON, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1);
+ UI_draw_roundbox_shade_x(GL_POLYGON, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1);
}
else {
/* strip is in disabled track - make less visible */
@@ -375,11 +374,11 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
}
/* - line style: dotted for muted */
- if (strip->flag & NLASTRIP_FLAG_MUTED)
+ if ((nlt->flag & NLATRACK_MUTED) || (strip->flag & NLASTRIP_FLAG_MUTED))
setlinestyle(4);
/* draw outline */
- uiDrawBoxShade(GL_LINE_LOOP, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1);
+ UI_draw_roundbox_shade_x(GL_LINE_LOOP, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1);
/* if action-clip strip, draw lines delimiting repeats too (in the same color as outline) */
if ((strip->type == NLASTRIP_TYPE_CLIP) && IS_EQF(strip->repeat, 1.0f) == 0) {
@@ -619,7 +618,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
/* *********************************************** */
/* Channel List */
-void draw_nla_channel_list(bContext *C, bAnimContext *ac, ARegion *ar)
+void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
@@ -670,7 +669,7 @@ void draw_nla_channel_list(bContext *C, bAnimContext *ac, ARegion *ar)
}
}
{ /* second pass: UI widgets */
- uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
+ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
size_t channel_index = 0;
y = (float)(-NLACHANNEL_HEIGHT(snla));
@@ -697,8 +696,8 @@ void draw_nla_channel_list(bContext *C, bAnimContext *ac, ARegion *ar)
channel_index++;
}
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
glDisable(GL_BLEND);
}
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index c787177a62a..a883f350f1c 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -1372,11 +1372,15 @@ static int nlaedit_toggle_mute_exec(bContext *C, wmOperator *UNUSED(op))
/* just flip the mute flag for now */
// TODO: have a pre-pass to check if mute all or unmute all?
strip->flag ^= NLASTRIP_FLAG_MUTED;
+
+ /* tag AnimData to get recalculated */
+ ale->update |= ANIM_UPDATE_DEPS;
}
}
}
- /* free temp data */
+ /* cleanup */
+ ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
/* set notifier that things have changed */
@@ -1436,7 +1440,9 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op)
if (BLI_listbase_is_empty(&nlt->strips) == false) {
NlaStrip *mstrip = (NlaStrip *)nlt->strips.first;
- if ((mstrip->flag & NLASTRIP_FLAG_TEMP_META) && (BLI_countlist(&mstrip->strips) == 2)) {
+ if ((mstrip->flag & NLASTRIP_FLAG_TEMP_META) &&
+ (BLI_listbase_count_ex(&mstrip->strips, 3) == 2))
+ {
/* remove this temp meta, so that we can see the strips inside */
BKE_nlastrips_clear_metas(&nlt->strips, 0, 1);
}
@@ -2128,9 +2134,13 @@ static int nlaedit_snap_exec(bContext *C, wmOperator *op)
/* remove the meta-strips now that we're done */
BKE_nlastrips_clear_metas(&nlt->strips, 0, 1);
+
+ /* tag for recalculating the animation */
+ ale->update |= ANIM_UPDATE_DEPS;
}
- /* free temp data */
+ /* cleanup */
+ ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
/* refresh auto strip properties */
@@ -2174,8 +2184,8 @@ static int nla_fmodifier_add_invoke(bContext *C, wmOperator *UNUSED(op), const w
uiLayout *layout;
int i;
- pup = uiPupMenuBegin(C, IFACE_("Add F-Modifier"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("Add F-Modifier"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
/* start from 1 to skip the 'Invalid' modifier type */
for (i = 1; i < FMODIFIER_NUM_TYPES; i++) {
@@ -2192,9 +2202,9 @@ static int nla_fmodifier_add_invoke(bContext *C, wmOperator *UNUSED(op), const w
}
uiItemS(layout);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
static int nla_fmodifier_add_exec(bContext *C, wmOperator *op)
@@ -2244,6 +2254,7 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op)
if (fcm) {
set_active_fmodifier(&strip->modifiers, fcm);
+ ale->update |= ANIM_UPDATE_DEPS;
}
else {
BKE_reportf(op->reports, RPT_ERROR,
@@ -2254,6 +2265,7 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op)
}
/* free temp data */
+ ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
/* set notifier that things have changed */
@@ -2319,6 +2331,9 @@ static int nla_fmodifier_copy_exec(bContext *C, wmOperator *op)
}
}
+ /* free temp data */
+ ANIM_animdata_freelist(&anim_data);
+
/* successful or not? */
if (ok == 0) {
BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied");
@@ -2373,10 +2388,12 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op)
for (strip = nlt->strips.first; strip; strip = strip->next) {
// TODO: do we want to replace existing modifiers? add user pref for that!
ok += ANIM_fmodifiers_paste_from_buf(&strip->modifiers, 0);
+ ale->update |= ANIM_UPDATE_DEPS;
}
}
/* clean up */
+ ANIM_animdata_update(&ac, &anim_data);
ANIM_animdata_freelist(&anim_data);
/* successful or not? */
diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h
index 766ae28da6f..bd96b5a4de5 100644
--- a/source/blender/editors/space_nla/nla_intern.h
+++ b/source/blender/editors/space_nla/nla_intern.h
@@ -50,7 +50,7 @@ void NLA_OT_properties(wmOperatorType *ot);
/* nla_draw.c */
void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar);
-void draw_nla_channel_list(bContext *C, bAnimContext *ac, ARegion *ar);
+void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar);
/* **************************************** */
/* nla_select.c */
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 5e1381db696..b3a875047db 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -28,15 +28,11 @@
* \ingroup spnla
*/
-
#include <string.h>
#include <stdio.h>
#include "DNA_scene_types.h"
-
-#include "BLI_blenlib.h"
-
#include "BKE_context.h"
#include "BKE_screen.h"
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 134e5dd80a2..ec584525aeb 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -180,7 +180,7 @@ static void nla_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
{
SpaceNla *snla = (SpaceNla *)sa->spacedata.first;
- /* init dopesheet data if non-existant (i.e. for old files) */
+ /* init dopesheet data if non-existent (i.e. for old files) */
if (snla->ads == NULL) {
snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
snla->ads->source = (ID *)G.main->scene.first; // XXX this is bad, but we need this to be set correct
@@ -236,7 +236,7 @@ static void nla_channel_area_draw(const bContext *C, ARegion *ar)
/* data */
if (ANIM_animdata_get_context(C, &ac)) {
- draw_nla_channel_list((bContext *)C, &ac, ar);
+ draw_nla_channel_list(C, &ac, ar);
}
/* reset view matrix */
@@ -305,7 +305,7 @@ static void nla_main_area_draw(const bContext *C, ARegion *ar)
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
- draw_markers_time(C, 0);
+ ED_markers_draw(C, DRAW_MARKERS_MARGIN);
/* preview range */
UI_view2d_view_ortho(v2d);
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index ffc82128181..6fa164a483f 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -38,6 +38,7 @@
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
+#include "DNA_text_types.h"
#include "BKE_context.h"
#include "BKE_curve.h"
@@ -54,7 +55,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
#include "ED_node.h"
@@ -64,7 +64,6 @@
#include "UI_resources.h"
#include "IMB_colormanagement.h"
-#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "node_intern.h" /* own include */
@@ -382,7 +381,7 @@ static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree,
static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float aspect)
{
/* XXX font id is crap design */
- const int fontid = UI_GetStyle()->widgetlabel.uifont_id;
+ const int fontid = UI_style_get()->widgetlabel.uifont_id;
NodeFrame *data = (NodeFrame *)node->storage;
rctf *rct = &node->totr;
int color_id = node_get_colorid(node);
@@ -391,6 +390,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp
float width, ascender;
float x, y;
const int font_size = data->label_size / aspect;
+ const float margin = (float)(NODE_DY / 4);
nodeLabel(ntree, node, label, sizeof(label));
@@ -406,11 +406,42 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp
/* 'x' doesn't need aspect correction */
x = BLI_rctf_cent_x(rct) - (0.5f * width);
- y = rct->ymax - (((NODE_DY / 4) / aspect) + (ascender * aspect));
+ y = rct->ymax - ((margin / aspect) + (ascender * aspect));
BLF_position(fontid, x, y, 0);
BLF_draw(fontid, label, BLF_DRAW_STR_DUMMY_MAX);
+ /* draw text body */
+ if (node->id) {
+ Text *text = (Text *)node->id;
+ TextLine *line;
+ const float line_spacing = (BLF_height_max(fontid) * aspect) * 0.7f;
+
+ /* 'x' doesn't need aspect correction */
+ x = rct->xmin + margin;
+ y = rct->ymax - ((margin / aspect) + (ascender * aspect));
+ y -= line_spacing;
+
+ BLF_enable(fontid, BLF_CLIPPING);
+ BLF_clipping(
+ fontid,
+ rct->xmin,
+ rct->ymin,
+ rct->xmin + ((rct->xmax - rct->xmin) / aspect) - margin,
+ rct->ymax);
+
+ for (line = text->lines.first; line; line = line->next) {
+ BLF_position(fontid, x, y, 0);
+ BLF_draw(fontid, line->line, line->len);
+ y -= line_spacing;
+ if (y < rct->ymin) {
+ break;
+ }
+ }
+
+ BLF_disable(fontid, BLF_CLIPPING);
+ }
+
BLF_disable(fontid, BLF_ASPECT);
}
@@ -424,7 +455,7 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
/* skip if out of view */
if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == false) {
- uiEndBlock(C, node->block);
+ UI_block_end(C, node->block);
node->block = NULL;
return;
}
@@ -441,8 +472,8 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
else
UI_ThemeColor4(TH_NODE_FRAME);
glEnable(GL_BLEND);
- uiSetRoundBox(UI_CNR_ALL);
- uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
glDisable(GL_BLEND);
/* outline active and selected emphasis */
@@ -454,8 +485,8 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
else
UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_LINE_LOOP,
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_gl_mode(GL_LINE_LOOP,
rct->xmin, rct->ymin,
rct->xmax, rct->ymax, BASIS_RAD);
@@ -468,8 +499,8 @@ static void node_draw_frame(const bContext *C, ARegion *ar, SpaceNode *snode,
UI_ThemeClearColor(color_id);
- uiEndBlock(C, node->block);
- uiDrawBlock(C, node->block);
+ UI_block_end(C, node->block);
+ UI_block_draw(C, node->block);
node->block = NULL;
}
@@ -500,6 +531,7 @@ static void node_buts_frame_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA
{
uiItemR(layout, ptr, "label_size", 0, IFACE_("Label Size"), ICON_NONE);
uiItemR(layout, ptr, "shrink", 0, IFACE_("Shrink"), ICON_NONE);
+ uiItemR(layout, ptr, "text", 0, NULL, ICON_NONE);
}
@@ -546,7 +578,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
if (node->totr.xmax < ar->v2d.cur.xmin || node->totr.xmin > ar->v2d.cur.xmax ||
node->totr.ymax < ar->v2d.cur.ymin || node->totr.ymin > ar->v2d.cur.ymax)
{
- uiEndBlock(C, node->block);
+ UI_block_end(C, node->block);
node->block = NULL;
return;
}
@@ -556,10 +588,10 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
*/
#if 0
/* body */
- uiSetRoundBox(UI_CNR_ALL);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_ThemeColor4(TH_NODE);
glEnable(GL_BLEND);
- uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
+ UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
glDisable(GL_BLEND);
/* outline active and selected emphasis */
@@ -571,7 +603,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, -40);
else
UI_ThemeColorShadeAlpha(TH_TEXT_HI, -20, -120);
- uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
+ UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
@@ -581,7 +613,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
if (node->label[0] != '\0') {
/* draw title (node label) */
BLI_strncpy(showname, node->label, sizeof(showname));
- uiDefBut(node->block, LABEL, 0, showname,
+ uiDefBut(node->block, UI_BTYPE_LABEL, 0, showname,
(int)(rct->xmin - NODE_DYS), (int)(rct->ymax),
(short)512, (short)NODE_DY,
NULL, 0, 0, 0, 0, NULL);
@@ -594,8 +626,8 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED(
node_socket_circle_draw(C, ntree, node, sock, socket_size, (sock->flag & SELECT) || (node->flag & SELECT));
}
- uiEndBlock(C, node->block);
- uiDrawBlock(C, node->block);
+ UI_block_end(C, node->block);
+ UI_block_draw(C, node->block);
node->block = NULL;
}
@@ -671,10 +703,10 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr,
uiItemR(col, ptr, "use_auto_refresh", 0, NULL, ICON_NONE);
}
- col = uiLayoutColumn(layout, false);
-
- if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER)
+ if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER) {
+ col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE);
+ }
}
static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -781,8 +813,8 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA
uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
- uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
uiItemR(layout, ptr, "interpolation", 0, "", ICON_NONE);
+ uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
if (RNA_enum_get(ptr, "projection") == SHD_PROJ_BOX) {
uiItemR(layout, ptr, "projection_blend", 0, "Blend", ICON_NONE);
@@ -807,10 +839,51 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin
uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL);
+
+ node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr);
+
uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE);
uiItemR(layout, ptr, "projection", 0, "", ICON_NONE);
+}
- node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr);
+static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
+{
+ PointerRNA imaptr = RNA_pointer_get(ptr, "image");
+ PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user");
+ Image *ima = imaptr.data;
+
+ uiLayoutSetContextPointer(layout, "image_user", &iuserptr);
+ uiTemplateID(layout, C, ptr, "image", ima ? NULL : "IMAGE_OT_new", "IMAGE_OT_open", NULL);
+
+ if (!ima)
+ return;
+
+ uiItemR(layout, &imaptr, "source", 0, IFACE_("Source"), ICON_NONE);
+
+ if (!(ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER))) {
+ uiLayout *row = uiLayoutRow(layout, true);
+
+ if (ima->packedfile)
+ uiItemO(row, "", ICON_PACKAGE, "image.unpack");
+ else
+ uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
+
+ row = uiLayoutRow(row, true);
+ uiLayoutSetEnabled(row, ima->packedfile == NULL);
+ uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
+ uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
+ }
+
+ /* multilayer? */
+ if (ima->type == IMA_TYPE_MULTILAYER && ima->rr) {
+ uiTemplateImageLayers(layout, C, ima, iuserptr.data);
+ }
+ else if (ima->source != IMA_SRC_GENERATED) {
+ uiTemplateImageInfo(layout, C, ima, iuserptr.data);
+ }
+
+ uiItemR(layout, ptr, "color_space", 0, IFACE_("Color Space"), ICON_NONE);
+ uiItemR(layout, ptr, "projection", 0, IFACE_("Projection"), ICON_NONE);
}
static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -863,6 +936,7 @@ static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C),
static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
+ uiItemR(layout, ptr, "object", 0, NULL, 0);
uiItemR(layout, ptr, "from_dupli", 0, NULL, 0);
}
@@ -1073,6 +1147,7 @@ static void node_shader_set_butfunc(bNodeType *ntype)
break;
case SH_NODE_TEX_ENVIRONMENT:
ntype->draw_buttons = node_shader_buts_tex_environment;
+ ntype->draw_buttons_ex = node_shader_buts_tex_environment_ex;
break;
case SH_NODE_TEX_GRADIENT:
ntype->draw_buttons = node_shader_buts_tex_gradient;
@@ -1672,13 +1747,13 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
/* using different collection properties if multilayer format is enabled */
if (multilayer) {
uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "layer_slots", ptr, "active_input_index",
- 0, 0, 0, 0);
+ NULL, 0, 0, 0, 0);
RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "layer_slots"),
active_index, &active_input_ptr);
}
else {
uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "file_slots", ptr, "active_input_index",
- 0, 0, 0, 0);
+ NULL, 0, 0, 0, 0);
RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "file_slots"),
active_index, &active_input_ptr);
}
@@ -2281,6 +2356,7 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN
static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNode *node = ptr->data;
+ NodePlaneTrackDeformData *data = node->storage;
uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL);
@@ -2309,6 +2385,12 @@ static void node_composit_buts_planetrackdeform(uiLayout *layout, bContext *C, P
uiItemR(layout, ptr, "plane_track_name", 0, "", ICON_ANIM_DATA);
}
}
+
+ uiItemR(layout, ptr, "use_motion_blur", 0, NULL, ICON_NONE);
+ if (data->flag & CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR) {
+ uiItemR(layout, ptr, "motion_blur_samples", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "motion_blur_shutter", 0, NULL, ICON_NONE);
+ }
}
static void node_composit_buts_cornerpin(uiLayout *UNUSED(layout), bContext *UNUSED(C), PointerRNA *UNUSED(ptr))
@@ -2899,9 +2981,9 @@ static void node_file_output_socket_draw(bContext *C, uiLayout *layout, PointerR
RNA_property_enum_name((bContext *)C, &imfptr, imtype_prop,
RNA_property_enum_get(&imfptr, imtype_prop), &imtype_name);
block = uiLayoutGetBlock(row);
- uiBlockSetEmboss(block, UI_EMBOSSP);
+ UI_block_emboss_set(block, UI_EMBOSS_PULLDOWN);
uiItemL(row, imtype_name, ICON_NONE);
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
}
}
@@ -3055,9 +3137,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode, b
/* somehow the offset has to be calculated inverse */
glaDefine2DArea(&ar->winrct);
- /* ortho at pixel level curarea */
- /* almost #wmOrtho2_region_pixelspace, but no +1 px */
- wmOrtho2_pixelspace(ar->winx, ar->winy);
+ wmOrtho2_region_pixelspace(ar);
x = (ar->winx - snode->zoom * ibuf->x) / 2 + snode->xof;
y = (ar->winy - snode->zoom * ibuf->y) / 2 + snode->yof;
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 02e6f9b69f3..b6fa4518ed6 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -29,8 +29,6 @@
* \ingroup spnode
*/
-#include <errno.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_node_types.h"
@@ -227,7 +225,7 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
float insert_point[2];
/* always first */
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
node_deselect_all(snode);
@@ -304,33 +302,12 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node;
- Image *ima = NULL;
+ Image *ima;
int type = 0;
- /* check input variables */
- if (RNA_struct_property_is_set(op->ptr, "filepath")) {
- char path[FILE_MAX];
- RNA_string_get(op->ptr, "filepath", path);
-
- errno = 0;
-
- ima = BKE_image_load_exists(path);
-
- if (!ima) {
- BKE_reportf(op->reports, RPT_ERROR, "Cannot read image '%s': %s",
- path, errno ? strerror(errno) : TIP_("unsupported format"));
- return OPERATOR_CANCELLED;
- }
- }
- else if (RNA_struct_property_is_set(op->ptr, "name")) {
- char name[MAX_ID_NAME - 2];
- RNA_string_get(op->ptr, "name", name);
- ima = (Image *)BKE_libblock_find_name(ID_IM, name);
-
- if (!ima) {
- BKE_reportf(op->reports, RPT_ERROR, "Image '%s' not found", name);
- return OPERATOR_CANCELLED;
- }
+ ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
+ if (!ima) {
+ return OPERATOR_CANCELLED;
}
switch (snode->nodetree->type) {
@@ -347,7 +324,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
node = node_add_node(C, NULL, type, snode->cursor[0], snode->cursor[1]);
@@ -357,9 +334,14 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
}
node->id = (ID *)ima;
-
- BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
- WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
+
+ /* When adding new image file via drag-drop we need to load imbuf in order
+ * to get proper image source.
+ */
+ if (RNA_struct_property_is_set(op->ptr, "filepath")) {
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
+ }
snode_notify(C, snode);
snode_dag_update(C, snode);
@@ -397,8 +379,8 @@ void NODE_OT_add_file(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE,
- WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Datablock name to assign");
}
@@ -426,7 +408,7 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
node = node_add_node(C, NULL, CMP_NODE_MASK, snode->cursor[0], snode->cursor[1]);
@@ -471,8 +453,8 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
PointerRNA ptr, idptr;
PropertyRNA *prop;
const char *idname;
- char _treename[MAX_ID_NAME - 2];
- char *treename = _treename;
+ char treename_buf[MAX_ID_NAME - 2];
+ const char *treename;
if (RNA_struct_property_is_set(op->ptr, "type")) {
prop = RNA_struct_find_property(op->ptr, "type");
@@ -484,10 +466,11 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
if (RNA_struct_property_is_set(op->ptr, "name")) {
- RNA_string_get(op->ptr, "name", treename);
+ RNA_string_get(op->ptr, "name", treename_buf);
+ treename = treename_buf;
}
else {
- treename = (char *)DATA_("NodeTree");
+ treename = DATA_("NodeTree");
}
if (!ntreeTypeFind(idname)) {
@@ -498,7 +481,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
ntree = ntreeAddTree(bmain, treename, idname);
/* hook into UI */
- uiIDContextProperty(C, &ptr, &prop);
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
if (prop) {
/* RNA_property_pointer_set increases the user count,
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index 58d94a28226..5b478d8bde3 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -57,6 +57,7 @@
/* ******************* node space & buttons ************** */
+#if 0
/* poll for active nodetree */
static int active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt))
{
@@ -64,6 +65,7 @@ static int active_nodetree_poll(const bContext *C, PanelType *UNUSED(pt))
return (snode && snode->nodetree);
}
+#endif
static int node_sockets_poll(const bContext *C, PanelType *UNUSED(pt))
{
@@ -146,14 +148,14 @@ static void node_tree_interface_panel(const bContext *C, Panel *pa)
col = uiLayoutColumn(split, true);
uiItemL(col, IFACE_("Inputs:"), ICON_NONE);
uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "inputs", &ptr, "inputs", &ptr, "active_input",
- 0, 0, 0, 0);
+ NULL, 0, 0, 0, 0);
opptr = uiItemFullO(col, "NODE_OT_tree_socket_add", "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&opptr, "in_out", SOCK_IN);
col = uiLayoutColumn(split, true);
uiItemL(col, IFACE_("Outputs:"), ICON_NONE);
uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "outputs", &ptr, "outputs", &ptr, "active_output",
- 0, 0, 0, 0);
+ NULL, 0, 0, 0, 0);
opptr = uiItemFullO(col, "NODE_OT_tree_socket_add", "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
RNA_enum_set(&opptr, "in_out", SOCK_OUT);
@@ -197,15 +199,6 @@ void node_buttons_register(ARegionType *art)
pt->draw = node_tree_interface_panel;
pt->poll = node_tree_interface_poll;
BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype node panel gpencil");
- strcpy(pt->idname, "NODE_PT_gpencil");
- strcpy(pt->label, N_("Grease Pencil"));
- strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw_header = ED_gpencil_panel_standard_header;
- pt->draw = ED_gpencil_panel_standard;
- pt->poll = active_nodetree_poll;
- BLI_addtail(&art->paneltypes, pt);
}
static int node_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 7b5ec38f4c6..87a64e95e63 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -66,10 +66,13 @@
#include "RNA_access.h"
#include "node_intern.h" /* own include */
-#include "COM_compositor.h"
+
+#ifdef WITH_COMPOSITOR
+# include "COM_compositor.h"
+#endif
/* XXX interface.h */
-extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select);
+extern void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select);
float ED_node_grid_size(void)
{
@@ -214,7 +217,7 @@ void ED_node_sort(bNodeTree *ntree)
{
/* merge sort is the algorithm of choice here */
bNode *first_a, *first_b, *node_a, *node_b, *tmp;
- int totnodes = BLI_countlist(&ntree->nodes);
+ int totnodes = BLI_listbase_count(&ntree->nodes);
int k, a, b;
k = 1;
@@ -283,11 +286,11 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree)
for (node = ntree->nodes.first; node; node = node->next) {
/* ui block */
BLI_snprintf(uiblockstr, sizeof(uiblockstr), "node buttons %p", (void *)node);
- node->block = uiBeginBlock(C, CTX_wm_region(C), uiblockstr, UI_EMBOSS);
- uiBlockSetHandleFunc(node->block, do_node_internal_buttons, node);
+ node->block = UI_block_begin(C, CTX_wm_region(C), uiblockstr, UI_EMBOSS);
+ UI_block_func_handle_set(node->block, do_node_internal_buttons, node);
/* this cancels events for background nodes */
- uiBlockSetFlag(node->block, UI_BLOCK_CLIP_EVENTS);
+ UI_block_flag_enable(node->block, UI_BLOCK_CLIP_EVENTS);
}
}
@@ -336,8 +339,9 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr);
- layout = uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
- locx + NODE_DYS, dy, NODE_WIDTH(node) - NODE_DY, NODE_DY, 0, UI_GetStyle());
+ layout = UI_block_layout(
+ node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
+ locx + NODE_DYS, dy, NODE_WIDTH(node) - NODE_DY, NODE_DY, 0, UI_style_get());
/* context pointers for current node and socket */
uiLayoutSetContextPointer(layout, "node", &nodeptr);
uiLayoutSetContextPointer(layout, "socket", &sockptr);
@@ -348,8 +352,8 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(nsock->name));
- uiBlockEndAlign(node->block);
- uiBlockLayoutResolve(node->block, NULL, &buty);
+ UI_block_align_end(node->block);
+ UI_block_layout_resolve(node->block, NULL, &buty);
/* ensure minimum socket height in case layout is empty */
buty = min_ii(buty, dy - NODE_DY);
@@ -407,14 +411,15 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
node->butr.ymax = 0;
- layout = uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
- locx + NODE_DYS, dy, node->butr.xmax, 0, 0, UI_GetStyle());
+ layout = UI_block_layout(
+ node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
+ locx + NODE_DYS, dy, node->butr.xmax, 0, 0, UI_style_get());
uiLayoutSetContextPointer(layout, "node", &nodeptr);
node->typeinfo->draw_buttons(layout, (bContext *)C, &nodeptr);
- uiBlockEndAlign(node->block);
- uiBlockLayoutResolve(node->block, NULL, &buty);
+ UI_block_align_end(node->block);
+ UI_block_layout_resolve(node->block, NULL, &buty);
dy = buty - NODE_DYS / 2;
}
@@ -426,8 +431,9 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
RNA_pointer_create(&ntree->id, &RNA_NodeSocket, nsock, &sockptr);
- layout = uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
- locx + NODE_DYS, dy, NODE_WIDTH(node) - NODE_DY, NODE_DY, 0, UI_GetStyle());
+ layout = UI_block_layout(
+ node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
+ locx + NODE_DYS, dy, NODE_WIDTH(node) - NODE_DY, NODE_DY, 0, UI_style_get());
/* context pointers for current node and socket */
uiLayoutSetContextPointer(layout, "node", &nodeptr);
uiLayoutSetContextPointer(layout, "socket", &sockptr);
@@ -436,8 +442,8 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(nsock->name));
- uiBlockEndAlign(node->block);
- uiBlockLayoutResolve(node->block, NULL, &buty);
+ UI_block_align_end(node->block);
+ UI_block_layout_resolve(node->block, NULL, &buty);
/* ensure minimum socket height in case layout is empty */
buty = min_ii(buty, dy - NODE_DY);
@@ -463,11 +469,12 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
/* Set the block bounds to clip mouse events from underlying nodes.
* Add a margin for sockets on each side.
*/
- uiExplicitBoundsBlock(node->block,
- node->totr.xmin - NODE_SOCKSIZE,
- node->totr.ymin,
- node->totr.xmax + NODE_SOCKSIZE,
- node->totr.ymax);
+ UI_block_bounds_set_explicit(
+ node->block,
+ node->totr.xmin - NODE_SOCKSIZE,
+ node->totr.ymin,
+ node->totr.xmax + NODE_SOCKSIZE,
+ node->totr.ymax);
}
/* based on settings in node, sets drawing rect info. each redraw! */
@@ -524,11 +531,12 @@ static void node_update_hidden(bNode *node)
/* Set the block bounds to clip mouse events from underlying nodes.
* Add a margin for sockets on each side.
*/
- uiExplicitBoundsBlock(node->block,
- node->totr.xmin - NODE_SOCKSIZE,
- node->totr.ymin,
- node->totr.xmax + NODE_SOCKSIZE,
- node->totr.ymax);
+ UI_block_bounds_set_explicit(
+ node->block,
+ node->totr.xmin - NODE_SOCKSIZE,
+ node->totr.ymin,
+ node->totr.xmax + NODE_SOCKSIZE,
+ node->totr.ymax);
}
void node_update_default(const bContext *C, bNodeTree *ntree, bNode *node)
@@ -739,16 +747,16 @@ void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha)
{
rctf *rct = &node->totr;
- uiSetRoundBox(UI_CNR_ALL);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
if (node->parent == NULL)
- ui_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT);
+ ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT);
else {
const float margin = 3.0f;
glColor4f(0.0f, 0.0f, 0.0f, 0.33f);
glEnable(GL_BLEND);
- uiRoundBox(rct->xmin - margin, rct->ymin - margin,
- rct->xmax + margin, rct->ymax + margin, radius + margin);
+ UI_draw_roundbox(rct->xmin - margin, rct->ymin - margin,
+ rct->xmax + margin, rct->ymax + margin, radius + margin);
glDisable(GL_BLEND);
}
}
@@ -771,7 +779,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* skip if out of view */
if (BLI_rctf_isect(&node->totr, &ar->v2d.cur, NULL) == false) {
- uiEndBlock(C, node->block);
+ UI_block_end(C, node->block);
node->block = NULL;
return;
}
@@ -800,8 +808,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
}
#endif
- uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
- uiRoundBox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD);
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
+ UI_draw_roundbox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD);
/* show/hide icons */
iconofs = rct->xmax - 0.35f * U.widget_unit;
@@ -810,27 +818,27 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
if (node->typeinfo->flag & NODE_PREVIEW) {
uiBut *but;
iconofs -= iconbutw;
- uiBlockSetEmboss(node->block, UI_EMBOSSN);
- but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_MATERIAL,
+ UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
+ but = uiDefIconBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, ICON_MATERIAL,
iconofs, rct->ymax - NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_preview_toggle");
+ UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_preview_toggle");
/* XXX this does not work when node is activated and the operator called right afterwards,
* since active ID is not updated yet (needs to process the notifier).
* This can only work as visual indicator!
*/
// if (!(node->flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT)))
-// uiButSetFlag(but, UI_BUT_DISABLED);
- uiBlockSetEmboss(node->block, UI_EMBOSS);
+// UI_but_flag_enable(but, UI_BUT_DISABLED);
+ UI_block_emboss_set(node->block, UI_EMBOSS);
}
/* group edit */
if (node->type == NODE_GROUP) {
uiBut *but;
iconofs -= iconbutw;
- uiBlockSetEmboss(node->block, UI_EMBOSSN);
- but = uiDefIconBut(node->block, TOGBUT, B_REDR, ICON_NODETREE,
+ UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
+ but = uiDefIconBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, ICON_NODETREE,
iconofs, rct->ymax - NODE_DY, iconbutw, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_group_edit");
- uiBlockSetEmboss(node->block, UI_EMBOSS);
+ UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_group_edit");
+ UI_block_emboss_set(node->block, UI_EMBOSS);
}
/* title */
@@ -844,15 +852,15 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
uiBut *but;
int but_size = UI_UNIT_X * 0.6f;
/* XXX button uses a custom triangle draw below, so make it invisible without icon */
- uiBlockSetEmboss(node->block, UI_EMBOSSN);
- but = uiDefBut(node->block, TOGBUT, B_REDR, "",
+ UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
+ but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "",
rct->xmin + 0.5f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2,
but_size, but_size, NULL, 0, 0, 0, 0, "");
- uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
- uiBlockSetEmboss(node->block, UI_EMBOSS);
+ UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
+ UI_block_emboss_set(node->block, UI_EMBOSS);
/* custom draw function for this button */
- UI_DrawTriIcon(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v');
+ UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v');
}
/* this isn't doing anything for the label, so commenting out */
@@ -868,7 +876,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
//if (node->flag & NODE_MUTED)
// BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */
- uiDefBut(node->block, LABEL, 0, showname,
+ uiDefBut(node->block, UI_BTYPE_LABEL, 0, showname,
(int)(rct->xmin + (NODE_MARGIN_X)), (int)(rct->ymax - NODE_DY),
(short)(iconofs - rct->xmin - 18.0f), (short)NODE_DY,
NULL, 0, 0, 0, 0, "");
@@ -881,8 +889,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
else
UI_ThemeColor4(TH_NODE);
glEnable(GL_BLEND);
- uiSetRoundBox(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
- uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax - NODE_DY, BASIS_RAD);
+ UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT);
+ UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax - NODE_DY, BASIS_RAD);
glDisable(GL_BLEND);
/* outline active and selected emphasis */
@@ -896,8 +904,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
else
UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
@@ -936,8 +944,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
UI_ThemeClearColor(color_id);
- uiEndBlock(C, node->block);
- uiDrawBlock(C, node->block);
+ UI_block_end(C, node->block);
+ UI_block_draw(C, node->block);
node->block = NULL;
}
@@ -969,7 +977,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
(void)ntree;
#endif
- uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
+ UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
/* outline active and selected emphasis */
if (node->flag & SELECT) {
@@ -980,7 +988,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -40);
else
UI_ThemeColorShadeAlpha(TH_SELECT, 0, -40);
- uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
+ UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
@@ -992,7 +1000,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
glEnable(GL_LINE_SMOOTH);
glColor3fv(node->color);
- uiDrawBox(GL_LINE_LOOP, rct->xmin + 1, rct->ymin + 1, rct->xmax -1, rct->ymax - 1, hiddenrad);
+ UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rct->xmin + 1, rct->ymin + 1, rct->xmax -1, rct->ymax - 1, hiddenrad);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
@@ -1009,15 +1017,15 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
uiBut *but;
int but_size = UI_UNIT_X * 0.6f;
/* XXX button uses a custom triangle draw below, so make it invisible without icon */
- uiBlockSetEmboss(node->block, UI_EMBOSSN);
- but = uiDefBut(node->block, TOGBUT, B_REDR, "",
+ UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
+ but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "",
rct->xmin + 10.0f - but_size / 2, centy - but_size / 2,
but_size, but_size, NULL, 0, 0, 0, 0, "");
- uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
- uiBlockSetEmboss(node->block, UI_EMBOSS);
+ UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
+ UI_block_emboss_set(node->block, UI_EMBOSS);
/* custom draw function for this button */
- UI_DrawTriIcon(rct->xmin + 10.0f, centy, 'h');
+ UI_draw_icon_tri(rct->xmin + 10.0f, centy, 'h');
}
/* disable lines */
@@ -1035,7 +1043,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
//if (node->flag & NODE_MUTED)
// BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */
- uiDefBut(node->block, LABEL, 0, showname,
+ uiDefBut(node->block, UI_BTYPE_LABEL, 0, showname,
(int)(rct->xmin + (NODE_MARGIN_X)), (int)(centy - 10),
(short)(BLI_rctf_size_x(rct) - 18.0f - 12.0f), (short)NODE_DY,
NULL, 0, 0, 0, 0, "");
@@ -1063,8 +1071,8 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
node_socket_circle_draw(C, ntree, node, sock, socket_size, sock->flag & SELECT);
}
- uiEndBlock(C, node->block);
- uiDrawBlock(C, node->block);
+ UI_block_end(C, node->block);
+ UI_block_draw(C, node->block);
node->block = NULL;
}
@@ -1125,6 +1133,9 @@ void node_update_nodetree(const bContext *C, bNodeTree *ntree)
{
bNode *node;
+ /* make sure socket "used" tags are correct, for displaying value buttons */
+ ntreeTagUsedSockets(ntree);
+
/* update nodes front to back, so children sizes get updated before parents */
for (node = ntree->nodes.last; node; node = node->prev) {
node_update(C, ntree, node);
@@ -1243,15 +1254,15 @@ static void draw_group_overlay(const bContext *C, ARegion *ar)
/* shade node groups to separate them visually */
UI_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70);
glEnable(GL_BLEND);
- uiSetRoundBox(UI_CNR_NONE);
- uiDrawBox(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0);
+ UI_draw_roundbox_corner_set(UI_CNR_NONE);
+ UI_draw_roundbox_gl_mode(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0);
glDisable(GL_BLEND);
/* set the block bounds to clip mouse events from underlying nodes */
- block = uiBeginBlock(C, ar, "node tree bounds block", UI_EMBOSS);
- uiExplicitBoundsBlock(block, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
- uiBlockSetFlag(block, UI_BLOCK_CLIP_EVENTS);
- uiEndBlock(C, block);
+ block = UI_block_begin(C, ar, "node tree bounds block", UI_EMBOSS);
+ UI_block_bounds_set_explicit(block, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ UI_block_flag_enable(block, UI_BLOCK_CLIP_EVENTS);
+ UI_block_end(C, block);
}
void drawnodespace(const bContext *C, ARegion *ar)
@@ -1293,6 +1304,11 @@ void drawnodespace(const bContext *C, ARegion *ar)
path = snode->treepath.last;
+ /* update tree path name (drawn in the bottom left) */
+ if (snode->id && UNLIKELY(!STREQ(path->node_name, snode->id->name + 2))) {
+ BLI_strncpy(path->node_name, snode->id->name + 2, sizeof(path->node_name));
+ }
+
/* current View2D center, will be set temporarily for parent node trees */
UI_view2d_center_get(v2d, &center[0], &center[1]);
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index ca13d87d632..f79d6e26f22 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -31,7 +31,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_action_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
@@ -73,8 +72,6 @@
#include "IMB_imbuf_types.h"
#include "node_intern.h" /* own include */
-#include "NOD_common.h"
-#include "NOD_socket.h"
#include "NOD_composite.h"
#include "NOD_shader.h"
#include "NOD_texture.h"
@@ -342,14 +339,22 @@ void snode_dag_update(bContext *C, SpaceNode *snode)
void snode_notify(bContext *C, SpaceNode *snode)
{
+ ID *id = snode->id;
+
WM_event_add_notifier(C, NC_NODE | NA_EDITED, NULL);
- if (ED_node_is_shader(snode))
- WM_event_add_notifier(C, NC_MATERIAL | ND_NODES, snode->id);
+ if (ED_node_is_shader(snode)) {
+ if (GS(id->name) == ID_MA)
+ WM_main_add_notifier(NC_MATERIAL | ND_SHADING, id);
+ else if (GS(id->name) == ID_LA)
+ WM_main_add_notifier(NC_LAMP | ND_LIGHTING, id);
+ else if (GS(id->name) == ID_WO)
+ WM_main_add_notifier(NC_WORLD | ND_WORLD, id);
+ }
else if (ED_node_is_compositor(snode))
- WM_event_add_notifier(C, NC_SCENE | ND_NODES, snode->id);
+ WM_event_add_notifier(C, NC_SCENE | ND_NODES, id);
else if (ED_node_is_texture(snode))
- WM_event_add_notifier(C, NC_TEXTURE | ND_NODES, snode->id);
+ WM_event_add_notifier(C, NC_TEXTURE | ND_NODES, id);
}
void ED_node_set_tree_type(SpaceNode *snode, bNodeTreeType *typeinfo)
@@ -561,7 +566,7 @@ void snode_set_context(const bContext *C)
return;
}
- if (snode->nodetree && strcmp(snode->nodetree->idname, snode->tree_idname) != 0) {
+ if (snode->nodetree && !STREQ(snode->nodetree->idname, snode->tree_idname)) {
/* current tree does not match selected type, clear tree path */
ntree = NULL;
id = NULL;
@@ -662,11 +667,16 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
/* if active texture changed, free glsl materials */
if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
Material *ma;
+ World *wo;
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree))
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
+ for (wo = bmain->world.first; wo; wo = wo->id.next)
+ if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree))
+ GPU_material_free(&wo->gpumaterial);
+
WM_main_add_notifier(NC_IMAGE, NULL);
}
@@ -695,7 +705,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
for (scene = bmain->scene.first; scene; scene = scene->id.next) {
if (scene->nodetree && scene->use_nodes && ntreeHasTree(scene->nodetree, ntree)) {
if (node->id == NULL || node->id == (ID *)scene) {
- int num_layers = BLI_countlist(&scene->r.layers);
+ int num_layers = BLI_listbase_count(&scene->r.layers);
scene->r.actlay = node->custom1;
/* Clamp the value, because it might have come from a different
* scene which could have more render layers than new one.
@@ -1142,7 +1152,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
bNodeLink *link, *newlink, *lastlink;
const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
lastnode = ntree->nodes.last;
for (node = ntree->nodes.first; node; node = node->next) {
@@ -1277,7 +1287,7 @@ static int node_read_renderlayers_exec(bContext *C, wmOperator *UNUSED(op))
Scene *curscene = CTX_data_scene(C), *scene;
bNode *node;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
/* first tag scenes unread */
for (scene = bmain->scene.first; scene; scene = scene->id.next)
@@ -1476,7 +1486,7 @@ static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op))
if ((snode == NULL) || (snode->edittree == NULL))
return OPERATOR_CANCELLED;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
node_flag_toggle_exec(snode, NODE_PREVIEW);
@@ -1540,7 +1550,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
if ((snode == NULL) || (snode->edittree == NULL))
return OPERATOR_CANCELLED;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
/* Toggle for all selected nodes */
hidden = 0;
@@ -1588,7 +1598,7 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
for (node = snode->edittree->nodes.first; node; node = node->next) {
/* Only allow muting of nodes having a mute func! */
@@ -1626,7 +1636,7 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node, *next;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
for (node = snode->edittree->nodes.first; node; node = next) {
next = node->next;
@@ -1667,7 +1677,7 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node, *next;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
for (node = snode->edittree->nodes.first; node; node = next) {
next = node->next;
@@ -1924,7 +1934,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
bNode *node;
bNodeLink *link, *newlink;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
/* clear current clipboard */
BKE_node_clipboard_clear();
@@ -2037,7 +2047,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
if (!all_nodes_valid)
return OPERATOR_CANCELLED;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
/* deselect old nodes */
node_deselect_all(snode);
@@ -2445,7 +2455,7 @@ static int viewer_border_exec(bContext *C, wmOperator *op)
void *lock;
ImBuf *ibuf;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index 96cc7fb4407..b69808d4e81 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -55,7 +55,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -64,7 +63,6 @@
#include "node_intern.h" /* own include */
#include "NOD_common.h"
-#include "NOD_socket.h"
static int node_group_operator_active(bContext *C)
{
@@ -144,7 +142,7 @@ static int node_group_edit_exec(bContext *C, wmOperator *op)
bNode *gnode;
const bool exit = RNA_boolean_get(op->ptr, "exit");
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
gnode = node_group_get_active(C, node_idname);
@@ -352,7 +350,7 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op)
const char *node_idname = group_node_idname(C);
bNode *gnode;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
gnode = node_group_get_active(C, node_idname);
if (!gnode)
@@ -522,7 +520,7 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
int type = RNA_enum_get(op->ptr, "type");
float offx, offy;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
/* are we inside of a group? */
ngroup = snode->edittree;
@@ -562,16 +560,16 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
- uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Separate"), ICON_NONE);
- uiLayout *layout = uiPupMenuLayout(pup);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Separate"), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_COPY);
uiItemEnumO(layout, "NODE_OT_group_separate", NULL, 0, "type", NODE_GS_MOVE);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
void NODE_OT_group_separate(wmOperatorType *ot)
@@ -915,7 +913,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
bNode *gnode;
Main *bmain = CTX_data_main(C);
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
if (!node_group_make_test_selected(ntree, NULL, ntree_idname, op->reports))
return OPERATOR_CANCELLED;
@@ -966,7 +964,7 @@ static int node_group_insert_exec(bContext *C, wmOperator *op)
bNode *gnode;
Main *bmain = CTX_data_main(C);
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
gnode = node_group_get_active(C, node_idname);
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 9598ff190c0..27c3ab813ae 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -163,7 +163,6 @@ void NODE_OT_links_cut(struct wmOperatorType *ot);
void NODE_OT_links_detach(struct wmOperatorType *ot);
void NODE_OT_parent_set(struct wmOperatorType *ot);
-void NODE_OT_parent_clear(struct wmOperatorType *ot);
void NODE_OT_join(struct wmOperatorType *ot);
void NODE_OT_attach(struct wmOperatorType *ot);
void NODE_OT_detach(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 7dcbeae4627..a7799e79312 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -111,7 +111,6 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_output_file_move_active_socket);
WM_operatortype_append(NODE_OT_parent_set);
- WM_operatortype_append(NODE_OT_parent_clear);
WM_operatortype_append(NODE_OT_join);
WM_operatortype_append(NODE_OT_attach);
WM_operatortype_append(NODE_OT_detach);
@@ -147,6 +146,10 @@ void ED_operatormacros_node(void)
RNA_boolean_set(mot->ptr, "release_confirm", true);
WM_operatortype_macro_define(ot, "NODE_OT_attach");
+ /* Note: Currently not in a default keymap or menu due to messy keymaps
+ * and tricky invoke functionality.
+ * Kept around in case users want to make own shortcuts.
+ */
ot = WM_operatortype_append_macro("NODE_OT_detach_translate_attach", "Detach and Move",
"Detach nodes, move and attach to frame",
OPTYPE_UNDO | OPTYPE_REGISTER);
@@ -267,7 +270,7 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_duplicate_move_keep_inputs", DKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "NODE_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_detach", PKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "NODE_OT_join", JKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_hide_toggle", HKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index 973ce56857c..c8951a1172e 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -57,7 +57,6 @@
#include "BLF_translation.h"
#include "node_intern.h" /* own include */
-#include "NOD_common.h"
/* ****************** Add *********************** */
@@ -203,7 +202,7 @@ static void snode_autoconnect(SpaceNode *snode, const bool allow_multiple, const
}
/* sort nodes left to right */
- BLI_sortlist(nodelist, sort_nodes_locx);
+ BLI_listbase_sort(nodelist, sort_nodes_locx);
for (nli = nodelist->first; nli; nli = nli->next) {
bNode *node_fr, *node_to;
@@ -236,7 +235,7 @@ static void snode_autoconnect(SpaceNode *snode, const bool allow_multiple, const
if (!has_selected_inputs) {
/* no selected inputs, connect by finding suitable match */
- int num_inputs = BLI_countlist(&node_to->inputs);
+ int num_inputs = BLI_listbase_count(&node_to->inputs);
for (i = 0; i < num_inputs; i++) {
@@ -368,7 +367,7 @@ static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op))
if (!node)
return OPERATOR_CANCELLED;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
if (node_link_viewer(C, node) == OPERATOR_CANCELLED)
return OPERATOR_CANCELLED;
@@ -747,7 +746,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&cursor[0], &cursor[1]);
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
nldrag = node_link_init(snode, cursor, detach);
@@ -803,7 +802,7 @@ static int node_make_link_exec(bContext *C, wmOperator *op)
SpaceNode *snode = CTX_wm_space_node(C);
const bool replace = RNA_boolean_get(op->ptr, "replace");
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
snode_autoconnect(snode, 1, replace);
@@ -874,7 +873,7 @@ static int cut_links_exec(bContext *C, wmOperator *op)
bool found = false;
bNodeLink *link, *next;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
for (link = snode->edittree->links.first; link; link = next) {
next = link->next;
@@ -884,7 +883,8 @@ static int cut_links_exec(bContext *C, wmOperator *op)
if (cut_links_intersect(link, mcoords, i)) {
if (found == false) {
- ED_preview_kill_jobs(C);
+ /* TODO(sergey): Why did we kill jobs twice? */
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
found = true;
}
@@ -941,7 +941,7 @@ static int detach_links_exec(bContext *C, wmOperator *UNUSED(op))
bNodeTree *ntree = snode->edittree;
bNode *node;
- ED_preview_kill_jobs(C);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
for (node = ntree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
@@ -1011,40 +1011,6 @@ void NODE_OT_parent_set(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/* ****************** Clear Parent ******************* */
-
-static int node_parent_clear_exec(bContext *C, wmOperator *UNUSED(op))
-{
- SpaceNode *snode = CTX_wm_space_node(C);
- bNodeTree *ntree = snode->edittree;
- bNode *node;
-
- for (node = ntree->nodes.first; node; node = node->next) {
- if (node->flag & NODE_SELECT) {
- nodeDetachNode(node);
- }
- }
-
- WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-void NODE_OT_parent_clear(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Clear Parent";
- ot->description = "Detach selected nodes";
- ot->idname = "NODE_OT_parent_clear";
-
- /* api callbacks */
- ot->exec = node_parent_clear_exec;
- ot->poll = ED_operator_node_editable;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-}
-
/* ****************** Join Nodes ******************* */
/* tags for depth-first search */
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index de580f612a0..25f9d56c8f0 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -972,7 +972,7 @@ static void node_find_cb(const struct bContext *C, void *UNUSED(arg), const char
BLI_snprintf(name, 256, "%s (%s)", node->name, node->label);
else
BLI_strncpy(name, node->name, 256);
- if (false == uiSearchItemAdd(items, name, node, 0))
+ if (false == UI_search_item_add(items, name, node, 0))
break;
}
}
@@ -1006,18 +1006,18 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op)
uiBut *but;
wmOperator *op = (wmOperator *)arg_op;
- block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
- uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, 9 * UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
- uiButSetSearchFunc(but, node_find_cb, op->type, node_find_call_cb, NULL);
+ UI_but_func_search_set(but, node_find_cb, op->type, node_find_call_cb, NULL);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
- uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
+ UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
- // uiButActiveOnly(C, ar, block, but); XXX using this here makes Blender hang - investigate
+ // UI_but_active_only(C, ar, block, but); XXX using this here makes Blender hang - investigate
wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
event.val = KM_PRESS;
@@ -1031,7 +1031,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op)
static int node_find_node_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- uiPupBlock(C, node_find_menu, op);
+ UI_popup_block_invoke(C, node_find_menu, op);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 99a481e5d82..8b68ac013c2 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -30,7 +30,6 @@
#include "DNA_node_types.h"
#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@@ -54,7 +53,6 @@
#include "ED_util.h"
-#include "node_intern.h"
/************************* Node Socket Manipulation **************************/
@@ -300,7 +298,7 @@ static void ui_node_link_items(NodeLinkArg *arg, int in_out, NodeLinkItem **r_it
for (ngroup = arg->bmain->nodetree.first; ngroup; ngroup = ngroup->id.next) {
ListBase *lb = ((in_out == SOCK_IN) ? &ngroup->inputs : &ngroup->outputs);
- totitems += BLI_countlist(lb);
+ totitems += BLI_listbase_count(lb);
}
if (totitems > 0) {
@@ -454,7 +452,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
if (first) {
column = uiLayoutColumn(layout, 0);
- uiBlockSetCurLayout(block, column);
+ UI_block_layout_set_current(block, column);
uiItemL(column, IFACE_(cname), ICON_NODE);
but = block->buttons.last;
@@ -466,7 +464,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
if (!cur_node_name || !STREQ(cur_node_name, items[i].node_name)) {
cur_node_name = items[i].node_name;
/* XXX Do not use uiItemL here, it would add an empty icon as we are in a menu! */
- uiDefBut(block, LABEL, 0, IFACE_(cur_node_name), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_(cur_node_name), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, "");
}
@@ -478,12 +476,12 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
icon = ICON_NONE;
}
- but = uiDefIconTextBut(block, BUT, 0, icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Add node to input"));
argN = MEM_dupallocN(arg);
argN->item = items[i];
- uiButSetNFunc(but, ui_node_link, argN, NULL);
+ UI_but_funcN_set(but, ui_node_link, argN, NULL);
}
if (items)
@@ -511,8 +509,8 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
bNodeSocket *sock = arg->sock;
bNodeTreeType *ntreetype = arg->ntree->typeinfo;
- uiBlockSetFlag(block, UI_BLOCK_NO_FLIP);
- uiBlockSetCurLayout(block, layout);
+ UI_block_flag_enable(block, UI_BLOCK_NO_FLIP);
+ UI_block_layout_set_current(block, layout);
split = uiLayoutSplit(layout, 0.0f, false);
arg->bmain = bmain;
@@ -523,20 +521,20 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
ntreetype->foreach_nodeclass(scene, arg, node_menu_column_foreach_cb);
column = uiLayoutColumn(split, false);
- uiBlockSetCurLayout(block, column);
+ UI_block_layout_set_current(block, column);
if (sock->link) {
uiItemL(column, IFACE_("Link"), ICON_NONE);
but = block->buttons.last;
but->drawflag = UI_BUT_TEXT_LEFT;
- but = uiDefBut(block, BUT, 0, IFACE_("Remove"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
+ but = uiDefBut(block, UI_BTYPE_BUT, 0, IFACE_("Remove"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Remove nodes connected to the input"));
- uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_REMOVE));
+ UI_but_funcN_set(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_REMOVE));
- but = uiDefBut(block, BUT, 0, IFACE_("Disconnect"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
+ but = uiDefBut(block, UI_BTYPE_BUT, 0, IFACE_("Disconnect"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Disconnect nodes connected to the input"));
- uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_DISCONNECT));
+ UI_but_funcN_set(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_DISCONNECT));
}
ui_node_menu_column(arg, NODE_CLASS_GROUP, N_("Group"));
@@ -553,7 +551,7 @@ void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSo
arg->node = node;
arg->sock = sock;
- uiBlockSetCurLayout(block, layout);
+ UI_block_layout_set_current(block, layout);
if (sock->link || sock->type == SOCK_SHADER || (sock->flag & SOCK_HIDE_VALUE)) {
char name[UI_MAX_NAME_STR];
@@ -563,7 +561,7 @@ void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSo
else
but = uiDefIconMenuBut(block, ui_template_node_link_menu, NULL, ICON_NONE, 0, 0, UI_UNIT_X, UI_UNIT_Y, "");
- uiButSetMenuFromPulldown(but);
+ UI_but_type_set_menu_from_pulldown(but);
but->flag |= UI_BUT_NODE_LINK;
but->poin = (char *)but;
@@ -638,7 +636,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
row = uiLayoutRow(split, true);
if (depth > 0) {
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
if (lnode && (lnode->inputs.first || (lnode->typeinfo->draw_buttons && lnode->type != NODE_GROUP))) {
int icon = (input->flag & SOCK_COLLAPSED) ? ICON_DISCLOSURE_TRI_RIGHT : ICON_DISCLOSURE_TRI_DOWN;
@@ -650,7 +648,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree,
bt = block->buttons.last;
bt->rect.xmax = UI_UNIT_X / 2;
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
uiItemL(row, label, ICON_NONE);
diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c
index dd5bad3f8ad..e3e263f2e44 100644
--- a/source/blender/editors/space_node/node_toolbar.c
+++ b/source/blender/editors/space_node/node_toolbar.c
@@ -28,27 +28,18 @@
* \ingroup nodes
*/
-
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "DNA_node_types.h"
#include "BKE_context.h"
-#include "BKE_node.h"
#include "BKE_screen.h"
#include "WM_api.h"
#include "WM_types.h"
-#include "RNA_access.h"
-
#include "ED_screen.h"
-#include "UI_interface.h"
-#include "UI_resources.h"
-
#include "node_intern.h" /* own include */
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index ccaeae34927..62cb0bc73cd 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -28,8 +28,6 @@
* \ingroup spnode
*/
-
-
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
@@ -152,7 +150,7 @@ void ED_node_tree_pop(SpaceNode *snode)
int ED_node_tree_depth(SpaceNode *snode)
{
- return BLI_countlist(&snode->treepath);
+ return BLI_listbase_count(&snode->treepath);
}
bNodeTree *ED_node_tree_get(SpaceNode *snode, int level)
@@ -515,6 +513,11 @@ static void node_area_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
ED_area_tag_refresh(sa);
}
break;
+ case NC_GPENCIL:
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
+ ED_area_tag_redraw(sa);
+ }
+ break;
}
}
@@ -665,12 +668,12 @@ static void node_main_area_draw(const bContext *C, ARegion *ar)
static int node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (GS(id->name) == ID_IM)
return 1;
}
else if (drag->type == WM_DRAG_PATH) {
- if (ELEM(drag->icon, 0, ICON_FILE_IMAGE)) /* rule might not work? */
+ if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)) /* rule might not work? */
return 1;
}
return 0;
@@ -679,7 +682,7 @@ static int node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *
static int node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (GS(id->name) == ID_MSK)
return 1;
}
@@ -688,20 +691,22 @@ static int node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent
static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (id) {
RNA_string_set(drop->ptr, "name", id->name + 2);
+ RNA_struct_property_unset(drop->ptr, "filepath");
}
- if (drag->path[0]) {
+ else if (drag->path[0]) {
RNA_string_set(drop->ptr, "filepath", drag->path);
+ RNA_struct_property_unset(drop->ptr, "name");
}
}
@@ -768,6 +773,8 @@ static void node_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegi
case NC_GPENCIL:
if (wmn->action == NA_EDITED)
ED_region_tag_redraw(ar);
+ else if (wmn->data & ND_GPENCIL_EDITMODE)
+ ED_region_tag_redraw(ar);
break;
}
}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index e033f781f62..2c61e69d611 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -31,6 +31,7 @@
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
#include "DNA_object_types.h"
@@ -175,16 +176,20 @@ static void restrictbutton_recursive_child(bContext *C, Scene *scene, Object *ob
{
Main *bmain = CTX_data_main(C);
Object *ob;
+
for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (BKE_object_is_child_recursive(ob_parent, ob)) {
- if (state) {
- ob->restrictflag |= flag;
- if (deselect) {
- ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
+ /* only do if child object is selectable */
+ if ((flag == OB_RESTRICT_SELECT) || (ob->restrictflag & OB_RESTRICT_SELECT) == 0) {
+ if (state) {
+ ob->restrictflag |= flag;
+ if (deselect) {
+ ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
+ }
+ }
+ else {
+ ob->restrictflag &= ~flag;
}
- }
- else {
- ob->restrictflag &= ~flag;
}
if (rnapropname) {
@@ -197,7 +202,7 @@ static void restrictbutton_recursive_child(bContext *C, Scene *scene, Object *ob
RNA_id_pointer_create(&ob->id, &ptr);
prop = RNA_struct_find_property(&ptr, rnapropname);
- fcu = rna_get_fcurve_context_ui(C, &ptr, prop, 0, &action, &driven);
+ fcu = rna_get_fcurve_context_ui(C, &ptr, prop, 0, NULL, &action, &driven);
if (fcu && !driven) {
id = ptr.id.data;
@@ -346,6 +351,11 @@ static void restrictbutton_ebone_visibility_cb(bContext *C, void *UNUSED(poin),
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
+static void restrictbutton_gp_layer_flag_cb(bContext *C, void *UNUSED(poin), void *UNUSED(poin2))
+{
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+}
+
static int group_restrict_flag(Group *gr, int flag)
{
GroupObject *gob;
@@ -437,6 +447,20 @@ static void restrictbutton_gr_restrict_render(bContext *C, void *poin, void *poi
WM_event_add_notifier(C, NC_GROUP, NULL);
}
+static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void *UNUSED(poin2))
+{
+ ID *id = (ID *)poin;
+
+ BLI_assert(id != NULL);
+
+ if (id->flag & LIB_FAKEUSER) {
+ id_us_plus(id);
+ }
+ else {
+ id_us_min(id);
+ }
+}
+
static void namebutton_cb(bContext *C, void *tsep, char *oldname)
{
@@ -447,7 +471,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
TreeStoreElem *tselem = tsep;
if (ts && tselem) {
- TreeElement *te = outliner_find_tse(soops, tselem);
+ TreeElement *te = outliner_find_tree_element(&soops->tree, tselem);
if (tselem->type == 0) {
test_idbutton(tselem->id->name); // library.c, unique name and alpha sort
@@ -549,6 +573,17 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
break;
}
+ case TSE_GP_LAYER:
+ {
+ bGPdata *gpd = (bGPdata *)tselem->id; // id = GP Datablock
+ bGPDlayer *gpl = te->directdata;
+
+ // XXX: name needs translation stuff
+ BLI_uniquename(&gpd->layers, gpl, "GP Layer", '.',
+ offsetof(bGPDlayer, info), sizeof(gpl->info));
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, gpd);
+ break;
+ }
case TSE_R_LAYER:
break;
}
@@ -584,29 +619,29 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
ob = (Object *)tselem->id;
RNA_pointer_create((ID *)ob, &RNA_Object, ob, &ptr);
- uiBlockSetEmboss(block, UI_EMBOSSN);
- bt = uiDefIconButR_prop(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF,
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, object_prop_hide, -1, 0, 0, -1, -1,
TIP_("Restrict viewport visibility (Ctrl - Recursive)"));
- uiButSetFunc(bt, restrictbutton_view_cb, scene, ob);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_view_cb, scene, ob);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- bt = uiDefIconButR_prop(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF,
+ bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_SELECT_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, object_prop_hide_select, -1, 0, 0, -1, -1,
TIP_("Restrict viewport selection (Ctrl - Recursive)"));
- uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_sel_cb, scene, ob);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- bt = uiDefIconButR_prop(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF,
+ bt = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, ICON_RESTRICT_RENDER_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
&ptr, object_prop_hide_render, -1, 0, 0, -1, -1,
TIP_("Restrict rendering (Ctrl - Recursive)"));
- uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_rend_cb, scene, ob);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
if (tselem->type == 0 && te->idcode == ID_GR) {
@@ -617,130 +652,153 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
if (gr->id.lib)
but_flag |= UI_BUT_DISABLED;
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW);
- bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF,
+ bt = uiDefIconBut(block, UI_BTYPE_ICON_TOGGLE, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View"));
- uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr);
- uiButSetFlag(bt, but_flag);
+ UI_but_func_set(bt, restrictbutton_gr_restrict_view, scene, gr);
+ UI_but_flag_enable(bt, but_flag);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT);
- bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF,
+ bt = uiDefIconBut(block, UI_BTYPE_ICON_TOGGLE, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View"));
- uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr);
- uiButSetFlag(bt, but_flag);
+ UI_but_func_set(bt, restrictbutton_gr_restrict_select, scene, gr);
+ UI_but_flag_enable(bt, but_flag);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER);
- bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF,
+ bt = uiDefIconBut(block, UI_BTYPE_ICON_TOGGLE, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Restrict/Allow renderability"));
- uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr);
- uiButSetFlag(bt, but_flag);
+ UI_but_func_set(bt, restrictbutton_gr_restrict_render, scene, gr);
+ UI_but_flag_enable(bt, but_flag);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
/* scene render layers and passes have toggle-able flags too! */
else if (tselem->type == TSE_R_LAYER) {
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
- bt = uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1,
+ bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE_N, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
UI_UNIT_Y, te->directdata, 0, 0, 0, 0, TIP_("Render this RenderLayer"));
- uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
else if (tselem->type == TSE_R_PASS) {
int *layflag = te->directdata;
int passflag = 1 << tselem->nr;
- uiBlockSetEmboss(block, UI_EMBOSSN);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
- bt = uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT - 1,
+ bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, passflag, 0, ICON_CHECKBOX_HLT - 1,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Render this Pass"));
- uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
layflag++; /* is lay_xor */
if (ELEM(passflag, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT,
SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT))
{
- bt = uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag) ? ICON_DOT : ICON_BLANK1,
+ bt = uiDefIconButBitI(block, UI_BTYPE_TOGGLE, passflag, 0, (*layflag & passflag) ? ICON_DOT : ICON_BLANK1,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Exclude this Pass from Combined"));
- uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
}
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
else if (tselem->type == TSE_MODIFIER) {
ModifierData *md = (ModifierData *)te->directdata;
ob = (Object *)tselem->id;
- uiBlockSetEmboss(block, UI_EMBOSSN);
- bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF,
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE_N, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &(md->mode), 0, 0, 0, 0,
TIP_("Restrict/Allow visibility in the 3D View"));
- uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_modifier_cb, scene, ob);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF,
+ bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE_N, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &(md->mode), 0, 0, 0, 0, TIP_("Restrict/Allow renderability"));
- uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_modifier_cb, scene, ob);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
else if (tselem->type == TSE_POSE_CHANNEL) {
bPoseChannel *pchan = (bPoseChannel *)te->directdata;
Bone *bone = pchan->bone;
ob = (Object *)tselem->id;
- uiBlockSetEmboss(block, UI_EMBOSSN);
- bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF,
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0,
TIP_("Restrict/Allow visibility in the 3D View"));
- uiButSetFunc(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
+ bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0,
TIP_("Restrict/Allow selection in the 3D View"));
- uiButSetFunc(bt, restrictbutton_bone_select_cb, ob->data, bone);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_bone_select_cb, ob->data, bone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
else if (tselem->type == TSE_EBONE) {
EditBone *ebone = (EditBone *)te->directdata;
- uiBlockSetEmboss(block, UI_EMBOSSN);
- bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF,
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0,
TIP_("Restrict/Allow visibility in the 3D View"));
- uiButSetFunc(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
+ bt = uiDefIconButBitI(block, UI_BTYPE_ICON_TOGGLE, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0,
TIP_("Restrict/Allow selection in the 3D View"));
- uiButSetFunc(bt, restrictbutton_ebone_select_cb, NULL, ebone);
- uiButSetFlag(bt, UI_BUT_DRAG_LOCK);
+ UI_but_func_set(bt, restrictbutton_ebone_select_cb, NULL, ebone);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
+ }
+ else if (tselem->type == TSE_GP_LAYER) {
+ bGPDlayer *gpl = (bGPDlayer *)te->directdata;
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE, GP_LAYER_HIDE, 0, ICON_RESTRICT_VIEW_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &gpl->flag, 0, 0, 0, 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, NULL, gpl);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+
+ bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE, GP_LAYER_LOCKED, 0, ICON_UNLOCKED,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &gpl->flag, 0, 0, 0, 0,
+ TIP_("Restrict/Allow editing of strokes and keyframes in this layer"));
+ UI_but_func_set(bt, restrictbutton_gp_layer_flag_cb, NULL, gpl);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+
+ /* TODO: visibility in renders */
+
+ UI_block_emboss_set(block, UI_EMBOSS);
}
}
@@ -748,6 +806,66 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
}
}
+static void outliner_draw_userbuts(uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb)
+{
+ uiBut *bt;
+ TreeElement *te;
+ TreeStoreElem *tselem;
+
+ for (te = lb->first; te; te = te->next) {
+ tselem = TREESTORE(te);
+ if (te->ys + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if (tselem->type == 0) {
+ ID *id = tselem->id;
+ const char *tip = NULL;
+ int icon = ICON_NONE;
+ char buf[16] = "";
+ int but_flag = UI_BUT_DRAG_LOCK;
+
+ if (id->lib)
+ but_flag |= UI_BUT_DISABLED;
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ if (id->flag & LIB_FAKEUSER) {
+ icon = ICON_FILE_TICK;
+ tip = TIP_("Datablock will be retained using a fake user");
+ }
+ else {
+ icon = ICON_X;
+ tip = TIP_("Datablock has no users and will be deleted");
+ }
+ bt = uiDefIconButBitS(block, UI_BTYPE_TOGGLE, LIB_FAKEUSER, 1, icon,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &id->flag, 0, 0, 0, 0, tip);
+ UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
+ UI_but_flag_enable(bt, but_flag);
+
+
+ BLI_str_format_int_grouped(buf, id->us);
+ bt = uiDefBut(block, UI_BTYPE_BUT, 1, buf,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys,
+ UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0,
+ TIP_("Number of users of this datablock"));
+ UI_but_flag_enable(bt, but_flag);
+
+
+ bt = uiDefButBitS(block, UI_BTYPE_TOGGLE, LIB_FAKEUSER, 1, (id->flag & LIB_FAKEUSER) ? "F" : " ",
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y,
+ &id->flag, 0, 0, 0, 0,
+ TIP_("Datablock has a 'fake' user which will keep it in the file "
+ "even if nothing else uses it"));
+ UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
+ UI_but_flag_enable(bt, but_flag);
+
+ UI_block_emboss_set(block, UI_EMBOSS);
+ }
+ }
+
+ if (TSELEM_OPEN(tselem, soops)) outliner_draw_userbuts(block, ar, soops, &te->subtree);
+ }
+}
+
static void outliner_draw_rnacols(ARegion *ar, int sizex)
{
View2D *v2d = &ar->v2d;
@@ -775,8 +893,6 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
TreeStoreElem *tselem;
PointerRNA *ptr;
PropertyRNA *prop;
-
- uiBlockSetEmboss(block, UI_EMBOSST);
for (te = lb->first; te; te = te->next) {
tselem = TREESTORE(te);
@@ -789,7 +905,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
if (RNA_property_type(prop) == PROP_POINTER) {
uiBut *but = uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, te->ys,
OL_RNA_COL_SIZEX, UI_UNIT_Y - 1);
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
else if (RNA_property_type(prop) == PROP_ENUM) {
uiDefAutoButR(block, ptr, prop, -1, NULL, ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX,
@@ -813,7 +929,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
if (TSELEM_OPEN(tselem, soops)) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree);
}
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, TreeElement *te)
@@ -837,12 +953,12 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Tre
spx = te->xs + 1.8f * UI_UNIT_X;
dx = ar->v2d.cur.xmax - (spx + 3.2f * UI_UNIT_X);
- bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, te->ys, dx, UI_UNIT_Y - 1, (void *)te->name,
+ bt = uiDefBut(block, UI_BTYPE_TEXT, OL_NAMEBUTTON, "", spx, te->ys, dx, UI_UNIT_Y - 1, (void *)te->name,
1.0, (float)len, 0, 0, "");
- uiButSetRenameFunc(bt, namebutton_cb, tselem);
+ UI_but_func_rename_set(bt, namebutton_cb, tselem);
/* returns false if button got removed */
- if (false == uiButActiveOnly(C, ar, block, bt)) {
+ if (false == UI_but_active_only(C, ar, block, bt)) {
tselem->flag &= ~TSE_TEXTBUT;
/* bad! (notifier within draw) without this, we don't get a refesh */
@@ -870,15 +986,45 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
glDisable(GL_BLEND);
}
else {
- uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL,
+ uiBut *but = uiDefIconBut(arg->block, UI_BTYPE_LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL,
0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : "");
if (arg->id)
- uiButSetDragID(but, arg->id);
+ UI_but_drag_set_id(but, arg->id);
}
}
+static void tselem_draw_gp_icon_uibut(struct DrawIconArg *arg, ID *id, bGPDlayer *gpl)
+{
+ /* restrict column clip - skip it for now... */
+ if (arg->x >= arg->xmax) {
+ /* pass */
+ }
+ else {
+ PointerRNA ptr;
+ float w = 0.85f * U.widget_unit;
+ float h = 0.85f * UI_UNIT_Y;
+
+ RNA_pointer_create(id, &RNA_GPencilLayer, gpl, &ptr);
+
+ UI_block_align_begin(arg->block);
+
+ UI_block_emboss_set(arg->block, RNA_boolean_get(&ptr, "is_stroke_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
+ uiDefButR(arg->block, UI_BTYPE_COLOR, 1, "", arg->xb, arg->yb, w, h,
+ &ptr, "color", -1,
+ 0, 0, 0, 0, NULL);
+
+ UI_block_emboss_set(arg->block, RNA_boolean_get(&ptr, "is_fill_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
+ uiDefButR(arg->block, UI_BTYPE_COLOR, 1, "", arg->xb, arg->yb, w, h,
+ &ptr, "fill_color", -1,
+ 0, 0, 0, 0, NULL);
+
+ UI_block_emboss_set(arg->block, UI_EMBOSS_NONE);
+ UI_block_align_end(arg->block);
+ }
+}
+
static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te,
float alpha)
{
@@ -1020,6 +1166,10 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
UI_icon_draw(x, y, ICON_MOD_WIREFRAME); break;
case eModifierType_LaplacianDeform:
UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break; /* XXX, needs own icon */
+ case eModifierType_DataTransfer:
+ UI_icon_draw(x, y, ICON_MOD_DATA_TRANSFER); break;
+ case eModifierType_NormalEdit:
+ UI_icon_draw(x, y, ICON_MOD_NORMALEDIT); break;
/* Default */
case eModifierType_None:
case eModifierType_ShapeKey:
@@ -1072,6 +1222,9 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
else
UI_icon_draw(x, y, RNA_struct_ui_icon(te->rnaptr.type));
break;
+ case TSE_GP_LAYER:
+ tselem_draw_gp_icon_uibut(&arg, tselem->id, te->directdata);
+ break;
default:
UI_icon_draw(x, y, ICON_DOT); break;
}
@@ -1165,6 +1318,8 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_DIRECT); break;
case ID_LS:
tselem_draw_icon_uibut(&arg, ICON_LINE_DATA); break;
+ case ID_GD:
+ tselem_draw_icon_uibut(&arg, ICON_GREASEPENCIL); break;
}
}
}
@@ -1206,13 +1361,14 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
if (active != OL_DRAWSEL_NONE) {
float ufac = UI_UNIT_X / 20.0f;
- uiSetRoundBox(UI_CNR_ALL);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
glColor4ub(255, 255, 255, 100);
- uiRoundBox((float) *offsx - 1.0f * ufac,
- (float)ys + 1.0f * ufac,
- (float)*offsx + UI_UNIT_X - 2.0f * ufac,
- (float)ys + UI_UNIT_Y - ufac,
- (float)UI_UNIT_Y / 2.0f - ufac);
+ UI_draw_roundbox(
+ (float) *offsx - 1.0f * ufac,
+ (float)ys + 1.0f * ufac,
+ (float)*offsx + UI_UNIT_X - 2.0f * ufac,
+ (float)ys + UI_UNIT_Y - ufac,
+ (float)UI_UNIT_Y / 2.0f - ufac);
glEnable(GL_BLEND); /* roundbox disables */
}
@@ -1247,8 +1403,9 @@ static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, i
}
-static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops,
- TreeElement *te, int startx, int *starty, TreeElement **te_edit)
+static void outliner_draw_tree_element(
+ bContext *C, uiBlock *block, const uiFontStyle *fstyle, Scene *scene, ARegion *ar, SpaceOops *soops,
+ TreeElement *te, int startx, int *starty, TreeElement **te_edit)
{
TreeElement *ten;
TreeStoreElem *tselem;
@@ -1352,12 +1509,13 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
/* active circle */
if (active != OL_DRAWSEL_NONE) {
- uiSetRoundBox(UI_CNR_ALL);
- uiRoundBox((float)startx + UI_UNIT_X,
- (float)*starty + 1.0f * ufac,
- (float)startx + 2.0f * UI_UNIT_X - 2.0f * ufac,
- (float)*starty + UI_UNIT_Y - 1.0f * ufac,
- UI_UNIT_Y / 2.0f - 1.0f * ufac);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox(
+ (float)startx + UI_UNIT_X,
+ (float)*starty + 1.0f * ufac,
+ (float)startx + 2.0f * UI_UNIT_X - 2.0f * ufac,
+ (float)*starty + UI_UNIT_Y - 1.0f * ufac,
+ UI_UNIT_Y / 2.0f - 1.0f * ufac);
glEnable(GL_BLEND); /* roundbox disables it */
te->flag |= TE_ACTIVE; // for lookup in display hierarchies
@@ -1406,9 +1564,9 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
else if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.75f);
else UI_ThemeColor(TH_TEXT);
- UI_DrawString(startx + offsx, *starty + 5 * ufac, te->name);
+ UI_fontstyle_draw_simple(fstyle, startx + offsx, *starty + 5 * ufac, te->name);
- offsx += (int)(UI_UNIT_X + UI_GetStringWidth(te->name));
+ offsx += (int)(UI_UNIT_X + UI_fontstyle_string_width(fstyle, te->name));
/* closed item, we draw the icons, not when it's a scene, or master-server list though */
if (!TSELEM_OPEN(tselem, soops)) {
@@ -1446,13 +1604,15 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
if (TSELEM_OPEN(tselem, soops)) {
*starty -= UI_UNIT_Y;
-
- for (ten = te->subtree.first; ten; ten = ten->next)
- outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx + UI_UNIT_X, starty, te_edit);
+
+ for (ten = te->subtree.first; ten; ten = ten->next) {
+ outliner_draw_tree_element(C, block, fstyle, scene, ar, soops, ten, startx + UI_UNIT_X, starty, te_edit);
+ }
}
else {
- for (ten = te->subtree.first; ten; ten = ten->next)
+ for (ten = te->subtree.first; ten; ten = ten->next) {
outliner_set_coord_tree_element(soops, ten, startx, *starty);
+ }
*starty -= UI_UNIT_Y;
}
@@ -1535,6 +1695,7 @@ static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb,
static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegion *ar,
SpaceOops *soops, TreeElement **te_edit)
{
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
TreeElement *te;
int starty, startx;
float col[3];
@@ -1565,7 +1726,7 @@ static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegio
starty = (int)ar->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
startx = 0;
for (te = soops->tree.first; te; te = te->next) {
- outliner_draw_tree_element(C, block, scene, ar, soops, te, startx, &starty, te_edit);
+ outliner_draw_tree_element(C, block, fstyle, scene, ar, soops, te, startx, &starty, te_edit);
}
}
@@ -1684,7 +1845,7 @@ void draw_outliner(const bContext *C)
/* draw outliner stuff (background, hierarchy lines and names) */
outliner_back(ar);
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
outliner_draw_tree((bContext *)C, block, scene, ar, soops, &te_edit);
if (ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) {
@@ -1692,6 +1853,11 @@ void draw_outliner(const bContext *C)
outliner_draw_rnacols(ar, sizex_rna);
outliner_draw_rnabuts(block, scene, ar, soops, sizex_rna, &soops->tree);
}
+ else if ((soops->outlinevis == SO_ID_ORPHANS) && !(soops->flag & SO_HIDE_RESTRICTCOLS)) {
+ /* draw user toggle columns */
+ outliner_draw_restrictcols(ar);
+ outliner_draw_userbuts(block, ar, soops, &soops->tree);
+ }
else if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) {
/* draw restriction columns */
outliner_draw_restrictcols(ar);
@@ -1703,8 +1869,8 @@ void draw_outliner(const bContext *C)
outliner_buttons(C, block, ar, te_edit);
}
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
/* clear flag that allows quick redraws */
soops->storeflag &= ~SO_TREESTORE_REDRAW;
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index ef621407abd..798dae2cef3 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -50,6 +50,7 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_material.h"
+#include "BKE_group.h"
#include "ED_object.h"
#include "ED_screen.h"
@@ -73,22 +74,6 @@
/* This is not used anywhere at the moment */
#if 0
-/* return 1 when levels were opened */
-static int outliner_open_back(SpaceOops *soops, TreeElement *te)
-{
- TreeStoreElem *tselem;
- int retval = 0;
-
- for (te = te->parent; te; te = te->parent) {
- tselem = TREESTORE(te);
- if (tselem->flag & TSE_CLOSED) {
- tselem->flag &= ~TSE_CLOSED;
- retval = 1;
- }
- }
- return retval;
-}
-
static void outliner_open_reveal(SpaceOops *soops, ListBase *lb, TreeElement *teFind, int *found)
{
TreeElement *te;
@@ -113,7 +98,9 @@ static void outliner_open_reveal(SpaceOops *soops, ListBase *lb, TreeElement *te
}
#endif
-static TreeElement *outliner_dropzone_element(const SpaceOops *soops, TreeElement *te, const float fmval[2], const int children)
+static TreeElement *outliner_dropzone_element(
+ const SpaceOops *soops, TreeElement *te,
+ const float fmval[2], const bool children)
{
if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) {
/* name and first icon */
@@ -132,7 +119,7 @@ static TreeElement *outliner_dropzone_element(const SpaceOops *soops, TreeElemen
}
/* Used for drag and drop parenting */
-TreeElement *outliner_dropzone_find(const SpaceOops *soops, const float fmval[2], const int children)
+TreeElement *outliner_dropzone_find(const SpaceOops *soops, const float fmval[2], const bool children)
{
TreeElement *te;
@@ -601,6 +588,50 @@ void OUTLINER_OT_selected_toggle(wmOperatorType *ot)
/* Show Active --------------------------------------------------- */
+static void outliner_set_coordinates_element_recursive(SpaceOops *soops, TreeElement *te, int startx, int *starty)
+{
+ TreeStoreElem *tselem = TREESTORE(te);
+
+ /* store coord and continue, we need coordinates for elements outside view too */
+ te->xs = (float)startx;
+ te->ys = (float)(*starty);
+ *starty -= UI_UNIT_Y;
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ TreeElement *ten;
+ for (ten = te->subtree.first; ten; ten = ten->next) {
+ outliner_set_coordinates_element_recursive(soops, ten, startx + UI_UNIT_X, starty);
+ }
+ }
+}
+
+/* to retrieve coordinates with redrawing the entire tree */
+static void outliner_set_coordinates(ARegion *ar, SpaceOops *soops)
+{
+ TreeElement *te;
+ int starty = (int)(ar->v2d.tot.ymax) - UI_UNIT_Y;
+
+ for (te = soops->tree.first; te; te = te->next) {
+ outliner_set_coordinates_element_recursive(soops, te, 0, &starty);
+ }
+}
+
+/* return 1 when levels were opened */
+static int outliner_open_back(TreeElement *te)
+{
+ TreeStoreElem *tselem;
+ int retval = 0;
+
+ for (te = te->parent; te; te = te->parent) {
+ tselem = TREESTORE(te);
+ if (tselem->flag & TSE_CLOSED) {
+ tselem->flag &= ~TSE_CLOSED;
+ retval = 1;
+ }
+ }
+ return retval;
+}
+
static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceOops *so = CTX_wm_space_outliner(C);
@@ -617,6 +648,11 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
te = outliner_find_id(so, &so->tree, (ID *)OBACT);
if (te) {
+ /* open up tree to active object */
+ if (outliner_open_back(te)) {
+ outliner_set_coordinates(ar, so);
+ }
+
/* make te->ys center of view */
ytop = te->ys + BLI_rcti_size_y(&v2d->mask) / 2;
if (ytop > 0) ytop = 0;
@@ -642,7 +678,7 @@ void OUTLINER_OT_show_active(wmOperatorType *ot)
/* identifiers */
ot->name = "Show Active";
ot->idname = "OUTLINER_OT_show_active";
- ot->description = "Adjust the view so that the active Object is shown centered";
+ ot->description = "Open up the tree and adjust the view so that the active Object is shown centered";
/* callbacks */
ot->exec = outliner_show_active_exec;
@@ -690,37 +726,6 @@ void OUTLINER_OT_scroll_page(wmOperatorType *ot)
#if 0
-/* recursive helper for function below */
-static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te, int startx, int *starty)
-{
- TreeStoreElem *tselem = TREESTORE(te);
-
- /* store coord and continue, we need coordinates for elements outside view too */
- te->xs = (float)startx;
- te->ys = (float)(*starty);
- *starty -= UI_UNIT_Y;
-
- if (TSELEM_OPEN(tselem, soops)) {
- TreeElement *ten;
- for (ten = te->subtree.first; ten; ten = ten->next) {
- outliner_set_coordinates_element(soops, ten, startx + UI_UNIT_X, starty);
- }
- }
-
-}
-
-/* to retrieve coordinates with redrawing the entire tree */
-static void outliner_set_coordinates(ARegion *ar, SpaceOops *soops)
-{
- TreeElement *te;
- int starty = (int)(ar->v2d.tot.ymax) - UI_UNIT_Y;
- int startx = 0;
-
- for (te = soops->tree.first; te; te = te->next) {
- outliner_set_coordinates_element(soops, te, startx, &starty);
- }
-}
-
/* find next element that has this name */
static TreeElement *outliner_find_name(SpaceOops *soops, ListBase *lb, char *name, int flags,
TreeElement *prev, int *prevFound)
@@ -1305,7 +1310,7 @@ static KeyingSet *verify_active_keyingset(Scene *scene, short add)
// XXX the default settings have yet to evolve
if ((add) && (ks == NULL)) {
ks = BKE_keyingset_add(&scene->keyingsets, NULL, NULL, KEYINGSET_ABSOLUTE, 0);
- scene->active_keyingset = BLI_countlist(&scene->keyingsets);
+ scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
}
return ks;
@@ -1347,7 +1352,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
/* TODO: what do we do with group name?
* for now, we don't supply one, and just let this use the KeyingSet name */
BKE_keyingset_add_path(ks, id, NULL, path, array_index, flag, groupmode);
- ks->active_path = BLI_countlist(&ks->paths);
+ ks->active_path = BLI_listbase_count(&ks->paths);
break;
}
case KEYINGSET_EDITMODE_REMOVE:
@@ -1453,6 +1458,62 @@ void OUTLINER_OT_keyingset_remove_selected(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/* ************************************************************** */
+/* ORPHANED DATABLOCKS */
+
+static int ed_operator_outliner_id_orphans_active(bContext *C)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ if ((sa) && (sa->spacetype == SPACE_OUTLINER)) {
+ SpaceOops *so = CTX_wm_space_outliner(C);
+ return (so->outlinevis == SO_ID_ORPHANS);
+ }
+ return 0;
+}
+
+/* Purge Orphans Operator --------------------------------------- */
+
+static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(evt))
+{
+ /* present a prompt to informing users that this change is irreversible */
+ return WM_operator_confirm_message(C, op,
+ "Purging unused datablocks cannot be undone. "
+ "Click here to proceed...");
+}
+
+static int outliner_orphans_purge_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ /* Firstly, ensure that the file has been saved,
+ * so that the latest changes since the last save
+ * are retained...
+ */
+ WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_EXEC_DEFAULT, NULL);
+
+ /* Now, reload the file to get rid of the orphans... */
+ WM_operator_name_call(C, "WM_OT_revert_mainfile", WM_OP_EXEC_DEFAULT, NULL);
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->idname = "OUTLINER_OT_orphans_purge";
+ ot->name = "Purge All";
+ ot->description = "Clear all orphaned datablocks without any users from the file (cannot be undone)";
+
+ /* callbacks */
+ ot->invoke = outliner_orphans_purge_invoke;
+ ot->exec = outliner_orphans_purge_exec;
+ ot->poll = ed_operator_outliner_id_orphans_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ************************************************************** */
+/* DRAG AND DROP OPERATORS */
+
/* ******************** Parent Drop Operator *********************** */
static int parent_drop_exec(bContext *C, wmOperator *op)
@@ -1500,7 +1561,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
/* Find object hovered over */
- te = outliner_dropzone_find(soops, fmval, 1);
+ te = outliner_dropzone_find(soops, fmval, true);
if (te) {
RNA_string_set(op->ptr, "parent", te->name);
@@ -1543,8 +1604,8 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
else {
/* Menu creation */
wmOperatorType *ot = WM_operatortype_find("OUTLINER_OT_parent_drop", false);
- uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Set Parent To"), ICON_NONE);
- uiLayout *layout = uiPupMenuLayout(pup);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Set Parent To"), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
PointerRNA ptr;
@@ -1615,9 +1676,9 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0);
}
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
}
else {
@@ -1715,7 +1776,7 @@ static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
/* Find object hovered over */
- te = outliner_dropzone_find(soops, fmval, 0);
+ te = outliner_dropzone_find(soops, fmval, false);
if (te) {
Base *base;
@@ -1785,7 +1846,7 @@ static int material_drop_invoke(bContext *C, wmOperator *op, const wmEvent *even
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
/* Find object hovered over */
- te = outliner_dropzone_find(soops, fmval, 1);
+ te = outliner_dropzone_find(soops, fmval, true);
if (te) {
RNA_string_set(op->ptr, "object", te->name);
@@ -1829,3 +1890,65 @@ void OUTLINER_OT_material_drop(wmOperatorType *ot)
RNA_def_string(ot->srna, "material", "Material", MAX_ID_NAME, "Material", "Target Material");
}
+static int group_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Main *bmain = CTX_data_main(C);
+ Group *group = NULL;
+ Object *ob = NULL;
+ Scene *scene = CTX_data_scene(C);
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ ARegion *ar = CTX_wm_region(C);
+ TreeElement *te = NULL;
+ char ob_name[MAX_ID_NAME - 2];
+ float fmval[2];
+
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+
+ /* Find object hovered over */
+ te = outliner_dropzone_find(soops, fmval, true);
+
+ if (te) {
+ group = (Group *)BKE_libblock_find_name(ID_GR, te->name);
+
+ RNA_string_get(op->ptr, "object", ob_name);
+ ob = (Object *)BKE_libblock_find_name(ID_OB, ob_name);
+
+ if (ELEM(NULL, group, ob)) {
+ return OPERATOR_CANCELLED;
+ }
+ if (BKE_group_object_exists(group, ob)) {
+ return OPERATOR_FINISHED;
+ }
+
+ if (BKE_group_object_cyclic_check(bmain, ob, group)) {
+ BKE_report(op->reports, RPT_ERROR, "Could not add the group because of dependency cycle detected");
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_group_object_add(group, ob, scene, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_CANCELLED;
+}
+
+void OUTLINER_OT_group_link(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Link Object to Group";
+ ot->description = "Link Object to Group in Outliner";
+ ot->idname = "OUTLINER_OT_group_link";
+
+ /* api callbacks */
+ ot->invoke = group_link_invoke;
+
+ ot->poll = ED_operator_outliner_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+ /* properties */
+ RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object");
+}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 317d33dd3e2..50fecebb742 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -104,6 +104,7 @@ typedef struct TreeElement {
#define TSE_KEYMAP 34
#define TSE_KEYMAP_ITEM 35
#define TSE_ID_BASE 36
+#define TSE_GP_LAYER 37
/* button events */
#define OL_NAMEBUTTON 1
@@ -166,6 +167,7 @@ void outliner_free_tree(ListBase *lb);
void outliner_cleanup_tree(struct SpaceOops *soops);
TreeElement *outliner_find_tse(struct SpaceOops *soops, TreeStoreElem *tse);
+TreeElement *outliner_find_tree_element(ListBase *lb, TreeStoreElem *store_elem);
TreeElement *outliner_find_id(struct SpaceOops *soops, ListBase *lb, struct ID *id);
struct ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode);
@@ -205,7 +207,7 @@ void group_toggle_renderability_cb(struct bContext *C, struct Scene *scene, Tree
void item_rename_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem);
-TreeElement *outliner_dropzone_find(const struct SpaceOops *soops, const float fmval[2], const int children);
+TreeElement *outliner_dropzone_find(const struct SpaceOops *soops, const float fmval[2], const bool children);
/* ...................................................... */
void OUTLINER_OT_item_activate(struct wmOperatorType *ot);
@@ -233,10 +235,13 @@ void OUTLINER_OT_keyingset_remove_selected(struct wmOperatorType *ot);
void OUTLINER_OT_drivers_add_selected(struct wmOperatorType *ot);
void OUTLINER_OT_drivers_delete_selected(struct wmOperatorType *ot);
+void OUTLINER_OT_orphans_purge(struct wmOperatorType *ot);
+
void OUTLINER_OT_parent_drop(struct wmOperatorType *ot);
void OUTLINER_OT_parent_clear(struct wmOperatorType *ot);
void OUTLINER_OT_scene_drop(struct wmOperatorType *ot);
void OUTLINER_OT_material_drop(struct wmOperatorType *ot);
+void OUTLINER_OT_group_link(struct wmOperatorType *ot);
/* outliner_tools.c ---------------------------------------------- */
@@ -247,7 +252,8 @@ void OUTLINER_OT_id_operation(struct wmOperatorType *ot);
void OUTLINER_OT_data_operation(struct wmOperatorType *ot);
void OUTLINER_OT_animdata_operation(struct wmOperatorType *ot);
void OUTLINER_OT_action_set(struct wmOperatorType *ot);
-
+void OUTLINER_OT_constraint_operation(struct wmOperatorType *ot);
+void OUTLINER_OT_modifier_operation(struct wmOperatorType *ot);
/* ---------------------------------------------------------------- */
/* outliner_ops.c */
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index d735b5e75cf..f5869575cc6 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -30,7 +30,6 @@
#include "DNA_space_types.h"
-#include "BLI_utildefines.h"
#include "RNA_access.h"
@@ -55,6 +54,8 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_data_operation);
WM_operatortype_append(OUTLINER_OT_animdata_operation);
WM_operatortype_append(OUTLINER_OT_action_set);
+ WM_operatortype_append(OUTLINER_OT_constraint_operation);
+ WM_operatortype_append(OUTLINER_OT_modifier_operation);
WM_operatortype_append(OUTLINER_OT_show_one_level);
WM_operatortype_append(OUTLINER_OT_show_active);
@@ -73,11 +74,14 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_drivers_add_selected);
WM_operatortype_append(OUTLINER_OT_drivers_delete_selected);
+
+ WM_operatortype_append(OUTLINER_OT_orphans_purge);
WM_operatortype_append(OUTLINER_OT_parent_drop);
WM_operatortype_append(OUTLINER_OT_parent_clear);
WM_operatortype_append(OUTLINER_OT_scene_drop);
WM_operatortype_append(OUTLINER_OT_material_drop);
+ WM_operatortype_append(OUTLINER_OT_group_link);
}
void outliner_keymap(wmKeyConfig *keyconf)
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 6f5bf712d55..730ee02f448 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -290,6 +290,10 @@ static eOLDrawState tree_element_active_material(
}
}
if (set != OL_SETSEL_NONE) {
+ /* Tagging object for update seems a bit stupid here, but looks like we have to do it
+ * for render views to update. See T42973.
+ * Note that RNA material update does it too, see e.g. rna_MaterialSlot_update(). */
+ DAG_id_tag_update((ID *)ob, OB_RECALC_OB);
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL);
}
return OL_DRAWSEL_NONE;
@@ -771,7 +775,7 @@ static eOLDrawState tree_element_active_sequence_dup(
continue;
}
-// if (!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name))
+// if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name))
// XXX select_single_seq(p, 0);
p = p->next;
}
@@ -869,6 +873,9 @@ eOLDrawState tree_element_type_active(
return tree_element_active_sequence_dup(scene, te, tselem, set);
case TSE_KEYMAP_ITEM:
return tree_element_active_keymap_item(C, te, tselem, set);
+ case TSE_GP_LAYER:
+ //return tree_element_active_gplayer(C, scene, te, tselem, set);
+ break;
}
return OL_DRAWSEL_NONE;
@@ -911,7 +918,7 @@ static bool do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Sp
if (tselem->type != TSE_SEQUENCE && tselem->type != TSE_SEQ_STRIP && tselem->type != TSE_SEQUENCE_DUP)
tree_element_set_active_object(C, scene, soops, te,
(extend && tselem->type == 0) ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
- recursive && tselem->type == 0 );
+ recursive && tselem->type == 0);
if (tselem->type == 0) { // the lib blocks
/* editmode? */
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index d09ed1a100e..64e00589712 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -33,6 +33,7 @@
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
#include "DNA_linestyle_types.h"
@@ -43,12 +44,15 @@
#include "DNA_sequence_types.h"
#include "DNA_world_types.h"
#include "DNA_object_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_modifier_types.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BKE_animsys.h"
#include "BKE_context.h"
+#include "BKE_constraint.h"
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_group.h"
@@ -69,6 +73,7 @@
#include "UI_interface.h"
#include "UI_view2d.h"
+#include "UI_resources.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -499,19 +504,39 @@ static void refreshdrivers_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te
/* --------------------------------- */
+typedef enum eOutliner_PropDataOps {
+ OL_DOP_SELECT = 1,
+ OL_DOP_DESELECT,
+ OL_DOP_HIDE,
+ OL_DOP_UNHIDE,
+ OL_DOP_SELECT_LINKED,
+} eOutliner_PropDataOps;
+
+typedef enum eOutliner_PropConstraintOps {
+ OL_CONSTRAINTOP_ENABLE = 1,
+ OL_CONSTRAINTOP_DISABLE,
+ OL_CONSTRAINTOP_DELETE
+} eOutliner_PropConstraintOps;
+
+typedef enum eOutliner_PropModifierOps {
+ OL_MODIFIER_OP_TOGVIS = 1,
+ OL_MODIFIER_OP_TOGREN,
+ OL_MODIFIER_OP_DELETE
+} eOutliner_PropModifierOps;
+
static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
{
bPoseChannel *pchan = (bPoseChannel *)te->directdata;
- if (event == 1)
+ if (event == OL_DOP_SELECT)
pchan->bone->flag |= BONE_SELECTED;
- else if (event == 2)
+ else if (event == OL_DOP_DESELECT)
pchan->bone->flag &= ~BONE_SELECTED;
- else if (event == 3) {
+ else if (event == OL_DOP_HIDE) {
pchan->bone->flag |= BONE_HIDDEN_P;
pchan->bone->flag &= ~BONE_SELECTED;
}
- else if (event == 4)
+ else if (event == OL_DOP_UNHIDE)
pchan->bone->flag &= ~BONE_HIDDEN_P;
}
@@ -519,15 +544,15 @@ static void bone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), v
{
Bone *bone = (Bone *)te->directdata;
- if (event == 1)
+ if (event == OL_DOP_SELECT)
bone->flag |= BONE_SELECTED;
- else if (event == 2)
+ else if (event == OL_DOP_DESELECT)
bone->flag &= ~BONE_SELECTED;
- else if (event == 3) {
+ else if (event == OL_DOP_HIDE) {
bone->flag |= BONE_HIDDEN_P;
bone->flag &= ~BONE_SELECTED;
}
- else if (event == 4)
+ else if (event == OL_DOP_UNHIDE)
bone->flag &= ~BONE_HIDDEN_P;
}
@@ -535,22 +560,22 @@ static void ebone_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem),
{
EditBone *ebone = (EditBone *)te->directdata;
- if (event == 1)
+ if (event == OL_DOP_SELECT)
ebone->flag |= BONE_SELECTED;
- else if (event == 2)
+ else if (event == OL_DOP_DESELECT)
ebone->flag &= ~BONE_SELECTED;
- else if (event == 3) {
+ else if (event == OL_DOP_HIDE) {
ebone->flag |= BONE_HIDDEN_A;
ebone->flag &= ~BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL;
}
- else if (event == 4)
+ else if (event == OL_DOP_UNHIDE)
ebone->flag &= ~BONE_HIDDEN_A;
}
static void sequence_cb(int event, TreeElement *te, TreeStoreElem *tselem, void *scene_ptr)
{
Sequence *seq = (Sequence *)te->directdata;
- if (event == 1) {
+ if (event == OL_DOP_SELECT) {
Scene *scene = (Scene *)scene_ptr;
Editing *ed = BKE_sequencer_editing_get(scene, false);
if (BLI_findindex(ed->seqbasep, seq) != -1) {
@@ -561,9 +586,23 @@ static void sequence_cb(int event, TreeElement *te, TreeStoreElem *tselem, void
(void)tselem;
}
+static void gp_layer_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
+{
+ bGPDlayer *gpl = (bGPDlayer *)te->directdata;
+
+ if (event == OL_DOP_SELECT)
+ gpl->flag |= GP_LAYER_SELECT;
+ else if (event == OL_DOP_DESELECT)
+ gpl->flag &= ~GP_LAYER_SELECT;
+ else if (event == OL_DOP_HIDE)
+ gpl->flag |= GP_LAYER_HIDE;
+ else if (event == OL_DOP_UNHIDE)
+ gpl->flag &= ~GP_LAYER_HIDE;
+}
+
static void data_select_linked_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v)
{
- if (event == 5) {
+ if (event == OL_DOP_SELECT_LINKED) {
if (RNA_struct_is_ID(te->rnaptr.type)) {
bContext *C = (bContext *) C_v;
ID *id = te->rnaptr.data;
@@ -573,6 +612,68 @@ static void data_select_linked_cb(int event, TreeElement *te, TreeStoreElem *UNU
}
}
+static void constraint_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v)
+{
+ bContext *C = C_v;
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ bConstraint *constraint = (bConstraint *)te->directdata;
+ Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
+
+ if (event == OL_CONSTRAINTOP_ENABLE) {
+ constraint->flag &= ~CONSTRAINT_OFF;
+ ED_object_constraint_update(ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
+ }
+ else if (event == OL_CONSTRAINTOP_DISABLE) {
+ constraint->flag = CONSTRAINT_OFF;
+ ED_object_constraint_update(ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
+ }
+ else if (event == OL_CONSTRAINTOP_DELETE) {
+ ListBase *lb = NULL;
+
+ if (TREESTORE(te->parent->parent)->type == TSE_POSE_CHANNEL) {
+ lb = &((bPoseChannel *)te->parent->parent->directdata)->constraints;
+ }
+ else {
+ lb = &ob->constraints;
+ }
+
+ if (BKE_constraint_remove_ex(lb, ob, constraint, true)) {
+ /* there's no active constraint now, so make sure this is the case */
+ BKE_constraints_active_set(&ob->constraints, NULL);
+ ED_object_constraint_update(ob); /* needed to set the flags on posebones correctly */
+ WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, ob);
+ te->store_elem->flag &= ~TSE_SELECTED;
+ }
+ }
+}
+
+static void modifier_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *Carg)
+{
+ bContext *C = (bContext *)Carg;
+ Main *bmain = CTX_data_main(C);
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ ModifierData *md = (ModifierData *)te->directdata;
+ Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
+
+ if (event == OL_MODIFIER_OP_TOGVIS) {
+ md->mode ^= eModifierMode_Realtime;
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ }
+ else if (event == OL_MODIFIER_OP_TOGREN) {
+ md->mode ^= eModifierMode_Render;
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ }
+ else if (event == OL_MODIFIER_OP_DELETE) {
+ ED_object_modifier_remove(NULL, bmain, ob, md);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER | NA_REMOVED, ob);
+ te->store_elem->flag &= ~TSE_SELECTED;
+ }
+}
+
static void outliner_do_data_operation(SpaceOops *soops, int type, int event, ListBase *lb,
void (*operation_cb)(int, TreeElement *, TreeStoreElem *, void *),
void *arg)
@@ -593,14 +694,57 @@ static void outliner_do_data_operation(SpaceOops *soops, int type, int event, Li
}
}
+static void outline_delete_hierarchy(bContext *C, Scene *scene, Base *base)
+{
+ Base *child_base;
+ Object *parent;
+
+ if (!base) {
+ return;
+ }
+
+ for (child_base = scene->base.first; child_base; child_base = child_base->next) {
+ for (parent = child_base->object->parent; parent && (parent != base->object); parent = parent->parent);
+ if (parent) {
+ outline_delete_hierarchy(C, scene, child_base);
+ }
+ }
+
+ ED_base_object_free_and_unlink(CTX_data_main(C), scene, base);
+}
+
+static void object_delete_hierarchy_cb(
+ bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
+{
+ Base *base = (Base *)te->directdata;
+ Object *obedit = scene->obedit;
+
+ if (!base) {
+ base = BKE_scene_base_find(scene, (Object *)tselem->id);
+ }
+ if (base) {
+ /* Check also library later. */
+ for (; obedit && (obedit != base->object); obedit = obedit->parent);
+ if (obedit == base->object) {
+ ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
+ }
+
+ outline_delete_hierarchy(C, scene, base);
+ te->directdata = NULL;
+ tselem->id = NULL;
+ }
+
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+}
+
/* **************************************** */
enum {
- OL_OP_ENDMARKER = 0,
- OL_OP_SELECT,
+ OL_OP_SELECT = 1,
OL_OP_DESELECT,
OL_OP_SELECT_HIERARCHY,
OL_OP_DELETE,
+ OL_OP_DELETE_HIERARCHY,
OL_OP_LOCALIZED, /* disabled, see below */
OL_OP_TOGVIS,
OL_OP_TOGSEL,
@@ -613,11 +757,12 @@ static EnumPropertyItem prop_object_op_types[] = {
{OL_OP_DESELECT, "DESELECT", 0, "Deselect", ""},
{OL_OP_SELECT_HIERARCHY, "SELECT_HIERARCHY", 0, "Select Hierarchy", ""},
{OL_OP_DELETE, "DELETE", 0, "Delete", ""},
+ {OL_OP_DELETE_HIERARCHY, "DELETE_HIERARCHY", 0, "Delete Hierarchy", ""},
{OL_OP_TOGVIS, "TOGVIS", 0, "Toggle Visible", ""},
{OL_OP_TOGSEL, "TOGSEL", 0, "Toggle Selectable", ""},
{OL_OP_TOGREN, "TOGREN", 0, "Toggle Renderable", ""},
{OL_OP_RENAME, "RENAME", 0, "Rename", ""},
- {OL_OP_ENDMARKER, NULL, 0, NULL, NULL}
+ {0, NULL, 0, NULL, NULL}
};
static int outliner_object_operation_exec(bContext *C, wmOperator *op)
@@ -672,6 +817,16 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
str = "Delete Objects";
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
}
+ else if (event == OL_OP_DELETE_HIERARCHY) {
+ outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_hierarchy_cb);
+
+ /* XXX: See OL_OP_DELETE comment above. */
+ outliner_cleanup_tree(soops);
+
+ DAG_relations_tag_update(bmain);
+ str = "Delete Object Hierarchy";
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
+ }
else if (event == OL_OP_LOCALIZED) { /* disabled, see above enum (ton) */
outliner_do_object_operation(C, scene, soops, &soops->tree, id_local_cb);
str = "Localized Objects";
@@ -725,15 +880,26 @@ void OUTLINER_OT_object_operation(wmOperatorType *ot)
/* **************************************** */
+typedef enum eOutliner_PropGroupOps {
+ OL_GROUPOP_UNLINK = 1,
+ OL_GROUPOP_LOCAL,
+ OL_GROUPOP_LINK,
+ OL_GROUPOP_INSTANCE,
+ OL_GROUPOP_TOGVIS,
+ OL_GROUPOP_TOGSEL,
+ OL_GROUPOP_TOGREN,
+ OL_GROUPOP_RENAME,
+} eOutliner_PropGroupOps;
+
static EnumPropertyItem prop_group_op_types[] = {
- {0, "UNLINK", 0, "Unlink Group", ""},
- {1, "LOCAL", 0, "Make Local Group", ""},
- {2, "LINK", 0, "Link Group Objects to Scene", ""},
- {3, "INSTANCE", 0, "Instance Groups in Scene", ""},
- {4, "TOGVIS", 0, "Toggle Visible Group", ""},
- {5, "TOGSEL", 0, "Toggle Selectable", ""},
- {6, "TOGREN", 0, "Toggle Renderable", ""},
- {7, "RENAME", 0, "Rename", ""},
+ {OL_GROUPOP_UNLINK, "UNLINK", 0, "Unlink Group", ""},
+ {OL_GROUPOP_LOCAL, "LOCAL", 0, "Make Local Group", ""},
+ {OL_GROUPOP_LINK, "LINK", 0, "Link Group Objects to Scene", ""},
+ {OL_GROUPOP_INSTANCE, "INSTANCE", 0, "Instance Groups in Scene", ""},
+ {OL_GROUPOP_TOGVIS, "TOGVIS", 0, "Toggle Visible Group", ""},
+ {OL_GROUPOP_TOGSEL, "TOGSEL", 0, "Toggle Selectable", ""},
+ {OL_GROUPOP_TOGREN, "TOGREN", 0, "Toggle Renderable", ""},
+ {OL_GROUPOP_RENAME, "RENAME", 0, "Rename", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -750,17 +916,32 @@ static int outliner_group_operation_exec(bContext *C, wmOperator *op)
event = RNA_enum_get(op->ptr, "type");
switch (event) {
- case 0: outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_group_cb); break;
- case 1: outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); break;
- case 2: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_linkobs2scene_cb); break;
- case 3: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_instance_cb); break;
- case 4: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_visibility_cb); break;
- case 5: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_selectability_cb); break;
- case 6: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_renderability_cb); break;
- case 7: outliner_do_libdata_operation(C, scene, soops, &soops->tree, item_rename_cb); break;
+ case OL_GROUPOP_UNLINK:
+ outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_group_cb);
+ break;
+ case OL_GROUPOP_LOCAL:
+ outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb);
+ break;
+ case OL_GROUPOP_LINK:
+ outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_linkobs2scene_cb);
+ break;
+ case OL_GROUPOP_INSTANCE:
+ outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_instance_cb);
+ break;
+ case OL_GROUPOP_TOGVIS:
+ outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_visibility_cb);
+ break;
+ case OL_GROUPOP_TOGSEL:
+ outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_selectability_cb);
+ break;
+ case OL_GROUPOP_TOGREN:
+ outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_renderability_cb);
+ break;
+ case OL_GROUPOP_RENAME:
+ outliner_do_libdata_operation(C, scene, soops, &soops->tree, item_rename_cb);
+ break;
default:
BLI_assert(0);
- return OPERATOR_CANCELLED;
}
@@ -1195,12 +1376,105 @@ void OUTLINER_OT_animdata_operation(wmOperatorType *ot)
/* **************************************** */
+static EnumPropertyItem prop_constraint_op_types[] = {
+ {OL_CONSTRAINTOP_ENABLE, "ENABLE", ICON_RESTRICT_VIEW_OFF, "Enable", ""},
+ {OL_CONSTRAINTOP_DISABLE, "DISABLE", ICON_RESTRICT_VIEW_ON, "Disable", ""},
+ {OL_CONSTRAINTOP_DELETE, "DELETE", ICON_X, "Delete", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static int outliner_constraint_operation_exec(bContext *C, wmOperator *op)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ eOutliner_PropConstraintOps event;
+
+ event = RNA_enum_get(op->ptr, "type");
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, constraint_cb, C);
+
+ if (event == OL_CONSTRAINTOP_DELETE) {
+ outliner_cleanup_tree(soops);
+ }
+
+ ED_undo_push(C, "Constraint operation");
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_constraint_operation(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Outliner Constraint Operation";
+ ot->idname = "OUTLINER_OT_constraint_operation";
+ ot->description = "";
+
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_constraint_operation_exec;
+ ot->poll = ED_operator_outliner_active;
+
+ ot->flag = 0;
+
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_constraint_op_types, 0, "Constraint Operation", "");
+}
+
+/* ******************** */
+
+static EnumPropertyItem prop_modifier_op_types[] = {
+ {OL_MODIFIER_OP_TOGVIS, "TOGVIS", ICON_RESTRICT_VIEW_OFF, "Toggle viewport use", ""},
+ {OL_MODIFIER_OP_TOGREN, "TOGREN", ICON_RESTRICT_RENDER_OFF, "Toggle render use", ""},
+ {OL_MODIFIER_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static int outliner_modifier_operation_exec(bContext *C, wmOperator *op)
+{
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
+ eOutliner_PropModifierOps event;
+
+ event = RNA_enum_get(op->ptr, "type");
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, modifier_cb, C);
+
+ if (event == OL_MODIFIER_OP_DELETE) {
+ outliner_cleanup_tree(soops);
+ }
+
+ ED_undo_push(C, "Modifier operation");
+
+ return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_modifier_operation(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Outliner Modifier Operation";
+ ot->idname = "OUTLINER_OT_modifier_operation";
+ ot->description = "";
+
+ /* callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = outliner_modifier_operation_exec;
+ ot->poll = ED_operator_outliner_active;
+
+ ot->flag = 0;
+
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_modifier_op_types, 0, "Modifier Operation", "");
+}
+
+/* ******************** */
+
+// XXX: select linked is for RNA structs only
static EnumPropertyItem prop_data_op_types[] = {
- {1, "SELECT", 0, "Select", ""},
- {2, "DESELECT", 0, "Deselect", ""},
- {3, "HIDE", 0, "Hide", ""},
- {4, "UNHIDE", 0, "Unhide", ""},
- {5, "SELECT_LINKED", 0, "Select Linked", ""},
+ {OL_DOP_SELECT, "SELECT", 0, "Select", ""},
+ {OL_DOP_DESELECT, "DESELECT", 0, "Deselect", ""},
+ {OL_DOP_HIDE, "HIDE", 0, "Hide", ""},
+ {OL_DOP_UNHIDE, "UNHIDE", 0, "Unhide", ""},
+ {OL_DOP_SELECT_LINKED, "SELECT_LINKED", 0, "Select Linked", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -1208,7 +1482,7 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op)
{
SpaceOops *soops = CTX_wm_space_outliner(C);
int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
- int event;
+ eOutliner_PropDataOps event;
/* check for invalid states */
if (soops == NULL)
@@ -1217,9 +1491,6 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op)
event = RNA_enum_get(op->ptr, "type");
set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
- if (event <= 0)
- return OPERATOR_CANCELLED;
-
switch (datalevel) {
case TSE_POSE_CHANNEL:
{
@@ -1252,8 +1523,16 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op)
}
break;
+ case TSE_GP_LAYER:
+ {
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, gp_layer_cb, NULL);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
+ ED_undo_push(C, "Grease Pencil Layer operation");
+ }
+ break;
+
case TSE_RNA_STRUCT:
- if (event == 5) {
+ if (event == OL_DOP_SELECT_LINKED) {
outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C);
}
break;
@@ -1342,6 +1621,15 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S
else if (ELEM(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) {
/*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/
}
+ else if (datalevel == TSE_ID_BASE) {
+ /* do nothing... there are no ops needed here yet */
+ }
+ else if (datalevel == TSE_CONSTRAINT) {
+ WM_operator_name_call(C, "OUTLINER_OT_constraint_operation", WM_OP_INVOKE_REGION_WIN, NULL);
+ }
+ else if (datalevel == TSE_MODIFIER) {
+ WM_operator_name_call(C, "OUTLINER_OT_modifier_operation", WM_OP_INVOKE_REGION_WIN, NULL);
+ }
else {
WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL);
}
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 5801dd126e3..7aac6a7797c 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -38,6 +38,7 @@
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_camera_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_group_types.h"
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
@@ -196,7 +197,7 @@ void outliner_cleanup_tree(SpaceOops *soops)
}
/* Find specific item from the treestore */
-static TreeElement *outliner_find_tree_element(ListBase *lb, TreeStoreElem *store_elem)
+TreeElement *outliner_find_tree_element(ListBase *lb, TreeStoreElem *store_elem)
{
TreeElement *te, *tes;
for (te = lb->first; te; te = te->next) {
@@ -430,11 +431,13 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
// TODO: move this to the front?
if (outliner_animdata_test(sce->adt))
outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0);
+
+ outliner_add_element(soops, lb, sce->gpd, te, 0, 0);
outliner_add_element(soops, lb, sce->world, te, 0, 0);
#ifdef WITH_FREESTYLE
- if (STREQ(sce->r.engine, "BLENDER_RENDER") && (sce->r.mode & R_EDGE_FRS))
+ if (STREQ(sce->r.engine, RE_engine_id_BLENDER_RENDER) && (sce->r.mode & R_EDGE_FRS))
outliner_add_line_styles(soops, lb, sce, te);
#endif
}
@@ -451,6 +454,8 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
if (ob->proxy && ob->id.lib == NULL)
outliner_add_element(soops, &te->subtree, ob->proxy, te, TSE_PROXY, 0);
+
+ outliner_add_element(soops, &te->subtree, ob->gpd, te, 0, 0);
outliner_add_element(soops, &te->subtree, ob->data, te, 0, 0);
@@ -809,6 +814,22 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
}
break;
}
+ case ID_GD:
+ {
+ bGPdata *gpd = (bGPdata *)id;
+ bGPDlayer *gpl;
+ int a = 0;
+
+ if (outliner_animdata_test(gpd->adt))
+ outliner_add_element(soops, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
+
+ // TODO: base element for layers?
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ outliner_add_element(soops, &te->subtree, gpl, te, TSE_GP_LAYER, a);
+ a++;
+ }
+ break;
+ }
}
}
@@ -856,6 +877,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
else if (type == TSE_ANIM_DATA) {
/* pass */
}
+ else if (type == TSE_GP_LAYER) {
+ /* pass */
+ }
else if (type == TSE_ID_BASE) {
/* pass */
}
@@ -938,6 +962,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
}
}
+ else if (type == TSE_GP_LAYER) {
+ bGPDlayer *gpl = (bGPDlayer *)idv;
+
+ te->name = gpl->info;
+ te->directdata = gpl;
+ }
else if (type == TSE_SEQUENCE) {
Sequence *seq = (Sequence *) idv;
Sequence *p;
@@ -1160,7 +1190,7 @@ static int need_add_seq_dup(Sequence *seq)
continue;
}
- if (!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name))
+ if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name))
return(2);
p = p->prev;
}
@@ -1172,7 +1202,7 @@ static int need_add_seq_dup(Sequence *seq)
continue;
}
- if (!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name))
+ if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name))
return(0);
p = p->next;
}
@@ -1191,12 +1221,90 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t
continue;
}
- if (!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name))
+ if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name))
/* ch = */ /* UNUSED */ outliner_add_element(soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
p = p->next;
}
}
+
+/* ----------------------------------------------- */
+
+
+static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeElement *te, Library *lib)
+{
+ TreeElement *ten;
+ ListBase *lbarray[MAX_LIBARRAY];
+ int a, tot;
+
+ tot = set_listbasepointers(mainvar, lbarray);
+ for (a = 0; a < tot; a++) {
+ if (lbarray[a]->first) {
+ ID *id = lbarray[a]->first;
+
+ /* check if there's data in current lib */
+ for (; id; id = id->next)
+ if (id->lib == lib)
+ break;
+
+ if (id) {
+ ten = outliner_add_element(soops, &te->subtree, (void *)lbarray[a], NULL, TSE_ID_BASE, 0);
+ ten->directdata = lbarray[a];
+
+ ten->name = (char *)BKE_idcode_to_name_plural(GS(id->name));
+ if (ten->name == NULL)
+ ten->name = "UNKNOWN";
+
+ for (id = lbarray[a]->first; id; id = id->next) {
+ if (id->lib == lib)
+ outliner_add_element(soops, &ten->subtree, id, ten, 0, 0);
+ }
+ }
+ }
+ }
+
+}
+
+static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
+{
+ TreeElement *ten;
+ ListBase *lbarray[MAX_LIBARRAY];
+ int a, tot;
+
+ tot = set_listbasepointers(mainvar, lbarray);
+ for (a = 0; a < tot; a++) {
+ if (lbarray[a]->first) {
+ ID *id = lbarray[a]->first;
+
+ /* check if there are any datablocks of this type which are orphans */
+ for (; id; id = id->next) {
+ if (ID_REAL_USERS(id) <= 0)
+ break;
+ }
+
+ if (id) {
+ /* header for this type of datablock */
+ /* TODO's:
+ * - Add a parameter to BKE_idcode_to_name_plural to get a sane "user-visible" name instead?
+ * - Ensure that this uses nice icons for the datablock type involved instead of the dot?
+ */
+ ten = outliner_add_element(soops, &soops->tree, (void *)lbarray[a], NULL, TSE_ID_BASE, 0);
+ ten->directdata = lbarray[a];
+
+ ten->name = (char *)BKE_idcode_to_name_plural(GS(id->name));
+ if (ten->name == NULL)
+ ten->name = "UNKNOWN";
+
+ /* add the orphaned datablocks - these will not be added with any subtrees attached */
+ for (id = lbarray[a]->first; id; id = id->next) {
+ if (ID_REAL_USERS(id) <= 0)
+ outliner_add_element(soops, &ten->subtree, id, ten, 0, 0);
+ }
+ }
+ }
+ }
+}
+
/* ======================================================= */
/* Generic Tree Building helpers - order these are called is top to bottom */
@@ -1311,7 +1419,10 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
TreeElement *te;
TreeStoreElem *tselem;
int totelem = 0;
-
+
+ if (soops->flag & SO_SKIP_SORT_ALPHA)
+ return;
+
te = lb->last;
if (te == NULL) return;
tselem = TREESTORE(te);
@@ -1371,59 +1482,42 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
/* Filtering ----------------------------------------------- */
-static int outliner_filter_has_name(TreeElement *te, const char *name, int flags)
+static bool outliner_filter_has_name(TreeElement *te, const char *name, int flags)
{
-#if 0
- int found = 0;
-
- /* determine if match */
- if (flags & SO_FIND_CASE_SENSITIVE) {
- if (flags & SO_FIND_COMPLETE)
- found = strcmp(te->name, name) == 0;
- else
- found = strstr(te->name, name) != NULL;
- }
- else {
- if (flags & SO_FIND_COMPLETE)
- found = BLI_strcasecmp(te->name, name) == 0;
- else
- found = BLI_strcasestr(te->name, name) != NULL;
- }
-#else
-
int fn_flag = 0;
- int found = 0;
-
+
if ((flags & SO_FIND_CASE_SENSITIVE) == 0)
fn_flag |= FNM_CASEFOLD;
- if (flags & SO_FIND_COMPLETE) {
- found = fnmatch(name, te->name, fn_flag) == 0;
- }
- else {
- char fn_name[sizeof(((struct SpaceOops *)NULL)->search_string) + 2];
- BLI_snprintf(fn_name, sizeof(fn_name), "*%s*", name);
- found = fnmatch(fn_name, te->name, fn_flag) == 0;
- }
- return found;
-#endif
+ return fnmatch(name, te->name, fn_flag) == 0;
}
static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
{
TreeElement *te, *ten;
TreeStoreElem *tselem;
-
+ char search_buff[sizeof(((struct SpaceOops *)NULL)->search_string) + 2];
+ char *search_string;
+
/* although we don't have any search string, we return true
* since the entire tree is ok then...
*/
if (soops->search_string[0] == 0)
return 1;
+ if (soops->search_flags & SO_FIND_COMPLETE) {
+ search_string = soops->search_string;
+ }
+ else {
+ /* Implicitly add heading/trailing wildcards if needed. */
+ BLI_strncpy_ensure_pad(search_buff, soops->search_string, '*', sizeof(search_buff));
+ search_string = search_buff;
+ }
+
for (te = lb->first; te; te = ten) {
ten = te->next;
- if (0 == outliner_filter_has_name(te, soops->search_string, soops->search_flags)) {
+ if (!outliner_filter_has_name(te, search_string, soops->search_flags)) {
/* item isn't something we're looking for, but...
* - if the subtree is expanded, check if there are any matches that can be easily found
* so that searching for "cu" in the default scene will still match the Cube
@@ -1458,42 +1552,6 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
return (BLI_listbase_is_empty(lb) == false);
}
-static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeElement *te, Library *lib)
-{
- TreeElement *ten;
- ListBase *lbarray[MAX_LIBARRAY];
- int a, tot;
-
- tot = set_listbasepointers(mainvar, lbarray);
- for (a = 0; a < tot; a++) {
- if (lbarray[a]->first) {
- ID *id = lbarray[a]->first;
-
- /* check if there's data in current lib */
- for (; id; id = id->next)
- if (id->lib == lib)
- break;
-
- if (id) {
-
- ten = outliner_add_element(soops, &te->subtree, (void *)lbarray[a], NULL, TSE_ID_BASE, 0);
- ten->directdata = lbarray[a];
-
- ten->name = (char *)BKE_idcode_to_name_plural(GS(id->name));
- if (ten->name == NULL)
- ten->name = "UNKNOWN";
-
- for (id = lbarray[a]->first; id; id = id->next) {
- if (id->lib == lib)
- outliner_add_element(soops, &ten->subtree, id, ten, 0, 0);
- }
- }
- }
- }
-
-}
-
-
/* ======================================================= */
/* Main Tree Building API */
@@ -1553,10 +1611,19 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
tselem = TREESTORE(ten);
lib = (Library *)tselem->id;
if (lib && lib->parent) {
- BLI_remlink(&soops->tree, ten);
par = (TreeElement *)lib->parent->id.newid;
- BLI_addtail(&par->subtree, ten);
- ten->parent = par;
+ if (tselem->id->flag & LIB_INDIRECT) {
+ /* Only remove from 'first level' if lib is not also directly used. */
+ BLI_remlink(&soops->tree, ten);
+ BLI_addtail(&par->subtree, ten);
+ ten->parent = par;
+ }
+ else {
+ /* Else, make a new copy of the libtree for our parent. */
+ TreeElement *dupten = outliner_add_element(soops, &par->subtree, lib, NULL, 0, 0);
+ outliner_add_library_contents(mainvar, soops, dupten, lib);
+ dupten->parent = par;
+ }
}
ten = nten;
}
@@ -1688,6 +1755,9 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
tselem->flag &= ~TSE_CLOSED;
}
}
+ else if (soops->outlinevis == SO_ID_ORPHANS) {
+ outliner_add_orphaned_datablocks(mainvar, soops);
+ }
else {
ten = outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0);
if (ten) ten->directdata = BASACT;
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 504d9628d98..e1aea8892b5 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -98,10 +98,10 @@ static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *e
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
if (drag->type == WM_DRAG_ID) {
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (GS(id->name) == ID_OB) {
/* Ensure item under cursor is valid drop target */
- TreeElement *te = outliner_dropzone_find(soops, fmval, 1);
+ TreeElement *te = outliner_dropzone_find(soops, fmval, true);
if (te && te->idcode == ID_OB && TREESTORE(te)->type == 0) {
Scene *scene;
@@ -129,7 +129,7 @@ static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *e
static void outliner_parent_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
RNA_string_set(drop->ptr, "child", id->name + 2);
}
@@ -148,10 +148,10 @@ static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *
}
if (drag->type == WM_DRAG_ID) {
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (GS(id->name) == ID_OB) {
if (((Object *)id)->parent) {
- if ((te = outliner_dropzone_find(soops, fmval, 1))) {
+ if ((te = outliner_dropzone_find(soops, fmval, true))) {
TreeStoreElem *tselem = TREESTORE(te);
switch (te->idcode) {
@@ -171,7 +171,7 @@ static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *
static void outliner_parent_clear_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
RNA_string_set(drop->ptr, "dragged_obj", id->name + 2);
/* Set to simple parent clear type. Avoid menus for drag and drop if possible.
@@ -188,10 +188,10 @@ static int outliner_scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *ev
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
if (drag->type == WM_DRAG_ID) {
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (GS(id->name) == ID_OB) {
/* Ensure item under cursor is valid drop target */
- TreeElement *te = outliner_dropzone_find(soops, fmval, 0);
+ TreeElement *te = outliner_dropzone_find(soops, fmval, false);
return (te && te->idcode == ID_SCE && TREESTORE(te)->type == 0);
}
}
@@ -200,7 +200,7 @@ static int outliner_scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *ev
static void outliner_scene_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
RNA_string_set(drop->ptr, "object", id->name + 2);
}
@@ -213,10 +213,10 @@ static int outliner_material_drop_poll(bContext *C, wmDrag *drag, const wmEvent
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
if (drag->type == WM_DRAG_ID) {
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (GS(id->name) == ID_MA) {
/* Ensure item under cursor is valid drop target */
- TreeElement *te = outliner_dropzone_find(soops, fmval, 1);
+ TreeElement *te = outliner_dropzone_find(soops, fmval, true);
return (te && te->idcode == ID_OB && TREESTORE(te)->type == 0);
}
}
@@ -225,11 +225,35 @@ static int outliner_material_drop_poll(bContext *C, wmDrag *drag, const wmEvent
static void outliner_material_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
RNA_string_set(drop->ptr, "material", id->name + 2);
}
+static int outliner_group_link_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+{
+ ARegion *ar = CTX_wm_region(C);
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+ float fmval[2];
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
+
+ if (drag->type == WM_DRAG_ID) {
+ ID *id = drag->poin;
+ if (GS(id->name) == ID_OB) {
+ /* Ensure item under cursor is valid drop target */
+ TreeElement *te = outliner_dropzone_find(soops, fmval, true);
+ return (te && te->idcode == ID_GR && TREESTORE(te)->type == 0);
+ }
+ }
+ return 0;
+}
+
+static void outliner_group_link_copy(wmDrag *drag, wmDropBox *drop)
+{
+ ID *id = drag->poin;
+ RNA_string_set(drop->ptr, "object", id->name + 2);
+}
+
/* region dropbox definition */
static void outliner_dropboxes(void)
{
@@ -239,6 +263,7 @@ static void outliner_dropboxes(void)
WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", outliner_parent_clear_poll, outliner_parent_clear_copy);
WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", outliner_scene_drop_poll, outliner_scene_drop_copy);
WM_dropbox_add(lb, "OUTLINER_OT_material_drop", outliner_material_drop_poll, outliner_material_drop_copy);
+ WM_dropbox_add(lb, "OUTLINER_OT_group_link", outliner_group_link_poll, outliner_group_link_copy);
}
static void outliner_main_area_draw(const bContext *C, ARegion *ar)
@@ -362,6 +387,10 @@ static void outliner_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa)
break;
}
break;
+ case NC_GPENCIL:
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED))
+ ED_region_tag_redraw(ar);
+ break;
}
}
diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c
index 9077d0cf8ed..d265ae62db6 100644
--- a/source/blender/editors/space_script/script_edit.c
+++ b/source/blender/editors/space_script/script_edit.c
@@ -32,7 +32,6 @@
#include <string.h>
#include <stdio.h>
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -131,7 +130,7 @@ static int script_reload_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
#else
- (void)C, (void)op; /* unused */
+ UNUSED_VARS(C, op);
return OPERATOR_CANCELLED;
#endif
}
diff --git a/source/blender/editors/space_script/script_ops.c b/source/blender/editors/space_script/script_ops.c
index 045df87d8db..41c07596a3b 100644
--- a/source/blender/editors/space_script/script_ops.c
+++ b/source/blender/editors/space_script/script_ops.c
@@ -32,19 +32,7 @@
#include <stdlib.h>
#include <math.h>
-
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-
-#include "BKE_context.h"
-
-#include "RNA_access.h"
-
#include "WM_api.h"
-#include "WM_types.h"
#include "script_intern.h"
@@ -63,4 +51,3 @@ void script_keymap(wmKeyConfig *UNUSED(keyconf))
{
/* Script space is deprecated, and doesn't need a keymap */
}
-
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index fd2cd268a27..759dcd3d0a4 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -35,7 +35,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -53,7 +52,6 @@
#include "UI_view2d.h"
#ifdef WITH_PYTHON
-#include "BPY_extern.h"
#endif
#include "script_intern.h" // own include
diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt
index 4cf9c0c95c2..d9aff2781f0 100644
--- a/source/blender/editors/space_sequencer/CMakeLists.txt
+++ b/source/blender/editors/space_sequencer/CMakeLists.txt
@@ -43,6 +43,7 @@ set(SRC
sequencer_edit.c
sequencer_modifier.c
sequencer_ops.c
+ sequencer_preview.c
sequencer_scopes.c
sequencer_select.c
sequencer_view.c
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 345988c1d5c..38a01bcd78c 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -40,7 +40,6 @@
#include "DNA_scene_types.h"
#include "DNA_mask_types.h"
-#include "BLF_translation.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -61,7 +60,6 @@
#include "ED_screen.h"
#include "ED_sequencer.h"
-#include "UI_view2d.h"
#include "BKE_sound.h"
@@ -626,7 +624,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- WM_operator_properties_filesel(ot, FOLDERFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
RNA_def_boolean(ot->srna, "sound", true, "Sound", "Load sound with the movie");
@@ -675,7 +673,7 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- WM_operator_properties_filesel(ot, FOLDERFILE | SOUNDFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_SOUND, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory");
@@ -774,7 +772,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME);
}
@@ -923,5 +921,6 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot)
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME);
RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type");
- RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f);
+ RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color",
+ "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c
index d75eeca2c67..70c6da0bfb3 100644
--- a/source/blender/editors/space_sequencer/sequencer_buttons.c
+++ b/source/blender/editors/space_sequencer/sequencer_buttons.c
@@ -46,12 +46,12 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "UI_interface.h"
#include "sequencer_intern.h"
/* **************************** buttons ********************************* */
+#if 0
static int sequencer_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt))
{
SpaceSeq *sseq = CTX_wm_space_seq(C);
@@ -59,9 +59,11 @@ static int sequencer_grease_pencil_panel_poll(const bContext *C, PanelType *UNUS
/* don't show the gpencil if we are not showing the image */
return ED_space_sequencer_check_show_imbuf(sseq);
}
+#endif
-void sequencer_buttons_register(ARegionType *art)
+void sequencer_buttons_register(ARegionType *UNUSED(art))
{
+#if 0
PanelType *pt;
pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil");
@@ -72,6 +74,7 @@ void sequencer_buttons_register(ARegionType *art)
pt->draw = ED_gpencil_panel_standard;
pt->poll = sequencer_grease_pencil_panel_poll;
BLI_addtail(&art->paneltypes, pt);
+#endif
}
/* **************** operator to open/close properties view ************* */
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index f9ca713ad2d..b63c46cba01 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -34,6 +34,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_threads.h"
#include "IMB_imbuf_types.h"
@@ -69,6 +70,8 @@
#include "WM_api.h"
+#include "MEM_guardedalloc.h"
+
/* own include */
#include "sequencer_intern.h"
@@ -82,9 +85,13 @@
/* Note, Don't use SEQ_BEGIN/SEQ_END while drawing!
* it messes up transform, - Campbell */
-static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2);
+#undef SEQ_BEGIN
+#undef SEQP_BEGIN
+#undef SEQ_END
+
+static Sequence *special_seq_update = NULL;
-static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[3])
+void color3ubv_from_seq(Scene *curscene, Sequence *seq, unsigned char col[3])
{
unsigned char blendcol[3];
SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
@@ -175,14 +182,14 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[
}
}
-static void drawseqwave(Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize)
+static void drawseqwave(const bContext *C, SpaceSeq *sseq, Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float stepsize)
{
/*
* x1 is the starting x value to draw the wave,
* x2 the end x value, same for y1 and y2
* stepsize is width of a pixel.
*/
- if (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM) {
+ if ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM)) {
int i, j, pos;
int length = floor((x2 - x1) / stepsize) + 1;
float ymid = (y1 + y2) / 2;
@@ -190,20 +197,32 @@ static void drawseqwave(Scene *scene, Sequence *seq, float x1, float y1, float x
float samplestep;
float startsample, endsample;
float value;
-
+ bSound *sound = seq->sound;
+
SoundWaveform *waveform;
-
- if (!seq->sound->waveform)
- sound_read_waveform(seq->sound);
-
- if (!seq->sound->waveform)
- return; /* zero length sound */
-
+
+ if (!sound->spinlock) {
+ sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
+ BLI_spin_init(sound->spinlock);
+ }
+
+ BLI_spin_lock(sound->spinlock);
+ if (!seq->sound->waveform) {
+ if (!(sound->flags & SOUND_FLAGS_WAVEFORM_LOADING)) {
+ /* prevent sounds from reloading */
+ seq->sound->flags |= SOUND_FLAGS_WAVEFORM_LOADING;
+ BLI_spin_unlock(sound->spinlock);
+ sequencer_preview_add_sound(C, seq);
+ }
+ else {
+ BLI_spin_unlock(sound->spinlock);
+ }
+ return; /* nothing to draw */
+ }
+ BLI_spin_unlock(sound->spinlock);
+
waveform = seq->sound->waveform;
-
- if (!waveform)
- return;
-
+
startsample = floor((seq->startofs + seq->anim_startofs) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND);
endsample = ceil((seq->startofs + seq->anim_startofs + seq->enddisp - seq->startdisp) / FPS * SOUND_WAVE_SAMPLES_PER_SECOND);
samplestep = (endsample - startsample) * stepsize / (x2 - x1);
@@ -299,7 +318,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
if ((seqm->flag & SEQ_MUTE) == 0 && (seq->flag & SEQ_MUTE))
drawmeta_stipple(1);
- get_seq_color3ubv(scene, seq, col);
+ color3ubv_from_seq(scene, seq, col);
glColor4ubv(col);
@@ -332,7 +351,10 @@ static float draw_seq_handle_size_get_clamped(Sequence *seq, const float pixelx)
{
const float minhandle = pixelx * SEQ_HANDLE_SIZE_MIN;
const float maxhandle = pixelx * SEQ_HANDLE_SIZE_MAX;
- return CLAMPIS(seq->handsize, minhandle, maxhandle);
+ float size = CLAMPIS(seq->handsize, minhandle, maxhandle);
+
+ /* ensure we're not greater than half width */
+ return min_ff(size, ((float)(seq->enddisp - seq->startdisp) / 2.0f) / pixelx);
}
/* draw a handle, for each end of a sequence strip */
@@ -415,112 +437,6 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, const float handsize_cla
}
}
-static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq)
-{
- float x1, x2, y1, y2, pixely, a;
- unsigned char col[3], blendcol[3];
- View2D *v2d = &ar->v2d;
-
- if (seq->type >= SEQ_TYPE_EFFECT) return;
-
- x1 = seq->startdisp;
- x2 = seq->enddisp;
-
- y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
- y2 = seq->machine + SEQ_STRIP_OFSTOP;
-
- pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
-
- if (pixely <= 0) return; /* can happen when the view is split/resized */
-
- blendcol[0] = blendcol[1] = blendcol[2] = 120;
-
- if (seq->startofs) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- get_seq_color3ubv(scene, seq, col);
-
- if (seq->flag & SELECT) {
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
- glColor4ub(col[0], col[1], col[2], 170);
- }
- else {
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
- glColor4ub(col[0], col[1], col[2], 110);
- }
-
- glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1);
-
- if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
- else glColor4ub(col[0], col[1], col[2], 160);
-
- fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); //outline
-
- glDisable(GL_BLEND);
- }
- if (seq->endofs) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- get_seq_color3ubv(scene, seq, col);
-
- if (seq->flag & SELECT) {
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
- glColor4ub(col[0], col[1], col[2], 170);
- }
- else {
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
- glColor4ub(col[0], col[1], col[2], 110);
- }
-
- glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
-
- if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
- else glColor4ub(col[0], col[1], col[2], 160);
-
- fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline
-
- glDisable(GL_BLEND);
- }
- if (seq->startstill) {
- get_seq_color3ubv(scene, seq, col);
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
- glColor3ubv((GLubyte *)col);
-
- draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
-
- /* feint pinstripes, helps see exactly which is extended and which isn't,
- * especially when the extension is very small */
- if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
- else UI_GetColorPtrShade3ubv(col, col, -16);
-
- glColor3ubv((GLubyte *)col);
-
- for (a = y1; a < y2; a += pixely * 2.0f) {
- fdrawline(x1, a, (float)(seq->start), a);
- }
- }
- if (seq->endstill) {
- get_seq_color3ubv(scene, seq, col);
- UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
- glColor3ubv((GLubyte *)col);
-
- draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2);
-
- /* feint pinstripes, helps see exactly which is extended and which isn't,
- * especially when the extension is very small */
- if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24);
- else UI_GetColorPtrShade3ubv(col, col, -16);
-
- glColor3ubv((GLubyte *)col);
-
- for (a = y1; a < y2; a += pixely * 2.0f) {
- fdrawline((float)(seq->start + seq->len), a, x2, a);
- }
- }
-}
-
/* draw info text on a sequence strip */
static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float y1, float y2, const unsigned char background_col[3])
{
@@ -554,7 +470,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
}
}
else if (seq->type == SEQ_TYPE_MOVIECLIP) {
- if (seq->clip && strcmp(name, seq->clip->id.name + 2) != 0) {
+ if (seq->clip && !STREQ(name, seq->clip->id.name + 2)) {
str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d",
name, seq->clip->id.name + 2, seq->len);
}
@@ -564,7 +480,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
}
}
else if (seq->type == SEQ_TYPE_MASK) {
- if (seq->mask && strcmp(name, seq->mask->id.name + 2) != 0) {
+ if (seq->mask && !STREQ(name, seq->mask->id.name + 2)) {
str_len = BLI_snprintf(str, sizeof(str), "%s: %s | %d",
name, seq->mask->id.name + 2, seq->len);
}
@@ -627,7 +543,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float
}
/* draws a shaded strip, made from gradient + flat color + gradient */
-static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2)
+void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2)
{
float ymid1, ymid2;
@@ -684,12 +600,117 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa
}
}
+void draw_sequence_extensions(Scene *scene, ARegion *ar, Sequence *seq)
+{
+ float x1, x2, y1, y2, pixely, a;
+ unsigned char col[3], blendcol[3];
+ View2D *v2d = &ar->v2d;
+
+ x1 = seq->startdisp;
+ x2 = seq->enddisp;
+
+ y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
+ y2 = seq->machine + SEQ_STRIP_OFSTOP;
+
+ pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
+
+ if (pixely <= 0) return; /* can happen when the view is split/resized */
+
+ blendcol[0] = blendcol[1] = blendcol[2] = 120;
+
+ if (seq->startofs) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ color3ubv_from_seq(scene, seq, col);
+
+ if (seq->flag & SELECT) {
+ UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
+ glColor4ub(col[0], col[1], col[2], 170);
+ }
+ else {
+ UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
+ glColor4ub(col[0], col[1], col[2], 110);
+ }
+
+ glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1);
+
+ if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
+ else glColor4ub(col[0], col[1], col[2], 160);
+
+ fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1); //outline
+
+ glDisable(GL_BLEND);
+ }
+ if (seq->endofs) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ color3ubv_from_seq(scene, seq, col);
+
+ if (seq->flag & SELECT) {
+ UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
+ glColor4ub(col[0], col[1], col[2], 170);
+ }
+ else {
+ UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
+ glColor4ub(col[0], col[1], col[2], 110);
+ }
+
+ glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
+
+ if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
+ else glColor4ub(col[0], col[1], col[2], 160);
+
+ fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline
+
+ glDisable(GL_BLEND);
+ }
+ if (seq->startstill) {
+ color3ubv_from_seq(scene, seq, col);
+ UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
+ glColor3ubv((GLubyte *)col);
+
+ draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
+
+ /* feint pinstripes, helps see exactly which is extended and which isn't,
+ * especially when the extension is very small */
+ if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
+ else UI_GetColorPtrShade3ubv(col, col, -16);
+
+ glColor3ubv((GLubyte *)col);
+
+ for (a = y1; a < y2; a += pixely * 2.0f) {
+ fdrawline(x1, a, (float)(seq->start), a);
+ }
+ }
+ if (seq->endstill) {
+ color3ubv_from_seq(scene, seq, col);
+ UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
+ glColor3ubv((GLubyte *)col);
+
+ draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2);
+
+ /* feint pinstripes, helps see exactly which is extended and which isn't,
+ * especially when the extension is very small */
+ if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24);
+ else UI_GetColorPtrShade3ubv(col, col, -16);
+
+ glColor3ubv((GLubyte *)col);
+
+ for (a = y1; a < y2; a += pixely * 2.0f) {
+ fdrawline((float)(seq->start + seq->len), a, x2, a);
+ }
+ }
+}
+
+
/*
* Draw a sequence strip, bounds check already made
* ARegion is currently only used to get the windows width in pixels
* so wave file sample drawing precision is zoom adjusted
*/
-static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline_tint, float pixelx)
+static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, ARegion *ar, Sequence *seq, int outline_tint, float pixelx)
{
View2D *v2d = &ar->v2d;
float x1, x2, y1, y2;
@@ -707,8 +728,8 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
/* get the correct color per strip type*/
- //get_seq_color3ubv(scene, seq, col);
- get_seq_color3ubv(scene, seq, background_col);
+ //color3ubv_from_seq(scene, seq, col);
+ color3ubv_from_seq(scene, seq, background_col);
/* draw the main strip body */
if (is_single_image) { /* single image */
@@ -719,11 +740,13 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
else { /* normal operation */
draw_shadedstrip(seq, background_col, x1, y1, x2, y2);
}
-
- /* draw additional info and controls */
- if (!is_single_image)
- draw_seq_extensions(scene, ar, seq);
-
+
+ if (!is_single_image) {
+ if ((sseq->draw_flag & SEQ_DRAW_OFFSET_EXT) || (seq == special_seq_update)) {
+ draw_sequence_extensions(scene, ar, seq);
+ }
+ }
+
draw_seq_handle(v2d, seq, handsize_clamped, SEQ_LEFTHANDLE);
draw_seq_handle(v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE);
@@ -733,7 +756,9 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
/* draw sound wave */
if (seq->type == SEQ_TYPE_SOUND_RAM) {
- drawseqwave(scene, seq, x1, y1, x2, y2, BLI_rctf_size_x(&ar->v2d.cur) / ar->winx);
+ if (!(sseq->flag & SEQ_NO_WAVEFORMS)) {
+ drawseqwave(C, sseq, scene, seq, x1, y1, x2, y2, BLI_rctf_size_x(&ar->v2d.cur) / ar->winx);
+ }
}
/* draw lock */
@@ -766,7 +791,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
glDisable(GL_POLYGON_STIPPLE);
}
- get_seq_color3ubv(scene, seq, col);
+ color3ubv_from_seq(scene, seq, col);
if ((G.moving & G_TRANSFORM_SEQ) && (seq->flag & SELECT)) {
if (seq->flag & SEQ_OVERLAP) {
col[0] = 255; col[1] = col[2] = 40;
@@ -784,7 +809,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
glLineStipple(1, 0x8888);
}
- uiDrawBoxShade(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0);
+ UI_draw_roundbox_shade_x(GL_LINE_LOOP, x1, y1, x2, y2, 0.0, 0.1, 0.0);
if (seq->flag & SEQ_MUTE) {
glDisable(GL_LINE_STIPPLE);
@@ -810,19 +835,29 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
}
}
-static Sequence *special_seq_update = NULL;
+void sequencer_special_update_set(Sequence *seq)
+{
+ special_seq_update = seq;
+}
-static void UNUSED_FUNCTION(set_special_seq_update) (int val)
+Sequence *ED_sequencer_special_preview_get(void)
{
-// int x;
+ return special_seq_update;
+}
- /* if mouse over a sequence && LEFTMOUSE */
- if (val) {
-// XXX special_seq_update = find_nearest_seq(&x);
- }
- else {
- special_seq_update = NULL;
- }
+void ED_sequencer_special_preview_set(bContext *C, const int mval[2])
+{
+ Scene *scene = CTX_data_scene(C);
+ ARegion *ar = CTX_wm_region(C);
+ int hand;
+ Sequence *seq;
+ seq = find_nearest_seq(scene, &ar->v2d, &hand, mval);
+ sequencer_special_update_set(seq);
+}
+
+void ED_sequencer_special_preview_clear(void)
+{
+ sequencer_special_update_set(NULL);
}
ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int cfra, int frame_ofs)
@@ -835,9 +870,6 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int
short is_break = G.is_break;
render_size = sseq->render_size;
- if (render_size == 99) {
- render_size = 100;
- }
if (render_size == 0) {
render_size = scene->r.size;
}
@@ -852,7 +884,10 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int
rectx = (render_size * (float)scene->r.xsch) / 100.0f + 0.5f;
recty = (render_size * (float)scene->r.ysch) / 100.0f + 0.5f;
- context = BKE_sequencer_new_render_data(bmain->eval_ctx, bmain, scene, rectx, recty, proxy_size);
+ BKE_sequencer_new_render_data(
+ bmain->eval_ctx, bmain, scene,
+ rectx, recty, proxy_size,
+ &context);
/* sequencer could start rendering, in this case we need to be sure it wouldn't be canceled
* by Esc pressed somewhere in the past
@@ -917,16 +952,40 @@ static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scop
return scope;
}
-void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay)
+static void sequencer_display_size(Scene *scene, SpaceSeq *sseq, float r_viewrect[2])
+{
+ float render_size, proxy_size;
+
+ if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_SCENE) {
+ render_size = (float)scene->r.size / 100.0f;
+ proxy_size = 1.0f;
+ }
+ else {
+ render_size = (float)sseq->render_size / 100.0f;
+ proxy_size = render_size;
+ }
+
+ r_viewrect[0] = (render_size * (float)scene->r.xsch);
+ r_viewrect[1] = (render_size * (float)scene->r.ysch);
+
+ /* rectx = viewrectx + 0.5f; */ /* UNUSED */
+ /* recty = viewrecty + 0.5f; */ /* UNUSED */
+
+ if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
+ r_viewrect[0] *= scene->r.xasp / scene->r.yasp;
+ r_viewrect[0] /= proxy_size;
+ r_viewrect[1] /= proxy_size;
+ }
+}
+
+void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay, bool draw_backdrop)
{
struct Main *bmain = CTX_data_main(C);
struct ImBuf *ibuf = NULL;
struct ImBuf *scope = NULL;
struct View2D *v2d = &ar->v2d;
/* int rectx, recty; */ /* UNUSED */
- float viewrectx, viewrecty;
- float render_size = 0.0;
- float proxy_size = 100.0;
+ float viewrect[2];
float col[3];
GLuint texid;
GLuint last_texid;
@@ -950,30 +1009,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
}
}
- render_size = sseq->render_size;
- if (render_size == 0) {
- render_size = scene->r.size;
- }
- else {
- proxy_size = render_size;
- }
- if (render_size < 0) {
- return;
- }
-
- viewrectx = (render_size * (float)scene->r.xsch) / 100.0f;
- viewrecty = (render_size * (float)scene->r.ysch) / 100.0f;
-
- /* rectx = viewrectx + 0.5f; */ /* UNUSED */
- /* recty = viewrecty + 0.5f; */ /* UNUSED */
-
- if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
- viewrectx *= scene->r.xasp / scene->r.yasp;
- viewrectx /= proxy_size / 100.0f;
- viewrecty /= proxy_size / 100.0f;
- }
-
- if (!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) {
+ if ((!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) && !draw_backdrop) {
UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -983,6 +1019,10 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
if (G.is_rendering)
return;
+ if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_NONE) {
+ return;
+ }
+
ibuf = sequencer_ibuf_get(bmain, scene, sseq, cfra, frame_ofs);
if (ibuf == NULL)
@@ -991,6 +1031,8 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
if (ibuf->rect == NULL && ibuf->rect_float == NULL)
return;
+ sequencer_display_size(scene, sseq, viewrect);
+
if (sseq->mainb != SEQ_DRAW_IMG_IMBUF || sseq->zebra != 0) {
SequencerScopes *scopes = &sseq->scopes;
@@ -1037,8 +1079,8 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
/* future files may have new scopes we don't catch above */
if (scope) {
scopes->reference_ibuf = ibuf;
- viewrectx = scope->x;
- viewrecty = scope->y;
+ viewrect[0] = scope->x;
+ viewrect[1] = scope->y;
}
else {
scopes->reference_ibuf = NULL;
@@ -1048,23 +1090,25 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
/* without this colors can flicker from previous opengl state */
glColor4ub(255, 255, 255, 255);
- UI_view2d_totRect_set(v2d, viewrectx + 0.5f, viewrecty + 0.5f);
- UI_view2d_curRect_validate(v2d);
-
- /* setting up the view - actual drawing starts here */
- UI_view2d_view_ortho(v2d);
-
- /* only draw alpha for main buffer */
- if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
- if (sseq->flag & SEQ_USE_ALPHA) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
- glColor4f(1.0, 1.0, 1.0, 1.0);
+ if (!draw_backdrop) {
+ UI_view2d_totRect_set(v2d, viewrect[0] + 0.5f, viewrect[1] + 0.5f);
+ UI_view2d_curRect_validate(v2d);
+
+ /* setting up the view - actual drawing starts here */
+ UI_view2d_view_ortho(v2d);
+
+ /* only draw alpha for main buffer */
+ if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
+ if (sseq->flag & SEQ_USE_ALPHA) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ }
}
}
-
+
if (scope) {
IMB_freeImBuf(ibuf);
ibuf = scope;
@@ -1154,6 +1198,14 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, format, type, display_buffer);
+ if (draw_backdrop) {
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ }
glBegin(GL_QUADS);
if (draw_overlay) {
@@ -1176,6 +1228,25 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin);
}
}
+ else if (draw_backdrop) {
+ float aspect = BLI_rcti_size_x(&ar->winrct) / (float)BLI_rcti_size_y(&ar->winrct);
+ float image_aspect = viewrect[0] / viewrect[1];
+ float imagex, imagey;
+
+ if (aspect >= image_aspect) {
+ imagex = image_aspect / aspect;
+ imagey = 1.0f;
+ }
+ else {
+ imagex = 1.0f;
+ imagey = aspect / image_aspect;
+ }
+
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(-imagex, -imagey);
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(-imagex, imagey);
+ glTexCoord2f(1.0f, 1.0f); glVertex2f(imagex, imagey);
+ glTexCoord2f(1.0f, 0.0f); glVertex2f(imagex, -imagey);
+ }
else {
glTexCoord2f(0.0f, 0.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymin);
glTexCoord2f(0.0f, 1.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymax);
@@ -1183,6 +1254,15 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin);
}
glEnd();
+
+ if (draw_backdrop) {
+ glPopMatrix();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+
+ }
+
glBindTexture(GL_TEXTURE_2D, last_texid);
glDisable(GL_TEXTURE_2D);
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA)
@@ -1192,6 +1272,16 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
if (glsl_used)
IMB_colormanagement_finish_glsl_draw();
+ if (cache_handle)
+ IMB_display_buffer_release(cache_handle);
+
+ if (!scope)
+ IMB_freeImBuf(ibuf);
+
+ if (draw_backdrop) {
+ return;
+ }
+
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
float x1 = v2d->tot.xmin;
@@ -1212,24 +1302,18 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
glEnd();
/* safety border */
- if ((sseq->flag & SEQ_DRAW_SAFE_MARGINS) != 0) {
- float fac = 0.1;
-
- float a = fac * (x2 - x1);
- x1 += a;
- x2 -= a;
-
- a = fac * (y2 - y1);
- y1 += a;
- y2 -= a;
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- uiSetRoundBox(UI_CNR_ALL);
- uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0);
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
+ if (sseq->flag & SEQ_SHOW_SAFE_MARGINS) {
+ UI_draw_safe_areas(
+ x1, x2, y1, y2,
+ scene->safe_areas.title,
+ scene->safe_areas.action);
+
+ if (sseq->flag & SEQ_SHOW_SAFE_CENTER) {
+ UI_draw_safe_areas(
+ x1, x2, y1, y2,
+ scene->safe_areas.title_center,
+ scene->safe_areas.action_center);
+ }
}
setlinestyle(0);
@@ -1241,9 +1325,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
ED_gpencil_draw_2dimage(C);
}
}
-
- if (!scope)
- IMB_freeImBuf(ibuf);
/* ortho at pixel level */
UI_view2d_view_restore(C);
@@ -1280,9 +1361,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
NULL, C);
}
}
-
- if (cache_handle)
- IMB_display_buffer_release(cache_handle);
}
#if 0
@@ -1359,6 +1437,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
{
Scene *scene = CTX_data_scene(C);
View2D *v2d = &ar->v2d;
+ SpaceSeq *sseq = CTX_wm_space_seq(C);
Sequence *last_seq = BKE_sequencer_active_get(scene);
int sel = 0, j;
float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
@@ -1379,7 +1458,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
else if (seq->machine > v2d->cur.ymax) continue;
/* strip passed all tests unscathed... so draw it now */
- draw_seq_strip(scene, ar, seq, outline_tint, pixelx);
+ draw_seq_strip(C, sseq, scene, ar, seq, outline_tint, pixelx);
}
/* draw selected next time round */
@@ -1388,7 +1467,16 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *ar)
/* draw the last selected last (i.e. 'active' in other parts of Blender), removes some overlapping error */
if (last_seq)
- draw_seq_strip(scene, ar, last_seq, 120, pixelx);
+ draw_seq_strip(C, sseq, scene, ar, last_seq, 120, pixelx);
+
+ /* draw highlight when previewing a single strip */
+ if (special_seq_update) {
+ const Sequence *seq = special_seq_update;
+ glEnable(GL_BLEND);
+ glColor4ub(255, 255, 255, 48);
+ glRectf(seq->startdisp, seq->machine + SEQ_STRIP_OFSBOTTOM, seq->enddisp, seq->machine + SEQ_STRIP_OFSTOP);
+ glDisable(GL_BLEND);
+ }
}
static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
@@ -1466,6 +1554,11 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
// NOTE: the gridlines are currently spaced every 25 frames, which is only fine for 25 fps, but maybe not for 30...
UI_view2d_constant_grid_draw(v2d);
+ if (sseq->draw_flag & SEQ_DRAW_BACKDROP) {
+ draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, true);
+ UI_view2d_view_ortho(v2d);
+ }
+
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
seq_draw_sfra_efra(scene, v2d);
@@ -1487,7 +1580,7 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
- draw_markers_time(C, DRAW_MARKERS_LINES);
+ ED_markers_draw(C, DRAW_MARKERS_LINES | DRAW_MARKERS_MARGIN);
/* preview range */
UI_view2d_view_ortho(v2d);
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 01259bb688f..aaf398bf3a1 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -37,6 +37,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
#include "BLF_translation.h"
@@ -49,7 +50,6 @@
#include "BKE_report.h"
#include "BKE_sound.h"
-#include "IMB_imbuf.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -59,11 +59,15 @@
/* for menu/popup icons etc etc*/
+#include "ED_numinput.h"
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_sequencer.h"
+#include "ED_space_api.h"
#include "UI_view2d.h"
+#include "UI_interface.h"
+
/* own include */
#include "sequencer_intern.h"
@@ -145,11 +149,12 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog
struct SeqIndexBuildContext *context = link->data;
BKE_sequencer_proxy_rebuild(context, stop, do_update, progress);
- }
-
- if (*stop) {
- pj->stop = 1;
- fprintf(stderr, "Canceling proxy rebuild on users request...\n");
+
+ if (*stop) {
+ pj->stop = 1;
+ fprintf(stderr, "Canceling proxy rebuild on users request...\n");
+ break;
+ }
}
}
@@ -178,6 +183,11 @@ static void seq_proxy_build_job(const bContext *C)
struct SeqIndexBuildContext *context;
LinkData *link;
Sequence *seq;
+ GSet *file_list;
+
+ if (ed == NULL) {
+ return;
+ }
wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Building Proxies",
WM_JOB_PROGRESS, WM_JOB_TYPE_SEQ_BUILD_PROXY);
@@ -195,16 +205,19 @@ static void seq_proxy_build_job(const bContext *C)
WM_jobs_callbacks(wm_job, proxy_startjob, NULL, NULL, proxy_endjob);
}
+ file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list");
SEQP_BEGIN (ed, seq)
{
if ((seq->flag & SELECT)) {
- context = BKE_sequencer_proxy_rebuild_context(pj->main, pj->scene, seq);
+ context = BKE_sequencer_proxy_rebuild_context(pj->main, pj->scene, seq, file_list);
link = BLI_genericNodeN(context);
BLI_addtail(&pj->queue, link);
}
}
SEQ_END
+ BLI_gset_free(file_list, MEM_freeN);
+
if (!WM_jobs_is_running(wm_job)) {
G.is_break = false;
WM_jobs_start(CTX_wm_manager(C), wm_job);
@@ -385,7 +398,7 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[
displen = (float)abs(seq->startdisp - seq->enddisp);
if (displen / pixelx > 16) { /* don't even try to grab the handles of small strips */
- /* Set the max value to handle to 1/3 of the total len when its less then 28.
+ /* Set the max value to handle to 1/3 of the total len when its less than 28.
* This is important because otherwise selecting handles happens even when you click in the middle */
if ((displen / 3) < 30 * pixelx) {
@@ -494,6 +507,13 @@ bool ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq)
ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF));
}
+bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq)
+{
+ return (ELEM(sseq->view, SEQ_VIEW_SEQUENCE, SEQ_VIEW_SEQUENCE_PREVIEW) &&
+ ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF));
+}
+
+
int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3, const char **error_str)
{
Editing *ed = BKE_sequencer_editing_get(scene, false);
@@ -975,13 +995,13 @@ static void UNUSED_FUNCTION(seq_remap_paths) (Scene *scene)
// XXX if (0 == sbutton(to, 0, sizeof(to)-1, "To: "))
// return;
- if (strcmp(to, from) == 0)
+ if (STREQ(to, from))
return;
SEQP_BEGIN (ed, seq)
{
if (seq->flag & SELECT) {
- if (strncmp(seq->strip->dir, from, strlen(from)) == 0) {
+ if (STREQLEN(seq->strip->dir, from, strlen(from))) {
printf("found %s\n", seq->strip->dir);
/* strip off the beginning */
@@ -1129,7 +1149,7 @@ int sequencer_strip_has_path_poll(bContext *C)
return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) && ((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq)));
}
-int sequencer_view_poll(bContext *C)
+int sequencer_view_preview_poll(bContext *C)
{
SpaceSeq *sseq = CTX_wm_space_seq(C);
Editing *ed = BKE_sequencer_editing_get(CTX_data_scene(C), false);
@@ -1139,6 +1159,15 @@ int sequencer_view_poll(bContext *C)
return 0;
}
+int sequencer_view_strips_poll(bContext *C)
+{
+ SpaceSeq *sseq = CTX_wm_space_seq(C);
+ if (sseq && ED_space_sequencer_check_show_strip(sseq))
+ return 1;
+
+ return 0;
+}
+
/* snap operator*/
static int sequencer_snap_exec(bContext *C, wmOperator *op)
{
@@ -1231,8 +1260,7 @@ void SEQUENCER_OT_snap(struct wmOperatorType *ot)
RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be snapped", INT_MIN, INT_MAX);
}
-
-typedef struct TrimData {
+typedef struct SlipData {
int init_mouse[2];
float init_mouseloc[2];
TransSeq *ts;
@@ -1241,7 +1269,9 @@ typedef struct TrimData {
int num_seq;
bool slow;
int slow_offset; /* offset at the point where offset was turned on */
-} TrimData;
+ void *draw_handle;
+ NumInput num_input;
+} SlipData;
static void transseq_backup(TransSeq *ts, Sequence *seq)
{
@@ -1274,20 +1304,35 @@ static void transseq_restore(TransSeq *ts, Sequence *seq)
seq->len = ts->len;
}
-static int trim_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool first_level)
+static void draw_slip_extensions(const bContext *C, ARegion *ar, void *data)
+{
+ Scene *scene = CTX_data_scene(C);
+ SlipData *td = data;
+ int i;
+
+ for (i = 0; i < td->num_seq; i++) {
+ Sequence *seq = td->seq_array[i];
+
+ if ((seq->type != SEQ_TYPE_META) && td->trim[i]) {
+ draw_sequence_extensions(scene, ar, seq);
+ }
+ }
+}
+
+static int slip_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool do_trim)
{
Sequence *seq;
int num_items = 0;
for (seq = seqbasep->first; seq; seq = seq->next) {
- if (!first_level || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) {
+ if (!do_trim || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) {
seq_array[offset + num_items] = seq;
- trim[offset + num_items] = first_level;
+ trim[offset + num_items] = do_trim;
num_items++;
if (seq->type == SEQ_TYPE_META) {
/* trim the sub-sequences */
- num_items += trim_add_sequences_rec(&seq->seqbase, seq_array, trim, num_items + offset, false);
+ num_items += slip_add_sequences_rec(&seq->seqbase, seq_array, trim, num_items + offset, false);
}
else if (seq->type & SEQ_TYPE_EFFECT) {
trim[offset + num_items] = false;
@@ -1298,7 +1343,7 @@ static int trim_add_sequences_rec(ListBase *seqbasep, Sequence **seq_array, bool
return num_items;
}
-static int trim_count_sequences_rec(ListBase *seqbasep, bool first_level)
+static int slip_count_sequences_rec(ListBase *seqbasep, bool first_level)
{
Sequence *seq;
int trimmed_sequences = 0;
@@ -1309,7 +1354,7 @@ static int trim_count_sequences_rec(ListBase *seqbasep, bool first_level)
if (seq->type == SEQ_TYPE_META) {
/* trim the sub-sequences */
- trimmed_sequences += trim_count_sequences_rec(&seq->seqbase, false);
+ trimmed_sequences += slip_count_sequences_rec(&seq->seqbase, false);
}
}
}
@@ -1317,33 +1362,43 @@ static int trim_count_sequences_rec(ListBase *seqbasep, bool first_level)
return trimmed_sequences;
}
-static int sequencer_trim_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- TrimData *data;
+ SlipData *data;
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, false);
+ ARegion *ar = CTX_wm_region(C);
float mouseloc[2];
int num_seq, i;
View2D *v2d = UI_view2d_fromcontext(C);
/* first recursively cound the trimmed elements */
- num_seq = trim_count_sequences_rec(ed->seqbasep, true);
+ num_seq = slip_count_sequences_rec(ed->seqbasep, true);
if (num_seq == 0)
return OPERATOR_CANCELLED;
- data = op->customdata = MEM_mallocN(sizeof(TrimData), "trimdata");
+ data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata");
data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform");
data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences");
data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim");
data->num_seq = num_seq;
- trim_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true);
+ initNumInput(&data->num_input);
+ data->num_input.idx_max = 0;
+ data->num_input.val_flag[0] |= NUM_NO_FRACTION;
+ data->num_input.unit_sys = USER_UNIT_NONE;
+ data->num_input.unit_type[0] = 0;
+
+
+ slip_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true);
for (i = 0; i < num_seq; i++) {
transseq_backup(data->ts + i, data->seq_array[i]);
}
+ data->draw_handle = ED_region_draw_cb_activate(ar->type, draw_slip_extensions, data, REGION_DRAW_POST_VIEW);
+
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]);
copy_v2_v2_int(data->init_mouse, event->mval);
@@ -1353,10 +1408,13 @@ static int sequencer_trim_invoke(bContext *C, wmOperator *op, const wmEvent *eve
WM_event_add_modal_handler(C, op);
+ /* notify so we draw extensions immediately */
+ WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
+
return OPERATOR_RUNNING_MODAL;
}
-static bool sequencer_trim_recursively(Scene *scene, TrimData *data, int offset)
+static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
{
/* only data types supported for now */
@@ -1415,9 +1473,9 @@ static bool sequencer_trim_recursively(Scene *scene, TrimData *data, int offset)
return false;
}
-static int sequencer_trim_exec(bContext *C, wmOperator *op)
+static int sequencer_slip_exec(bContext *C, wmOperator *op)
{
- TrimData *data;
+ SlipData *data;
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, false);
int num_seq, i;
@@ -1425,80 +1483,125 @@ static int sequencer_trim_exec(bContext *C, wmOperator *op)
bool success = false;
/* first recursively cound the trimmed elements */
- num_seq = trim_count_sequences_rec(ed->seqbasep, true);
+ num_seq = slip_count_sequences_rec(ed->seqbasep, true);
if (num_seq == 0)
return OPERATOR_CANCELLED;
- data = op->customdata = MEM_mallocN(sizeof(TrimData), "trimdata");
+ data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata");
data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform");
data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences");
data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim");
data->num_seq = num_seq;
- trim_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true);
+ slip_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true);
for (i = 0; i < num_seq; i++) {
transseq_backup(data->ts + i, data->seq_array[i]);
}
- success = sequencer_trim_recursively(scene, data, offset);
+ success = sequencer_slip_recursively(scene, data, offset);
MEM_freeN(data->seq_array);
MEM_freeN(data->trim);
MEM_freeN(data->ts);
MEM_freeN(data);
- if (success) return OPERATOR_FINISHED;
- else return OPERATOR_CANCELLED;
+ if (success) {
+ WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+
+static void sequencer_slip_update_header(Scene *scene, ScrArea *sa, SlipData *data, int offset)
+{
+#define HEADER_LENGTH 40
+ char msg[HEADER_LENGTH];
+
+ if (sa) {
+ if (hasNumInput(&data->num_input)) {
+ char num_str[NUM_STR_REP_LEN];
+ outputNumInput(&data->num_input, num_str, &scene->unit);
+ BLI_snprintf(msg, HEADER_LENGTH, "Trim offset: %s", num_str);
+ }
+ else {
+ BLI_snprintf(msg, HEADER_LENGTH, "Trim offset: %d", offset);
+ }
+ }
+
+ ED_area_headerprint(sa, msg);
+
+#undef HEADER_LENGTH
}
-static int sequencer_trim_modal(bContext *C, wmOperator *op, const wmEvent *event)
+static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
- TrimData *data = (TrimData *)op->customdata;
+ SlipData *data = (SlipData *)op->customdata;
ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ const bool has_numInput = hasNumInput(&data->num_input);
+ bool handled = true;
+
+ /* Modal numinput active, try to handle numeric inputs first... */
+ if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &data->num_input, event)) {
+ float offset;
+ applyNumInput(&data->num_input, &offset);
+
+ sequencer_slip_update_header(scene, sa, data, (int)offset);
+
+ RNA_int_set(op->ptr, "offset", offset);
+
+ if (sequencer_slip_recursively(scene, data, offset)) {
+ WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+ }
switch (event->type) {
case MOUSEMOVE:
{
- float mouseloc[2];
- int offset;
- int mouse_x;
- View2D *v2d = UI_view2d_fromcontext(C);
-
- if (data->slow) {
- mouse_x = event->mval[0] - data->slow_offset;
- mouse_x *= 0.1f;
- mouse_x += data->slow_offset;
- }
- else {
- mouse_x = event->mval[0];
- }
+ if (!has_numInput) {
+ float mouseloc[2];
+ int offset;
+ int mouse_x;
+ View2D *v2d = UI_view2d_fromcontext(C);
+
+ if (data->slow) {
+ mouse_x = event->mval[0] - data->slow_offset;
+ mouse_x *= 0.1f;
+ mouse_x += data->slow_offset;
+ }
+ else {
+ mouse_x = event->mval[0];
+ }
- /* choose the side based on which side of the playhead the mouse is on */
- UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]);
- offset = mouseloc[0] - data->init_mouseloc[0];
+ /* choose the side based on which side of the playhead the mouse is on */
+ UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]);
+ offset = mouseloc[0] - data->init_mouseloc[0];
- RNA_int_set(op->ptr, "offset", offset);
+ sequencer_slip_update_header(scene, sa, data, offset);
- if (sa) {
-#define HEADER_LENGTH 40
- char msg[HEADER_LENGTH];
- BLI_snprintf(msg, HEADER_LENGTH, "Trim offset: %d", offset);
-#undef HEADER_LENGTH
- ED_area_headerprint(sa, msg);
- }
+ RNA_int_set(op->ptr, "offset", offset);
- if (sequencer_trim_recursively(scene, data, offset)) {
- WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
+ if (sequencer_slip_recursively(scene, data, offset)) {
+ WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
+ }
}
break;
}
case LEFTMOUSE:
+ case RETKEY:
+ case SPACEKEY:
{
+ ED_region_draw_cb_exit(ar->type, data->draw_handle);
MEM_freeN(data->seq_array);
MEM_freeN(data->trim);
MEM_freeN(data->ts);
@@ -1527,6 +1630,8 @@ static int sequencer_trim_modal(bContext *C, wmOperator *op, const wmEvent *even
BKE_sequence_calc(scene, seq);
}
+ ED_region_draw_cb_exit(ar->type, data->draw_handle);
+
MEM_freeN(data->seq_array);
MEM_freeN(data->ts);
MEM_freeN(data->trim);
@@ -1546,33 +1651,50 @@ static int sequencer_trim_modal(bContext *C, wmOperator *op, const wmEvent *even
case RIGHTSHIFTKEY:
case LEFTSHIFTKEY:
- if (event->val == KM_PRESS) {
- data->slow = true;
- data->slow_offset = event->mval[0];
- }
- else if (event->val == KM_RELEASE) {
- data->slow = false;
+ if (!has_numInput) {
+ if (event->val == KM_PRESS) {
+ data->slow = true;
+ data->slow_offset = event->mval[0];
+ }
+ else if (event->val == KM_RELEASE) {
+ data->slow = false;
+ }
}
break;
default:
+ handled = false;
break;
}
+ /* Modal numinput inactive, try to handle numeric inputs last... */
+ if (!handled && event->val == KM_PRESS && handleNumInput(C, &data->num_input, event)) {
+ float offset;
+ applyNumInput(&data->num_input, &offset);
+
+ sequencer_slip_update_header(scene, sa, data, (int)offset);
+
+ RNA_int_set(op->ptr, "offset", offset);
+
+ if (sequencer_slip_recursively(scene, data, offset)) {
+ WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
+ }
+ }
+
return OPERATOR_RUNNING_MODAL;
}
-void SEQUENCER_OT_trim(struct wmOperatorType *ot)
+void SEQUENCER_OT_slip(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Trim Strips";
- ot->idname = "SEQUENCER_OT_trim";
+ ot->idname = "SEQUENCER_OT_slip";
ot->description = "Trim the contents of the active strip";
/* api callbacks */
- ot->invoke = sequencer_trim_invoke;
- ot->modal = sequencer_trim_modal;
- ot->exec = sequencer_trim_exec;
+ ot->invoke = sequencer_slip_invoke;
+ ot->modal = sequencer_slip_modal;
+ ot->exec = sequencer_slip_exec;
ot->poll = sequencer_edit_poll;
/* flags */
@@ -1582,7 +1704,6 @@ void SEQUENCER_OT_trim(struct wmOperatorType *ot)
INT32_MIN, INT32_MAX);
}
-
/* mute operator */
static int sequencer_mute_exec(bContext *C, wmOperator *op)
{
@@ -2425,8 +2546,8 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
Sequence *seq, *seqm, *next, *last_seq = BKE_sequencer_active_get(scene);
int channel_max = 1;
- if (BKE_sequence_base_isolated_sel_check(ed->seqbasep, false) == false) {
- BKE_report(op->reports, RPT_ERROR, "Please select more than one or all related strips");
+ if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) {
+ BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
return OPERATOR_CANCELLED;
}
@@ -2805,74 +2926,13 @@ void SEQUENCER_OT_view_selected(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER;
}
-
-static int find_next_prev_edit(Scene *scene, int cfra,
- const short side,
- const bool do_skip_mute, const bool do_center)
-{
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- Sequence *seq;
-
- int dist, best_dist, best_frame = cfra;
- int seq_frames[2], seq_frames_tot;
-
- best_dist = MAXFRAME * 2;
-
- if (ed == NULL) return cfra;
-
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- int i;
-
- if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
- continue;
- }
-
- if (do_center) {
- seq_frames[0] = (seq->startdisp + seq->enddisp) / 2;
- seq_frames_tot = 1;
- }
- else {
- seq_frames[0] = seq->startdisp;
- seq_frames[1] = seq->enddisp;
-
- seq_frames_tot = 2;
- }
-
- for (i = 0; i < seq_frames_tot; i++) {
- const int seq_frame = seq_frames[i];
-
- dist = MAXFRAME * 2;
-
- switch (side) {
- case SEQ_SIDE_LEFT:
- if (seq_frame < cfra) {
- dist = cfra - seq_frame;
- }
- break;
- case SEQ_SIDE_RIGHT:
- if (seq_frame > cfra) {
- dist = seq_frame - cfra;
- }
- break;
- }
-
- if (dist < best_dist) {
- best_frame = seq_frame;
- best_dist = dist;
- }
- }
- }
-
- return best_frame;
-}
-
static bool strip_jump_internal(Scene *scene,
const short side,
const bool do_skip_mute, const bool do_center)
{
bool changed = false;
int cfra = CFRA;
- int nfra = find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center);
+ int nfra = BKE_sequencer_find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center, false);
if (nfra != cfra) {
CFRA = nfra;
@@ -3119,7 +3179,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
BKE_sequencer_free_clipboard();
- if (BKE_sequence_base_isolated_sel_check(ed->seqbasep, true) == false) {
+ if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) {
BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
return OPERATOR_CANCELLED;
}
@@ -3345,7 +3405,7 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
ot->invoke = WM_border_select_invoke;
ot->exec = view_ghost_border_exec;
ot->modal = WM_border_select_modal;
- ot->poll = sequencer_view_poll;
+ ot->poll = sequencer_view_preview_poll;
ot->cancel = WM_border_select_cancel;
/* flags */
@@ -3356,13 +3416,48 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
}
/* rebuild_proxy operator */
-static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
+
+static int sequencer_rebuild_proxy_invoke(bContext *C, wmOperator *UNUSED(op),
+ const wmEvent *UNUSED(event))
{
seq_proxy_build_job(C);
return OPERATOR_FINISHED;
}
+static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *seq;
+ GSet *file_list;
+
+ if (ed == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list");
+
+ SEQP_BEGIN(ed, seq)
+ {
+ if ((seq->flag & SELECT)) {
+ struct SeqIndexBuildContext *context;
+ short stop = 0, do_update;
+ float progress;
+ context = BKE_sequencer_proxy_rebuild_context(bmain, scene, seq, file_list);
+ BKE_sequencer_proxy_rebuild(context, &stop, &do_update, &progress);
+ BKE_sequencer_proxy_rebuild_finish(context, 0);
+ BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
+ }
+ }
+ SEQ_END
+
+ BLI_gset_free(file_list, MEM_freeN);
+
+ return OPERATOR_FINISHED;
+}
+
void SEQUENCER_OT_rebuild_proxy(wmOperatorType *ot)
{
/* identifiers */
@@ -3371,13 +3466,98 @@ void SEQUENCER_OT_rebuild_proxy(wmOperatorType *ot)
ot->description = "Rebuild all selected proxies and timecode indices using the job system";
/* api callbacks */
+ ot->invoke = sequencer_rebuild_proxy_invoke;
ot->exec = sequencer_rebuild_proxy_exec;
- ot->poll = ED_operator_sequencer_active;
/* flags */
ot->flag = OPTYPE_REGISTER;
}
+static int sequencer_enable_proxies_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y);
+}
+
+static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *seq;
+ bool proxy_25 = RNA_boolean_get(op->ptr, "proxy_25");
+ bool proxy_50 = RNA_boolean_get(op->ptr, "proxy_50");
+ bool proxy_75 = RNA_boolean_get(op->ptr, "proxy_75");
+ bool proxy_100 = RNA_boolean_get(op->ptr, "proxy_100");
+ bool override = RNA_boolean_get(op->ptr, "override");
+ bool turnon = true;
+
+ if (ed == NULL || !(proxy_25 || proxy_50 || proxy_75 || proxy_100)) {
+ turnon = false;
+ }
+
+ SEQP_BEGIN(ed, seq)
+ {
+ if ((seq->flag & SELECT)) {
+ if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE, SEQ_TYPE_META, SEQ_TYPE_SCENE, SEQ_TYPE_MULTICAM)) {
+ BKE_sequencer_proxy_set(seq, turnon);
+ if (seq->strip->proxy == NULL) {
+ continue;
+ }
+
+ if (proxy_25)
+ seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_25;
+ else
+ seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_25;
+
+ if (proxy_50)
+ seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_50;
+ else
+ seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_50;
+
+ if (proxy_75)
+ seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_75;
+ else
+ seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_75;
+
+ if (proxy_100)
+ seq->strip->proxy->build_size_flags |= SEQ_PROXY_IMAGE_SIZE_100;
+ else
+ seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_100;
+
+ if (!override)
+ seq->strip->proxy->build_flags |= SEQ_PROXY_SKIP_EXISTING;
+ else
+ seq->strip->proxy->build_flags &= ~SEQ_PROXY_SKIP_EXISTING;
+ }
+ }
+ }
+ SEQ_END
+
+ WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void SEQUENCER_OT_enable_proxies(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Selected Strip Proxies";
+ ot->idname = "SEQUENCER_OT_enable_proxies";
+ ot->description = "Enable selected proxies on all selected Movie strips";
+
+ /* api callbacks */
+ ot->invoke = sequencer_enable_proxies_invoke;
+ ot->exec = sequencer_enable_proxies_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
+
+ RNA_def_boolean(ot->srna, "proxy_25", false, "25%", "");
+ RNA_def_boolean(ot->srna, "proxy_50", false, "50%", "");
+ RNA_def_boolean(ot->srna, "proxy_75", false, "75%", "");
+ RNA_def_boolean(ot->srna, "proxy_100", false, "100%", "");
+ RNA_def_boolean(ot->srna, "override", false, "Override", "");
+}
+
/* change ops */
static EnumPropertyItem prop_change_effect_input_types[] = {
@@ -3614,8 +3794,7 @@ void SEQUENCER_OT_change_path(struct wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES,
FILE_DEFAULTDISPLAY);
}
-
diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h
index 4fada72d0d9..461c72961c2 100644
--- a/source/blender/editors/space_sequencer/sequencer_intern.h
+++ b/source/blender/editors/space_sequencer/sequencer_intern.h
@@ -45,6 +45,7 @@ struct ARegion;
struct ARegionType;
struct Scene;
struct Main;
+struct SequencePreview;
/* space_sequencer.c */
struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa);
@@ -52,7 +53,12 @@ struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa);
/* sequencer_draw.c */
void draw_timeline_seq(const struct bContext *C, struct ARegion *ar);
-void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay);
+void draw_image_seq(const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay, bool draw_backdrop);
+void color3ubv_from_seq(struct Scene *curscene, struct Sequence *seq, unsigned char col[3]);
+void draw_shadedstrip(struct Sequence *seq, unsigned char col[3], float x1, float y1, float x2, float y2);
+void draw_sequence_extensions(struct Scene *scene, struct ARegion *ar, struct Sequence *seq);
+
+void sequencer_special_update_set(Sequence *seq);
/* UNUSED */
// void seq_reset_imageofs(struct SpaceSeq *sseq);
@@ -73,7 +79,8 @@ int sequencer_edit_poll(struct bContext *C);
/* UNUSED */
//int sequencer_strip_poll(struct bContext *C);
int sequencer_strip_has_path_poll(struct bContext *C);
-int sequencer_view_poll(struct bContext *C);
+int sequencer_view_preview_poll(struct bContext *C);
+int sequencer_view_strips_poll(struct bContext *C);
/* externs */
extern EnumPropertyItem sequencer_prop_effect_types[];
@@ -84,7 +91,7 @@ struct wmOperatorType;
struct wmKeyConfig;
void SEQUENCER_OT_cut(struct wmOperatorType *ot);
-void SEQUENCER_OT_trim(struct wmOperatorType *ot);
+void SEQUENCER_OT_slip(struct wmOperatorType *ot);
void SEQUENCER_OT_mute(struct wmOperatorType *ot);
void SEQUENCER_OT_unmute(struct wmOperatorType *ot);
void SEQUENCER_OT_lock(struct wmOperatorType *ot);
@@ -124,6 +131,7 @@ void SEQUENCER_OT_copy(struct wmOperatorType *ot);
void SEQUENCER_OT_paste(struct wmOperatorType *ot);
void SEQUENCER_OT_rebuild_proxy(struct wmOperatorType *ot);
+void SEQUENCER_OT_enable_proxies(struct wmOperatorType *ot);
/* preview specific operators */
void SEQUENCER_OT_view_all_preview(struct wmOperatorType *ot);
@@ -150,13 +158,6 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot);
-/* RNA enums, just to be more readable */
-enum {
- SEQ_SIDE_NONE = 0,
- SEQ_SIDE_LEFT,
- SEQ_SIDE_RIGHT,
- SEQ_SIDE_BOTH
-};
enum {
SEQ_CUT_SOFT,
SEQ_CUT_HARD
@@ -199,5 +200,8 @@ void SEQUENCER_OT_strip_modifier_move(struct wmOperatorType *ot);
/* sequencer_view.c */
void SEQUENCER_OT_sample(struct wmOperatorType *ot);
+/* sequencer_preview.c */
+void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq);
+
#endif /* __SEQUENCER_INTERN_H__ */
diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c
index ff40bf1e638..83f3f9bc961 100644
--- a/source/blender/editors/space_sequencer/sequencer_modifier.c
+++ b/source/blender/editors/space_sequencer/sequencer_modifier.c
@@ -29,24 +29,14 @@
* \ingroup spseq
*/
-#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
-#include "DNA_mask_types.h"
-#include "DNA_userdef_types.h"
#include "BKE_context.h"
-#include "BKE_global.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
#include "BKE_sequencer.h"
-#include "BKE_movieclip.h"
-#include "BKE_mask.h"
-#include "BKE_report.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -54,8 +44,6 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
-#include "UI_interface.h"
-#include "UI_resources.h"
/* own include */
#include "sequencer_intern.h"
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index dff8f69509e..33a8a1c5b41 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -40,6 +40,8 @@
#include "ED_markers.h"
#include "ED_transform.h" /* transform keymap */
+#include "BKE_sequencer.h"
+
#include "sequencer_intern.h"
@@ -50,7 +52,7 @@ void sequencer_operatortypes(void)
{
/* sequencer_edit.c */
WM_operatortype_append(SEQUENCER_OT_cut);
- WM_operatortype_append(SEQUENCER_OT_trim);
+ WM_operatortype_append(SEQUENCER_OT_slip);
WM_operatortype_append(SEQUENCER_OT_mute);
WM_operatortype_append(SEQUENCER_OT_unmute);
WM_operatortype_append(SEQUENCER_OT_lock);
@@ -86,6 +88,7 @@ void sequencer_operatortypes(void)
WM_operatortype_append(SEQUENCER_OT_view_ghost_border);
WM_operatortype_append(SEQUENCER_OT_rebuild_proxy);
+ WM_operatortype_append(SEQUENCER_OT_enable_proxies);
WM_operatortype_append(SEQUENCER_OT_change_effect_input);
WM_operatortype_append(SEQUENCER_OT_change_effect_type);
WM_operatortype_append(SEQUENCER_OT_change_path);
@@ -317,7 +320,7 @@ void sequencer_keymap(wmKeyConfig *keyconf)
WM_keymap_add_menu(keymap, "SEQUENCER_MT_change", CKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "SEQUENCER_OT_trim", TKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SEQUENCER_OT_slip", SKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_int", OKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "scene.sequence_editor.overlay_frame");
diff --git a/source/blender/editors/space_sequencer/sequencer_preview.c b/source/blender/editors/space_sequencer/sequencer_preview.c
new file mode 100644
index 00000000000..c8834d394f5
--- /dev/null
+++ b/source/blender/editors/space_sequencer/sequencer_preview.c
@@ -0,0 +1,172 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation, 2003-2009, Antony Riakiotakis
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_sequencer/sequencer_preview.c
+ * \ingroup spseq
+ */
+
+#include "DNA_sequence_types.h"
+#include "DNA_sound_types.h"
+
+#include "BLI_listbase.h"
+#include "BLI_threads.h"
+
+#include "BKE_sound.h"
+#include "BKE_context.h"
+#include "BKE_global.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "sequencer_intern.h"
+
+typedef struct PreviewJob {
+ ListBase previews;
+ ThreadMutex *mutex;
+ Scene *scene;
+ int total;
+ int processed;
+} PreviewJob;
+
+typedef struct PreviewJobAudio {
+ struct PreviewJobAudio *next, *prev;
+ bSound *sound;
+ int lr; /* sample left or right */
+ int startframe;
+ bool waveform; /* reload sound or waveform */
+} PreviewJobAudio;
+
+static void free_preview_job(void *data)
+{
+ PreviewJob *pj = (PreviewJob *)data;
+
+ BLI_mutex_free(pj->mutex);
+ BLI_freelistN(&pj->previews);
+ MEM_freeN(pj);
+}
+
+/* only this runs inside thread */
+static void preview_startjob(void *data, short *stop, short *do_update, float *progress)
+{
+ PreviewJob *pj = data;
+ PreviewJobAudio *previewjb;
+
+ BLI_mutex_lock(pj->mutex);
+ previewjb = pj->previews.first;
+ BLI_mutex_unlock(pj->mutex);
+
+ while (previewjb) {
+ PreviewJobAudio *preview_next;
+ bSound *sound = previewjb->sound;
+
+ sound_read_waveform(sound, stop);
+
+ if (*stop || G.is_break) {
+ BLI_mutex_lock(pj->mutex);
+ previewjb = previewjb->next;
+ BLI_mutex_unlock(pj->mutex);
+ while (previewjb) {
+ sound = previewjb->sound;
+
+ /* make sure we cleanup the loading flag! */
+ BLI_spin_lock(sound->spinlock);
+ sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+ BLI_spin_unlock(sound->spinlock);
+
+ BLI_mutex_lock(pj->mutex);
+ previewjb = previewjb->next;
+ BLI_mutex_unlock(pj->mutex);
+ }
+
+ BLI_mutex_lock(pj->mutex);
+ BLI_freelistN(&pj->previews);
+ pj->total = 0;
+ pj->processed = 0;
+ BLI_mutex_unlock(pj->mutex);
+ break;
+ }
+
+ BLI_mutex_lock(pj->mutex);
+ preview_next = previewjb->next;
+ BLI_freelinkN(&pj->previews, previewjb);
+ previewjb = preview_next;
+ pj->processed++;
+ *progress = (pj->total > 0) ? (float)pj->processed / (float)pj->total : 1.0f;
+ *do_update = true;
+ BLI_mutex_unlock(pj->mutex);
+ }
+}
+
+static void preview_endjob(void *data)
+{
+ PreviewJob *pj = data;
+
+ WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, pj->scene);
+}
+
+
+void sequencer_preview_add_sound(const bContext *C, Sequence *seq)
+{
+ /* first, get the preview job, if it exists */
+ wmJob *wm_job;
+ PreviewJob *pj;
+ ScrArea *sa = CTX_wm_area(C);
+ PreviewJobAudio *audiojob = MEM_callocN(sizeof(PreviewJobAudio), "preview_audio");
+ wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Strip Previews",
+ WM_JOB_PROGRESS, WM_JOB_TYPE_SEQ_BUILD_PREVIEW);
+
+ pj = WM_jobs_customdata_get(wm_job);
+
+ if (!pj) {
+ pj = MEM_callocN(sizeof(PreviewJob), "preview rebuild job");
+
+ pj->mutex = BLI_mutex_alloc();
+ pj->scene = CTX_data_scene(C);
+
+ WM_jobs_customdata_set(wm_job, pj, free_preview_job);
+ WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_SEQUENCER, NC_SCENE | ND_SEQUENCER);
+ WM_jobs_callbacks(wm_job, preview_startjob, NULL, NULL, preview_endjob);
+ }
+
+ /* attempt to lock mutex of job here */
+
+ audiojob->sound = seq->sound;
+
+ BLI_mutex_lock(pj->mutex);
+ BLI_addtail(&pj->previews, audiojob);
+ pj->total++;
+ BLI_mutex_unlock(pj->mutex);
+
+ if (!WM_jobs_is_running(wm_job)) {
+ G.is_break = false;
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+ }
+
+ ED_area_tag_redraw(sa);
+}
diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c
index 9b3b9f23036..24b3776da6d 100644
--- a/source/blender/editors/space_sequencer/sequencer_scopes.c
+++ b/source/blender/editors/space_sequencer/sequencer_scopes.c
@@ -55,7 +55,7 @@ static void rgb_to_yuv_normalized(const float rgb[3], float yuv[3])
static void scope_put_pixel(unsigned char *table, unsigned char *pos)
{
- char newval = table[*pos];
+ unsigned char newval = table[*pos];
pos[0] = pos[1] = pos[2] = newval;
pos[3] = 255;
}
@@ -148,8 +148,8 @@ static ImBuf *make_waveform_view_from_ibuf_byte(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
int x, y;
- unsigned char *src = (unsigned char *) ibuf->rect;
- unsigned char *tgt = (unsigned char *) rval->rect;
+ const unsigned char *src = (unsigned char *)ibuf->rect;
+ unsigned char *tgt = (unsigned char *)rval->rect;
int w = ibuf->x + 3;
int h = 515;
float waveform_gamma = 0.2;
@@ -166,7 +166,7 @@ static ImBuf *make_waveform_view_from_ibuf_byte(ImBuf *ibuf)
unsigned char *last_p = NULL;
for (x = 0; x < ibuf->x; x++) {
- unsigned char *rgb = src + 4 * (ibuf->x * y + x);
+ const unsigned char *rgb = src + 4 * (ibuf->x * y + x);
float v = (float)rgb_to_luma_byte(rgb) / 255.0f;
unsigned char *p = tgt;
p += 4 * (w * ((int) (v * (h - 3)) + 1) + x + 1);
@@ -189,7 +189,7 @@ static ImBuf *make_waveform_view_from_ibuf_float(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
int x, y;
- float *src = ibuf->rect_float;
+ const float *src = ibuf->rect_float;
unsigned char *tgt = (unsigned char *) rval->rect;
int w = ibuf->x + 3;
int h = 515;
@@ -245,8 +245,8 @@ static ImBuf *make_sep_waveform_view_from_ibuf_byte(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
int x, y;
- unsigned char *src = (unsigned char *) ibuf->rect;
- unsigned char *tgt = (unsigned char *) rval->rect;
+ const unsigned char *src = (const unsigned char *)ibuf->rect;
+ unsigned char *tgt = (unsigned char *)rval->rect;
int w = ibuf->x + 3;
int sw = ibuf->x / 3;
int h = 515;
@@ -264,7 +264,7 @@ static ImBuf *make_sep_waveform_view_from_ibuf_byte(ImBuf *ibuf)
for (x = 0; x < ibuf->x; x++) {
int c;
- unsigned char *rgb = src + 4 * (ibuf->x * y + x);
+ const unsigned char *rgb = src + 4 * (ibuf->x * y + x);
for (c = 0; c < 3; c++) {
unsigned char *p = tgt;
p += 4 * (w * ((rgb[c] * (h - 3)) / 255 + 1) + c * sw + x / 3 + 1);
@@ -290,8 +290,8 @@ static ImBuf *make_sep_waveform_view_from_ibuf_float(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
int x, y;
- float *src = ibuf->rect_float;
- unsigned char *tgt = (unsigned char *) rval->rect;
+ const float *src = ibuf->rect_float;
+ unsigned char *tgt = (unsigned char *)rval->rect;
int w = ibuf->x + 3;
int sw = ibuf->x / 3;
int h = 515;
@@ -455,7 +455,7 @@ static ImBuf *make_histogram_view_from_ibuf_byte(ImBuf *ibuf)
ImBuf *rval = IMB_allocImBuf(515, 128, 32, IB_rect);
int x, y;
unsigned int nr, ng, nb;
- unsigned char *src = (unsigned char *) ibuf->rect;
+ const unsigned char *src = (unsigned char *)ibuf->rect;
unsigned int bins[3][HIS_STEPS];
@@ -468,7 +468,7 @@ static ImBuf *make_histogram_view_from_ibuf_byte(ImBuf *ibuf)
memset(cur_bins, 0, sizeof(cur_bins));
for (x = 0; x < ibuf->x; x++) {
- unsigned char *pixel = src + (y * ibuf->x + x) * 4;
+ const unsigned char *pixel = src + (y * ibuf->x + x) * 4;
cur_bins[0][pixel[0]]++;
cur_bins[1][pixel[1]]++;
@@ -532,7 +532,7 @@ static ImBuf *make_histogram_view_from_ibuf_float(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(515, 128, 32, IB_rect);
int nr, ng, nb, x, y;
- float *src = ibuf->rect_float;
+ const float *src = ibuf->rect_float;
unsigned int bins[3][HIS_STEPS];
@@ -635,7 +635,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_byte(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(515, 515, 32, IB_rect);
int x, y;
- char *src = (char *) ibuf->rect;
+ const char *src = (const char *) ibuf->rect;
char *tgt = (char *) rval->rect;
float rgb[3], yuv[3];
int w = 515;
@@ -659,7 +659,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_byte(ImBuf *ibuf)
for (y = 0; y < ibuf->y; y++) {
for (x = 0; x < ibuf->x; x++) {
const char *src1 = src + 4 * (ibuf->x * y + x);
- const char *p;
+ char *p;
rgb[0] = (float)src1[0] / 255.0f;
rgb[1] = (float)src1[1] / 255.0f;
@@ -681,7 +681,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf)
{
ImBuf *rval = IMB_allocImBuf(515, 515, 32, IB_rect);
int x, y;
- float *src = ibuf->rect_float;
+ const float *src = ibuf->rect_float;
char *tgt = (char *) rval->rect;
float rgb[3], yuv[3];
int w = 515;
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 933daf4adee..4fbe0c6a241 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -357,25 +357,22 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *e
case SEQ_SELECT_LR_MOUSE:
x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
break;
-
case SEQ_SELECT_LR_LEFT:
- x = CFRA - 1;
- break;
case SEQ_SELECT_LR_RIGHT:
- x = CFRA + 1;
+ x = CFRA;
break;
}
SEQP_BEGIN (ed, seq)
{
if (x < CFRA) {
- if (seq->enddisp < CFRA) {
+ if (seq->enddisp <= CFRA) {
seq->flag |= SELECT;
recurs_sel_seq(seq);
}
}
else {
- if (seq->startdisp > CFRA) {
+ if (seq->startdisp >= CFRA) {
seq->flag |= SELECT;
recurs_sel_seq(seq);
}
@@ -999,7 +996,7 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq)
if (SEQ_HAS_PATH(actseq) && dir) {
SEQP_BEGIN (ed, seq)
{
- if (SEQ_HAS_PATH(seq) && seq->strip && strcmp(seq->strip->dir, dir) == 0) {
+ if (SEQ_HAS_PATH(seq) && seq->strip && STREQ(seq->strip->dir, dir)) {
seq->flag |= SELECT;
changed = true;
}
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index c0cfaed7867..7a7f189b187 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -144,9 +144,9 @@ static SpaceLink *sequencer_new(const bContext *C)
ar->alignment = RGN_ALIGN_TOP;
ar->flag |= RGN_FLAG_HIDDEN;
/* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
- ar->v2d.keepzoom = V2D_KEEPASPECT | V2D_KEEPZOOM;
- ar->v2d.minzoom = 0.00001f;
- ar->v2d.maxzoom = 100000.0f;
+ ar->v2d.keepzoom = V2D_KEEPASPECT | V2D_KEEPZOOM | V2D_LIMITZOOM;
+ ar->v2d.minzoom = 0.001f;
+ ar->v2d.maxzoom = 1000.0f;
ar->v2d.tot.xmin = -960.0f; /* 1920 width centered */
ar->v2d.tot.ymin = -540.0f; /* 1080 height centered */
ar->v2d.tot.xmax = 960.0f;
@@ -328,7 +328,7 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl)
SpaceSeq *sseqn = MEM_dupallocN(sl);
/* clear or remove stuff from old */
-// XXX sseq->gpd = gpencil_data_duplicate(sseq->gpd);
+// XXX sseq->gpd = gpencil_data_duplicate(sseq->gpd, false);
memset(&sseqn->scopes, 0, sizeof(sseqn->scopes));
@@ -352,6 +352,10 @@ static void sequencer_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn
if (wmn->data == ND_SPACE_SEQUENCER)
sequencer_scopes_tag_refresh(sa);
break;
+ case NC_GPENCIL:
+ if (wmn->data & ND_GPENCIL_EDITMODE)
+ ED_area_tag_redraw(sa);
+ break;
}
}
@@ -500,6 +504,13 @@ static void sequencer_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa
break;
}
break;
+ case NC_ANIMATION:
+ switch (wmn->data) {
+ case ND_KEYFRAME:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
case NC_SPACE:
if (wmn->data == ND_SPACE_SEQUENCER)
ED_region_tag_redraw(ar);
@@ -559,7 +570,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar)
if (sseq->mainb == SEQ_DRAW_SEQUENCE) sseq->mainb = SEQ_DRAW_IMG_IMBUF;
if (!show_split || sseq->overlay_type != SEQ_DRAW_OVERLAY_REFERENCE)
- draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false);
+ draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, false);
if (show_split && sseq->overlay_type != SEQ_DRAW_OVERLAY_CURRENT) {
int over_cfra;
@@ -570,7 +581,7 @@ static void sequencer_preview_area_draw(const bContext *C, ARegion *ar)
over_cfra = scene->r.cfra + scene->ed->over_ofs;
if (over_cfra != scene->r.cfra || sseq->overlay_type != SEQ_DRAW_OVERLAY_RECT)
- draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true);
+ draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true, false);
}
if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) {
@@ -585,7 +596,7 @@ static void sequencer_preview_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
- if (wmn->action == NA_EDITED) {
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
ED_region_tag_redraw(ar);
}
break;
@@ -595,6 +606,16 @@ static void sequencer_preview_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED
case ND_MARKERS:
case ND_SEQUENCER:
case ND_RENDER_OPTIONS:
+ case ND_DRAW_RENDER_VIEWPORT:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_ANIMATION:
+ switch (wmn->data) {
+ case ND_KEYFRAME:
+ /* Otherwise, often prevents seing immediately effects of keyframe editing... */
+ BKE_sequencer_cache_cleanup();
ED_region_tag_redraw(ar);
break;
}
@@ -641,7 +662,7 @@ static void sequencer_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED
/* context changes */
switch (wmn->category) {
case NC_GPENCIL:
- if (wmn->data == ND_DATA) {
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
ED_region_tag_redraw(ar);
}
break;
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 1e710b88cad..d890b9f9b4d 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -135,7 +135,7 @@ static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
break;
case ND_CURSOR:
if (st->text && st->text == wmn->reference)
- text_scroll_to_cursor(st, sa);
+ text_scroll_to_cursor__area(st, sa, true);
ED_area_tag_redraw(sa);
break;
@@ -156,7 +156,7 @@ static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
break;
case NA_SELECTED:
if (st->text && st->text == wmn->reference)
- text_scroll_to_cursor(st, sa);
+ text_scroll_to_cursor__area(st, sa, true);
break;
}
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index 99e1606c9bd..1637ae14892 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -183,7 +183,7 @@ static GHash *text_autocomplete_build(Text *text)
const int choice_len = i_end - i_start;
if ((choice_len > seek_len) &&
- (seek_len == 0 || strncmp(seek, str_sub, seek_len) == 0) &&
+ (seek_len == 0 || STREQLEN(seek, str_sub, seek_len)) &&
(seek != str_sub))
{
// printf("Adding: %s\n", s);
@@ -207,18 +207,16 @@ static GHash *text_autocomplete_build(Text *text)
}
{
- GHashIterator *iter = BLI_ghashIterator_new(gh);
+ GHashIterator gh_iter;
/* get the formatter for highlighting */
TextFormatType *tft;
tft = ED_text_format_get(text);
- for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) {
- const char *s = BLI_ghashIterator_getValue(iter);
+ GHASH_ITER (gh_iter, gh) {
+ const char *s = BLI_ghashIterator_getValue(&gh_iter);
texttool_suggest_add(s, tft->format_identifier(s));
}
- BLI_ghashIterator_free(iter);
-
}
}
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index af827d6dc5a..462b619f497 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -28,8 +28,6 @@
* \ingroup sptext
*/
-
-
#include "MEM_guardedalloc.h"
#include "BLF_api.h"
@@ -44,6 +42,9 @@
#include "BKE_context.h"
#include "BKE_suggestions.h"
#include "BKE_text.h"
+#include "BKE_screen.h"
+
+#include "ED_text.h"
#include "BIF_gl.h"
@@ -381,7 +382,9 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
int a, fstart, fpos; /* utf8 chars */
int mi, ma, mstart, mend; /* mem */
char fmt_prev = 0xff;
-
+ /* don't draw lines below this */
+ const int clip_min_y = -(int)(st->lheight_dpi - 1);
+
flatten_string(st, &fs, str);
str = fs.buf;
max = w / st->cwidth;
@@ -424,7 +427,8 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
mend = txt_utf8_forward_columns(str + mend, max, &padding) - str;
end = (wrap += max - padding);
- if (y <= 0) break;
+ if (y <= clip_min_y)
+ break;
}
else if (str[mi] == ' ' || str[mi] == '-') {
wrap = i + 1; mend = mi + 1;
@@ -432,7 +436,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
}
/* Draw the remaining text */
- for (a = fstart, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
+ for (a = fstart, ma = mstart; str[ma] && y > clip_min_y; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
if (use_syntax) {
if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
}
@@ -519,7 +523,7 @@ static void text_drawcache_init(SpaceText *st)
DrawCache *drawcache = MEM_callocN(sizeof(DrawCache), "text draw cache");
drawcache->winx = -1;
- drawcache->nlines = BLI_countlist(&st->text->lines);
+ drawcache->nlines = BLI_listbase_count(&st->text->lines);
drawcache->text_id[0] = '\0';
st->drawcache = drawcache;
@@ -545,7 +549,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar)
full_update |= drawcache->tabnumber != st->tabnumber; /* word-wrapping option was toggled */
full_update |= drawcache->lheight != st->lheight_dpi; /* word-wrapping option was toggled */
full_update |= drawcache->cwidth != st->cwidth; /* word-wrapping option was toggled */
- full_update |= strncmp(drawcache->text_id, txt->id.name, MAX_ID_NAME); /* text datablock was changed */
+ full_update |= !STREQLEN(drawcache->text_id, txt->id.name, MAX_ID_NAME); /* text datablock was changed */
if (st->wordwrap) {
/* update line heights */
@@ -560,7 +564,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar)
int lineno = 0, size, lines_count;
int *fp = drawcache->line_height, *new_tail, *old_tail;
- nlines = BLI_countlist(&txt->lines);
+ nlines = BLI_listbase_count(&txt->lines);
size = sizeof(int) * nlines;
if (fp) fp = MEM_reallocN(fp, size);
@@ -605,7 +609,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar)
}
if (full_update || drawcache->update_flag) {
- nlines = BLI_countlist(&txt->lines);
+ nlines = BLI_listbase_count(&txt->lines);
if (st->showlinenrs)
st->linenrs_tot = (int)floor(log10((float)nlines)) + 1;
@@ -892,15 +896,15 @@ static void draw_textscroll(SpaceText *st, rcti *scroll, rcti *back)
UI_ThemeColor(TH_BACK);
glRecti(back->xmin, back->ymin, back->xmax, back->ymax);
- uiWidgetScrollDraw(&wcol, scroll, &st->txtbar, (st->flags & ST_SCROLL_SELECT) ? UI_SCROLL_PRESSED : 0);
+ UI_draw_widget_scroll(&wcol, scroll, &st->txtbar, (st->flags & ST_SCROLL_SELECT) ? UI_SCROLL_PRESSED : 0);
- uiSetRoundBox(UI_CNR_ALL);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
rad = 0.4f * min_ii(BLI_rcti_size_x(&st->txtscroll), BLI_rcti_size_y(&st->txtscroll));
UI_GetThemeColor3ubv(TH_HILITE, col);
col[3] = 48;
glColor4ubv(col);
glEnable(GL_BLEND);
- uiRoundBox(st->txtscroll.xmin + 1, st->txtscroll.ymin, st->txtscroll.xmax - 1, st->txtscroll.ymax, rad);
+ UI_draw_roundbox(st->txtscroll.xmin + 1, st->txtscroll.ymin, st->txtscroll.xmax - 1, st->txtscroll.ymax, rad);
glDisable(GL_BLEND);
}
@@ -1034,7 +1038,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
x = MAX2(0, ar->winx - boxw);
/* not needed but stands out nicer */
- uiDrawBoxShadow(220, x, y - boxh, x + boxw, y);
+ UI_draw_box_shadow(220, x, y - boxh, x + boxw, y);
UI_ThemeColor(TH_SHADE1);
glRecti(x - 1, y + 1, x + boxw + 1, y - boxh - 1);
@@ -1323,6 +1327,8 @@ void draw_text_main(SpaceText *st, ARegion *ar)
int i, x, y, winx, linecount = 0, lineno = 0;
int wraplinecount = 0, wrap_skip = 0;
int margin_column_x;
+ /* don't draw lines below this */
+ const int clip_min_y = -(int)(st->lheight_dpi - 1);
/* if no text, nothing to do */
if (!text)
@@ -1330,7 +1336,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
/* dpi controlled line height and font size */
st->lheight_dpi = (U.widget_unit * st->lheight) / 20;
- st->viewlines = (st->lheight_dpi) ? (int)ar->winy / (st->lheight_dpi + TXT_LINE_SPACING) : 0;
+ st->viewlines = (st->lheight_dpi) ? (int)(ar->winy - clip_min_y) / (st->lheight_dpi + TXT_LINE_SPACING) : 0;
text_update_drawcache(st, ar);
@@ -1394,7 +1400,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
/* draw the text */
UI_ThemeColor(TH_TEXT);
- for (i = 0; y > 0 && i < st->viewlines && tmp; i++, tmp = tmp->next) {
+ for (i = 0; y > clip_min_y && i < st->viewlines && tmp; i++, tmp = tmp->next) {
if (st->showsyntax && !tmp->format)
tft->format_line(st, tmp, false);
@@ -1441,7 +1447,6 @@ void draw_text_main(SpaceText *st, ARegion *ar)
/* draw other stuff */
draw_brackets(st, ar);
- glTranslatef(GLA_PIXEL_OFS, GLA_PIXEL_OFS, 0.0f); /* XXX scroll requires exact pixel space */
draw_textscroll(st, &scroll, &back);
draw_documentation(st, ar);
draw_suggestion_list(st, ar);
@@ -1461,22 +1466,15 @@ void text_update_character_width(SpaceText *st)
/* Moves the view to the cursor location,
* also used to make sure the view isn't outside the file */
-void text_scroll_to_cursor(SpaceText *st, ScrArea *sa)
+void text_scroll_to_cursor(SpaceText *st, ARegion *ar, const bool center)
{
Text *text;
- ARegion *ar = NULL;
- int i, x, winx = 0;
+ int i, x, winx = ar->winx;
if (ELEM(NULL, st, st->text, st->text->curl)) return;
text = st->text;
- for (ar = sa->regionbase.first; ar; ar = ar->next)
- if (ar->regiontype == RGN_TYPE_WINDOW) {
- winx = ar->winx;
- break;
- }
-
text_update_character_width(st);
i = txt_get_span(text->lines.first, text->sell);
@@ -1486,8 +1484,19 @@ void text_scroll_to_cursor(SpaceText *st, ScrArea *sa)
i += offl;
}
- if (st->top + st->viewlines <= i || st->top > i)
- st->top = i - st->viewlines / 2;
+ if (center) {
+ if (st->top + st->viewlines <= i || st->top > i) {
+ st->top = i - st->viewlines / 2;
+ }
+ }
+ else {
+ if (st->top + st->viewlines <= i) {
+ st->top = i - (st->viewlines - 1);
+ }
+ else if (st->top > i) {
+ st->top = i;
+ }
+ }
if (st->wordwrap) {
st->left = 0;
@@ -1496,8 +1505,19 @@ void text_scroll_to_cursor(SpaceText *st, ScrArea *sa)
x = st->cwidth * (text_get_char_pos(st, text->sell->line, text->selc) - st->left);
winx -= TXT_OFFSET + (st->showlinenrs ? TEXTXLOC : 0) + TXT_SCROLL_WIDTH;
- if (x <= 0 || x > winx)
- st->left += (x - winx / 2) / st->cwidth;
+ if (center) {
+ if (x <= 0 || x > winx) {
+ st->left += (x - winx / 2) / st->cwidth;
+ }
+ }
+ else {
+ if (x <= 0) {
+ st->left += ((x + 1) / st->cwidth) - 1;
+ }
+ else if (x > winx) {
+ st->left += ((x - (winx + 1)) / st->cwidth) + 1;
+ }
+ }
}
if (st->top < 0) st->top = 0;
@@ -1507,10 +1527,58 @@ void text_scroll_to_cursor(SpaceText *st, ScrArea *sa)
st->scroll_accum[1] = 0.0f;
}
+/* takes an area instead of a region, use for listeners */
+void text_scroll_to_cursor__area(SpaceText *st, ScrArea *sa, const bool center)
+{
+ ARegion *ar;
+
+ if (ELEM(NULL, st, st->text, st->text->curl)) return;
+
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+
+ if (ar) {
+ text_scroll_to_cursor(st, ar, center);
+ }
+}
+
void text_update_cursor_moved(bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
SpaceText *st = CTX_wm_space_text(C);
- text_scroll_to_cursor(st, sa);
+ text_scroll_to_cursor__area(st, sa, true);
+}
+
+/**
+ * Takes a cursor (row, character) and returns x,y pixel coords.
+ */
+bool ED_text_region_location_from_cursor(SpaceText *st, ARegion *ar, const int cursor_co[2], int r_pixel_co[2])
+{
+ TextLine *line = NULL;
+
+ if (!st->text) {
+ goto error;
+ }
+
+ line = BLI_findlink(&st->text->lines, cursor_co[0]);
+ if (!line || (cursor_co[1] < 0) || (cursor_co[1] > line->len)) {
+ goto error;
+ }
+ else {
+ int offl, offc;
+ int linenr_offset = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
+ /* handle tabs as well! */
+ int char_pos = text_get_char_pos(st, line->line, cursor_co[1]);
+
+ wrap_offset(st, ar, line, cursor_co[1], &offl, &offc);
+ r_pixel_co[0] = (char_pos + offc - st->left) * st->cwidth + linenr_offset;
+ r_pixel_co[1] = (cursor_co[0] + offl - st->top) * (st->lheight_dpi + TXT_LINE_SPACING);
+ r_pixel_co[1] = (ar->winy - (r_pixel_co[1] + TXT_OFFSET)) - st->lheight_dpi;
+ }
+ return true;
+
+
+error:
+ r_pixel_co[0] = r_pixel_co[1] = -1;
+ return false;
}
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index b1d57f5a75e..92a3cce12e6 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -34,7 +34,6 @@
#include "BLI_blenlib.h"
-#include "BLF_translation.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -142,7 +141,7 @@ void TEXT_OT_start_find(wmOperatorType *ot)
uiPopupMenu *pup;
if (text) {
- pup = uiPupMenuBegin(C, IFACE_("Text"), ICON_NONE);
+ pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE);
if (txt_has_sel(text)) {
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_cut");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_copy");
@@ -153,13 +152,13 @@ void TEXT_OT_start_find(wmOperatorType *ot)
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save_as");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_run_script");
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
else {
- pup = uiPupMenuBegin(C, IFACE_("File"), ICON_NONE);
+ pup = UI_popup_menu_begin(C, IFACE_("File"), ICON_NONE);
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open");
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
}
@@ -168,11 +167,11 @@ void TEXT_OT_start_find(wmOperatorType *ot)
uiPopupMenu *pup;
- pup = uiPupMenuBegin(C, IFACE_("Edit"), ICON_NONE);
+ pup = UI_popup_menu_begin(C, IFACE_("Edit"), ICON_NONE);
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_cut");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_copy");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_paste");
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
{
@@ -181,19 +180,19 @@ void TEXT_OT_start_find(wmOperatorType *ot)
uiPopupMenu *pup;
if (text) {
- pup = uiPupMenuBegin(C, IFACE_("Text"), ICON_NONE);
+ pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE);
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_save_as");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_run_script");
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
else {
- pup = uiPupMenuBegin(C, IFACE_("File"), ICON_NONE);
+ pup = UI_popup_menu_begin(C, IFACE_("File"), ICON_NONE);
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_new");
uiItemO(layout, NULL, ICON_NONE, "TEXT_OT_open");
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
}
@@ -202,7 +201,7 @@ void TEXT_OT_start_find(wmOperatorType *ot)
uiPopupMenu *pup;
- pup = uiPupMenuBegin(C, IFACE_("Text"), ICON_NONE);
+ pup = UI_popup_menu_begin(C, IFACE_("Text"), ICON_NONE);
uiItemEnumO(layout, "TEXT_OT_move", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Top of File"),
0, "type", FILE_TOP);
uiItemEnumO(layout, "TEXT_OT_move", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Bottom of File"),
@@ -210,7 +209,7 @@ void TEXT_OT_start_find(wmOperatorType *ot)
uiItemEnumO(layout, "TEXT_OT_move", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Page Up"), 0, "type", PREV_PAGE);
uiItemEnumO(layout, "TEXT_OT_move", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Page Down"),
0, "type", NEXT_PAGE);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
#endif
diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h
index d4cd029dac0..f577714c480 100644
--- a/source/blender/editors/space_text/text_intern.h
+++ b/source/blender/editors/space_text/text_intern.h
@@ -50,7 +50,8 @@ void draw_text_main(struct SpaceText *st, struct ARegion *ar);
void text_update_line_edited(struct TextLine *line);
void text_update_edited(struct Text *text);
void text_update_character_width(struct SpaceText *st);
-void text_scroll_to_cursor(struct SpaceText *st, struct ScrArea *sa);
+void text_scroll_to_cursor(struct SpaceText *st, struct ARegion *ar, const bool center);
+void text_scroll_to_cursor__area(struct SpaceText *st, struct ScrArea *sa, const bool center);
void text_update_cursor_moved(struct bContext *C);
#define TXT_OFFSET ((int)(0.5f * U.widget_unit))
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 852edaac7dc..ad8050a50e8 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -171,7 +171,7 @@ static int text_new_exec(bContext *C, wmOperator *UNUSED(op))
text = BKE_text_add(bmain, "Text");
/* hook into UI */
- uiIDContextProperty(C, &ptr, &prop);
+ UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
if (prop) {
RNA_id_pointer_create(&text->id, &idptr);
@@ -214,7 +214,7 @@ static void text_open_init(bContext *C, wmOperator *op)
PropertyPointerRNA *pprop;
op->customdata = pprop = MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA");
- uiIDContextProperty(C, &pprop->ptr, &pprop->prop);
+ UI_context_active_but_prop_get_templateID(C, &pprop->ptr, &pprop->prop);
}
static void text_open_cancel(bContext *UNUSED(C), wmOperator *op)
@@ -300,7 +300,7 @@ void TEXT_OT_open(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE | PYSCRIPTFILE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_TEXT | FILE_TYPE_PYSCRIPT, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path
RNA_def_boolean(ot->srna, "internal", 0, "Make internal", "Make text file internal after loading");
}
@@ -577,7 +577,7 @@ void TEXT_OT_save_as(wmOperatorType *ot)
ot->poll = text_edit_poll;
/* properties */
- WM_operator_properties_filesel(ot, FOLDERFILE | TEXTFILE | PYSCRIPTFILE, FILE_SPECIAL, FILE_SAVE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_TEXT | FILE_TYPE_PYSCRIPT, FILE_SPECIAL, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); //XXX TODO, relative_path
}
@@ -714,88 +714,6 @@ void TEXT_OT_refresh_pyconstraints(wmOperatorType *ot)
/******************* paste operator *********************/
-static char *txt_copy_selected(Text *text)
-{
- TextLine *tmp, *linef, *linel;
- char *buf = NULL;
- int charf, charl, length = 0;
-
- if (!text) return NULL;
- if (!text->curl) return NULL;
- if (!text->sell) return NULL;
-
- if (!txt_has_sel(text)) return NULL;
-
- if (text->curl == text->sell) {
- linef = linel = text->curl;
-
- if (text->curc < text->selc) {
- charf = text->curc;
- charl = text->selc;
- }
- else {
- charf = text->selc;
- charl = text->curc;
- }
- }
- else if (txt_get_span(text->curl, text->sell) < 0) {
- linef = text->sell;
- linel = text->curl;
-
- charf = text->selc;
- charl = text->curc;
- }
- else {
- linef = text->curl;
- linel = text->sell;
-
- charf = text->curc;
- charl = text->selc;
- }
-
- if (linef == linel) {
- length = charl - charf;
-
- buf = MEM_callocN(length + 1, "cut buffera");
-
- BLI_strncpy(buf, linef->line + charf, length + 1);
- }
- else {
- length += linef->len - charf;
- length += charl;
- length++; /* For the '\n' */
-
- tmp = linef->next;
- while (tmp && tmp != linel) {
- length += tmp->len + 1;
- tmp = tmp->next;
- }
-
- buf = MEM_callocN(length + 1, "cut bufferb");
-
- strncpy(buf, linef->line + charf, linef->len - charf);
- length = linef->len - charf;
-
- buf[length++] = '\n';
-
- tmp = linef->next;
- while (tmp && tmp != linel) {
- strncpy(buf + length, tmp->line, tmp->len);
- length += tmp->len;
-
- buf[length++] = '\n';
-
- tmp = tmp->next;
- }
- strncpy(buf + length, linel->line, charl);
- length += charl;
-
- buf[length] = 0;
- }
-
- return buf;
-}
-
static int text_paste_exec(bContext *C, wmOperator *op)
{
const bool selection = RNA_boolean_get(op->ptr, "selection");
@@ -876,7 +794,10 @@ static void txt_copy_clipboard(Text *text)
{
char *buf;
- buf = txt_copy_selected(text);
+ if (!txt_has_sel(text))
+ return;
+
+ buf = txt_sel_to_buf(text);
if (buf) {
WM_clipboard_text_set(buf, 0);
@@ -2415,6 +2336,7 @@ typedef struct SetSelection {
int selecting;
int selc, sell;
short old[2];
+ wmTimer *timer; /* needed for scrolling when mouse at region bounds */
} SetSelection;
static int flatten_width(SpaceText *st, const char *str)
@@ -2615,10 +2537,14 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, con
y -= txt_get_span(text->lines.first, *linep) - st->top;
if (y > 0) {
- while (y-- != 0) if ((*linep)->next) *linep = (*linep)->next;
+ while (y-- != 0) {
+ if ((*linep)->next) *linep = (*linep)->next;
+ }
}
else if (y < 0) {
- while (y++ != 0) if ((*linep)->prev) *linep = (*linep)->prev;
+ while (y++ != 0) {
+ if ((*linep)->prev) *linep = (*linep)->prev;
+ }
}
@@ -2629,6 +2555,29 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, con
if (!sel) txt_pop_sel(text);
}
+static void text_cursor_timer_ensure(bContext *C, SetSelection *ssel)
+{
+ if (ssel->timer == NULL) {
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+
+ ssel->timer = WM_event_add_timer(wm, win, TIMER, 0.02f);
+ }
+}
+
+static void text_cursor_timer_remove(bContext *C, SetSelection *ssel)
+{
+ if (ssel->timer) {
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+
+ WM_event_remove_timer(wm, win, ssel->timer);
+ }
+ ssel->timer = NULL;
+}
+
+
+
static void text_cursor_set_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
@@ -2636,32 +2585,34 @@ static void text_cursor_set_apply(bContext *C, wmOperator *op, const wmEvent *ev
SetSelection *ssel = op->customdata;
if (event->mval[1] < 0 || event->mval[1] > ar->winy) {
- int d = (ssel->old[1] - event->mval[1]) * st->pix_per_line;
- if (d) txt_screen_skip(st, ar, d);
-
- text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1] < 0 ? 0 : ar->winy, 1);
+ text_cursor_timer_ensure(C, ssel);
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
+ if (event->type == TIMER) {
+ text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1], 1);
+ text_scroll_to_cursor(st, ar, false);
+ WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
+ }
}
else if (!st->wordwrap && (event->mval[0] < 0 || event->mval[0] > ar->winx)) {
- if (event->mval[0] > ar->winx) st->left++;
- else if (event->mval[0] < 0 && st->left > 0) st->left--;
-
- text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1], 1);
+ text_cursor_timer_ensure(C, ssel);
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
- // XXX PIL_sleep_ms(10);
+ if (event->type == TIMER) {
+ text_cursor_set_to_pos(st, ar, CLAMPIS(event->mval[0], 0, ar->winx), event->mval[1], 1);
+ text_scroll_to_cursor(st, ar, false);
+ WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
+ }
}
else {
- text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1], 1);
+ text_cursor_timer_remove(C, ssel);
- text_update_cursor_moved(C);
- WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
+ if (event->type != TIMER) {
+ text_cursor_set_to_pos(st, ar, event->mval[0], event->mval[1], 1);
+ text_scroll_to_cursor(st, ar, false);
+ WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
- ssel->old[0] = event->mval[0];
- ssel->old[1] = event->mval[1];
+ ssel->old[0] = event->mval[0];
+ ssel->old[1] = event->mval[1];
+ }
}
}
@@ -2681,6 +2632,7 @@ static void text_cursor_set_exit(bContext *C, wmOperator *op)
text_update_cursor_moved(C);
WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
+ text_cursor_timer_remove(C, ssel);
MEM_freeN(ssel);
}
@@ -2717,6 +2669,7 @@ static int text_set_selection_modal(bContext *C, wmOperator *op, const wmEvent *
case RIGHTMOUSE:
text_cursor_set_exit(C, op);
return OPERATOR_FINISHED;
+ case TIMER:
case MOUSEMOVE:
text_cursor_set_apply(C, op, event);
break;
@@ -2970,7 +2923,7 @@ static int text_find_and_replace(bContext *C, wmOperator *op, short mode)
if (mode != TEXT_FIND && txt_has_sel(text)) {
tmp = txt_sel_to_buf(text);
- if (flags & ST_MATCH_CASE) found = strcmp(st->findstr, tmp) == 0;
+ if (flags & ST_MATCH_CASE) found = STREQ(st->findstr, tmp);
else found = BLI_strcasecmp(st->findstr, tmp) == 0;
if (found) {
@@ -3144,36 +3097,36 @@ static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, const wmEve
case 1:
if (text->flags & TXT_ISDIRTY) {
/* modified locally and externally, ahhh. offer more possibilites. */
- pup = uiPupMenuBegin(C, IFACE_("File Modified Outside and Inside Blender"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("File Modified Outside and Inside Blender"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiItemEnumO_ptr(layout, op->type, IFACE_("Reload from disk (ignore local changes)"),
0, "resolution", RESOLVE_RELOAD);
uiItemEnumO_ptr(layout, op->type, IFACE_("Save to disk (ignore outside changes)"),
0, "resolution", RESOLVE_SAVE);
uiItemEnumO_ptr(layout, op->type, IFACE_("Make text internal (separate copy)"),
0, "resolution", RESOLVE_MAKE_INTERNAL);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
else {
- pup = uiPupMenuBegin(C, IFACE_("File Modified Outside Blender"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("File Modified Outside Blender"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiItemEnumO_ptr(layout, op->type, IFACE_("Reload from disk"), 0, "resolution", RESOLVE_RELOAD);
uiItemEnumO_ptr(layout, op->type, IFACE_("Make text internal (separate copy)"),
0, "resolution", RESOLVE_MAKE_INTERNAL);
uiItemEnumO_ptr(layout, op->type, IFACE_("Ignore"), 0, "resolution", RESOLVE_IGNORE);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
break;
case 2:
- pup = uiPupMenuBegin(C, IFACE_("File Deleted Outside Blender"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("File Deleted Outside Blender"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiItemEnumO_ptr(layout, op->type, IFACE_("Make text internal"), 0, "resolution", RESOLVE_MAKE_INTERNAL);
uiItemEnumO_ptr(layout, op->type, IFACE_("Recreate file"), 0, "resolution", RESOLVE_SAVE);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
break;
}
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
void TEXT_OT_resolve_conflict(wmOperatorType *ot)
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index 88c57d45b79..91a09708e1d 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -32,6 +32,7 @@
#include <string.h>
#include <stdio.h>
+#include "DNA_gpencil_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -57,6 +58,7 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "UI_interface.h"
#include "ED_space_api.h"
#include "ED_markers.h"
@@ -89,13 +91,12 @@ static void time_draw_sfra_efra(Scene *scene, View2D *v2d)
fdrawline((float)PEFRA, v2d->cur.ymin, (float)PEFRA, v2d->cur.ymax);
}
-#define CACHE_DRAW_HEIGHT 3.0f
-
static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene)
{
PTCacheID *pid;
ListBase pidlist;
SpaceTimeCache *stc = stime->caches.first;
+ const float cache_draw_height = (4.0f * UI_DPI_FAC * U.pixelsize);
float yoffs = 0.f;
if (!(stime->cache_display & TIME_CACHE_DISPLAY) || (!ob))
@@ -171,7 +172,7 @@ static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene)
glPushMatrix();
glTranslatef(0.0, (float)V2D_SCROLL_HEIGHT + yoffs, 0.0);
- glScalef(1.0, CACHE_DRAW_HEIGHT, 0.0);
+ glScalef(1.0, cache_draw_height, 0.0);
switch (pid->type) {
case PTCACHE_TYPE_SOFTBODY:
@@ -229,7 +230,7 @@ static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene)
glPopMatrix();
- yoffs += CACHE_DRAW_HEIGHT;
+ yoffs += cache_draw_height;
stc = stc->next;
}
@@ -294,6 +295,8 @@ static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel)
bDopeSheet ads = {NULL};
DLRBT_Tree keys;
ActKeyColumn *ak;
+ float ymin = v2d->tot.ymin;
+ float ymax = v2d->tot.ymax * 0.6f + ymin * 0.4f;
/* init binarytree-list for getting keyframes */
BLI_dlrbTree_init(&keys);
@@ -301,7 +304,7 @@ static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel)
/* init dopesheet settings */
if (onlysel)
ads.filterflag |= ADS_FILTER_ONLYSEL;
-
+
/* populate tree with keyframe nodes */
switch (GS(id->name)) {
case ID_SCE:
@@ -310,6 +313,9 @@ static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel)
case ID_OB:
ob_to_keylist(&ads, (Object *)id, &keys, NULL);
break;
+ case ID_GD:
+ gpencil_to_keylist(&ads, (bGPdata *)id, &keys);
+ break;
}
/* build linked-list for searching */
@@ -325,8 +331,8 @@ static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel)
(ak) && (ak->cfra <= v2d->cur.xmax);
ak = ak->next)
{
- glVertex2f(ak->cfra, v2d->tot.ymin);
- glVertex2f(ak->cfra, v2d->tot.ymax);
+ glVertex2f(ak->cfra, ymin);
+ glVertex2f(ak->cfra, ymax);
}
glEnd(); // GL_LINES
@@ -339,16 +345,23 @@ static void time_draw_keyframes(const bContext *C, ARegion *ar)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = CTX_data_gpencil_data(C);
View2D *v2d = &ar->v2d;
bool onlysel = ((scene->flag & SCE_KEYS_NO_SELONLY) == 0);
+ /* draw grease pencil keyframes (if available) */
+ if (gpd) {
+ UI_ThemeColor(TH_TIME_GP_KEYFRAME);
+ time_draw_idblock_keyframes(v2d, (ID *)gpd, onlysel);
+ }
+
/* draw scene keyframes first
* - don't try to do this when only drawing active/selected data keyframes,
* since this can become quite slow
*/
if (onlysel == 0) {
/* set draw color */
- glColor3ub(0xDD, 0xA7, 0x00);
+ UI_ThemeColorShade(TH_TIME_KEYFRAME, -50);
time_draw_idblock_keyframes(v2d, (ID *)scene, onlysel);
}
@@ -357,7 +370,7 @@ static void time_draw_keyframes(const bContext *C, ARegion *ar)
* OR the onlysel flag was set, which means that only active object's keyframes should
* be considered
*/
- glColor3ub(0xDD, 0xD7, 0x00);
+ UI_ThemeColor(TH_TIME_KEYFRAME);
if (ob && ((ob->mode == OB_MODE_POSE) || onlysel)) {
/* draw keyframes for active object only */
@@ -520,7 +533,7 @@ static void time_main_area_draw(const bContext *C, ARegion *ar)
/* markers */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
- draw_markers_time(C, 0);
+ ED_markers_draw(C, 0);
/* caches */
time_draw_cache(stime, obact, scene);
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 0bd094b6a33..f986e909c7f 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -47,9 +47,7 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "UI_view2d.h"
-#include "userpref_intern.h" // own include
/* ******************** default callbacks for userpref space ***************** */
diff --git a/source/blender/editors/space_userpref/userpref_ops.c b/source/blender/editors/space_userpref/userpref_ops.c
index 8dd6c3c0271..0783eacc65c 100644
--- a/source/blender/editors/space_userpref/userpref_ops.c
+++ b/source/blender/editors/space_userpref/userpref_ops.c
@@ -32,5 +32,4 @@
#include <string.h>
#include <stdio.h>
-#include "userpref_intern.h"
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 320267a4a7c..ab69e67361d 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -44,6 +44,7 @@ set(SRC
drawarmature.c
drawmesh.c
drawobject.c
+ drawsimdebug.c
drawvolume.c
space_view3d.c
view3d_buttons.c
diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c
index 17f90fc54e3..d8b18140cde 100644
--- a/source/blender/editors/space_view3d/drawanimviz.c
+++ b/source/blender/editors/space_view3d/drawanimviz.c
@@ -54,7 +54,6 @@
#include "ED_armature.h"
#include "ED_keyframes_draw.h"
-#include "BLF_api.h"
#include "UI_resources.h"
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 651c9389341..f33f074e6c5 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -61,7 +61,6 @@
#include "ED_armature.h"
#include "ED_keyframes_draw.h"
-#include "BLF_api.h"
#include "UI_resources.h"
@@ -1620,7 +1619,7 @@ static void draw_pose_dofs(Object *ob)
for (a = -16; a <= 16; a++) {
/* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */
float fac = ((float)a) / 16.0f * 0.5f;
- phi = (float)(0.5 * M_PI) + fac * (pchan->limitmax[0] - pchan->limitmin[0]);
+ phi = (float)M_PI_2 + fac * (pchan->limitmax[0] - pchan->limitmin[0]);
i = (a == -16) ? 2 : 3;
corner[i][0] = 0.0f;
@@ -2396,7 +2395,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
/* draw from first frame of range to last */
- for (CFRA = (int)start; CFRA < end; CFRA += (int)stepsize) {
+ for (CFRA = (int)start; CFRA <= end; CFRA += (int)stepsize) {
colfac = (end - (float)CFRA) / range;
UI_ThemeColorShadeAlpha(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)));
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index fa9ba23e454..755c633531d 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -60,7 +60,6 @@
#include "UI_resources.h"
-#include "GPU_buffers.h"
#include "GPU_extensions.h"
#include "GPU_draw.h"
#include "GPU_material.h"
@@ -97,7 +96,7 @@ typedef struct drawTFace_userData {
BLI_INLINE int edge_vis_index(const int index) { return index * 2; }
BLI_INLINE int edge_sel_index(const int index) { return index * 2 + 1; }
-static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me)
+static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me, bool draw_select_edges)
{
BLI_bitmap *bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__);
MPoly *mp;
@@ -113,8 +112,17 @@ static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me)
ml = me->mloop + mp->loopstart;
for (j = 0; j < mp->totloop; j++, ml++) {
- BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_vis_index(ml->e));
- if (select_set) BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_sel_index(ml->e));
+ if ((draw_select_edges == false) &&
+ (select_set && BLI_BITMAP_TEST(bitmap_edge_flags, edge_sel_index(ml->e))))
+ {
+ BLI_BITMAP_DISABLE(bitmap_edge_flags, edge_vis_index(ml->e));
+ }
+ else {
+ BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_vis_index(ml->e));
+ if (select_set) {
+ BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_sel_index(ml->e));
+ }
+ }
}
}
}
@@ -129,21 +137,26 @@ static DMDrawOption draw_mesh_face_select__setHiddenOpts(void *userData, int ind
Mesh *me = data->me;
if (me->drawflag & ME_DRAWEDGES) {
- if ((me->drawflag & ME_HIDDENEDGES) || (BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index))))
+ if ((BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index))))
return DM_DRAW_OPTION_NORMAL;
else
return DM_DRAW_OPTION_SKIP;
}
- else if (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index)))
+ else if (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index)) &&
+ BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index)))
+ {
return DM_DRAW_OPTION_NORMAL;
- else
+ }
+ else {
return DM_DRAW_OPTION_SKIP;
+ }
}
static DMDrawOption draw_mesh_face_select__setSelectOpts(void *userData, int index)
{
drawMeshFaceSelect_userData *data = userData;
- return (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index))) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP;
+ return (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index)) &&
+ BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index))) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP;
}
/* draws unselected */
@@ -158,12 +171,12 @@ static DMDrawOption draw_mesh_face_select__drawFaceOptsInv(void *userData, int i
return DM_DRAW_OPTION_SKIP;
}
-void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
+void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, bool draw_select_edges)
{
drawMeshFaceSelect_userData data;
data.me = me;
- data.edge_flags = get_tface_mesh_marked_edge_info(me);
+ data.edge_flags = get_tface_mesh_marked_edge_info(me, draw_select_edges);
glEnable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
@@ -562,14 +575,6 @@ static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, const bool has_mc
}
}
-static DMDrawOption draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), const bool has_mcol, int UNUSED(matnr))
-{
- if (has_mcol)
- return DM_DRAW_OPTION_NORMAL;
- else
- return DM_DRAW_OPTION_NO_MCOL;
-}
-
static DMDrawOption draw_tface__set_draw(MTFace *tface, const bool UNUSED(has_mcol), int matnr)
{
Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
@@ -668,48 +673,48 @@ static void update_tface_color_layer(DerivedMesh *dm)
}
}
-static DMDrawOption draw_tface_mapped__set_draw(void *userData, int index)
+static DMDrawOption draw_tface_mapped__set_draw(void *userData, int origindex, int UNUSED(mat_nr))
{
Mesh *me = ((drawTFace_userData *)userData)->me;
/* array checked for NULL before calling */
- MPoly *mpoly = &me->mpoly[index];
+ MPoly *mpoly = &me->mpoly[origindex];
- BLI_assert(index >= 0 && index < me->totpoly);
+ BLI_assert(origindex >= 0 && origindex < me->totpoly);
if (mpoly->flag & ME_HIDE) {
return DM_DRAW_OPTION_SKIP;
}
else {
- MTexPoly *tpoly = (me->mtpoly) ? &me->mtpoly[index] : NULL;
+ MTexPoly *tpoly = (me->mtpoly) ? &me->mtpoly[origindex] : NULL;
MTFace mtf = {{{0}}};
int matnr = mpoly->mat_nr;
if (tpoly) {
ME_MTEXFACE_CPY(&mtf, tpoly);
}
-
+
return draw_tface__set_draw(&mtf, (me->mloopcol != NULL), matnr);
}
}
-static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index)
+static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int origindex, int mat_nr)
{
drawEMTFMapped_userData *data = userData;
BMEditMesh *em = data->em;
BMFace *efa;
- if (UNLIKELY(index >= em->bm->totface))
+ if (UNLIKELY(origindex >= em->bm->totface))
return DM_DRAW_OPTION_NORMAL;
- efa = BM_face_at_index(em->bm, index);
+ efa = BM_face_at_index(em->bm, origindex);
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
return DM_DRAW_OPTION_SKIP;
}
else {
MTFace mtf = {{{0}}};
- int matnr = efa->mat_nr;
+ int matnr = (mat_nr != -1) ? mat_nr : efa->mat_nr;
if (data->has_mtface) {
MTexPoly *tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
@@ -929,24 +934,16 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData, uvflag);
}
}
- else {
- if (GPU_buffer_legacy(dm)) {
- if (draw_flags & DRAW_MODIFIERS_PREVIEW)
- dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL, uvflag);
- else
- dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL, uvflag);
- }
- else {
- drawTFace_userData userData;
-
- update_tface_color_layer(dm);
-
- userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
- userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
- userData.me = NULL;
-
- dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag);
- }
+ else {
+ drawTFace_userData userData;
+
+ update_tface_color_layer(dm);
+
+ userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
+ userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
+ userData.me = NULL;
+
+ dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag);
}
/* draw game engine text hack */
@@ -956,8 +953,10 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
draw_textured_end();
/* draw edges and selected faces over textured mesh */
- if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
- draw_mesh_face_select(rv3d, me, dm);
+ if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) {
+ bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0;
+ draw_mesh_face_select(rv3d, me, dm, draw_select_edges);
+ }
/* reset from negative scale correction */
glFrontFace(GL_CCW);
@@ -1153,8 +1152,10 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
glMatrixMode(GL_MODELVIEW);
/* faceselect mode drawing over textured mesh */
- if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
- draw_mesh_face_select(rv3d, ob->data, dm);
+ if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) {
+ bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0;
+ draw_mesh_face_select(rv3d, ob->data, dm, draw_select_edges);
+ }
}
/* Vertex Paint and Weight Paint */
@@ -1189,7 +1190,7 @@ void draw_mesh_paint_weight_faces(DerivedMesh *dm, const bool use_light,
}
dm->drawMappedFaces(dm, (DMSetDrawOptions)facemask_cb, GPU_enable_material, NULL, user_data,
- DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
+ DM_DRAW_USE_COLORS);
if (use_light) {
draw_mesh_paint_light_end();
@@ -1206,12 +1207,11 @@ void draw_mesh_paint_vcolor_faces(DerivedMesh *dm, const bool use_light,
if (me->mloopcol) {
dm->drawMappedFaces(dm, facemask_cb, GPU_enable_material, NULL, user_data,
- DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
+ DM_DRAW_USE_COLORS);
}
else {
glColor3f(1.0f, 1.0f, 1.0f);
- dm->drawMappedFaces(dm, facemask_cb, GPU_enable_material, NULL, user_data,
- DM_DRAW_ALWAYS_SMOOTH);
+ dm->drawMappedFaces(dm, facemask_cb, GPU_enable_material, NULL, user_data, 0);
}
if (use_light) {
@@ -1279,7 +1279,8 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
/* draw face selection on top */
if (draw_flags & DRAW_FACE_SELECT) {
- draw_mesh_face_select(rv3d, me, dm);
+ bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0;
+ draw_mesh_face_select(rv3d, me, dm, draw_select_edges);
}
else if ((use_light == false) || (ob->dtx & OB_DRAWWIRE)) {
const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index db04d3ccd66..61c9891e201 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -732,7 +732,7 @@ void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4])
}
/* circle for object centers, special_color is for library or ob users */
-static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3], int selstate, int special_color)
+static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3], int selstate, bool special_color)
{
const float size = ED_view3d_pixel_size(rv3d, co) * (float)U.obcenter_dia * 0.5f;
float verts[CIRCLE_RESOL][3];
@@ -740,6 +740,8 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3],
/* using gldepthfunc guarantees that it does write z values,
* but not checks for it, so centers remain visible independent order of drawing */
if (v3d->zbuf) glDepthFunc(GL_ALWAYS);
+ /* write to near buffer always */
+ glDepthRange(0.0, 0.0);
glEnable(GL_BLEND);
if (special_color) {
@@ -769,6 +771,7 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, const float co[3],
/* finish up */
glDisableClientState(GL_VERTEX_ARRAY);
+ glDepthRange(0.0, 1.0);
glDisable(GL_BLEND);
if (v3d->zbuf) glDepthFunc(GL_LEQUAL);
@@ -1331,7 +1334,7 @@ static void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base,
/* draw the circle/square representing spotbl */
if (la->type == LA_SPOT) {
- float spotblcirc = fabsf(z) * (1.0f - powf(la->spotblend, 2));
+ float spotblcirc = fabsf(z) * (1.0f - pow2f(la->spotblend));
/* hide line if it is zero size or overlaps with outer border,
* previously it adjusted to always to show it but that seems
* confusing because it doesn't show the actual blend size */
@@ -1948,8 +1951,8 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short s
}
}
- glPointSize(1.0);
bglEnd();
+ glPointSize(1.0);
}
static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int actdef_wcol)
@@ -2153,8 +2156,7 @@ static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data)
invert_m3_m3(data->imat, obmat);
/* transposed inverted matrix */
- copy_m3_m3(data->tmat, data->imat);
- transpose_m3(data->tmat);
+ transpose_m3_m3(data->tmat, data->imat);
}
}
@@ -2497,7 +2499,7 @@ static void draw_dm_edges_weight_interp(BMEditMesh *em, DerivedMesh *dm, const c
data.bm = em->bm;
data.cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
- data.defgroup_tot = BLI_countlist(&ob->defbase);
+ data.defgroup_tot = BLI_listbase_count(&ob->defbase);
data.vgroup_index = ob->actdef - 1;
data.weight_user = weight_user;
UI_GetThemeColor3fv(TH_VERTEX_UNREFERENCED, data.alert_color);
@@ -2953,21 +2955,23 @@ static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d,
if (!sel_only) wireCol[3] = 255;
}
- if (ts->selectmode == SCE_SELECT_FACE) {
- draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act);
- }
- else if ((me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_SELECT_EDGE)) {
+ if ((me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_SELECT_EDGE)) {
if (cageDM->drawMappedEdgesInterp &&
((ts->selectmode & SCE_SELECT_VERTEX) || (me->drawflag & ME_DRAWEIGHT)))
{
- glShadeModel(GL_SMOOTH);
if (draw_dm_edges_weight_check(me, v3d)) {
+ glShadeModel(GL_SMOOTH);
draw_dm_edges_weight_interp(em, cageDM, ts->weightuser);
+ glShadeModel(GL_FLAT);
+ }
+ else if (ts->selectmode == SCE_SELECT_FACE) {
+ draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act);
}
else {
+ glShadeModel(GL_SMOOTH);
draw_dm_edges_sel_interp(em, cageDM, wireCol, selCol);
+ glShadeModel(GL_FLAT);
}
- glShadeModel(GL_FLAT);
}
else {
draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act);
@@ -3375,7 +3379,6 @@ static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index)
efa = BM_face_at_index(em->bm, index);
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- GPU_enable_material(efa->mat_nr + 1, NULL);
return DM_DRAW_OPTION_NORMAL;
}
else {
@@ -3672,6 +3675,12 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
}
}
+static bool object_is_halo(Scene *scene, Object *ob)
+{
+ const Material *ma = give_current_material(ob, 1);
+ return (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene));
+}
+
static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
@@ -3681,8 +3690,6 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
Object *ob = base->object;
#endif
Mesh *me = ob->data;
- Material *ma = give_current_material(ob, 1);
- const bool hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene));
eWireDrawMode draw_wire = OBDRAW_WIRE_OFF;
int /* totvert,*/ totedge, totface;
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
@@ -3718,7 +3725,9 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0)
draw_bounding_volume(ob, ob->boundtype);
}
- else if (hasHaloMat || (totface == 0 && totedge == 0)) {
+ else if ((totface == 0 && totedge == 0) ||
+ ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob)))
+ {
glPointSize(1.5);
dm->drawVerts(dm);
glPointSize(1.0);
@@ -3773,7 +3782,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
glFrontFace(GL_CCW);
if (draw_flags & DRAW_FACE_SELECT)
- draw_mesh_face_select(rv3d, me, dm);
+ draw_mesh_face_select(rv3d, me, dm, false);
}
else {
draw_mesh_textured(scene, v3d, rv3d, ob, dm, draw_flags);
@@ -4328,19 +4337,8 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3
ListBase *lb = NULL;
DispList *dl;
Curve *cu;
- const short render_only = (v3d->flag2 & V3D_RENDER_OVERRIDE);
- const short solid = (dt > OB_WIRE);
-
- if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == false) {
- return false;
- }
-
- if (ob->type == OB_MBALL) {
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
- }
- else {
- glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CCW : GL_CW);
- }
+ const bool render_only = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0;
+ const bool solid = (dt > OB_WIRE);
switch (ob->type) {
case OB_FONT:
@@ -4469,7 +4467,28 @@ static bool drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *ba
ensure_curve_cache(scene, base->object);
#endif
- retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == false) {
+ retval = false;
+ }
+ else {
+ Object *ob = base->object;
+ GLenum mode;
+
+ if (ob->type == OB_MBALL) {
+ mode = (ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW;
+ }
+ else {
+ mode = (ob->transflag & OB_NEG_SCALE) ? GL_CCW : GL_CW;
+ }
+
+ glFrontFace(mode);
+
+ retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
+
+ if (mode != GL_CCW) {
+ glFrontFace(GL_CCW);
+ }
+ }
if (v3d->flag2 & V3D_BACKFACE_CULLING) {
glDisable(GL_CULL_FACE);
@@ -5144,7 +5163,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
cache = psys->pathcache;
for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
path = cache[a];
- if (path->steps > 0) {
+ if (path->segments > 0) {
glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
if (1) { //ob_dt > OB_WIRE) {
@@ -5156,7 +5175,136 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
}
}
- glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
+ glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
+ }
+ }
+
+ if (part->type == PART_HAIR) {
+ if (part->draw & PART_DRAW_GUIDE_HAIRS) {
+ DerivedMesh *hair_dm = psys->hair_out_dm;
+
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
+ if (pa->totkey > 1) {
+ HairKey *hkey = pa->hair;
+
+ glVertexPointer(3, GL_FLOAT, sizeof(HairKey), hkey->world_co);
+
+ // XXX use proper theme color here
+// UI_ThemeColor(TH_NORMAL);
+ glColor3f(0.58f, 0.67f, 1.0f);
+
+ glDrawArrays(GL_LINE_STRIP, 0, pa->totkey);
+ }
+ }
+
+ if (hair_dm) {
+ MVert *mvert = hair_dm->getVertArray(hair_dm);
+ int i;
+
+ glColor3f(0.9f, 0.4f, 0.4f);
+
+ glBegin(GL_LINES);
+ for (a = 0, pa = psys->particles; a < totpart; a++, pa++) {
+ for (i = 1; i < pa->totkey; ++i) {
+ float v1[3], v2[3];
+
+ copy_v3_v3(v1, mvert[pa->hair_index + i - 1].co);
+ copy_v3_v3(v2, mvert[pa->hair_index + i].co);
+
+ mul_m4_v3(ob->obmat, v1);
+ mul_m4_v3(ob->obmat, v2);
+
+ glVertex3fv(v1);
+ glVertex3fv(v2);
+ }
+ }
+ glEnd();
+ }
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_COLOR_MATERIAL);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ if ((dflag & DRAW_CONSTCOLOR) == 0)
+ if (part->draw_col == PART_DRAW_COL_MAT)
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
+
+ if (part->draw & PART_DRAW_HAIR_GRID) {
+ ClothModifierData *clmd = psys->clmd;
+ if (clmd) {
+ float *a = clmd->hair_grid_min;
+ float *b = clmd->hair_grid_max;
+ int *res = clmd->hair_grid_res;
+ int i;
+
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ if (select)
+ UI_ThemeColor(TH_ACTIVE);
+ else
+ UI_ThemeColor(TH_WIRE);
+ glBegin(GL_LINES);
+ glVertex3f(a[0], a[1], a[2]); glVertex3f(b[0], a[1], a[2]);
+ glVertex3f(b[0], a[1], a[2]); glVertex3f(b[0], b[1], a[2]);
+ glVertex3f(b[0], b[1], a[2]); glVertex3f(a[0], b[1], a[2]);
+ glVertex3f(a[0], b[1], a[2]); glVertex3f(a[0], a[1], a[2]);
+
+ glVertex3f(a[0], a[1], b[2]); glVertex3f(b[0], a[1], b[2]);
+ glVertex3f(b[0], a[1], b[2]); glVertex3f(b[0], b[1], b[2]);
+ glVertex3f(b[0], b[1], b[2]); glVertex3f(a[0], b[1], b[2]);
+ glVertex3f(a[0], b[1], b[2]); glVertex3f(a[0], a[1], b[2]);
+
+ glVertex3f(a[0], a[1], a[2]); glVertex3f(a[0], a[1], b[2]);
+ glVertex3f(b[0], a[1], a[2]); glVertex3f(b[0], a[1], b[2]);
+ glVertex3f(a[0], b[1], a[2]); glVertex3f(a[0], b[1], b[2]);
+ glVertex3f(b[0], b[1], a[2]); glVertex3f(b[0], b[1], b[2]);
+ glEnd();
+
+ if (select)
+ UI_ThemeColorShadeAlpha(TH_ACTIVE, 0, -100);
+ else
+ UI_ThemeColorShadeAlpha(TH_WIRE, 0, -100);
+ glEnable(GL_BLEND);
+ glBegin(GL_LINES);
+ for (i = 1; i < res[0]-1; ++i) {
+ float f = interpf(b[0], a[0], (float)i / (float)(res[0]-1));
+ glVertex3f(f, a[1], a[2]); glVertex3f(f, b[1], a[2]);
+ glVertex3f(f, b[1], a[2]); glVertex3f(f, b[1], b[2]);
+ glVertex3f(f, b[1], b[2]); glVertex3f(f, a[1], b[2]);
+ glVertex3f(f, a[1], b[2]); glVertex3f(f, a[1], a[2]);
+ }
+ for (i = 1; i < res[1]-1; ++i) {
+ float f = interpf(b[1], a[1], (float)i / (float)(res[1]-1));
+ glVertex3f(a[0], f, a[2]); glVertex3f(b[0], f, a[2]);
+ glVertex3f(b[0], f, a[2]); glVertex3f(b[0], f, b[2]);
+ glVertex3f(b[0], f, b[2]); glVertex3f(a[0], f, b[2]);
+ glVertex3f(a[0], f, b[2]); glVertex3f(a[0], f, a[2]);
+ }
+ for (i = 1; i < res[2]-1; ++i) {
+ float f = interpf(b[2], a[2], (float)i / (float)(res[2]-1));
+ glVertex3f(a[0], a[1], f); glVertex3f(b[0], a[1], f);
+ glVertex3f(b[0], a[1], f); glVertex3f(b[0], b[1], f);
+ glVertex3f(b[0], b[1], f); glVertex3f(a[0], b[1], f);
+ glVertex3f(a[0], b[1], f); glVertex3f(a[0], a[1], f);
+ }
+ glEnd();
+ glDisable(GL_BLEND);
+
+ glEnable(GL_LIGHTING);
+ glEnable(GL_COLOR_MATERIAL);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ if ((dflag & DRAW_CONSTCOLOR) == 0)
+ if (part->draw_col == PART_DRAW_COL_MAT)
+ glEnableClientState(GL_COLOR_ARRAY);
+ }
}
}
@@ -5175,7 +5323,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
}
}
- glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
+ glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
}
@@ -5327,7 +5475,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
PTCacheEditKey *key;
ParticleEditSettings *pset = PE_settings(scene);
int i, k, totpoint = edit->totpoint, timed = pset->flag & PE_FADE_TIME ? pset->fade_frames : 0;
- int steps = 1;
+ int totkeys = 1;
float sel_col[3];
float nosel_col[3];
float *pathcol = NULL, *pcol;
@@ -5346,10 +5494,10 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
UI_GetThemeColor3fv(TH_VERTEX, nosel_col);
/* draw paths */
- steps = (*edit->pathcache)->steps + 1;
+ totkeys = (*edit->pathcache)->segments + 1;
glEnable(GL_BLEND);
- pathcol = MEM_callocN(steps * 4 * sizeof(float), "particle path color data");
+ pathcol = MEM_callocN(totkeys * 4 * sizeof(float), "particle path color data");
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
@@ -5369,7 +5517,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co);
if (point->flag & PEP_HIDE) {
- for (k = 0, pcol = pathcol; k < steps; k++, pcol += 4) {
+ for (k = 0, pcol = pathcol; k < totkeys; k++, pcol += 4) {
copy_v3_v3(pcol, path->col);
pcol[3] = 0.25f;
}
@@ -5377,7 +5525,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
glColorPointer(4, GL_FLOAT, 4 * sizeof(float), pathcol);
}
else if (timed) {
- for (k = 0, pcol = pathcol, pkey = path; k < steps; k++, pkey++, pcol += 4) {
+ for (k = 0, pcol = pathcol, pkey = path; k < totkeys; k++, pkey++, pcol += 4) {
copy_v3_v3(pcol, pkey->col);
pcol[3] = 1.0f - fabsf((float)(CFRA) -pkey->time) / (float)pset->fade_frames;
}
@@ -5387,7 +5535,7 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
else
glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
- glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
+ glDrawArrays(GL_LINE_STRIP, 0, path->segments + 1);
}
if (pathcol) { MEM_freeN(pathcol); pathcol = pcol = NULL; }
@@ -6859,15 +7007,18 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
glDepthMask(0);
if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
- DerivedMesh *dm = ob->derivedFinal;
+ DerivedMesh *dm;
bool has_faces = false;
- if (dm)
- DM_update_materials(dm, ob);
#ifdef SEQUENCER_DAG_WORKAROUND
ensure_curve_cache(scene, ob);
#endif
+ dm = ob->derivedFinal;
+ if (dm) {
+ DM_update_materials(dm, ob);
+ }
+
if (dm) {
has_faces = dm->getNumTessFaces(dm) > 0;
}
@@ -7257,7 +7408,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
if (ob->type == OB_MESH) {
if (dt < OB_SOLID) {
- zbufoff = 1;
+ zbufoff = true;
dt = OB_SOLID;
}
@@ -7679,10 +7830,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if ((dt <= OB_SOLID) && !render_override) {
if (((ob->gameflag & OB_DYNAMIC) &&
- !ELEM(ob->collision_boundtype, OB_BOUND_TRIANGLE_MESH, OB_BOUND_CONVEX_HULL)) ||
+ ((ob->gameflag & OB_BOUNDS) == 0)) ||
((ob->gameflag & OB_BOUNDS) &&
- (ob->boundtype == OB_BOUND_SPHERE)))
+ (ob->collision_boundtype == OB_BOUND_SPHERE)))
{
float imat[4][4], vec[3] = {0.0f, 0.0f, 0.0f};
@@ -7723,7 +7874,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
if (render_override) {
/* don't draw */
}
- else if ((scene->basact) == base)
+ else if (is_obact)
do_draw_center = ACTIVE;
else if (base->flag & SELECT)
do_draw_center = SELECT;
@@ -7975,7 +8126,7 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
cpack(0);
if (use_faceselect) {
- dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, GPU_enable_material, NULL, em->bm, 0);
+ dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, NULL, NULL, em->bm, 0);
if (check_ob_drawface_dot(scene, v3d, ob->dt)) {
glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
@@ -7987,7 +8138,7 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
}
else {
- dm->drawMappedFaces(dm, bbs_mesh_mask__setSolidDrawOptions, GPU_enable_material, NULL, em->bm, 0);
+ dm->drawMappedFaces(dm, bbs_mesh_mask__setSolidDrawOptions, NULL, NULL, em->bm, 0);
}
}
@@ -8048,9 +8199,9 @@ static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
DM_update_materials(dm, ob);
if ((me->editflag & ME_EDIT_PAINT_FACE_SEL))
- dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, GPU_enable_material, NULL, me, 0);
+ dm->drawMappedFaces(dm, bbs_mesh_solid_hide__setDrawOpts, NULL, NULL, me, 0);
else
- dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, GPU_enable_material, NULL, me, 0);
+ dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, NULL, NULL, me, 0);
dm->release(dm);
}
diff --git a/source/blender/editors/space_view3d/drawsimdebug.c b/source/blender/editors/space_view3d/drawsimdebug.c
new file mode 100644
index 00000000000..6113bfd4143
--- /dev/null
+++ b/source/blender/editors/space_view3d/drawsimdebug.c
@@ -0,0 +1,173 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/drawsimdebug.c
+ * \ingroup spview3d
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+
+#include "BKE_effect.h"
+#include "BKE_global.h"
+#include "BKE_modifier.h"
+
+#include "view3d_intern.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "UI_resources.h"
+
+static void draw_sim_debug_elements(SimDebugData *debug_data, float imat[4][4])
+{
+ GHashIterator iter;
+
+ /**** dots ****/
+
+ glPointSize(3.0f);
+ glBegin(GL_POINTS);
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ if (elem->type != SIM_DEBUG_ELEM_DOT)
+ continue;
+
+ glColor3f(elem->color[0], elem->color[1], elem->color[2]);
+ glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ }
+ glEnd();
+ glPointSize(1.0f);
+
+ /**** circles ****/
+
+ {
+ float circle[16][2] = {
+ {0.000000, 1.000000}, {0.382683, 0.923880}, {0.707107, 0.707107}, {0.923880, 0.382683},
+ {1.000000, -0.000000}, {0.923880, -0.382683}, {0.707107, -0.707107}, {0.382683, -0.923880},
+ {-0.000000, -1.000000}, {-0.382683, -0.923880}, {-0.707107, -0.707107}, {-0.923879, -0.382684},
+ {-1.000000, 0.000000}, {-0.923879, 0.382684}, {-0.707107, 0.707107}, {-0.382683, 0.923880} };
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ float radius = elem->v2[0];
+ float co[3];
+ int i;
+
+ if (elem->type != SIM_DEBUG_ELEM_CIRCLE)
+ continue;
+
+ glColor3f(elem->color[0], elem->color[1], elem->color[2]);
+ glBegin(GL_LINE_LOOP);
+ for (i = 0; i < 16; ++i) {
+ co[0] = radius * circle[i][0];
+ co[1] = radius * circle[i][1];
+ co[2] = 0.0f;
+ mul_mat3_m4_v3(imat, co);
+ add_v3_v3(co, elem->v1);
+
+ glVertex3f(co[0], co[1], co[2]);
+ }
+ glEnd();
+ }
+ }
+
+ /**** lines ****/
+
+ glBegin(GL_LINES);
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ if (elem->type != SIM_DEBUG_ELEM_LINE)
+ continue;
+
+ glColor3f(elem->color[0], elem->color[1], elem->color[2]);
+ glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ glVertex3f(elem->v2[0], elem->v2[1], elem->v2[2]);
+ }
+ glEnd();
+
+ /**** vectors ****/
+
+ glPointSize(2.0f);
+ glBegin(GL_POINTS);
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ if (elem->type != SIM_DEBUG_ELEM_VECTOR)
+ continue;
+
+ glColor3f(elem->color[0], elem->color[1], elem->color[2]);
+ glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ }
+ glEnd();
+ glPointSize(1.0f);
+
+ glBegin(GL_LINES);
+ for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
+ float t[3];
+ if (elem->type != SIM_DEBUG_ELEM_VECTOR)
+ continue;
+
+ glColor3f(elem->color[0], elem->color[1], elem->color[2]);
+ glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
+ add_v3_v3v3(t, elem->v1, elem->v2);
+ glVertex3f(t[0], t[1], t[2]);
+ }
+ glEnd();
+}
+
+void draw_sim_debug_data(Scene *UNUSED(scene), View3D *UNUSED(v3d), ARegion *ar)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ /*Object *ob = base->object;*/
+ float imat[4][4];
+
+ if (!_sim_debug_data)
+ return;
+
+ invert_m4_m4(imat, rv3d->viewmatob);
+
+// glDepthMask(GL_FALSE);
+// glEnable(GL_BLEND);
+
+ glPushMatrix();
+
+ glLoadMatrixf(rv3d->viewmat);
+ draw_sim_debug_elements(_sim_debug_data, imat);
+
+ glPopMatrix();
+
+// glDepthMask(GL_TRUE);
+// glDisable(GL_BLEND);
+}
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index 59798f97d93..a220e1e39b0 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -27,8 +27,6 @@
* \ingroup spview3d
*/
-
-
#include <string.h>
#include <math.h>
@@ -38,7 +36,6 @@
#include "DNA_screen_types.h"
#include "DNA_smoke_types.h"
#include "DNA_view3d_types.h"
-#include "DNA_property_types.h"
#include "BLI_utildefines.h"
#include "BLI_math.h"
@@ -53,8 +50,6 @@
#include "ED_mesh.h"
-#include "BLF_api.h"
-
#include "view3d_intern.h" // own include
struct GPUTexture;
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index b3accb431ee..35fb2bce115 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -56,6 +56,7 @@
#include "GPU_extensions.h"
#include "GPU_material.h"
+#include "GPU_compositing.h"
#include "BIF_gl.h"
@@ -414,10 +415,15 @@ static void view3d_free(SpaceLink *sl)
/* matcap material, its preview rect gets freed via icons */
if (vd->defmaterial) {
if (vd->defmaterial->gpumaterial.first)
- GPU_material_free(vd->defmaterial);
+ GPU_material_free(&vd->defmaterial->gpumaterial);
BKE_previewimg_free(&vd->defmaterial->preview);
MEM_freeN(vd->defmaterial);
}
+
+ if (vd->fx_settings.ssao)
+ MEM_freeN(vd->fx_settings.ssao);
+ if (vd->fx_settings.dof)
+ MEM_freeN(vd->fx_settings.dof);
}
@@ -459,7 +465,11 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
}
v3dn->properties_storage = NULL;
-
+ if (v3dn->fx_settings.dof)
+ v3dn->fx_settings.dof = MEM_dupallocN(v3do->fx_settings.dof);
+ if (v3dn->fx_settings.ssao)
+ v3dn->fx_settings.ssao = MEM_dupallocN(v3do->fx_settings.ssao);
+
return (SpaceLink *)v3dn;
}
@@ -559,12 +569,17 @@ static void view3d_main_area_exit(wmWindowManager *wm, ARegion *ar)
GPU_offscreen_free(rv3d->gpuoffscreen);
rv3d->gpuoffscreen = NULL;
}
+
+ if (rv3d->compositor) {
+ GPU_fx_compositor_destroy(rv3d->compositor);
+ rv3d->compositor = NULL;
+ }
}
static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (GS(id->name) == ID_OB)
return 1;
}
@@ -574,7 +589,7 @@ static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent
static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (GS(id->name) == ID_GR)
return 1;
}
@@ -584,7 +599,7 @@ static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEve
static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (GS(id->name) == ID_MA)
return 1;
}
@@ -594,12 +609,12 @@ static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent
static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
if (GS(id->name) == ID_IM)
return 1;
}
else if (drag->type == WM_DRAG_PATH) {
- if (ELEM(drag->icon, 0, ICON_FILE_IMAGE)) /* rule might not work? */
+ if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE)) /* rule might not work? */
return 1;
}
return 0;
@@ -641,14 +656,14 @@ static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *e
static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_group_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
drop->opcontext = WM_OP_EXEC_DEFAULT;
RNA_string_set(drop->ptr, "name", id->name + 2);
@@ -656,19 +671,23 @@ static void view3d_group_drop_copy(wmDrag *drag, wmDropBox *drop)
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
RNA_string_set(drop->ptr, "name", id->name + 2);
}
static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
- if (id)
+ if (id) {
RNA_string_set(drop->ptr, "name", id->name + 2);
- if (drag->path[0])
+ RNA_struct_property_unset(drop->ptr, "filepath");
+ }
+ else if (drag->path[0]) {
RNA_string_set(drop->ptr, "filepath", drag->path);
+ RNA_struct_property_unset(drop->ptr, "image");
+ }
}
@@ -709,6 +728,9 @@ static void view3d_main_area_free(ARegion *ar)
if (rv3d->gpuoffscreen) {
GPU_offscreen_free(rv3d->gpuoffscreen);
}
+ if (rv3d->compositor) {
+ GPU_fx_compositor_destroy(rv3d->compositor);
+ }
MEM_freeN(rv3d);
ar->regiondata = NULL;
@@ -732,6 +754,7 @@ static void *view3d_main_area_duplicate(void *poin)
new->render_engine = NULL;
new->sms = NULL;
new->smooth_timer = NULL;
+ new->compositor = NULL;
return new;
}
@@ -813,6 +836,16 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
case ND_WORLD:
/* handled by space_view3d_listener() for v3d access */
break;
+ case ND_DRAW_RENDER_VIEWPORT:
+ {
+ if (v3d->camera && (scene == wmn->reference)) {
+ RegionView3D *rv3d = ar->regiondata;
+ if (rv3d->persp == RV3D_CAMOB) {
+ ED_region_tag_redraw(ar);
+ }
+ }
+ break;
+ }
}
if (wmn->action == NA_EDITED)
ED_region_tag_redraw(ar);
@@ -852,13 +885,35 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
break;
}
break;
+ case NC_CAMERA:
+ switch (wmn->data) {
+ case ND_DRAW_RENDER_VIEWPORT:
+ {
+ if (v3d->camera && (v3d->camera->data == wmn->reference)) {
+ RegionView3D *rv3d = ar->regiondata;
+ if (rv3d->persp == RV3D_CAMOB) {
+ ED_region_tag_redraw(ar);
+ }
+ }
+ break;
+ }
+ }
+ break;
case NC_GROUP:
/* all group ops for now */
ED_region_tag_redraw(ar);
break;
case NC_BRUSH:
- if (wmn->action == NA_EDITED)
- ED_region_tag_redraw_overlay(ar);
+ switch (wmn->action) {
+ case NA_EDITED:
+ ED_region_tag_redraw_overlay(ar);
+ break;
+ case NA_SELECTED:
+ /* used on brush changes - needed because 3d cursor
+ * has to be drawn if clone brush is selected */
+ ED_region_tag_redraw(ar);
+ break;
+ }
break;
case NC_MATERIAL:
switch (wmn->data) {
@@ -950,8 +1005,9 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
break;
case NC_GPENCIL:
- if (wmn->action == NA_EDITED)
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED)) {
ED_region_tag_redraw(ar);
+ }
break;
}
}
@@ -1007,6 +1063,10 @@ static void view3d_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa)
if (wmn->data == ND_SPACE_VIEW3D)
ED_region_tag_redraw(ar);
break;
+ case NC_GPENCIL:
+ if (wmn->data & ND_GPENCIL_EDITMODE)
+ ED_region_tag_redraw(ar);
+ break;
}
}
@@ -1092,7 +1152,8 @@ static void view3d_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa
ED_region_tag_redraw(ar);
break;
case NC_BRUSH:
- if (wmn->action == NA_EDITED)
+ /* NA_SELECTED is used on brush changes */
+ if (ELEM(wmn->action, NA_EDITED, NA_SELECTED))
ED_region_tag_redraw(ar);
break;
case NC_SPACE:
@@ -1104,7 +1165,7 @@ static void view3d_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa
ED_region_tag_redraw(ar);
break;
case NC_GPENCIL:
- if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
+ if ((wmn->data & (ND_DATA | ND_GPENCIL_EDITMODE)) || (wmn->action == NA_EDITED))
ED_region_tag_redraw(ar);
break;
case NC_IMAGE:
@@ -1168,7 +1229,8 @@ static void space_view3d_listener(bScreen *UNUSED(sc), ScrArea *sa, struct wmNot
case NC_WORLD:
switch (wmn->data) {
case ND_WORLD_DRAW:
- if (v3d->flag2 & V3D_RENDER_OVERRIDE)
+ case ND_WORLD:
+ if (v3d->flag3 & V3D_SHOW_WORLD)
ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
break;
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 6a43357179e..88f43ab340f 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -60,6 +60,7 @@
#include "BKE_editmesh.h"
#include "BKE_deform.h"
#include "BKE_object.h"
+#include "BKE_object_deform.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -68,7 +69,6 @@
#include "ED_armature.h"
#include "ED_gpencil.h"
-#include "ED_object.h"
#include "ED_mesh.h"
#include "ED_screen.h"
@@ -360,7 +360,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
if (tot == 0) {
- uiDefBut(block, LABEL, 0, IFACE_("Nothing selected"), 0, 130, 200, 20, NULL, 0, 0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("Nothing selected"), 0, 130, 200, 20, NULL, 0, 0, 0, 0, "");
return;
}
@@ -404,7 +404,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
if (tot == 1) {
if (totcurvedata) /* Curve */
c = IFACE_("Control Point:");
@@ -413,68 +413,68 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
else
c = IFACE_("Median:");
- uiDefBut(block, LABEL, 0, c, 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, c, 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, "");
- uiBlockBeginAlign(block);
+ UI_block_align_begin(block);
/* Should be no need to translate these. */
- but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("X:"), 0, yi -= buth, 200, buth,
+ but = uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("X:"), 0, yi -= buth, 200, buth,
&(tfp->ve_median[LOC_X]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
- uiButSetUnitType(but, PROP_UNIT_LENGTH);
- but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Y:"), 0, yi -= buth, 200, buth,
+ UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
+ but = uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Y:"), 0, yi -= buth, 200, buth,
&(tfp->ve_median[LOC_Y]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
- uiButSetUnitType(but, PROP_UNIT_LENGTH);
- but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Z:"), 0, yi -= buth, 200, buth,
+ UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
+ but = uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Z:"), 0, yi -= buth, 200, buth,
&(tfp->ve_median[LOC_Z]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
- uiButSetUnitType(but, PROP_UNIT_LENGTH);
+ UI_but_unit_type_set(but, PROP_UNIT_LENGTH);
if (totcurvebweight == tot) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("W:"), 0, yi -= buth, 200, buth,
+ uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("W:"), 0, yi -= buth, 200, buth,
&(tfp->ve_median[C_BWEIGHT]), 0.01, 100.0, 1, 3, "");
}
- uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, IFACE_("Global"),
+ UI_block_align_begin(block);
+ uiDefButBitS(block, UI_BTYPE_TOGGLE, V3D_GLOBAL_STATS, B_REDR, IFACE_("Global"),
0, yi -= buth + but_margin, 100, buth,
&v3d->flag, 0, 0, 0, 0, TIP_("Displays global values"));
- uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, IFACE_("Local"),
+ uiDefButBitS(block, UI_BTYPE_TOGGLE_N, V3D_GLOBAL_STATS, B_REDR, IFACE_("Local"),
100, yi, 100, buth,
&v3d->flag, 0, 0, 0, 0, TIP_("Displays local values"));
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
/* Meshes... */
if (has_meshdata) {
if (tot) {
- uiDefBut(block, LABEL, 0, tot == 1 ? IFACE_("Vertex Data:") : IFACE_("Vertices Data:"),
+ uiDefBut(block, UI_BTYPE_LABEL, 0, tot == 1 ? IFACE_("Vertex Data:") : IFACE_("Vertices Data:"),
0, yi -= buth + but_margin, 200, buth, NULL, 0.0, 0.0, 0, 0, "");
/* customdata layer added on demand */
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN,
tot == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
0, yi -= buth + but_margin, 200, buth,
&(tfp->ve_median[M_BV_WEIGHT]), 0.0, 1.0, 1, 2, TIP_("Vertex weight used by Bevel modifier"));
}
if (has_skinradius) {
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ UI_block_align_begin(block);
+ uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN,
tot == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"),
0, yi -= buth + but_margin, 200, buth,
&(tfp->ve_median[M_SKIN_X]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier"));
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN,
tot == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"),
0, yi -= buth + but_margin, 200, buth,
&(tfp->ve_median[M_SKIN_Y]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier"));
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
}
if (totedgedata) {
- uiDefBut(block, LABEL, 0, totedgedata == 1 ? IFACE_("Edge Data:") : IFACE_("Edges Data:"),
+ uiDefBut(block, UI_BTYPE_LABEL, 0, totedgedata == 1 ? IFACE_("Edge Data:") : IFACE_("Edges Data:"),
0, yi -= buth + but_margin, 200, buth, NULL, 0.0, 0.0, 0, 0, "");
/* customdata layer added on demand */
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN,
totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
0, yi -= buth + but_margin, 200, buth,
&(tfp->ve_median[M_BE_WEIGHT]), 0.0, 1.0, 1, 2, TIP_("Edge weight used by Bevel modifier"));
/* customdata layer added on demand */
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN,
totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
0, yi -= buth + but_margin, 200, buth,
&(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 2, TIP_("Weight used by SubSurf modifier"));
@@ -482,38 +482,38 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
/* Curve... */
else if (totcurvedata == 1) {
- uiDefButR(block, NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, 200, buth,
+ uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, 200, buth,
&data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL);
- uiDefButR(block, NUM, 0, IFACE_("Radius:"), 0, yi -= buth + but_margin, 200, buth,
+ uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Radius:"), 0, yi -= buth + but_margin, 200, buth,
&data_ptr, "radius", 0, 0.0, 100.0, 1, 3, NULL);
- uiDefButR(block, NUM, 0, IFACE_("Tilt:"), 0, yi -= buth + but_margin, 200, buth,
+ uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Tilt:"), 0, yi -= buth + but_margin, 200, buth,
&data_ptr, "tilt", 0, -tilt_limit, tilt_limit, 1, 3, NULL);
}
else if (totcurvedata > 1) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"),
+ uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"),
0, yi -= buth + but_margin, 200, buth,
&(tfp->ve_median[C_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal"));
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius:"),
+ uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius:"),
0, yi -= buth + but_margin, 200, buth,
&(tfp->ve_median[C_RADIUS]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points"));
- but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Tilt:"),
+ but = uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Tilt:"),
0, yi -= buth + but_margin, 200, buth,
&(tfp->ve_median[C_TILT]), -tilt_limit, tilt_limit, 1, 3,
TIP_("Tilt of curve control points"));
- uiButSetUnitType(but, PROP_UNIT_ROTATION);
+ UI_but_unit_type_set(but, PROP_UNIT_ROTATION);
}
/* Lattice... */
else if (totlattdata == 1) {
- uiDefButR(block, NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, 200, buth,
+ uiDefButR(block, UI_BTYPE_NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, 200, buth,
&data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL);
}
else if (totlattdata > 1) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"),
+ uiDefButF(block, UI_BTYPE_NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"),
0, yi -= buth + but_margin, 200, buth,
&(tfp->ve_median[L_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal"));
}
- uiBlockEndAlign(block);
+ UI_block_align_end(block);
}
else { /* apply */
int i;
@@ -834,7 +834,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
int yco = 0;
int lock_count = 0;
- uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL);
+ UI_block_func_handle_set(block, do_view3d_vgroup_buttons, NULL);
bcol = uiLayoutColumn(pa->layout, true);
row = uiLayoutRow(bcol, true); /* The filter button row */
@@ -844,9 +844,9 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
col = uiLayoutColumn(bcol, true);
- vgroup_validmap = ED_vgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
+ vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) {
- bool locked = dg->flag & DG_LOCK_WEIGHT;
+ bool locked = (dg->flag & DG_LOCK_WEIGHT) != 0;
if (vgroup_validmap[i]) {
MDeformWeight *dw = defvert_find_index(dv, i);
if (dw) {
@@ -858,13 +858,13 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
/* The Weight Group Name */
ot = ot_weight_set_active;
- but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, dg->name,
+ but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, WM_OP_EXEC_DEFAULT, dg->name,
xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y, "");
- but_ptr = uiButGetOperatorPtrRNA(but);
+ but_ptr = UI_but_operator_ptr_get(but);
RNA_int_set(but_ptr, "weight_group", i);
- uiButSetDrawFlag(but, UI_BUT_TEXT_RIGHT);
+ UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT);
if (ob->actdef != i + 1) {
- uiButSetFlag(but, UI_BUT_INACTIVE);
+ UI_but_flag_enable(but, UI_BUT_INACTIVE);
}
xco += x;
@@ -873,10 +873,10 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
/* The weight group value */
/* To be reworked still */
- but = uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, "",
+ but = uiDefButF(block, UI_BTYPE_NUM, B_VGRP_PNL_EDIT_SINGLE + i, "",
xco, yco, (x = UI_UNIT_X * 4), UI_UNIT_Y,
&dw->weight, 0.0, 1.0, 1, 3, "");
- uiButSetDrawFlag(but, UI_BUT_TEXT_LEFT);
+ UI_but_drawflag_enable(but, UI_BUT_TEXT_LEFT);
if (locked) {
lock_count++;
}
@@ -911,19 +911,19 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
row = uiLayoutRow(col, true);
ot = WM_operatortype_find("OBJECT_OT_vertex_weight_normalize_active_vertex", 1);
- but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Normalize",
+ but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, WM_OP_EXEC_DEFAULT, "Normalize",
0, yco, UI_UNIT_X * 5, UI_UNIT_Y,
TIP_("Normalize weights of active vertex (if affected groups are unlocked)"));
if (lock_count) {
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
ot = WM_operatortype_find("OBJECT_OT_vertex_weight_copy", 1);
- but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Copy",
+ but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, WM_OP_EXEC_DEFAULT, "Copy",
UI_UNIT_X * 5, yco, UI_UNIT_X * 5, UI_UNIT_Y,
TIP_("Copy active vertex to other selected vertices (if affected groups are unlocked)"));
if (lock_count) {
- uiButSetFlag(but, UI_BUT_DISABLED);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
}
}
@@ -1145,7 +1145,7 @@ static void view3d_panel_transform(const bContext *C, Panel *pa)
uiLayout *col;
block = uiLayoutGetBlock(pa->layout);
- uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
+ UI_block_func_handle_set(block, do_view3d_region_buttons, NULL);
col = uiLayoutColumn(pa->layout, false);
@@ -1185,14 +1185,6 @@ void view3d_buttons_register(ARegionType *art)
pt->poll = view3d_panel_transform_poll;
BLI_addtail(&art->paneltypes, pt);
- pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
- strcpy(pt->idname, "VIEW3D_PT_gpencil");
- strcpy(pt->label, N_("Grease Pencil")); /* XXX C panels are not available through RNA (bpy.types)! */
- strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw_header = ED_gpencil_panel_standard_header;
- pt->draw = ED_gpencil_panel_standard;
- BLI_addtail(&art->paneltypes, pt);
-
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup");
strcpy(pt->idname, "VIEW3D_PT_vgroup");
strcpy(pt->label, N_("Vertex Weights")); /* XXX C panels are not available through RNA (bpy.types)! */
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index ee0f3da18b4..95e918abdcf 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -51,14 +51,12 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BKE_object.h"
#include "BKE_depsgraph.h" /* for object updating */
-#include "ED_keyframing.h"
#include "ED_screen.h"
#include "view3d_intern.h" /* own include */
@@ -266,6 +264,8 @@ void ED_view3d_cameracontrol_update(
BKE_object_apply_mat4(v3d->camera, view_mat, true, true);
+ DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
+
copy_v3_v3(v3d->camera->size, size_back);
id_key = &v3d->camera->id;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 61bfb0176ef..58ef9184dd0 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -42,6 +42,7 @@
#include "DNA_lamp_types.h"
#include "DNA_scene_types.h"
#include "DNA_world_types.h"
+#include "DNA_brush_types.h"
#include "MEM_guardedalloc.h"
@@ -94,6 +95,7 @@
#include "GPU_draw.h"
#include "GPU_material.h"
#include "GPU_extensions.h"
+#include "GPU_compositing.h"
#include "view3d_intern.h" /* own include */
@@ -162,15 +164,15 @@ static void view3d_draw_clipping(RegionView3D *rv3d)
/* fill in zero alpha for rendering & re-projection [#31530] */
unsigned char col[4];
- UI_GetThemeColorShade3ubv(TH_BACK, -8, col);
- col[3] = 0;
+ UI_GetThemeColor4ubv(TH_V3D_CLIPPING_BORDER, col);
glColor4ubv(col);
+ glEnable(GL_BLEND);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, bb->vec);
glDrawElements(GL_QUADS, sizeof(clipping_index) / sizeof(unsigned int), GL_UNSIGNED_INT, clipping_index);
glDisableClientState(GL_VERTEX_ARRAY);
-
+ glDisable(GL_BLEND);
}
}
@@ -294,7 +296,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
dx = fabs(x - (wx) * fx / fw);
if (dx == 0) dx = fabs(y - (wy) * fy / fw);
- glDepthMask(0); /* disable write in zbuffer */
+ glDepthMask(GL_FALSE); /* disable write in zbuffer */
/* check zoom out */
UI_ThemeColor(TH_GRID);
@@ -433,7 +435,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
fdrawline(x, 0.0, x, (float)ar->winy);
- glDepthMask(1); /* enable write in zbuffer */
+ glDepthMask(GL_TRUE); /* enable write in zbuffer */
}
#undef GRID_MIN_PX
@@ -475,8 +477,7 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit)
grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
grid = gridlines * grid_scale;
- if (v3d->zbuf && scene->obedit)
- glDepthMask(0); /* for zbuffer-select */
+ glDepthMask(GL_FALSE);
UI_GetThemeColor3ubv(TH_GRID, col_grid);
@@ -545,7 +546,7 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit)
}
}
- if (v3d->zbuf && scene->obedit) glDepthMask(1);
+ glDepthMask(GL_TRUE);
}
@@ -586,20 +587,26 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
float ydisp = 0.0; /* vertical displacement to allow obj info text */
int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */
float vec[3];
- char axis_text[2] = "x";
float dx, dy;
- int i;
-
+
+ int axis_order[3] = {0, 1, 2};
+ int axis_i;
+
startx += rect->xmin;
starty += rect->ymin;
-
+
+ axis_sort_v3(rv3d->viewinv[2], axis_order);
+
/* thickness of lines is proportional to k */
glLineWidth(2);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- for (i = 0; i < 3; i++) {
+ for (axis_i = 0; axis_i < 3; axis_i++) {
+ int i = axis_order[axis_i];
+ const char axis_text[2] = {'x' + i, '\0'};
+
zero_v3(vec);
vec[i] = 1.0f;
mul_qt_v3(rv3d->viewquat, vec);
@@ -616,8 +623,6 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, axis_text, 1);
}
- axis_text[0]++;
-
/* BLF_draw_default disables blending */
glEnable(GL_BLEND);
}
@@ -787,7 +792,16 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d)
if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) {
Camera *cam;
cam = v3d->camera->data;
- name = (cam->type != CAM_ORTHO) ? IFACE_("Camera Persp") : IFACE_("Camera Ortho");
+ if (cam->type == CAM_PERSP) {
+ name = IFACE_("Camera Persp");
+ }
+ else if (cam->type == CAM_ORTHO) {
+ name = IFACE_("Camera Ortho");
+ }
+ else {
+ BLI_assert(cam->type == CAM_PANO);
+ name = IFACE_("Camera Pano");
+ }
}
else {
name = IFACE_("Object as Camera");
@@ -1057,14 +1071,13 @@ static void drawviewborder_triangle(float x1, float x2, float y1, float y2, cons
static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
{
- float hmargin, vmargin;
float x1, x2, y1, y2;
float x1i, x2i, y1i, y2i;
rctf viewborder;
Camera *ca = NULL;
RegionView3D *rv3d = ar->regiondata;
-
+
if (v3d->camera == NULL)
return;
if (v3d->camera->type == OB_CAMERA)
@@ -1146,10 +1159,10 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
if (scene->r.mode & R_BORDER) {
float x3, y3, x4, y4;
- x3 = x1 + scene->r.border.xmin * (x2 - x1);
- y3 = y1 + scene->r.border.ymin * (y2 - y1);
- x4 = x1 + scene->r.border.xmax * (x2 - x1);
- y4 = y1 + scene->r.border.ymax * (y2 - y1);
+ x3 = x1i + 1 + roundf(scene->r.border.xmin * (x2 - x1));
+ y3 = y1i + 1 + roundf(scene->r.border.ymin * (y2 - y1));
+ x4 = x1i + 1 + roundf(scene->r.border.xmax * (x2 - x1));
+ y4 = y1i + 1 + roundf(scene->r.border.ymax * (y2 - y1));
cpack(0x4040FF);
glRecti(x3, y3, x4, y4);
@@ -1216,17 +1229,20 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
drawviewborder_triangle(x1, x2, y1, y2, 1, 'B');
}
- if (ca->flag & CAM_SHOWTITLESAFE) {
- UI_ThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25, 0);
-
- hmargin = 0.1f * (x2 - x1);
- vmargin = 0.05f * (y2 - y1);
- uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f);
+ if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
+ UI_draw_safe_areas(
+ x1, x2, y1, y2,
+ scene->safe_areas.title,
+ scene->safe_areas.action);
- hmargin = 0.035f * (x2 - x1);
- vmargin = 0.035f * (y2 - y1);
- uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1 + vmargin, x2 - hmargin, y2 - vmargin, 2.0f);
+ if (ca->flag & CAM_SHOW_SAFE_CENTER) {
+ UI_draw_safe_areas(
+ x1, x2, y1, y2,
+ scene->safe_areas.title_center,
+ scene->safe_areas.action_center);
+ }
}
+
if (ca->flag & CAM_SHOWSENSOR) {
/* determine sensor fit, and get sensor x/y, for auto fit we
* assume and square sensor and only use sensor_x */
@@ -1260,7 +1276,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
/* draw */
UI_ThemeColorShade(TH_VIEW_OVERLAY, 100);
- uiDrawBox(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f);
+ UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f);
}
}
@@ -1270,8 +1286,9 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
/* camera name - draw in highlighted text color */
if (ca && (ca->flag & CAM_SHOWNAME)) {
UI_ThemeColor(TH_TEXT_HI);
- BLF_draw_default(x1i, y1i - 15, 0.0f, v3d->camera->id.name + 2, sizeof(v3d->camera->id.name) - 2);
- UI_ThemeColor(TH_WIRE);
+ BLF_draw_default(
+ x1i, y1i - (0.7f * U.widget_unit), 0.0f,
+ v3d->camera->id.name + 2, sizeof(v3d->camera->id.name) - 2);
}
}
@@ -1358,11 +1375,11 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
}
if (rv3d->gpuoffscreen)
- GPU_offscreen_bind(rv3d->gpuoffscreen);
+ GPU_offscreen_bind(rv3d->gpuoffscreen, true);
else
glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
- glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClearColor(0.0, 0.0, 0.0, 0.0);
if (v3d->zbuf) {
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -1381,7 +1398,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
draw_object_backbufsel(scene, v3d, rv3d, base->object);
if (rv3d->gpuoffscreen)
- GPU_offscreen_unbind(rv3d->gpuoffscreen);
+ GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
else
ar->swap = 0; /* mark invalid backbuf for wm draw */
@@ -1407,10 +1424,10 @@ void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int form
RegionView3D *rv3d = ar->regiondata;
if (rv3d->gpuoffscreen) {
- GPU_offscreen_bind(rv3d->gpuoffscreen);
+ GPU_offscreen_bind(rv3d->gpuoffscreen, true);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(x, y, w, h, format, type, data);
- GPU_offscreen_unbind(rv3d->gpuoffscreen);
+ GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
}
else {
glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
@@ -1599,7 +1616,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
{
float image_aspect[2];
float fac, asp, zoomx, zoomy;
- float x1, y1, x2, y2;
+ float x1, y1, x2, y2, centx, centy;
ImBuf *ibuf = NULL, *freeibuf, *releaseibuf;
void *lock;
@@ -1705,6 +1722,9 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
y2 += yof_scale;
}
+ centx = (x1 + x2) / 2.0f;
+ centy = (y1 + y2) / 2.0f;
+
/* aspect correction */
if (bgpic->flag & V3D_BGPIC_CAMERA_ASPECT) {
/* apply aspect from clip */
@@ -1722,16 +1742,14 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if ((asp_src > asp_dst) == ((bgpic->flag & V3D_BGPIC_CAMERA_CROP) != 0)) {
/* fit X */
const float div = asp_src / asp_dst;
- const float cent = (x1 + x2) / 2.0f;
- x1 = ((x1 - cent) * div) + cent;
- x2 = ((x2 - cent) * div) + cent;
+ x1 = ((x1 - centx) * div) + centx;
+ x2 = ((x2 - centx) * div) + centx;
}
else {
/* fit Y */
const float div = asp_dst / asp_src;
- const float cent = (y1 + y2) / 2.0f;
- y1 = ((y1 - cent) * div) + cent;
- y2 = ((y2 - cent) * div) + cent;
+ y1 = ((y1 - centy) * div) + centy;
+ y2 = ((y2 - centy) * div) + centy;
}
}
}
@@ -1758,6 +1776,9 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
y1 = sco[1] + asp * fac * (bgpic->yof - bgpic->size);
x2 = sco[0] + fac * (bgpic->xof + bgpic->size);
y2 = sco[1] + asp * fac * (bgpic->yof + bgpic->size);
+
+ centx = (x1 + x2) / 2.0f;
+ centy = (y1 + y2) / 2.0f;
}
/* complete clip? */
@@ -1808,6 +1829,19 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
glPushMatrix();
ED_region_pixelspace(ar);
+ glTranslatef(centx, centy, 0.0);
+ if (rv3d->persp != RV3D_CAMOB) {
+ glRotatef(RAD2DEGF(-bgpic->rotation), 0.0f, 0.0f, 1.0f);
+ }
+
+ if (bgpic->flag & V3D_BGPIC_FLIP_X) {
+ zoomx *= -1.0f;
+ x1 = x2;
+ }
+ if (bgpic->flag & V3D_BGPIC_FLIP_Y) {
+ zoomy *= -1.0f;
+ y1 = y2;
+ }
glPixelZoom(zoomx, zoomy);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f - bgpic->blend);
@@ -1815,7 +1849,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
* glaDrawPixelsSafe in some cases, which will end up in missing
* alpha transparency for the background image (sergey)
*/
- glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
+ glaDrawPixelsTex(x1 - centx, y1 - centy, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
glPixelZoom(1.0, 1.0);
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
@@ -1886,7 +1920,7 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d)
{
View3DAfter *v3da, *next;
- glDepthMask(0);
+ glDepthMask(GL_FALSE);
v3d->transp = true;
for (v3da = v3d->afterdraw_transp.first; v3da; v3da = next) {
@@ -1897,17 +1931,19 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d)
}
v3d->transp = false;
- glDepthMask(1);
+ glDepthMask(GL_TRUE);
}
/* clears zbuffer and draws it over */
-static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, const bool clear)
+static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, bool *clear)
{
View3DAfter *v3da, *next;
- if (clear && v3d->zbuf)
+ if (*clear && v3d->zbuf) {
glClear(GL_DEPTH_BUFFER_BIT);
+ *clear = false;
+ }
v3d->xray = true;
for (v3da = v3d->afterdraw_xray.first; v3da; v3da = next) {
@@ -1931,6 +1967,8 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const
v3d->xray = true;
v3d->transp = true;
+ glDepthMask(GL_FALSE);
+
for (v3da = v3d->afterdraw_xraytransp.first; v3da; v3da = next) {
next = v3da->next;
draw_object(scene, ar, v3d, v3da->base, v3da->dflag);
@@ -1941,6 +1979,7 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const
v3d->transp = false;
v3d->xray = false;
+ glDepthMask(GL_TRUE);
}
/* *********************** */
@@ -2003,7 +2042,7 @@ static void draw_dupli_objects_color(
tbase.flag = OB_FROMDUPLI | base->flag;
lb = object_duplilist(G.main->eval_ctx, scene, base->object);
- // BLI_sortlist(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
+ // BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
apply_data = duplilist_apply(base->object, lb);
@@ -2499,7 +2538,10 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
/* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
- ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, false, false);
+ ED_view3d_draw_offscreen(
+ scene, v3d, &ar, winsize, winsize, viewmat, winmat,
+ false, false, true,
+ NULL, NULL, NULL);
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
v3d->drawtype = drawtype;
@@ -2557,6 +2599,7 @@ CustomDataMask ED_view3d_screen_datamask(bScreen *screen)
void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
+ rctf cameraborder;
/* setup window matrices */
if (winmat)
@@ -2574,7 +2617,23 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
invert_m4_m4(rv3d->persinv, rv3d->persmat);
invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
+
+ /* calculate GLSL view dependent values */
+ /* store window coordinates scaling/offset */
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &cameraborder, false);
+ rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
+ rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
+
+ rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
+ rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
+ }
+ else {
+ rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
+ rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
+ }
+
/* calculate pixelsize factor once, is used for lamps and obcenters */
{
/* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
@@ -2597,8 +2656,6 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
}
}
-
-
/**
* Shared by #ED_view3d_draw_offscreen and #view3d_main_area_draw_objects
*
@@ -2609,11 +2666,17 @@ static void view3d_draw_objects(
const bContext *C,
Scene *scene, View3D *v3d, ARegion *ar,
const char **grid_unit,
- const bool do_bgpic, const bool draw_offscreen)
+ const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
{
RegionView3D *rv3d = ar->regiondata;
Base *base;
const bool do_camera_frame = !draw_offscreen;
+ const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0;
+ const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
+ /* only draw grids after in solid modes, else it hovers over mesh wires */
+ const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE);
+ bool do_composite_xray = false;
+ bool xrayclear = true;
if (!draw_offscreen) {
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
@@ -2644,28 +2707,24 @@ static void view3d_draw_objects(
glEnable(GL_DEPTH_TEST);
}
- if (!draw_offscreen) {
+ /* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override
+ * objects if done last */
+ if (draw_grids) {
/* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */
- rv3d->gridview = v3d->grid;
- if (scene->unit.system) {
- rv3d->gridview /= scene->unit.scale_length;
- }
+ rv3d->gridview = ED_view3d_grid_scale(scene, v3d, grid_unit);
- if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) {
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- drawfloor(scene, v3d, grid_unit);
- }
+ if (!draw_floor) {
+ ED_region_pixelspace(ar);
+ *grid_unit = NULL; /* drawgrid need this to detect/affect smallest valid unit... */
+ drawgrid(&scene->unit, ar, v3d, grid_unit);
+ /* XXX make function? replaces persp(1) */
+ glMatrixMode(GL_PROJECTION);
+ glLoadMatrixf(rv3d->winmat);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(rv3d->viewmat);
}
else {
- if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
- ED_region_pixelspace(ar);
- drawgrid(&scene->unit, ar, v3d, grid_unit);
- /* XXX make function? replaces persp(1) */
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(rv3d->winmat);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(rv3d->viewmat);
- }
+ drawfloor(scene, v3d, grid_unit);
}
}
@@ -2741,6 +2800,11 @@ static void view3d_draw_objects(
}
}
+ /* perspective floor goes last to use scene depth and avoid writing to depth buffer */
+ if (draw_grids_after) {
+ drawfloor(scene, v3d, grid_unit);
+ }
+
/* must be before xray draw which clears the depth buffer */
if (v3d->flag2 & V3D_SHOW_GPENCIL) {
/* must be before xray draw which clears the depth buffer */
@@ -2751,8 +2815,19 @@ static void view3d_draw_objects(
/* transp and X-ray afterdraw stuff */
if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d);
- if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, true);
- if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, true);
+
+ /* always do that here to cleanup depth buffers if none needed */
+ if (fx) {
+ do_composite_xray = v3d->zbuf && (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first);
+ GPU_fx_compositor_setup_XRay_pass(fx, do_composite_xray);
+ }
+
+ if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, &xrayclear);
+ if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, xrayclear);
+
+ if (fx && do_composite_xray) {
+ GPU_fx_compositor_XRay_resolve(fx);
+ }
if (!draw_offscreen) {
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
@@ -2801,15 +2876,216 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d)
gpu_update_lamps_shadows(scene, v3d);
}
+/*
+ * Function to clear the view
+ */
+static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
+{
+ if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) {
+ bool glsl = GPU_glsl_support() && BKE_scene_use_new_shading_nodes(scene) && scene->world->nodetree && scene->world->use_nodes;
+
+ if (glsl) {
+ RegionView3D *rv3d = ar->regiondata;
+ GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
+
+ /* calculate full shader for background */
+ GPU_material_bind(gpumat, 1, 1, 1.0, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+ glShadeModel(GL_SMOOTH);
+ glBegin(GL_QUADS);
+ glVertex3f(-1.0, -1.0, 1.0);
+ glVertex3f(1.0, -1.0, 1.0);
+ glVertex3f(1.0, 1.0, 1.0);
+ glVertex3f(-1.0, 1.0, 1.0);
+ glEnd();
+ glShadeModel(GL_FLAT);
+
+ GPU_material_unbind(gpumat);
+
+ glDepthFunc(GL_LEQUAL);
+ glDisable(GL_DEPTH_TEST);
+ }
+ else if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */
+ int x, y;
+ float col_hor[3];
+ float col_zen[3];
+
+#define VIEWGRAD_RES_X 16
+#define VIEWGRAD_RES_Y 16
+
+ GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4];
+ static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][3];
+ static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4];
+ static bool buf_calculated = false;
+
+ IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
+ &scene->display_settings);
+ IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings,
+ &scene->display_settings);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* calculate buffers the first time only */
+ if (!buf_calculated) {
+ for (x = 0; x < VIEWGRAD_RES_X; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y; y++) {
+ const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1);
+ const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1);
+
+ /* -1..1 range */
+ grid_pos[x][y][0] = (xf - 0.5f) * 2.0f;
+ grid_pos[x][y][1] = (yf - 0.5f) * 2.0f;
+ grid_pos[x][y][2] = 1.0;
+ }
+ }
+
+ for (x = 0; x < VIEWGRAD_RES_X - 1; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y - 1; y++) {
+ indices[x][y][0] = x * VIEWGRAD_RES_X + y;
+ indices[x][y][1] = x * VIEWGRAD_RES_X + y + 1;
+ indices[x][y][2] = (x + 1) * VIEWGRAD_RES_X + y + 1;
+ indices[x][y][3] = (x + 1) * VIEWGRAD_RES_X + y;
+ }
+ }
+
+ buf_calculated = true;
+ }
+
+ for (x = 0; x < VIEWGRAD_RES_X; x++) {
+ for (y = 0; y < VIEWGRAD_RES_Y; y++) {
+ const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1);
+ const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1);
+ const float mval[2] = {xf * (float)ar->winx, yf * ar->winy};
+ const float z_up[3] = {0.0f, 0.0f, 1.0f};
+ float out[3];
+ GLubyte *col_ub = grid_col[x][y];
+
+ float col_fac;
+ float col_fl[3];
+
+ ED_view3d_win_to_vector(ar, mval, out);
+
+ if (scene->world->skytype & WO_SKYPAPER) {
+ if (scene->world->skytype & WO_SKYREAL) {
+ col_fac = fabsf(((float)y / (float)VIEWGRAD_RES_Y) - 0.5f) * 2.0f;
+ }
+ else {
+ col_fac = (float)y / (float)VIEWGRAD_RES_Y;
+ }
+ }
+ else {
+ if (scene->world->skytype & WO_SKYREAL) {
+ col_fac = fabsf((angle_normalized_v3v3(z_up, out) / (float)M_PI) - 0.5f) * 2.0f;
+ }
+ else {
+ col_fac = 1.0f - (angle_normalized_v3v3(z_up, out) / (float)M_PI);
+ }
+ }
+
+ interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac);
+
+ rgb_float_to_uchar(col_ub, col_fl);
+ col_ub[3] = 255;
+ }
+ }
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, grid_pos);
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col);
+
+ glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+
+ glDepthFunc(GL_LEQUAL);
+ glDisable(GL_DEPTH_TEST);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ glShadeModel(GL_FLAT);
+
+#undef VIEWGRAD_RES_X
+#undef VIEWGRAD_RES_Y
+ }
+ else { /* solid sky */
+ float col_hor[3];
+ IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
+ &scene->display_settings);
+
+ glClearColor(col_hor[0], col_hor[1], col_hor[2], 1.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ }
+ else {
+ if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+ glShadeModel(GL_SMOOTH);
+ glBegin(GL_QUADS);
+ UI_ThemeColor(TH_LOW_GRAD);
+ glVertex3f(-1.0, -1.0, 1.0);
+ glVertex3f(1.0, -1.0, 1.0);
+ UI_ThemeColor(TH_HIGH_GRAD);
+ glVertex3f(1.0, 1.0, 1.0);
+ glVertex3f(-1.0, 1.0, 1.0);
+ glEnd();
+ glShadeModel(GL_FLAT);
+
+ glDepthFunc(GL_LEQUAL);
+ glDisable(GL_DEPTH_TEST);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+ }
+ else {
+ UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ }
+}
+
/* ED_view3d_draw_offscreen_init should be called before this to initialize
* stuff like shadow buffers
*/
-void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
- float viewmat[4][4], float winmat[4][4],
- bool do_bgpic, bool do_sky)
-{
+void ED_view3d_draw_offscreen(
+ Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy,
+ float viewmat[4][4], float winmat[4][4],
+ bool do_bgpic, bool do_sky, bool is_persp,
+ GPUOffScreen *ofs,
+ GPUFX *fx, GPUFXSettings *fx_settings)
+{
+ struct bThemeState theme_state;
int bwinx, bwiny;
rcti brect;
+ bool do_compositing = false;
+ RegionView3D *rv3d = ar->regiondata;
glPushMatrix();
@@ -2825,7 +3101,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx,
ar->winrct.xmax = winx;
ar->winrct.ymax = winy;
- /* set theme */
+ UI_Theme_Store(&theme_state);
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
/* set flags */
@@ -2837,26 +3113,32 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx,
GPU_free_images_anim();
}
+ /* setup view matrices before fx or unbinding the offscreen buffers will cause issues */
+ view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat);
+
+ /* framebuffer fx needed, we need to draw offscreen first */
+ if (v3d->fx_settings.fx_flag && fx) {
+ do_compositing = GPU_fx_compositor_initialize_passes(fx, &ar->winrct, NULL, fx_settings);
+ }
+
/* clear opengl buffers */
if (do_sky) {
- float sky_color[3];
-
- ED_view3d_offscreen_sky_color_get(scene, sky_color);
- glClearColor(sky_color[0], sky_color[1], sky_color[2], 1.0f);
+ view3d_main_area_clear(scene, v3d, ar);
}
else {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-
- /* setup view matrices */
- view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat);
-
-
/* main drawing call */
- view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true);
+ view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL);
+
+ /* post process */
+ if (do_compositing) {
+ if (!winmat)
+ is_persp = rv3d->is_persp;
+ GPU_fx_do_composite_pass(fx, winmat, is_persp, scene, ofs);
+ }
if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) {
/* draw grease-pencil stuff */
@@ -2879,21 +3161,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx,
glPopMatrix();
- /* XXX, without this the sequencer flickers with opengl draw enabled, need to find out why - campbell */
- glColor4ub(255, 255, 255, 255);
+ UI_Theme_Restore(&theme_state);
G.f &= ~G_RENDER_OGL;
}
-/* get a color used for offscreen sky, returns color in sRGB space */
-void ED_view3d_offscreen_sky_color_get(Scene *scene, float sky_color[3])
-{
- if (scene->world)
- linearrgb_to_srgb_v3_v3(sky_color, &scene->world->horr);
- else
- UI_GetThemeColor3fv(TH_BACK, sky_color);
-}
-
/* utility func for ED_view3d_draw_offscreen */
ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag,
bool draw_background, int alpha_mode, char err_out[256])
@@ -2901,8 +3173,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
RegionView3D *rv3d = ar->regiondata;
ImBuf *ibuf;
GPUOffScreen *ofs;
- bool draw_sky = (alpha_mode == R_ADDSKY);
-
+ bool draw_sky = (alpha_mode == R_ADDSKY) && v3d && (v3d->flag3 & V3D_SHOW_WORLD);
+
/* state changes make normal drawing go weird otherwise */
glPushAttrib(GL_LIGHTING_BIT);
@@ -2915,11 +3187,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
ED_view3d_draw_offscreen_init(scene, v3d);
- GPU_offscreen_bind(ofs);
+ GPU_offscreen_bind(ofs, true);
/* render 3d view */
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
CameraParams params;
+ GPUFXSettings fx_settings = {NULL};
+ Object *camera = v3d->camera;
BKE_camera_params_init(&params);
/* fallback for non camera objects */
@@ -2929,10 +3203,18 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background, draw_sky);
+ BKE_camera_to_gpu_dof(camera, &fx_settings);
+
+ ED_view3d_draw_offscreen(
+ scene, v3d, ar, sizex, sizey, NULL, params.winmat,
+ draw_background, draw_sky, !params.is_ortho,
+ ofs, NULL, &fx_settings);
}
else {
- ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background, draw_sky);
+ ED_view3d_draw_offscreen(
+ scene, v3d, ar, sizex, sizey, NULL, NULL,
+ draw_background, draw_sky, true,
+ ofs, NULL, NULL);
}
/* read in pixels & stamp */
@@ -2944,20 +3226,20 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
/* unbind */
- GPU_offscreen_unbind(ofs);
+ GPU_offscreen_unbind(ofs, true);
GPU_offscreen_free(ofs);
glPopAttrib();
if (ibuf->rect_float && ibuf->rect)
IMB_rect_from_float(ibuf);
-
+
return ibuf;
}
/* creates own 3d views, used by the sequencer */
ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype,
- bool use_solid_tex, bool draw_background, int alpha_mode, char err_out[256])
+ bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, char err_out[256])
{
View3D v3d = {NULL};
ARegion ar = {NULL};
@@ -2972,6 +3254,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w
v3d.lay = scene->lay;
v3d.drawtype = drawtype;
v3d.flag2 = V3D_RENDER_OVERRIDE;
+
+ if (use_gpencil)
+ v3d.flag2 |= V3D_SHOW_GPENCIL;
if (use_solid_tex)
v3d.flag2 |= V3D_SOLID_TEX;
@@ -3205,178 +3490,6 @@ static void view3d_main_area_draw_engine_info(View3D *v3d, RegionView3D *rv3d, A
ED_region_info_draw(ar, rv3d->render_engine->text, 1, fill_color);
}
-/*
- * Function to clear the view
- */
-static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
-{
- /* clear background */
- if (scene->world && (v3d->flag2 & V3D_RENDER_OVERRIDE)) { /* clear with solid color */
- if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */
- int x, y;
- float col_hor[3];
- float col_zen[3];
-
-#define VIEWGRAD_RES_X 16
-#define VIEWGRAD_RES_Y 16
-
- GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4];
- static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][3];
- static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4];
- static bool buf_calculated = false;
-
- IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
- &scene->display_settings);
- IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings,
- &scene->display_settings);
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glShadeModel(GL_SMOOTH);
-
- /* calculate buffers the first time only */
- if (!buf_calculated) {
- for (x = 0; x < VIEWGRAD_RES_X; x++) {
- for (y = 0; y < VIEWGRAD_RES_Y; y++) {
- const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1);
- const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1);
-
- /* -1..1 range */
- grid_pos[x][y][0] = (xf - 0.5f) * 2.0f;
- grid_pos[x][y][1] = (yf - 0.5f) * 2.0f;
- grid_pos[x][y][2] = 1.0;
- }
- }
-
- for (x = 0; x < VIEWGRAD_RES_X - 1; x++) {
- for (y = 0; y < VIEWGRAD_RES_Y - 1; y++) {
- indices[x][y][0] = x * VIEWGRAD_RES_X + y;
- indices[x][y][1] = x * VIEWGRAD_RES_X + y + 1;
- indices[x][y][2] = (x + 1) * VIEWGRAD_RES_X + y + 1;
- indices[x][y][3] = (x + 1) * VIEWGRAD_RES_X + y;
- }
- }
-
- buf_calculated = true;
- }
-
- for (x = 0; x < VIEWGRAD_RES_X; x++) {
- for (y = 0; y < VIEWGRAD_RES_Y; y++) {
- const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1);
- const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1);
- const float mval[2] = {xf * (float)ar->winx, yf * ar->winy};
- const float z_up[3] = {0.0f, 0.0f, 1.0f};
- float out[3];
- GLubyte *col_ub = grid_col[x][y];
-
- float col_fac;
- float col_fl[3];
-
- ED_view3d_win_to_vector(ar, mval, out);
-
- if (scene->world->skytype & WO_SKYPAPER) {
- if (scene->world->skytype & WO_SKYREAL) {
- col_fac = fabsf(((float)y / (float)VIEWGRAD_RES_Y) - 0.5f) * 2.0f;
- }
- else {
- col_fac = (float)y / (float)VIEWGRAD_RES_Y;
- }
- }
- else {
- if (scene->world->skytype & WO_SKYREAL) {
- col_fac = fabsf((angle_normalized_v3v3(z_up, out) / (float)M_PI) - 0.5f) * 2.0f;
- }
- else {
- col_fac = 1.0f - (angle_normalized_v3v3(z_up, out) / (float)M_PI);
- }
- }
-
- interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac);
-
- rgb_float_to_uchar(col_ub, col_fl);
- col_ub[3] = 0;
- }
- }
-
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_ALWAYS);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, grid_pos);
- glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col);
-
- glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
-
- glDepthFunc(GL_LEQUAL);
- glDisable(GL_DEPTH_TEST);
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-
- glShadeModel(GL_FLAT);
-
-#undef VIEWGRAD_RES_X
-#undef VIEWGRAD_RES_Y
- }
- else { /* solid sky */
- float col_hor[3];
- IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings,
- &scene->display_settings);
-
- glClearColor(col_hor[0], col_hor[1], col_hor[2], 0.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- }
- }
- else {
- if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_ALWAYS);
- glShadeModel(GL_SMOOTH);
- glBegin(GL_QUADS);
- UI_ThemeColor(TH_LOW_GRAD);
- glVertex3f(-1.0, -1.0, 1.0);
- glVertex3f(1.0, -1.0, 1.0);
- UI_ThemeColor(TH_HIGH_GRAD);
- glVertex3f(1.0, 1.0, 1.0);
- glVertex3f(-1.0, 1.0, 1.0);
- glEnd();
- glShadeModel(GL_FLAT);
-
- glDepthFunc(GL_LEQUAL);
- glDisable(GL_DEPTH_TEST);
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
-
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- }
- else {
- UI_ThemeClearColor(TH_HIGH_GRAD);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- }
- }
-}
-
-
#ifdef WITH_GAMEENGINE
static void update_lods(Scene *scene, float camera_pos[3])
{
@@ -3391,13 +3504,15 @@ static void update_lods(Scene *scene, float camera_pos[3])
}
#endif
-
static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3D *v3d,
ARegion *ar, const char **grid_unit)
{
RegionView3D *rv3d = ar->regiondata;
unsigned int lay_used = v3d->lay_used;
-
+
+ /* post processing */
+ bool do_compositing = false;
+
/* shadow buffers, before we setup matrices */
if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
gpu_update_lamps_shadows(scene, v3d);
@@ -3413,7 +3528,7 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
rv3d->rflag &= ~RV3D_IS_GAME_ENGINE;
#ifdef WITH_GAMEENGINE
- if (STREQ(scene->r.engine, "BLENDER_GAME")) {
+ if (STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME)) {
rv3d->rflag |= RV3D_IS_GAME_ENGINE;
/* Make sure LoDs are up to date */
@@ -3421,6 +3536,22 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
}
#endif
+ /* framebuffer fx needed, we need to draw offscreen first */
+ if (v3d->fx_settings.fx_flag) {
+ GPUFXSettings fx_settings;
+ BKE_screen_gpu_fx_validate(&v3d->fx_settings);
+ fx_settings = v3d->fx_settings;
+ if (!rv3d->compositor)
+ rv3d->compositor = GPU_fx_compositor_create();
+
+ if (rv3d->persp == RV3D_CAMOB && v3d->camera)
+ BKE_camera_to_gpu_dof(v3d->camera, &fx_settings);
+ else {
+ fx_settings.dof = NULL;
+ }
+ do_compositing = GPU_fx_compositor_initialize_passes(rv3d->compositor, &ar->winrct, &ar->drawrct, &fx_settings);
+ }
+
/* clear the background */
view3d_main_area_clear(scene, v3d, ar);
@@ -3430,7 +3561,12 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
}
/* main drawing call */
- view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false);
+ view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
+
+ /* post process */
+ if (do_compositing) {
+ GPU_fx_do_composite_pass(rv3d->compositor, rv3d->winmat, rv3d->is_persp, scene, NULL);
+ }
/* Disable back anti-aliasing */
if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) {
@@ -3454,6 +3590,36 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
}
+static bool is_cursor_visible(Scene *scene)
+{
+ Object *ob = OBACT;
+
+ /* don't draw cursor in paint modes, but with a few exceptions */
+ if (ob && ob->mode & OB_MODE_ALL_PAINT) {
+ /* exception: object is in weight paint and has deforming armature in pose mode */
+ if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ if (BKE_object_pose_armature_get(ob) != NULL) {
+ return true;
+ }
+ }
+ /* exception: object in texture paint mode, clone brush, use_clone_layer disabled */
+ else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ const Paint *p = BKE_paint_get_active(scene);
+
+ if (p && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) {
+ if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
+ return true;
+ }
+ }
+ }
+
+ /* no exception met? then don't draw cursor! */
+ return false;
+ }
+
+ return true;
+}
+
static void view3d_main_area_draw_info(const bContext *C, Scene *scene,
ARegion *ar, View3D *v3d,
const char *grid_unit, bool render_border)
@@ -3487,7 +3653,10 @@ static void view3d_main_area_draw_info(const bContext *C, Scene *scene,
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
Object *ob;
- drawcursor(scene, ar, v3d);
+ /* 3d cursor */
+ if (is_cursor_visible(scene)) {
+ drawcursor(scene, ar, v3d);
+ }
if (U.uiflag & USER_SHOW_ROTVIEWICON)
draw_view_axis(rv3d, &rect);
@@ -3545,9 +3714,13 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
/* draw viewport using opengl */
if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(scene) || clip_border) {
view3d_main_area_draw_objects(C, scene, v3d, ar, &grid_unit);
+
#ifdef DEBUG_DRAW
bl_debug_draw();
#endif
+ if (G.debug & G_DEBUG_SIMDATA)
+ draw_sim_debug_data(scene, v3d, ar);
+
ED_region_pixelspace(ar);
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index d3bd59cacc8..51915e05a9e 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -49,7 +49,6 @@
#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_font.h"
-#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_object.h"
#include "BKE_paint.h"
@@ -190,6 +189,7 @@ bool ED_view3d_camera_autokey(
struct bContext *C, const bool do_rotate, const bool do_translate)
{
if (autokeyframe_cfra_can_key(scene, id_key)) {
+ const float cfra = (float)CFRA;
ListBase dsources = {NULL, NULL};
/* add data-source override for the camera object */
@@ -201,12 +201,12 @@ bool ED_view3d_camera_autokey(
* TODO: need to check in future that frame changed before doing this
*/
if (do_rotate) {
- struct KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_ROTATION_ID);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
if (do_translate) {
- struct KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
/* free temp data */
@@ -626,9 +626,9 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
* center, in other cases it's not clear what rotation center shall be
* so just rotate around object origin
*/
- if (ob->mode & OB_MODE_SCULPT) {
+ if (ob->mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT)) {
float stroke[3];
- ED_sculpt_stroke_get_average(ob, stroke);
+ BKE_paint_stroke_get_average(scene, ob, stroke);
copy_v3_v3(lastofs, stroke);
}
else {
@@ -1035,7 +1035,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
* - of rotation is linearly proportional
* - to the distance that the mouse is
* - dragged. */
- phi = si * (float)(M_PI / 2.0);
+ phi = si * (float)M_PI_2;
q1[0] = cosf(phi);
mul_v3_fl(q1 + 1, sinf(phi));
@@ -1119,6 +1119,8 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
+ bool use_autokey = false;
+ int ret = OPERATOR_RUNNING_MODAL;
/* execute the events */
if (event->type == MOUSEMOVE) {
@@ -1153,17 +1155,25 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event_code == VIEW_APPLY) {
viewrotate_apply(vod, event->x, event->y);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ use_autokey = true;
+ }
}
else if (event_code == VIEW_CONFIRM) {
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, true);
ED_view3d_depth_tag_update(vod->rv3d);
+ use_autokey = true;
+ ret = OPERATOR_FINISHED;
+ }
- viewops_data_free(C, op);
+ if (use_autokey) {
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, true);
+ }
- return OPERATOR_FINISHED;
+ if (ret & OPERATOR_FINISHED) {
+ viewops_data_free(C, op);
}
- return OPERATOR_RUNNING_MODAL;
+ return ret;
}
/**
@@ -1221,26 +1231,31 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_region_tag_redraw(vod->ar);
}
- if (event->type == MOUSEPAN) {
+ if (ELEM(event->type, MOUSEPAN, MOUSEROTATE)) {
/* Rotate direction we keep always same */
- if (U.uiflag2 & USER_TRACKPAD_NATURAL)
- viewrotate_apply(vod, 2 * event->x - event->prevx, 2 * event->y - event->prevy);
- else
- viewrotate_apply(vod, event->prevx, event->prevy);
-
- ED_view3d_depth_tag_update(vod->rv3d);
-
- viewops_data_free(C, op);
-
- return OPERATOR_FINISHED;
- }
- else if (event->type == MOUSEROTATE) {
- /* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */
- viewrotate_apply(vod, event->prevx, event->y);
+ int x, y;
+
+ if (event->type == MOUSEPAN) {
+ if (U.uiflag2 & USER_TRACKPAD_NATURAL) {
+ x = 2 * event->x - event->prevx;
+ y = 2 * event->y - event->prevy;
+ }
+ else {
+ x = event->prevx;
+ y = event->prevy;
+ }
+ }
+ else {
+ /* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */
+ x = event->prevx;
+ y = event->y;
+ }
+
+ viewrotate_apply(vod, x, y);
ED_view3d_depth_tag_update(vod->rv3d);
-
+
viewops_data_free(C, op);
-
+
return OPERATOR_FINISHED;
}
else {
@@ -1912,7 +1927,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
vod->rv3d->ofs_lock[1] -= ((vod->oldy - y) * 2.0f) / (float)vod->ar->winy;
}
else if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) {
- const float zoomfac = BKE_screen_view3d_zoom_to_fac((float)vod->rv3d->camzoom) * 2.0f;
+ const float zoomfac = BKE_screen_view3d_zoom_to_fac(vod->rv3d->camzoom) * 2.0f;
vod->rv3d->camdx += (vod->oldx - x) / (vod->ar->winx * zoomfac);
vod->rv3d->camdy += (vod->oldy - y) / (vod->ar->winy * zoomfac);
CLAMP(vod->rv3d->camdx, -1.0f, 1.0f);
@@ -1946,6 +1961,8 @@ static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
+ bool use_autokey = false;
+ int ret = OPERATOR_RUNNING_MODAL;
/* execute the events */
if (event->type == MOUSEMOVE) {
@@ -1972,17 +1989,25 @@ static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event_code == VIEW_APPLY) {
viewmove_apply(vod, event->x, event->y);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ use_autokey = true;
+ }
}
else if (event_code == VIEW_CONFIRM) {
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
ED_view3d_depth_tag_update(vod->rv3d);
+ use_autokey = true;
+ ret = OPERATOR_FINISHED;
+ }
- viewops_data_free(C, op);
+ if (use_autokey) {
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
+ }
- return OPERATOR_FINISHED;
+ if (ret & OPERATOR_FINISHED) {
+ viewops_data_free(C, op);
}
- return OPERATOR_RUNNING_MODAL;
+ return ret;
}
static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -2214,6 +2239,8 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
+ bool use_autokey = false;
+ int ret = OPERATOR_RUNNING_MODAL;
/* execute the events */
if (event->type == TIMER && event->customdata == vod->timer) {
@@ -2244,16 +2271,25 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event_code == VIEW_APPLY) {
viewzoom_apply(vod, &event->x, U.viewzoom, (U.uiflag & USER_ZOOM_INVERT) != 0);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ use_autokey = true;
+ }
}
else if (event_code == VIEW_CONFIRM) {
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
ED_view3d_depth_tag_update(vod->rv3d);
- viewops_data_free(C, op);
+ use_autokey = true;
+ ret = OPERATOR_FINISHED;
+ }
- return OPERATOR_FINISHED;
+ if (use_autokey) {
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
}
- return OPERATOR_RUNNING_MODAL;
+ if (ret & OPERATOR_FINISHED) {
+ viewops_data_free(C, op);
+ }
+
+ return ret;
}
static int viewzoom_exec(bContext *C, wmOperator *op)
@@ -2315,6 +2351,7 @@ static int viewzoom_exec(bContext *C, wmOperator *op)
ED_view3d_depth_tag_update(rv3d);
ED_view3d_camera_lock_sync(v3d, rv3d);
+ ED_view3d_camera_lock_autokey(v3d, rv3d, C, false, true);
ED_region_tag_redraw(ar);
@@ -2389,8 +2426,10 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
vod->origy = vod->oldy = vod->origy + event->x - event->prevx;
viewzoom_apply(vod, &event->prevx, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) != 0);
}
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
+
ED_view3d_depth_tag_update(vod->rv3d);
-
+
viewops_data_free(C, op);
return OPERATOR_FINISHED;
}
@@ -2486,6 +2525,8 @@ static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
+ bool use_autokey = false;
+ int ret = OPERATOR_RUNNING_MODAL;
/* execute the events */
if (event->type == MOUSEMOVE) {
@@ -2512,16 +2553,25 @@ static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event_code == VIEW_APPLY) {
viewdolly_apply(vod, event->x, event->y, (U.uiflag & USER_ZOOM_INVERT) != 0);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ use_autokey = true;
+ }
}
else if (event_code == VIEW_CONFIRM) {
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
ED_view3d_depth_tag_update(vod->rv3d);
- viewops_data_free(C, op);
+ use_autokey = true;
+ ret = OPERATOR_FINISHED;
+ }
- return OPERATOR_FINISHED;
+ if (use_autokey) {
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, false, true);
+ }
+
+ if (ret & OPERATOR_FINISHED) {
+ viewops_data_free(C, op);
}
- return OPERATOR_RUNNING_MODAL;
+ return ret;
}
static int viewdolly_exec(bContext *C, wmOperator *op)
@@ -2926,8 +2976,10 @@ static int viewselected_exec(bContext *C, wmOperator *op)
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
ok = PE_minmax(scene, min, max);
}
- else if (ob && (ob->mode & OB_MODE_SCULPT)) {
- ok = ED_sculpt_minmax(C, min, max);
+ else if (ob && (ob->mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT))) {
+ BKE_paint_stroke_get_average(scene, ob, min);
+ copy_v3_v3(max, min);
+ ok = true;
ok_dist = 0; /* don't zoom */
}
else {
@@ -3322,7 +3374,8 @@ void VIEW3D_OT_render_border(wmOperatorType *ot)
/* rna */
WM_operator_properties_border(ot);
- prop = RNA_def_boolean(ot->srna, "camera_only", 0, "Camera Only", "Set render border for camera view and final render only");
+ prop = RNA_def_boolean(ot->srna, "camera_only", false, "Camera Only",
+ "Set render border for camera view and final render only");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
@@ -3650,22 +3703,6 @@ static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar,
}
if (align_active == false) {
- /* normal operation */
- if (rv3d->viewlock & RV3D_LOCKED) {
- /* only pass on if */
-
- /* nice confusing if-block */
- if (!((rv3d->view == RV3D_VIEW_FRONT && view == RV3D_VIEW_BACK) ||
- (rv3d->view == RV3D_VIEW_BACK && view == RV3D_VIEW_FRONT) ||
- (rv3d->view == RV3D_VIEW_RIGHT && view == RV3D_VIEW_LEFT) ||
- (rv3d->view == RV3D_VIEW_LEFT && view == RV3D_VIEW_RIGHT) ||
- (rv3d->view == RV3D_VIEW_BOTTOM && view == RV3D_VIEW_TOP) ||
- (rv3d->view == RV3D_VIEW_TOP && view == RV3D_VIEW_BOTTOM)))
- {
- return;
- }
- }
-
rv3d->view = view;
}
@@ -3712,10 +3749,6 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
viewnum = RNA_enum_get(op->ptr, "type");
align_active = RNA_boolean_get(op->ptr, "align_active");
- /* set this to zero, gets handled in axis_set_view */
- if (rv3d->viewlock & RV3D_LOCKED)
- align_active = false;
-
/* Use this to test if we started out with a camera */
if (rv3d->persp == RV3D_CAMOB) {
@@ -3841,23 +3874,37 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
ARegion *ar;
RegionView3D *rv3d;
int orbitdir;
+ char view_opposite;
+ PropertyRNA *prop_angle = RNA_struct_find_property(op->ptr, "angle");
+ float angle = RNA_property_is_set(op->ptr, prop_angle) ?
+ RNA_property_float_get(op->ptr, prop_angle) : DEG2RADF((float)U.pad_rot_angle);
/* no NULL check is needed, poll checks */
- ED_view3d_context_user_region(C, &v3d, &ar);
+ v3d = CTX_wm_view3d(C);
+ ar = CTX_wm_region(C);
rv3d = ar->regiondata;
+ /* support for switching to the opposite view (even when in locked views) */
+ view_opposite = (fabsf(angle) == (float)M_PI) ? ED_view3d_axis_view_opposite(rv3d->view) : RV3D_VIEW_USER;
orbitdir = RNA_enum_get(op->ptr, "type");
- if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
+ if ((rv3d->viewlock & RV3D_LOCKED) && (view_opposite == RV3D_VIEW_USER)) {
+ /* no NULL check is needed, poll checks */
+ ED_view3d_context_user_region(C, &v3d, &ar);
+ rv3d = ar->regiondata;
+ }
+
+ if ((rv3d->viewlock & RV3D_LOCKED) == 0 || (view_opposite != RV3D_VIEW_USER)) {
if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- float angle = DEG2RADF((float)U.pad_rot_angle);
float quat_mul[4];
float quat_new[4];
float ofs_new[3];
float *ofs_new_pt = NULL;
- view3d_ensure_persp(v3d, ar);
+ if (view_opposite == RV3D_VIEW_USER) {
+ view3d_ensure_persp(v3d, ar);
+ }
if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) {
const float zvec[3] = {0.0f, 0.0f, 1.0f};
@@ -3880,7 +3927,15 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
}
mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul);
- rv3d->view = RV3D_VIEW_USER;
+
+ if (view_opposite != RV3D_VIEW_USER) {
+ rv3d->view = view_opposite;
+ /* avoid float in-precision, just get a new orientation */
+ ED_view3d_quat_from_axis_view(view_opposite, quat_new);
+ }
+ else {
+ rv3d->view = RV3D_VIEW_USER;
+ }
if (U.uiflag & USER_ORBIT_SELECTION) {
float dyn_ofs[3];
@@ -3911,6 +3966,8 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_view_orbit(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "View Orbit";
ot->description = "Orbit the view";
@@ -3924,7 +3981,11 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot)
ot->flag = 0;
/* properties */
+ prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
ot->prop = RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
+
}
@@ -3970,6 +4031,8 @@ static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
+ bool use_autokey = false;
+ int ret = OPERATOR_RUNNING_MODAL;
/* execute the events */
if (event->type == MOUSEMOVE) {
@@ -3996,16 +4059,25 @@ static int viewroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event_code == VIEW_APPLY) {
viewroll_apply(vod, event->x, event->y);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ use_autokey = true;
+ }
}
else if (event_code == VIEW_CONFIRM) {
- ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, false);
ED_view3d_depth_tag_update(vod->rv3d);
- viewops_data_free(C, op);
+ use_autokey = true;
+ ret = OPERATOR_FINISHED;
+ }
- return OPERATOR_FINISHED;
+ if (use_autokey) {
+ ED_view3d_camera_lock_autokey(vod->v3d, vod->rv3d, C, true, false);
+ }
+
+ if (ret & OPERATOR_FINISHED) {
+ viewops_data_free(C, op);
}
- return OPERATOR_RUNNING_MODAL;
+ return ret;
}
static EnumPropertyItem prop_view_roll_items[] = {
@@ -4279,32 +4351,16 @@ static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op))
static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
- Image *ima = NULL;
+ Image *ima;
BGpic *bgpic;
- char name[MAX_ID_NAME - 2];
-
- /* check input variables */
- if (RNA_struct_property_is_set(op->ptr, "filepath")) {
- char path[FILE_MAX];
-
- RNA_string_get(op->ptr, "filepath", path);
- ima = BKE_image_load_exists(path);
- }
- else if (RNA_struct_property_is_set(op->ptr, "name")) {
- RNA_string_get(op->ptr, "name", name);
- ima = (Image *)BKE_libblock_find_name(ID_IM, name);
- }
+ ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
+ /* may be NULL, continue anyway */
+
bgpic = background_image_add(C);
-
- if (ima) {
- bgpic->ima = ima;
-
- id_us_plus(&ima->id);
-
- if (!(v3d->flag & V3D_DISPBGPICS))
- v3d->flag |= V3D_DISPBGPICS;
- }
+ bgpic->ima = ima;
+
+ v3d->flag |= V3D_DISPBGPICS;
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
@@ -4330,7 +4386,8 @@ void VIEW3D_OT_background_image_add(wmOperatorType *ot)
/* properties */
RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Image name to assign");
- RNA_def_string(ot->srna, "filepath", "Path", FILE_MAX, "Filepath", "Path to image file");
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
+ WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY);
}
@@ -4380,20 +4437,6 @@ void VIEW3D_OT_background_image_remove(wmOperatorType *ot)
/* ********************* set clipping operator ****************** */
-static void calc_clipping_plane(float clip[6][4], const BoundBox *clipbb, const bool is_flip)
-{
- int val;
-
- for (val = 0; val < 4; val++) {
- normal_tri_v3(clip[val], clipbb->vec[val], clipbb->vec[val == 3 ? 0 : val + 1], clipbb->vec[val + 4]);
- if (UNLIKELY(is_flip)) {
- negate_v3(clip[val]);
- }
-
- clip[val][3] = -dot_v3v3(clip[val], clipbb->vec[val]);
- }
-}
-
static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float mat[4][4])
{
BoundBox clipbb_local;
@@ -4406,7 +4449,7 @@ static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float
mul_v3_m4v3(clipbb_local.vec[i], imat, clipbb->vec[i]);
}
- calc_clipping_plane(clip_local, &clipbb_local, is_negative_m4(mat));
+ ED_view3d_clipping_calc_from_boundbox(clip_local, &clipbb_local, is_negative_m4(mat));
}
void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4])
@@ -4956,8 +4999,9 @@ BGpic *ED_view3D_background_image_new(View3D *v3d)
{
BGpic *bgpic = MEM_callocN(sizeof(BGpic), "Background Image");
- bgpic->size = 5.0;
- bgpic->blend = 0.5;
+ bgpic->rotation = 0.0f;
+ bgpic->size = 5.0f;
+ bgpic->blend = 0.5f;
bgpic->iuser.fie_ima = 2;
bgpic->iuser.ok = 1;
bgpic->view = 0; /* 0 for all */
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index a88724a1cdd..11ed9867e2f 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -32,12 +32,9 @@
#include <stdio.h>
#include <stdlib.h>
-#include "DNA_brush_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -45,8 +42,6 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_main.h"
-#include "BKE_modifier.h"
-#include "BKE_paint.h"
#include "BKE_screen.h"
#include "BKE_editmesh.h"
@@ -262,7 +257,7 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
Object *obedit = CTX_data_edit_object(C);
uiBlock *block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL);
+ UI_block_func_handle_set(block, do_view3d_header_buttons, NULL);
if (obedit && (obedit->type == OB_MESH)) {
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -270,13 +265,13 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
row = uiLayoutRow(layout, true);
block = uiLayoutGetBlock(row);
- uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
+ uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection"));
- uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
+ uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click expands/contracts selection"));
- uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
+ uiDefIconButBitS(block, UI_BTYPE_TOGGLE, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection"));
}
@@ -302,10 +297,10 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
RNA_pointer_create(&scene->id, &RNA_Scene, scene, &sceneptr);
block = uiLayoutGetBlock(layout);
- uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL);
+ UI_block_func_handle_set(block, do_view3d_header_buttons, NULL);
/* other buttons: */
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
/* mode */
if (ob) {
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 84ac4f7d02d..25dbc8830fe 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -48,9 +48,11 @@ struct bMotionPath;
struct bPoseChannel;
struct bScreen;
struct Mesh;
+struct SimDebugData;
struct wmNDOFMotionData;
struct wmOperatorType;
struct wmWindowManager;
+struct wmKeyConfig;
/* drawing flags: */
enum {
@@ -163,7 +165,9 @@ bool draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* drawmesh.c */
void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
-void draw_mesh_face_select(struct RegionView3D *rv3d, struct Mesh *me, struct DerivedMesh *dm);
+void draw_mesh_face_select(
+ struct RegionView3D *rv3d, struct Mesh *me, struct DerivedMesh *dm,
+ bool draw_select_edges);
void draw_mesh_paint_weight_faces(struct DerivedMesh *dm, const bool do_light,
void *facemask_cb, void *user_data);
void draw_mesh_paint_vcolor_faces(struct DerivedMesh *dm, const bool use_light,
@@ -175,6 +179,9 @@ void draw_mesh_paint_weight_edges(RegionView3D *rv3d, struct DerivedMesh *dm,
void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
struct Object *ob, struct DerivedMesh *dm, const int draw_flags);
+/* drawsimdebug.c */
+void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar);
+
/* view3d_draw.c */
void view3d_main_area_draw(const struct bContext *C, struct ARegion *ar);
void ED_view3d_draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, bool alphaoverride);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 6a505959820..8c668b2b8e0 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -42,6 +42,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BKE_appdir.h"
#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_main.h"
@@ -77,7 +78,7 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- BLI_make_file_string("/", str, BLI_temp_dir_base(), "copybuffer.blend");
+ BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
BKE_copybuffer_save(str, op->reports);
BKE_report(op->reports, RPT_INFO, "Copied selected objects to buffer");
@@ -102,7 +103,7 @@ static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
{
char str[FILE_MAX];
- BLI_make_file_string("/", str, BLI_temp_dir_base(), "copybuffer.blend");
+ BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
if (BKE_copybuffer_paste(C, str, op->reports)) {
WM_event_add_notifier(C, NC_WINDOW, NULL);
@@ -298,6 +299,9 @@ void view3d_keymap(wmKeyConfig *keyconf)
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_roll", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPLEFT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD6, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPRIGHT);
+ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", PAD9, KM_PRESS, 0, 0);
+ RNA_enum_set(kmi->ptr, "type", V3D_VIEW_STEPRIGHT);
+ RNA_float_set(kmi->ptr, "angle", (float)M_PI);
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);
@@ -343,8 +347,8 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, KM_CTRL | KM_SHIFT, 0);
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "use_all_regions", false);
- RNA_float_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", NDOF_BUTTON_ROLL_CCW, KM_PRESS, 0, 0)->ptr, "angle", M_PI / -2);
- RNA_float_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", NDOF_BUTTON_ROLL_CW, KM_PRESS, 0, 0)->ptr, "angle", M_PI / 2);
+ RNA_float_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", NDOF_BUTTON_ROLL_CCW, KM_PRESS, 0, 0)->ptr, "angle", -M_PI_2);
+ RNA_float_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", NDOF_BUTTON_ROLL_CW, KM_PRESS, 0, 0)->ptr, "angle", M_PI_2);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index 75c1d9dcd22..74e3fde0eec 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -497,7 +497,7 @@ void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float
float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f;
if (rv3d->persp == RV3D_CAMOB) {
/* ortho camera needs offset applied */
- const float zoomfac = BKE_screen_view3d_zoom_to_fac((float)rv3d->camzoom) * 4.0f;
+ const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 4.0f;
dx += rv3d->camdx * zoomfac;
dy += rv3d->camdy * zoomfac;
}
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
index 652f44ea95a..eba31866f54 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -70,7 +70,7 @@
* \param r_co hit location.
* \param r_no hit normal (optional).
* \param co_ss Screenspace coordinate.
- * \param use_depth Snap to the closest element, use when using more then one snap type.
+ * \param use_depth Snap to the closest element, use when using more than one snap type.
* \param use_obedit Use editmode cage.
* \param use_vert Snap to verts.
* \param use_edge Snap to edges.
@@ -187,7 +187,6 @@ typedef struct RulerInfo {
/* wm state */
wmWindow *win;
- ScrArea *sa;
ARegion *ar;
void *draw_handle_pixel;
} RulerInfo;
@@ -550,10 +549,11 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
/* draw text (bg) */
glColor4ubv(color_back);
- uiSetRoundBox(UI_CNR_ALL);
- uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin,
- pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
- bg_radius);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox(
+ pos[0] - bg_margin, pos[1] - bg_margin,
+ pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
+ bg_radius);
/* draw text */
glColor3ubv(color_text);
BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
@@ -639,8 +639,8 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a
/* draw text (bg) */
glColor4ubv(color_back);
- uiSetRoundBox(UI_CNR_ALL);
- uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin,
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox(pos[0] - bg_margin, pos[1] - bg_margin,
pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
bg_radius);
/* draw text */
@@ -798,7 +798,6 @@ static int view3d_ruler_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
op->customdata = ruler_info;
ruler_info->win = win;
- ruler_info->sa = sa;
ruler_info->ar = ar;
ruler_info->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ruler_info_draw_pixel,
ruler_info, REGION_DRAW_POST_PIXEL);
@@ -825,11 +824,11 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
bool do_draw = false;
int exit_code = OPERATOR_RUNNING_MODAL;
RulerInfo *ruler_info = op->customdata;
- ScrArea *sa = ruler_info->sa;
+ ScrArea *sa = CTX_wm_area(C);
ARegion *ar = ruler_info->ar;
RegionView3D *rv3d = ar->regiondata;
- /* its possible to change spaces while running the operator [#34894] */
+ /* its possible to change spaces while running the operator [#34894] */
if (UNLIKELY(ar != CTX_wm_region(C))) {
exit_code = OPERATOR_FINISHED;
goto exit;
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 9d5240feb43..d0f22ba58c5 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -93,7 +93,6 @@
#include "ED_mball.h"
#include "UI_interface.h"
-#include "UI_resources.h"
#include "view3d_intern.h" /* own include */
@@ -1143,7 +1142,7 @@ static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, unsigned int
const char *name = ob->id.name + 2;
BLI_strncpy(object_mouse_select_menu_data[i].idname, name, MAX_ID_NAME - 2);
- object_mouse_select_menu_data[i].icon = uiIconFromID(&ob->id);
+ object_mouse_select_menu_data[i].icon = UI_icon_from_id(&ob->id);
}
{
@@ -1346,7 +1345,7 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
{
ViewContext vc;
Base *basact = NULL;
- unsigned int buffer[4 * MAXPICKBUF];
+ unsigned int buffer[MAXPICKBUF];
int hits;
bool do_nearest;
@@ -1444,7 +1443,7 @@ static bool mouse_select(bContext *C, const int mval[2],
}
}
else {
- unsigned int buffer[4 * MAXPICKBUF];
+ unsigned int buffer[MAXPICKBUF];
bool do_nearest;
/* if objects have posemode set, the bones are in the same selection buffer */
@@ -1877,7 +1876,7 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool ext
MetaElem *ml;
int a;
- unsigned int buffer[4 * MAXPICKBUF];
+ unsigned int buffer[MAXPICKBUF];
short hits;
hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, false);
@@ -1911,7 +1910,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool
EditBone *ebone;
int a;
- unsigned int buffer[4 * MAXPICKBUF];
+ unsigned int buffer[MAXPICKBUF];
short hits;
hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, false);
@@ -2007,8 +2006,8 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
}
/* selection buffer now has bones potentially too, so we add MAXPICKBUF */
- vbuffer = MEM_mallocN(4 * (totobj + MAXPICKBUF) * sizeof(unsigned int), "selection buffer");
- hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKBUF), rect, false);
+ vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(unsigned int), "selection buffer");
+ hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, false);
/*
* LOGIC NOTES (theeth):
* The buffer and ListBase have the same relative order, which makes the selection
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 8e6deeddc39..0608c35129d 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -33,15 +33,18 @@
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_object_types.h"
+#include "DNA_meta_types.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_lattice.h"
+#include "BKE_main.h"
#include "BKE_mball.h"
#include "BKE_object.h"
#include "BKE_editmesh.h"
@@ -53,13 +56,16 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "ED_object.h"
#include "ED_transverts.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
+#include "ED_curve.h"
#include "view3d_intern.h"
static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]);
+static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3]);
/* *********************** operators ******************** */
@@ -205,8 +211,9 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
static int snap_sel_to_curs_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ Object *obact = CTX_data_active_object(C);
View3D *v3d = CTX_wm_view3d(C);
TransVertStore tvs = {NULL};
TransVert *tv;
@@ -221,7 +228,14 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op)
cursor_global = ED_view3d_cursor3d_get(scene, v3d);
if (use_offset) {
- snap_curs_to_sel_ex(C, center_global);
+ if ((v3d && v3d->around == V3D_ACTIVE) &&
+ snap_calc_active_center(C, true, center_global))
+ {
+ /* pass */
+ }
+ else {
+ snap_curs_to_sel_ex(C, center_global);
+ }
sub_v3_v3v3(offset_global, cursor_global, center_global);
}
@@ -260,59 +274,98 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op)
ED_transverts_update_obedit(&tvs, obedit);
ED_transverts_free(&tvs);
}
- else {
+ else if (obact && (obact->mode & OB_MODE_POSE)) {
struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
- CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
- {
- if (ob->mode & OB_MODE_POSE) {
- bPoseChannel *pchan;
- bArmature *arm = ob->data;
- float cursor_local[3];
-
- invert_m4_m4(ob->imat, ob->obmat);
- mul_v3_m4v3(cursor_local, ob->imat, cursor_global);
+ bPoseChannel *pchan;
+ bArmature *arm = obact->data;
+ float cursor_local[3];
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if (pchan->bone->flag & BONE_SELECTED) {
- if (PBONE_VISIBLE(arm, pchan->bone)) {
- if ((pchan->bone->flag & BONE_CONNECTED) == 0) {
- /* Get position in pchan (pose) space. */
- float cursor_pose[3];
+ invert_m4_m4(obact->imat, obact->obmat);
+ mul_v3_m4v3(cursor_local, obact->imat, cursor_global);
- if (use_offset) {
- mul_v3_m4v3(cursor_pose, ob->obmat, pchan->pose_mat[3]);
- add_v3_v3(cursor_pose, offset_global);
+ for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if ((pchan->bone->flag & BONE_SELECTED) &&
+ (PBONE_VISIBLE(arm, pchan->bone)) &&
+ /* if the bone has a parent and is connected to the parent,
+ * don't do anything - will break chain unless we do auto-ik.
+ */
+ (pchan->bone->flag & BONE_CONNECTED) == 0)
+ {
+ pchan->bone->flag |= BONE_TRANSFORM;
+ }
+ else {
+ pchan->bone->flag &= ~BONE_TRANSFORM;
+ }
+ }
- mul_m4_v3(ob->imat, cursor_pose);
- BKE_armature_loc_pose_to_bone(pchan, cursor_pose, cursor_pose);
- }
- else {
- BKE_armature_loc_pose_to_bone(pchan, cursor_local, cursor_pose);
- }
+ for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if ((pchan->bone->flag & BONE_TRANSFORM) &&
+ /* check that our parents not transformed (if we have one) */
+ ((pchan->bone->parent &&
+ BKE_armature_bone_flag_test_recursive(pchan->bone->parent, BONE_TRANSFORM)) == 0))
+ {
+ /* Get position in pchan (pose) space. */
+ float cursor_pose[3];
- /* copy new position */
- if ((pchan->protectflag & OB_LOCK_LOCX) == 0)
- pchan->loc[0] = cursor_pose[0];
- if ((pchan->protectflag & OB_LOCK_LOCY) == 0)
- pchan->loc[1] = cursor_pose[1];
- if ((pchan->protectflag & OB_LOCK_LOCZ) == 0)
- pchan->loc[2] = cursor_pose[2];
+ if (use_offset) {
+ mul_v3_m4v3(cursor_pose, obact->obmat, pchan->pose_mat[3]);
+ add_v3_v3(cursor_pose, offset_global);
- /* auto-keyframing */
- ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
- }
- /* if the bone has a parent and is connected to the parent,
- * don't do anything - will break chain unless we do auto-ik.
- */
- }
- }
+ mul_m4_v3(obact->imat, cursor_pose);
+ BKE_armature_loc_pose_to_bone(pchan, cursor_pose, cursor_pose);
}
- ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
-
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ else {
+ BKE_armature_loc_pose_to_bone(pchan, cursor_local, cursor_pose);
+ }
+
+ /* copy new position */
+ if ((pchan->protectflag & OB_LOCK_LOCX) == 0)
+ pchan->loc[0] = cursor_pose[0];
+ if ((pchan->protectflag & OB_LOCK_LOCY) == 0)
+ pchan->loc[1] = cursor_pose[1];
+ if ((pchan->protectflag & OB_LOCK_LOCZ) == 0)
+ pchan->loc[2] = cursor_pose[2];
+
+ /* auto-keyframing */
+ ED_autokeyframe_pchan(C, scene, obact, pchan, ks);
}
- else {
+ }
+
+ for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) {
+ pchan->bone->flag &= ~BONE_TRANSFORM;
+ }
+
+ obact->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
+
+ DAG_id_tag_update(&obact->id, OB_RECALC_DATA);
+ }
+ else {
+ struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
+ Main *bmain = CTX_data_main(C);
+
+ ListBase ctx_data_list;
+ CollectionPointerLink *ctx_ob;
+ Object *ob;
+
+ CTX_data_selected_editable_objects(C, &ctx_data_list);
+
+ /* reset flags */
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ ob->flag &= ~OB_DONE;
+ }
+
+ /* tag objects we're transforming */
+ for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) {
+ ob = ctx_ob->ptr.data;
+ ob->flag |= OB_DONE;
+ }
+
+ for (ctx_ob = ctx_data_list.first; ctx_ob; ctx_ob = ctx_ob->next) {
+ ob = ctx_ob->ptr.data;
+
+ if ((ob->parent && BKE_object_flag_test_recursive(ob->parent, OB_DONE)) == 0) {
+
float cursor_parent[3]; /* parent-relative */
if (use_offset) {
@@ -323,11 +376,11 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op)
}
sub_v3_v3(cursor_parent, ob->obmat[3]);
-
+
if (ob->parent) {
float originmat[3][3];
BKE_object_where_is_calc_ex(scene, NULL, ob, originmat);
-
+
invert_m3_m3(imat, originmat);
mul_m3_v3(imat, cursor_parent);
}
@@ -344,7 +397,8 @@ static int snap_sel_to_curs_exec(bContext *C, wmOperator *op)
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
}
- CTX_DATA_END;
+
+ BLI_freelistN(&ctx_data_list);
}
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
@@ -592,45 +646,60 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
/* ********************************************** */
-static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op))
+/* this could be exported to be a generic function
+ * see: calculateCenterActive */
+
+static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3])
{
Object *obedit = CTX_data_edit_object(C);
- Object *obact = CTX_data_active_object(C);
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- float *curs;
-
- curs = ED_view3d_cursor3d_get(scene, v3d);
if (obedit) {
- if (obedit->type == OB_MESH) {
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- /* check active */
- BMEditSelection ese;
-
- if (BM_select_history_active_get(em->bm, &ese)) {
- BM_editselection_center(&ese, curs);
- }
-
- mul_m4_v3(obedit->obmat, curs);
+ if (ED_object_editmode_calc_active_center(obedit, select_only, r_center)) {
+ mul_m4_v3(obedit->obmat, r_center);
+ return true;
}
- else if (obedit->type == OB_LATTICE) {
- BPoint *actbp = BKE_lattice_active_point_get(obedit->data);
+ }
+ else {
+ Object *ob = CTX_data_active_object(C);
- if (actbp) {
- copy_v3_v3(curs, actbp->vec);
- mul_m4_v3(obedit->obmat, curs);
+ if (ob) {
+ if (ob->mode & OB_MODE_POSE) {
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+ if (pchan) {
+ if (!select_only || (pchan->bone->flag & BONE_SELECTED)) {
+ copy_v3_v3(r_center, pchan->pose_head);
+ mul_m4_v3(ob->obmat, r_center);
+ return true;
+ }
+ }
+ }
+ else {
+ if (!select_only || (ob->flag & SELECT)) {
+ copy_v3_v3(r_center, ob->obmat[3]);
+ return true;
+ }
}
}
}
+
+ return false;
+}
+
+static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ float *curs;
+
+ curs = ED_view3d_cursor3d_get(scene, v3d);
+
+ if (snap_calc_active_center(C, false, curs)) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ return OPERATOR_FINISHED;
+ }
else {
- if (obact) {
- copy_v3_v3(curs, obact->obmat[3]);
- }
+ return OPERATOR_CANCELLED;
}
-
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
- return OPERATOR_FINISHED;
}
void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index 3f7f12d2020..af24a99a6f2 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -39,7 +39,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -118,7 +117,7 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
uiLayoutSetEnabled(pa->layout, false);
/* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */
- uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op);
+ UI_block_func_handle_set(block, ED_undo_operator_repeat_cb_evt, op);
view3d_panel_operator_redo_operator(C, pa, op);
}
@@ -151,20 +150,19 @@ static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
{
- GHashIterator *iter = WM_operatortype_iter();
+ GHashIterator iter;
- for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) {
- wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
+ for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
+ wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
if (BLI_strcasestr(ot->name, str)) {
if (WM_operator_poll((bContext *)C, ot)) {
- if (false == uiSearchItemAdd(items, ot->name, ot, 0))
+ if (false == UI_search_item_add(items, ot->name, ot, 0))
break;
}
}
}
- BLI_ghashIterator_free(iter);
}
@@ -180,18 +178,18 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
/* clear initial search string, then all items show */
search[0] = 0;
- block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
- uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_SEARCH_MENU);
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 15, uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 15, UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, 150, 19, 0, 0, "");
- uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb, NULL);
+ UI_but_func_search_set(but, operator_search_cb, arg_listbase, operator_call_cb, NULL);
- uiBoundsBlock(block, 6);
- uiBlockSetDirection(block, UI_DOWN);
- uiEndBlock(C, block);
+ UI_block_bounds_set_normal(block, 6);
+ UI_block_direction_set(block, UI_DIR_DOWN);
+ UI_block_end(C, block);
wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
@@ -218,7 +216,7 @@ static void view3d_panel_tool_shelf(const bContext *C, Panel *pa)
CustomTool *ct;
for (ct = st->toolshelf.first; ct; ct = ct->next) {
- if (0 == strncmp(context, ct->context, OP_MAX_TYPENAME)) {
+ if (STREQLEN(context, ct->context, OP_MAX_TYPENAME)) {
col = uiLayoutColumn(pa->layout, true);
uiItemFullO(col, ct->opname, NULL, ICON_NONE, NULL, WM_OP_INVOKE_REGION_WIN, 0);
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 858d001a381..4888c6846d2 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -37,9 +37,7 @@
#include "BLI_math.h"
#include "BLI_rect.h"
-#include "BLI_listbase.h"
#include "BLI_utildefines.h"
-#include "BLI_callbacks.h"
#include "BKE_anim.h"
#include "BKE_action.h"
@@ -55,7 +53,6 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
-#include "GPU_draw.h"
#include "GPU_select.h"
#include "WM_api.h"
@@ -64,14 +61,16 @@
#include "ED_screen.h"
#include "ED_armature.h"
-#include "RE_engine.h"
#ifdef WITH_GAMEENGINE
-#include "BL_System.h"
+# include "BLI_listbase.h"
+# include "BLI_callbacks.h"
+
+# include "GPU_draw.h"
+
+# include "BL_System.h"
#endif
-#include "RNA_access.h"
-#include "RNA_define.h"
#include "view3d_intern.h" /* own include */
@@ -356,6 +355,7 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w
view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
ED_view3d_camera_lock_sync(v3d, rv3d);
+ ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
}
if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
@@ -382,6 +382,10 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w
v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv;
ED_view3d_camera_lock_sync(v3d, rv3d);
+ if (ED_screen_animation_playing(CTX_wm_manager(C))) {
+ ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
+ }
+
}
if (rv3d->viewlock & RV3D_BOXVIEW)
@@ -492,26 +496,22 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
Object *camera_ob = v3d ? v3d->camera : scene->camera;
float r_co[3]; /* the new location to apply */
+ float r_scale; /* only for ortho cameras */
if (camera_ob == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active camera");
return OPERATOR_CANCELLED;
}
- else if (camera_ob->type != OB_CAMERA) {
- BKE_report(op->reports, RPT_ERROR, "Object not a camera");
- return OPERATOR_CANCELLED;
- }
- else if (((Camera *)camera_ob->data)->type == R_ORTHO) {
- BKE_report(op->reports, RPT_ERROR, "Orthographic cameras not supported");
- return OPERATOR_CANCELLED;
- }
/* this function does all the important stuff */
- if (BKE_camera_view_frame_fit_to_scene(scene, v3d, camera_ob, r_co)) {
-
+ if (BKE_camera_view_frame_fit_to_scene(scene, v3d, camera_ob, r_co, &r_scale)) {
ObjectTfmProtectedChannels obtfm;
float obmat_new[4][4];
+ if ((camera_ob->type == OB_CAMERA) && (((Camera *)camera_ob->data)->type == CAM_ORTHO)) {
+ ((Camera *)camera_ob->data)->ortho_scale = r_scale;
+ }
+
copy_m4_m4(obmat_new, camera_ob->obmat);
copy_v3_v3(obmat_new[3], r_co);
@@ -609,6 +609,20 @@ void VIEW3D_OT_object_as_camera(wmOperatorType *ot)
/* ********************************** */
+void ED_view3d_clipping_calc_from_boundbox(float clip[4][4], const BoundBox *bb, const bool is_flip)
+{
+ int val;
+
+ for (val = 0; val < 4; val++) {
+ normal_tri_v3(clip[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
+ if (UNLIKELY(is_flip)) {
+ negate_v3(clip[val]);
+ }
+
+ clip[val][3] = -dot_v3v3(clip[val], bb->vec[val]);
+ }
+}
+
void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, const rcti *rect)
{
float modelview[4][4];
@@ -644,16 +658,7 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co
((float *)modelview)[a] = mats->modelview[a];
flip_sign = is_negative_m4(modelview);
- /* then plane equations */
- for (val = 0; val < 4; val++) {
-
- normal_tri_v3(planes[val], bb->vec[val], bb->vec[val == 3 ? 0 : val + 1], bb->vec[val + 4]);
-
- if (flip_sign)
- negate_v3(planes[val]);
-
- planes[val][3] = -dot_v3v3(planes[val], bb->vec[val]);
- }
+ ED_view3d_clipping_calc_from_boundbox(planes, bb, flip_sign);
}
static bool view3d_boundbox_clip_m4(const BoundBox *bb, float persmatob[4][4])
@@ -891,6 +896,21 @@ char ED_view3d_lock_view_from_index(int index)
}
+char ED_view3d_axis_view_opposite(char view)
+{
+ switch (view) {
+ case RV3D_VIEW_FRONT: return RV3D_VIEW_BACK;
+ case RV3D_VIEW_BACK: return RV3D_VIEW_FRONT;
+ case RV3D_VIEW_LEFT: return RV3D_VIEW_RIGHT;
+ case RV3D_VIEW_RIGHT: return RV3D_VIEW_LEFT;
+ case RV3D_VIEW_TOP: return RV3D_VIEW_BOTTOM;
+ case RV3D_VIEW_BOTTOM: return RV3D_VIEW_TOP;
+ }
+
+ return RV3D_VIEW_USER;
+}
+
+
bool ED_view3d_lock(RegionView3D *rv3d)
{
return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->viewquat);
@@ -1543,18 +1563,22 @@ static void game_set_commmandline_options(GameData *gm)
static int game_engine_poll(bContext *C)
{
+ bScreen *screen;
/* we need a context and area to launch BGE
* it's a temporary solution to avoid crash at load time
* if we try to auto run the BGE. Ideally we want the
* context to be set as soon as we load the file. */
if (CTX_wm_window(C) == NULL) return 0;
- if (CTX_wm_screen(C) == NULL) return 0;
+ if ((screen = CTX_wm_screen(C)) == NULL) return 0;
if (CTX_wm_area(C) == NULL) return 0;
if (CTX_data_mode_enum(C) != CTX_MODE_OBJECT)
return 0;
+ if (!BKE_scene_uses_blender_game(screen->scene))
+ return 0;
+
return 1;
}
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index c54948b23c6..191eeb05c71 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -42,8 +42,6 @@
#include "BLF_translation.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
#include "BIF_gl.h"
@@ -152,6 +150,8 @@ void walk_modal_keymap(wmKeyConfig *keyconf)
{WALK_MODAL_JUMP, "JUMP", 0, "Jump", "Jump when in walk mode"},
{WALK_MODAL_JUMP_STOP, "JUMP_STOP", 0, "Jump Stop", "Stop pushing jump"},
+ {WALK_MODAL_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"},
+
{0, NULL, 0, NULL, NULL}};
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Walk Modal");
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 24499688835..061d00424b8 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -44,12 +44,14 @@
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h" /* PET modes */
+#include "BLI_alloca.h"
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BLI_rect.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_ghash.h"
+#include "BLI_memarena.h"
#include "BKE_nla.h"
#include "BKE_editmesh_bvh.h"
@@ -93,8 +95,8 @@
#define MAX_INFO_LEN 256
static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg);
-static int doEdgeSlide(TransInfo *t, float perc);
-static int doVertSlide(TransInfo *t, float perc);
+static void doEdgeSlide(TransInfo *t, float perc);
+static void doVertSlide(TransInfo *t, float perc);
static void drawEdgeSlide(const struct bContext *C, TransInfo *t);
static void drawVertSlide(const struct bContext *C, TransInfo *t);
@@ -138,6 +140,9 @@ static void applyCurveShrinkFatten(TransInfo *t, const int mval[2]);
static void initMaskShrinkFatten(TransInfo *t);
static void applyMaskShrinkFatten(TransInfo *t, const int mval[2]);
+static void initGPShrinkFatten(TransInfo *t);
+static void applyGPShrinkFatten(TransInfo *t, const int mval[2]);
+
static void initTrackball(TransInfo *t);
static void applyTrackball(TransInfo *t, const int mval[2]);
@@ -200,6 +205,12 @@ static bool transdata_check_local_center(TransInfo *t, short around)
);
}
+bool transdata_check_local_islands(TransInfo *t, short around)
+{
+ return ((around == V3D_LOCAL) && (
+ (t->obedit && ELEM(t->obedit->type, OB_MESH))));
+}
+
/* ************************** SPACE DEPENDANT CODE **************************** */
void setTransformViewMatrices(TransInfo *t)
@@ -579,7 +590,10 @@ void removeAspectRatio(TransInfo *t, float vec[2])
static void viewRedrawForce(const bContext *C, TransInfo *t)
{
- if (t->spacetype == SPACE_VIEW3D) {
+ if (t->options & CTX_GPENCIL_STROKES) {
+ WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
+ }
+ else if (t->spacetype == SPACE_VIEW3D) {
if (t->options & CTX_PAINT_CURVE) {
wmWindow *window = CTX_wm_window(C);
WM_paint_cursor_tag_redraw(window, t->ar);
@@ -662,8 +676,11 @@ static void viewRedrawPost(bContext *C, TransInfo *t)
WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
/* redraw UV editor */
- if (t->mode == TFM_EDGE_SLIDE && (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT))
+ if (ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE) &&
+ (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT))
+ {
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
+ }
/* XXX temp, first hack to get auto-render in compositor work (ton) */
WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM_DONE, CTX_data_scene(C));
@@ -960,6 +977,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
{
char cmode = constraintModeToChar(t);
bool handled = false;
+ const int modifiers_prev = t->modifiers;
t->redraw |= handleMouseInput(t, &t->mouse, event);
@@ -1125,47 +1143,22 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
break;
case TFM_MODAL_AXIS_X:
- if ((t->flag & T_NO_CONSTRAINT) == 0) {
- if (cmode == 'X') {
- stopConstraint(t);
- }
- else {
- if (t->flag & T_2D_EDIT) {
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0), IFACE_("along X"));
- }
- else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS0), IFACE_("along %s X"));
- }
- }
+ if (!(t->flag & T_NO_CONSTRAINT)) {
+ transform_event_xyz_constraint(t, XKEY, cmode);
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_AXIS_Y:
if ((t->flag & T_NO_CONSTRAINT) == 0) {
- if (cmode == 'Y') {
- stopConstraint(t);
- }
- else {
- if (t->flag & T_2D_EDIT) {
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1), IFACE_("along Y"));
- }
- else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS1), IFACE_("along %s Y"));
- }
- }
+ transform_event_xyz_constraint(t, YKEY, cmode);
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_AXIS_Z:
- if ((t->flag & (T_NO_CONSTRAINT | T_2D_EDIT)) == 0) {
- if (cmode == 'Z') {
- stopConstraint(t);
- }
- else {
- setUserConstraint(t, t->current_orientation, (CON_AXIS2), IFACE_("along %s Z"));
- }
+ if ((t->flag & (T_NO_CONSTRAINT)) == 0) {
+ transform_event_xyz_constraint(t, ZKEY, cmode);
t->redraw |= TREDRAW_HARD;
handled = true;
}
@@ -1511,6 +1504,13 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
}
+ /* if we change snap options, get the unsnapped values back */
+ if ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) !=
+ (modifiers_prev & (MOD_SNAP | MOD_SNAP_INVERT)))
+ {
+ applyMouseInput(t, &t->mouse, t->mval, t->values);
+ }
+
/* Per transform event, if present */
if (t->handleEvent &&
(!handled ||
@@ -1974,8 +1974,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
}
- if (RNA_struct_find_property(op->ptr, "proportional")) {
- RNA_enum_set(op->ptr, "proportional", proportional);
+ if ((prop = RNA_struct_find_property(op->ptr, "proportional"))) {
+ RNA_property_enum_set(op->ptr, prop, proportional);
RNA_enum_set(op->ptr, "proportional_edit_falloff", t->prop_mode);
RNA_float_set(op->ptr, "proportional_size", t->prop_size);
}
@@ -2032,6 +2032,12 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
options |= CTX_TEXTURE;
}
}
+
+ if ((prop = RNA_struct_find_property(op->ptr, "gpencil_strokes")) && RNA_property_is_set(op->ptr, prop)) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ options |= CTX_GPENCIL_STROKES;
+ }
+ }
t->options = options;
@@ -2163,6 +2169,9 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
case TFM_MASK_SHRINKFATTEN:
initMaskShrinkFatten(t);
break;
+ case TFM_GPENCIL_SHRINKFATTEN:
+ initGPShrinkFatten(t);
+ break;
case TFM_TRACKBALL:
initTrackball(t);
break;
@@ -2341,8 +2350,12 @@ int transformEnd(bContext *C, TransInfo *t)
/* handle restoring objects */
if (t->state == TRANS_CANCEL) {
/* exception, edge slide transformed UVs too */
- if (t->mode == TFM_EDGE_SLIDE)
+ if (t->mode == TFM_EDGE_SLIDE) {
doEdgeSlide(t, 0.0f);
+ }
+ else if (t->mode == TFM_VERT_SLIDE) {
+ doVertSlide(t, 0.0f);
+ }
exit_code = OPERATOR_CANCELLED;
restoreTransObjects(t); // calls recalcData()
@@ -3139,7 +3152,7 @@ static void initResize(TransInfo *t)
t->num.unit_type[2] = B_UNIT_NONE;
}
-static void headerResize(TransInfo *t, float vec[3], char str[MAX_INFO_LEN])
+static void headerResize(TransInfo *t, const float vec[3], char str[MAX_INFO_LEN])
{
char tvec[NUM_STR_REP_LEN * 3];
size_t ofs = 0;
@@ -3184,38 +3197,23 @@ static void headerResize(TransInfo *t, float vec[3], char str[MAX_INFO_LEN])
}
}
-/* FLT_EPSILON is too small [#29633], 0.0000001f starts to flip */
-#define TX_FLIP_EPS 0.00001f
-BLI_INLINE int tx_sign(const float a)
-{
- return (a < -TX_FLIP_EPS ? 1 : a > TX_FLIP_EPS ? 2 : 3);
-}
-BLI_INLINE int tx_vec_sign_flip(const float a[3], const float b[3])
-{
- return ((tx_sign(a[0]) & tx_sign(b[0])) == 0 ||
- (tx_sign(a[1]) & tx_sign(b[1])) == 0 ||
- (tx_sign(a[2]) & tx_sign(b[2])) == 0);
-}
-
-/* smat is reference matrix, only scaled */
+/**
+ * \a smat is reference matrix only.
+ *
+ * \note this is a tricky area, before making changes see: T29633, T42444
+ */
static void TransMat3ToSize(float mat[3][3], float smat[3][3], float size[3])
{
- float vec[3];
-
- copy_v3_v3(vec, mat[0]);
- size[0] = normalize_v3(vec);
- copy_v3_v3(vec, mat[1]);
- size[1] = normalize_v3(vec);
- copy_v3_v3(vec, mat[2]);
- size[2] = normalize_v3(vec);
-
+ float rmat[3][3];
+
+ mat3_to_rot_size(rmat, size, mat);
+
/* first tried with dotproduct... but the sign flip is crucial */
- if (tx_vec_sign_flip(mat[0], smat[0]) ) size[0] = -size[0];
- if (tx_vec_sign_flip(mat[1], smat[1]) ) size[1] = -size[1];
- if (tx_vec_sign_flip(mat[2], smat[2]) ) size[2] = -size[2];
+ if (dot_v3v3(rmat[0], smat[0]) < 0.0f) size[0] = -size[0];
+ if (dot_v3v3(rmat[1], smat[1]) < 0.0f) size[1] = -size[1];
+ if (dot_v3v3(rmat[2], smat[2]) < 0.0f) size[2] = -size[2];
}
-
static void ElementResize(TransInfo *t, TransData *td, float mat[3][3])
{
float tmat[3][3], smat[3][3], center[3];
@@ -4101,6 +4099,11 @@ static void initTranslation(TransInfo *t)
t->snap[1] = ED_node_grid_size() * NODE_GRID_STEPS;
t->snap[2] = ED_node_grid_size();
}
+ else if (t->spacetype == SPACE_IPO) {
+ t->snap[0] = 0.0f;
+ t->snap[1] = 1.0;
+ t->snap[2] = 0.1f;
+ }
else {
t->snap[0] = 0.0f;
t->snap[1] = t->snap[2] = 1.0f;
@@ -4122,7 +4125,7 @@ static void initTranslation(TransInfo *t)
}
}
-static void headerTranslation(TransInfo *t, float vec[3], char str[MAX_INFO_LEN])
+static void headerTranslation(TransInfo *t, const float vec[3], char str[MAX_INFO_LEN])
{
size_t ofs = 0;
char tvec[NUM_STR_REP_LEN * 3];
@@ -4215,7 +4218,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char str[MAX_INFO_LEN]
}
}
-static void applyTranslationValue(TransInfo *t, float vec[3])
+static void applyTranslationValue(TransInfo *t, const float vec[3])
{
TransData *td = t->data;
float tvec[3];
@@ -4227,29 +4230,21 @@ static void applyTranslationValue(TransInfo *t, float vec[3])
if (td->flag & TD_SKIP)
continue;
-
+
/* handle snapping rotation before doing the translation */
if (usingSnappingNormal(t)) {
if (validSnappingNormal(t)) {
const float *original_normal;
- float axis[3];
- float quat[4];
float mat[3][3];
- float angle;
/* In pose mode, we want to align normals with Y axis of bones... */
if (t->flag & T_POSE)
original_normal = td->axismtx[1];
else
original_normal = td->axismtx[2];
-
- cross_v3_v3v3(axis, original_normal, t->tsnap.snapNormal);
- angle = saacos(dot_v3v3(original_normal, t->tsnap.snapNormal));
-
- axis_angle_to_quat(quat, axis, angle);
-
- quat_to_mat3(mat, quat);
-
+
+ rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal);
+
ElementRotation(t, td, mat, V3D_LOCAL);
}
else {
@@ -4681,6 +4676,83 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
/* -------------------------------------------------------------------- */
+/* Transform (GPencil Shrink/Fatten) */
+
+/** \name Transform GPencil Strokes Shrink/Fatten
+ * \{ */
+
+static void initGPShrinkFatten(TransInfo *t)
+{
+ t->mode = TFM_GPENCIL_SHRINKFATTEN;
+ t->transform = applyGPShrinkFatten;
+
+ initMouseInputMode(t, &t->mouse, INPUT_SPRING);
+
+ t->idx_max = 0;
+ t->num.idx_max = 0;
+ t->snap[0] = 0.0f;
+ t->snap[1] = 0.1f;
+ t->snap[2] = t->snap[1] * 0.1f;
+
+ copy_v3_fl(t->num.val_inc, t->snap[1]);
+ t->num.unit_sys = t->scene->unit.system;
+ t->num.unit_type[0] = B_UNIT_NONE;
+
+ t->flag |= T_NO_ZERO;
+#ifdef USE_NUM_NO_ZERO
+ t->num.val_flag[0] |= NUM_NO_ZERO;
+#endif
+
+ t->flag |= T_NO_CONSTRAINT;
+}
+
+static void applyGPShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
+{
+ TransData *td = t->data;
+ float ratio;
+ int i;
+ char str[MAX_INFO_LEN];
+
+ ratio = t->values[0];
+
+ snapGridIncrement(t, &ratio);
+
+ applyNumInput(&t->num, &ratio);
+
+ /* header print for NumInput */
+ if (hasNumInput(&t->num)) {
+ char c[NUM_STR_REP_LEN];
+
+ outputNumInput(&(t->num), c, &t->scene->unit);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shrink/Fatten: %s"), c);
+ }
+ else {
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shrink/Fatten: %3f"), ratio);
+ }
+
+ for (i = 0; i < t->total; i++, td++) {
+ if (td->flag & TD_NOACTION)
+ break;
+
+ if (td->flag & TD_SKIP)
+ continue;
+
+ if (td->val) {
+ *td->val = td->ival * ratio;
+ /* apply PET */
+ *td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
+ if (*td->val <= 0.0f) *td->val = 0.001f;
+ }
+ }
+
+ recalcData(t);
+
+ ED_area_headerprint(t->sa, str);
+}
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
/* Transform (Push/Pull) */
/** \name Transform Push/Pull
@@ -4960,7 +5032,7 @@ static void initBoneSize(TransInfo *t)
t->num.unit_type[2] = B_UNIT_NONE;
}
-static void headerBoneSize(TransInfo *t, float vec[3], char str[MAX_INFO_LEN])
+static void headerBoneSize(TransInfo *t, const float vec[3], char str[MAX_INFO_LEN])
{
char tvec[NUM_STR_REP_LEN * 3];
if (hasNumInput(&t->num)) {
@@ -5130,6 +5202,220 @@ static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
}
/** \} */
+/* -------------------------------------------------------------------- */
+/* Original Data Store */
+
+/** \name Orig-Data Store Utility Functions
+ * \{ */
+
+static void slide_origdata_init_flag(
+ TransInfo *t, SlideOrigData *sod)
+{
+ BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
+ BMesh *bm = em->bm;
+
+ if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) &&
+ /* don't do this at all for non-basis shape keys, too easy to
+ * accidentally break uv maps or vertex colors then */
+ (bm->shapenr <= 1) &&
+ CustomData_has_math(&bm->ldata))
+ {
+ sod->use_origfaces = true;
+ }
+ else {
+ sod->use_origfaces = false;
+ }
+}
+
+static void slide_origdata_init_data(
+ TransInfo *t, SlideOrigData *sod)
+{
+ if (sod->use_origfaces) {
+ BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
+ BMesh *bm = em->bm;
+
+ sod->origfaces = BLI_ghash_ptr_new(__func__);
+ sod->bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default);
+ /* we need to have matching customdata */
+ BM_mesh_copy_init_customdata(sod->bm_origfaces, bm, NULL);
+ }
+}
+
+static void slide_origdata_create_data_vert(
+ BMesh *bm, SlideOrigData *sod,
+ TransDataGenericSlideVert *sv)
+{
+ BMIter liter;
+ int j, l_num;
+ float *loop_weights;
+
+ /* copy face data */
+ // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
+ BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v);
+ l_num = liter.count;
+ loop_weights = BLI_array_alloca(loop_weights, l_num);
+ for (j = 0; j < l_num; j++) {
+ BMLoop *l = BM_iter_step(&liter);
+ if (!BLI_ghash_haskey(sod->origfaces, l->f)) {
+ BMFace *f_copy = BM_face_copy(sod->bm_origfaces, bm, l->f, true, true);
+ BLI_ghash_insert(sod->origfaces, l->f, f_copy);
+ }
+ loop_weights[j] = BM_loop_calc_face_angle(l);
+ }
+
+ /* store cd_loop_groups */
+ if (l_num != 0) {
+ sv->cd_loop_groups = BLI_memarena_alloc(sod->arena, sod->layer_math_map_num * sizeof(void *));
+ for (j = 0; j < sod->layer_math_map_num; j++) {
+ const int layer_nr = sod->layer_math_map[j];
+ sv->cd_loop_groups[j] = BM_vert_loop_groups_data_layer_create(bm, sv->v, layer_nr, loop_weights, sod->arena);
+ }
+ }
+ else {
+ sv->cd_loop_groups = NULL;
+ }
+
+ BLI_ghash_insert(sod->origverts, sv->v, sv);
+}
+
+static void slide_origdata_create_data(
+ TransInfo *t, SlideOrigData *sod,
+ TransDataGenericSlideVert *sv, unsigned int v_stride, unsigned int v_num)
+{
+ if (sod->use_origfaces) {
+ BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
+ BMesh *bm = em->bm;
+ unsigned int i;
+
+ int layer_index_dst;
+ int j;
+
+ /* over alloc, only 'math' layers are indexed */
+ sod->layer_math_map = MEM_mallocN(bm->ldata.totlayer * sizeof(int), __func__);
+ layer_index_dst = 0;
+ for (j = 0; j < bm->ldata.totlayer; j++) {
+ if (CustomData_layer_has_math(&bm->ldata, j)) {
+ sod->layer_math_map[layer_index_dst++] = j;
+ }
+ }
+ BLI_assert(layer_index_dst != 0);
+ sod->layer_math_map_num = layer_index_dst;
+
+ sod->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
+ sod->origverts = BLI_ghash_ptr_new_ex(__func__, v_num);
+
+ for (i = 0; i < v_num; i++, sv = POINTER_OFFSET(sv, v_stride)) {
+ slide_origdata_create_data_vert(bm, sod, sv);
+ }
+ }
+}
+
+/**
+ * If we're sliding the vert, return its original location, if not, the current location is good.
+ */
+static const float *slide_origdata_orig_vert_co(SlideOrigData *sod, BMVert *v)
+{
+ TransDataGenericSlideVert *sv = BLI_ghash_lookup(sod->origverts, v);
+ return sv ? sv->co_orig_3d : v->co;
+}
+
+static void slide_origdata_interp_data_vert(
+ SlideOrigData *sod, BMesh *bm, bool is_final,
+ TransDataGenericSlideVert *sv)
+{
+ BMIter liter;
+ int j, l_num;
+ float *loop_weights;
+ const bool do_loop_weight = (len_squared_v3v3(sv->v->co, sv->co_orig_3d) > FLT_EPSILON);
+
+ // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
+ BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, sv->v);
+ l_num = liter.count;
+ loop_weights = do_loop_weight ? BLI_array_alloca(loop_weights, l_num) : NULL;
+ for (j = 0; j < l_num; j++) {
+ BMFace *f_copy; /* the copy of 'f' */
+ BMLoop *l = BM_iter_step(&liter);
+
+ f_copy = BLI_ghash_lookup(sod->origfaces, l->f);
+
+ /* only loop data, no vertex data since that contains shape keys,
+ * and we do not want to mess up other shape keys */
+ BM_loop_interp_from_face(bm, l, f_copy, false, is_final);
+
+ /* make sure face-attributes are correct (e.g. MTexPoly) */
+ BM_elem_attrs_copy(sod->bm_origfaces, bm, f_copy, l->f);
+
+ /* weight the loop */
+ if (do_loop_weight) {
+ const float *v_prev = slide_origdata_orig_vert_co(sod, l->prev->v);
+ const float *v_next = slide_origdata_orig_vert_co(sod, l->next->v);
+ const float dist = dist_signed_squared_to_corner_v3v3v3(sv->v->co, v_prev, sv->co_orig_3d, v_next, f_copy->no);
+ const float eps = 0.00001f;
+ loop_weights[j] = (dist >= 0.0f) ? 1.0f : ((dist <= -eps) ? 0.0f : (1.0f + (dist / eps)));
+ }
+ }
+
+ if (do_loop_weight) {
+ for (j = 0; j < sod->layer_math_map_num; j++) {
+ BM_vert_loop_groups_data_layer_merge_weights(bm, sv->cd_loop_groups[j], sod->layer_math_map[j], loop_weights);
+ }
+ }
+ else {
+ for (j = 0; j < sod->layer_math_map_num; j++) {
+ BM_vert_loop_groups_data_layer_merge(bm, sv->cd_loop_groups[j], sod->layer_math_map[j]);
+ }
+ }
+}
+
+static void slide_origdata_interp_data(
+ TransInfo *t, SlideOrigData *sod,
+ TransDataGenericSlideVert *sv, unsigned int v_stride, unsigned int v_num,
+ bool is_final)
+{
+ if (sod->use_origfaces) {
+ BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
+ BMesh *bm = em->bm;
+ unsigned int i;
+
+ for (i = 0; i < v_num; i++, sv = POINTER_OFFSET(sv, v_stride)) {
+
+ if (sv->cd_loop_groups) {
+ slide_origdata_interp_data_vert(sod, bm, is_final, sv);
+ }
+ }
+ }
+}
+
+static void slide_origdata_free_date(
+ SlideOrigData *sod)
+{
+ if (sod->use_origfaces) {
+ if (sod->bm_origfaces) {
+ BM_mesh_free(sod->bm_origfaces);
+ sod->bm_origfaces = NULL;
+ }
+
+ if (sod->origfaces) {
+ BLI_ghash_free(sod->origfaces, NULL, NULL);
+ sod->origfaces = NULL;
+ }
+
+ if (sod->origverts) {
+ BLI_ghash_free(sod->origverts, NULL, NULL);
+ sod->origverts = NULL;
+ }
+
+ if (sod->arena) {
+ BLI_memarena_free(sod->arena);
+ sod->arena = NULL;
+ }
+
+ MEM_SAFE_FREE(sod->layer_math_map);
+ }
+}
+
+/** \} */
/* -------------------------------------------------------------------- */
/* Transform (Edge Slide) */
@@ -5388,16 +5674,7 @@ static bool createEdgeSlideVerts(TransInfo *t)
rv3d = t->ar ? t->ar->regiondata : NULL;
}
- if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) &&
- /* don't do this at all for non-basis shape keys, too easy to
- * accidentally break uv maps or vertex colors then */
- (bm->shapenr <= 1))
- {
- sld->use_origfaces = true;
- }
- else {
- sld->use_origfaces = false;
- }
+ slide_origdata_init_flag(t, &sld->orig_data);
sld->is_proportional = true;
sld->curr_sv_index = 0;
@@ -5789,30 +6066,12 @@ static bool createEdgeSlideVerts(TransInfo *t)
}
bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
-
- if (sld->use_origfaces) {
- sld->origfaces = BLI_ghash_ptr_new(__func__);
- sld->bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default);
- /* we need to have matching customdata */
- BM_mesh_copy_init_customdata(sld->bm_origfaces, bm, NULL);
- }
+ slide_origdata_init_data(t, &sld->orig_data);
+ slide_origdata_create_data(t, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
/*create copies of faces for customdata projection*/
sv_array = sld->sv;
for (i = 0; i < sld->totsv; i++, sv_array++) {
- BMIter fiter;
- BMFace *f;
-
-
- if (sld->use_origfaces) {
- BM_ITER_ELEM (f, &fiter, sv_array->v, BM_FACES_OF_VERT) {
- if (!BLI_ghash_haskey(sld->origfaces, f)) {
- BMFace *f_copy = BM_face_copy(sld->bm_origfaces, bm, f, true, true);
- BLI_ghash_insert(sld->origfaces, f, f_copy);
- }
- }
- }
-
/* switch a/b if loop direction is different from global direction */
l_nr = sv_array->loop_nr;
if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) {
@@ -5856,172 +6115,27 @@ static bool createEdgeSlideVerts(TransInfo *t)
void projectEdgeSlideData(TransInfo *t, bool is_final)
{
EdgeSlideData *sld = t->customData;
- TransDataEdgeSlideVert *sv;
- BMEditMesh *em = sld->em;
- int i;
+ SlideOrigData *sod = &sld->orig_data;
- if (sld->use_origfaces == false) {
+ if (sod->use_origfaces == false) {
return;
}
- for (i = 0, sv = sld->sv; i < sld->totsv; sv++, i++) {
- BMIter fiter;
- BMLoop *l;
-
- BM_ITER_ELEM (l, &fiter, sv->v, BM_LOOPS_OF_VERT) {
- BMFace *f_copy; /* the copy of 'f' */
- BMFace *f_copy_flip; /* the copy of 'f' or detect if we need to flip to the shorter side. */
-
- f_copy = BLI_ghash_lookup(sld->origfaces, l->f);
-
- /* project onto copied projection face */
- f_copy_flip = f_copy;
-
- if (BM_elem_flag_test(l->e, BM_ELEM_SELECT) || BM_elem_flag_test(l->prev->e, BM_ELEM_SELECT)) {
- /* the loop is attached of the selected edges that are sliding */
- BMLoop *l_ed_sel = l;
-
- if (!BM_elem_flag_test(l->e, BM_ELEM_SELECT))
- l_ed_sel = l_ed_sel->prev;
-
- if (sld->perc < 0.0f) {
- if (BM_vert_in_face(l_ed_sel->radial_next->f, sv->v_b)) {
- f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f);
- }
- }
- else if (sld->perc > 0.0f) {
- if (BM_vert_in_face(l_ed_sel->radial_next->f, sv->v_a)) {
- f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f);
- }
- }
-
- BLI_assert(f_copy_flip != NULL);
- if (!f_copy_flip) {
- continue; /* shouldn't happen, but protection */
- }
- }
- else {
- /* the loop is attached to only one vertex and not a selected edge,
- * this means we have to find a selected edges face going in the right direction
- * to copy from else we get bad distortion see: [#31080] */
- BMIter eiter;
- BMEdge *e_sel;
-
- BLI_assert(l->v == sv->v);
- BM_ITER_ELEM (e_sel, &eiter, sv->v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(e_sel, BM_ELEM_SELECT)) {
- break;
- }
- }
-
- if (e_sel) {
- /* warning if the UV's are not contiguous, this will copy from the _wrong_ UVs
- * in fact whenever the face being copied is not 'f_copy' this can happen,
- * we could be a lot smarter about this but would need to deal with every UV channel or
- * add a way to mask out lauers when calling #BM_loop_interp_from_face() */
-
- /*
- * + +----------------+
- * \ | |
- * (this) l_adj| |
- * \ | |
- * \| e_sel |
- * +----------+----------------+ <- the edge we are sliding.
- * /|sv->v |
- * / | |
- * (or) l_adj| |
- * / | |
- * + +----------------+
- * (above)
- * 'other connected loops', attached to sv->v slide faces.
- *
- * NOTE: The faces connected to the edge may not have contiguous UV's
- * so step around the loops to find l_adj.
- * However if the 'other loops' are not cotiguous it will still give problems.
- *
- * A full solution to this would have to store
- * per-customdata-layer map of which loops are contiguous
- * and take this into account when interpolating.
- *
- * NOTE: If l_adj's edge isnt manifold then use then
- * interpolate the loop from its own face.
- * Can happen when 'other connected loops' are disconnected from the face-fan.
- */
-
- BMLoop *l_adj = NULL;
- if (sld->perc < 0.0f) {
- if (BM_vert_in_face(e_sel->l->f, sv->v_b)) {
- l_adj = e_sel->l;
- }
- else if (BM_vert_in_face(e_sel->l->radial_next->f, sv->v_b)) {
- l_adj = e_sel->l->radial_next;
- }
- }
- else if (sld->perc > 0.0f) {
- if (BM_vert_in_face(e_sel->l->f, sv->v_a)) {
- l_adj = e_sel->l;
- }
- else if (BM_vert_in_face(e_sel->l->radial_next->f, sv->v_a)) {
- l_adj = e_sel->l->radial_next;
- }
- }
-
- /* step across to the face */
- if (l_adj) {
- l_adj = BM_loop_other_edge_loop(l_adj, sv->v);
- if (!BM_edge_is_boundary(l_adj->e)) {
- l_adj = l_adj->radial_next;
- }
- else {
- /* disconnected face-fan, fallback to self */
- l_adj = l;
- }
-
- f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_adj->f);
- }
- }
- }
-
- /* only loop data, no vertex data since that contains shape keys,
- * and we do not want to mess up other shape keys */
- BM_loop_interp_from_face(em->bm, l, f_copy_flip, false, false);
-
- if (is_final) {
- BM_loop_interp_multires(em->bm, l, f_copy_flip);
- if (f_copy != f_copy_flip) {
- BM_loop_interp_multires(em->bm, l, f_copy);
- }
- }
-
- /* make sure face-attributes are correct (e.g. MTexPoly) */
- BM_elem_attrs_copy(sld->bm_origfaces, em->bm, f_copy, l->f);
- }
- }
+ slide_origdata_interp_data(t, sod, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv, is_final);
}
void freeEdgeSlideTempFaces(EdgeSlideData *sld)
{
- if (sld->use_origfaces) {
- if (sld->bm_origfaces) {
- BM_mesh_free(sld->bm_origfaces);
- sld->bm_origfaces = NULL;
- }
-
- if (sld->origfaces) {
- BLI_ghash_free(sld->origfaces, NULL, NULL);
- sld->origfaces = NULL;
- }
- }
+ slide_origdata_free_date(&sld->orig_data);
}
-
void freeEdgeSlideVerts(TransInfo *t)
{
EdgeSlideData *sld = t->customData;
if (!sld)
return;
-
+
freeEdgeSlideTempFaces(sld);
bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
@@ -6195,7 +6309,7 @@ static void drawEdgeSlide(const struct bContext *C, TransInfo *t)
}
}
-static int doEdgeSlide(TransInfo *t, float perc)
+static void doEdgeSlide(TransInfo *t, float perc)
{
EdgeSlideData *sld = t->customData;
TransDataEdgeSlideVert *svlist = sld->sv, *sv;
@@ -6252,8 +6366,6 @@ static int doEdgeSlide(TransInfo *t, float perc)
}
projectEdgeSlideData(t, 0);
-
- return 1;
}
static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
@@ -6418,6 +6530,8 @@ static bool createVertSlideVerts(TransInfo *t)
rv3d = ar ? ar->regiondata : NULL;
}
+ slide_origdata_init_flag(t, &sld->orig_data);
+
sld->is_proportional = true;
sld->curr_sv_index = 0;
sld->flipped_vtx = false;
@@ -6513,6 +6627,10 @@ static bool createVertSlideVerts(TransInfo *t)
sld->sv = sv_array;
sld->totsv = j;
+ bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+ slide_origdata_init_data(t, &sld->orig_data);
+ slide_origdata_create_data(t, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv);
+
sld->em = em;
sld->perc = 0.0f;
@@ -6527,6 +6645,23 @@ static bool createVertSlideVerts(TransInfo *t)
return true;
}
+void projectVertSlideData(TransInfo *t, bool is_final)
+{
+ VertSlideData *sld = t->customData;
+ SlideOrigData *sod = &sld->orig_data;
+
+ if (sod->use_origfaces == false) {
+ return;
+ }
+
+ slide_origdata_interp_data(t, sod, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv, is_final);
+}
+
+void freeVertSlideTempFaces(VertSlideData *sld)
+{
+ slide_origdata_free_date(&sld->orig_data);
+}
+
void freeVertSlideVerts(TransInfo *t)
{
VertSlideData *sld = t->customData;
@@ -6534,6 +6669,9 @@ void freeVertSlideVerts(TransInfo *t)
if (!sld)
return;
+ freeVertSlideTempFaces(sld);
+
+ bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
if (sld->totsv > 0) {
TransDataVertSlideVert *sv = sld->sv;
@@ -6643,7 +6781,7 @@ static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEven
#endif
case MOUSEMOVE:
{
- /* don't recalculat the best edge */
+ /* don't recalculate the best edge */
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
if (is_clamp) {
calcVertSlideMouseActiveEdges(t, event->mval);
@@ -6730,7 +6868,7 @@ static void drawVertSlide(const struct bContext *C, TransInfo *t)
}
}
-static int doVertSlide(TransInfo *t, float perc)
+static void doVertSlide(TransInfo *t, float perc)
{
VertSlideData *sld = t->customData;
TransDataVertSlideVert *svlist = sld->sv, *sv;
@@ -6770,7 +6908,7 @@ static int doVertSlide(TransInfo *t, float perc)
}
}
- return 1;
+ projectVertSlideData(t, false);
}
static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
@@ -7145,7 +7283,7 @@ static void initSeqSlide(TransInfo *t)
t->num.unit_type[1] = B_UNIT_NONE;
}
-static void headerSeqSlide(TransInfo *t, float val[2], char str[MAX_INFO_LEN])
+static void headerSeqSlide(TransInfo *t, const float val[2], char str[MAX_INFO_LEN])
{
char tvec[NUM_STR_REP_LEN * 3];
size_t ofs = 0;
@@ -7169,10 +7307,11 @@ static void headerSeqSlide(TransInfo *t, float val[2], char str[MAX_INFO_LEN])
WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0));
}
-static void applySeqSlideValue(TransInfo *t, const float val[2])
+static void applySeqSlideValue(TransInfo *t, const float val[2], int frame)
{
TransData *td = t->data;
int i;
+ TransSeq *ts = t->customData;
for (i = 0; i < t->total; i++, td++) {
float tvec[2];
@@ -7187,15 +7326,21 @@ static void applySeqSlideValue(TransInfo *t, const float val[2])
mul_v2_fl(tvec, td->factor);
- td->loc[0] = td->iloc[0] + tvec[0];
+ if (t->modifiers & MOD_SNAP_INVERT) {
+ td->loc[0] = frame + td->factor * (td->iloc[0] - ts->min);
+ }
+ else {
+ td->loc[0] = td->iloc[0] + tvec[0];
+ }
+
td->loc[1] = td->iloc[1] + tvec[1];
}
}
-static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2]))
+static void applySeqSlide(TransInfo *t, const int mval[2])
{
char str[MAX_INFO_LEN];
-
+ int snap_frame = 0;
if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f};
float tvec[3];
@@ -7203,7 +7348,8 @@ static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2]))
copy_v3_v3(t->values, tvec);
}
else {
- snapGridIncrement(t, t->values);
+ snap_frame = snapSequenceBounds(t, mval);
+ // snapGridIncrement(t, t->values);
applyNumInput(&t->num, t->values);
}
@@ -7211,7 +7357,7 @@ static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2]))
t->values[1] = floor(t->values[1] + 0.5f);
headerSeqSlide(t, t->values, str);
- applySeqSlideValue(t, t->values);
+ applySeqSlideValue(t, t->values, snap_frame);
recalcData(t);
@@ -7536,7 +7682,7 @@ static void initTimeSlide(TransInfo *t)
t->num.unit_type[0] = B_UNIT_NONE;
}
-static void headerTimeSlide(TransInfo *t, float sval, char str[MAX_INFO_LEN])
+static void headerTimeSlide(TransInfo *t, const float sval, char str[MAX_INFO_LEN])
{
char tvec[NUM_STR_REP_LEN * 3];
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 67d55639528..8d6c693b14a 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -173,6 +173,13 @@ typedef struct TransDataSeq {
} TransDataSeq;
+typedef struct TransSeq {
+ TransDataSeq *tdseq;
+ int min;
+ int max;
+ bool snap_left;
+} TransSeq;
+
/* for NLA transform (stored in td->extra pointer) */
typedef struct TransDataNla {
ID *id; /* ID-block NLA-data is attached to */
@@ -193,31 +200,55 @@ typedef struct TransDataNla {
struct LinkNode;
struct GHash;
+/* header of TransDataEdgeSlideVert, TransDataEdgeSlideEdge */
+typedef struct TransDataGenericSlideVert {
+ struct BMVert *v;
+ struct LinkNode **cd_loop_groups;
+ float co_orig_3d[3];
+} TransDataGenericSlideVert;
+
typedef struct TransDataEdgeSlideVert {
- struct BMVert *v_a, *v_b;
+ /* TransDataGenericSlideVert */
struct BMVert *v;
+ struct LinkNode **cd_loop_groups;
float v_co_orig[3];
+ /* end generic */
float edge_len;
+ struct BMVert *v_a, *v_b;
+
/* add origvert.co to get the original locations */
float dir_a[3], dir_b[3];
int loop_nr;
} TransDataEdgeSlideVert;
+
+/* store original data so we can correct UV's and similar when sliding */
+typedef struct SlideOrigData {
+ /* flag that is set when origfaces is initialized */
+ bool use_origfaces;
+ struct GHash *origverts; /* map {BMVert: TransDataGenericSlideVert} */
+ struct GHash *origfaces;
+ struct BMesh *bm_origfaces;
+
+ struct MemArena *arena;
+ /* number of math BMLoop layers */
+ int layer_math_map_num;
+ /* array size of 'layer_math_map_num'
+ * maps TransDataVertSlideVert.cd_group index to absolute CustomData layer index */
+ int *layer_math_map;
+} SlideOrigData;
+
typedef struct EdgeSlideData {
TransDataEdgeSlideVert *sv;
int totsv;
-
- struct GHash *origfaces;
int mval_start[2], mval_end[2];
struct BMEditMesh *em;
- /* flag that is set when origfaces is initialized */
- bool use_origfaces;
- struct BMesh *bm_origfaces;
+ SlideOrigData orig_data;
float perc;
@@ -229,8 +260,12 @@ typedef struct EdgeSlideData {
typedef struct TransDataVertSlideVert {
+ /* TransDataGenericSlideVert */
BMVert *v;
+ struct LinkNode **cd_loop_groups;
float co_orig_3d[3];
+ /* end generic */
+
float co_orig_2d[2];
float (*co_link_orig_3d)[3];
float (*co_link_orig_2d)[2];
@@ -244,6 +279,8 @@ typedef struct VertSlideData {
struct BMEditMesh *em;
+ SlideOrigData orig_data;
+
float perc;
bool is_proportional;
@@ -545,6 +582,7 @@ void special_aftertrans_update(struct bContext *C, TransInfo *t);
int special_transform_moving(TransInfo *t);
void transform_autoik_update(TransInfo *t, short mode);
+bool transdata_check_local_islands(TransInfo *t, short around);
int count_set_pose_transflags(int *out_mode, short around, struct Object *ob);
@@ -588,6 +626,8 @@ typedef enum {
void snapGridIncrement(TransInfo *t, float *val);
void snapGridIncrementAction(TransInfo *t, float *val, GearsType action);
+int snapSequenceBounds(TransInfo *t, const int mval[2]);
+
bool activeSnap(TransInfo *t);
bool validSnap(TransInfo *t);
@@ -689,7 +729,9 @@ void freeEdgeSlideTempFaces(EdgeSlideData *sld);
void freeEdgeSlideVerts(TransInfo *t);
void projectEdgeSlideData(TransInfo *t, bool is_final);
+void freeVertSlideTempFaces(VertSlideData *sld);
void freeVertSlideVerts(TransInfo *t);
+void projectVertSlideData(TransInfo *t, bool is_final);
/* TODO. transform_queries.c */
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index d8f17315c01..ccb81c7342b 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -208,7 +208,7 @@ static void axisProjection(TransInfo *t, const float axis[3], const float in[3],
viewAxisCorrectCenter(t, t_con_center);
angle = fabsf(angle_v3v3(axis, t->viewinv[2]));
- if (angle > (float)M_PI / 2.0f) {
+ if (angle > (float)M_PI_2) {
angle = (float)M_PI - angle;
}
angle = RAD2DEGF(angle);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 16c4a87b763..b50f56aae3e 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -54,7 +54,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_smallhash.h"
#include "BLI_listbase.h"
#include "BLI_linklist_stack.h"
#include "BLI_string.h"
@@ -90,7 +89,6 @@
#include "BKE_editmesh.h"
#include "BKE_tracking.h"
#include "BKE_mask.h"
-#include "BKE_lattice.h"
#include "BIK_api.h"
@@ -107,6 +105,7 @@
#include "ED_uvedit.h"
#include "ED_clip.h"
#include "ED_mask.h"
+#include "ED_gpencil.h"
#include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */
#include "WM_types.h"
@@ -218,6 +217,9 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
float _proj_vec[3];
const float *proj_vec = NULL;
+ /* support for face-islands */
+ const bool use_island = transdata_check_local_islands(t, t->around);
+
if (t->flag & T_PROP_PROJECTED) {
if (t->spacetype == SPACE_VIEW3D && t->ar && t->ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = t->ar->regiondata;
@@ -239,7 +241,12 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
for (i = 0, td = t->data; i < t->total; i++, td++) {
if (td->flag & TD_SELECTED) {
- sub_v3_v3v3(vec, tob->center, td->center);
+ if (use_island) {
+ sub_v3_v3v3(vec, tob->iloc, td->iloc);
+ }
+ else {
+ sub_v3_v3v3(vec, tob->center, td->center);
+ }
mul_m3_v3(tob->mtx, vec);
if (proj_vec) {
@@ -251,6 +258,10 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
dist_sq = len_squared_v3(vec);
if ((tob->rdist == -1.0f) || (dist_sq < SQUARE(tob->rdist))) {
tob->rdist = sqrtf(dist_sq);
+ if (use_island) {
+ copy_v3_v3(tob->center, td->center);
+ copy_m3_m3(tob->axismtx, td->axismtx);
+ }
}
}
else {
@@ -2167,6 +2178,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx
BMEditMesh *em, BMVert *eve, float *bweight,
struct TransIslandData *v_island)
{
+ float *no, _no[3];
BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0);
td->flag = 0;
@@ -2176,19 +2188,30 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx
td->loc = eve->co;
copy_v3_v3(td->iloc, td->loc);
+ if ((t->mode == TFM_SHRINKFATTEN) &&
+ (em->selectmode & SCE_SELECT_FACE) &&
+ BM_elem_flag_test(eve, BM_ELEM_SELECT) &&
+ (BM_vert_normal_update_ex(eve, BM_ELEM_SELECT, _no)))
+ {
+ no = _no;
+ }
+ else {
+ no = eve->no;
+ }
+
if (v_island) {
copy_v3_v3(td->center, v_island->co);
copy_m3_m3(td->axismtx, v_island->axismtx);
}
else if (t->around == V3D_LOCAL) {
copy_v3_v3(td->center, td->loc);
- createSpaceNormal(td->axismtx, eve->no);
+ createSpaceNormal(td->axismtx, no);
}
else {
copy_v3_v3(td->center, td->loc);
/* Setting normals */
- copy_v3_v3(td->axismtx[2], eve->no);
+ copy_v3_v3(td->axismtx[2], no);
td->axismtx[0][0] =
td->axismtx[0][1] =
td->axismtx[0][2] =
@@ -2217,7 +2240,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx
}
else if (t->mode == TFM_SHRINKFATTEN) {
td->ext = tx;
- tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, BM_ELEM_SELECT);
+ tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, no, BM_ELEM_SELECT);
}
}
@@ -2636,7 +2659,7 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f
/* uv coords are scaled by aspects. this is needed for rotations and
* proportional editing to be consistent with the stretched uv coords
* that are displayed. this also means that for display and numinput,
- * and when the the uv coords are flushed, these are converted each time */
+ * and when the uv coords are flushed, these are converted each time */
td2d->loc[0] = uv[0] * aspx;
td2d->loc[1] = uv[1] * aspy;
td2d->loc[2] = 0.0f;
@@ -2794,8 +2817,8 @@ void flushTransUVs(TransInfo *t)
td->loc2d[1] = td->loc[1] * invy;
if ((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) {
- td->loc2d[0] = floorf(width * td->loc2d[0] + 0.5f) / width;
- td->loc2d[1] = floorf(height * td->loc2d[1] + 0.5f) / height;
+ td->loc2d[0] = roundf(width * td->loc2d[0]) / width;
+ td->loc2d[1] = roundf(height * td->loc2d[1]) / height;
}
}
}
@@ -3138,7 +3161,7 @@ static void posttrans_gpd_clean(bGPdata *gpd)
bGPDframe *gpf, *gpfn;
bool is_double = false;
- BLI_sortlist_r(&gpl->frames, &is_double, gpf_cmp_frame);
+ BLI_listbase_sort_r(&gpl->frames, &is_double, gpf_cmp_frame);
if (is_double) {
for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
@@ -3165,7 +3188,7 @@ static void posttrans_mask_clean(Mask *mask)
MaskLayerShape *masklay_shape, *masklay_shape_next;
bool is_double = false;
- BLI_sortlist_r(&masklay->splines_shapes, &is_double, masklay_shape_cmp_frame);
+ BLI_listbase_sort_r(&masklay->splines_shapes, &is_double, masklay_shape_cmp_frame);
if (is_double) {
for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_next) {
@@ -3757,7 +3780,6 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
BezTriple *bezt;
int count = 0, i;
- float cfra;
float mtx[3][3], smtx[3][3];
const bool is_translation_mode = graph_edit_is_translation_mode(t);
const bool use_handle = !(sipo->flag & SIPO_NOHANDLES);
@@ -3792,7 +3814,12 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
-
+ float cfra;
+
+ /* F-Curve may not have any keyframes */
+ if (fcu->bezt == NULL)
+ continue;
+
/* convert current-frame to action-time (slightly less accurate, especially under
* higher scaling ratios, but is faster than converting all points)
*/
@@ -3800,45 +3827,27 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
else
cfra = (float)CFRA;
-
- /* F-Curve may not have any keyframes */
- if (fcu->bezt == NULL)
- continue;
-
+
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse */
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
- const bool sel2 = bezt->f2 & SELECT;
- const bool sel1 = use_handle ? bezt->f1 & SELECT : sel2;
- const bool sel3 = use_handle ? bezt->f3 & SELECT : sel2;
-
- if (is_translation_mode) {
- /* for 'normal' pivots - just include anything that is selected.
- * this works a bit differently in translation modes */
- if (sel2) {
+ const bool sel2 = (bezt->f2 & SELECT) != 0;
+ const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
+ const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
+
+ if (!is_translation_mode || !(sel2)) {
+ if (sel1) {
count++;
}
- else {
- if (sel1) count++;
- if (sel3) count++;
- }
- }
- else if (use_local_center) {
- /* for local-pivot we only need to count the number of selected handles only,
- * so that centerpoints don't get moved wrong
- */
- if (bezt->ipo == BEZT_IPO_BEZ) {
- if (sel1) count++;
- if (sel3) count++;
+
+ if (sel3) {
+ count++;
}
- /* else if (sel2) count++; // TODO: could this cause problems? */
- /* - yes this causes problems, because no td is created for the center point */
}
- else {
- /* for 'normal' pivots - just include anything that is selected */
- if (sel1) count++;
- if (sel2) count++;
- if (sel3) count++;
+
+ /* only include main vert if selected */
+ if (sel2 && !use_local_center) {
+ count++;
}
}
}
@@ -3887,8 +3896,13 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
- bool intvals = (fcu->flag & FCURVE_INT_VALUES);
+ bool intvals = (fcu->flag & FCURVE_INT_VALUES) != 0;
float unit_scale;
+ float cfra;
+
+ /* F-Curve may not have any keyframes */
+ if (fcu->bezt == NULL)
+ continue;
/* convert current-frame to action-time (slightly less accurate, especially under
* higher scaling ratios, but is faster than converting all points)
@@ -3897,19 +3911,15 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
else
cfra = (float)CFRA;
-
- /* F-Curve may not have any keyframes */
- if (fcu->bezt == NULL)
- continue;
-
+
unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, anim_map_flag);
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse (if applicable) */
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
- const bool sel2 = bezt->f2 & SELECT;
- const bool sel1 = use_handle ? bezt->f1 & SELECT : sel2;
- const bool sel3 = use_handle ? bezt->f3 & SELECT : sel2;
+ const bool sel2 = (bezt->f2 & SELECT) != 0;
+ const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
+ const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
TransDataCurveHandleFlags *hdata = NULL;
/* short h1=1, h2=1; */ /* UNUSED */
@@ -4516,10 +4526,47 @@ static int SeqToTransData_Recursive(TransInfo *t, ListBase *seqbase, TransData *
}
}
}
-
return tot;
}
+
+static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts)
+{
+ Sequence *seq;
+ int recursive, count, flag;
+ int max = INT32_MIN, min = INT32_MAX;
+
+ for (seq = seqbase->first; seq; seq = seq->next) {
+
+ /* just to get the flag since there are corner cases where this isn't totally obvious */
+ SeqTransInfo(t, seq, &recursive, &count, &flag);
+
+ /* use 'flag' which is derived from seq->flag but modified for special cases */
+ if (flag & SELECT) {
+ if (flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) {
+ if (flag & SEQ_LEFTSEL) {
+ min = min_ii(seq->startdisp, min);
+ max = max_ii(seq->startdisp, max);
+ }
+ if (flag & SEQ_RIGHTSEL) {
+ min = min_ii(seq->enddisp, min);
+ max = max_ii(seq->enddisp, max);
+ }
+ }
+ else {
+ min = min_ii(seq->startdisp, min);
+ max = max_ii(seq->enddisp, max);
+ }
+ }
+ }
+
+ if (ts) {
+ ts->max = max;
+ ts->min = min;
+ }
+}
+
+
static void freeSeqData(TransInfo *t)
{
Editing *ed = BKE_sequencer_editing_get(t->scene, false);
@@ -4682,6 +4729,8 @@ static void freeSeqData(TransInfo *t)
}
if ((t->customData != NULL) && (t->flag & T_FREE_CUSTOMDATA)) {
+ TransSeq *ts = t->customData;
+ MEM_freeN(ts->tdseq);
MEM_freeN(t->customData);
t->customData = NULL;
}
@@ -4701,6 +4750,8 @@ static void createTransSeqData(bContext *C, TransInfo *t)
TransData *td = NULL;
TransData2D *td2d = NULL;
TransDataSeq *tdsq = NULL;
+ TransSeq *ts = NULL;
+ int xmouse;
int count = 0;
@@ -4711,12 +4762,11 @@ static void createTransSeqData(bContext *C, TransInfo *t)
t->customFree = freeSeqData;
+ xmouse = (int)UI_view2d_region_to_view_x(v2d, t->imval[0]);
+
/* which side of the current frame should be allowed */
if (t->mode == TFM_TIME_EXTEND) {
/* only side on which mouse is gets transformed */
- float xmouse, ymouse;
-
- UI_view2d_region_to_view(v2d, t->imval[0], t->imval[1], &xmouse, &ymouse);
t->frame_side = (xmouse > CFRA) ? 'R' : 'L';
}
else {
@@ -4756,15 +4806,19 @@ static void createTransSeqData(bContext *C, TransInfo *t)
return;
}
+ t->customData = ts = MEM_mallocN(sizeof(TransSeq), "transseq");
td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransSeq TransData");
td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransSeq TransData2D");
- tdsq = t->customData = MEM_callocN(t->total * sizeof(TransDataSeq), "TransSeq TransDataSeq");
+ ts->tdseq = tdsq = MEM_callocN(t->total * sizeof(TransDataSeq), "TransSeq TransDataSeq");
t->flag |= T_FREE_CUSTOMDATA;
-
-
/* loop 2: build transdata array */
SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq);
+ SeqTransDataBounds(t, ed->seqbasep, ts);
+
+ /* set the snap mode based on how close the mouse is at the end/start points */
+ if (abs(xmouse - ts->max) > abs(xmouse - ts->min))
+ ts->snap_left = true;
#undef XXX_DURIAN_ANIM_TX_HACK
}
@@ -5300,7 +5354,7 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o
/* only if bone name matches too...
* NOTE: this will do constraints too, but those are ok to do here too?
*/
- if (pchanName && strcmp(pchanName, pchan->name) == 0)
+ if (pchanName && STREQ(pchanName, pchan->name))
insert_keyframe(reports, id, act, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
if (pchanName) MEM_freeN(pchanName);
@@ -5543,6 +5597,12 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
* during cleanup - psy-fi */
freeEdgeSlideTempFaces(sld);
}
+ else if (t->mode == TFM_VERT_SLIDE) {
+ /* as above */
+ VertSlideData *sld = t->customData;
+ projectVertSlideData(t, true);
+ freeVertSlideTempFaces(sld);
+ }
if (t->obedit->type == OB_MESH) {
special_aftertrans_update__mesh(C, t);
@@ -5555,12 +5615,21 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
sld->perc = 0.0;
projectEdgeSlideData(t, false);
}
+ else if (t->mode == TFM_VERT_SLIDE) {
+ VertSlideData *sld = t->customData;
+
+ sld->perc = 0.0;
+ projectVertSlideData(t, false);
+ }
}
}
}
- if (t->spacetype == SPACE_SEQ) {
+ if (t->options & CTX_GPENCIL_STROKES) {
+ /* pass */
+ }
+ else if (t->spacetype == SPACE_SEQ) {
/* freeSeqData in transform_conversions.c does this
* keep here so the else at the end wont run... */
@@ -6798,7 +6867,7 @@ static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point,
/* CV coords are scaled by aspects. this is needed for rotations and
* proportional editing to be consistent with the stretched CV coords
* that are displayed. this also means that for display and numinput,
- * and when the the CV coords are flushed, these are converted each time */
+ * and when the CV coords are flushed, these are converted each time */
mul_v2_m3v2(td2d->loc, parent_matrix, bezt->vec[i]);
td2d->loc[0] *= asp[0];
td2d->loc[1] *= asp[1];
@@ -7227,6 +7296,246 @@ void flushTransPaintCurve(TransInfo *t)
}
+static void createTransGPencil(bContext *C, TransInfo *t)
+{
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
+ bGPDlayer *gpl;
+ TransData *td = NULL;
+ float mtx[3][3], smtx[3][3];
+
+ const Scene *scene = CTX_data_scene(C);
+ const int cfra = CFRA;
+
+ const int propedit = (t->flag & T_PROP_EDIT);
+ const int propedit_connected = (t->flag & T_PROP_CONNECTED);
+
+
+ /* == Grease Pencil Strokes to Transform Data ==
+ * Grease Pencil stroke points can be a mixture of 2D (screen-space),
+ * or 3D coordinates. However, they're always saved as 3D points.
+ * For now, we just do these without creating TransData2D for the 2D
+ * strokes. This may cause issues in future though.
+ */
+ t->total = 0;
+
+ if (gpd == NULL)
+ return;
+
+ /* First Pass: Count the number of datapoints required for the strokes,
+ * (and additional info about the configuration - e.g. 2D/3D?)
+ */
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* only editable and visible layers are considered */
+ if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0 &&
+ (gpl->actframe != NULL))
+ {
+ bGPDframe *gpf = gpl->actframe;
+ bGPDstroke *gps;
+
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+
+ if (propedit) {
+ /* Proportional Editing... */
+ if (propedit_connected) {
+ /* connected only - so only if selected */
+ if (gps->flag & GP_STROKE_SELECT)
+ t->total += gps->totpoints;
+ }
+ else {
+ /* everything goes - connection status doesn't matter */
+ t->total += gps->totpoints;
+ }
+ }
+ else {
+ /* only selected stroke points are considered */
+ if (gps->flag & GP_STROKE_SELECT) {
+ bGPDspoint *pt;
+ int i;
+
+ // TODO: 2D vs 3D?
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT)
+ t->total++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Stop trying if nothing selected */
+ if (t->total == 0) {
+ return;
+ }
+
+ /* Allocate memory for data */
+ t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(GPencil)");
+ td = t->data;
+
+ unit_m3(smtx);
+ unit_m3(mtx);
+
+ /* Second Pass: Build transdata array */
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* only editable and visible layers are considered */
+ if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0 &&
+ (gpl->actframe != NULL))
+ {
+ bGPDframe *gpf = gpl->actframe;
+ bGPDstroke *gps;
+
+ /* Make a new frame to work on if the layer's frame and the current scene frame don't match up
+ * - This is useful when animating as it saves that "uh-oh" moment when you realize you've
+ * spent too much time editing the wrong frame...
+ */
+ // XXX: should this be allowed when framelock is enabled?
+ if (gpf->framenum != cfra) {
+ bGPDframe *new_frame = gpencil_frame_duplicate(gpf);
+ bGPDframe *gf;
+ bool found = false;
+
+ /* Find frame to insert it before */
+ for (gf = gpf->next; gf; gf = gf->next) {
+ if (gf->framenum > cfra) {
+ /* Add it here */
+ BLI_insertlinkbefore(&gpl->frames, gf, new_frame);
+
+ found = true;
+ break;
+ }
+ else if (gf->framenum == cfra) {
+ /* This only happens when we're editing with framelock on...
+ * - Delete the new frame and don't do anything else here...
+ */
+ //printf("GP Frame convert to TransData - Copy aborted for frame %d -> %d\n", gpf->framenum, gf->framenum);
+ free_gpencil_strokes(new_frame);
+ MEM_freeN(new_frame);
+ new_frame = NULL;
+
+ found = true;
+ break;
+ }
+ }
+
+ if (found == false) {
+ /* Add new frame to the end */
+ BLI_addtail(&gpl->frames, new_frame);
+ }
+
+ /* Edit the new frame instead, if it did get created + added */
+ if (new_frame) {
+ // TODO: tag this one as being "newly created" so that we can remove it if the edit is cancelled
+ new_frame->framenum = cfra;
+
+ gpf = new_frame;
+ }
+ }
+
+ /* Loop over strokes, adding TransData for points as needed... */
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ TransData *head = td;
+ TransData *tail = td;
+ bool stroke_ok;
+
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false) {
+ continue;
+ }
+
+ /* What we need to include depends on proportional editing settings... */
+ if (propedit) {
+ if (propedit_connected) {
+ /* A) "Connected" - Only those in selected strokes */
+ stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0;
+ }
+ else {
+ /* B) All points, always */
+ stroke_ok = true;
+ }
+ }
+ else {
+ /* C) Only selected points in selected strokes */
+ stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0;
+ }
+
+ /* Do stroke... */
+ if (stroke_ok && gps->totpoints) {
+ bGPDspoint *pt;
+ int i;
+
+#if 0 /* XXX: this isn't needed anymore; cannot calculate center this way or propedit breaks */
+ const float ninv = 1.0f / gps->totpoints;
+ float center[3] = {0.0f};
+
+ /* compute midpoint of stroke */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ madd_v3_v3v3fl(center, center, &pt->x, ninv);
+ }
+#endif
+
+ /* add all necessary points... */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ bool point_ok;
+
+ /* include point? */
+ if (propedit) {
+ /* Always all points in strokes that get included */
+ point_ok = true;
+ }
+ else {
+ /* Only selected points in selected strokes */
+ point_ok = (pt->flag & GP_SPOINT_SELECT) != 0;
+ }
+
+ /* do point... */
+ if (point_ok) {
+ copy_v3_v3(td->iloc, &pt->x);
+ copy_v3_v3(td->center, &pt->x); // XXX: what about t->around == local?
+
+ td->loc = &pt->x;
+
+ td->flag = 0;
+
+ if (pt->flag & GP_SPOINT_SELECT)
+ td->flag |= TD_SELECTED;
+
+ /* for other transform modes (e.g. shrink-fatten), need to additional data */
+ if (t->mode == TFM_GPENCIL_SHRINKFATTEN) {
+ td->val = &pt->pressure;
+ td->ival = pt->pressure;
+ }
+
+ /* configure 2D points so that they don't play up... */
+ if (gps->flag & (GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) {
+ td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
+ // XXX: matrices may need to be different?
+ }
+
+ copy_m3_m3(td->smtx, smtx);
+ copy_m3_m3(td->mtx, mtx);
+ unit_m3(td->axismtx); // XXX?
+
+ td++;
+ tail++;
+ }
+ }
+
+ /* March over these points, and calculate the proportional editing distances */
+ if (propedit && (head != tail)) {
+ /* XXX: for now, we are similar enough that this works... */
+ calc_distanceCurveVerts(head, tail - 1);
+ }
+ }
+ }
+ }
+ }
+}
+
+
void createTransData(bContext *C, TransInfo *t)
{
Scene *scene = t->scene;
@@ -7247,6 +7556,16 @@ void createTransData(bContext *C, TransInfo *t)
sort_trans_data_dist(t);
}
}
+ else if (t->options & CTX_GPENCIL_STROKES) {
+ t->flag |= T_POINTS; // XXX...
+ createTransGPencil(C, t);
+
+ if (t->data && (t->flag & T_PROP_EDIT)) {
+ sort_trans_data(t); // makes selected become first in array
+ set_prop_dist(t, 1);
+ sort_trans_data_dist(t);
+ }
+ }
else if (t->spacetype == SPACE_IMAGE) {
t->flag |= T_POINTS | T_2D_EDIT;
if (t->options & CTX_MASK) {
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 2f035949edc..5f02fa1b05f 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -87,6 +87,7 @@
#include "ED_keyframing.h"
#include "ED_markers.h"
#include "ED_mesh.h"
+#include "ED_object.h"
#include "ED_particle.h"
#include "ED_screen_types.h"
#include "ED_space_api.h"
@@ -109,21 +110,7 @@
void getViewVector(TransInfo *t, float coord[3], float vec[3])
{
if (t->persp != RV3D_ORTHO) {
- float p1[4], p2[4];
-
- copy_v3_v3(p1, coord);
- p1[3] = 1.0f;
- copy_v3_v3(p2, p1);
- p2[3] = 1.0f;
- mul_m4_v4(t->viewmat, p2);
-
- p2[0] = 2.0f * p2[0];
- p2[1] = 2.0f * p2[1];
- p2[2] = 2.0f * p2[2];
-
- mul_m4_v4(t->viewinv, p2);
-
- sub_v3_v3v3(vec, p1, p2);
+ sub_v3_v3v3(vec, coord, t->viewinv[3]);
}
else {
copy_v3_v3(vec, t->viewinv[2]);
@@ -975,6 +962,9 @@ void recalcData(TransInfo *t)
else if (t->options & CTX_PAINT_CURVE) {
flushTransPaintCurve(t);
}
+ else if (t->options & CTX_GPENCIL_STROKES) {
+ /* pass? */
+ }
else if (t->spacetype == SPACE_IMAGE) {
recalcData_image(t);
}
@@ -1203,9 +1193,13 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
}
/* exceptional case */
- if (t->around == V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
+ if (t->around == V3D_LOCAL) {
if (ELEM(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL)) {
- t->options |= CTX_NO_PET;
+ const bool use_island = transdata_check_local_islands(t, t->around);
+
+ if (obedit && !use_island) {
+ t->options |= CTX_NO_PET;
+ }
}
}
@@ -1227,7 +1221,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
}
}
else {
- RNA_property_boolean_set(op->ptr, prop, t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT);
+ RNA_property_boolean_set(op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) != 0);
}
}
@@ -1325,6 +1319,9 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
if (t->obedit) {
t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional);
}
+ else if (t->options & CTX_GPENCIL_STROKES) {
+ t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional);
+ }
else if (t->options & CTX_MASK) {
if (ts->proportional_mask) {
t->flag |= T_PROP_EDIT;
@@ -1686,63 +1683,8 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
bool ok = false;
if (t->obedit) {
- switch (t->obedit->type) {
- case OB_MESH:
- {
- BMEditSelection ese;
- BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
-
- if (BM_select_history_active_get(em->bm, &ese)) {
- BM_editselection_center(&ese, r_center);
- ok = true;
- }
- break;
- }
- case OB_ARMATURE:
- {
- bArmature *arm = t->obedit->data;
- EditBone *ebo = arm->act_edbone;
-
- if (ebo && (!select_only || (ebo->flag & (BONE_SELECTED | BONE_ROOTSEL)))) {
- copy_v3_v3(r_center, ebo->head);
- ok = true;
- }
-
- break;
- }
- case OB_CURVE:
- case OB_SURF:
- {
- float center[3];
- Curve *cu = (Curve *)t->obedit->data;
-
- if (ED_curve_active_center(cu, center)) {
- copy_v3_v3(r_center, center);
- ok = true;
- }
- break;
- }
- case OB_MBALL:
- {
- MetaBall *mb = (MetaBall *)t->obedit->data;
- MetaElem *ml_act = mb->lastelem;
-
- if (ml_act && (!select_only || (ml_act->flag & SELECT))) {
- copy_v3_v3(r_center, &ml_act->x);
- ok = true;
- }
- break;
- }
- case OB_LATTICE:
- {
- BPoint *actbp = BKE_lattice_active_point_get(t->obedit->data);
-
- if (actbp) {
- copy_v3_v3(r_center, actbp->vec);
- ok = true;
- }
- break;
- }
+ if (ED_object_editmode_calc_active_center(t->obedit, select_only, r_center)) {
+ ok = true;
}
}
else if (t->flag & T_POSE) {
@@ -1878,9 +1820,12 @@ void calculatePropRatio(TransInfo *t)
TransData *td = t->data;
int i;
float dist;
- short connected = t->flag & T_PROP_CONNECTED;
+ const bool connected = (t->flag & T_PROP_CONNECTED) != 0;
+
+ t->proptext[0] = '\0';
if (t->flag & T_PROP_EDIT) {
+ const char *pet_id = NULL;
for (i = 0; i < t->total; i++, td++) {
if (td->flag & TD_SELECTED) {
td->factor = 1.0f;
@@ -1941,6 +1886,9 @@ void calculatePropRatio(TransInfo *t)
case PROP_RANDOM:
td->factor = BLI_frand() * dist;
break;
+ case PROP_INVSQUARE:
+ td->factor = dist * (2.0f - dist);
+ break;
default:
td->factor = 1;
break;
@@ -1949,35 +1897,40 @@ void calculatePropRatio(TransInfo *t)
}
switch (t->prop_mode) {
case PROP_SHARP:
- strcpy(t->proptext, IFACE_("(Sharp)"));
+ pet_id = N_("(Sharp)");
break;
case PROP_SMOOTH:
- strcpy(t->proptext, IFACE_("(Smooth)"));
+ pet_id = N_("(Smooth)");
break;
case PROP_ROOT:
- strcpy(t->proptext, IFACE_("(Root)"));
+ pet_id = N_("(Root)");
break;
case PROP_LIN:
- strcpy(t->proptext, IFACE_("(Linear)"));
+ pet_id = N_("(Linear)");
break;
case PROP_CONST:
- strcpy(t->proptext, IFACE_("(Constant)"));
+ pet_id = N_("(Constant)");
break;
case PROP_SPHERE:
- strcpy(t->proptext, IFACE_("(Sphere)"));
+ pet_id = N_("(Sphere)");
break;
case PROP_RANDOM:
- strcpy(t->proptext, IFACE_("(Random)"));
+ pet_id = N_("(Random)");
+ break;
+ case PROP_INVSQUARE:
+ pet_id = N_("(InvSquare)");
break;
default:
- t->proptext[0] = '\0';
break;
}
+
+ if (pet_id) {
+ BLI_strncpy(t->proptext, IFACE_(pet_id), sizeof(t->proptext));
+ }
}
else {
for (i = 0; i < t->total; i++, td++) {
td->factor = 1.0;
}
- t->proptext[0] = '\0';
}
}
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 37a6d50e149..fc8e6cd0286 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -177,7 +177,7 @@ static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], con
mul_qt_v3(quat, gmat[0]);
/* Y-axis */
- axis_angle_to_quat(quat, axis, M_PI / 2.0);
+ axis_angle_to_quat(quat, axis, M_PI_2);
copy_v3_v3(gmat[1], gmat[0]);
mul_qt_v3(quat, gmat[1]);
@@ -268,7 +268,6 @@ static int calc_manipulator_stats(const bContext *C)
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
- ToolSettings *ts = CTX_data_tool_settings(C);
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
Base *base;
@@ -305,48 +304,11 @@ static int calc_manipulator_stats(const bContext *C)
BMIter iter;
- /* do vertices/edges/faces for center depending on selection
- * mode. note we can't use just vertex selection flag because
- * it is not flush down on changes */
- if (ts->selectmode & SCE_SELECT_VERTEX) {
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- totsel++;
- calc_tw_center(scene, eve->co);
- }
- }
- }
- }
- else if (ts->selectmode & SCE_SELECT_EDGE) {
- BMIter itersub;
- BMEdge *eed;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- /* check the vertex has a selected edge, only add it once */
- BM_ITER_ELEM (eed, &itersub, eve, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- totsel++;
- calc_tw_center(scene, eve->co);
- break;
- }
- }
- }
- }
- }
- else {
- BMIter itersub;
- BMFace *efa;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- /* check the vertex has a selected face, only add it once */
- BM_ITER_ELEM (efa, &itersub, eve, BM_FACES_OF_VERT) {
- if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
- totsel++;
- calc_tw_center(scene, eve->co);
- break;
- }
- }
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ totsel++;
+ calc_tw_center(scene, eve->co);
}
}
}
@@ -1850,7 +1812,6 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
WM_operator_name_call(C, "TRANSFORM_OT_translate", WM_OP_INVOKE_DEFAULT, op->ptr);
- //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_translate", 0), event, op->ptr, NULL, false);
}
else if (drawflags & MAN_SCALE_C) {
switch (drawflags) {
@@ -1881,7 +1842,6 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
WM_operator_name_call(C, "TRANSFORM_OT_resize", WM_OP_INVOKE_DEFAULT, op->ptr);
- //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_resize", 0), event, op->ptr, NULL, false);
}
else if (drawflags == MAN_ROT_T) { /* trackball need special case, init is different */
/* Do not pass op->ptr!!! trackball has no "constraint" properties!
@@ -1894,8 +1854,7 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
if ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) && RNA_property_is_set(op->ptr, prop)) {
RNA_property_boolean_set(&props_ptr, prop, RNA_property_boolean_get(op->ptr, prop));
}
- WM_operator_name_call(C, ot->idname, WM_OP_INVOKE_DEFAULT, &props_ptr);
- //wm_operator_invoke(C, WM_operatortype_find(ot->idname, 0), event, NULL, NULL, false);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
WM_operator_properties_free(&props_ptr);
}
else if (drawflags & MAN_ROT_C) {
@@ -1912,7 +1871,6 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
}
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
WM_operator_name_call(C, "TRANSFORM_OT_rotate", WM_OP_INVOKE_DEFAULT, op->ptr);
- //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_rotate", 0), event, op->ptr, NULL, false);
}
}
/* after transform, restore drawflags */
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 81e065ee33a..0ee5ab96a85 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -142,6 +142,7 @@ EnumPropertyItem transform_mode_types[] =
{TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone_Envelope", ""},
{TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", 0, "Curve_Shrinkfatten", ""},
{TFM_MASK_SHRINKFATTEN, "MASK_SHRINKFATTEN", 0, "Mask_Shrinkfatten", ""},
+ {TFM_GPENCIL_SHRINKFATTEN, "GPENCIL_SHRINKFATTEN", 0, "GPencil_Shrinkfatten", ""},
{TFM_BONE_ROLL, "BONE_ROLL", 0, "Bone_Roll", ""},
{TFM_TIME_TRANSLATE, "TIME_TRANSLATE", 0, "Time_Translate", ""},
{TFM_TIME_SLIDE, "TIME_SLIDE", 0, "Time_Slide", ""},
@@ -171,12 +172,12 @@ static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), const
uiPopupMenu *pup;
uiLayout *layout;
- pup = uiPupMenuBegin(C, IFACE_("Orientation"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("Orientation"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
uiItemsEnumO(layout, "TRANSFORM_OT_select_orientation", "orientation");
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
static void TRANSFORM_OT_select_orientation(struct wmOperatorType *ot)
@@ -324,6 +325,9 @@ static void transformops_loopsel_hack(bContext *C, wmOperator *op)
}
}
}
+#else
+/* prevent removal by cleanup */
+# error "loopslide hack removed!"
#endif /* USE_LOOPSLIDE_HACK */
@@ -543,7 +547,11 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
}
}
}
-
+
+ if (flags & P_GPENCIL_EDIT) {
+ RNA_def_boolean(ot->srna, "gpencil_strokes", 0, "Edit Grease Pencil", "Edit selected Grease Pencil strokes");
+ }
+
if ((flags & P_OPTIONS) && !(flags & P_NO_TEXSPACE)) {
RNA_def_boolean(ot->srna, "texture_space", 0, "Edit Texture Space", "Edit Object data texture space");
prop = RNA_def_boolean(ot->srna, "remove_on_cancel", 0, "Remove on Cancel", "Remove elements on cancel");
@@ -578,7 +586,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
- Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS);
+ Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS | P_GPENCIL_EDIT);
}
static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
@@ -598,7 +606,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
- Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS);
+ Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS | P_GPENCIL_EDIT);
}
static int skin_resize_poll(bContext *C)
@@ -652,7 +660,7 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
prop = RNA_def_float_vector(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
RNA_def_property_subtype(prop, PROP_ANGLE);
- Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
+ Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT);
}
static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
@@ -675,7 +683,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
prop = RNA_def_float(ot->srna, "value", 0.0f, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
RNA_def_property_subtype(prop, PROP_ANGLE);
- Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP);
+ Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_GPENCIL_EDIT);
}
static void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
@@ -721,7 +729,7 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot)
RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
- Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
+ Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT);
}
static void TRANSFORM_OT_shear(struct wmOperatorType *ot)
@@ -741,7 +749,7 @@ static void TRANSFORM_OT_shear(struct wmOperatorType *ot)
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
- Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
+ Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT);
// XXX Shear axis?
}
@@ -803,7 +811,7 @@ static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot)
RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1);
- Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
+ Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT);
}
static void TRANSFORM_OT_mirror(struct wmOperatorType *ot)
@@ -821,7 +829,7 @@ static void TRANSFORM_OT_mirror(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
- Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL);
+ Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_GPENCIL_EDIT);
}
static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
@@ -861,7 +869,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f);
- Transform_Properties(ot, P_MIRROR | P_SNAP);
+ Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV);
}
static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
@@ -967,7 +975,7 @@ static 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);
- Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP);
+ Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_GPENCIL_EDIT);
}
void transform_operatortypes(void)
@@ -1106,9 +1114,6 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
/* XXX release_confirm is set in the macro operator definition */
WM_keymap_add_item(keymap, "NODE_OT_move_detach_links_release", EVT_TWEAK_A, KM_ANY, KM_ALT, 0);
WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", EVT_TWEAK_S, KM_ANY, KM_ALT, 0);
-
- /* dettach and translate */
- WM_keymap_add_item(keymap, "NODE_OT_detach_translate_attach", FKEY, KM_PRESS, KM_ALT, 0);
break;
case SPACE_SEQ:
WM_keymap_add_item(keymap, OP_SEQ_SLIDE, GKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index c7d63da8281..7fea8e163fd 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -24,7 +24,6 @@
* \ingroup edtransform
*/
-
#include <string.h>
#include <stddef.h>
#include <ctype.h>
@@ -57,10 +56,6 @@
#include "ED_armature.h"
-#include "RNA_define.h"
-
-#include "UI_interface.h"
-
#include "transform.h"
/* *********************** TransSpace ************************** */
@@ -392,7 +387,7 @@ void BIF_selectTransformOrientationValue(bContext *C, int orientation)
int BIF_countTransformOrientation(const bContext *C)
{
ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
- return BLI_countlist(transform_spaces);
+ return BLI_listbase_count(transform_spaces);
}
bool applyTransformOrientation(const bContext *C, float mat[3][3], char *r_name)
@@ -723,14 +718,16 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
/* should never fail */
if (LIKELY(v_pair[0] && v_pair[1])) {
bool v_pair_swap = false;
- /* Logic explained:
+ float tvec[3];
+ /**
+ * Logic explained:
*
* - Edges and vert-pairs treated the same way.
- * - Point the Z axis along the edge vector (towards the active vertex).
- * - Point the Y axis outwards (the same direction as the normals).
+ * - Point the Y axis along the edge vector (towards the active vertex).
+ * - Point the Z axis outwards (the same direction as the normals).
*
- * Note that this is at odds a little with face select (and 3 vertices)
- * which point the Z axis along the normal, however in both cases Z is the dominant axis.
+ * \note Z points outwards - along the normal.
+ * take care making changes here, see: T38592, T43708
*/
/* be deterministic where possible and ensure v_pair[0] is active */
@@ -738,7 +735,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
v_pair_swap = true;
}
else if (eed && BM_edge_is_boundary(eed)) {
- /* pradictable direction for boundary edges */
+ /* predictable direction for boundary edges */
if (eed->l->v != v_pair[0]) {
v_pair_swap = true;
}
@@ -748,10 +745,15 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
SWAP(BMVert *, v_pair[0], v_pair[1]);
}
- add_v3_v3v3(plane, v_pair[0]->no, v_pair[1]->no);
- sub_v3_v3v3(normal, v_pair[0]->co, v_pair[1]->co);
+ add_v3_v3v3(normal, v_pair[0]->no, v_pair[1]->no);
+ sub_v3_v3v3(plane, v_pair[0]->co, v_pair[1]->co);
/* flip the plane normal so we point outwards */
negate_v3(plane);
+
+ /* align normal to edge direction (so normal is perpendicular to the plane).
+ * 'ORIENTATION_EDGE' will do the other way around */
+ project_v3_v3v3(tvec, normal, plane);
+ sub_v3_v3(normal, tvec);
}
result = ORIENTATION_EDGE;
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 8a3e8f19db4..4a2927ace00 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -59,6 +59,7 @@
#include "BKE_anim.h" /* for duplis */
#include "BKE_context.h"
#include "BKE_editmesh.h"
+#include "BKE_sequencer.h"
#include "BKE_main.h"
#include "BKE_tracking.h"
@@ -341,22 +342,15 @@ void applyProject(TransInfo *t)
if (t->tsnap.align && (t->flag & T_OBJECT)) {
/* handle alignment as well */
const float *original_normal;
- float axis[3];
float mat[3][3];
- float angle;
float totmat[3][3], smat[3][3];
- float eul[3], fmat[3][3], quat[4];
+ float eul[3], fmat[3][3];
float obmat[3][3];
/* In pose mode, we want to align normals with Y axis of bones... */
original_normal = td->axismtx[2];
- cross_v3_v3v3(axis, original_normal, no);
- angle = saacos(dot_v3v3(original_normal, no));
-
- axis_angle_to_quat(quat, axis, angle);
-
- quat_to_mat3(mat, quat);
+ rotation_between_vecs_to_mat3(mat, original_normal, no);
mul_m3_m3m3(totmat, mat, td->mtx);
mul_m3_m3m3(smat, td->smtx, totmat);
@@ -1543,8 +1537,7 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes
float ray_start_local[3], ray_normal_local[3], local_scale, len_diff = TRANSFORM_DIST_MAX_RAY;
invert_m4_m4(imat, obmat);
- copy_m3_m4(timat, imat);
- transpose_m3(timat);
+ transpose_m3_m4(timat, imat);
copy_v3_v3(ray_start_local, ray_start);
copy_v3_v3(ray_normal_local, ray_normal);
@@ -1956,21 +1949,32 @@ static bool snapObjectsRay(Scene *scene, short snap_mode, Base *base_act, View3D
(ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT) && base != base_act)))
{
Object *ob = base->object;
-
+ Object *ob_snap = ob;
+ bool use_obedit = false;
+
+ /* for linked objects, use the same object but a different matrix */
+ if (obedit && ob->data == obedit->data) {
+ use_obedit = true;
+ ob_snap = obedit;
+ }
+
if (ob->transflag & OB_DUPLI) {
DupliObject *dupli_ob;
ListBase *lb = object_duplilist(G.main->eval_ctx, scene, ob);
for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
- retval |= snapObject(scene, snap_mode, ar, dupli_ob->ob, dupli_ob->mat, false,
+ bool use_obedit_dupli = (obedit && dupli_ob->ob->data == obedit->data);
+ Object *dupli_snap = (use_obedit_dupli) ? obedit : dupli_ob->ob;
+
+ retval |= snapObject(scene, snap_mode, ar, dupli_snap, dupli_ob->mat, use_obedit_dupli,
r_ob, r_obmat,
ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist);
}
free_object_duplilist(lb);
}
-
- retval |= snapObject(scene, snap_mode, ar, ob, ob->obmat, false,
+
+ retval |= snapObject(scene, snap_mode, ar, ob_snap, ob->obmat, use_obedit,
r_ob, r_obmat,
ray_start, ray_normal, ray_origin, mval, r_loc, r_no, r_dist_px, r_ray_dist);
}
@@ -2101,8 +2105,7 @@ static bool peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4],
invert_m4_m4(imat, obmat);
- copy_m3_m4(timat, imat);
- transpose_m3(timat);
+ transpose_m3_m4(timat, imat);
copy_v3_v3(ray_start_local, ray_start);
copy_v3_v3(ray_normal_local, ray_normal);
@@ -2265,7 +2268,7 @@ static bool peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit,
}
}
- BLI_sortlist(depth_peels, cmpPeel);
+ BLI_listbase_sort(depth_peels, cmpPeel);
removeDoublesPeel(depth_peels);
return retval;
@@ -2428,6 +2431,27 @@ void snapGridIncrement(TransInfo *t, float *val)
snapGridIncrementAction(t, val, action);
}
+int snapSequenceBounds(TransInfo *t, const int mval[2])
+{
+ float xmouse, ymouse;
+ int frame;
+ int mframe;
+ TransSeq *ts = t->customData;
+ /* reuse increment, strictly speaking could be another snap mode, but leave as is */
+ if (!(t->modifiers & MOD_SNAP_INVERT))
+ return 0;
+
+ /* convert to frame range */
+ UI_view2d_region_to_view(&t->ar->v2d, mval[0], mval[1], &xmouse, &ymouse);
+ mframe = iroundf(xmouse);
+ /* now find the closest sequence */
+ frame = BKE_sequencer_find_next_prev_edit(t->scene, mframe, SEQ_SIDE_BOTH, true, false, true);
+
+ if (!ts->snap_left)
+ frame = frame - (ts->max - ts->min);
+
+ return frame;
+}
static void applyGridIncrement(TransInfo *t, float *val, int max_index, const float fac[3], GearsType action)
{
@@ -2455,6 +2479,19 @@ static void applyGridIncrement(TransInfo *t, float *val, int max_index, const fl
ED_space_image_get_uv_aspect(t->sa->spacedata.first, asp, asp + 1);
}
}
+ else if ((t->spacetype == SPACE_IPO) && (t->mode == TFM_TRANSLATION)) {
+ View2D *v2d = &t->ar->v2d;
+ View2DGrid *grid;
+ SpaceIpo *sipo = t->sa->spacedata.first;
+ int unity = V2D_UNIT_VALUES;
+ int unitx = (sipo->flag & SIPO_DRAWTIME) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMESCALE;
+
+ /* grid */
+ grid = UI_view2d_grid_calc(t->scene, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, t->ar->winx, t->ar->winy);
+
+ UI_view2d_grid_size(grid, &asp[0], &asp[1]);
+ UI_view2d_grid_free(grid);
+ }
for (i = 0; i <= max_index; i++) {
val[i] = fac[action] * asp[i] * floorf(val[i] / (fac[action] * asp[i]) + 0.5f);
diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c
index 104b628c25a..c3eef94f4bb 100644
--- a/source/blender/editors/util/ed_transverts.c
+++ b/source/blender/editors/util/ed_transverts.c
@@ -310,7 +310,7 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const
}
else if (obedit->type == OB_ARMATURE) {
bArmature *arm = obedit->data;
- int totmalloc = BLI_countlist(arm->edbo);
+ int totmalloc = BLI_listbase_count(arm->edbo);
totmalloc *= 2; /* probably overkill but bones can have 2 trans verts each */
@@ -441,7 +441,7 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, Object *obedit, const
}
else if (obedit->type == OB_MBALL) {
MetaBall *mb = obedit->data;
- int totmalloc = BLI_countlist(mb->editelems);
+ int totmalloc = BLI_listbase_count(mb->editelems);
tv = tvs->transverts = MEM_callocN(totmalloc * sizeof(TransVert), __func__);
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index ec0471da8d3..438eb1f3864 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -174,7 +174,7 @@ bool ED_editors_flush_edits(const bContext *C, bool for_render)
}
else {
/* Set reorder=false so that saving the file doesn't reorder
- * the BMesh's elements */
+ * the BMesh's elements */
BKE_sculptsession_bm_to_me(ob, false);
}
}
@@ -218,8 +218,8 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
char line[FILE_MAX + 100];
wmOperatorType *ot = WM_operatortype_find(opname, 1);
- pup = uiPupMenuBegin(C, IFACE_("Unpack File"), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_("Unpack File"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
props_ptr = uiItemFullO_ptr(layout, ot, IFACE_("Remove Pack"), ICON_NONE,
NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS);
@@ -231,7 +231,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
BLI_split_file_part(abs_name, fi, sizeof(fi));
BLI_snprintf(local_name, sizeof(local_name), "//%s/%s", folder, fi);
- if (strcmp(abs_name, local_name) != 0) {
+ if (!STREQ(abs_name, local_name)) {
switch (checkPackedFile(local_name, pf)) {
case PF_NOFILE:
BLI_snprintf(line, sizeof(line), IFACE_("Create %s"), local_name);
@@ -295,7 +295,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
break;
}
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
/* ********************* generic callbacks for drawcall api *********************** */
diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c
index ef95e4cb3ff..7f5edb5ea9e 100644
--- a/source/blender/editors/util/editmode_undo.c
+++ b/source/blender/editors/util/editmode_undo.c
@@ -48,8 +48,6 @@
#include "ED_util.h"
#include "ED_mesh.h"
-#include "UI_interface.h"
-#include "UI_resources.h"
#include "util_intern.h"
@@ -208,7 +206,7 @@ static void undo_clean_stack(bContext *C)
/* for when objects are converted, renamed, or global undo changes pointers... */
if (uel->type == obedit->type) {
- if (strcmp(uel->id.name, obedit->id.name) == 0) {
+ if (STREQ(uel->id.name, obedit->id.name)) {
if (uel->validate_undo == NULL)
is_valid = true;
else if (uel->validate_undo(uel->undodata, editdata))
@@ -307,7 +305,7 @@ void undo_editmode_name(bContext *C, const char *undoname)
UndoElem *uel;
for (uel = undobase.last; uel; uel = uel->prev) {
- if (strcmp(undoname, uel->name) == 0)
+ if (STREQ(undoname, uel->name))
break;
}
if (uel && uel->prev) {
@@ -323,7 +321,7 @@ int undo_editmode_valid(const char *undoname)
UndoElem *uel;
for (uel = undobase.last; uel; uel = uel->prev) {
- if (strcmp(undoname, uel->name) == 0)
+ if (STREQ(undoname, uel->name))
break;
}
return uel != NULL;
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index a154f12a786..050631362b4 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -103,7 +103,7 @@ void outputNumInput(NumInput *n, char *str, UnitSettings *unit_settings)
if (n->val_flag[i] & NUM_EDITED) {
/* Get the best precision, allows us to draw '10.0001' as '10' instead! */
- prec = uiFloatPrecisionCalc(prec, (double)n->val[i]);
+ prec = UI_calc_float_precision(prec, (double)n->val[i]);
if (i == n->idx) {
const char *heading_exp = "", *trailing_exp = "";
char before_cursor[NUM_STR_REP_LEN];
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 189a938e3d8..ab882a388ad 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -29,8 +29,6 @@
* \ingroup edutil
*/
-
-
#include <stdlib.h>
#include <string.h>
#include <math.h>
@@ -47,6 +45,7 @@
#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_main.h"
#include "BKE_screen.h"
#include "ED_armature.h"
@@ -124,6 +123,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
Object *obact = CTX_data_active_object(C);
@@ -146,7 +146,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) {
if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) {
if (U.uiflag & USER_GLOBALUNDO) {
- ED_viewport_render_kill_jobs(C, true);
+ ED_viewport_render_kill_jobs(wm, bmain, true);
BKE_undo_name(C, undoname);
}
}
@@ -199,7 +199,7 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
/* for example, texface stores image pointers */
undo_editmode_clear();
- ED_viewport_render_kill_jobs(C, true);
+ ED_viewport_render_kill_jobs(wm, bmain, true);
if (undoname)
BKE_undo_name(C, undoname);
@@ -379,7 +379,7 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
{
int retval;
- ED_viewport_render_kill_jobs(C, true);
+ ED_viewport_render_kill_jobs(wm, CTX_data_main(C), true);
if (G.debug & G_DEBUG)
printf("redo_cb: operator redo %s\n", op->type->name);
@@ -536,8 +536,8 @@ static int undo_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
EnumPropertyItem *item = rna_undo_itemf(C, undosys, &totitem);
if (totitem > 0) {
- uiPopupMenu *pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
- uiLayout *layout = uiPupMenuLayout(pup);
+ uiPopupMenu *pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
uiLayout *column = NULL;
const int col_size = 20 + totitem / 12;
@@ -558,7 +558,7 @@ static int undo_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
MEM_freeN(item);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
}
}
@@ -580,10 +580,10 @@ static int undo_history_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL);
}
else if (undosys == UNDOSYSTEM_IMAPAINT) {
- ED_undo_paint_step_num(C, UNDO_PAINT_IMAGE, item );
+ ED_undo_paint_step_num(C, UNDO_PAINT_IMAGE, item);
}
else {
- ED_viewport_render_kill_jobs(C, true);
+ ED_viewport_render_kill_jobs(CTX_wm_manager(C), CTX_data_main(C), true);
BKE_undo_number(C, item);
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C));
}
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index 6816e785c1f..0d8dd2369d8 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -53,7 +53,6 @@
#include "ED_uvedit.h"
#include "UI_interface.h"
-#include "UI_resources.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -142,11 +141,25 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
em = BKE_editmesh_from_object(obedit);
if (uvedit_center(scene, em, ima, center)) {
+ float range_xy[2][2] = {
+ {-10.0f, 10.0f},
+ {-10.0f, 10.0f},
+ };
+
copy_v2_v2(uvedit_old_center, center);
+ /* expand UI range by center */
+ CLAMP_MAX(range_xy[0][0], uvedit_old_center[0]);
+ CLAMP_MIN(range_xy[0][1], uvedit_old_center[0]);
+ CLAMP_MAX(range_xy[1][0], uvedit_old_center[1]);
+ CLAMP_MIN(range_xy[1][1], uvedit_old_center[1]);
+
if (!(sima->flag & SI_COORDFLOATS)) {
uvedit_old_center[0] *= imx;
uvedit_old_center[1] *= imy;
+
+ mul_v2_fl(range_xy[0], imx);
+ mul_v2_fl(range_xy[1], imy);
}
if (sima->flag & SI_COORDFLOATS) {
@@ -158,12 +171,12 @@ static void uvedit_vertex_buttons(const bContext *C, uiBlock *block)
digits = 2;
}
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_UVEDIT_VERTEX, IFACE_("X:"), 0, 0, width, UI_UNIT_Y, &uvedit_old_center[0],
- -10 * imx, 10.0 * imx, step, digits, "");
- uiDefButF(block, NUM, B_UVEDIT_VERTEX, IFACE_("Y:"), width, 0, width, UI_UNIT_Y, &uvedit_old_center[1],
- -10 * imy, 10.0 * imy, step, digits, "");
- uiBlockEndAlign(block);
+ UI_block_align_begin(block);
+ uiDefButF(block, UI_BTYPE_NUM, B_UVEDIT_VERTEX, IFACE_("X:"), 0, 0, width, UI_UNIT_Y, &uvedit_old_center[0],
+ UNPACK2(range_xy[0]), step, digits, "");
+ uiDefButF(block, UI_BTYPE_NUM, B_UVEDIT_VERTEX, IFACE_("Y:"), width, 0, width, UI_UNIT_Y, &uvedit_old_center[1],
+ UNPACK2(range_xy[1]), step, digits, "");
+ UI_block_align_end(block);
}
}
@@ -212,7 +225,7 @@ static void image_panel_uv(const bContext *C, Panel *pa)
uiBlock *block;
block = uiLayoutAbsoluteBlock(pa->layout);
- uiBlockSetHandleFunc(block, do_uvedit_vertex, NULL);
+ UI_block_func_handle_set(block, do_uvedit_vertex, NULL);
uvedit_vertex_buttons(C, block);
}
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 83fd7e6505d..b2c4970479a 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -43,7 +43,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_alloca.h"
#include "BLI_buffer.h"
#include "BLI_bitmap.h"
@@ -71,7 +70,7 @@
static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset);
-void draw_image_cursor(ARegion *ar, const float cursor[2])
+void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
{
float zoom[2], x_fac, y_fac;
@@ -325,7 +324,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
a = fabsf(uvang[i] - ang[i]) / (float)M_PI;
- weight_to_rgb(col, 1.0f - powf((1.0f - a), 2.0f));
+ weight_to_rgb(col, 1.0f - pow2f(1.0f - a));
glColor3fv(col);
glVertex2fv(luv->uv);
}
@@ -506,6 +505,8 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob)
mloopuv_base = mloopuv;
for (a = me->totpoly; a > 0; a--, mpoly++) {
+ if ((scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE) && mpoly->mat_nr != ob->actcol - 1)
+ continue;
glBegin(GL_LINE_LOOP);
mloopuv = mloopuv_base + mpoly->loopstart;
@@ -963,7 +964,7 @@ static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bo
*show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT);
}
-void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact)
+void ED_uvedit_draw_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact)
{
ToolSettings *toolsettings = scene->toolsettings;
bool show_uvedit, show_uvshadow, show_texpaint_uvshadow;
@@ -980,7 +981,7 @@ void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedi
draw_uvs_texpaint(sima, scene, obact);
if (show_uvedit && !(toolsettings->use_uv_sculpt))
- draw_image_cursor(ar, sima->cursor);
+ ED_image_draw_cursor(ar, sima->cursor);
}
}
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 52365ff3478..d1fd8d969a4 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -41,6 +41,7 @@ struct SpaceImage;
struct UvElementMap;
struct wmOperatorType;
struct BMEditMesh;
+struct BMesh;
struct BMFace;
struct BMLoop;
struct BMEdge;
@@ -71,7 +72,6 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM
/* utility tool functions */
void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit);
-void uvedit_get_aspect(struct Scene *scene, struct Object *ob, struct BMEditMesh *em, float *aspx, float *aspy);
/* operators */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 4b341547370..c70fcdbbd94 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -668,6 +668,24 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2],
return changed;
}
+/* Be careful when using this, it bypasses all synchronization options */
+void ED_uvedit_select_all(BMesh *bm)
+{
+ BMFace *efa;
+ BMLoop *l;
+ BMIter iter, liter;
+ MLoopUV *luv;
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ luv->flag |= MLOOPUV_VERTSEL;
+ }
+ }
+}
+
static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[2])
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
@@ -1291,10 +1309,10 @@ static int uv_select_more_less(bContext *C, const bool select)
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (select) {
- EDBM_select_more(em);
+ EDBM_select_more(em, true);
}
else {
- EDBM_select_less(em);
+ EDBM_select_less(em, true);
}
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
@@ -1753,7 +1771,7 @@ static int uv_remove_doubles_exec(bContext *C, wmOperator *op)
if ((vert_arr[uv_b_index].weld == false) &&
(len_manhattan_v2v2(uv_a, uv_b) < threshold))
{
- minmax_v2v2_v2(uv_max, uv_min, uv_b);
+ minmax_v2v2_v2(uv_min, uv_max, uv_b);
BLI_array_append(loop_arr, vert_arr[uv_b_index].uv_loop);
vert_arr[uv_b_index].weld = true;
}
@@ -3171,8 +3189,8 @@ static void UV_OT_select_lasso(wmOperatorType *ot)
static void uv_snap_to_pixel(float uvco[2], float w, float h)
{
- uvco[0] = ((float)((int)((uvco[0] * w) + 0.5f))) / w;
- uvco[1] = ((float)((int)((uvco[1] * h) + 0.5f))) / h;
+ uvco[0] = roundf(uvco[0] * w) / w;
+ uvco[1] = roundf(uvco[1] * h) / h;
}
static void uv_snap_cursor_to_pixels(SpaceImage *sima)
@@ -3859,6 +3877,15 @@ static int uv_set_2d_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *e
ARegion *ar = CTX_wm_region(C);
float location[2];
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ if (event->mval[1] <= 16) {
+ SpaceImage *sima = CTX_wm_space_image(C);
+ if (sima && ED_space_image_show_cache(sima)) {
+ return OPERATOR_PASS_THROUGH;
+ }
+ }
+ }
+
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
RNA_float_set_array(op->ptr, "location", location);
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 79f53e1d971..00615f9bef7 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -35,7 +35,6 @@
#include "BLI_boxpack2d.h"
#include "BLI_convexhull2d.h"
-#include "uvedit_intern.h"
#include "uvedit_parametrizer.h"
#include <math.h>
@@ -2673,8 +2672,8 @@ static PBool p_abf_matrix_invert(PAbfSystem *sys, PChart *chart)
}
for (i = 0; i < ninterior; i++) {
- sys->lambdaPlanar[i] += nlGetVariable(0, i);
- sys->lambdaLength[i] += nlGetVariable(0, ninterior + i);
+ sys->lambdaPlanar[i] += (float)nlGetVariable(0, i);
+ sys->lambdaLength[i] += (float)nlGetVariable(0, ninterior + i);
}
}
@@ -3403,8 +3402,8 @@ static void p_chart_stretch_minimize(PChart *chart, RNG *rng)
static int p_compare_geometric_uv(const void *a, const void *b)
{
- PVert *v1 = *(PVert **)a;
- PVert *v2 = *(PVert **)b;
+ const PVert *v1 = *(const PVert * const *)a;
+ const PVert *v2 = *(const PVert * const *)b;
if (v1->uv[0] < v2->uv[0])
return -1;
@@ -3789,11 +3788,14 @@ static PBool p_node_intersect(SmoothNode *node, float co[2])
/* smoothing */
-static int p_compare_float(const void *a, const void *b)
+static int p_compare_float(const void *a_, const void *b_)
{
- if (*((float *)a) < *((float *)b))
+ const float a = *(const float *)a_;
+ const float b = *(const float *)b_;
+
+ if (a < b)
return -1;
- else if (*((float *)a) == *((float *)b))
+ else if (a == b)
return 0;
else
return 1;
@@ -4194,7 +4196,7 @@ void param_delete(ParamHandle *handle)
static void p_add_ngon(ParamHandle *handle, ParamKey key, int nverts,
ParamKey *vkeys, float **co, float **uv,
- ParamBool *pin, ParamBool *select, float normal[3])
+ ParamBool *pin, ParamBool *select, const float normal[3])
{
int *boundary = BLI_array_alloca(boundary, nverts);
int i;
@@ -4559,7 +4561,7 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate)
box->index = i; /* warning this index skips PCHART_NOPACK boxes */
if (margin > 0.0f)
- area += sqrtf(box->w * box->h);
+ area += (double)sqrtf(box->w * box->h);
}
if (margin > 0.0f) {
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index fcd5267fd44..f7a8735ccca 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -574,11 +574,11 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat
edgecos = dot_v2v2(normal, state->normals + index_tmp1 * 2);
edgesin = cross_v2v2(normal, state->normals + index_tmp1 * 2);
if (edgesin > 0.0f) {
- rotation += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
+ rotation += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
rot_elem++;
}
else {
- rotation_neg += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
+ rotation_neg += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
rot_elem_neg++;
}
}
@@ -1354,16 +1354,15 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
/* Stitch hash initialization functions */
static unsigned int uv_edge_hash(const void *key)
{
- UvEdge *edge = (UvEdge *)key;
- return
- BLI_ghashutil_uinthash(edge->uv2) +
- BLI_ghashutil_uinthash(edge->uv1);
+ const UvEdge *edge = key;
+ return (BLI_ghashutil_uinthash(edge->uv2) +
+ BLI_ghashutil_uinthash(edge->uv1));
}
static bool uv_edge_compare(const void *a, const void *b)
{
- UvEdge *edge1 = (UvEdge *)a;
- UvEdge *edge2 = (UvEdge *)b;
+ const UvEdge *edge1 = a;
+ const UvEdge *edge2 = b;
if ((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)) {
return 0;
@@ -1602,7 +1601,7 @@ static int stitch_init(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- GHashIterator *ghi;
+ GHashIterator gh_iter;
UvEdge *all_edges;
StitchState *state;
Scene *scene = CTX_data_scene(C);
@@ -1660,7 +1659,7 @@ static int stitch_init(bContext *C, wmOperator *op)
return 0;
}
- uvedit_get_aspect(scene, obedit, em, &aspx, &aspy);
+ ED_uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy);
state->aspect = aspx / aspy;
/* Entirely possible if redoing last operator that static island is bigger than total number of islands.
@@ -1749,14 +1748,11 @@ static int stitch_init(bContext *C, wmOperator *op)
}
}
-
- ghi = BLI_ghashIterator_new(edge_hash);
total_edges = BLI_ghash_size(edge_hash);
state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges");
/* I assume any system will be able to at least allocate an iterator :p */
if (!edges) {
- BLI_ghashIterator_free(ghi);
state_delete(state);
return 0;
}
@@ -1764,12 +1760,12 @@ static int stitch_init(bContext *C, wmOperator *op)
state->total_separate_edges = total_edges;
/* fill the edges with data */
- for (i = 0, BLI_ghashIterator_init(ghi, edge_hash); !BLI_ghashIterator_done(ghi); BLI_ghashIterator_step(ghi)) {
- edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
+ i = 0;
+ GHASH_ITER (gh_iter, edge_hash) {
+ edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter));
}
/* cleanup temporary stuff */
- BLI_ghashIterator_free(ghi);
MEM_freeN(all_edges);
BLI_ghash_free(edge_hash, NULL, NULL);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 335d8e6589e..793f84b05ec 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -190,21 +190,21 @@ static bool uvedit_have_selection(Scene *scene, BMEditMesh *em, bool implicit)
return false;
}
-void uvedit_get_aspect(Scene *scene, Object *ob, BMEditMesh *em, float *aspx, float *aspy)
+void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, float *aspy)
{
bool sloppy = true;
bool selected = false;
BMFace *efa;
Image *ima;
- efa = BM_mesh_active_face_get(em->bm, sloppy, selected);
+ efa = BM_mesh_active_face_get(bm, sloppy, selected);
if (efa) {
if (BKE_scene_use_new_shading_nodes(scene)) {
ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL);
}
else {
- MTexPoly *tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ MTexPoly *tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
ima = tf->tpage;
}
@@ -247,11 +247,10 @@ static void construct_param_handle_face_add(ParamHandle *handle, Scene *scene,
param_face_add(handle, key, i, vkeys, co, uv, pin, select, efa->no);
}
-static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh *em,
+static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMesh *bm,
const bool implicit, const bool fill, const bool sel,
const bool correct_aspect)
{
- BMesh *bm = em->bm;
ParamHandle *handle;
BMFace *efa;
BMLoop *l;
@@ -262,20 +261,19 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
handle = param_construct_begin();
-
if (correct_aspect) {
float aspx, aspy;
- uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ ED_uvedit_get_aspect(scene, ob, bm, &aspx, &aspy);
if (aspx != aspy)
param_aspect_ratio(handle, aspx, aspy);
}
/* we need the vert indices */
- BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
continue;
@@ -299,7 +297,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMEditMesh
}
if (!implicit) {
- BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SEAM)) {
ParamKey vkeys[2];
vkeys[0] = (ParamKey)BM_elem_index_get(eed->v1);
@@ -378,7 +376,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B
if (correct_aspect) {
float aspx, aspy;
- uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy);
if (aspx != aspy)
param_aspect_ratio(handle, aspx, aspy);
@@ -522,7 +520,7 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op)
ms->blend = RNA_float_get(op->ptr, "blend");
ms->iterations = RNA_int_get(op->ptr, "iterations");
ms->i = 0;
- ms->handle = construct_param_handle(scene, obedit, em, implicit, fill_holes, 1, 1);
+ ms->handle = construct_param_handle(scene, obedit, em->bm, implicit, fill_holes, 1, 1);
ms->lasttime = PIL_check_seconds_timer();
param_stretch_begin(ms->handle);
@@ -701,16 +699,23 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
/* ******************** Pack Islands operator **************** */
+void ED_uvedit_pack_islands(Scene *scene, Object *ob, BMesh *bm, bool selected, bool correct_aspect, bool do_rotate)
+{
+ ParamHandle *handle;
+ handle = construct_param_handle(scene, ob, bm, true, false, selected, correct_aspect);
+ param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate);
+ param_flush(handle);
+ param_delete(handle);
+}
+
static int pack_islands_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- ParamHandle *handle;
- bool implicit = true;
bool do_rotate = RNA_boolean_get(op->ptr, "rotate");
- if (!uvedit_have_selection(scene, em, implicit)) {
+ if (!uvedit_have_selection(scene, em, true)) {
return OPERATOR_CANCELLED;
}
@@ -719,10 +724,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
else
RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin);
- handle = construct_param_handle(scene, obedit, em, implicit, 0, 1, 1);
- param_pack(handle, scene->toolsettings->uvcalc_margin, do_rotate);
- param_flush(handle);
- param_delete(handle);
+ ED_uvedit_pack_islands(scene, obedit, em->bm, true, true, do_rotate);
DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
@@ -762,7 +764,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
- handle = construct_param_handle(scene, obedit, em, implicit, 0, 1, 1);
+ handle = construct_param_handle(scene, obedit, em->bm, implicit, 0, 1, 1);
param_average(handle);
param_flush(handle);
param_delete(handle);
@@ -807,7 +809,7 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
if (use_subsurf)
liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, false, true);
else
- liveHandle = construct_param_handle(scene, obedit, em, false, fillholes, false, true);
+ liveHandle = construct_param_handle(scene, obedit, em->bm, false, fillholes, false, true);
param_lscm_begin(liveHandle, PARAM_TRUE, abf);
}
@@ -1008,7 +1010,7 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em)
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- uvedit_get_aspect(scene, ob, em, &aspx, &aspy);
+ ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy);
if (aspx == aspy)
return;
@@ -1072,7 +1074,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
if (scale_to_bounds) {
INIT_MINMAX2(min, max);
-
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
@@ -1082,7 +1084,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
minmax_v2v2_v2(min, max, luv->uv);
}
}
-
+
/* rescale UV to be in 1/1 */
dx = (max[0] - min[0]);
dy = (max[1] - min[1]);
@@ -1098,7 +1100,7 @@ static void uv_map_clip_correct(Scene *scene, Object *ob, BMEditMesh *em, wmOper
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-
+
luv->uv[0] = (luv->uv[0] - min[0]) * dx;
luv->uv[1] = (luv->uv[1] - min[1]) * dy;
}
@@ -1128,7 +1130,7 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel)
ParamHandle *handle;
const bool fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0;
- const bool correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) != 0;
+ const bool correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0;
bool use_subsurf;
modifier_unwrap_state(obedit, scene, &use_subsurf);
@@ -1136,7 +1138,7 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel)
if (use_subsurf)
handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect);
else
- handle = construct_param_handle(scene, obedit, em, false, fill_holes, sel, correct_aspect);
+ handle = construct_param_handle(scene, obedit, em->bm, false, fill_holes, sel, correct_aspect);
param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0);
param_lscm_solve(handle);
@@ -1599,39 +1601,30 @@ void UV_OT_cylinder_project(wmOperatorType *ot)
/******************* Cube Project operator ****************/
-static int cube_project_exec(bContext *C, wmOperator *op)
+void ED_uvedit_unwrap_cube_project(Object *ob, BMesh *bm, float cube_size, bool use_select)
{
- Scene *scene = CTX_data_scene(C);
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
/* MTexPoly *tf; */ /* UNUSED */
MLoopUV *luv;
- float cube_size, *loc, dx, dy;
+ float *loc, dx, dy;
int cox, coy;
int cd_loop_uv_offset;
- /* add uvs if they don't exist yet */
- if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
- return OPERATOR_CANCELLED;
- }
+ cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
-
- loc = obedit->obmat[3];
- cube_size = RNA_float_get(op->ptr, "cube_size");
+ loc = ob->obmat[3];
/* choose x,y,z axis for projection depending on the largest normal
* component, but clusters all together around the center of map. */
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
int first = 1;
/* tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
- if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
+ if (use_select && !BM_elem_flag_test(efa, BM_ELEM_SELECT))
continue;
axis_dominant_v3(&cox, &coy, efa->no);
@@ -1642,19 +1635,34 @@ static int cube_project_exec(bContext *C, wmOperator *op)
luv->uv[0] = 0.5f + 0.5f * cube_size * (loc[cox] + l->v->co[cox]);
luv->uv[1] = 0.5f + 0.5f * cube_size * (loc[coy] + l->v->co[coy]);
-
+
if (first) {
dx = floor(luv->uv[0]);
dy = floor(luv->uv[1]);
first = 0;
}
-
+
luv->uv[0] -= dx;
luv->uv[1] -= dy;
}
}
+}
+
+static int cube_project_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ float cube_size = RNA_float_get(op->ptr, "cube_size");
+
+ /* add uvs if they don't exist yet */
+ if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ ED_uvedit_unwrap_cube_project(obedit, em->bm, cube_size, true);
uv_map_clip_correct(scene, obedit, em, op);
DAG_id_tag_update(obedit->data, 0);
diff --git a/source/blender/freestyle/CMakeLists.txt b/source/blender/freestyle/CMakeLists.txt
index cb187eca6ac..c14a5c53734 100644
--- a/source/blender/freestyle/CMakeLists.txt
+++ b/source/blender/freestyle/CMakeLists.txt
@@ -392,6 +392,8 @@ set(SRC
intern/scene_graph/NodeGroup.h
intern/scene_graph/NodeLight.cpp
intern/scene_graph/NodeLight.h
+ intern/scene_graph/NodeSceneRenderLayer.cpp
+ intern/scene_graph/NodeSceneRenderLayer.h
intern/scene_graph/NodeShape.cpp
intern/scene_graph/NodeShape.h
intern/scene_graph/NodeTransform.cpp
@@ -489,6 +491,7 @@ set(SRC
intern/system/TimeUtils.h
intern/view_map/ArbitraryGridDensityProvider.cpp
intern/view_map/ArbitraryGridDensityProvider.h
+ intern/view_map/AutoPtrHelper.h
intern/view_map/AverageAreaGridDensityProvider.cpp
intern/view_map/AverageAreaGridDensityProvider.h
intern/view_map/BoxGrid.cpp
@@ -575,6 +578,6 @@ if(WIN32)
list(APPEND INC_SYS
${PTHREADS_INC}
)
-endif(WIN32)
+endif()
blender_add_lib(bf_freestyle "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/freestyle/intern/application/AppConfig.cpp b/source/blender/freestyle/intern/application/AppConfig.cpp
index cf7959ffaef..44f8e9b135e 100644
--- a/source/blender/freestyle/intern/application/AppConfig.cpp
+++ b/source/blender/freestyle/intern/application/AppConfig.cpp
@@ -31,7 +31,7 @@
using namespace std;
extern "C" {
-#include "BLI_path_util.h"
+#include "BKE_appdir.h"
}
namespace Freestyle {
@@ -43,7 +43,7 @@ Path::Path()
{
// get the root directory
// soc
- setRootDir(BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL));
+ setRootDir(BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, NULL));
_pInstance = this;
}
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index 7ecb4164caf..8d9b1a4fb52 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -40,6 +40,7 @@ extern "C" {
#include "../scene_graph/NodeDrawingStyle.h"
#include "../scene_graph/NodeShape.h"
#include "../scene_graph/NodeTransform.h"
+#include "../scene_graph/NodeSceneRenderLayer.h"
#include "../scene_graph/ScenePrettyPrinter.h"
#include "../scene_graph/VertexRep.h"
@@ -67,6 +68,7 @@ extern "C" {
#include "BKE_global.h"
#include "BLI_utildefines.h"
+#include "BLI_path_util.h"
#include "DNA_freestyle_types.h"
@@ -219,11 +221,10 @@ bool Controller::hitViewMapCache()
if (!_EnableViewMapCache) {
return false;
}
- real hashCode = sceneHashFunc.getValue();
- if (prevSceneHash == hashCode) {
+ if (sceneHashFunc.match()) {
return (NULL != _ViewMap);
}
- prevSceneHash = hashCode;
+ sceneHashFunc.store();
return false;
}
@@ -280,10 +281,27 @@ int Controller::LoadMesh(Render *re, SceneRenderLayer *srl)
return 0;
if (_EnableViewMapCache) {
+
+ NodeCamera *cam;
+ if (freestyle_proj[3][3] != 0.0)
+ cam = new NodeOrthographicCamera;
+ else
+ cam = new NodePerspectiveCamera;
+ double proj[16];
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ proj[i * 4 + j] = freestyle_proj[i][j];
+ }
+ }
+ cam->setProjectionMatrix(proj);
+ _RootNode->AddChild(cam);
+ _RootNode->AddChild(new NodeSceneRenderLayer(*re->scene, *srl));
+
sceneHashFunc.reset();
- blenderScene->accept(sceneHashFunc);
+ //blenderScene->accept(sceneHashFunc);
+ _RootNode->accept(sceneHashFunc);
if (G.debug & G_DEBUG_FREESTYLE) {
- printf("Scene hash : %.16e\n", sceneHashFunc.getValue());
+ cout << "Scene hash : " << sceneHashFunc.toString() << endl;
}
if (hitViewMapCache()) {
ClearRootNode();
@@ -851,7 +869,7 @@ void Controller::DrawStrokes()
real d = _Chrono.stop();
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Strokes generation : " << d << endl;
- cout << "Stroke count : " << _Canvas->stroke_count << endl;
+ cout << "Stroke count : " << _Canvas->getStrokeCount() << endl;
}
resetModified();
DeleteViewMap();
@@ -864,10 +882,13 @@ void Controller::ResetRenderCount()
Render *Controller::RenderStrokes(Render *re, bool render)
{
+ int totmesh = 0;
_Chrono.start();
BlenderStrokeRenderer *blenderRenderer = new BlenderStrokeRenderer(re, ++_render_count);
- if (render)
+ if (render) {
_Canvas->Render(blenderRenderer);
+ totmesh = blenderRenderer->GenerateScene();
+ }
real d = _Chrono.stop();
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Temporary scene generation: " << d << endl;
@@ -886,8 +907,8 @@ Render *Controller::RenderStrokes(Render *re, bool render)
float mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
float megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
- printf("%d verts, %d faces, mem %.2fM (%.2fM, peak %.2fM)\n",
- freestyle_render->i.totvert, freestyle_render->i.totface,
+ printf("%d objs, %d verts, %d faces, mem %.2fM (%.2fM, peak %.2fM)\n",
+ totmesh, freestyle_render->i.totvert, freestyle_render->i.totface,
megs_used_memory, mmap_used_memory, megs_peak_memory);
}
delete blenderRenderer;
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index 57882cbce0c..dfcc77d3b23 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -457,6 +457,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
unsigned nSize = vSize;
float *normals = new float[nSize];
unsigned *numVertexPerFaces = new unsigned[numFaces];
+ vector<Material *> meshMaterials;
vector<FrsMaterial> meshFrsMaterials;
IndexedFaceSet::TRIANGLES_STYLE *faceStyle = new IndexedFaceSet::TRIANGLES_STYLE[numFaces];
@@ -588,20 +589,21 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
tmpMat.setPriority(mat->line_priority);
}
- if (meshFrsMaterials.empty()) {
+ if (meshMaterials.empty()) {
+ meshMaterials.push_back(mat);
meshFrsMaterials.push_back(tmpMat);
shape->setFrsMaterial(tmpMat);
}
else {
- // find if the material is already in the list
+ // find if the Blender material is already in the list
unsigned int i = 0;
bool found = false;
- for (vector<FrsMaterial>::iterator it = meshFrsMaterials.begin(), itend = meshFrsMaterials.end();
+ for (vector<Material *>::iterator it = meshMaterials.begin(), itend = meshMaterials.end();
it != itend;
it++, i++)
{
- if (*it == tmpMat) {
+ if (*it == mat) {
ls.currentMIndex = i;
found = true;
break;
@@ -609,6 +611,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
}
if (!found) {
+ meshMaterials.push_back(mat);
meshFrsMaterials.push_back(tmpMat);
ls.currentMIndex = meshFrsMaterials.size() - 1;
}
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 456118d4d2f..f304e8ae9bd 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -66,6 +66,8 @@ extern "C" {
namespace Freestyle {
+const char *BlenderStrokeRenderer::uvNames[] = {"along_stroke", "along_stroke_tips"};
+
BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : StrokeRenderer()
{
freestyle_bmain = re->freestyle_bmain;
@@ -208,6 +210,8 @@ BlenderStrokeRenderer::~BlenderStrokeRenderer()
if (_use_shading_nodes)
BLI_ghash_free(_nodetree_hash, NULL, NULL);
+
+ FreeStrokeGroups();
}
float BlenderStrokeRenderer::get_stroke_vertex_z(void) const
@@ -414,10 +418,10 @@ Material* BlenderStrokeRenderer::GetStrokeShader(Main *bmain, bNodeTree *iNodeTr
input_uvmap->locy = node->locy;
NodeShaderUVMap *storage = (NodeShaderUVMap *)input_uvmap->storage;
if (node->custom1 & 1) { // use_tips
- BLI_strncpy(storage->uv_map, "along_stroke_tips", sizeof(storage->uv_map));
+ BLI_strncpy(storage->uv_map, uvNames[1], sizeof(storage->uv_map));
}
else {
- BLI_strncpy(storage->uv_map, "along_stroke", sizeof(storage->uv_map));
+ BLI_strncpy(storage->uv_map, uvNames[0], sizeof(storage->uv_map));
}
fromsock = (bNodeSocket *)BLI_findlink(&input_uvmap->outputs, 0); // UV
@@ -440,6 +444,11 @@ Material* BlenderStrokeRenderer::GetStrokeShader(Main *bmain, bNodeTree *iNodeTr
void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
{
+ RenderStrokeRepBasic(iStrokeRep);
+}
+
+void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
+{
if (_use_shading_nodes) {
bNodeTree *nt = iStrokeRep->getNodeTree();
Material *ma = (Material *)BLI_ghash_lookup(_nodetree_hash, nt);
@@ -448,7 +457,7 @@ void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
BLI_ghash_insert(_nodetree_hash, nt, ma);
}
- if (strcmp(freestyle_scene->r.engine, "CYCLES") == 0) {
+ if (STREQ(freestyle_scene->r.engine, RE_engine_id_CYCLES)) {
PointerRNA scene_ptr, freestyle_scene_ptr;
RNA_pointer_create(NULL, &RNA_Scene, old_scene, &scene_ptr);
RNA_pointer_create(NULL, &RNA_Scene, freestyle_scene, &freestyle_scene_ptr);
@@ -509,10 +518,10 @@ void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
// We'll generate both with tips and without tips
// coordinates, on two different UV layers.
if (ma->mtex[a]->texflag & MTEX_TIPS) {
- BLI_strncpy(ma->mtex[a]->uvname, "along_stroke_tips", sizeof(ma->mtex[a]->uvname));
+ BLI_strncpy(ma->mtex[a]->uvname, uvNames[1], sizeof(ma->mtex[a]->uvname));
}
else {
- BLI_strncpy(ma->mtex[a]->uvname, "along_stroke", sizeof(ma->mtex[a]->uvname));
+ BLI_strncpy(ma->mtex[a]->uvname, uvNames[0], sizeof(ma->mtex[a]->uvname));
}
a++;
}
@@ -521,7 +530,42 @@ void BlenderStrokeRenderer::RenderStrokeRep(StrokeRep *iStrokeRep) const
}
}
- RenderStrokeRepBasic(iStrokeRep);
+ const vector<Strip*>& strips = iStrokeRep->getStrips();
+ const bool hasTex = iStrokeRep->hasTex();
+ int totvert = 0, totedge = 0, totpoly = 0, totloop = 0;
+ int visible_faces, visible_segments;
+ for (vector<Strip*>::const_iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
+ Strip::vertex_container& strip_vertices = (*s)->vertices();
+
+ // count visible faces and strip segments
+ test_strip_visibility(strip_vertices, &visible_faces, &visible_segments);
+ if (visible_faces == 0)
+ continue;
+
+ totvert += visible_faces + visible_segments * 2;
+ totedge += visible_faces * 2 + visible_segments;
+ totpoly += visible_faces;
+ totloop += visible_faces * 3;
+ }
+
+ BlenderStrokeRenderer *self = const_cast<BlenderStrokeRenderer *>(this); // FIXME
+ vector<StrokeGroup*> *groups = hasTex ? &self->texturedStrokeGroups : &self->strokeGroups;
+ StrokeGroup *group;
+ if (groups->empty() || !(groups->back()->totvert + totvert < MESH_MAX_VERTS &&
+ groups->back()->totcol + 1 < MAXMAT))
+ {
+ group = new StrokeGroup;
+ groups->push_back(group);
+ }
+ else {
+ group = groups->back();
+ }
+ group->strokes.push_back(iStrokeRep);
+ group->totvert += totvert;
+ group->totedge += totedge;
+ group->totpoly += totpoly;
+ group->totloop += totloop;
+ group->totcol++;
}
// Check if the triangle is visible (i.e., within the render image boundary)
@@ -578,127 +622,173 @@ void BlenderStrokeRenderer::test_strip_visibility(Strip::vertex_container& strip
}
}
-// Build a mesh object representing a stroke
-void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
+// Release allocated memory for stroke groups
+void BlenderStrokeRenderer::FreeStrokeGroups()
{
- vector<Strip*>& strips = iStrokeRep->getStrips();
- const bool hasTex = iStrokeRep->hasTex();
- Strip::vertex_container::iterator v[3];
- StrokeVertexRep *svRep[3];
- unsigned int vertex_index, edge_index, loop_index;
- Vec2r p;
-
- int totvert = 0, totedge = 0, totpoly = 0, totloop = 0;
- int visible_faces, visible_segments;
+ vector<StrokeGroup*>::const_iterator it, itend;
- bool visible;
- for (vector<Strip*>::iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
- Strip::vertex_container& strip_vertices = (*s)->vertices();
+ for (it = strokeGroups.begin(), itend = strokeGroups.end();
+ it != itend; ++it)
+ {
+ delete (*it);
+ }
+ for (it = texturedStrokeGroups.begin(), itend = texturedStrokeGroups.end();
+ it != itend; ++it)
+ {
+ delete (*it);
+ }
+}
- // count visible faces and strip segments
- test_strip_visibility(strip_vertices, &visible_faces, &visible_segments);
- if (visible_faces == 0)
- continue;
+// Build a scene populated by mesh objects representing stylized strokes
+int BlenderStrokeRenderer::GenerateScene()
+{
+ vector<StrokeGroup*>::const_iterator it, itend;
- totvert += visible_faces + visible_segments * 2;
- totedge += visible_faces * 2 + visible_segments;
- totpoly += visible_faces;
- totloop += visible_faces * 3;
+ for (it = strokeGroups.begin(), itend = strokeGroups.end();
+ it != itend; ++it)
+ {
+ GenerateStrokeMesh(*it, false);
+ }
+ for (it = texturedStrokeGroups.begin(), itend = texturedStrokeGroups.end();
+ it != itend; ++it)
+ {
+ GenerateStrokeMesh(*it, true);
}
+ return get_stroke_count();
+}
+
+// Return the number of strokes
+int BlenderStrokeRenderer::get_stroke_count() const
+{
+ return strokeGroups.size() + texturedStrokeGroups.size();
+}
+// Build a mesh object representing a group of stylized strokes
+void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex)
+{
#if 0
Object *object_mesh = BKE_object_add(freestyle_bmain, freestyle_scene, OB_MESH);
#else
Object *object_mesh = NewMesh();
#endif
Mesh *mesh = (Mesh *)object_mesh->data;
- mesh->mat = (Material **)MEM_mallocN(1 * sizeof(Material *), "MaterialList");
- mesh->mat[0] = iStrokeRep->getMaterial();
- mesh->totcol = 1;
- test_object_materials(freestyle_bmain, (ID *)mesh);
-
- // vertices allocation
- mesh->totvert = totvert; // visible_faces + visible_segments * 2;
- CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
-
- // edges allocation
- mesh->totedge = totedge; // visible_faces * 2 + visible_segments;
- CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
- // faces allocation
- mesh->totpoly = totpoly; // visible_faces;
- CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
+ mesh->totvert = group->totvert;
+ mesh->totedge = group->totedge;
+ mesh->totpoly = group->totpoly;
+ mesh->totloop = group->totloop;
+ mesh->totcol = group->totcol;
- // loops allocation
- mesh->totloop = totloop; // visible_faces * 3;
- CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
+ mesh->mvert = (MVert *)CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
+ mesh->medge = (MEdge *)CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
+ mesh->mpoly = (MPoly *)CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
+ mesh->mloop = (MLoop *)CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
- // uv maps
+ MVert *vertices = mesh->mvert;
+ MEdge *edges = mesh->medge;
+ MPoly *polys = mesh->mpoly;
+ MLoop *loops = mesh->mloop;
MLoopUV *loopsuv[2] = { NULL };
- if (hasTex) {
- loopsuv[0] = (MLoopUV *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, "along_stroke");
- loopsuv[1] = (MLoopUV *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, "along_stroke_tips");
- CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, "along_stroke");
- CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, "along_stroke_tips");
+ if (hasTex) {
+ // First UV layer
+ CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, uvNames[0]);
+ CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, uvNames[0]);
+ CustomData_set_layer_active(&mesh->pdata, CD_MTEXPOLY, 0);
+ CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 0);
+ BKE_mesh_update_customdata_pointers(mesh, true);
+ loopsuv[0] = mesh->mloopuv;
+
+ // Second UV layer
+ CustomData_add_layer_named(&mesh->pdata, CD_MTEXPOLY, CD_CALLOC, NULL, mesh->totpoly, uvNames[1]);
+ CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_CALLOC, NULL, mesh->totloop, uvNames[1]);
+ CustomData_set_layer_active(&mesh->pdata, CD_MTEXPOLY, 1);
+ CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 1);
+ BKE_mesh_update_customdata_pointers(mesh, true);
+ loopsuv[1] = mesh->mloopuv;
}
// colors and transparency (the latter represented by grayscale colors)
MLoopCol *colors = (MLoopCol *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop, "Color");
MLoopCol *transp = (MLoopCol *)CustomData_add_layer_named(&mesh->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, mesh->totloop, "Alpha");
+ mesh->mloopcol = colors;
- BKE_mesh_update_customdata_pointers(mesh, true);
+ mesh->mat = (Material **)MEM_mallocN(sizeof(Material *) * mesh->totcol, "MaterialList");
////////////////////
// Data copy
////////////////////
- MVert *vertices = mesh->mvert;
- MEdge *edges = mesh->medge;
- MPoly *polys = mesh->mpoly;
- MLoop *loops = mesh->mloop;
+ int vertex_index = 0, edge_index = 0, loop_index = 0, material_index = 0;
+ int visible_faces, visible_segments;
+ bool visible;
+ Strip::vertex_container::iterator v[3];
+ StrokeVertexRep *svRep[3];
+ Vec2r p;
- vertex_index = edge_index = loop_index = 0;
+ for (vector<StrokeRep*>::const_iterator it = group->strokes.begin(), itend = group->strokes.end();
+ it != itend; ++it)
+ {
+ mesh->mat[material_index] = (*it)->getMaterial();
- for (vector<Strip*>::iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
- Strip::vertex_container& strip_vertices = (*s)->vertices();
- int strip_vertex_count = strip_vertices.size();
+ vector<Strip*>& strips = (*it)->getStrips();
+ for (vector<Strip*>::const_iterator s = strips.begin(), send = strips.end(); s != send; ++s) {
+ Strip::vertex_container& strip_vertices = (*s)->vertices();
+ int strip_vertex_count = strip_vertices.size();
- // count visible faces and strip segments
- test_strip_visibility(strip_vertices, &visible_faces, &visible_segments);
- if (visible_faces == 0)
- continue;
+ // count visible faces and strip segments
+ test_strip_visibility(strip_vertices, &visible_faces, &visible_segments);
+ if (visible_faces == 0)
+ continue;
- v[0] = strip_vertices.begin();
- v[1] = v[0] + 1;
- v[2] = v[0] + 2;
+ v[0] = strip_vertices.begin();
+ v[1] = v[0] + 1;
+ v[2] = v[0] + 2;
- visible = false;
+ visible = false;
- // Note: Mesh generation in the following loop assumes stroke strips
- // to be triangle strips.
- for (int n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
- svRep[0] = *(v[0]);
- svRep[1] = *(v[1]);
- svRep[2] = *(v[2]);
- if (!test_triangle_visibility(svRep)) {
- visible = false;
- }
- else {
- if (!visible) {
- // first vertex
- vertices->co[0] = svRep[0]->point2d()[0];
- vertices->co[1] = svRep[0]->point2d()[1];
- vertices->co[2] = get_stroke_vertex_z();
- vertices->no[0] = 0;
- vertices->no[1] = 0;
- vertices->no[2] = SHRT_MAX;
- ++vertices;
- ++vertex_index;
+ // Note: Mesh generation in the following loop assumes stroke strips
+ // to be triangle strips.
+ for (int n = 2; n < strip_vertex_count; n++, v[0]++, v[1]++, v[2]++) {
+ svRep[0] = *(v[0]);
+ svRep[1] = *(v[1]);
+ svRep[2] = *(v[2]);
+ if (!test_triangle_visibility(svRep)) {
+ visible = false;
+ }
+ else {
+ if (!visible) {
+ // first vertex
+ vertices->co[0] = svRep[0]->point2d()[0];
+ vertices->co[1] = svRep[0]->point2d()[1];
+ vertices->co[2] = get_stroke_vertex_z();
+ vertices->no[0] = 0;
+ vertices->no[1] = 0;
+ vertices->no[2] = SHRT_MAX;
+ ++vertices;
+ ++vertex_index;
+
+ // second vertex
+ vertices->co[0] = svRep[1]->point2d()[0];
+ vertices->co[1] = svRep[1]->point2d()[1];
+ vertices->co[2] = get_stroke_vertex_z();
+ vertices->no[0] = 0;
+ vertices->no[1] = 0;
+ vertices->no[2] = SHRT_MAX;
+ ++vertices;
+ ++vertex_index;
+
+ // first edge
+ edges->v1 = vertex_index - 2;
+ edges->v2 = vertex_index - 1;
+ ++edges;
+ ++edge_index;
+ }
+ visible = true;
- // second vertex
- vertices->co[0] = svRep[1]->point2d()[0];
- vertices->co[1] = svRep[1]->point2d()[1];
+ // vertex
+ vertices->co[0] = svRep[2]->point2d()[0];
+ vertices->co[1] = svRep[2]->point2d()[1];
vertices->co[2] = get_stroke_vertex_z();
vertices->no[0] = 0;
vertices->no[1] = 0;
@@ -706,141 +796,130 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
++vertices;
++vertex_index;
- // first edge
- edges->v1 = vertex_index - 2;
- edges->v2 = vertex_index - 1;
+ // edges
+ edges->v1 = vertex_index - 1;
+ edges->v2 = vertex_index - 3;
++edges;
++edge_index;
- }
- visible = true;
-
- // vertex
- vertices->co[0] = svRep[2]->point2d()[0];
- vertices->co[1] = svRep[2]->point2d()[1];
- vertices->co[2] = get_stroke_vertex_z();
- vertices->no[0] = 0;
- vertices->no[1] = 0;
- vertices->no[2] = SHRT_MAX;
- ++vertices;
- ++vertex_index;
-
- // edges
- edges->v1 = vertex_index - 1;
- edges->v2 = vertex_index - 3;
- ++edges;
- ++edge_index;
-
- edges->v1 = vertex_index - 1;
- edges->v2 = vertex_index - 2;
- ++edges;
- ++edge_index;
-
- // poly
- polys->loopstart = loop_index;
- polys->totloop = 3;
- ++polys;
-
- // Even and odd loops connect triangles vertices differently
- bool is_odd = n % 2;
- // loops
- if (is_odd) {
- loops[0].v = vertex_index - 1;
- loops[0].e = edge_index - 2;
-
- loops[1].v = vertex_index - 3;
- loops[1].e = edge_index - 3;
-
- loops[2].v = vertex_index - 2;
- loops[2].e = edge_index - 1;
- }
- else {
- loops[0].v = vertex_index - 1;
- loops[0].e = edge_index - 1;
- loops[1].v = vertex_index - 2;
- loops[1].e = edge_index - 3;
+ edges->v1 = vertex_index - 1;
+ edges->v2 = vertex_index - 2;
+ ++edges;
+ ++edge_index;
- loops[2].v = vertex_index - 3;
- loops[2].e = edge_index - 2;
- }
- loops += 3;
- loop_index += 3;
-
- // UV
- if (hasTex) {
- // First UV layer (loopsuv[0]) has no tips (texCoord(0)).
- // Second UV layer (loopsuv[1]) has tips: (texCoord(1)).
- for (int L = 0; L < 2; L++) {
- if (is_odd) {
- loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
- loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
-
- loopsuv[L][1].uv[0] = svRep[0]->texCoord(L).x();
- loopsuv[L][1].uv[1] = svRep[0]->texCoord(L).y();
-
- loopsuv[L][2].uv[0] = svRep[1]->texCoord(L).x();
- loopsuv[L][2].uv[1] = svRep[1]->texCoord(L).y();
- }
- else {
- loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
- loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
+ // poly
+ polys->loopstart = loop_index;
+ polys->totloop = 3;
+ polys->mat_nr = material_index;
+ ++polys;
+
+ // Even and odd loops connect triangles vertices differently
+ bool is_odd = n % 2;
+ // loops
+ if (is_odd) {
+ loops[0].v = vertex_index - 1;
+ loops[0].e = edge_index - 2;
- loopsuv[L][1].uv[0] = svRep[1]->texCoord(L).x();
- loopsuv[L][1].uv[1] = svRep[1]->texCoord(L).y();
+ loops[1].v = vertex_index - 3;
+ loops[1].e = edge_index - 3;
- loopsuv[L][2].uv[0] = svRep[0]->texCoord(L).x();
- loopsuv[L][2].uv[1] = svRep[0]->texCoord(L).y();
+ loops[2].v = vertex_index - 2;
+ loops[2].e = edge_index - 1;
+ }
+ else {
+ loops[0].v = vertex_index - 1;
+ loops[0].e = edge_index - 1;
+
+ loops[1].v = vertex_index - 2;
+ loops[1].e = edge_index - 3;
+
+ loops[2].v = vertex_index - 3;
+ loops[2].e = edge_index - 2;
+ }
+ loops += 3;
+ loop_index += 3;
+
+ // UV
+ if (hasTex) {
+ // First UV layer (loopsuv[0]) has no tips (texCoord(0)).
+ // Second UV layer (loopsuv[1]) has tips: (texCoord(1)).
+ for (int L = 0; L < 2; L++) {
+ if (is_odd) {
+ loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
+ loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
+
+ loopsuv[L][1].uv[0] = svRep[0]->texCoord(L).x();
+ loopsuv[L][1].uv[1] = svRep[0]->texCoord(L).y();
+
+ loopsuv[L][2].uv[0] = svRep[1]->texCoord(L).x();
+ loopsuv[L][2].uv[1] = svRep[1]->texCoord(L).y();
+ }
+ else {
+ loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
+ loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
+
+ loopsuv[L][1].uv[0] = svRep[1]->texCoord(L).x();
+ loopsuv[L][1].uv[1] = svRep[1]->texCoord(L).y();
+
+ loopsuv[L][2].uv[0] = svRep[0]->texCoord(L).x();
+ loopsuv[L][2].uv[1] = svRep[0]->texCoord(L).y();
+ }
+ loopsuv[L] += 3;
}
- loopsuv[L] += 3;
}
- }
- // colors and alpha transparency
- if (is_odd) {
- colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
- colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
- colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
- colors[0].a = (short)(255.0f * svRep[2]->alpha());
-
- colors[1].r = (short)(255.0f * svRep[0]->color()[0]);
- colors[1].g = (short)(255.0f * svRep[0]->color()[1]);
- colors[1].b = (short)(255.0f * svRep[0]->color()[2]);
- colors[1].a = (short)(255.0f * svRep[0]->alpha());
-
- colors[2].r = (short)(255.0f * svRep[1]->color()[0]);
- colors[2].g = (short)(255.0f * svRep[1]->color()[1]);
- colors[2].b = (short)(255.0f * svRep[1]->color()[2]);
- colors[2].a = (short)(255.0f * svRep[1]->alpha());
- }
- else {
- colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
- colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
- colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
- colors[0].a = (short)(255.0f * svRep[2]->alpha());
-
- colors[1].r = (short)(255.0f * svRep[1]->color()[0]);
- colors[1].g = (short)(255.0f * svRep[1]->color()[1]);
- colors[1].b = (short)(255.0f * svRep[1]->color()[2]);
- colors[1].a = (short)(255.0f * svRep[1]->alpha());
-
- colors[2].r = (short)(255.0f * svRep[0]->color()[0]);
- colors[2].g = (short)(255.0f * svRep[0]->color()[1]);
- colors[2].b = (short)(255.0f * svRep[0]->color()[2]);
- colors[2].a = (short)(255.0f * svRep[0]->alpha());
+ // colors and alpha transparency
+ if (is_odd) {
+ colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
+ colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
+ colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
+ colors[0].a = (short)(255.0f * svRep[2]->alpha());
+
+ colors[1].r = (short)(255.0f * svRep[0]->color()[0]);
+ colors[1].g = (short)(255.0f * svRep[0]->color()[1]);
+ colors[1].b = (short)(255.0f * svRep[0]->color()[2]);
+ colors[1].a = (short)(255.0f * svRep[0]->alpha());
+
+ colors[2].r = (short)(255.0f * svRep[1]->color()[0]);
+ colors[2].g = (short)(255.0f * svRep[1]->color()[1]);
+ colors[2].b = (short)(255.0f * svRep[1]->color()[2]);
+ colors[2].a = (short)(255.0f * svRep[1]->alpha());
+ }
+ else {
+ colors[0].r = (short)(255.0f * svRep[2]->color()[0]);
+ colors[0].g = (short)(255.0f * svRep[2]->color()[1]);
+ colors[0].b = (short)(255.0f * svRep[2]->color()[2]);
+ colors[0].a = (short)(255.0f * svRep[2]->alpha());
+
+ colors[1].r = (short)(255.0f * svRep[1]->color()[0]);
+ colors[1].g = (short)(255.0f * svRep[1]->color()[1]);
+ colors[1].b = (short)(255.0f * svRep[1]->color()[2]);
+ colors[1].a = (short)(255.0f * svRep[1]->alpha());
+
+ colors[2].r = (short)(255.0f * svRep[0]->color()[0]);
+ colors[2].g = (short)(255.0f * svRep[0]->color()[1]);
+ colors[2].b = (short)(255.0f * svRep[0]->color()[2]);
+ colors[2].a = (short)(255.0f * svRep[0]->alpha());
+ }
+ transp[0].r = transp[0].g = transp[0].b = colors[0].a;
+ transp[1].r = transp[1].g = transp[1].b = colors[1].a;
+ transp[2].r = transp[2].g = transp[2].b = colors[2].a;
+ colors += 3;
+ transp += 3;
}
- transp[0].r = transp[0].g = transp[0].b = colors[0].a;
- transp[1].r = transp[1].g = transp[1].b = colors[1].a;
- transp[2].r = transp[2].g = transp[2].b = colors[2].a;
- colors += 3;
- transp += 3;
- }
- } // loop over strip vertices
- } // loop over strips
-#if 0
- BLI_assert(totvert == vertex_index);
- BLI_assert(totedge == edge_index);
- BLI_assert(totloop == loop_index);
- BKE_mesh_validate(mesh, true);
+ } // loop over strip vertices
+ } // loop over strips
+ material_index++;
+ } // loop over strokes
+
+ test_object_materials(freestyle_bmain, (ID *)mesh);
+
+#if 0 // XXX
+ BLI_assert(mesh->totvert == vertex_index);
+ BLI_assert(mesh->totedge == edge_index);
+ BLI_assert(mesh->totloop == loop_index);
+ BLI_assert(mesh->totcol == material_index);
+ BKE_mesh_validate(mesh, true, true);
#endif
}
@@ -884,7 +963,8 @@ Render *BlenderStrokeRenderer::RenderScene(Render *re, bool render)
Render *freestyle_render = RE_NewRender(freestyle_scene->id.name);
- RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene, render);
+ RE_RenderFreestyleStrokes(freestyle_render, freestyle_bmain, freestyle_scene,
+ render && get_stroke_count() > 0);
return freestyle_render;
}
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
index 74e5d321df2..ec53efa14cd 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.h
@@ -53,6 +53,21 @@ public:
Object *NewMesh() const;
+ struct StrokeGroup {
+ explicit StrokeGroup() : totvert(0), totedge(0), totpoly(0), totloop(0), totcol(0) {}
+ vector<StrokeRep*> strokes;
+ int totvert;
+ int totedge;
+ int totpoly;
+ int totloop;
+ int totcol;
+ };
+ vector<StrokeGroup*> strokeGroups, texturedStrokeGroups;
+
+ int GenerateScene();
+ void GenerateStrokeMesh(StrokeGroup *group, bool hasTex);
+ void FreeStrokeGroups();
+
Render *RenderScene(Render *re, bool render);
static Material* GetStrokeShader(Main *bmain, bNodeTree *iNodeTree, bool do_id_user);
@@ -68,16 +83,20 @@ protected:
bool _use_shading_nodes;
struct GHash *_nodetree_hash;
+ static const char *uvNames[];
+
+ int get_stroke_count() const;
float get_stroke_vertex_z(void) const;
unsigned int get_stroke_mesh_id(void) const;
bool test_triangle_visibility(StrokeVertexRep *svRep[3]) const;
void test_strip_visibility(Strip::vertex_container& strip_vertices,
int *visible_faces, int *visible_segments) const;
+ vector<StrokeRep *> _strokeReps;
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:BlenderStrokeRenderer")
#endif
-
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 4dd4598cc91..32b4c5455a7 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -182,7 +182,7 @@ static void init_camera(Render *re)
{
// It is assumed that imported meshes are in the camera coordinate system.
// Therefore, the view point (i.e., camera position) is at the origin, and
- // the the model-view matrix is simply the identity matrix.
+ // the model-view matrix is simply the identity matrix.
freestyle_viewpoint[0] = 0.0;
freestyle_viewpoint[1] = 0.0;
@@ -496,7 +496,7 @@ void FRS_composite_result(Render *re, SceneRenderLayer *srl, Render *freestyle_r
rl = render_get_active_layer( freestyle_render, freestyle_render->result );
if (!rl || rl->rectf == NULL) {
if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Cannot find Freestyle result image" << endl;
+ cout << "No Freestyle result image to composite" << endl;
}
return;
}
diff --git a/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp b/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp
index dd678ee6fbd..ad54a81f156 100644
--- a/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp
+++ b/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp
@@ -92,10 +92,11 @@ ContextFunctions_get_border(PyObject *self)
{
BBox<Vec2i> border(ContextFunctions::GetBorderCF());
PyObject *v = PyTuple_New(4);
- PyTuple_SET_ITEM(v, 0, PyLong_FromLong(border.getMin().x()));
- PyTuple_SET_ITEM(v, 1, PyLong_FromLong(border.getMin().y()));
- PyTuple_SET_ITEM(v, 2, PyLong_FromLong(border.getMax().x()));
- PyTuple_SET_ITEM(v, 3, PyLong_FromLong(border.getMax().y()));
+ PyTuple_SET_ITEMS(v,
+ PyLong_FromLong(border.getMin().x()),
+ PyLong_FromLong(border.getMin().y()),
+ PyLong_FromLong(border.getMax().x()),
+ PyLong_FromLong(border.getMax().y()));
return v;
}
diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp
index dbd836bc562..4e1a0a119aa 100644
--- a/source/blender/freestyle/intern/python/BPy_Convert.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp
@@ -81,7 +81,7 @@ PyObject *Vector_from_Vec2f(Vec2f& vec)
float vec_data[2]; // because vec->_coord is protected
vec_data[0] = vec.x();
vec_data[1] = vec.y();
- return Vector_CreatePyObject(vec_data, 2, Py_NEW, NULL);
+ return Vector_CreatePyObject(vec_data, 2, NULL);
}
PyObject *Vector_from_Vec3f(Vec3f& vec)
@@ -90,7 +90,7 @@ PyObject *Vector_from_Vec3f(Vec3f& vec)
vec_data[0] = vec.x();
vec_data[1] = vec.y();
vec_data[2] = vec.z();
- return Vector_CreatePyObject(vec_data, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(vec_data, 3, NULL);
}
PyObject *Vector_from_Vec3r(Vec3r& vec)
@@ -99,7 +99,7 @@ PyObject *Vector_from_Vec3r(Vec3r& vec)
vec_data[0] = vec.x();
vec_data[1] = vec.y();
vec_data[2] = vec.z();
- return Vector_CreatePyObject(vec_data, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(vec_data, 3, NULL);
}
PyObject *BPy_Id_from_Id(Id& id)
@@ -401,8 +401,9 @@ PyObject *BPy_CurvePoint_from_CurvePoint(CurvePoint& cp)
PyObject *BPy_directedViewEdge_from_directedViewEdge(ViewVertex::directedViewEdge& dve)
{
PyObject *py_dve = PyTuple_New(2);
- PyTuple_SET_ITEM(py_dve, 0, BPy_ViewEdge_from_ViewEdge(*(dve.first)));
- PyTuple_SET_ITEM(py_dve, 1, PyBool_from_bool(dve.second));
+ PyTuple_SET_ITEMS(py_dve,
+ BPy_ViewEdge_from_ViewEdge(*(dve.first)),
+ PyBool_from_bool(dve.second));
return py_dve;
}
diff --git a/source/blender/freestyle/intern/python/BPy_Convert.h b/source/blender/freestyle/intern/python/BPy_Convert.h
index e6e763e763e..35c1e58369c 100644
--- a/source/blender/freestyle/intern/python/BPy_Convert.h
+++ b/source/blender/freestyle/intern/python/BPy_Convert.h
@@ -92,6 +92,7 @@ extern "C" {
///////////////////////////////////////////////////////////////////////////////////////////
#include "mathutils/mathutils.h"
+#include "generic/python_utildefines.h"
//==============================
// C++ => Python
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
index 5b8d50eb5eb..487a473b7bd 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
@@ -60,6 +60,7 @@ extern "C" {
#include "FRS_freestyle.h"
#include "RNA_access.h"
+#include "BKE_appdir.h"
#include "DNA_scene_types.h"
#include "bpy_rna.h" /* pyrna_struct_CreatePyObject() */
@@ -86,24 +87,24 @@ static PyObject *Freestyle_getCurrentScene(PyObject *self)
static int ramp_blend_type(const char *type)
{
- if (!strcmp(type, "MIX")) return MA_RAMP_BLEND;
- if (!strcmp(type, "ADD")) return MA_RAMP_ADD;
- if (!strcmp(type, "MULTIPLY")) return MA_RAMP_MULT;
- if (!strcmp(type, "SUBTRACT")) return MA_RAMP_SUB;
- if (!strcmp(type, "SCREEN")) return MA_RAMP_SCREEN;
- if (!strcmp(type, "DIVIDE")) return MA_RAMP_DIV;
- if (!strcmp(type, "DIFFERENCE")) return MA_RAMP_DIFF;
- if (!strcmp(type, "DARKEN")) return MA_RAMP_DARK;
- if (!strcmp(type, "LIGHTEN")) return MA_RAMP_LIGHT;
- if (!strcmp(type, "OVERLAY")) return MA_RAMP_OVERLAY;
- if (!strcmp(type, "DODGE")) return MA_RAMP_DODGE;
- if (!strcmp(type, "BURN")) return MA_RAMP_BURN;
- if (!strcmp(type, "HUE")) return MA_RAMP_HUE;
- if (!strcmp(type, "SATURATION")) return MA_RAMP_SAT;
- if (!strcmp(type, "VALUE")) return MA_RAMP_VAL;
- if (!strcmp(type, "COLOR")) return MA_RAMP_COLOR;
- if (!strcmp(type, "SOFT_LIGHT")) return MA_RAMP_SOFT;
- if (!strcmp(type, "LINEAR_LIGHT")) return MA_RAMP_LINEAR;
+ if (STREQ(type, "MIX")) return MA_RAMP_BLEND;
+ if (STREQ(type, "ADD")) return MA_RAMP_ADD;
+ if (STREQ(type, "MULTIPLY")) return MA_RAMP_MULT;
+ if (STREQ(type, "SUBTRACT")) return MA_RAMP_SUB;
+ if (STREQ(type, "SCREEN")) return MA_RAMP_SCREEN;
+ if (STREQ(type, "DIVIDE")) return MA_RAMP_DIV;
+ if (STREQ(type, "DIFFERENCE")) return MA_RAMP_DIFF;
+ if (STREQ(type, "DARKEN")) return MA_RAMP_DARK;
+ if (STREQ(type, "LIGHTEN")) return MA_RAMP_LIGHT;
+ if (STREQ(type, "OVERLAY")) return MA_RAMP_OVERLAY;
+ if (STREQ(type, "DODGE")) return MA_RAMP_DODGE;
+ if (STREQ(type, "BURN")) return MA_RAMP_BURN;
+ if (STREQ(type, "HUE")) return MA_RAMP_HUE;
+ if (STREQ(type, "SATURATION")) return MA_RAMP_SAT;
+ if (STREQ(type, "VALUE")) return MA_RAMP_VAL;
+ if (STREQ(type, "COLOR")) return MA_RAMP_COLOR;
+ if (STREQ(type, "SOFT_LIGHT")) return MA_RAMP_SOFT;
+ if (STREQ(type, "LINEAR_LIGHT")) return MA_RAMP_LINEAR;
return -1;
}
@@ -152,7 +153,7 @@ static PyObject *Freestyle_blendRamp(PyObject *self, PyObject *args)
return NULL;
}
ramp_blend(type, a, fac, b);
- return Vector_CreatePyObject(a, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(a, 3, NULL);
}
#include "BKE_texture.h" /* do_colorband() */
@@ -186,7 +187,7 @@ static PyObject *Freestyle_evaluateColorRamp(PyObject *self, PyObject *args)
PyErr_SetString(PyExc_ValueError, "failed to evaluate the color ramp");
return NULL;
}
- return Vector_CreatePyObject(out, 4, Py_NEW, NULL);
+ return Vector_CreatePyObject(out, 4, NULL);
}
#include "DNA_color_types.h"
@@ -492,7 +493,7 @@ PyObject *Freestyle_Init(void)
PyDict_SetItemString(PySys_GetObject("modules"), module_definition.m_name, module);
// update 'sys.path' for Freestyle Python API modules
- const char * const path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "freestyle");
+ const char * const path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "freestyle");
if (path) {
char modpath[FILE_MAX];
BLI_join_dirfile(modpath, sizeof(modpath), path, "modules");
diff --git a/source/blender/freestyle/intern/python/BPy_Operators.cpp b/source/blender/freestyle/intern/python/BPy_Operators.cpp
index d3cb44f5903..57ec15f4150 100644
--- a/source/blender/freestyle/intern/python/BPy_Operators.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Operators.cpp
@@ -532,8 +532,9 @@ static PyObject *Operators_create(BPy_Operators *self, PyObject *args, PyObject
return NULL;
}
vector<StrokeShader *> shaders;
+ shaders.reserve(PyList_Size(obj2));
for (int i = 0; i < PyList_Size(obj2); i++) {
- PyObject *py_ss = PyList_GetItem(obj2, i);
+ PyObject *py_ss = PyList_GET_ITEM(obj2, i);
if (!BPy_StrokeShader_Check(py_ss)) {
PyErr_SetString(PyExc_TypeError, "Operators.create(): 2nd argument must be a list of StrokeShader objects");
return NULL;
diff --git a/source/blender/freestyle/intern/python/BPy_SShape.cpp b/source/blender/freestyle/intern/python/BPy_SShape.cpp
index e5a38171ecd..11ed07df5de 100644
--- a/source/blender/freestyle/intern/python/BPy_SShape.cpp
+++ b/source/blender/freestyle/intern/python/BPy_SShape.cpp
@@ -227,13 +227,14 @@ PyDoc_STRVAR(SShape_vertices_doc,
static PyObject *SShape_vertices_get(BPy_SShape *self, void *UNUSED(closure))
{
- PyObject *py_vertices = PyList_New(0);
vector< SVertex * > vertices = self->ss->getVertexList();
vector< SVertex * >::iterator it;
+ PyObject *py_vertices = PyList_New(vertices.size());
+ unsigned int i = 0;
for (it = vertices.begin(); it != vertices.end(); it++) {
- PyList_Append(py_vertices, BPy_SVertex_from_SVertex(*(*it)));
+ PyList_SET_ITEM(py_vertices, i++, BPy_SVertex_from_SVertex(*(*it)));
}
return py_vertices;
@@ -246,13 +247,14 @@ PyDoc_STRVAR(SShape_edges_doc,
static PyObject *SShape_edges_get(BPy_SShape *self, void *UNUSED(closure))
{
- PyObject *py_edges = PyList_New(0);
vector< FEdge * > edges = self->ss->getEdgeList();
vector< FEdge * >::iterator it;
+ PyObject *py_edges = PyList_New(edges.size());
+ unsigned int i = 0;
for (it = edges.begin(); it != edges.end(); it++) {
- PyList_Append(py_edges, Any_BPy_FEdge_from_FEdge(*(*it)));
+ PyList_SET_ITEM(py_edges, i++, Any_BPy_FEdge_from_FEdge(*(*it)));
}
return py_edges;
diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
index 2c767eacaec..d933d9f6ed7 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
+++ b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
@@ -207,19 +207,19 @@ PyDoc_STRVAR(ViewShape_vertices_doc,
static PyObject *ViewShape_vertices_get(BPy_ViewShape *self, void *UNUSED(closure))
{
- PyObject *py_vertices = PyList_New(0);
-
vector<ViewVertex *> vertices = self->vs->vertices();
vector<ViewVertex *>::iterator it;
+ PyObject *py_vertices = PyList_New(vertices.size());
+ unsigned int i = 0;
+
for (it = vertices.begin(); it != vertices.end(); it++) {
- PyList_Append( py_vertices, Any_BPy_ViewVertex_from_ViewVertex(*(*it)));
+ PyList_SET_ITEM(py_vertices, i++, Any_BPy_ViewVertex_from_ViewVertex(*(*it)));
}
return py_vertices;
}
static int ViewShape_vertices_set(BPy_ViewShape *self, PyObject *value, void *UNUSED(closure))
{
- PyObject *list = 0;
PyObject *item;
vector< ViewVertex *> v;
@@ -227,8 +227,10 @@ static int ViewShape_vertices_set(BPy_ViewShape *self, PyObject *value, void *UN
PyErr_SetString(PyExc_TypeError, "value must be a list of ViewVertex objects");
return -1;
}
- for (int i = 0; i < PyList_Size(list); i++) {
- item = PyList_GetItem(list, i);
+
+ v.reserve(PyList_GET_SIZE(value));
+ for (unsigned int i = 0; i < PyList_GET_SIZE(value); i++) {
+ item = PyList_GET_ITEM(value, i);
if (BPy_ViewVertex_Check(item)) {
v.push_back(((BPy_ViewVertex *)item)->vv);
}
@@ -248,20 +250,19 @@ PyDoc_STRVAR(ViewShape_edges_doc,
static PyObject *ViewShape_edges_get(BPy_ViewShape *self, void *UNUSED(closure))
{
- PyObject *py_edges = PyList_New(0);
-
vector<ViewEdge *> edges = self->vs->edges();
vector<ViewEdge *>::iterator it;
+ PyObject *py_edges = PyList_New(edges.size());
+ unsigned int i = 0;
for (it = edges.begin(); it != edges.end(); it++) {
- PyList_Append(py_edges, BPy_ViewEdge_from_ViewEdge(*(*it)));
+ PyList_SET_ITEM(py_edges, i++, BPy_ViewEdge_from_ViewEdge(*(*it)));
}
return py_edges;
}
static int ViewShape_edges_set(BPy_ViewShape *self, PyObject *value, void *UNUSED(closure))
{
- PyObject *list = 0;
PyObject *item;
vector<ViewEdge *> v;
@@ -269,8 +270,10 @@ static int ViewShape_edges_set(BPy_ViewShape *self, PyObject *value, void *UNUSE
PyErr_SetString(PyExc_TypeError, "value must be a list of ViewEdge objects");
return -1;
}
- for (int i = 0; i < PyList_Size(list); i++) {
- item = PyList_GetItem(list, i);
+
+ v.reserve(PyList_GET_SIZE(value));
+ for (int i = 0; i < PyList_GET_SIZE(value); i++) {
+ item = PyList_GET_ITEM(value, i);
if (BPy_ViewEdge_Check(item)) {
v.push_back(((BPy_ViewEdge *)item)->ve);
}
diff --git a/source/blender/freestyle/intern/python/Director.cpp b/source/blender/freestyle/intern/python/Director.cpp
index 653fd0b1d29..9f85e84e297 100644
--- a/source/blender/freestyle/intern/python/Director.cpp
+++ b/source/blender/freestyle/intern/python/Director.cpp
@@ -265,8 +265,9 @@ int Director_BPy_UnaryFunction0D___call__(void *uf0D, void *py_uf0D, Interface0D
}
else if (BPy_UnaryFunction0DVectorViewShape_Check(obj)) {
vector<ViewShape*> vec;
+ vec.reserve(PyList_Size(result));
for (int i = 0; i < PyList_Size(result); i++) {
- ViewShape *b = ((BPy_ViewShape *)PyList_GetItem(result, i))->vs;
+ ViewShape *b = ((BPy_ViewShape *)PyList_GET_ITEM(result, i))->vs;
vec.push_back(b);
}
((UnaryFunction0D< vector<ViewShape*> > *)uf0D)->result = vec;
@@ -318,8 +319,9 @@ int Director_BPy_UnaryFunction1D___call__(void *uf1D, void *py_uf1D, Interface1D
}
else if (BPy_UnaryFunction1DVectorViewShape_Check(obj)) {
vector<ViewShape*> vec;
+ vec.reserve(PyList_Size(result));
for (int i = 1; i < PyList_Size(result); i++) {
- ViewShape *b = ((BPy_ViewShape *)PyList_GetItem(result, i))->vs;
+ ViewShape *b = ((BPy_ViewShape *)PyList_GET_ITEM(result, i))->vs;
vec.push_back(b);
}
((UnaryFunction1D< vector<ViewShape*> > *)uf1D)->result = vec;
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
index 6f47ce93ca8..1d51bf287af 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
@@ -342,13 +342,14 @@ PyDoc_STRVAR(SVertex_normals_doc,
static PyObject *SVertex_normals_get(BPy_SVertex *self, void *UNUSED(closure))
{
PyObject *py_normals;
- set< Vec3r > normals;
-
- py_normals = PyList_New(0);
- normals = self->sv->normals();
- for (set< Vec3r >::iterator set_iterator = normals.begin(); set_iterator != normals.end(); set_iterator++) {
- Vec3r v(*set_iterator);
- PyList_Append(py_normals, Vector_from_Vec3r(v));
+ set< Vec3r > normals = self->sv->normals();
+ set< Vec3r >::iterator it;
+ py_normals = PyList_New(normals.size());
+ unsigned int i = 0;
+
+ for (it = normals.begin(); it != normals.end(); it++) {
+ Vec3r v(*it);
+ PyList_SET_ITEM(py_normals, i++, Vector_from_Vec3r(v));
}
return py_normals;
}
@@ -399,13 +400,14 @@ static PyObject *SVertex_curvatures_get(BPy_SVertex *self, void *UNUSED(closure)
Vec3r e2(info->e2.x(), info->e2.y(), info->e2.z());
Vec3r er(info->er.x(), info->er.y(), info->er.z());
PyObject *retval = PyTuple_New(7);
- PyTuple_SET_ITEM(retval, 0, PyFloat_FromDouble(info->K1));
- PyTuple_SET_ITEM(retval, 2, Vector_from_Vec3r(e1));
- PyTuple_SET_ITEM(retval, 1, PyFloat_FromDouble(info->K2));
- PyTuple_SET_ITEM(retval, 3, Vector_from_Vec3r(e2));
- PyTuple_SET_ITEM(retval, 4, PyFloat_FromDouble(info->Kr));
- PyTuple_SET_ITEM(retval, 5, Vector_from_Vec3r(er));
- PyTuple_SET_ITEM(retval, 6, PyFloat_FromDouble(info->dKr));
+ PyTuple_SET_ITEMS(retval,
+ PyFloat_FromDouble(info->K1),
+ PyFloat_FromDouble(info->K2),
+ Vector_from_Vec3r(e1),
+ Vector_from_Vec3r(e2),
+ PyFloat_FromDouble(info->Kr),
+ Vector_from_Vec3r(er),
+ PyFloat_FromDouble(info->dKr));
return retval;
}
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
index 9329bd40c76..edc49eb8004 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
@@ -117,7 +117,7 @@ static PyObject *AdjacencyIterator_iternext(BPy_AdjacencyIterator *self)
self->at_start = false;
else {
self->a_it->increment();
- if (self->a_it->isEnd()){
+ if (self->a_it->isEnd()) {
PyErr_SetNone(PyExc_StopIteration);
return NULL;
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
index c72ab2aba71..2a61dfb075a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.cpp
@@ -112,20 +112,14 @@ static PyObject *UnaryFunction0DVectorViewShape___call__(BPy_UnaryFunction0DVect
}
return NULL;
}
- PyObject *list = PyList_New(0);
- PyObject *item;
- for (unsigned int i = 0; i < self->uf0D_vectorviewshape->result.size(); i++) {
+
+ const unsigned int list_len = self->uf0D_vectorviewshape->result.size();
+ PyObject *list = PyList_New(list_len);
+ for (unsigned int i = 0; i < list_len; i++) {
ViewShape *v = self->uf0D_vectorviewshape->result[i];
- if (v) {
- item = BPy_ViewShape_from_ViewShape(*v);
- }
- else {
- item = Py_None;
- Py_INCREF(item);
- }
- PyList_Append(list, item);
+ PyList_SET_ITEM(list, i, v ? BPy_ViewShape_from_ViewShape(*v) : (Py_INCREF(Py_None), Py_None));
}
-
+
return list;
}
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
index a028952fa69..c15d974e771 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.cpp
@@ -142,18 +142,12 @@ static PyObject *UnaryFunction1DVectorViewShape___call__(BPy_UnaryFunction1DVect
}
return NULL;
}
- PyObject *list = PyList_New(0);
- PyObject *item;
- for (unsigned int i = 0; i < self->uf1D_vectorviewshape->result.size(); i++) {
+
+ const unsigned int list_len = self->uf1D_vectorviewshape->result.size();
+ PyObject *list = PyList_New(list_len);
+ for (unsigned int i = 0; i < list_len; i++) {
ViewShape *v = self->uf1D_vectorviewshape->result[i];
- if (v) {
- item = BPy_ViewShape_from_ViewShape(*v);
- }
- else {
- item = Py_None;
- Py_INCREF(item);
- }
- PyList_Append(list, item);
+ PyList_SET_ITEM(list, i, v ? BPy_ViewShape_from_ViewShape(*v) : (Py_INCREF(Py_None), Py_None));
}
return list;
diff --git a/source/blender/freestyle/intern/scene_graph/NodeCamera.h b/source/blender/freestyle/intern/scene_graph/NodeCamera.h
index 5d84a624830..78c34fdef6d 100644
--- a/source/blender/freestyle/intern/scene_graph/NodeCamera.h
+++ b/source/blender/freestyle/intern/scene_graph/NodeCamera.h
@@ -53,7 +53,9 @@ public:
/*! Default matrices: Identity for both projection and modelview. */
NodeCamera(CameraType camera_type = GENERIC);
+#if 0 /* UNUSED, gives warning in gcc */
NodeCamera(const NodeCamera& iBrother);
+#endif
virtual ~NodeCamera() {}
diff --git a/source/blender/freestyle/intern/scene_graph/NodeSceneRenderLayer.cpp b/source/blender/freestyle/intern/scene_graph/NodeSceneRenderLayer.cpp
new file mode 100644
index 00000000000..24c56ff4e28
--- /dev/null
+++ b/source/blender/freestyle/intern/scene_graph/NodeSceneRenderLayer.cpp
@@ -0,0 +1,35 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/scene_graph/NodeSceneRenderLayer.cpp
+ * \ingroup freestyle
+ * \brief Class to represent a scene render layer in Blender.
+ */
+
+#include "NodeSceneRenderLayer.h"
+
+namespace Freestyle {
+
+void NodeSceneRenderLayer::accept(SceneVisitor& v)
+{
+ v.visitNodeSceneRenderLayer(*this);
+}
+
+} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/scene_graph/NodeSceneRenderLayer.h b/source/blender/freestyle/intern/scene_graph/NodeSceneRenderLayer.h
new file mode 100644
index 00000000000..4b079df5632
--- /dev/null
+++ b/source/blender/freestyle/intern/scene_graph/NodeSceneRenderLayer.h
@@ -0,0 +1,76 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_NODE_SCENE_RENDER_LAYER_H__
+#define __FREESTYLE_NODE_SCENE_RENDER_LAYER_H__
+
+/** \file blender/freestyle/intern/scene_graph/NodeSceneRenderLayer.h
+ * \ingroup freestyle
+ * \brief Class to represent a scene render layer in Blender.
+ */
+
+#include "Node.h"
+
+extern "C" {
+#include "DNA_scene_types.h" /* for Scene and SceneRenderLayer */
+}
+
+using namespace std;
+
+namespace Freestyle {
+
+class NodeSceneRenderLayer : public Node
+{
+public:
+ inline NodeSceneRenderLayer(Scene& scene, SceneRenderLayer& srl) : Node(), _Scene(scene), _SceneRenderLayer(srl) {}
+ virtual ~NodeSceneRenderLayer() {}
+
+ inline struct Scene& scene() const
+ {
+ return _Scene;
+ }
+
+ inline struct SceneRenderLayer& sceneRenderLayer() const
+ {
+ return _SceneRenderLayer;
+ }
+
+ inline void setSceneRenderLayer(Scene& scene)
+ {
+ _Scene = scene;
+ }
+
+ inline void setSceneRenderLayer(SceneRenderLayer& srl)
+ {
+ _SceneRenderLayer = srl;
+ }
+
+ /*! Accept the corresponding visitor */
+ virtual void accept(SceneVisitor& v);
+
+protected:
+
+ Scene& _Scene;
+ SceneRenderLayer& _SceneRenderLayer;
+};
+
+} /* namespace Freestyle */
+
+#endif // __FREESTYLE_NODE_SCENE_RENDER_LAYER_H__
diff --git a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
index 6e8856f1b93..22538736fbf 100644
--- a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
+++ b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
@@ -24,16 +24,61 @@
#include "SceneHash.h"
+#include <sstream>
+
namespace Freestyle {
+string SceneHash::toString()
+{
+ stringstream ss;
+ ss << hex << _sum;
+ return ss.str();
+}
+
+void SceneHash::visitNodeSceneRenderLayer(NodeSceneRenderLayer& node)
+{
+ struct RenderData *r = &node.scene().r;
+ adler32((unsigned char *)&r->xsch, sizeof(r->xsch)); // resolution_x
+ adler32((unsigned char *)&r->ysch, sizeof(r->ysch)); // resolution_y
+ adler32((unsigned char *)&r->size, sizeof(r->size)); // resolution_percentage
+
+ struct FreestyleConfig *config = &node.sceneRenderLayer().freestyleConfig;
+ adler32((unsigned char *)&config->flags, sizeof(config->flags));
+ adler32((unsigned char *)&config->crease_angle, sizeof(config->crease_angle));
+ adler32((unsigned char *)&config->sphere_radius, sizeof(config->sphere_radius));
+ adler32((unsigned char *)&config->dkr_epsilon, sizeof(config->dkr_epsilon));
+}
+
+void SceneHash::visitNodeCamera(NodeCamera& cam)
+{
+ double *proj = cam.projectionMatrix();
+ for (int i = 0; i < 16; i++) {
+ adler32((unsigned char *)&proj[i], sizeof(double));
+ }
+}
+
void SceneHash::visitIndexedFaceSet(IndexedFaceSet& ifs)
{
const real *v = ifs.vertices();
const unsigned n = ifs.vsize();
for (unsigned i = 0; i < n; i++) {
- _hashcode += v[i];
+ adler32((unsigned char *)&v[i], sizeof(v[i]));
+ }
+}
+
+static const int MOD_ADLER = 65521;
+
+void SceneHash::adler32(unsigned char *data, int size)
+{
+ uint32_t sum1 = _sum & 0xffff;
+ uint32_t sum2 = (_sum >> 16) & 0xffff;
+
+ for (int i = 0; i < size; i++) {
+ sum1 = (sum1 + data[i]) % MOD_ADLER;
+ sum2 = (sum1 + sum2) % MOD_ADLER;
}
+ _sum = sum1 | (sum2 << 16);
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/scene_graph/SceneHash.h b/source/blender/freestyle/intern/scene_graph/SceneHash.h
index 8f5f847eaab..9da711673f0 100644
--- a/source/blender/freestyle/intern/scene_graph/SceneHash.h
+++ b/source/blender/freestyle/intern/scene_graph/SceneHash.h
@@ -26,8 +26,12 @@
*/
#include "IndexedFaceSet.h"
+#include "NodeSceneRenderLayer.h"
+#include "NodeCamera.h"
#include "SceneVisitor.h"
+#include "BLI_sys_types.h"
+
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
@@ -39,23 +43,34 @@ class SceneHash : public SceneVisitor
public:
inline SceneHash() : SceneVisitor()
{
- _hashcode = 0.0;
+ _sum = 1;
}
virtual ~SceneHash() {}
+ VISIT_DECL(NodeCamera)
+ VISIT_DECL(NodeSceneRenderLayer)
VISIT_DECL(IndexedFaceSet)
- inline real getValue() {
- return _hashcode;
+ string toString();
+
+ inline bool match() {
+ return _sum == _prevSum;
+ }
+
+ inline void store() {
+ _prevSum = _sum;
}
inline void reset() {
- _hashcode = 0.0;
+ _sum = 1;
}
private:
- real _hashcode;
+ void adler32(unsigned char *data, int size);
+
+ uint32_t _sum;
+ uint32_t _prevSum;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SceneHash")
diff --git a/source/blender/freestyle/intern/scene_graph/SceneVisitor.h b/source/blender/freestyle/intern/scene_graph/SceneVisitor.h
index c00f5124a31..712585c4064 100644
--- a/source/blender/freestyle/intern/scene_graph/SceneVisitor.h
+++ b/source/blender/freestyle/intern/scene_graph/SceneVisitor.h
@@ -56,6 +56,7 @@ class NodeLight;
class NodeCamera;
class NodeDrawingStyle;
class NodeTransform;
+class NodeSceneRenderLayer;
class Rep;
class LineRep;
@@ -87,6 +88,7 @@ public:
VISIT_COMPLETE_DEF(NodeCamera)
VISIT_COMPLETE_DEF(NodeDrawingStyle)
VISIT_COMPLETE_DEF(NodeTransform)
+ VISIT_COMPLETE_DEF(NodeSceneRenderLayer)
VISIT_COMPLETE_DEF(Rep)
VISIT_COMPLETE_DEF(LineRep)
diff --git a/source/blender/freestyle/intern/stroke/Canvas.h b/source/blender/freestyle/intern/stroke/Canvas.h
index b56b5f92c14..5919344b6e0 100644
--- a/source/blender/freestyle/intern/stroke/Canvas.h
+++ b/source/blender/freestyle/intern/stroke/Canvas.h
@@ -95,6 +95,7 @@ protected:
static const char *_MapsPath;
SteerableViewMap *_steerableViewMap;
bool _basic;
+ int stroke_count;
public:
/* Builds the Canvas */
@@ -213,7 +214,10 @@ public:
return false;
}
- int stroke_count;
+ inline int getStrokeCount() const
+ {
+ return stroke_count;
+ }
/*! modifiers */
inline void setSelectedFEdge(FEdge *iFEdge)
diff --git a/source/blender/freestyle/intern/stroke/ChainingIterators.h b/source/blender/freestyle/intern/stroke/ChainingIterators.h
index 5d05ed2776d..4ece24c5ecf 100644
--- a/source/blender/freestyle/intern/stroke/ChainingIterators.h
+++ b/source/blender/freestyle/intern/stroke/ChainingIterators.h
@@ -101,7 +101,7 @@ public:
return _internalIterator.isBegin();
}
- /*! Returns true if the current ViewEdge is is coming towards the iteration vertex. False otherwise. */
+ /*! Returns true if the current ViewEdge is coming towards the iteration vertex. False otherwise. */
bool isIncoming() const;
/*! Returns a *pointer* to the pointed ViewEdge. */
diff --git a/source/blender/freestyle/intern/stroke/Curve.cpp b/source/blender/freestyle/intern/stroke/Curve.cpp
index 32cfac016d6..69c5dcdfe28 100644
--- a/source/blender/freestyle/intern/stroke/Curve.cpp
+++ b/source/blender/freestyle/intern/stroke/Curve.cpp
@@ -25,6 +25,8 @@
* \date 11/01/2003
*/
+#include <stdio.h> /* printf */
+
#include "Curve.h"
#include "CurveIterators.h"
#include "CurveAdvancedIterators.h"
diff --git a/source/blender/freestyle/intern/stroke/Stroke.cpp b/source/blender/freestyle/intern/stroke/Stroke.cpp
index 863da069259..244b20f6b89 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.cpp
+++ b/source/blender/freestyle/intern/stroke/Stroke.cpp
@@ -400,6 +400,7 @@ Stroke::Stroke()
}
_nodeTree = NULL;
_tips = false;
+ _rep = NULL;
}
Stroke::Stroke(const Stroke& iBrother)
@@ -427,6 +428,10 @@ Stroke::Stroke(const Stroke& iBrother)
}
_nodeTree = iBrother._nodeTree;
_tips = iBrother._tips;
+ if (iBrother._rep)
+ _rep = new StrokeRep(*(iBrother._rep));
+ else
+ _rep = NULL;
}
Stroke::~Stroke()
@@ -439,6 +444,10 @@ Stroke::~Stroke()
}
_ViewEdges.clear();
+ if (_rep) {
+ delete _rep;
+ _rep = NULL;
+ }
}
Stroke& Stroke::operator=(const Stroke& iBrother)
@@ -456,6 +465,12 @@ Stroke& Stroke::operator=(const Stroke& iBrother)
_id = iBrother._id;
_ViewEdges = iBrother._ViewEdges;
_sampling = iBrother._sampling;
+ if (_rep)
+ delete _rep;
+ if (iBrother._rep)
+ _rep = new StrokeRep(*(iBrother._rep));
+ else
+ _rep = NULL;
return *this;
}
@@ -757,14 +772,16 @@ void Stroke::ScaleThickness(float iFactor)
void Stroke::Render(const StrokeRenderer *iRenderer)
{
- StrokeRep rep(this);
- iRenderer->RenderStrokeRep(&rep);
+ if (!_rep)
+ _rep = new StrokeRep(this);
+ iRenderer->RenderStrokeRep(_rep);
}
void Stroke::RenderBasic(const StrokeRenderer *iRenderer)
{
- StrokeRep rep(this);
- iRenderer->RenderStrokeRepBasic(&rep);
+ if (!_rep)
+ _rep = new StrokeRep(this);
+ iRenderer->RenderStrokeRep(_rep);
}
Stroke::vertex_iterator Stroke::vertices_begin(float sampling)
diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h
index 8ff801ed144..5f0b4eab309 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.h
+++ b/source/blender/freestyle/intern/stroke/Stroke.h
@@ -549,6 +549,7 @@ private:
MTex *_mtex[MAX_MTEX];
bNodeTree *_nodeTree;
bool _tips;
+ StrokeRep *_rep;
Vec2r _extremityOrientations[2]; // the orientations of the first and last extermity
public:
diff --git a/source/blender/freestyle/intern/stroke/StrokeRep.cpp b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
index f7857107006..ab06e207331 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRep.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeRep.cpp
@@ -425,7 +425,7 @@ void Strip::cleanUpSingularities (const vector<StrokeVertex*>& iStrokeVertices)
Vec2r avP(0.0, 0.0);
for (j = i - timeSinceSingu1; j <= i; j++)
avP = Vec2r(avP + _vertices[2 * j]->point2d());
- avP = Vec2r( 1.0 / float(timeSinceSingu1 + 1) * avP);
+ avP = Vec2r(1.0 / float(timeSinceSingu1 + 1) * avP);
for (j = i - timeSinceSingu1; j <= i; j++)
_vertices[2 * j]->setPoint2d(avP);
//_vertex[2 * j] = _vertex[2 * i];
diff --git a/source/blender/freestyle/intern/system/StringUtils.h b/source/blender/freestyle/intern/system/StringUtils.h
index 77b543c7886..e11798762e4 100644
--- a/source/blender/freestyle/intern/system/StringUtils.h
+++ b/source/blender/freestyle/intern/system/StringUtils.h
@@ -36,7 +36,8 @@
extern "C" {
#include "BKE_utildefines.h"
-#include "BLI_blenlib.h"
+#include "BLI_string.h"
+#include "BLI_path_util.h"
}
using namespace std;
diff --git a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
index 8bc7c0952a8..3243c4d1fb7 100644
--- a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.cpp
@@ -100,22 +100,22 @@ ArbitraryGridDensityProviderFactory::ArbitraryGridDensityProviderFactory(unsigne
ArbitraryGridDensityProviderFactory::~ArbitraryGridDensityProviderFactory() {}
-auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source,
- const real proscenium[4])
+AutoPtr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source,
+ const real proscenium[4])
{
- return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, proscenium, numCells));
+ return AutoPtr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, proscenium, numCells));
}
-auto_ptr<GridDensityProvider>
+AutoPtr<GridDensityProvider>
ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform)
{
- return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, bbox, transform, numCells));
+ return AutoPtr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, bbox, transform, numCells));
}
-auto_ptr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+AutoPtr<GridDensityProvider> ArbitraryGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{
- return auto_ptr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
+ return AutoPtr<GridDensityProvider>(new ArbitraryGridDensityProvider(source, numCells));
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
index 652cb9b34b0..c7939d34da4 100644
--- a/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/ArbitraryGridDensityProvider.h
@@ -58,10 +58,10 @@ public:
ArbitraryGridDensityProviderFactory(unsigned numCells);
~ArbitraryGridDensityProviderFactory();
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected:
unsigned numCells;
diff --git a/source/blender/freestyle/intern/view_map/AutoPtrHelper.h b/source/blender/freestyle/intern/view_map/AutoPtrHelper.h
new file mode 100644
index 00000000000..17a43c184c7
--- /dev/null
+++ b/source/blender/freestyle/intern/view_map/AutoPtrHelper.h
@@ -0,0 +1,60 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_AUTOPTR_HELPER_H__
+#define __FREESTYLE_AUTOPTR_HELPER_H__
+
+/** \file blender/freestyle/intern/view_map/AutoPtrHelper.h
+ * \ingroup freestyle
+ * \brief Utility header for auto_ptr/unique_ptr selection
+ * \author Sergey Sharybin
+ * \date 2015-02-09
+ */
+
+#include <memory>
+
+namespace Freestyle {
+
+#if __cplusplus > 199711L
+template<typename T>
+class AutoPtr : public std::unique_ptr<T> {
+public:
+ AutoPtr() : std::unique_ptr<T>() {}
+ AutoPtr(T *ptr) : std::unique_ptr<T>(ptr) {}
+
+ /* TODO(sergey): Is there more clear way to do this? */
+ template<typename X>
+ AutoPtr(AutoPtr<X>& other) : std::unique_ptr<T>(other.get()) {
+ other.release();
+ }
+};
+#else
+template<typename T>
+class AutoPtr : public std::auto_ptr<T> {
+public:
+ AutoPtr() : std::auto_ptr<T>() {}
+ AutoPtr(T *ptr) : std::auto_ptr<T>(ptr) {}
+ AutoPtr(std::auto_ptr_ref<T> ref) : std::auto_ptr<T>(ref) {}
+};
+#endif
+
+} /* namespace Freestyle */
+
+#endif // __FREESTYLE_AUTOPTR_HELPER_H__
diff --git a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
index 952b9752a3e..b5e133ec441 100644
--- a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.cpp
@@ -121,22 +121,22 @@ AverageAreaGridDensityProviderFactory::AverageAreaGridDensityProviderFactory(rea
AverageAreaGridDensityProviderFactory::~AverageAreaGridDensityProviderFactory() {}
-auto_ptr<GridDensityProvider>
+AutoPtr<GridDensityProvider>
AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{
- return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
+ return AutoPtr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
}
-auto_ptr<GridDensityProvider>
+AutoPtr<GridDensityProvider>
AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform)
{
- return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
+ return AutoPtr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, bbox, transform, sizeFactor));
}
-auto_ptr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+AutoPtr<GridDensityProvider> AverageAreaGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{
- return auto_ptr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor));
+ return AutoPtr<GridDensityProvider>(new AverageAreaGridDensityProvider(source, sizeFactor));
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
index d63557f5cda..2c58cc32da9 100644
--- a/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/AverageAreaGridDensityProvider.h
@@ -55,10 +55,10 @@ public:
AverageAreaGridDensityProviderFactory(real sizeFactor);
~AverageAreaGridDensityProviderFactory();
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected:
real sizeFactor;
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
index a5e526fc490..9827ec68c5d 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
@@ -497,7 +497,7 @@ void FEdgeXDetector::ProcessRidgeFace(WXFace *iFace)
}
}
}
- // Once we have K1 along the the ppal direction compute the derivative : K1b - K1a put it in DotP
+ // Once we have K1 along the ppal direction compute the derivative : K1b - K1a put it in DotP
//real d = fabs(K1_b) - fabs(K1_a);
real d = 0;
real threshold = _meanK1 + (_maxK1 - _meanK1) / 7.0;
diff --git a/source/blender/freestyle/intern/view_map/GridDensityProvider.h b/source/blender/freestyle/intern/view_map/GridDensityProvider.h
index 272d64dd6de..b49e74d6402 100644
--- a/source/blender/freestyle/intern/view_map/GridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/GridDensityProvider.h
@@ -32,6 +32,7 @@
#include <algorithm>
#include <memory>
+#include "AutoPtrHelper.h"
#include "OccluderSource.h"
#include "../geometry/BBox.h"
@@ -148,12 +149,12 @@ class GridDensityProviderFactory
public:
GridDensityProviderFactory() {}
- virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) = 0;
+ virtual AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]) = 0;
- virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform) = 0;
+ virtual AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform) = 0;
- virtual auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) = 0;
+ virtual AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source) = 0;
virtual ~GridDensityProviderFactory () {}
diff --git a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
index 00f5cc90cc4..18edc82b096 100644
--- a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
+++ b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
@@ -36,45 +36,45 @@ HeuristicGridDensityProviderFactory::HeuristicGridDensityProviderFactory(real si
HeuristicGridDensityProviderFactory::~HeuristicGridDensityProviderFactory() {}
-auto_ptr<GridDensityProvider>
+AutoPtr<GridDensityProvider>
HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{
- auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
- auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
+ AutoPtr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
+ AutoPtr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
if (avg->cellSize() > p23->cellSize()) {
- return (auto_ptr<GridDensityProvider>) p23;
+ return (AutoPtr<GridDensityProvider>) p23;
}
else {
- return (auto_ptr<GridDensityProvider>) avg;
+ return (AutoPtr<GridDensityProvider>) avg;
}
}
-auto_ptr<GridDensityProvider>
+AutoPtr<GridDensityProvider>
HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform)
{
- auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox,
- transform, sizeFactor));
- auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
+ AutoPtr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, bbox,
+ transform, sizeFactor));
+ AutoPtr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
if (avg->cellSize() > p23->cellSize()) {
- return (auto_ptr<GridDensityProvider>) p23;
+ return (AutoPtr<GridDensityProvider>) p23;
}
else {
- return (auto_ptr<GridDensityProvider>) avg;
+ return (AutoPtr<GridDensityProvider>) avg;
}
}
-auto_ptr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{
real proscenium[4];
GridDensityProvider::calculateOptimalProscenium(source, proscenium);
- auto_ptr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
- auto_ptr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
+ AutoPtr<AverageAreaGridDensityProvider> avg(new AverageAreaGridDensityProvider(source, proscenium, sizeFactor));
+ AutoPtr<Pow23GridDensityProvider> p23(new Pow23GridDensityProvider(source, proscenium, numFaces));
if (avg->cellSize() > p23->cellSize()) {
- return (auto_ptr<GridDensityProvider>) p23;
+ return (AutoPtr<GridDensityProvider>) p23;
}
else {
- return (auto_ptr<GridDensityProvider>) avg;
+ return (AutoPtr<GridDensityProvider>) avg;
}
}
diff --git a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
index 65f2af6df2f..9414e4931f5 100644
--- a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
+++ b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.h
@@ -42,10 +42,10 @@ public:
HeuristicGridDensityProviderFactory(real sizeFactor, unsigned numFaces);
~HeuristicGridDensityProviderFactory();
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected:
real sizeFactor;
diff --git a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
index e3bb9b87ecc..8dff079e0cf 100644
--- a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
+++ b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.cpp
@@ -99,22 +99,22 @@ Pow23GridDensityProviderFactory::Pow23GridDensityProviderFactory(unsigned numFac
Pow23GridDensityProviderFactory::~Pow23GridDensityProviderFactory () {}
-auto_ptr<GridDensityProvider>
+AutoPtr<GridDensityProvider>
Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const real proscenium[4])
{
- return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, proscenium, numFaces));
+ return AutoPtr<GridDensityProvider>(new Pow23GridDensityProvider(source, proscenium, numFaces));
}
-auto_ptr<GridDensityProvider>
+AutoPtr<GridDensityProvider>
Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
const GridHelpers::Transform& transform)
{
- return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
+ return AutoPtr<GridDensityProvider>(new Pow23GridDensityProvider(source, bbox, transform, numFaces));
}
-auto_ptr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
+AutoPtr<GridDensityProvider> Pow23GridDensityProviderFactory::newGridDensityProvider(OccluderSource& source)
{
- return auto_ptr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
+ return AutoPtr<GridDensityProvider>(new Pow23GridDensityProvider(source, numFaces));
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
index 7f646790ab6..5dfa9cdfc87 100644
--- a/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
+++ b/source/blender/freestyle/intern/view_map/Pow23GridDensityProvider.h
@@ -58,10 +58,10 @@ public:
Pow23GridDensityProviderFactory(unsigned numFaces);
~Pow23GridDensityProviderFactory();
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
- const GridHelpers::Transform& transform);
- auto_ptr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const real proscenium[4]);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source, const BBox<Vec3r>& bbox,
+ const GridHelpers::Transform& transform);
+ AutoPtr<GridDensityProvider> newGridDensityProvider(OccluderSource& source);
protected:
unsigned numFaces;
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
index a0a1282219c..8adc2fa66fd 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
@@ -1300,8 +1300,8 @@ void ViewMapBuilder::computeCusps(ViewMap *ioViewMap)
void ViewMapBuilder::ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox,
real epsilon, bool cull, GridDensityProviderFactory& factory)
{
- auto_ptr<GridHelpers::Transform> transform;
- auto_ptr<OccluderSource> source;
+ AutoPtr<GridHelpers::Transform> transform;
+ AutoPtr<OccluderSource> source;
if (_orthographicProjection) {
transform.reset(new BoxGrid::Transform);
@@ -1317,7 +1317,7 @@ void ViewMapBuilder::ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge&
source.reset(new OccluderSource(*transform, we));
}
- auto_ptr<GridDensityProvider> density(factory.newGridDensityProvider(*source, bbox, *transform));
+ AutoPtr<GridDensityProvider> density(factory.newGridDensityProvider(*source, bbox, *transform));
if (_orthographicProjection) {
BoxGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
@@ -1332,8 +1332,8 @@ void ViewMapBuilder::ComputeCumulativeVisibility(ViewMap *ioViewMap, WingedEdge&
void ViewMapBuilder::ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& we, const BBox<Vec3r>& bbox,
real epsilon, bool cull, GridDensityProviderFactory& factory)
{
- auto_ptr<GridHelpers::Transform> transform;
- auto_ptr<OccluderSource> source;
+ AutoPtr<GridHelpers::Transform> transform;
+ AutoPtr<OccluderSource> source;
if (_orthographicProjection) {
transform.reset(new BoxGrid::Transform);
@@ -1349,7 +1349,7 @@ void ViewMapBuilder::ComputeDetailedVisibility(ViewMap *ioViewMap, WingedEdge& w
source.reset(new OccluderSource(*transform, we));
}
- auto_ptr<GridDensityProvider> density(factory.newGridDensityProvider(*source, bbox, *transform));
+ AutoPtr<GridDensityProvider> density(factory.newGridDensityProvider(*source, bbox, *transform));
if (_orthographicProjection) {
BoxGrid grid(*source, *density, ioViewMap, _viewpoint, _EnableQI);
diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
index 38941b23357..97dcc86cf31 100644
--- a/source/blender/freestyle/intern/winged_edge/Curvature.cpp
+++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp
@@ -211,8 +211,9 @@ bool gts_vertex_gaussian_curvature(WVertex *v, real *Kg)
}
WVertex::incoming_edge_iterator itE;
- for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++)
- area += (*itE)->GetaFace()->getArea();
+ for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
+ area += (*itE)->GetaFace()->getArea();
+ }
for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) {
WOEdge *e = (*itE)->getPrevOnFace();
@@ -535,6 +536,7 @@ void gts_vertex_principal_directions(WVertex *v, Vec3r Kh, real Kg, Vec3r &e1, V
namespace OGF {
+#if 0
inline static real angle(WOEdge *h)
{
const Vec3r& n1 = h->GetbFace()->GetNormal();
@@ -549,6 +551,7 @@ inline static real angle(WOEdge *h)
}
return ::asin(sine);
}
+#endif
// precondition1: P is inside the sphere
// precondition2: P,V points to the outside of the sphere (i.e. OP.V > 0)
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 63eea9486ed..b5d9028a8ae 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -54,17 +54,36 @@ set(SRC
intern/gpu_material.c
intern/gpu_simple_shader.c
intern/gpu_select.c
+ intern/gpu_compositing.c
+ intern/gpu_debug.c
+
+ shaders/gpu_shader_fx_lib.glsl
+ shaders/gpu_shader_fx_ssao_frag.glsl
+ shaders/gpu_shader_fx_dof_frag.glsl
+ shaders/gpu_shader_fx_dof_vert.glsl
+ shaders/gpu_shader_fx_vert.glsl
+ shaders/gpu_shader_material.glsl
+ shaders/gpu_shader_sep_gaussian_blur_frag.glsl
+ shaders/gpu_shader_sep_gaussian_blur_vert.glsl
+ shaders/gpu_shader_simple_frag.glsl
+ shaders/gpu_shader_simple_vert.glsl
+ shaders/gpu_shader_vertex.glsl
+ shaders/gpu_shader_vsm_store_frag.glsl
+ shaders/gpu_shader_vsm_store_vert.glsl
+ shaders/gpu_shader_fx_depth_resolve.glsl
GPU_buffers.h
GPU_draw.h
+ GPU_debug.h
GPU_extensions.h
GPU_glew.h
GPU_init_exit.h
GPU_material.h
GPU_simple_shader.h
GPU_select.h
+ GPU_compositing.h
intern/gpu_codegen.h
- intern/gpu_extensions_private.h
+ intern/gpu_private.h
)
data_to_c_simple(shaders/gpu_shader_material.glsl SRC)
@@ -73,8 +92,15 @@ data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_simple_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_simple_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vertex.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_vertex_world.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_ssao_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_dof_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_dof_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_depth_resolve.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_lib.glsl SRC)
if(WITH_GAMEENGINE)
add_definitions(-DWITH_GAMEENGINE)
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index ba461d5f8a2..e9b600a9267 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -54,6 +54,7 @@ typedef struct GPUBuffer {
int size; /* in bytes */
void *pointer; /* used with vertex arrays */
unsigned int id; /* used with vertex buffer objects */
+ bool use_vbo; /* true for VBOs, false for vertex arrays */
} GPUBuffer;
typedef struct GPUBufferMaterial {
@@ -85,6 +86,7 @@ typedef struct GPUDrawObject {
GPUBuffer *points;
GPUBuffer *normals;
GPUBuffer *uv;
+ GPUBuffer *uv_tex;
GPUBuffer *colors;
GPUBuffer *edges;
GPUBuffer *uvedges;
@@ -113,10 +115,6 @@ typedef struct GPUDrawObject {
/* caches of the original DerivedMesh values */
int totvert;
int totedge;
-
- /* if there was a failure allocating some buffer, use old
- * rendering code */
- bool legacy;
} GPUDrawObject;
/* used for GLSL materials */
@@ -129,7 +127,7 @@ typedef struct GPUAttrib {
void GPU_global_buffer_pool_free(void);
void GPU_global_buffer_pool_free_unused(void);
-GPUBuffer *GPU_buffer_alloc(int size);
+GPUBuffer *GPU_buffer_alloc(int size, bool force_vertex_arrays);
void GPU_buffer_free(GPUBuffer *buffer);
GPUDrawObject *GPU_drawobject_new(struct DerivedMesh *dm);
@@ -161,9 +159,6 @@ void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start,
/* called after drawing */
void GPU_buffer_unbind(void);
-/* used to check whether to use the old (without buffers) code */
-bool GPU_buffer_legacy(struct DerivedMesh *dm);
-
/* Buffers for non-DerivedMesh drawing */
typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers;
diff --git a/source/blender/gpu/GPU_compositing.h b/source/blender/gpu/GPU_compositing.h
new file mode 100644
index 00000000000..93f1bc64922
--- /dev/null
+++ b/source/blender/gpu/GPU_compositing.h
@@ -0,0 +1,96 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Antony Riakiotakis.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_compositing.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_COMPOSITING_H__
+#define __GPU_COMPOSITING_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* opaque handle for framebuffer compositing effects (defined in gpu_compositing.c )*/
+typedef struct GPUFX GPUFX;
+struct GPUDOFSettings;
+struct GPUSSAOSettings;
+struct GPUOffScreen;
+struct GPUFXSettings;
+struct RegionView3D;
+struct rcti;
+struct Scene;
+struct View3D;
+enum eGPUFXFlags;
+
+/**** Public API *****/
+
+typedef enum GPUFXShaderEffect {
+ /* Screen space ambient occlusion shader */
+ GPU_SHADER_FX_SSAO = 1,
+
+ /* depth of field passes. Yep, quite a complex effect */
+ GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE = 2,
+ GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO = 3,
+ GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE = 4,
+ GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR = 5,
+ GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE = 6,
+
+ GPU_SHADER_FX_DEPTH_RESOLVE = 7,
+} GPUFXShaderEffect;
+
+/* keep in synch with enum above! */
+#define MAX_FX_SHADERS 8
+
+/* generate a new FX compositor */
+GPUFX *GPU_fx_compositor_create(void);
+
+/* destroy a text compositor */
+void GPU_fx_compositor_destroy(GPUFX *fx);
+
+/* initialize a framebuffer with size taken from the viewport */
+bool GPU_fx_compositor_initialize_passes(
+ GPUFX *fx, const struct rcti *rect, const struct rcti *scissor_rect,
+ const struct GPUFXSettings *fx_settings);
+
+/* do compositing on the fx passes that have been initialized */
+bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, struct Scene *scene, struct GPUOffScreen *ofs);
+
+/* bind new depth buffer for XRay pass */
+void GPU_fx_compositor_setup_XRay_pass(GPUFX *fx, bool do_xray);
+
+/* resolve a final depth buffer by compositing the XRay and normal depth buffers */
+void GPU_fx_compositor_XRay_resolve(GPUFX *fx);
+
+void GPU_fx_compositor_init_dof_settings(struct GPUDOFSettings *dof);
+void GPU_fx_compositor_init_ssao_settings(struct GPUSSAOSettings *ssao);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __GPU_COMPOSITING_H__
diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/gpu/GPU_debug.h
new file mode 100644
index 00000000000..a74c0e7c67b
--- /dev/null
+++ b/source/blender/gpu/GPU_debug.h
@@ -0,0 +1,77 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Jason Wilkins.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file source/blender/gpu/GPU_debug.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_DEBUG_H__
+#define __GPU_DEBUG_H__
+
+#include "GPU_glew.h"
+
+#include "BLI_utildefines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* prints something if debug mode is active only */
+void GPU_print_error_debug(const char *str);
+
+/* replacement for gluErrorString */
+const char *gpuErrorString(GLenum err);
+
+/* prints current OpenGL state */
+void GPU_state_print(void);
+
+void gpu_assert_no_gl_errors(const char *file, int line, const char *str);
+
+# define GPU_ASSERT_NO_GL_ERRORS(str) gpu_assert_no_gl_errors(__FILE__, __LINE__, (str))
+
+# define GPU_CHECK_ERRORS_AROUND(glProcCall) \
+ ( \
+ GPU_ASSERT_NO_GL_ERRORS("Pre: " #glProcCall), \
+ (glProcCall), \
+ GPU_ASSERT_NO_GL_ERRORS("Post: " #glProcCall) \
+ )
+
+
+#ifdef WITH_GPU_DEBUG
+/* inserts a debug marker message for the debug context messaging system */
+void gpu_string_marker (size_t size, const char *str);
+
+# define GPU_STRING_MARKER(size, str) gpu_string_marker((size), (str))
+#else /* WITH_GPU_DEBUG */
+# define GPU_STRING_MARKER(len, str) ((void)(size),(void)(str))
+#endif /* WITH_GPU_DEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GPU_DEBUG_H__ */
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index 3ddec157c49..57aa7f202b0 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -57,10 +57,6 @@ 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
@@ -127,7 +123,7 @@ void GPU_paint_update_image(struct Image *ima, int x, int y, int w, int h);
void GPU_update_images_framechange(void);
int GPU_update_image_time(struct Image *ima, double time);
int GPU_verify_image(struct Image *ima, struct ImageUser *iuser, int tftile, bool compare, bool mipmap, bool is_data);
-void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int rectw, int recth,
+void GPU_create_gl_tex(unsigned int *bind, unsigned int *rect, float *frect, int rectw, int recth,
bool mipmap, bool use_hight_bit_depth, struct Image *ima);
void GPU_create_gl_tex_compressed(unsigned int *bind, unsigned int *pix, int x, int y, int mipmap, struct Image *ima, struct ImBuf *ibuf);
bool GPU_upload_dxt_texture(struct ImBuf *ibuf);
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 3daf8585539..228bea14e00 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -55,10 +55,10 @@ typedef struct GPUShader GPUShader;
/* GPU extensions support */
void GPU_extensions_disable(void);
-int GPU_print_error(const char *str);
int GPU_glsl_support(void);
int GPU_non_power_of_two_support(void);
+int GPU_vertex_buffer_support(void);
int GPU_display_list_support(void);
int GPU_color_depth(void);
void GPU_code_generate_glsl_lib(void);
@@ -107,11 +107,19 @@ int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver);
* - if created with from_blender, will not free the texture
*/
+typedef enum GPUHDRType {
+ GPU_HDR_NONE = 0,
+ GPU_HDR_HALF_FLOAT = 1,
+ GPU_HDR_FULL_FLOAT = (1 << 1),
+} GPUHDRType;
+
GPUTexture *GPU_texture_create_1D(int w, float *pixels, char err_out[256]);
-GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels, GPUHDRType hdr, char err_out[256]);
GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *fpixels);
GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256]);
+GPUTexture *GPU_texture_create_2D_procedural(int w, int h, float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_1D_procedural(int w, float *pixels, char err_out[256]);
GPUTexture *GPU_texture_from_blender(struct Image *ima,
struct ImageUser *iuser, bool is_data, double time, int mipmap);
GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
@@ -126,6 +134,8 @@ void GPU_texture_ref(GPUTexture *tex);
void GPU_texture_bind(GPUTexture *tex, int number);
void GPU_texture_unbind(GPUTexture *tex);
+void GPU_depth_texture_mode(GPUTexture *tex, bool compare, bool use_filter);
+
GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex);
int GPU_texture_target(GPUTexture *tex);
@@ -140,12 +150,17 @@ int GPU_texture_opengl_bindcode(GPUTexture *tex);
* - after any of the GPU_framebuffer_* functions, GPU_framebuffer_restore must
* be called before rendering to the window framebuffer again */
+void GPU_texture_bind_as_framebuffer(GPUTexture *tex);
+
GPUFrameBuffer *GPU_framebuffer_create(void);
-int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err_out[256]);
-void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex);
-void GPU_framebuffer_texture_bind(GPUFrameBuffer *fb, GPUTexture *tex, int w, int h);
+int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256]);
+void GPU_framebuffer_texture_detach(GPUTexture *tex);
+void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot);
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex);
void GPU_framebuffer_free(GPUFrameBuffer *fb);
+bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]);
+
+void GPU_framebuffer_bind_no_save(GPUFrameBuffer *fb, int slot);
void GPU_framebuffer_restore(void);
void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *blurfb, GPUTexture *blurtex);
@@ -156,8 +171,8 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b
GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256]);
void GPU_offscreen_free(GPUOffScreen *ofs);
-void GPU_offscreen_bind(GPUOffScreen *ofs);
-void GPU_offscreen_unbind(GPUOffScreen *ofs);
+void GPU_offscreen_bind(GPUOffScreen *ofs, bool save);
+void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore);
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels);
int GPU_offscreen_width(GPUOffScreen *ofs);
int GPU_offscreen_height(GPUOffScreen *ofs);
@@ -174,7 +189,7 @@ void GPU_shader_unbind(void);
int GPU_shader_get_uniform(GPUShader *shader, const char *name);
void GPU_shader_uniform_vector(GPUShader *shader, int location, int length,
- int arraysize, float *value);
+ int arraysize, const float *value);
void GPU_shader_uniform_texture(GPUShader *shader, int location, GPUTexture *tex);
void GPU_shader_uniform_int(GPUShader *shader, int location, int value);
@@ -187,6 +202,8 @@ typedef enum GPUBuiltinShader {
} GPUBuiltinShader;
GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader);
+GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp);
+
void GPU_shader_free_builtin_shaders(void);
/* Vertex attributes for shaders */
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index a111401343e..64ce936e64a 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -32,6 +32,7 @@
#ifndef __GPU_MATERIAL_H__
#define __GPU_MATERIAL_H__
+#include "DNA_customdata_types.h" /* for CustomDataType */
#include "DNA_listBase.h"
#include "BLI_sys_types.h" /* for bool */
@@ -58,6 +59,7 @@ struct GPUMaterial;
struct GPUTexture;
struct GPULamp;
struct PreviewImage;
+struct World;
typedef struct GPUNode GPUNode;
typedef struct GPUNodeLink GPUNodeLink;
@@ -67,6 +69,7 @@ typedef struct GPULamp GPULamp;
/* Functions to create GPU Materials nodes */
typedef enum GPUType {
+ /* The value indicates the number of elements in each type */
GPU_NONE = 0,
GPU_FLOAT = 1,
GPU_VEC2 = 2,
@@ -74,20 +77,22 @@ typedef enum GPUType {
GPU_VEC4 = 4,
GPU_MAT3 = 9,
GPU_MAT4 = 16,
+
GPU_TEX2D = 1002,
GPU_SHADOW2D = 1003,
GPU_ATTRIB = 3001
} GPUType;
typedef enum GPUBuiltin {
- GPU_VIEW_MATRIX = 1,
- GPU_OBJECT_MATRIX = 2,
- GPU_INVERSE_VIEW_MATRIX = 4,
- GPU_INVERSE_OBJECT_MATRIX = 8,
- GPU_VIEW_POSITION = 16,
- GPU_VIEW_NORMAL = 32,
- GPU_OBCOLOR = 64,
- GPU_AUTO_BUMPSCALE = 128,
+ GPU_VIEW_MATRIX = (1 << 0),
+ GPU_OBJECT_MATRIX = (1 << 1),
+ GPU_INVERSE_VIEW_MATRIX = (1 << 2),
+ GPU_INVERSE_OBJECT_MATRIX = (1 << 3),
+ GPU_VIEW_POSITION = (1 << 4),
+ GPU_VIEW_NORMAL = (1 << 5),
+ GPU_OBCOLOR = (1 << 6),
+ GPU_AUTO_BUMPSCALE = (1 << 7),
+ GPU_CAMERA_TEXCO_FACTORS = (1 << 8),
} GPUBuiltin;
typedef enum GPUOpenGLBuiltin {
@@ -95,6 +100,12 @@ typedef enum GPUOpenGLBuiltin {
GPU_COLOR = 2,
} GPUOpenGLBuiltin;
+typedef enum GPUMatType {
+ GPU_MATERIAL_TYPE_MESH = 1,
+ GPU_MATERIAL_TYPE_WORLD = 2,
+} GPUMatType;
+
+
typedef enum GPUBlendMode {
GPU_BLEND_SOLID = 0,
GPU_BLEND_ADD = 1,
@@ -113,13 +124,40 @@ typedef struct GPUNodeStack {
short sockettype;
} GPUNodeStack;
-GPUNodeLink *GPU_attribute(int type, const char *name);
+typedef enum GPUDynamicType {
+ GPU_DYNAMIC_NONE = 0,
+ GPU_DYNAMIC_OBJECT_VIEWMAT = 1,
+ GPU_DYNAMIC_OBJECT_MAT = 2,
+ GPU_DYNAMIC_OBJECT_VIEWIMAT = 3,
+ GPU_DYNAMIC_OBJECT_IMAT = 4,
+ GPU_DYNAMIC_OBJECT_COLOR = 5,
+ GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE = 15,
+
+ GPU_DYNAMIC_LAMP_FIRST = 6,
+ GPU_DYNAMIC_LAMP_DYNVEC = 6,
+ GPU_DYNAMIC_LAMP_DYNCO = 7,
+ GPU_DYNAMIC_LAMP_DYNIMAT = 8,
+ GPU_DYNAMIC_LAMP_DYNPERSMAT = 9,
+ GPU_DYNAMIC_LAMP_DYNENERGY = 10,
+ GPU_DYNAMIC_LAMP_DYNCOL = 11,
+ GPU_DYNAMIC_LAMP_LAST = 11,
+ GPU_DYNAMIC_SAMPLER_2DBUFFER = 12,
+ GPU_DYNAMIC_SAMPLER_2DIMAGE = 13,
+ GPU_DYNAMIC_SAMPLER_2DSHADOW = 14,
+ GPU_DYNAMIC_LAMP_DISTANCE = 16,
+ GPU_DYNAMIC_LAMP_ATT1 = 17,
+ GPU_DYNAMIC_LAMP_ATT2 = 18,
+ GPU_DYNAMIC_LAMP_SPOTSIZE = 19,
+ GPU_DYNAMIC_LAMP_SPOTBLEND = 20,
+} GPUDynamicType;
+
+GPUNodeLink *GPU_attribute(CustomDataType type, const char *name);
GPUNodeLink *GPU_uniform(float *num);
-GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data);
+GPUNodeLink *GPU_dynamic_uniform(float *num, GPUDynamicType dynamictype, void *data);
GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, bool is_data);
GPUNodeLink *GPU_image_preview(struct PreviewImage *prv);
GPUNodeLink *GPU_texture(int size, float *pixels);
-GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, int dynamictype, void *data);
+GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, GPUDynamicType dynamictype, void *data);
GPUNodeLink *GPU_builtin(GPUBuiltin builtin);
GPUNodeLink *GPU_opengl_builtin(GPUOpenGLBuiltin builtin);
@@ -131,19 +169,21 @@ void GPU_material_enable_alpha(GPUMaterial *material);
GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
/* High level functions to create and use GPU materials */
+GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo);
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma);
GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma);
-void GPU_material_free(struct Material *ma);
+void GPU_material_free(struct ListBase *gpumaterial);
void GPU_materials_free(void);
bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
-void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4], bool scenelock);
+void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock);
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float obcol[4], float autobumpscale);
void GPU_material_unbind(GPUMaterial *material);
int GPU_material_bound(GPUMaterial *material);
struct Scene *GPU_material_scene(GPUMaterial *material);
+GPUMatType GPU_Material_get_type(GPUMaterial *material);
void GPU_material_vertex_attributes(GPUMaterial *material,
struct GPUVertexAttribs *attrib);
@@ -159,6 +199,7 @@ typedef struct GPUShadeInput {
GPUNodeLink *rgb, *specrgb, *vn, *view, *vcol, *ref;
GPUNodeLink *alpha, *refl, *spec, *emit, *har, *amb;
+ GPUNodeLink *spectra;
} GPUShadeInput;
typedef struct GPUShadeResult {
@@ -170,33 +211,6 @@ void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr);
/* Export GLSL shader */
-typedef enum GPUDynamicType {
- GPU_DYNAMIC_NONE = 0,
- GPU_DYNAMIC_OBJECT_VIEWMAT = 1,
- GPU_DYNAMIC_OBJECT_MAT = 2,
- GPU_DYNAMIC_OBJECT_VIEWIMAT = 3,
- GPU_DYNAMIC_OBJECT_IMAT = 4,
- GPU_DYNAMIC_OBJECT_COLOR = 5,
- GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE = 15,
-
- GPU_DYNAMIC_LAMP_FIRST = 6,
- GPU_DYNAMIC_LAMP_DYNVEC = 6,
- GPU_DYNAMIC_LAMP_DYNCO = 7,
- GPU_DYNAMIC_LAMP_DYNIMAT = 8,
- GPU_DYNAMIC_LAMP_DYNPERSMAT = 9,
- GPU_DYNAMIC_LAMP_DYNENERGY = 10,
- GPU_DYNAMIC_LAMP_DYNCOL = 11,
- GPU_DYNAMIC_LAMP_LAST = 11,
- GPU_DYNAMIC_SAMPLER_2DBUFFER = 12,
- GPU_DYNAMIC_SAMPLER_2DIMAGE = 13,
- GPU_DYNAMIC_SAMPLER_2DSHADOW = 14,
- GPU_DYNAMIC_LAMP_DISTANCE = 16,
- GPU_DYNAMIC_LAMP_ATT1 = 17,
- GPU_DYNAMIC_LAMP_ATT2 = 18,
- GPU_DYNAMIC_LAMP_SPOTSIZE = 19,
- GPU_DYNAMIC_LAMP_SPOTBLEND = 20,
-} GPUDynamicType;
-
typedef enum GPUDataType {
GPU_DATA_NONE = 0,
GPU_DATA_1I = 1, // 1 integer
@@ -257,7 +271,7 @@ void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float ener
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2);
void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend);
int GPU_lamp_shadow_layer(GPULamp *lamp);
-GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **col, GPUNodeLink **lv, GPUNodeLink **dist, GPUNodeLink **shadow);
+GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **col, GPUNodeLink **lv, GPUNodeLink **dist, GPUNodeLink **shadow, GPUNodeLink **energy);
#ifdef __cplusplus
}
diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript
index f11ecafc986..f52b39dba3b 100644
--- a/source/blender/gpu/SConscript
+++ b/source/blender/gpu/SConscript
@@ -65,10 +65,17 @@ import os
sources.extend((
os.path.join(env['DATA_SOURCES'], "gpu_shader_simple_frag.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_simple_vert.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_fx_ssao_frag.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_fx_dof_frag.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_fx_dof_vert.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_fx_depth_resolve.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_fx_lib.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_fx_vert.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_material.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_frag.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_vert.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex_world.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_frag.glsl.c"),
os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_vert.glsl.c"),
))
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index b5a576b509c..56167d466f1 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -46,13 +46,11 @@
#include "BLI_ghash.h"
#include "BLI_threads.h"
-#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_ccg.h"
#include "BKE_DerivedMesh.h"
#include "BKE_paint.h"
-#include "BKE_material.h"
#include "BKE_pbvh.h"
#include "DNA_userdef_types.h"
@@ -76,7 +74,6 @@ typedef enum {
#define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n))
/* -1 - undefined, 0 - vertex arrays, 1 - VBOs */
-static int useVBOs = -1;
static GPUBufferState GLStates = 0;
static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } };
@@ -111,10 +108,6 @@ static GPUBufferPool *gpu_buffer_pool_new(void)
{
GPUBufferPool *pool;
- /* enable VBOs if supported */
- if (useVBOs == -1)
- useVBOs = (GLEW_ARB_vertex_buffer_object ? 1 : 0);
-
pool = MEM_callocN(sizeof(GPUBufferPool), "GPUBuffer_Pool");
pool->maxsize = MAX_FREE_GPU_BUFFERS;
@@ -158,7 +151,7 @@ static void gpu_buffer_pool_delete_last(GPUBufferPool *pool)
return;
/* delete the buffer's data */
- if (useVBOs)
+ if (last->use_vbo)
glDeleteBuffersARB(1, &last->id);
else
MEM_freeN(last->pointer);
@@ -194,8 +187,10 @@ static void gpu_buffer_pool_free_unused(GPUBufferPool *pool)
while (pool->totbuf)
gpu_buffer_pool_delete_last(pool);
- glDeleteBuffersARB(pool->totpbvhbufids, pool->pbvhbufids);
- pool->totpbvhbufids = 0;
+ if (pool->totpbvhbufids > 0) {
+ glDeleteBuffersARB(pool->totpbvhbufids, pool->pbvhbufids);
+ pool->totpbvhbufids = 0;
+ }
BLI_mutex_unlock(&buffer_mutex);
}
@@ -226,7 +221,7 @@ void GPU_global_buffer_pool_free_unused(void)
*
* Thread-unsafe version for internal usage only.
*/
-static GPUBuffer *gpu_buffer_alloc_intern(int size)
+static GPUBuffer *gpu_buffer_alloc_intern(int size, bool use_VBO)
{
GPUBufferPool *pool;
GPUBuffer *buf;
@@ -251,6 +246,11 @@ static GPUBuffer *gpu_buffer_alloc_intern(int size)
for (i = 0; i < pool->totbuf; i++) {
bufsize = pool->buffers[i]->size;
+ /* only return a buffer that matches the VBO preference */
+ if (pool->buffers[i]->use_vbo != use_VBO) {
+ continue;
+ }
+
/* check for an exact size match */
if (bufsize == size) {
bestfit = i;
@@ -279,8 +279,9 @@ static GPUBuffer *gpu_buffer_alloc_intern(int size)
/* no acceptable buffer found in the pool, create a new one */
buf = MEM_callocN(sizeof(GPUBuffer), "GPUBuffer");
buf->size = size;
+ buf->use_vbo = use_VBO;
- if (useVBOs == 1) {
+ if (use_VBO) {
/* create a new VBO and initialize it to the requested
* size */
glGenBuffersARB(1, &buf->id);
@@ -307,9 +308,10 @@ static GPUBuffer *gpu_buffer_alloc_intern(int size)
}
/* Same as above, but safe for threading. */
-GPUBuffer *GPU_buffer_alloc(int size)
+GPUBuffer *GPU_buffer_alloc(int size, bool force_vertex_arrays)
{
GPUBuffer *buffer;
+ bool use_VBOs = (GLEW_ARB_vertex_buffer_object) && !(U.gameflags & USER_DISABLE_VBO) && !force_vertex_arrays;
if (size == 0) {
/* Early out, no lock needed in this case. */
@@ -317,7 +319,7 @@ GPUBuffer *GPU_buffer_alloc(int size)
}
BLI_mutex_lock(&buffer_mutex);
- buffer = gpu_buffer_alloc_intern(size);
+ buffer = gpu_buffer_alloc_intern(size, use_VBOs);
BLI_mutex_unlock(&buffer_mutex);
return buffer;
@@ -577,6 +579,7 @@ void GPU_drawobject_free(DerivedMesh *dm)
GPU_buffer_free(gdo->points);
GPU_buffer_free(gdo->normals);
GPU_buffer_free(gdo->uv);
+ GPU_buffer_free(gdo->uv_tex);
GPU_buffer_free(gdo->colors);
GPU_buffer_free(gdo->edges);
GPU_buffer_free(gdo->uvedges);
@@ -585,6 +588,22 @@ void GPU_drawobject_free(DerivedMesh *dm)
dm->drawObject = NULL;
}
+static GPUBuffer *gpu_try_realloc(GPUBufferPool *pool, GPUBuffer *buffer, int size, bool use_VBOs)
+{
+ gpu_buffer_free_intern(buffer);
+ gpu_buffer_pool_delete_last(pool);
+ buffer = NULL;
+
+ /* try freeing an entry from the pool
+ * and reallocating the buffer */
+ if (pool->totbuf > 0) {
+ gpu_buffer_pool_delete_last(pool);
+ buffer = gpu_buffer_alloc_intern(size, use_VBOs);
+ }
+
+ return buffer;
+}
+
typedef void (*GPUBufferCopyFunc)(DerivedMesh *dm, float *varray, int *index,
int *mat_orig_to_new, void *user_data);
@@ -598,7 +617,7 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object,
int *mat_orig_to_new;
int *cur_index_per_mat;
int i;
- bool success;
+ bool use_VBOs = (GLEW_ARB_vertex_buffer_object) && !(U.gameflags & USER_DISABLE_VBO);
GLboolean uploaded;
pool = gpu_get_global_buffer_pool();
@@ -606,11 +625,7 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object,
BLI_mutex_lock(&buffer_mutex);
/* alloc a GPUBuffer; fall back to legacy mode on failure */
- if (!(buffer = gpu_buffer_alloc_intern(size)))
- dm->drawObject->legacy = 1;
-
- /* nothing to do for legacy mode */
- if (dm->drawObject->legacy) {
+ if (!(buffer = gpu_buffer_alloc_intern(size, use_VBOs))) {
BLI_mutex_unlock(&buffer_mutex);
return NULL;
}
@@ -628,8 +643,8 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object,
mat_orig_to_new[object->materials[i].mat_nr] = i;
}
- if (useVBOs) {
- success = 0;
+ if (use_VBOs) {
+ bool success = false;
while (!success) {
/* bind the buffer and discard previous data,
@@ -639,32 +654,22 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object,
/* attempt to map the buffer */
if (!(varray = glMapBufferARB(target, GL_WRITE_ONLY_ARB))) {
- /* failed to map the buffer; delete it */
- gpu_buffer_free_intern(buffer);
- gpu_buffer_pool_delete_last(pool);
- buffer = NULL;
-
- /* try freeing an entry from the pool
- * and reallocating the buffer */
- if (pool->totbuf > 0) {
- gpu_buffer_pool_delete_last(pool);
- buffer = gpu_buffer_alloc_intern(size);
- }
+ buffer = gpu_try_realloc(pool, buffer, size, true);
/* allocation still failed; fall back
* to legacy mode */
if (!buffer) {
- dm->drawObject->legacy = 1;
- success = 1;
+ use_VBOs = false;
+ success = true;
}
}
else {
- success = 1;
+ success = true;
}
}
/* check legacy fallback didn't happen */
- if (dm->drawObject->legacy == 0) {
+ if (use_VBOs) {
uploaded = GL_FALSE;
/* attempt to upload the data to the VBO */
while (uploaded == GL_FALSE) {
@@ -677,15 +682,16 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object,
}
glBindBufferARB(target, 0);
}
- else {
+ if (!use_VBOs) {
/* VBO not supported, use vertex array fallback */
- if (buffer->pointer) {
+ if (!buffer || !buffer->pointer) {
+ buffer = gpu_try_realloc(pool, buffer, size, false);
+ }
+
+ if (buffer) {
varray = buffer->pointer;
(*copy_f)(dm, varray, cur_index_per_mat, mat_orig_to_new, user);
}
- else {
- dm->drawObject->legacy = 1;
- }
}
MEM_freeN(cur_index_per_mat);
@@ -1019,7 +1025,7 @@ static GPUBuffer **gpu_drawobject_buffer_from_type(GPUDrawObject *gdo, GPUBuffer
case GPU_BUFFER_UV:
return &gdo->uv;
case GPU_BUFFER_UV_TEXPAINT:
- return &gdo->uv;
+ return &gdo->uv_tex;
case GPU_BUFFER_EDGE:
return &gdo->edges;
case GPU_BUFFER_UVEDGE:
@@ -1105,7 +1111,7 @@ void GPU_vertex_setup(DerivedMesh *dm)
return;
glEnableClientState(GL_VERTEX_ARRAY);
- if (useVBOs) {
+ if (dm->drawObject->points->use_vbo) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->points->id);
glVertexPointer(3, GL_FLOAT, 0, 0);
}
@@ -1122,7 +1128,7 @@ void GPU_normal_setup(DerivedMesh *dm)
return;
glEnableClientState(GL_NORMAL_ARRAY);
- if (useVBOs) {
+ if (dm->drawObject->normals->use_vbo) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->normals->id);
glNormalPointer(GL_FLOAT, 0, 0);
}
@@ -1139,7 +1145,7 @@ void GPU_uv_setup(DerivedMesh *dm)
return;
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- if (useVBOs) {
+ if (dm->drawObject->uv->use_vbo) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
}
@@ -1156,8 +1162,8 @@ void GPU_texpaint_uv_setup(DerivedMesh *dm)
return;
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- if (useVBOs) {
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id);
+ if (dm->drawObject->uv_tex->use_vbo) {
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv_tex->id);
glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0);
glClientActiveTexture(GL_TEXTURE2);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -1165,10 +1171,10 @@ void GPU_texpaint_uv_setup(DerivedMesh *dm)
glClientActiveTexture(GL_TEXTURE0);
}
else {
- glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), dm->drawObject->uv->pointer);
+ glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), dm->drawObject->uv_tex->pointer);
glClientActiveTexture(GL_TEXTURE2);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)dm->drawObject->uv->pointer + 2 * sizeof(float));
+ glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)dm->drawObject->uv_tex->pointer + 2 * sizeof(float));
glClientActiveTexture(GL_TEXTURE0);
}
@@ -1202,7 +1208,7 @@ void GPU_color_setup(DerivedMesh *dm, int colType)
return;
glEnableClientState(GL_COLOR_ARRAY);
- if (useVBOs) {
+ if (dm->drawObject->colors->use_vbo) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->colors->id);
glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
}
@@ -1222,7 +1228,7 @@ void GPU_edge_setup(DerivedMesh *dm)
return;
glEnableClientState(GL_VERTEX_ARRAY);
- if (useVBOs) {
+ if (dm->drawObject->points->use_vbo) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->points->id);
glVertexPointer(3, GL_FLOAT, 0, 0);
}
@@ -1232,7 +1238,7 @@ void GPU_edge_setup(DerivedMesh *dm)
GLStates |= GPU_BUFFER_VERTEX_STATE;
- if (useVBOs)
+ if (dm->drawObject->edges->use_vbo)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, dm->drawObject->edges->id);
GLStates |= GPU_BUFFER_ELEMENT_STATE;
@@ -1244,7 +1250,7 @@ void GPU_uvedge_setup(DerivedMesh *dm)
return;
glEnableClientState(GL_VERTEX_ARRAY);
- if (useVBOs) {
+ if (dm->drawObject->uvedges->use_vbo) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uvedges->id);
glVertexPointer(2, GL_FLOAT, 0, 0);
}
@@ -1290,6 +1296,7 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda
int i;
int elementsize;
intptr_t offset = 0;
+ char *basep;
for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) {
if (attribData[i].index != -1) {
@@ -1300,28 +1307,26 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda
}
elementsize = GPU_attrib_element_size(data, numdata);
- if (useVBOs) {
+ if (buffer->use_vbo) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id);
- for (i = 0; i < numdata; i++) {
- glEnableVertexAttribArrayARB(data[i].index);
- glVertexAttribPointerARB(data[i].index, data[i].size, data[i].type,
- GL_FALSE, elementsize, (void *)offset);
- offset += data[i].size * GPU_typesize(data[i].type);
-
- attribData[i].index = data[i].index;
- attribData[i].size = data[i].size;
- attribData[i].type = data[i].type;
- }
- attribData[numdata].index = -1;
+ basep = NULL;
}
else {
- for (i = 0; i < numdata; i++) {
- glEnableVertexAttribArrayARB(data[i].index);
- glVertexAttribPointerARB(data[i].index, data[i].size, data[i].type,
- GL_FALSE, elementsize, (char *)buffer->pointer + offset);
- offset += data[i].size * GPU_typesize(data[i].type);
- }
+ basep = buffer->pointer;
}
+
+ for (i = 0; i < numdata; i++) {
+ glEnableVertexAttribArrayARB(data[i].index);
+ glVertexAttribPointerARB(data[i].index, data[i].size, data[i].type,
+ GL_FALSE, elementsize, (void *)(basep + offset));
+ offset += data[i].size * GPU_typesize(data[i].type);
+
+ attribData[i].index = data[i].index;
+ attribData[i].size = data[i].size;
+ attribData[i].type = data[i].type;
+ }
+
+ attribData[numdata].index = -1;
}
@@ -1343,7 +1348,8 @@ void GPU_buffer_unbind(void)
if (GLStates & GPU_BUFFER_COLOR_STATE)
glDisableClientState(GL_COLOR_ARRAY);
if (GLStates & GPU_BUFFER_ELEMENT_STATE) {
- if (useVBOs) {
+ /* not guaranteed we used VBOs but in that case it's just a no-op */
+ if (GLEW_ARB_vertex_buffer_object) {
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
}
@@ -1359,7 +1365,8 @@ void GPU_buffer_unbind(void)
break;
}
- if (useVBOs)
+ /* not guaranteed we used VBOs but in that case it's just a no-op */
+ if (GLEW_ARB_vertex_buffer_object)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
@@ -1377,19 +1384,6 @@ void GPU_color_switch(int mode)
}
}
-/* return 1 if drawing should be done using old immediate-mode
- * code, 0 otherwise */
-bool GPU_buffer_legacy(DerivedMesh *dm)
-{
- int test = (U.gameflags & USER_DISABLE_VBO);
- if (test)
- return 1;
-
- if (dm->drawObject == NULL)
- dm->drawObject = GPU_drawobject_new(dm);
- return dm->drawObject->legacy;
-}
-
void *GPU_buffer_lock(GPUBuffer *buffer)
{
float *varray;
@@ -1397,7 +1391,7 @@ void *GPU_buffer_lock(GPUBuffer *buffer)
if (!buffer)
return 0;
- if (useVBOs) {
+ if (buffer->use_vbo) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id);
varray = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
return varray;
@@ -1414,7 +1408,7 @@ void *GPU_buffer_lock_stream(GPUBuffer *buffer)
if (!buffer)
return 0;
- if (useVBOs) {
+ if (buffer->use_vbo) {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id);
/* discard previous data, avoid stalling gpu */
glBufferDataARB(GL_ARRAY_BUFFER_ARB, buffer->size, 0, GL_STREAM_DRAW_ARB);
@@ -1428,12 +1422,10 @@ void *GPU_buffer_lock_stream(GPUBuffer *buffer)
void GPU_buffer_unlock(GPUBuffer *buffer)
{
- if (useVBOs) {
- if (buffer) {
- /* note: this operation can fail, could return
- * an error code from this function? */
- glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
- }
+ if (buffer->use_vbo) {
+ /* note: this operation can fail, could return
+ * an error code from this function? */
+ glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
}
@@ -1442,7 +1434,7 @@ void GPU_buffer_unlock(GPUBuffer *buffer)
void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, int count)
{
glDrawElements(mode, count, GL_UNSIGNED_INT,
- (useVBOs ?
+ (elements->use_vbo ?
(void *)(start * sizeof(unsigned int)) :
((int *)elements->pointer) + start));
}
@@ -2748,7 +2740,7 @@ void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
/* debug function, draws the pbvh BB */
void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf)
{
- float quads[4][4][3] = {
+ const float quads[4][4][3] = {
{
{min[0], min[1], min[2]},
{max[0], min[1], min[2]},
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 4182f51561b..47d2ac2d2e5 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -31,8 +31,6 @@
* Convert material node-trees to GLSL.
*/
-#include "GPU_glew.h"
-
#include "MEM_guardedalloc.h"
#include "DNA_customdata_types.h"
@@ -44,6 +42,7 @@
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
+#include "GPU_glew.h"
#include "GPU_material.h"
#include "GPU_extensions.h"
@@ -51,26 +50,43 @@
#include "gpu_codegen.h"
-#include "node_util.h" /* For muting node stuff... */
-
#include <string.h>
#include <stdarg.h>
extern char datatoc_gpu_shader_material_glsl[];
extern char datatoc_gpu_shader_vertex_glsl[];
+extern char datatoc_gpu_shader_vertex_world_glsl[];
static char *glsl_material_library = NULL;
-/* structs and defines */
+/* type definitions and constants */
+
+enum {
+ MAX_FUNCTION_NAME = 64
+};
+enum {
+ MAX_PARAMETER = 32
+};
+typedef enum {
+ FUNCTION_QUAL_IN,
+ FUNCTION_QUAL_OUT,
+ FUNCTION_QUAL_INOUT
+} GPUFunctionQual;
+
+typedef struct GPUFunction {
+ char name[MAX_FUNCTION_NAME];
+ GPUType paramtype[MAX_PARAMETER];
+ GPUFunctionQual paramqual[MAX_PARAMETER];
+ int totparam;
+} GPUFunction;
+
+/* Indices match the GPUType enum */
static const char *GPU_DATATYPE_STR[17] = {"", "float", "vec2", "vec3", "vec4",
NULL, NULL, NULL, NULL, "mat3", NULL, NULL, NULL, NULL, NULL, NULL, "mat4"};
-#define LINK_IMAGE_BLENDER 1
-#define LINK_IMAGE_PREVIEW 2
-
/* GLSL code parsing for finding function definitions.
* These are stored in a hash for lookup when creating a material. */
@@ -127,7 +143,9 @@ static char *gpu_str_skip_token(char *str, char *token, int max)
static void gpu_parse_functions_string(GHash *hash, char *code)
{
GPUFunction *function;
- int i, type, qual;
+ GPUType type;
+ GPUFunctionQual qual;
+ int i;
while ((code = strstr(code, "void "))) {
function = MEM_callocN(sizeof(GPUFunction), "GPUFunction");
@@ -147,7 +165,7 @@ static void gpu_parse_functions_string(GHash *hash, char *code)
code = gpu_str_skip_token(code, NULL, 0);
/* test for type */
- type= 0;
+ type= GPU_NONE;
for (i=1; i<=16; i++) {
if (GPU_DATATYPE_STR[i] && gpu_str_prefix(code, GPU_DATATYPE_STR[i])) {
type= i;
@@ -161,7 +179,7 @@ static void gpu_parse_functions_string(GHash *hash, char *code)
type= GPU_TEX2D;
if (type) {
- /* add paramater */
+ /* add parameter */
code = gpu_str_skip_token(code, NULL, 0);
code = gpu_str_skip_token(code, NULL, 0);
function->paramqual[function->totparam]= qual;
@@ -232,14 +250,14 @@ static char *gpu_generate_function_prototyps(GHash *hash)
}
#endif
-GPUFunction *GPU_lookup_function(const char *name)
+static GPUFunction *gpu_lookup_function(const char *name)
{
if (!FUNCTION_HASH) {
FUNCTION_HASH = BLI_ghash_str_new("GPU_lookup_function gh");
gpu_parse_functions_string(FUNCTION_HASH, glsl_material_library);
}
- return (GPUFunction*)BLI_ghash_lookup(FUNCTION_HASH, (void *)name);
+ return BLI_ghash_lookup(FUNCTION_HASH, (const void *)name);
}
void gpu_codegen_init(void)
@@ -252,7 +270,7 @@ void gpu_codegen_exit(void)
extern Material defmaterial; // render module abuse...
if (defmaterial.gpumaterial.first)
- GPU_material_free(&defmaterial);
+ GPU_material_free(&defmaterial.gpumaterial);
if (FUNCTION_HASH) {
BLI_ghash_free(FUNCTION_HASH, NULL, MEM_freeN);
@@ -321,7 +339,7 @@ static void codegen_convert_datatype(DynStr *ds, int from, int to, const char *t
}
}
-static void codegen_print_datatype(DynStr *ds, int type, float *data)
+static void codegen_print_datatype(DynStr *ds, const GPUType type, float *data)
{
int i;
@@ -364,10 +382,28 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
return "unfobcolor";
else if (builtin == GPU_AUTO_BUMPSCALE)
return "unfobautobumpscale";
+ else if (builtin == GPU_CAMERA_TEXCO_FACTORS)
+ return "unfcameratexfactors";
else
return "";
}
+/* assign only one texid per buffer to avoid sampling the same texture twice */
+static void codegen_set_texid(GHash *bindhash, GPUInput *input, int *texid, void *key)
+{
+ if (BLI_ghash_haskey(bindhash, key)) {
+ /* Reuse existing texid */
+ input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, key));
+ }
+ else {
+ /* Allocate new texid */
+ input->texid = *texid;
+ (*texid)++;
+ input->bindtex = true;
+ BLI_ghash_insert(bindhash, key, SET_INT_IN_POINTER(input->texid));
+ }
+}
+
static void codegen_set_unique_ids(ListBase *nodes)
{
GHash *bindhash, *definehash;
@@ -383,68 +419,43 @@ static void codegen_set_unique_ids(ListBase *nodes)
for (input=node->inputs.first; input; input=input->next) {
/* set id for unique names of uniform variables */
input->id = id++;
- input->bindtex = 0;
- input->definetex = 0;
+ input->bindtex = false;
+ input->definetex = false;
/* set texid used for settings texture slot with multitexture */
if (codegen_input_has_texture(input) &&
((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL)))
{
+ /* assign only one texid per buffer to avoid sampling
+ * the same texture twice */
if (input->link) {
- /* input is texture from buffer, assign only one texid per
- * buffer to avoid sampling the same texture twice */
- if (!BLI_ghash_haskey(bindhash, input->link)) {
- input->texid = texid++;
- input->bindtex = 1;
- BLI_ghash_insert(bindhash, input->link, SET_INT_IN_POINTER(input->texid));
- }
- else
- input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->link));
+ /* input is texture from buffer */
+ codegen_set_texid(bindhash, input, &texid, input->link);
}
else if (input->ima) {
- /* input is texture from image, assign only one texid per
- * buffer to avoid sampling the same texture twice */
- if (!BLI_ghash_haskey(bindhash, input->ima)) {
- input->texid = texid++;
- input->bindtex = 1;
- BLI_ghash_insert(bindhash, input->ima, SET_INT_IN_POINTER(input->texid));
- }
- else
- input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->ima));
+ /* input is texture from image */
+ codegen_set_texid(bindhash, input, &texid, input->ima);
}
else if (input->prv) {
- /* input is texture from preview render, assign only one texid per
- * buffer to avoid sampling the same texture twice */
- if (!BLI_ghash_haskey(bindhash, input->prv)) {
- input->texid = texid++;
- input->bindtex = 1;
- BLI_ghash_insert(bindhash, input->prv, SET_INT_IN_POINTER(input->texid));
- }
- else
- input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->prv));
+ /* input is texture from preview render */
+ codegen_set_texid(bindhash, input, &texid, input->prv);
}
- else {
- if (!BLI_ghash_haskey(bindhash, input->tex)) {
- /* input is user created texture, check tex pointer */
- input->texid = texid++;
- input->bindtex = 1;
- BLI_ghash_insert(bindhash, input->tex, SET_INT_IN_POINTER(input->texid));
- }
- else
- input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->tex));
+ else if (input->tex) {
+ /* input is user created texture, check tex pointer */
+ codegen_set_texid(bindhash, input, &texid, input->tex);
}
/* make sure this pixel is defined exactly once */
if (input->source == GPU_SOURCE_TEX_PIXEL) {
if (input->ima) {
if (!BLI_ghash_haskey(definehash, input->ima)) {
- input->definetex = 1;
+ input->definetex = true;
BLI_ghash_insert(definehash, input->ima, SET_INT_IN_POINTER(input->texid));
}
}
else {
if (!BLI_ghash_haskey(definehash, input->link)) {
- input->definetex = 1;
+ input->definetex = true;
BLI_ghash_insert(definehash, input->link, SET_INT_IN_POINTER(input->texid));
}
}
@@ -605,7 +616,7 @@ static void codegen_call_functions(DynStr *ds, ListBase *nodes, GPUOutput *final
BLI_dynstr_append(ds, ";\n");
}
-static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const char *UNUSED(name))
+static char *code_generate_fragment(ListBase *nodes, GPUOutput *output)
{
DynStr *ds = BLI_dynstr_new();
char *code;
@@ -624,8 +635,7 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const ch
if (builtins & GPU_VIEW_NORMAL)
BLI_dynstr_append(ds, "\tvec3 facingnormal = (gl_FrontFacing)? varnormal: -varnormal;\n");
-
-
+
codegen_declare_tmps(ds, nodes);
codegen_call_functions(ds, nodes, output);
@@ -640,12 +650,13 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const ch
return code;
}
-static char *code_generate_vertex(ListBase *nodes)
+static char *code_generate_vertex(ListBase *nodes, const GPUMatType type)
{
DynStr *ds = BLI_dynstr_new();
GPUNode *node;
GPUInput *input;
char *code;
+ char *vertcode;
for (node=nodes->first; node; node=node->next) {
for (input=node->inputs.first; input; input=input->next) {
@@ -659,8 +670,21 @@ static char *code_generate_vertex(ListBase *nodes)
}
BLI_dynstr_append(ds, "\n");
- BLI_dynstr_append(ds, datatoc_gpu_shader_vertex_glsl);
+ switch (type) {
+ case GPU_MATERIAL_TYPE_MESH:
+ vertcode = datatoc_gpu_shader_vertex_glsl;
+ break;
+ case GPU_MATERIAL_TYPE_WORLD:
+ vertcode = datatoc_gpu_shader_vertex_world_glsl;
+ break;
+ default:
+ fprintf(stderr, "invalid material type, set one after GPU_material_construct_begin\n");
+ break;
+ }
+
+ BLI_dynstr_append(ds, vertcode);
+
for (node=nodes->first; node; node=node->next)
for (input=node->inputs.first; input; input=input->next)
if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
@@ -726,7 +750,7 @@ GPUShader *GPU_pass_shader(GPUPass *pass)
return pass->shader;
}
-static void GPU_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
+static void gpu_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
{
GPUShader *shader = pass->shader;
GPUNode *node;
@@ -848,16 +872,16 @@ void GPU_pass_unbind(GPUPass *pass)
/* Node Link Functions */
-static GPUNodeLink *GPU_node_link_create(int type)
+static GPUNodeLink *GPU_node_link_create(void)
{
GPUNodeLink *link = MEM_callocN(sizeof(GPUNodeLink), "GPUNodeLink");
- link->type = type;
+ link->type = GPU_NONE;
link->users++;
return link;
}
-static void GPU_node_link_free(GPUNodeLink *link)
+static void gpu_node_link_free(GPUNodeLink *link)
{
link->users--;
@@ -882,12 +906,7 @@ static GPUNode *GPU_node_begin(const char *name)
return node;
}
-static void GPU_node_end(GPUNode *UNUSED(node))
-{
- /* empty */
-}
-
-static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
+static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const GPUType type)
{
GPUInput *input;
GPUNode *outnode;
@@ -897,7 +916,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
outnode = link->output->node;
name = outnode->name;
- if (strcmp(name, "set_value")==0 || strcmp(name, "set_rgb")==0) {
+ if (STREQ(name, "set_value") || STREQ(name, "set_rgb")) {
input = MEM_dupallocN(outnode->inputs.first);
input->type = type;
if (input->link)
@@ -941,7 +960,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
input->tex = link->dynamictex;
input->textarget = GL_TEXTURE_2D;
input->textype = type;
- input->dynamictex = 1;
+ input->dynamictex = true;
input->dynamicdata = link->ptr2;
MEM_freeN(link);
}
@@ -952,7 +971,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
input->textype = type;
//input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
- input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, NULL);
+ input->tex = GPU_texture_create_2D(link->texturesize, 1, link->ptr1, GPU_HDR_NONE, NULL);
input->textarget = GL_TEXTURE_2D;
MEM_freeN(link->ptr1);
@@ -963,7 +982,7 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
input->type = GPU_VEC4;
input->source = GPU_SOURCE_TEX;
- if (link->image == LINK_IMAGE_PREVIEW)
+ if (link->image == GPU_NODE_LINK_IMAGE_PREVIEW)
input->prv = link->ptr1;
else {
input->ima = link->ptr1;
@@ -1008,13 +1027,13 @@ static void gpu_node_input_socket(GPUNode *node, GPUNodeStack *sock)
gpu_node_input_link(node, sock->link, sock->type);
}
else {
- link = GPU_node_link_create(0);
+ link = GPU_node_link_create();
link->ptr1 = sock->vec;
gpu_node_input_link(node, link, sock->type);
}
}
-static void GPU_node_output(GPUNode *node, int type, const char *UNUSED(name), GPUNodeLink **link)
+static void gpu_node_output(GPUNode *node, const GPUType type, GPUNodeLink **link)
{
GPUOutput *output = MEM_callocN(sizeof(GPUOutput), "GPUOutput");
@@ -1022,7 +1041,8 @@ static void GPU_node_output(GPUNode *node, int type, const char *UNUSED(name), G
output->node = node;
if (link) {
- *link = output->link = GPU_node_link_create(type);
+ *link = output->link = GPU_node_link_create();
+ output->link->type = type;
output->link->output = output;
/* note: the caller owns the reference to the linkfer, GPUOutput
@@ -1033,13 +1053,13 @@ static void GPU_node_output(GPUNode *node, int type, const char *UNUSED(name), G
BLI_addtail(&node->outputs, output);
}
-static void GPU_inputs_free(ListBase *inputs)
+static void gpu_inputs_free(ListBase *inputs)
{
GPUInput *input;
for (input=inputs->first; input; input=input->next) {
if (input->link)
- GPU_node_link_free(input->link);
+ gpu_node_link_free(input->link);
else if (input->tex && !input->dynamictex)
GPU_texture_free(input->tex);
}
@@ -1047,28 +1067,28 @@ static void GPU_inputs_free(ListBase *inputs)
BLI_freelistN(inputs);
}
-static void GPU_node_free(GPUNode *node)
+static void gpu_node_free(GPUNode *node)
{
GPUOutput *output;
- GPU_inputs_free(&node->inputs);
+ gpu_inputs_free(&node->inputs);
for (output=node->outputs.first; output; output=output->next)
if (output->link) {
output->link->output = NULL;
- GPU_node_link_free(output->link);
+ gpu_node_link_free(output->link);
}
BLI_freelistN(&node->outputs);
MEM_freeN(node);
}
-static void GPU_nodes_free(ListBase *nodes)
+static void gpu_nodes_free(ListBase *nodes)
{
GPUNode *node;
while ((node = BLI_pophead(nodes))) {
- GPU_node_free(node);
+ gpu_node_free(node);
}
}
@@ -1090,7 +1110,7 @@ static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *a
if (input->source == GPU_SOURCE_ATTRIB) {
for (a=0; a<attribs->totlayer; a++) {
if (attribs->layer[a].type == input->attribtype &&
- strcmp(attribs->layer[a].name, input->attribname) == 0)
+ STREQ(attribs->layer[a].name, input->attribname))
{
break;
}
@@ -1130,9 +1150,9 @@ static void gpu_nodes_get_builtin_flag(ListBase *nodes, int *builtin)
/* varargs linking */
-GPUNodeLink *GPU_attribute(int type, const char *name)
+GPUNodeLink *GPU_attribute(const CustomDataType type, const char *name)
{
- GPUNodeLink *link = GPU_node_link_create(0);
+ GPUNodeLink *link = GPU_node_link_create();
link->attribtype= type;
link->attribname= name;
@@ -1142,7 +1162,7 @@ GPUNodeLink *GPU_attribute(int type, const char *name)
GPUNodeLink *GPU_uniform(float *num)
{
- GPUNodeLink *link = GPU_node_link_create(0);
+ GPUNodeLink *link = GPU_node_link_create();
link->ptr1= num;
link->ptr2= NULL;
@@ -1150,13 +1170,13 @@ GPUNodeLink *GPU_uniform(float *num)
return link;
}
-GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data)
+GPUNodeLink *GPU_dynamic_uniform(float *num, GPUDynamicType dynamictype, void *data)
{
- GPUNodeLink *link = GPU_node_link_create(0);
+ GPUNodeLink *link = GPU_node_link_create();
link->ptr1= num;
link->ptr2= data;
- link->dynamic= 1;
+ link->dynamic= true;
link->dynamictype = dynamictype;
@@ -1165,9 +1185,9 @@ GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data)
GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data)
{
- GPUNodeLink *link = GPU_node_link_create(0);
+ GPUNodeLink *link = GPU_node_link_create();
- link->image = LINK_IMAGE_BLENDER;
+ link->image = GPU_NODE_LINK_IMAGE_BLENDER;
link->ptr1 = ima;
link->ptr2 = iuser;
link->image_isdata = is_data;
@@ -1177,9 +1197,9 @@ GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, bool is_data)
GPUNodeLink *GPU_image_preview(PreviewImage *prv)
{
- GPUNodeLink *link = GPU_node_link_create(0);
+ GPUNodeLink *link = GPU_node_link_create();
- link->image= LINK_IMAGE_PREVIEW;
+ link->image= GPU_NODE_LINK_IMAGE_PREVIEW;
link->ptr1= prv;
return link;
@@ -1188,20 +1208,20 @@ GPUNodeLink *GPU_image_preview(PreviewImage *prv)
GPUNodeLink *GPU_texture(int size, float *pixels)
{
- GPUNodeLink *link = GPU_node_link_create(0);
+ GPUNodeLink *link = GPU_node_link_create();
- link->texture = 1;
+ link->texture = true;
link->texturesize = size;
link->ptr1= pixels;
return link;
}
-GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex, int dynamictype, void *data)
+GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex, GPUDynamicType dynamictype, void *data)
{
- GPUNodeLink *link = GPU_node_link_create(0);
+ GPUNodeLink *link = GPU_node_link_create();
- link->dynamic = 1;
+ link->dynamic = true;
link->dynamictex = tex;
link->dynamictype = dynamictype;
link->ptr2 = data;
@@ -1211,7 +1231,7 @@ GPUNodeLink *GPU_dynamic_texture(GPUTexture *tex, int dynamictype, void *data)
GPUNodeLink *GPU_builtin(GPUBuiltin builtin)
{
- GPUNodeLink *link = GPU_node_link_create(0);
+ GPUNodeLink *link = GPU_node_link_create();
link->builtin= builtin;
@@ -1220,7 +1240,7 @@ GPUNodeLink *GPU_builtin(GPUBuiltin builtin)
GPUNodeLink *GPU_opengl_builtin(GPUOpenGLBuiltin builtin)
{
- GPUNodeLink *link = GPU_node_link_create(0);
+ GPUNodeLink *link = GPU_node_link_create();
link->oglbuiltin = builtin;
@@ -1235,7 +1255,7 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...)
va_list params;
int i;
- function = GPU_lookup_function(name);
+ function = gpu_lookup_function(name);
if (!function) {
fprintf(stderr, "GPU failed to find function %s\n", name);
return 0;
@@ -1247,7 +1267,7 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...)
for (i=0; i<function->totparam; i++) {
if (function->paramqual[i] != FUNCTION_QUAL_IN) {
linkptr= va_arg(params, GPUNodeLink**);
- GPU_node_output(node, function->paramtype[i], "", linkptr);
+ gpu_node_output(node, function->paramtype[i], linkptr);
}
else {
link= va_arg(params, GPUNodeLink*);
@@ -1256,8 +1276,6 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...)
}
va_end(params);
- GPU_node_end(node);
-
gpu_material_add_node(mat, node);
return 1;
@@ -1271,7 +1289,7 @@ bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNod
va_list params;
int i, totin, totout;
- function = GPU_lookup_function(name);
+ function = gpu_lookup_function(name);
if (!function) {
fprintf(stderr, "GPU failed to find function %s\n", name);
return 0;
@@ -1290,7 +1308,7 @@ bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNod
if (out) {
for (i = 0; out[i].type != GPU_NONE; i++) {
- GPU_node_output(node, out[i].type, out[i].name, &out[i].link);
+ gpu_node_output(node, out[i].type, &out[i].link);
totout++;
}
}
@@ -1300,7 +1318,7 @@ bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNod
if (function->paramqual[i] != FUNCTION_QUAL_IN) {
if (totout == 0) {
linkptr= va_arg(params, GPUNodeLink**);
- GPU_node_output(node, function->paramtype[i], "", linkptr);
+ gpu_node_output(node, function->paramtype[i], linkptr);
}
else
totout--;
@@ -1319,8 +1337,6 @@ bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNod
}
va_end(params);
- GPU_node_end(node);
-
gpu_material_add_node(mat, node);
return 1;
@@ -1336,7 +1352,7 @@ int GPU_link_changed(GPUNodeLink *link)
node = link->output->node;
name = node->name;
- if (strcmp(name, "set_value")==0 || strcmp(name, "set_rgb")==0) {
+ if (STREQ(name, "set_value") || STREQ(name, "set_rgb")) {
input = node->inputs.first;
return (input->link != NULL);
}
@@ -1361,7 +1377,7 @@ static void gpu_nodes_tag(GPUNodeLink *link)
if (node->tag)
return;
- node->tag= 1;
+ node->tag = true;
for (input=node->inputs.first; input; input=input->next)
if (input->link)
gpu_nodes_tag(input->link);
@@ -1372,7 +1388,7 @@ static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
GPUNode *node, *next;
for (node=nodes->first; node; node=node->next)
- node->tag= 0;
+ node->tag = false;
gpu_nodes_tag(outlink);
@@ -1381,12 +1397,14 @@ static void gpu_nodes_prune(ListBase *nodes, GPUNodeLink *outlink)
if (!node->tag) {
BLI_remlink(nodes, node);
- GPU_node_free(node);
+ gpu_node_free(node);
}
}
}
-GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttribs *attribs, int *builtins, const char *name)
+GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink,
+ GPUVertexAttribs *attribs, int *builtins,
+ const GPUMatType type, const char *UNUSED(name))
{
GPUShader *shader;
GPUPass *pass;
@@ -1404,8 +1422,8 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
gpu_nodes_get_builtin_flag(nodes, builtins);
/* generate code and compile with opengl */
- fragmentcode = code_generate_fragment(nodes, outlink->output, name);
- vertexcode = code_generate_vertex(nodes);
+ fragmentcode = code_generate_fragment(nodes, outlink->output);
+ vertexcode = code_generate_vertex(nodes, type);
shader = GPU_shader_create(vertexcode, fragmentcode, glsl_material_library, NULL);
/* failed? */
@@ -1416,7 +1434,7 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
MEM_freeN(vertexcode);
memset(attribs, 0, sizeof(*attribs));
memset(builtins, 0, sizeof(*builtins));
- GPU_nodes_free(nodes);
+ gpu_nodes_free(nodes);
return NULL;
}
@@ -1430,8 +1448,8 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
pass->libcode = glsl_material_library;
/* extract dynamic inputs and throw away nodes */
- GPU_nodes_extract_dynamic_inputs(pass, nodes);
- GPU_nodes_free(nodes);
+ gpu_nodes_extract_dynamic_inputs(pass, nodes);
+ gpu_nodes_free(nodes);
return pass;
}
@@ -1439,7 +1457,7 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
void GPU_pass_free(GPUPass *pass)
{
GPU_shader_free(pass->shader);
- GPU_inputs_free(&pass->inputs);
+ gpu_inputs_free(&pass->inputs);
if (pass->fragmentcode)
MEM_freeN(pass->fragmentcode);
if (pass->vertexcode)
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 69213925931..a6da5e018fd 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -33,6 +33,7 @@
#ifndef __GPU_CODEGEN_H__
#define __GPU_CODEGEN_H__
+#include "DNA_customdata_types.h"
#include "DNA_listBase.h"
#include "GPU_material.h"
#include "GPU_glew.h"
@@ -45,22 +46,6 @@ struct GPUVertexAttribs;
struct GPUFrameBuffer;
struct PreviewImage;
-#define MAX_FUNCTION_NAME 64
-#define MAX_PARAMETER 32
-
-#define FUNCTION_QUAL_IN 0
-#define FUNCTION_QUAL_OUT 1
-#define FUNCTION_QUAL_INOUT 2
-
-typedef struct GPUFunction {
- char name[MAX_FUNCTION_NAME];
- int paramtype[MAX_PARAMETER];
- int paramqual[MAX_PARAMETER];
- int totparam;
-} GPUFunction;
-
-GPUFunction *GPU_lookup_function(const char *name);
-
/* Pass Generation
* - Takes a list of nodes and a desired output, and makes a pass. This
* will take ownership of the nodes and free them early if unused or
@@ -76,11 +61,19 @@ typedef enum GPUDataSource {
GPU_SOURCE_ATTRIB
} GPUDataSource;
+typedef enum {
+ GPU_NODE_LINK_IMAGE_NONE = 0,
+ GPU_NODE_LINK_IMAGE_BLENDER = 1,
+ GPU_NODE_LINK_IMAGE_PREVIEW = 2
+} GPUNodeLinkImage;
+
struct GPUNode {
struct GPUNode *next, *prev;
const char *name;
- int tag;
+
+ /* Internal flag to mark nodes during pruning */
+ bool tag;
ListBase inputs;
ListBase outputs;
@@ -89,21 +82,23 @@ struct GPUNode {
struct GPUNodeLink {
GPUNodeStack *socket;
- int attribtype;
+ CustomDataType attribtype;
const char *attribname;
- int image;
- int image_isdata;
+ GPUNodeLinkImage image;
+ bool image_isdata;
- int texture;
+ bool texture;
int texturesize;
void *ptr1, *ptr2;
- int dynamic;
- int dynamictype;
+ bool dynamic;
+ GPUDynamicType dynamictype;
+
+ GPUType type;
- int type;
+ /* Refcount */
int users;
struct GPUTexture *dynamictex;
@@ -118,7 +113,7 @@ typedef struct GPUOutput {
struct GPUOutput *next, *prev;
GPUNode *node;
- int type; /* data type = length of vector/matrix */
+ GPUType type; /* data type = length of vector/matrix */
GPUNodeLink *link; /* output link */
int id; /* unique id as created by code generator */
} GPUOutput;
@@ -128,23 +123,23 @@ typedef struct GPUInput {
GPUNode *node;
- int type; /* datatype */
- int source; /* data source */
+ GPUType type; /* datatype */
+ GPUDataSource source; /* data source */
int id; /* unique id as created by code generator */
- int texid; /* number for multitexture */
+ int texid; /* number for multitexture, starting from zero */
int attribid; /* id for vertex attributes */
- int bindtex; /* input is responsible for binding the texture? */
- int definetex; /* input is responsible for defining the pixel? */
- int textarget; /* GL_TEXTURE_* */
- int textype; /* datatype */
+ bool bindtex; /* input is responsible for binding the texture? */
+ bool definetex; /* input is responsible for defining the pixel? */
+ int textarget; /* GL texture target, e.g. GL_TEXTURE_2D */
+ GPUType textype; /* datatype */
struct Image *ima; /* image */
struct ImageUser *iuser;/* image user */
struct PreviewImage *prv; /* preview images & icons */
- int image_isdata; /* image does not contain color data */
+ bool image_isdata; /* image does not contain color data */
float *dynamicvec; /* vector data in case it is dynamic */
- int dynamictype; /* origin of the dynamic uniform (GPUDynamicType) */
+ GPUDynamicType dynamictype; /* origin of the dynamic uniform */
void *dynamicdata; /* data source of the dynamic uniform */
struct GPUTexture *tex; /* input texture, only set at runtime */
int shaderloc; /* id from opengl */
@@ -152,9 +147,9 @@ typedef struct GPUInput {
float vec[16]; /* vector data */
GPUNodeLink *link;
- int dynamictex; /* dynamic? */
- int attribtype; /* attribute type */
- char attribname[32]; /* attribute name */
+ bool dynamictex; /* dynamic? */
+ CustomDataType attribtype; /* attribute type */
+ char attribname[MAX_CUSTOMDATA_LAYER_NAME]; /* attribute name */
int attribfirst; /* this is the first one that is bound */
GPUBuiltin builtin; /* builtin uniform */
GPUOpenGLBuiltin oglbuiltin; /* opengl built in varying */
@@ -175,7 +170,8 @@ struct GPUPass {
typedef struct GPUPass GPUPass;
GPUPass *GPU_generate_pass(ListBase *nodes, struct GPUNodeLink *outlink,
- struct GPUVertexAttribs *attribs, int *builtin, const char *name);
+ struct GPUVertexAttribs *attribs, int *builtin,
+ const GPUMatType type, const char *name);
struct GPUShader *GPU_pass_shader(GPUPass *pass);
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
new file mode 100644
index 00000000000..511167b775a
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -0,0 +1,987 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Antony Riakiotakis.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_compositing.c
+ * \ingroup gpu
+ *
+ * System that manages framebuffer compositing.
+ */
+
+#include "BLI_sys_types.h"
+#include "BLI_rect.h"
+#include "BLI_math.h"
+#include "BLI_listbase.h"
+#include "BLI_linklist.h"
+
+#include "BLI_rand.h"
+#include "BLI_listbase.h"
+
+#include "DNA_vec_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_gpu_types.h"
+
+#include "GPU_extensions.h"
+#include "GPU_compositing.h"
+
+#include "GL/glew.h"
+
+#include "MEM_guardedalloc.h"
+
+static const float fullscreencos[4][2] = {{-1.0f, -1.0f}, {1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}};
+static const float fullscreenuvs[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}};
+
+struct GPUFX {
+ /* we borrow the term gbuffer from deferred rendering however this is just a regular
+ * depth/color framebuffer. Could be extended later though */
+ GPUFrameBuffer *gbuffer;
+
+ /* texture bound to the first color attachment of the gbuffer */
+ GPUTexture *color_buffer;
+
+ /* second texture used for ping-pong compositing */
+ GPUTexture *color_buffer_sec;
+
+ /* all those buffers below have to coexist. Fortunately they are all quarter sized (1/16th of memory) of original framebuffer */
+ int dof_downsampled_w;
+ int dof_downsampled_h;
+
+ /* texture used for near coc and color blurring calculation */
+ GPUTexture *dof_near_coc_buffer;
+ /* blurred near coc buffer. */
+ GPUTexture *dof_near_coc_blurred_buffer;
+ /* final near coc buffer. */
+ GPUTexture *dof_near_coc_final_buffer;
+
+ /* half size blur buffer */
+ GPUTexture *dof_half_downsampled;
+ /* high quality dof texture downsamplers. 6 levels means 64 pixels wide */
+ GPUTexture *dof_nearfar_coc[6];
+ GPUTexture *dof_near_blur;
+ GPUTexture *dof_far_blur;
+ GPUTexture *dof_concentric_samples_tex;
+
+ /* texture bound to the depth attachment of the gbuffer */
+ GPUTexture *depth_buffer;
+ GPUTexture *depth_buffer_xray;
+
+ /* texture used for jittering for various effects */
+ GPUTexture *jitter_buffer;
+
+ /* texture used for ssao */
+ int ssao_sample_count;
+ GPUTexture *ssao_concentric_samples_tex;
+
+ /* dimensions of the gbuffer */
+ int gbuffer_dim[2];
+
+ GPUFXSettings settings;
+
+ /* or-ed flags of enabled effects */
+ int effects;
+
+ /* number of passes, needed to detect if ping pong buffer allocation is needed */
+ int num_passes;
+
+ /* we have a stencil, restore the previous state */
+ bool restore_stencil;
+};
+
+#if 0
+/* concentric mapping, see "A Low Distortion Map Between Disk and Square" and
+ * http://psgraphics.blogspot.nl/2011/01/improved-code-for-concentric-map.html */
+static GPUTexture * create_concentric_sample_texture(int side)
+{
+ GPUTexture *tex;
+ float midpoint = 0.5f * (side - 1);
+ float *texels = (float *)MEM_mallocN(sizeof(float) * 2 * side * side, "concentric_tex");
+ int i, j;
+
+ for (i = 0; i < side; i++) {
+ for (j = 0; j < side; j++) {
+ int index = (i * side + j) * 2;
+ float a = 1.0f - i / midpoint;
+ float b = 1.0f - j / midpoint;
+ float phi, r;
+ if (a * a > b * b) {
+ r = a;
+ phi = (M_PI_4) * (b / a);
+ }
+ else {
+ r = b;
+ phi = M_PI_2 - (M_PI_4) * (a / b);
+ }
+ texels[index] = r * cos(phi);
+ texels[index + 1] = r * sin(phi);
+ }
+ }
+
+ tex = GPU_texture_create_1D_procedural(side * side, texels, NULL);
+ MEM_freeN(texels);
+ return tex;
+}
+#endif
+
+static GPUTexture *create_spiral_sample_texture(int numsaples)
+{
+ GPUTexture *tex;
+ float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * numsaples, "concentric_tex");
+ const float numsaples_inv = 1.0f / numsaples;
+ int i;
+ /* arbitrary number to ensure we don't get conciding samples every circle */
+ const float spirals = 7.357;
+
+ for (i = 0; i < numsaples; i++) {
+ float r = (i + 0.5f) * numsaples_inv;
+ float phi = r * spirals * (float)(2.0 * M_PI);
+ texels[i][0] = r * cosf(phi);
+ texels[i][1] = r * sinf(phi);
+ }
+
+ tex = GPU_texture_create_1D_procedural(numsaples, (float *)texels, NULL);
+ MEM_freeN(texels);
+ return tex;
+}
+
+/* generate a new FX compositor */
+GPUFX *GPU_fx_compositor_create(void)
+{
+ GPUFX *fx = MEM_callocN(sizeof(GPUFX), "GPUFX compositor");
+
+ return fx;
+}
+
+static void cleanup_fx_dof_buffers(GPUFX *fx)
+{
+ if (fx->dof_near_coc_blurred_buffer) {
+ GPU_texture_free(fx->dof_near_coc_blurred_buffer);
+ fx->dof_near_coc_blurred_buffer = NULL;
+ }
+ if (fx->dof_near_coc_buffer) {
+ GPU_texture_free(fx->dof_near_coc_buffer);
+ fx->dof_near_coc_buffer = NULL;
+ }
+ if (fx->dof_near_coc_final_buffer) {
+ GPU_texture_free(fx->dof_near_coc_final_buffer);
+ fx->dof_near_coc_final_buffer = NULL;
+ }
+
+ if (fx->dof_half_downsampled) {
+ GPU_texture_free(fx->dof_half_downsampled);
+ fx->dof_half_downsampled = NULL;
+ }
+ if (fx->dof_nearfar_coc[0]) {
+ int i;
+ for (i = 0; i < 6; i++) {
+ GPU_texture_free(fx->dof_nearfar_coc[i]);
+ fx->dof_nearfar_coc[i] = NULL;
+ }
+ }
+ if (fx->dof_near_blur) {
+ GPU_texture_free(fx->dof_near_blur);
+ fx->dof_near_blur = NULL;
+ }
+ if (fx->dof_far_blur) {
+ GPU_texture_free(fx->dof_far_blur);
+ fx->dof_far_blur = NULL;
+ }
+ if (fx->dof_concentric_samples_tex) {
+ GPU_texture_free(fx->dof_concentric_samples_tex);
+ fx->dof_concentric_samples_tex = NULL;
+ }
+}
+
+static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
+{
+ if (fx->color_buffer) {
+ GPU_framebuffer_texture_detach(fx->color_buffer);
+ GPU_texture_free(fx->color_buffer);
+ fx->color_buffer = NULL;
+ }
+
+ if (fx->color_buffer_sec) {
+ GPU_framebuffer_texture_detach(fx->color_buffer_sec);
+ GPU_texture_free(fx->color_buffer_sec);
+ fx->color_buffer_sec = NULL;
+ }
+
+ if (fx->depth_buffer) {
+ GPU_framebuffer_texture_detach(fx->depth_buffer);
+ GPU_texture_free(fx->depth_buffer);
+ fx->depth_buffer = NULL;
+ }
+
+ if (fx->depth_buffer_xray) {
+ GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
+ GPU_texture_free(fx->depth_buffer_xray);
+ fx->depth_buffer_xray = NULL;
+ }
+
+ cleanup_fx_dof_buffers(fx);
+
+ if (fx->ssao_concentric_samples_tex) {
+ GPU_texture_free(fx->ssao_concentric_samples_tex);
+ fx->ssao_concentric_samples_tex = NULL;
+ }
+
+ if (fx->jitter_buffer && do_fbo) {
+ GPU_texture_free(fx->jitter_buffer);
+ fx->jitter_buffer = NULL;
+ }
+
+ if (fx->gbuffer && do_fbo) {
+ GPU_framebuffer_free(fx->gbuffer);
+ fx->gbuffer = NULL;
+ }
+}
+
+/* destroy a text compositor */
+void GPU_fx_compositor_destroy(GPUFX *fx)
+{
+ cleanup_fx_gl_data(fx, true);
+ MEM_freeN(fx);
+}
+
+static GPUTexture * create_jitter_texture(void)
+{
+ float jitter [64 * 64][2];
+ int i;
+
+ for (i = 0; i < 64 * 64; i++) {
+ jitter[i][0] = 2.0f * BLI_frand() - 1.0f;
+ jitter[i][1] = 2.0f * BLI_frand() - 1.0f;
+ normalize_v2(jitter[i]);
+ }
+
+ return GPU_texture_create_2D_procedural(64, 64, &jitter[0][0], NULL);
+}
+
+
+bool GPU_fx_compositor_initialize_passes(
+ GPUFX *fx, const rcti *rect, const rcti *scissor_rect,
+ const GPUFXSettings *fx_settings)
+{
+ int w = BLI_rcti_size_x(rect), h = BLI_rcti_size_y(rect);
+ char err_out[256];
+ int num_passes = 0;
+ char fx_flag;
+
+ fx->effects = 0;
+
+ if (!fx_settings) {
+ cleanup_fx_gl_data(fx, true);
+ return false;
+ }
+
+ fx_flag = fx_settings->fx_flag;
+
+ /* disable effects if no options passed for them */
+ if (!fx_settings->dof) {
+ fx_flag &= ~GPU_FX_FLAG_DOF;
+ }
+ if (!fx_settings->ssao || fx_settings->ssao->samples < 1) {
+ fx_flag &= ~GPU_FX_FLAG_SSAO;
+ }
+
+ if (!fx_flag) {
+ cleanup_fx_gl_data(fx, true);
+ return false;
+ }
+
+ /* scissor is missing when drawing offscreen, in that case, dimensions match exactly. In opposite case
+ * add one to match viewport dimensions */
+ if (scissor_rect) {
+ w++, h++;
+ }
+
+ fx->num_passes = 0;
+ /* dof really needs a ping-pong buffer to work */
+ if (fx_flag & GPU_FX_FLAG_DOF)
+ num_passes++;
+
+ if (fx_flag & GPU_FX_FLAG_SSAO)
+ num_passes++;
+
+ if (!fx->gbuffer)
+ fx->gbuffer = GPU_framebuffer_create();
+
+ /* try creating the jitter texture */
+ if (!fx->jitter_buffer)
+ fx->jitter_buffer = create_jitter_texture();
+
+ if (!fx->gbuffer)
+ return false;
+
+ /* check if color buffers need recreation */
+ if (!fx->color_buffer || !fx->depth_buffer || w != fx->gbuffer_dim[0] || h != fx->gbuffer_dim[1]) {
+ cleanup_fx_gl_data(fx, false);
+
+ if (!(fx->color_buffer = GPU_texture_create_2D(w, h, NULL, GPU_HDR_NONE, err_out))) {
+ printf(".256%s\n", err_out);
+ cleanup_fx_gl_data(fx, true);
+ return false;
+ }
+
+ if (!(fx->depth_buffer = GPU_texture_create_depth(w, h, err_out))) {
+ printf("%.256s\n", err_out);
+ cleanup_fx_gl_data(fx, true);
+ return false;
+ }
+ }
+
+ if (fx_flag & GPU_FX_FLAG_SSAO) {
+ if (fx_settings->ssao->samples != fx->ssao_sample_count || !fx->ssao_concentric_samples_tex) {
+ if (fx_settings->ssao->samples < 1)
+ fx_settings->ssao->samples = 1;
+
+ fx->ssao_sample_count = fx_settings->ssao->samples;
+
+ if (fx->ssao_concentric_samples_tex) {
+ GPU_texture_free(fx->ssao_concentric_samples_tex);
+ }
+
+ fx->ssao_concentric_samples_tex = create_spiral_sample_texture(fx_settings->ssao->samples);
+ }
+ }
+ else {
+ if (fx->ssao_concentric_samples_tex) {
+ GPU_texture_free(fx->ssao_concentric_samples_tex);
+ fx->ssao_concentric_samples_tex = NULL;
+ }
+ }
+
+ /* create textures for dof effect */
+ if (fx_flag & GPU_FX_FLAG_DOF) {
+ if (!fx->dof_near_coc_buffer || !fx->dof_near_coc_blurred_buffer || !fx->dof_near_coc_final_buffer) {
+ fx->dof_downsampled_w = w / 4;
+ fx->dof_downsampled_h = h / 4;
+
+ if (!(fx->dof_near_coc_buffer = GPU_texture_create_2D(
+ fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out)))
+ {
+ printf("%.256s\n", err_out);
+ cleanup_fx_gl_data(fx, true);
+ return false;
+ }
+ if (!(fx->dof_near_coc_blurred_buffer = GPU_texture_create_2D(
+ fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out)))
+ {
+ printf("%.256s\n", err_out);
+ cleanup_fx_gl_data(fx, true);
+ return false;
+ }
+ if (!(fx->dof_near_coc_final_buffer = GPU_texture_create_2D(
+ fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, GPU_HDR_NONE, err_out)))
+ {
+ printf("%.256s\n", err_out);
+ cleanup_fx_gl_data(fx, true);
+ return false;
+ }
+ }
+ }
+ else {
+ /* cleanup unnecessary buffers */
+ cleanup_fx_dof_buffers(fx);
+ }
+
+ /* we need to pass data between shader stages, allocate an extra color buffer */
+ if (num_passes > 1) {
+ if(!fx->color_buffer_sec) {
+ if (!(fx->color_buffer_sec = GPU_texture_create_2D(w, h, NULL, GPU_HDR_NONE, err_out))) {
+ printf(".256%s\n", err_out);
+ cleanup_fx_gl_data(fx, true);
+ return false;
+ }
+ }
+ }
+ else {
+ if (fx->color_buffer_sec) {
+ GPU_framebuffer_texture_detach(fx->color_buffer_sec);
+ GPU_texture_free(fx->color_buffer_sec);
+ fx->color_buffer_sec = NULL;
+ }
+ }
+
+ /* bind the buffers */
+
+ /* first depth buffer, because system assumes read/write buffers */
+ if(!GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, err_out))
+ printf("%.256s\n", err_out);
+
+ if(!GPU_framebuffer_texture_attach(fx->gbuffer, fx->color_buffer, 0, err_out))
+ printf("%.256s\n", err_out);
+
+ if(!GPU_framebuffer_check_valid(fx->gbuffer, err_out))
+ printf("%.256s\n", err_out);
+
+ GPU_texture_bind_as_framebuffer(fx->color_buffer);
+
+ /* enable scissor test. It's needed to ensure sculpting works correctly */
+ if (scissor_rect) {
+ int w_sc = BLI_rcti_size_x(scissor_rect) + 1;
+ int h_sc = BLI_rcti_size_y(scissor_rect) + 1;
+ glPushAttrib(GL_SCISSOR_BIT);
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(scissor_rect->xmin - rect->xmin, scissor_rect->ymin - rect->ymin,
+ w_sc, h_sc);
+ fx->restore_stencil = true;
+ }
+ else {
+ fx->restore_stencil = false;
+ }
+
+ fx->effects = fx_flag;
+
+ if (fx_settings)
+ fx->settings = *fx_settings;
+ fx->gbuffer_dim[0] = w;
+ fx->gbuffer_dim[1] = h;
+
+ fx->num_passes = num_passes;
+
+ return true;
+}
+
+static void gpu_fx_bind_render_target(int *passes_left, GPUFX *fx, struct GPUOffScreen *ofs, GPUTexture *target)
+{
+ if ((*passes_left)-- == 1) {
+ GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
+ if (ofs) {
+ GPU_offscreen_bind(ofs, false);
+ }
+ else
+ GPU_framebuffer_restore();
+ }
+ else {
+ /* bind the ping buffer to the color buffer */
+ GPU_framebuffer_texture_attach(fx->gbuffer, target, 0, NULL);
+ }
+}
+
+void GPU_fx_compositor_setup_XRay_pass(GPUFX *fx, bool do_xray)
+{
+ char err_out[256];
+
+ if (do_xray) {
+ if (!fx->depth_buffer_xray && !(fx->depth_buffer_xray = GPU_texture_create_depth(fx->gbuffer_dim[0], fx->gbuffer_dim[1], err_out))) {
+ printf("%.256s\n", err_out);
+ cleanup_fx_gl_data(fx, true);
+ return;
+ }
+ }
+ else {
+ if (fx->depth_buffer_xray) {
+ GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
+ GPU_texture_free(fx->depth_buffer_xray);
+ fx->depth_buffer_xray = NULL;
+ }
+ return;
+ }
+
+ GPU_framebuffer_texture_detach(fx->depth_buffer);
+
+ /* first depth buffer, because system assumes read/write buffers */
+ if(!GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer_xray, 0, err_out))
+ printf("%.256s\n", err_out);
+}
+
+
+void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
+{
+ GPUShader *depth_resolve_shader;
+ GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
+
+ /* attach regular framebuffer */
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, NULL);
+
+ /* full screen quad where we will always write to depth buffer */
+ glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_SCISSOR_BIT);
+ glDepthFunc(GL_ALWAYS);
+ /* disable scissor from sculpt if any */
+ glDisable(GL_SCISSOR_TEST);
+ /* disable writing to color buffer, it's depth only pass */
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+ /* set up quad buffer */
+ glVertexPointer(2, GL_FLOAT, 0, fullscreencos);
+ glTexCoordPointer(2, GL_FLOAT, 0, fullscreenuvs);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ depth_resolve_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_RESOLVE, false);
+
+ if (depth_resolve_shader) {
+ int depth_uniform;
+
+ depth_uniform = GPU_shader_get_uniform(depth_resolve_shader, "depthbuffer");
+
+ GPU_shader_bind(depth_resolve_shader);
+
+ GPU_texture_bind(fx->depth_buffer_xray, 0);
+ GPU_depth_texture_mode(fx->depth_buffer_xray, false, true);
+ GPU_shader_uniform_texture(depth_resolve_shader, depth_uniform, fx->depth_buffer_xray);
+
+ /* draw */
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ /* disable bindings */
+ GPU_depth_texture_mode(fx->depth_buffer_xray, true, false);
+ GPU_texture_unbind(fx->depth_buffer_xray);
+
+ GPU_shader_unbind();
+ }
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glPopAttrib();
+}
+
+
+bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, struct Scene *scene, struct GPUOffScreen *ofs)
+{
+ GPUTexture *src, *target;
+ int numslots = 0;
+ float invproj[4][4];
+ int i;
+ /* number of passes left. when there are no more passes, the result is passed to the frambuffer */
+ int passes_left = fx->num_passes;
+ /* view vectors for the corners of the view frustum. Can be used to recreate the world space position easily */
+ float viewvecs[3][4] = {
+ {-1.0f, -1.0f, -1.0f, 1.0f},
+ {1.0f, -1.0f, -1.0f, 1.0f},
+ {-1.0f, 1.0f, -1.0f, 1.0f}
+ };
+
+ if (fx->effects == 0)
+ return false;
+
+ /* first, unbind the render-to-texture framebuffer */
+ GPU_framebuffer_texture_detach(fx->color_buffer);
+ GPU_framebuffer_texture_detach(fx->depth_buffer);
+
+ if (fx->restore_stencil)
+ glPopAttrib();
+
+ src = fx->color_buffer;
+ target = fx->color_buffer_sec;
+
+ /* set up quad buffer */
+ glVertexPointer(2, GL_FLOAT, 0, fullscreencos);
+ glTexCoordPointer(2, GL_FLOAT, 0, fullscreenuvs);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ /* full screen FX pass */
+
+ /* invert the view matrix */
+ invert_m4_m4(invproj, projmat);
+
+ /* convert the view vectors to view space */
+ for (i = 0; i < 3; i++) {
+ mul_m4_v4(invproj, viewvecs[i]);
+ /* normalized trick see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
+ if (is_persp)
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
+ viewvecs[i][3] = 1.0;
+ }
+
+ /* we need to store the differences */
+ viewvecs[1][0] -= viewvecs[0][0];
+ viewvecs[1][1] = viewvecs[2][1] - viewvecs[0][1];
+
+ /* calculate a depth offset as well */
+ if (!is_persp) {
+ float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
+ mul_m4_v4(invproj, vec_far);
+ mul_v3_fl(vec_far, 1.0f / vec_far[3]);
+ viewvecs[1][2] = vec_far[2] - viewvecs[0][2];
+ }
+
+ /* set invalid color in case shader fails */
+ glColor3f(1.0, 0.0, 1.0);
+ glDisable(GL_DEPTH_TEST);
+
+ /* ssao pass */
+ if (fx->effects & GPU_FX_FLAG_SSAO) {
+ GPUShader *ssao_shader;
+ ssao_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_SSAO, is_persp);
+ if (ssao_shader) {
+ const GPUSSAOSettings *fx_ssao = fx->settings.ssao;
+ int color_uniform, depth_uniform;
+ int ssao_uniform, ssao_color_uniform, viewvecs_uniform, ssao_sample_params_uniform;
+ int ssao_jitter_uniform, ssao_concentric_tex;
+ float ssao_params[4] = {fx_ssao->distance_max, fx_ssao->factor, fx_ssao->attenuation, 0.0f};
+ float sample_params[4];
+
+ sample_params[0] = fx->ssao_sample_count;
+ /* multiplier so we tile the random texture on screen */
+ sample_params[2] = fx->gbuffer_dim[0] / 64.0;
+ sample_params[3] = fx->gbuffer_dim[1] / 64.0;
+
+ ssao_uniform = GPU_shader_get_uniform(ssao_shader, "ssao_params");
+ ssao_color_uniform = GPU_shader_get_uniform(ssao_shader, "ssao_color");
+ color_uniform = GPU_shader_get_uniform(ssao_shader, "colorbuffer");
+ depth_uniform = GPU_shader_get_uniform(ssao_shader, "depthbuffer");
+ viewvecs_uniform = GPU_shader_get_uniform(ssao_shader, "viewvecs");
+ ssao_sample_params_uniform = GPU_shader_get_uniform(ssao_shader, "ssao_sample_params");
+ ssao_concentric_tex = GPU_shader_get_uniform(ssao_shader, "ssao_concentric_tex");
+ ssao_jitter_uniform = GPU_shader_get_uniform(ssao_shader, "jitter_tex");
+
+ GPU_shader_bind(ssao_shader);
+
+ GPU_shader_uniform_vector(ssao_shader, ssao_uniform, 4, 1, ssao_params);
+ GPU_shader_uniform_vector(ssao_shader, ssao_color_uniform, 4, 1, fx_ssao->color);
+ GPU_shader_uniform_vector(ssao_shader, viewvecs_uniform, 4, 3, viewvecs[0]);
+ GPU_shader_uniform_vector(ssao_shader, ssao_sample_params_uniform, 4, 1, sample_params);
+
+ GPU_texture_bind(src, numslots++);
+ GPU_shader_uniform_texture(ssao_shader, color_uniform, src);
+
+ GPU_texture_bind(fx->depth_buffer, numslots++);
+ GPU_depth_texture_mode(fx->depth_buffer, false, true);
+ GPU_shader_uniform_texture(ssao_shader, depth_uniform, fx->depth_buffer);
+
+ GPU_texture_bind(fx->jitter_buffer, numslots++);
+ GPU_shader_uniform_texture(ssao_shader, ssao_jitter_uniform, fx->jitter_buffer);
+
+ GPU_texture_bind(fx->ssao_concentric_samples_tex, numslots++);
+ GPU_shader_uniform_texture(ssao_shader, ssao_concentric_tex, fx->ssao_concentric_samples_tex);
+
+ /* draw */
+ gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ /* disable bindings */
+ GPU_texture_unbind(src);
+ GPU_depth_texture_mode(fx->depth_buffer, true, false);
+ GPU_texture_unbind(fx->depth_buffer);
+ GPU_texture_unbind(fx->jitter_buffer);
+ GPU_texture_unbind(fx->ssao_concentric_samples_tex);
+
+ /* may not be attached, in that case this just returns */
+ if (target) {
+ GPU_framebuffer_texture_detach(target);
+ if (ofs) {
+ GPU_offscreen_bind(ofs, false);
+ }
+ else {
+ GPU_framebuffer_restore();
+ }
+ }
+
+ /* swap here, after src/target have been unbound */
+ SWAP(GPUTexture *, target, src);
+ numslots = 0;
+ }
+ }
+
+ /* second pass, dof */
+ if (fx->effects & GPU_FX_FLAG_DOF) {
+ const GPUDOFSettings *fx_dof = fx->settings.dof;
+ GPUShader *dof_shader_pass1, *dof_shader_pass2, *dof_shader_pass3, *dof_shader_pass4, *dof_shader_pass5;
+ float dof_params[4];
+ float scale = scene->unit.system ? scene->unit.scale_length : 1.0f;
+ /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
+ * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
+ * because the shader reads coordinates in world space, which is in blender units. */
+ float scale_camera = 0.001f / scale;
+ /* we want radius here for the aperture number */
+ float aperture = 0.5f * scale_camera * fx_dof->focal_length / fx_dof->fstop;
+
+ dof_params[0] = aperture * fabsf(scale_camera * fx_dof->focal_length / ((fx_dof->focus_distance / scale) - scale_camera * fx_dof->focal_length));
+ dof_params[1] = fx_dof->focus_distance / scale;
+ dof_params[2] = fx->gbuffer_dim[0] / (scale_camera * fx_dof->sensor);
+ dof_params[3] = 0.0f;
+
+ /* DOF effect has many passes but most of them are performed on a texture whose dimensions are 4 times less than the original
+ * (16 times lower than original screen resolution). Technique used is not very exact but should be fast enough and is based
+ * on "Practical Post-Process Depth of Field" see http://http.developer.nvidia.com/GPUGems3/gpugems3_ch28.html */
+ dof_shader_pass1 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE, is_persp);
+ dof_shader_pass2 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO, is_persp);
+ dof_shader_pass3 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE, is_persp);
+ dof_shader_pass4 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR, is_persp);
+ dof_shader_pass5 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE, is_persp);
+
+ /* error occured, restore framebuffers and return */
+ if (!(dof_shader_pass1 && dof_shader_pass2 && dof_shader_pass3 && dof_shader_pass4 && dof_shader_pass5)) {
+ GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
+ GPU_framebuffer_restore();
+ return false;
+ }
+
+ /* pass first, first level of blur in low res buffer */
+ {
+ int invrendertargetdim_uniform, color_uniform, depth_uniform, dof_uniform;
+ int viewvecs_uniform;
+
+ float invrendertargetdim[2] = {1.0f / fx->gbuffer_dim[0], 1.0f / fx->gbuffer_dim[1]};
+
+ dof_uniform = GPU_shader_get_uniform(dof_shader_pass1, "dof_params");
+ invrendertargetdim_uniform = GPU_shader_get_uniform(dof_shader_pass1, "invrendertargetdim");
+ color_uniform = GPU_shader_get_uniform(dof_shader_pass1, "colorbuffer");
+ depth_uniform = GPU_shader_get_uniform(dof_shader_pass1, "depthbuffer");
+ viewvecs_uniform = GPU_shader_get_uniform(dof_shader_pass1, "viewvecs");
+
+ GPU_shader_bind(dof_shader_pass1);
+
+ GPU_shader_uniform_vector(dof_shader_pass1, dof_uniform, 4, 1, dof_params);
+ GPU_shader_uniform_vector(dof_shader_pass1, invrendertargetdim_uniform, 2, 1, invrendertargetdim);
+ GPU_shader_uniform_vector(dof_shader_pass1, viewvecs_uniform, 4, 3, viewvecs[0]);
+
+ GPU_texture_bind(src, numslots++);
+ GPU_shader_uniform_texture(dof_shader_pass1, color_uniform, src);
+
+ GPU_texture_bind(fx->depth_buffer, numslots++);
+ GPU_depth_texture_mode(fx->depth_buffer, false, true);
+ GPU_shader_uniform_texture(dof_shader_pass1, depth_uniform, fx->depth_buffer);
+
+ /* target is the downsampled coc buffer */
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0, NULL);
+ /* binding takes care of setting the viewport to the downsampled size */
+ GPU_texture_bind_as_framebuffer(fx->dof_near_coc_buffer);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ /* disable bindings */
+ GPU_texture_unbind(src);
+ GPU_depth_texture_mode(fx->depth_buffer, true, false);
+ GPU_texture_unbind(fx->depth_buffer);
+
+ GPU_framebuffer_texture_detach(fx->dof_near_coc_buffer);
+ numslots = 0;
+ }
+
+ /* second pass, gaussian blur the downsampled image */
+ {
+ int invrendertargetdim_uniform, color_uniform, depth_uniform, dof_uniform;
+ int viewvecs_uniform;
+ float invrendertargetdim[2] = {1.0f / GPU_texture_opengl_width(fx->dof_near_coc_blurred_buffer),
+ 1.0f / GPU_texture_opengl_height(fx->dof_near_coc_blurred_buffer)};
+ float tmp = invrendertargetdim[0];
+ invrendertargetdim[0] = 0.0f;
+
+ dof_params[2] = GPU_texture_opengl_width(fx->dof_near_coc_blurred_buffer) / (scale_camera * fx_dof->sensor);
+
+ dof_uniform = GPU_shader_get_uniform(dof_shader_pass2, "dof_params");
+ invrendertargetdim_uniform = GPU_shader_get_uniform(dof_shader_pass2, "invrendertargetdim");
+ color_uniform = GPU_shader_get_uniform(dof_shader_pass2, "colorbuffer");
+ depth_uniform = GPU_shader_get_uniform(dof_shader_pass2, "depthbuffer");
+ viewvecs_uniform = GPU_shader_get_uniform(dof_shader_pass2, "viewvecs");
+
+ /* Blurring vertically */
+ GPU_shader_bind(dof_shader_pass2);
+
+ GPU_shader_uniform_vector(dof_shader_pass2, dof_uniform, 4, 1, dof_params);
+ GPU_shader_uniform_vector(dof_shader_pass2, invrendertargetdim_uniform, 2, 1, invrendertargetdim);
+ GPU_shader_uniform_vector(dof_shader_pass2, viewvecs_uniform, 4, 3, viewvecs[0]);
+
+ GPU_texture_bind(fx->depth_buffer, numslots++);
+ GPU_depth_texture_mode(fx->depth_buffer, false, true);
+ GPU_shader_uniform_texture(dof_shader_pass2, depth_uniform, fx->depth_buffer);
+
+ GPU_texture_bind(fx->dof_near_coc_buffer, numslots++);
+ GPU_shader_uniform_texture(dof_shader_pass2, color_uniform, fx->dof_near_coc_buffer);
+
+ /* use final buffer as a temp here */
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0, NULL);
+
+ /* Drawing quad */
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ /* *unbind/detach */
+ GPU_texture_unbind(fx->dof_near_coc_buffer);
+ GPU_framebuffer_texture_detach(fx->dof_near_coc_final_buffer);
+
+ /* Blurring horizontally */
+ invrendertargetdim[0] = tmp;
+ invrendertargetdim[1] = 0.0f;
+ GPU_shader_uniform_vector(dof_shader_pass2, invrendertargetdim_uniform, 2, 1, invrendertargetdim);
+
+ GPU_texture_bind(fx->dof_near_coc_final_buffer, numslots++);
+ GPU_shader_uniform_texture(dof_shader_pass2, color_uniform, fx->dof_near_coc_final_buffer);
+
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_blurred_buffer, 0, NULL);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ /* *unbind/detach */
+ GPU_depth_texture_mode(fx->depth_buffer, true, false);
+ GPU_texture_unbind(fx->depth_buffer);
+
+ GPU_texture_unbind(fx->dof_near_coc_final_buffer);
+ GPU_framebuffer_texture_detach(fx->dof_near_coc_blurred_buffer);
+
+ dof_params[2] = fx->gbuffer_dim[0] / (scale_camera * fx_dof->sensor);
+
+ numslots = 0;
+ }
+
+ /* third pass, calculate near coc */
+ {
+ int near_coc_downsampled, near_coc_blurred;
+
+ near_coc_downsampled = GPU_shader_get_uniform(dof_shader_pass3, "colorbuffer");
+ near_coc_blurred = GPU_shader_get_uniform(dof_shader_pass3, "blurredcolorbuffer");
+
+ GPU_shader_bind(dof_shader_pass3);
+
+ GPU_texture_bind(fx->dof_near_coc_buffer, numslots++);
+ GPU_shader_uniform_texture(dof_shader_pass3, near_coc_downsampled, fx->dof_near_coc_buffer);
+
+ GPU_texture_bind(fx->dof_near_coc_blurred_buffer, numslots++);
+ GPU_shader_uniform_texture(dof_shader_pass3, near_coc_blurred, fx->dof_near_coc_blurred_buffer);
+
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0, NULL);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ /* disable bindings */
+ GPU_texture_unbind(fx->dof_near_coc_buffer);
+ GPU_texture_unbind(fx->dof_near_coc_blurred_buffer);
+
+ /* unbinding here restores the size to the original */
+ GPU_framebuffer_texture_detach(fx->dof_near_coc_final_buffer);
+
+ numslots = 0;
+ }
+
+ /* fourth pass blur final coc once to eliminate discontinuities */
+ {
+ int near_coc_downsampled;
+ int invrendertargetdim_uniform;
+ float invrendertargetdim[2] = {1.0f / GPU_texture_opengl_width(fx->dof_near_coc_blurred_buffer),
+ 1.0f / GPU_texture_opengl_height(fx->dof_near_coc_blurred_buffer)};
+
+ near_coc_downsampled = GPU_shader_get_uniform(dof_shader_pass4, "colorbuffer");
+ invrendertargetdim_uniform = GPU_shader_get_uniform(dof_shader_pass4, "invrendertargetdim");
+
+ GPU_shader_bind(dof_shader_pass4);
+
+ GPU_texture_bind(fx->dof_near_coc_final_buffer, numslots++);
+ GPU_shader_uniform_texture(dof_shader_pass4, near_coc_downsampled, fx->dof_near_coc_final_buffer);
+ GPU_shader_uniform_vector(dof_shader_pass4, invrendertargetdim_uniform, 2, 1, invrendertargetdim);
+
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0, NULL);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ /* disable bindings */
+ GPU_texture_unbind(fx->dof_near_coc_final_buffer);
+
+ /* unbinding here restores the size to the original */
+ GPU_framebuffer_texture_unbind(fx->gbuffer, fx->dof_near_coc_buffer);
+ GPU_framebuffer_texture_detach(fx->dof_near_coc_buffer);
+
+ numslots = 0;
+ }
+
+ /* final pass, merge blurred layers according to final calculated coc */
+ {
+ int medium_blurred_uniform, high_blurred_uniform, original_uniform, depth_uniform, dof_uniform;
+ int invrendertargetdim_uniform, viewvecs_uniform;
+ float invrendertargetdim[2] = {1.0f / fx->gbuffer_dim[0], 1.0f / fx->gbuffer_dim[1]};
+
+ medium_blurred_uniform = GPU_shader_get_uniform(dof_shader_pass5, "mblurredcolorbuffer");
+ high_blurred_uniform = GPU_shader_get_uniform(dof_shader_pass5, "blurredcolorbuffer");
+ dof_uniform = GPU_shader_get_uniform(dof_shader_pass5, "dof_params");
+ invrendertargetdim_uniform = GPU_shader_get_uniform(dof_shader_pass5, "invrendertargetdim");
+ original_uniform = GPU_shader_get_uniform(dof_shader_pass5, "colorbuffer");
+ depth_uniform = GPU_shader_get_uniform(dof_shader_pass5, "depthbuffer");
+ viewvecs_uniform = GPU_shader_get_uniform(dof_shader_pass5, "viewvecs");
+
+ GPU_shader_bind(dof_shader_pass5);
+
+ GPU_shader_uniform_vector(dof_shader_pass5, dof_uniform, 4, 1, dof_params);
+ GPU_shader_uniform_vector(dof_shader_pass5, invrendertargetdim_uniform, 2, 1, invrendertargetdim);
+ GPU_shader_uniform_vector(dof_shader_pass5, viewvecs_uniform, 4, 3, viewvecs[0]);
+
+ GPU_texture_bind(src, numslots++);
+ GPU_shader_uniform_texture(dof_shader_pass5, original_uniform, src);
+
+ GPU_texture_bind(fx->dof_near_coc_blurred_buffer, numslots++);
+ GPU_shader_uniform_texture(dof_shader_pass5, high_blurred_uniform, fx->dof_near_coc_blurred_buffer);
+
+ GPU_texture_bind(fx->dof_near_coc_buffer, numslots++);
+ GPU_shader_uniform_texture(dof_shader_pass5, medium_blurred_uniform, fx->dof_near_coc_buffer);
+
+ GPU_texture_bind(fx->depth_buffer, numslots++);
+ GPU_depth_texture_mode(fx->depth_buffer, false, true);
+ GPU_shader_uniform_texture(dof_shader_pass5, depth_uniform, fx->depth_buffer);
+
+ /* if this is the last pass, prepare for rendering on the frambuffer */
+ gpu_fx_bind_render_target(&passes_left, fx, ofs, target);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ /* disable bindings */
+ GPU_texture_unbind(fx->dof_near_coc_buffer);
+ GPU_texture_unbind(fx->dof_near_coc_blurred_buffer);
+ GPU_texture_unbind(src);
+ GPU_depth_texture_mode(fx->depth_buffer, true, false);
+ GPU_texture_unbind(fx->depth_buffer);
+
+ /* may not be attached, in that case this just returns */
+ if (target) {
+ GPU_framebuffer_texture_detach(target);
+ if (ofs) {
+ GPU_offscreen_bind(ofs, false);
+ }
+ else {
+ GPU_framebuffer_restore();
+ }
+ }
+
+ SWAP(GPUTexture *, target, src);
+ numslots = 0;
+ }
+ }
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ GPU_shader_unbind();
+
+ return true;
+}
+
+void GPU_fx_compositor_init_dof_settings(GPUDOFSettings *fx_dof)
+{
+ fx_dof->fstop = 128.0f;
+ fx_dof->focal_length = 1.0f;
+ fx_dof->focus_distance = 1.0f;
+ fx_dof->sensor = 1.0f;
+}
+
+void GPU_fx_compositor_init_ssao_settings(GPUSSAOSettings *fx_ssao)
+{
+ fx_ssao->factor = 1.0f;
+ fx_ssao->distance_max = 0.2f;
+ fx_ssao->attenuation = 1.0f;
+ fx_ssao->samples = 20;
+}
diff --git a/source/blender/gpu/intern/gpu_debug.c b/source/blender/gpu/intern/gpu_debug.c
new file mode 100644
index 00000000000..21257a9c734
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_debug.c
@@ -0,0 +1,749 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel, Jason Wilkins.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file source/blender/gpu/GPU_debug.h
+ * \ingroup gpu
+ */
+
+#include "BLI_sys_types.h"
+
+#include "BKE_global.h"
+
+#include "GPU_glew.h"
+#include "GPU_debug.h"
+#include "intern/gpu_private.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CASE_CODE_RETURN_STR(code) case code: return #code;
+
+static const char* gpu_gl_error_symbol(GLenum err)
+{
+ switch(err) {
+ CASE_CODE_RETURN_STR(GL_NO_ERROR)
+ CASE_CODE_RETURN_STR(GL_INVALID_ENUM)
+ CASE_CODE_RETURN_STR(GL_INVALID_VALUE)
+ CASE_CODE_RETURN_STR(GL_INVALID_OPERATION)
+ CASE_CODE_RETURN_STR(GL_STACK_OVERFLOW)
+ CASE_CODE_RETURN_STR(GL_STACK_UNDERFLOW)
+ CASE_CODE_RETURN_STR(GL_OUT_OF_MEMORY)
+
+#if GL_ARB_imaging
+ CASE_CODE_RETURN_STR(GL_TABLE_TOO_LARGE)
+#endif
+
+#if defined(WITH_GLU)
+ CASE_CODE_RETURN_STR(GLU_INVALID_ENUM)
+ CASE_CODE_RETURN_STR(GLU_INVALID_VALUE)
+ CASE_CODE_RETURN_STR(GLU_OUT_OF_MEMORY)
+#endif
+
+ default:
+ return "<unknown error>";
+ }
+}
+
+#undef CASE_CODE_RETURN_STR
+
+
+static bool gpu_report_gl_errors(const char *file, int line, const char *str)
+{
+ GLenum gl_error = glGetError();
+
+ if (gl_error == GL_NO_ERROR) {
+ return true;
+ }
+ else {
+ /* glGetError should have cleared the error flag, so if we get the
+ same flag twice that means glGetError itself probably triggered
+ the error. This happens on Windows if the GL context is invalid.
+ */
+ {
+ GLenum new_error = glGetError();
+ if (gl_error == new_error) {
+ fprintf(stderr, "GL: Possible context invalidation issue\n");
+ return false;
+ }
+ }
+
+ fprintf(
+ stderr,
+ "%s(%d): ``%s'' -> GL Error (0x%04X - %s): %s\n",
+ file,
+ line,
+ str,
+ gl_error,
+ gpu_gl_error_symbol(gl_error),
+ gpuErrorString(gl_error));
+
+ return false;
+ }
+}
+
+
+const char* gpuErrorString(GLenum err)
+{
+ switch(err) {
+ case GL_NO_ERROR:
+ return "No Error";
+
+ case GL_INVALID_ENUM:
+ return "Invalid Enumeration";
+
+ case GL_INVALID_VALUE:
+ return "Invalid Value";
+
+ case GL_INVALID_OPERATION:
+ return "Invalid Operation";
+
+ case GL_STACK_OVERFLOW:
+ return "Stack Overflow";
+
+ case GL_STACK_UNDERFLOW:
+ return "Stack Underflow";
+
+ case GL_OUT_OF_MEMORY:
+ return "Out of Memory";
+
+#if GL_ARB_imaging
+ case GL_TABLE_TOO_LARGE:
+ return "Table Too Large";
+#endif
+
+#if defined(WITH_GLU)
+ case GLU_INVALID_ENUM:
+ return "Invalid Enum (GLU)";
+
+ case GLU_INVALID_VALUE:
+ return "Invalid Value (GLU)";
+
+ case GLU_OUT_OF_MEMORY:
+ return "Out of Memory (GLU)";
+#endif
+
+ default:
+ return "<unknown error>";
+ }
+}
+
+
+#ifdef WITH_GPU_DEBUG
+
+/* Debug callbacks need the same calling convention as OpenGL functions.
+ */
+#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
+ /* Win32 but not WinCE */
+# define APIENTRY __stdcall
+#else
+# define APIENTRY
+#endif
+
+
+static void APIENTRY gpu_debug_proc(GLenum UNUSED(source), GLenum UNUSED(type), GLuint UNUSED(id),
+ GLenum UNUSED(severity), GLsizei UNUSED(length),
+ const GLchar *message, GLvoid *UNUSED(userParm))
+{
+ fprintf(stderr, "GL: %s\n", message);
+}
+
+
+#ifndef GLEW_ES_ONLY
+static void APIENTRY gpu_debug_proc_amd(GLuint UNUSED(id), GLenum UNUSED(category),
+ GLenum UNUSED(severity), GLsizei UNUSED(length),
+ const GLchar *message, GLvoid *UNUSED(userParm))
+{
+ fprintf(stderr, "GL: %s\n", message);
+}
+#endif
+
+
+#undef APIENTRY
+
+void gpu_debug_init(void)
+{
+ const char success[] = "Successfully hooked OpenGL debug callback.";
+
+#if !defined(WITH_GLEW_ES) && !defined(GLEW_ES_ONLY)
+ if (GLEW_VERSION_4_3) {
+ glDebugMessageCallback(gpu_debug_proc, mxGetCurrentContext());
+ glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
+ GPU_STRING_MARKER(sizeof(success), success);
+ return;
+ }
+#endif
+
+ if (GLEW_KHR_debug) {
+#ifndef GLEW_NO_ES
+ if (MX_profile_es20)
+ {
+ glDebugMessageCallbackKHR(gpu_debug_proc, mxGetCurrentContext());
+ glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
+ GPU_STRING_MARKER(sizeof(success), success);
+ }
+ else
+#endif
+ {
+#ifndef GLEW_ES_ONLY
+ glDebugMessageCallback(gpu_debug_proc, mxGetCurrentContext());
+ glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
+ GPU_STRING_MARKER(sizeof(success), success);
+#endif
+ }
+
+ return;
+ }
+
+#ifndef GLEW_ES_ONLY
+ if (GLEW_ARB_debug_output) {
+ glDebugMessageCallbackARB(gpu_debug_proc, mxGetCurrentContext());
+ glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
+ GPU_STRING_MARKER(sizeof(success), success);
+
+ return;
+ }
+
+ if (GLEW_AMD_debug_output) {
+ glDebugMessageCallbackAMD(gpu_debug_proc_amd, mxGetCurrentContext());
+ glDebugMessageEnableAMD(GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
+ GPU_STRING_MARKER(sizeof(success), success);
+
+ return;
+ }
+#endif
+
+ fprintf(stderr, "Failed to hook OpenGL debug callback.\n");
+
+ return;
+}
+
+
+void gpu_debug_exit(void)
+{
+#ifndef WITH_GLEW_ES
+#ifndef GLEW_ES_ONLY
+ if (GLEW_VERSION_4_3) {
+ glDebugMessageCallback(NULL, NULL);
+
+ return;
+ }
+#endif
+#endif
+
+ if (GLEW_KHR_debug) {
+#ifndef GLEW_NO_ES
+ if (MX_profile_es20)
+ {
+ glDebugMessageCallbackKHR(NULL, NULL);
+ }
+ else
+#endif
+ {
+#ifndef GLEW_ES_ONLY
+ glDebugMessageCallback(NULL, NULL);
+#endif
+ }
+
+ return;
+ }
+
+#ifndef GLEW_ES_ONLY
+ if (GLEW_ARB_debug_output) {
+ glDebugMessageCallbackARB(NULL, NULL);
+
+ return;
+ }
+
+ if (GLEW_AMD_debug_output) {
+ glDebugMessageCallbackAMD(NULL, NULL);
+
+ return;
+ }
+#endif
+
+ return;
+}
+
+void gpu_string_marker(size_t length, const char *buf)
+{
+#ifndef WITH_GLEW_ES
+#ifndef GLEW_ES_ONLY
+ if (GLEW_VERSION_4_3) {
+ glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0, GL_DEBUG_SEVERITY_NOTIFICATION, length, buf);
+
+ return;
+ }
+#endif
+#endif
+
+ if (GLEW_KHR_debug) {
+#ifndef GLEW_NO_ES
+ if (MX_profile_es20)
+ {
+ glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION_KHR, GL_DEBUG_TYPE_MARKER_KHR, 0, GL_DEBUG_SEVERITY_NOTIFICATION_KHR, length, buf);
+ }
+ else
+#endif
+ {
+#ifndef GLEW_ES_ONLY
+ glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0, GL_DEBUG_SEVERITY_NOTIFICATION, length, buf);
+#endif
+ }
+
+ return;
+ }
+
+#ifndef GLEW_ES_ONLY
+ if (GLEW_ARB_debug_output) {
+ glDebugMessageInsertARB(GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, length, buf);
+
+ return;
+ }
+
+ if (GLEW_AMD_debug_output) {
+ glDebugMessageInsertAMD(GL_DEBUG_CATEGORY_APPLICATION_AMD, GL_DEBUG_SEVERITY_LOW_AMD, 0, length, buf);
+
+ return;
+ }
+
+ if (GLEW_GREMEDY_string_marker) {
+ glStringMarkerGREMEDY(length, buf);
+
+ return;
+ }
+#endif
+
+ return;
+}
+
+#endif /* WITH_GPU_DEBUG */
+
+void GPU_print_error_debug(const char *str)
+{
+ if (G.debug & G_DEBUG)
+ fprintf(stderr, "GPU: %s\n", str);
+}
+
+
+void gpu_assert_no_gl_errors(const char* file, int line, const char* str)
+{
+ if (G.debug) {
+ GLboolean gl_ok = gpu_report_gl_errors(file, line, str);
+
+ BLI_assert(gl_ok);
+ }
+}
+
+
+static void gpu_state_print_fl_ex(const char *name, GLenum type)
+{
+ const unsigned char err_mark[4] = {0xff, 0xff, 0xff, 0xff};
+
+ float value[32];
+ int a;
+
+ memset(value, 0xff, sizeof(value));
+ glGetFloatv(type, value);
+
+ if (glGetError() == GL_NO_ERROR) {
+ printf("%s: ", name);
+ for (a = 0; a < 32; a++) {
+ if (memcmp(&value[a], err_mark, sizeof(value[a])) == 0) {
+ break;
+ }
+ printf("%.2f ", value[a]);
+ }
+ printf("\n");
+ }
+}
+
+#define gpu_state_print_fl(val) gpu_state_print_fl_ex(#val, val)
+
+void GPU_state_print(void)
+{
+ GPU_ASSERT_NO_GL_ERRORS("GPU_state_print"); /* clear any errors */
+
+ gpu_state_print_fl(GL_ACCUM_ALPHA_BITS);
+ gpu_state_print_fl(GL_ACCUM_BLUE_BITS);
+ gpu_state_print_fl(GL_ACCUM_CLEAR_VALUE);
+ gpu_state_print_fl(GL_ACCUM_GREEN_BITS);
+ gpu_state_print_fl(GL_ACCUM_RED_BITS);
+ gpu_state_print_fl(GL_ACTIVE_TEXTURE);
+ gpu_state_print_fl(GL_ALIASED_LINE_WIDTH_RANGE);
+ gpu_state_print_fl(GL_ALIASED_POINT_SIZE_RANGE);
+ gpu_state_print_fl(GL_ALPHA_BIAS);
+ gpu_state_print_fl(GL_ALPHA_BITS);
+ gpu_state_print_fl(GL_ALPHA_SCALE);
+ gpu_state_print_fl(GL_ALPHA_TEST);
+ gpu_state_print_fl(GL_ALPHA_TEST_FUNC);
+ gpu_state_print_fl(GL_ALPHA_TEST_REF);
+ gpu_state_print_fl(GL_ARRAY_BUFFER_BINDING);
+ gpu_state_print_fl(GL_ATTRIB_STACK_DEPTH);
+ gpu_state_print_fl(GL_AUTO_NORMAL);
+ gpu_state_print_fl(GL_AUX_BUFFERS);
+ gpu_state_print_fl(GL_BLEND);
+ gpu_state_print_fl(GL_BLEND_COLOR);
+ gpu_state_print_fl(GL_BLEND_DST_ALPHA);
+ gpu_state_print_fl(GL_BLEND_DST_RGB);
+ gpu_state_print_fl(GL_BLEND_EQUATION_ALPHA);
+ gpu_state_print_fl(GL_BLEND_EQUATION_RGB);
+ gpu_state_print_fl(GL_BLEND_SRC_ALPHA);
+ gpu_state_print_fl(GL_BLEND_SRC_RGB);
+ gpu_state_print_fl(GL_BLUE_BIAS);
+ gpu_state_print_fl(GL_BLUE_BITS);
+ gpu_state_print_fl(GL_BLUE_SCALE);
+ gpu_state_print_fl(GL_CLIENT_ACTIVE_TEXTURE);
+ gpu_state_print_fl(GL_CLIENT_ATTRIB_STACK_DEPTH);
+ gpu_state_print_fl(GL_CLIP_PLANE0);
+ gpu_state_print_fl(GL_COLOR_ARRAY);
+ gpu_state_print_fl(GL_COLOR_ARRAY_BUFFER_BINDING);
+ gpu_state_print_fl(GL_COLOR_ARRAY_SIZE);
+ gpu_state_print_fl(GL_COLOR_ARRAY_STRIDE);
+ gpu_state_print_fl(GL_COLOR_ARRAY_TYPE);
+ gpu_state_print_fl(GL_COLOR_CLEAR_VALUE);
+ gpu_state_print_fl(GL_COLOR_LOGIC_OP);
+ gpu_state_print_fl(GL_COLOR_MATERIAL);
+ gpu_state_print_fl(GL_COLOR_MATERIAL_FACE);
+ gpu_state_print_fl(GL_COLOR_MATERIAL_PARAMETER);
+ gpu_state_print_fl(GL_COLOR_MATRIX);
+ gpu_state_print_fl(GL_COLOR_MATRIX_STACK_DEPTH);
+ gpu_state_print_fl(GL_COLOR_SUM);
+ gpu_state_print_fl(GL_COLOR_TABLE);
+ gpu_state_print_fl(GL_COLOR_WRITEMASK);
+ gpu_state_print_fl(GL_COMPRESSED_TEXTURE_FORMATS);
+ gpu_state_print_fl(GL_CONVOLUTION_1D);
+ gpu_state_print_fl(GL_CONVOLUTION_2D);
+ gpu_state_print_fl(GL_CULL_FACE);
+ gpu_state_print_fl(GL_CULL_FACE_MODE);
+ gpu_state_print_fl(GL_CURRENT_COLOR);
+ gpu_state_print_fl(GL_CURRENT_FOG_COORD);
+ gpu_state_print_fl(GL_CURRENT_INDEX);
+ gpu_state_print_fl(GL_CURRENT_NORMAL);
+ gpu_state_print_fl(GL_CURRENT_PROGRAM);
+ gpu_state_print_fl(GL_CURRENT_RASTER_COLOR);
+ gpu_state_print_fl(GL_CURRENT_RASTER_DISTANCE);
+ gpu_state_print_fl(GL_CURRENT_RASTER_INDEX);
+ gpu_state_print_fl(GL_CURRENT_RASTER_POSITION);
+ gpu_state_print_fl(GL_CURRENT_RASTER_POSITION_VALID);
+ gpu_state_print_fl(GL_CURRENT_RASTER_SECONDARY_COLOR);
+ gpu_state_print_fl(GL_CURRENT_RASTER_TEXTURE_COORDS);
+ gpu_state_print_fl(GL_CURRENT_SECONDARY_COLOR);
+ gpu_state_print_fl(GL_CURRENT_TEXTURE_COORDS);
+ gpu_state_print_fl(GL_DEPTH_BIAS);
+ gpu_state_print_fl(GL_DEPTH_BITS);
+ gpu_state_print_fl(GL_DEPTH_CLEAR_VALUE);
+ gpu_state_print_fl(GL_DEPTH_FUNC);
+ gpu_state_print_fl(GL_DEPTH_RANGE);
+ gpu_state_print_fl(GL_DEPTH_SCALE);
+ gpu_state_print_fl(GL_DEPTH_TEST);
+ gpu_state_print_fl(GL_DEPTH_WRITEMASK);
+ gpu_state_print_fl(GL_DITHER);
+ gpu_state_print_fl(GL_DOUBLEBUFFER);
+ gpu_state_print_fl(GL_DRAW_BUFFER);
+ gpu_state_print_fl(GL_DRAW_BUFFER0);
+ gpu_state_print_fl(GL_EDGE_FLAG);
+ gpu_state_print_fl(GL_EDGE_FLAG_ARRAY);
+ gpu_state_print_fl(GL_EDGE_FLAG_ARRAY_BUFFER_BINDING);
+ gpu_state_print_fl(GL_EDGE_FLAG_ARRAY_STRIDE);
+ gpu_state_print_fl(GL_ELEMENT_ARRAY_BUFFER_BINDING);
+ gpu_state_print_fl(GL_FEEDBACK_BUFFER_SIZE);
+ gpu_state_print_fl(GL_FEEDBACK_BUFFER_TYPE);
+ gpu_state_print_fl(GL_FOG);
+ gpu_state_print_fl(GL_FOG_COLOR);
+ gpu_state_print_fl(GL_FOG_COORD_ARRAY);
+ gpu_state_print_fl(GL_FOG_COORD_ARRAY_BUFFER_BINDING);
+ gpu_state_print_fl(GL_FOG_COORD_ARRAY_STRIDE);
+ gpu_state_print_fl(GL_FOG_COORD_ARRAY_TYPE);
+ gpu_state_print_fl(GL_FOG_COORD_SRC);
+ gpu_state_print_fl(GL_FOG_DENSITY);
+ gpu_state_print_fl(GL_FOG_END);
+ gpu_state_print_fl(GL_FOG_HINT);
+ gpu_state_print_fl(GL_FOG_INDEX);
+ gpu_state_print_fl(GL_FOG_MODE);
+ gpu_state_print_fl(GL_FOG_START);
+ gpu_state_print_fl(GL_FRAGMENT_PROGRAM_ARB);
+ gpu_state_print_fl(GL_FRAGMENT_SHADER_DERIVATIVE_HINT);
+ gpu_state_print_fl(GL_FRONT_FACE);
+ gpu_state_print_fl(GL_GENERATE_MIPMAP_HINT);
+ gpu_state_print_fl(GL_GREEN_BIAS);
+ gpu_state_print_fl(GL_GREEN_BITS);
+ gpu_state_print_fl(GL_GREEN_SCALE);
+ gpu_state_print_fl(GL_HISTOGRAM);
+ gpu_state_print_fl(GL_INDEX_ARRAY);
+ gpu_state_print_fl(GL_INDEX_ARRAY_BUFFER_BINDING);
+ gpu_state_print_fl(GL_INDEX_ARRAY_STRIDE);
+ gpu_state_print_fl(GL_INDEX_ARRAY_TYPE);
+ gpu_state_print_fl(GL_INDEX_BITS);
+ gpu_state_print_fl(GL_INDEX_CLEAR_VALUE);
+ gpu_state_print_fl(GL_INDEX_LOGIC_OP);
+ gpu_state_print_fl(GL_INDEX_MODE);
+ gpu_state_print_fl(GL_INDEX_OFFSET);
+ gpu_state_print_fl(GL_INDEX_SHIFT);
+ gpu_state_print_fl(GL_INDEX_WRITEMASK);
+ gpu_state_print_fl(GL_LIGHT0);
+ gpu_state_print_fl(GL_LIGHT1);
+ gpu_state_print_fl(GL_LIGHT2);
+ gpu_state_print_fl(GL_LIGHT3);
+ gpu_state_print_fl(GL_LIGHT4);
+ gpu_state_print_fl(GL_LIGHT5);
+ gpu_state_print_fl(GL_LIGHT6);
+ gpu_state_print_fl(GL_LIGHT7);
+ gpu_state_print_fl(GL_LIGHTING);
+ gpu_state_print_fl(GL_LIGHT_MODEL_AMBIENT);
+ gpu_state_print_fl(GL_LIGHT_MODEL_COLOR_CONTROL);
+ gpu_state_print_fl(GL_LIGHT_MODEL_LOCAL_VIEWER);
+ gpu_state_print_fl(GL_LIGHT_MODEL_TWO_SIDE);
+ gpu_state_print_fl(GL_LINE_SMOOTH);
+ gpu_state_print_fl(GL_LINE_SMOOTH_HINT);
+ gpu_state_print_fl(GL_LINE_STIPPLE);
+ gpu_state_print_fl(GL_LINE_STIPPLE_PATTERN);
+ gpu_state_print_fl(GL_LINE_STIPPLE_REPEAT);
+ gpu_state_print_fl(GL_LINE_WIDTH);
+ gpu_state_print_fl(GL_LINE_WIDTH_GRANULARITY);
+ gpu_state_print_fl(GL_LINE_WIDTH_RANGE);
+ gpu_state_print_fl(GL_LIST_BASE);
+ gpu_state_print_fl(GL_LIST_INDEX);
+ gpu_state_print_fl(GL_LIST_MODE);
+ gpu_state_print_fl(GL_LOGIC_OP);
+ gpu_state_print_fl(GL_LOGIC_OP_MODE);
+ gpu_state_print_fl(GL_MAP1_COLOR_4);
+ gpu_state_print_fl(GL_MAP1_GRID_DOMAIN);
+ gpu_state_print_fl(GL_MAP1_GRID_SEGMENTS);
+ gpu_state_print_fl(GL_MAP1_INDEX);
+ gpu_state_print_fl(GL_MAP1_NORMAL);
+ gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_1);
+ gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_2);
+ gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_3);
+ gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_4);
+ gpu_state_print_fl(GL_MAP1_VERTEX_3);
+ gpu_state_print_fl(GL_MAP1_VERTEX_4);
+ gpu_state_print_fl(GL_MAP2_COLOR_4);
+ gpu_state_print_fl(GL_MAP2_GRID_DOMAIN);
+ gpu_state_print_fl(GL_MAP2_GRID_SEGMENTS);
+ gpu_state_print_fl(GL_MAP2_INDEX);
+ gpu_state_print_fl(GL_MAP2_NORMAL);
+ gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_1);
+ gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_2);
+ gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_3);
+ gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_4);
+ gpu_state_print_fl(GL_MAP2_VERTEX_3);
+ gpu_state_print_fl(GL_MAP2_VERTEX_4);
+ gpu_state_print_fl(GL_MAP_COLOR);
+ gpu_state_print_fl(GL_MAP_STENCIL);
+ gpu_state_print_fl(GL_MATRIX_MODE);
+ gpu_state_print_fl(GL_MAX_3D_TEXTURE_SIZE);
+ gpu_state_print_fl(GL_MAX_ATTRIB_STACK_DEPTH);
+ gpu_state_print_fl(GL_MAX_CLIENT_ATTRIB_STACK_DEPTH);
+ gpu_state_print_fl(GL_MAX_CLIP_PLANES);
+ gpu_state_print_fl(GL_MAX_COLOR_MATRIX_STACK_DEPTH);
+ gpu_state_print_fl(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ gpu_state_print_fl(GL_MAX_CUBE_MAP_TEXTURE_SIZE);
+ gpu_state_print_fl(GL_MAX_DRAW_BUFFERS);
+ gpu_state_print_fl(GL_MAX_ELEMENTS_INDICES);
+ gpu_state_print_fl(GL_MAX_ELEMENTS_VERTICES);
+ gpu_state_print_fl(GL_MAX_EVAL_ORDER);
+ gpu_state_print_fl(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
+ gpu_state_print_fl(GL_MAX_LIGHTS);
+ gpu_state_print_fl(GL_MAX_LIST_NESTING);
+ gpu_state_print_fl(GL_MAX_MODELVIEW_STACK_DEPTH);
+ gpu_state_print_fl(GL_MAX_NAME_STACK_DEPTH);
+ gpu_state_print_fl(GL_MAX_PIXEL_MAP_TABLE);
+ gpu_state_print_fl(GL_MAX_PROJECTION_STACK_DEPTH);
+ gpu_state_print_fl(GL_MAX_TEXTURE_COORDS);
+ gpu_state_print_fl(GL_MAX_TEXTURE_IMAGE_UNITS);
+ gpu_state_print_fl(GL_MAX_TEXTURE_LOD_BIAS);
+ gpu_state_print_fl(GL_MAX_TEXTURE_SIZE);
+ gpu_state_print_fl(GL_MAX_TEXTURE_STACK_DEPTH);
+ gpu_state_print_fl(GL_MAX_TEXTURE_UNITS);
+ gpu_state_print_fl(GL_MAX_VARYING_FLOATS);
+ gpu_state_print_fl(GL_MAX_VERTEX_ATTRIBS);
+ gpu_state_print_fl(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ gpu_state_print_fl(GL_MAX_VERTEX_UNIFORM_COMPONENTS);
+ gpu_state_print_fl(GL_MAX_VIEWPORT_DIMS);
+ gpu_state_print_fl(GL_MINMAX);
+ gpu_state_print_fl(GL_MODELVIEW_MATRIX);
+ gpu_state_print_fl(GL_MODELVIEW_STACK_DEPTH);
+ gpu_state_print_fl(GL_MULTISAMPLE);
+ gpu_state_print_fl(GL_MULTISAMPLE_ARB);
+ gpu_state_print_fl(GL_NAME_STACK_DEPTH);
+ gpu_state_print_fl(GL_NORMALIZE);
+ gpu_state_print_fl(GL_NORMAL_ARRAY);
+ gpu_state_print_fl(GL_NORMAL_ARRAY_BUFFER_BINDING);
+ gpu_state_print_fl(GL_NORMAL_ARRAY_STRIDE);
+ gpu_state_print_fl(GL_NORMAL_ARRAY_TYPE);
+ gpu_state_print_fl(GL_NUM_COMPRESSED_TEXTURE_FORMATS);
+ gpu_state_print_fl(GL_PACK_ALIGNMENT);
+ gpu_state_print_fl(GL_PACK_IMAGE_HEIGHT);
+ gpu_state_print_fl(GL_PACK_LSB_FIRST);
+ gpu_state_print_fl(GL_PACK_ROW_LENGTH);
+ gpu_state_print_fl(GL_PACK_SKIP_IMAGES);
+ gpu_state_print_fl(GL_PACK_SKIP_PIXELS);
+ gpu_state_print_fl(GL_PACK_SKIP_ROWS);
+ gpu_state_print_fl(GL_PACK_SWAP_BYTES);
+ gpu_state_print_fl(GL_PERSPECTIVE_CORRECTION_HINT);
+ gpu_state_print_fl(GL_PIXEL_MAP_A_TO_A_SIZE);
+ gpu_state_print_fl(GL_PIXEL_MAP_B_TO_B_SIZE);
+ gpu_state_print_fl(GL_PIXEL_MAP_G_TO_G_SIZE);
+ gpu_state_print_fl(GL_PIXEL_MAP_I_TO_A_SIZE);
+ gpu_state_print_fl(GL_PIXEL_MAP_I_TO_B_SIZE);
+ gpu_state_print_fl(GL_PIXEL_MAP_I_TO_G_SIZE);
+ gpu_state_print_fl(GL_PIXEL_MAP_I_TO_I_SIZE);
+ gpu_state_print_fl(GL_PIXEL_MAP_I_TO_R_SIZE);
+ gpu_state_print_fl(GL_PIXEL_MAP_R_TO_R_SIZE);
+ gpu_state_print_fl(GL_PIXEL_MAP_S_TO_S_SIZE);
+ gpu_state_print_fl(GL_PIXEL_PACK_BUFFER_BINDING);
+ gpu_state_print_fl(GL_PIXEL_UNPACK_BUFFER_BINDING);
+ gpu_state_print_fl(GL_POINT_DISTANCE_ATTENUATION);
+ gpu_state_print_fl(GL_POINT_FADE_THRESHOLD_SIZE);
+ gpu_state_print_fl(GL_POINT_SIZE);
+ gpu_state_print_fl(GL_POINT_SIZE_GRANULARITY);
+ gpu_state_print_fl(GL_POINT_SIZE_MAX);
+ gpu_state_print_fl(GL_POINT_SIZE_MIN);
+ gpu_state_print_fl(GL_POINT_SIZE_RANGE);
+ gpu_state_print_fl(GL_POINT_SMOOTH);
+ gpu_state_print_fl(GL_POINT_SMOOTH_HINT);
+ gpu_state_print_fl(GL_POINT_SPRITE);
+ gpu_state_print_fl(GL_POLYGON_MODE);
+ gpu_state_print_fl(GL_POLYGON_OFFSET_FACTOR);
+ gpu_state_print_fl(GL_POLYGON_OFFSET_FILL);
+ gpu_state_print_fl(GL_POLYGON_OFFSET_LINE);
+ gpu_state_print_fl(GL_POLYGON_OFFSET_POINT);
+ gpu_state_print_fl(GL_POLYGON_OFFSET_UNITS);
+ gpu_state_print_fl(GL_POLYGON_SMOOTH);
+ gpu_state_print_fl(GL_POLYGON_SMOOTH_HINT);
+ gpu_state_print_fl(GL_POLYGON_STIPPLE);
+ gpu_state_print_fl(GL_POST_COLOR_MATRIX_ALPHA_BIAS);
+ gpu_state_print_fl(GL_POST_COLOR_MATRIX_ALPHA_SCALE);
+ gpu_state_print_fl(GL_POST_COLOR_MATRIX_BLUE_BIAS);
+ gpu_state_print_fl(GL_POST_COLOR_MATRIX_BLUE_SCALE);
+ gpu_state_print_fl(GL_POST_COLOR_MATRIX_COLOR_TABLE);
+ gpu_state_print_fl(GL_POST_COLOR_MATRIX_GREEN_BIAS);
+ gpu_state_print_fl(GL_POST_COLOR_MATRIX_GREEN_SCALE);
+ gpu_state_print_fl(GL_POST_COLOR_MATRIX_RED_BIAS);
+ gpu_state_print_fl(GL_POST_COLOR_MATRIX_RED_SCALE);
+ gpu_state_print_fl(GL_POST_CONVOLUTION_ALPHA_BIAS);
+ gpu_state_print_fl(GL_POST_CONVOLUTION_ALPHA_SCALE);
+ gpu_state_print_fl(GL_POST_CONVOLUTION_BLUE_BIAS);
+ gpu_state_print_fl(GL_POST_CONVOLUTION_BLUE_SCALE);
+ gpu_state_print_fl(GL_POST_CONVOLUTION_COLOR_TABLE);
+ gpu_state_print_fl(GL_POST_CONVOLUTION_GREEN_BIAS);
+ gpu_state_print_fl(GL_POST_CONVOLUTION_GREEN_SCALE);
+ gpu_state_print_fl(GL_POST_CONVOLUTION_RED_BIAS);
+ gpu_state_print_fl(GL_POST_CONVOLUTION_RED_SCALE);
+ gpu_state_print_fl(GL_PROJECTION_MATRIX);
+ gpu_state_print_fl(GL_PROJECTION_STACK_DEPTH);
+ gpu_state_print_fl(GL_READ_BUFFER);
+ gpu_state_print_fl(GL_RED_BIAS);
+ gpu_state_print_fl(GL_RED_BITS);
+ gpu_state_print_fl(GL_RED_SCALE);
+ gpu_state_print_fl(GL_RENDER_MODE);
+ gpu_state_print_fl(GL_RESCALE_NORMAL);
+ gpu_state_print_fl(GL_RGBA_MODE);
+ gpu_state_print_fl(GL_SAMPLES);
+ gpu_state_print_fl(GL_SAMPLE_BUFFERS);
+ gpu_state_print_fl(GL_SAMPLE_COVERAGE_INVERT);
+ gpu_state_print_fl(GL_SAMPLE_COVERAGE_VALUE);
+ gpu_state_print_fl(GL_SCISSOR_BOX);
+ gpu_state_print_fl(GL_SCISSOR_TEST);
+ gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY);
+ gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING);
+ gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_SIZE);
+ gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_STRIDE);
+ gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_TYPE);
+ gpu_state_print_fl(GL_SELECTION_BUFFER_SIZE);
+ gpu_state_print_fl(GL_SEPARABLE_2D);
+ gpu_state_print_fl(GL_SHADE_MODEL);
+ gpu_state_print_fl(GL_SMOOTH_LINE_WIDTH_GRANULARITY);
+ gpu_state_print_fl(GL_SMOOTH_LINE_WIDTH_RANGE);
+ gpu_state_print_fl(GL_SMOOTH_POINT_SIZE_GRANULARITY);
+ gpu_state_print_fl(GL_SMOOTH_POINT_SIZE_RANGE);
+ gpu_state_print_fl(GL_STENCIL_BACK_FAIL);
+ gpu_state_print_fl(GL_STENCIL_BACK_FUNC);
+ gpu_state_print_fl(GL_STENCIL_BACK_PASS_DEPTH_FAIL);
+ gpu_state_print_fl(GL_STENCIL_BACK_PASS_DEPTH_PASS);
+ gpu_state_print_fl(GL_STENCIL_BACK_REF);
+ gpu_state_print_fl(GL_STENCIL_BACK_VALUE_MASK);
+ gpu_state_print_fl(GL_STENCIL_BACK_WRITEMASK);
+ gpu_state_print_fl(GL_STENCIL_BITS);
+ gpu_state_print_fl(GL_STENCIL_CLEAR_VALUE);
+ gpu_state_print_fl(GL_STENCIL_FAIL);
+ gpu_state_print_fl(GL_STENCIL_FUNC);
+ gpu_state_print_fl(GL_STENCIL_PASS_DEPTH_FAIL);
+ gpu_state_print_fl(GL_STENCIL_PASS_DEPTH_PASS);
+ gpu_state_print_fl(GL_STENCIL_REF);
+ gpu_state_print_fl(GL_STENCIL_TEST);
+ gpu_state_print_fl(GL_STENCIL_VALUE_MASK);
+ gpu_state_print_fl(GL_STENCIL_WRITEMASK);
+ gpu_state_print_fl(GL_STEREO);
+ gpu_state_print_fl(GL_SUBPIXEL_BITS);
+ gpu_state_print_fl(GL_TEXTURE_1D);
+ gpu_state_print_fl(GL_TEXTURE_2D);
+ gpu_state_print_fl(GL_TEXTURE_3D);
+ gpu_state_print_fl(GL_TEXTURE_BINDING_1D);
+ gpu_state_print_fl(GL_TEXTURE_BINDING_2D);
+ gpu_state_print_fl(GL_TEXTURE_BINDING_3D);
+ gpu_state_print_fl(GL_TEXTURE_BINDING_CUBE_MAP);
+ gpu_state_print_fl(GL_TEXTURE_COMPRESSION_HINT);
+ gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY);
+ gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING);
+ gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_SIZE);
+ gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_STRIDE);
+ gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_TYPE);
+ gpu_state_print_fl(GL_TEXTURE_CUBE_MAP);
+ gpu_state_print_fl(GL_TEXTURE_CUBE_MAP_ARB);
+ gpu_state_print_fl(GL_TEXTURE_GEN_Q);
+ gpu_state_print_fl(GL_TEXTURE_GEN_R);
+ gpu_state_print_fl(GL_TEXTURE_GEN_S);
+ gpu_state_print_fl(GL_TEXTURE_GEN_T);
+ gpu_state_print_fl(GL_TEXTURE_MATRIX);
+ gpu_state_print_fl(GL_TEXTURE_STACK_DEPTH);
+ gpu_state_print_fl(GL_TRANSPOSE_COLOR_MATRIX);
+ gpu_state_print_fl(GL_TRANSPOSE_MODELVIEW_MATRIX);
+ gpu_state_print_fl(GL_TRANSPOSE_PROJECTION_MATRIX);
+ gpu_state_print_fl(GL_TRANSPOSE_TEXTURE_MATRIX);
+ gpu_state_print_fl(GL_UNPACK_ALIGNMENT);
+ gpu_state_print_fl(GL_UNPACK_IMAGE_HEIGHT);
+ gpu_state_print_fl(GL_UNPACK_LSB_FIRST);
+ gpu_state_print_fl(GL_UNPACK_ROW_LENGTH);
+ gpu_state_print_fl(GL_UNPACK_SKIP_IMAGES);
+ gpu_state_print_fl(GL_UNPACK_SKIP_PIXELS);
+ gpu_state_print_fl(GL_UNPACK_SKIP_ROWS);
+ gpu_state_print_fl(GL_UNPACK_SWAP_BYTES);
+ gpu_state_print_fl(GL_VERTEX_ARRAY);
+ gpu_state_print_fl(GL_VERTEX_ARRAY_BUFFER_BINDING);
+ gpu_state_print_fl(GL_VERTEX_ARRAY_SIZE);
+ gpu_state_print_fl(GL_VERTEX_ARRAY_STRIDE);
+ gpu_state_print_fl(GL_VERTEX_ARRAY_TYPE);
+ gpu_state_print_fl(GL_VERTEX_PROGRAM_POINT_SIZE);
+ gpu_state_print_fl(GL_VERTEX_PROGRAM_TWO_SIDE);
+ gpu_state_print_fl(GL_VIEWPORT);
+ gpu_state_print_fl(GL_ZOOM_X);
+ gpu_state_print_fl(GL_ZOOM_Y);
+}
+
+#undef gpu_state_print_fl
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 622e7b5ce9e..3ed7253d309 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -39,6 +39,7 @@
#include <string.h>
#include "GPU_glew.h"
+#include "GPU_debug.h"
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
@@ -688,11 +689,10 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, bool compare, boo
}
/* Image *ima can be NULL */
-void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int rectw, int recth,
+void GPU_create_gl_tex(unsigned int *bind, unsigned int *rect, float *frect, int rectw, int recth,
bool mipmap, bool use_high_bit_depth, Image *ima)
{
- unsigned int *scalerect = NULL;
- float *fscalerect = NULL;
+ ImBuf *ibuf = NULL;
int tpx = rectw;
int tpy = recth;
@@ -702,20 +702,20 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int
* Then don't bother scaling for hardware that supports NPOT textures! */
if ((!GPU_non_power_of_two_support() && !is_power_of_2_resolution(rectw, recth)) ||
is_over_resolution_limit(rectw, recth)) {
- rectw= smaller_power_of_2_limit(rectw);
- recth= smaller_power_of_2_limit(recth);
+ rectw = smaller_power_of_2_limit(rectw);
+ recth = smaller_power_of_2_limit(recth);
if (use_high_bit_depth) {
- fscalerect= MEM_mallocN(rectw*recth*sizeof(*fscalerect)*4, "fscalerect");
- gluScaleImage(GL_RGBA, tpx, tpy, GL_FLOAT, frect, rectw, recth, GL_FLOAT, fscalerect);
+ ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy);
+ IMB_scaleImBuf(ibuf, rectw, recth);
- frect = fscalerect;
+ frect = ibuf->rect_float;
}
else {
- scalerect= MEM_mallocN(rectw*recth*sizeof(*scalerect), "scalerect");
- gluScaleImage(GL_RGBA, tpx, tpy, GL_UNSIGNED_BYTE, pix, rectw, recth, GL_UNSIGNED_BYTE, scalerect);
+ ibuf = IMB_allocFromBuffer(rect, NULL, tpx, tpy);
+ IMB_scaleImBuf(ibuf, rectw, recth);
- pix= scalerect;
+ rect = ibuf->rect;
}
}
@@ -724,19 +724,27 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int
glBindTexture(GL_TEXTURE_2D, *bind);
if (!(GPU_get_mipmap() && mipmap)) {
- if (use_high_bit_depth)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+ if (use_high_bit_depth) {
+ if (GLEW_ARB_texture_float)
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+ else
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+ }
else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
}
else {
if (GTS.gpu_mipmap) {
- if (use_high_bit_depth)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+ if (use_high_bit_depth) {
+ if (GLEW_ARB_texture_float)
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+ else
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
+ }
else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
gpu_generate_mipmap(GL_TEXTURE_2D);
}
@@ -744,7 +752,7 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int
if (use_high_bit_depth)
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, rectw, recth, GL_RGBA, GL_FLOAT, frect);
else
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, pix);
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
@@ -758,10 +766,8 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int
/* set to modulate with vertex color */
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- if (scalerect)
- MEM_freeN(scalerect);
- if (fscalerect)
- MEM_freeN(fscalerect);
+ if (ibuf)
+ IMB_freeImBuf(ibuf);
}
/**
@@ -788,12 +794,12 @@ bool GPU_upload_dxt_texture(ImBuf *ibuf)
}
if (format == 0) {
- printf("Unable to find a suitable DXT compression, falling back to uncompressed\n");
+ fprintf(stderr, "Unable to find a suitable DXT compression, falling back to uncompressed\n");
return false;
}
if (!is_power_of_2_resolution(width, height)) {
- printf("Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n");
+ fprintf(stderr, "Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n");
return false;
}
@@ -977,16 +983,16 @@ static bool GPU_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x,
if (rectw + x > x_limit) rectw--;
if (recth + y > y_limit) recth--;
- /* float rectangles are already continuous in memory so we can use gluScaleImage */
+ /* float rectangles are already continuous in memory so we can use IMB_scaleImBuf */
if (frect) {
- float *fscalerect = MEM_mallocN(rectw*recth*sizeof(*fscalerect)*4, "fscalerect");
- gluScaleImage(GL_RGBA, w, h, GL_FLOAT, frect, rectw, recth, GL_FLOAT, fscalerect);
+ ImBuf *ibuf = IMB_allocFromBuffer(NULL, frect, w, h);
+ IMB_scaleImBuf(ibuf, rectw, recth);
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, rectw, recth, GL_RGBA,
- GL_FLOAT, fscalerect);
+ GL_FLOAT, ibuf->rect_float);
- MEM_freeN(fscalerect);
+ IMB_freeImBuf(ibuf);
}
/* byte images are not continuous in memory so do manual interpolation */
else {
@@ -1316,7 +1322,7 @@ void GPU_free_images_old(void)
{
Image *ima;
static int lasttime = 0;
- int ctime = (int)PIL_check_seconds_timer();
+ int ctime = PIL_check_seconds_timer_i();
/*
* Run garbage collector once for every collecting period of time
@@ -1376,6 +1382,7 @@ static struct GPUMaterialState {
bool gscenelock;
float (*gviewmat)[4];
float (*gviewinv)[4];
+ float (*gviewcamtexcofac);
bool backface_culling;
@@ -1389,9 +1396,10 @@ static struct GPUMaterialState {
} GMS = {NULL};
/* fixed function material, alpha handed by caller */
-static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob, const int new_shading_nodes)
+static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob, const int new_shading_nodes,
+ const bool dimdown)
{
- if (new_shading_nodes || bmat->mode & MA_SHLESS) {
+ if (bmat->mode & MA_SHLESS) {
copy_v3_v3(smat->diff, &bmat->r);
smat->diff[3]= 1.0;
@@ -1401,6 +1409,24 @@ static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat,
zero_v4(smat->spec);
smat->hard= 0;
}
+ else if (new_shading_nodes) {
+ copy_v3_v3(smat->diff, &bmat->r);
+ smat->diff[3]= 1.0;
+
+ copy_v3_v3(smat->spec, &bmat->specr);
+ smat->spec[3] = 1.0;
+ smat->hard= CLAMPIS(bmat->har, 0, 128);
+
+ if (dimdown) {
+ mul_v3_fl(smat->diff, 0.8f);
+ mul_v3_fl(smat->spec, 0.5f);
+ }
+
+ if (gamma) {
+ linearrgb_to_srgb_v3_v3(smat->diff, smat->diff);
+ linearrgb_to_srgb_v3_v3(smat->spec, smat->spec);
+ }
+ }
else {
mul_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit);
smat->diff[3]= 1.0; /* caller may set this to bmat->alpha */
@@ -1465,6 +1491,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
GMS.gscenelock = (v3d->scenelock != 0);
GMS.gviewmat= rv3d->viewmat;
GMS.gviewinv= rv3d->viewinv;
+ GMS.gviewcamtexcofac = rv3d->viewcamtexcofac;
/* alpha pass setup. there's various cases to handle here:
* - object transparency on: only solid materials draw in the first pass,
@@ -1501,7 +1528,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
/* no materials assigned? */
if (ob->totcol==0) {
- gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes);
+ gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes, true);
/* do material 1 too, for displists! */
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
@@ -1531,7 +1558,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
}
else {
/* fixed function opengl materials */
- gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes);
+ gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes, false);
if (GMS.use_alpha_pass && ((ma->mode & MA_TRANSP) || (new_shading_nodes && ma->alpha != 1.0f))) {
GMS.matbuf[a].diff[3]= ma->alpha;
@@ -1623,7 +1650,7 @@ int GPU_enable_material(int nr, void *attribs)
gpumat = GPU_material_from_blender(GMS.gscene, mat);
GPU_material_vertex_attributes(gpumat, gattribs);
- GPU_material_bind(gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT), GMS.gviewmat, GMS.gviewinv, GMS.gscenelock);
+ GPU_material_bind(gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT), GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac, GMS.gscenelock);
auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f;
GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gob->col, auto_bump_scale);
@@ -1984,390 +2011,3 @@ void GPU_state_init(void)
gpu_multisample(false);
}
-#ifdef DEBUG
-/* debugging aid */
-static void gpu_state_print_fl_ex(const char *name, GLenum type)
-{
- const unsigned char err_mark[4] = {0xff, 0xff, 0xff, 0xff};
-
- float value[32];
- int a;
-
- memset(value, 0xff, sizeof(value));
- glGetFloatv(type, value);
-
- printf("%s: ", name);
- for (a = 0; a < 32; a++) {
- if (memcmp(&value[a], err_mark, sizeof(value[a])) == 0) {
- break;
- }
- printf("%.2f ", value[a]);
- }
- printf("\n");
-}
-
-#define gpu_state_print_fl(val) gpu_state_print_fl_ex(#val, val)
-
-void GPU_state_print(void)
-{
- gpu_state_print_fl(GL_ACCUM_ALPHA_BITS);
- gpu_state_print_fl(GL_ACCUM_BLUE_BITS);
- gpu_state_print_fl(GL_ACCUM_CLEAR_VALUE);
- gpu_state_print_fl(GL_ACCUM_GREEN_BITS);
- gpu_state_print_fl(GL_ACCUM_RED_BITS);
- gpu_state_print_fl(GL_ACTIVE_TEXTURE);
- gpu_state_print_fl(GL_ALIASED_LINE_WIDTH_RANGE);
- gpu_state_print_fl(GL_ALIASED_POINT_SIZE_RANGE);
- gpu_state_print_fl(GL_ALPHA_BIAS);
- gpu_state_print_fl(GL_ALPHA_BITS);
- gpu_state_print_fl(GL_ALPHA_SCALE);
- gpu_state_print_fl(GL_ALPHA_TEST);
- gpu_state_print_fl(GL_ALPHA_TEST_FUNC);
- gpu_state_print_fl(GL_ALPHA_TEST_REF);
- gpu_state_print_fl(GL_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_AUTO_NORMAL);
- gpu_state_print_fl(GL_AUX_BUFFERS);
- gpu_state_print_fl(GL_BLEND);
- gpu_state_print_fl(GL_BLEND_COLOR);
- gpu_state_print_fl(GL_BLEND_DST_ALPHA);
- gpu_state_print_fl(GL_BLEND_DST_RGB);
- gpu_state_print_fl(GL_BLEND_EQUATION_ALPHA);
- gpu_state_print_fl(GL_BLEND_EQUATION_RGB);
- gpu_state_print_fl(GL_BLEND_SRC_ALPHA);
- gpu_state_print_fl(GL_BLEND_SRC_RGB);
- gpu_state_print_fl(GL_BLUE_BIAS);
- gpu_state_print_fl(GL_BLUE_BITS);
- gpu_state_print_fl(GL_BLUE_SCALE);
- gpu_state_print_fl(GL_CLIENT_ACTIVE_TEXTURE);
- gpu_state_print_fl(GL_CLIENT_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_CLIP_PLANE0);
- gpu_state_print_fl(GL_COLOR_ARRAY);
- gpu_state_print_fl(GL_COLOR_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_COLOR_ARRAY_SIZE);
- gpu_state_print_fl(GL_COLOR_ARRAY_STRIDE);
- gpu_state_print_fl(GL_COLOR_ARRAY_TYPE);
- gpu_state_print_fl(GL_COLOR_CLEAR_VALUE);
- gpu_state_print_fl(GL_COLOR_LOGIC_OP);
- gpu_state_print_fl(GL_COLOR_MATERIAL);
- gpu_state_print_fl(GL_COLOR_MATERIAL_FACE);
- gpu_state_print_fl(GL_COLOR_MATERIAL_PARAMETER);
- gpu_state_print_fl(GL_COLOR_MATRIX);
- gpu_state_print_fl(GL_COLOR_MATRIX_STACK_DEPTH);
- gpu_state_print_fl(GL_COLOR_SUM);
- gpu_state_print_fl(GL_COLOR_TABLE);
- gpu_state_print_fl(GL_COLOR_WRITEMASK);
- gpu_state_print_fl(GL_COMPRESSED_TEXTURE_FORMATS);
- gpu_state_print_fl(GL_CONVOLUTION_1D);
- gpu_state_print_fl(GL_CONVOLUTION_2D);
- gpu_state_print_fl(GL_CULL_FACE);
- gpu_state_print_fl(GL_CULL_FACE_MODE);
- gpu_state_print_fl(GL_CURRENT_COLOR);
- gpu_state_print_fl(GL_CURRENT_FOG_COORD);
- gpu_state_print_fl(GL_CURRENT_INDEX);
- gpu_state_print_fl(GL_CURRENT_NORMAL);
- gpu_state_print_fl(GL_CURRENT_PROGRAM);
- gpu_state_print_fl(GL_CURRENT_RASTER_COLOR);
- gpu_state_print_fl(GL_CURRENT_RASTER_DISTANCE);
- gpu_state_print_fl(GL_CURRENT_RASTER_INDEX);
- gpu_state_print_fl(GL_CURRENT_RASTER_POSITION);
- gpu_state_print_fl(GL_CURRENT_RASTER_POSITION_VALID);
- gpu_state_print_fl(GL_CURRENT_RASTER_SECONDARY_COLOR);
- gpu_state_print_fl(GL_CURRENT_RASTER_TEXTURE_COORDS);
- gpu_state_print_fl(GL_CURRENT_SECONDARY_COLOR);
- gpu_state_print_fl(GL_CURRENT_TEXTURE_COORDS);
- gpu_state_print_fl(GL_DEPTH_BIAS);
- gpu_state_print_fl(GL_DEPTH_BITS);
- gpu_state_print_fl(GL_DEPTH_CLEAR_VALUE);
- gpu_state_print_fl(GL_DEPTH_FUNC);
- gpu_state_print_fl(GL_DEPTH_RANGE);
- gpu_state_print_fl(GL_DEPTH_SCALE);
- gpu_state_print_fl(GL_DEPTH_TEST);
- gpu_state_print_fl(GL_DEPTH_WRITEMASK);
- gpu_state_print_fl(GL_DITHER);
- gpu_state_print_fl(GL_DOUBLEBUFFER);
- gpu_state_print_fl(GL_DRAW_BUFFER);
- gpu_state_print_fl(GL_DRAW_BUFFER0);
- gpu_state_print_fl(GL_EDGE_FLAG);
- gpu_state_print_fl(GL_EDGE_FLAG_ARRAY);
- gpu_state_print_fl(GL_EDGE_FLAG_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_EDGE_FLAG_ARRAY_STRIDE);
- gpu_state_print_fl(GL_ELEMENT_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_FEEDBACK_BUFFER_SIZE);
- gpu_state_print_fl(GL_FEEDBACK_BUFFER_TYPE);
- gpu_state_print_fl(GL_FOG);
- gpu_state_print_fl(GL_FOG_COLOR);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY_STRIDE);
- gpu_state_print_fl(GL_FOG_COORD_ARRAY_TYPE);
- gpu_state_print_fl(GL_FOG_COORD_SRC);
- gpu_state_print_fl(GL_FOG_DENSITY);
- gpu_state_print_fl(GL_FOG_END);
- gpu_state_print_fl(GL_FOG_HINT);
- gpu_state_print_fl(GL_FOG_INDEX);
- gpu_state_print_fl(GL_FOG_MODE);
- gpu_state_print_fl(GL_FOG_START);
- gpu_state_print_fl(GL_FRAGMENT_PROGRAM_ARB);
- gpu_state_print_fl(GL_FRAGMENT_SHADER_DERIVATIVE_HINT);
- gpu_state_print_fl(GL_FRONT_FACE);
- gpu_state_print_fl(GL_GENERATE_MIPMAP_HINT);
- gpu_state_print_fl(GL_GREEN_BIAS);
- gpu_state_print_fl(GL_GREEN_BITS);
- gpu_state_print_fl(GL_GREEN_SCALE);
- gpu_state_print_fl(GL_HISTOGRAM);
- gpu_state_print_fl(GL_INDEX_ARRAY);
- gpu_state_print_fl(GL_INDEX_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_INDEX_ARRAY_STRIDE);
- gpu_state_print_fl(GL_INDEX_ARRAY_TYPE);
- gpu_state_print_fl(GL_INDEX_BITS);
- gpu_state_print_fl(GL_INDEX_CLEAR_VALUE);
- gpu_state_print_fl(GL_INDEX_LOGIC_OP);
- gpu_state_print_fl(GL_INDEX_MODE);
- gpu_state_print_fl(GL_INDEX_OFFSET);
- gpu_state_print_fl(GL_INDEX_SHIFT);
- gpu_state_print_fl(GL_INDEX_WRITEMASK);
- gpu_state_print_fl(GL_LIGHT0);
- gpu_state_print_fl(GL_LIGHT1);
- gpu_state_print_fl(GL_LIGHT2);
- gpu_state_print_fl(GL_LIGHT3);
- gpu_state_print_fl(GL_LIGHT4);
- gpu_state_print_fl(GL_LIGHT5);
- gpu_state_print_fl(GL_LIGHT6);
- gpu_state_print_fl(GL_LIGHT7);
- gpu_state_print_fl(GL_LIGHTING);
- gpu_state_print_fl(GL_LIGHT_MODEL_AMBIENT);
- gpu_state_print_fl(GL_LIGHT_MODEL_COLOR_CONTROL);
- gpu_state_print_fl(GL_LIGHT_MODEL_LOCAL_VIEWER);
- gpu_state_print_fl(GL_LIGHT_MODEL_TWO_SIDE);
- gpu_state_print_fl(GL_LINE_SMOOTH);
- gpu_state_print_fl(GL_LINE_SMOOTH_HINT);
- gpu_state_print_fl(GL_LINE_STIPPLE);
- gpu_state_print_fl(GL_LINE_STIPPLE_PATTERN);
- gpu_state_print_fl(GL_LINE_STIPPLE_REPEAT);
- gpu_state_print_fl(GL_LINE_WIDTH);
- gpu_state_print_fl(GL_LINE_WIDTH_GRANULARITY);
- gpu_state_print_fl(GL_LINE_WIDTH_RANGE);
- gpu_state_print_fl(GL_LIST_BASE);
- gpu_state_print_fl(GL_LIST_INDEX);
- gpu_state_print_fl(GL_LIST_MODE);
- gpu_state_print_fl(GL_LOGIC_OP);
- gpu_state_print_fl(GL_LOGIC_OP_MODE);
- gpu_state_print_fl(GL_MAP1_COLOR_4);
- gpu_state_print_fl(GL_MAP1_GRID_DOMAIN);
- gpu_state_print_fl(GL_MAP1_GRID_SEGMENTS);
- gpu_state_print_fl(GL_MAP1_INDEX);
- gpu_state_print_fl(GL_MAP1_NORMAL);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_1);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_2);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_3);
- gpu_state_print_fl(GL_MAP1_TEXTURE_COORD_4);
- gpu_state_print_fl(GL_MAP1_VERTEX_3);
- gpu_state_print_fl(GL_MAP1_VERTEX_4);
- gpu_state_print_fl(GL_MAP2_COLOR_4);
- gpu_state_print_fl(GL_MAP2_GRID_DOMAIN);
- gpu_state_print_fl(GL_MAP2_GRID_SEGMENTS);
- gpu_state_print_fl(GL_MAP2_INDEX);
- gpu_state_print_fl(GL_MAP2_NORMAL);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_1);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_2);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_3);
- gpu_state_print_fl(GL_MAP2_TEXTURE_COORD_4);
- gpu_state_print_fl(GL_MAP2_VERTEX_3);
- gpu_state_print_fl(GL_MAP2_VERTEX_4);
- gpu_state_print_fl(GL_MAP_COLOR);
- gpu_state_print_fl(GL_MAP_STENCIL);
- gpu_state_print_fl(GL_MATRIX_MODE);
- gpu_state_print_fl(GL_MAX_3D_TEXTURE_SIZE);
- gpu_state_print_fl(GL_MAX_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_CLIENT_ATTRIB_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_CLIP_PLANES);
- gpu_state_print_fl(GL_MAX_COLOR_MATRIX_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
- gpu_state_print_fl(GL_MAX_CUBE_MAP_TEXTURE_SIZE);
- gpu_state_print_fl(GL_MAX_DRAW_BUFFERS);
- gpu_state_print_fl(GL_MAX_ELEMENTS_INDICES);
- gpu_state_print_fl(GL_MAX_ELEMENTS_VERTICES);
- gpu_state_print_fl(GL_MAX_EVAL_ORDER);
- gpu_state_print_fl(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
- gpu_state_print_fl(GL_MAX_LIGHTS);
- gpu_state_print_fl(GL_MAX_LIST_NESTING);
- gpu_state_print_fl(GL_MAX_MODELVIEW_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_NAME_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_PIXEL_MAP_TABLE);
- gpu_state_print_fl(GL_MAX_PROJECTION_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_TEXTURE_COORDS);
- gpu_state_print_fl(GL_MAX_TEXTURE_IMAGE_UNITS);
- gpu_state_print_fl(GL_MAX_TEXTURE_LOD_BIAS);
- gpu_state_print_fl(GL_MAX_TEXTURE_SIZE);
- gpu_state_print_fl(GL_MAX_TEXTURE_STACK_DEPTH);
- gpu_state_print_fl(GL_MAX_TEXTURE_UNITS);
- gpu_state_print_fl(GL_MAX_VARYING_FLOATS);
- gpu_state_print_fl(GL_MAX_VERTEX_ATTRIBS);
- gpu_state_print_fl(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
- gpu_state_print_fl(GL_MAX_VERTEX_UNIFORM_COMPONENTS);
- gpu_state_print_fl(GL_MAX_VIEWPORT_DIMS);
- gpu_state_print_fl(GL_MINMAX);
- gpu_state_print_fl(GL_MODELVIEW_MATRIX);
- gpu_state_print_fl(GL_MODELVIEW_STACK_DEPTH);
- gpu_state_print_fl(GL_MULTISAMPLE);
- gpu_state_print_fl(GL_MULTISAMPLE_ARB);
- gpu_state_print_fl(GL_NAME_STACK_DEPTH);
- gpu_state_print_fl(GL_NORMALIZE);
- gpu_state_print_fl(GL_NORMAL_ARRAY);
- gpu_state_print_fl(GL_NORMAL_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_NORMAL_ARRAY_STRIDE);
- gpu_state_print_fl(GL_NORMAL_ARRAY_TYPE);
- gpu_state_print_fl(GL_NUM_COMPRESSED_TEXTURE_FORMATS);
- gpu_state_print_fl(GL_PACK_ALIGNMENT);
- gpu_state_print_fl(GL_PACK_IMAGE_HEIGHT);
- gpu_state_print_fl(GL_PACK_LSB_FIRST);
- gpu_state_print_fl(GL_PACK_ROW_LENGTH);
- gpu_state_print_fl(GL_PACK_SKIP_IMAGES);
- gpu_state_print_fl(GL_PACK_SKIP_PIXELS);
- gpu_state_print_fl(GL_PACK_SKIP_ROWS);
- gpu_state_print_fl(GL_PACK_SWAP_BYTES);
- gpu_state_print_fl(GL_PERSPECTIVE_CORRECTION_HINT);
- gpu_state_print_fl(GL_PIXEL_MAP_A_TO_A_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_B_TO_B_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_G_TO_G_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_A_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_B_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_G_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_I_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_I_TO_R_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_R_TO_R_SIZE);
- gpu_state_print_fl(GL_PIXEL_MAP_S_TO_S_SIZE);
- gpu_state_print_fl(GL_PIXEL_PACK_BUFFER_BINDING);
- gpu_state_print_fl(GL_PIXEL_UNPACK_BUFFER_BINDING);
- gpu_state_print_fl(GL_POINT_DISTANCE_ATTENUATION);
- gpu_state_print_fl(GL_POINT_FADE_THRESHOLD_SIZE);
- gpu_state_print_fl(GL_POINT_SIZE);
- gpu_state_print_fl(GL_POINT_SIZE_GRANULARITY);
- gpu_state_print_fl(GL_POINT_SIZE_MAX);
- gpu_state_print_fl(GL_POINT_SIZE_MIN);
- gpu_state_print_fl(GL_POINT_SIZE_RANGE);
- gpu_state_print_fl(GL_POINT_SMOOTH);
- gpu_state_print_fl(GL_POINT_SMOOTH_HINT);
- gpu_state_print_fl(GL_POINT_SPRITE);
- gpu_state_print_fl(GL_POLYGON_MODE);
- gpu_state_print_fl(GL_POLYGON_OFFSET_FACTOR);
- gpu_state_print_fl(GL_POLYGON_OFFSET_FILL);
- gpu_state_print_fl(GL_POLYGON_OFFSET_LINE);
- gpu_state_print_fl(GL_POLYGON_OFFSET_POINT);
- gpu_state_print_fl(GL_POLYGON_OFFSET_UNITS);
- gpu_state_print_fl(GL_POLYGON_SMOOTH);
- gpu_state_print_fl(GL_POLYGON_SMOOTH_HINT);
- gpu_state_print_fl(GL_POLYGON_STIPPLE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_ALPHA_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_ALPHA_SCALE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_BLUE_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_BLUE_SCALE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_COLOR_TABLE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_GREEN_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_GREEN_SCALE);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_RED_BIAS);
- gpu_state_print_fl(GL_POST_COLOR_MATRIX_RED_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_ALPHA_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_ALPHA_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_BLUE_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_BLUE_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_COLOR_TABLE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_GREEN_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_GREEN_SCALE);
- gpu_state_print_fl(GL_POST_CONVOLUTION_RED_BIAS);
- gpu_state_print_fl(GL_POST_CONVOLUTION_RED_SCALE);
- gpu_state_print_fl(GL_PROJECTION_MATRIX);
- gpu_state_print_fl(GL_PROJECTION_STACK_DEPTH);
- gpu_state_print_fl(GL_READ_BUFFER);
- gpu_state_print_fl(GL_RED_BIAS);
- gpu_state_print_fl(GL_RED_BITS);
- gpu_state_print_fl(GL_RED_SCALE);
- gpu_state_print_fl(GL_RENDER_MODE);
- gpu_state_print_fl(GL_RESCALE_NORMAL);
- gpu_state_print_fl(GL_RGBA_MODE);
- gpu_state_print_fl(GL_SAMPLES);
- gpu_state_print_fl(GL_SAMPLE_BUFFERS);
- gpu_state_print_fl(GL_SAMPLE_COVERAGE_INVERT);
- gpu_state_print_fl(GL_SAMPLE_COVERAGE_VALUE);
- gpu_state_print_fl(GL_SCISSOR_BOX);
- gpu_state_print_fl(GL_SCISSOR_TEST);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_SIZE);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_STRIDE);
- gpu_state_print_fl(GL_SECONDARY_COLOR_ARRAY_TYPE);
- gpu_state_print_fl(GL_SELECTION_BUFFER_SIZE);
- gpu_state_print_fl(GL_SEPARABLE_2D);
- gpu_state_print_fl(GL_SHADE_MODEL);
- gpu_state_print_fl(GL_SMOOTH_LINE_WIDTH_GRANULARITY);
- gpu_state_print_fl(GL_SMOOTH_LINE_WIDTH_RANGE);
- gpu_state_print_fl(GL_SMOOTH_POINT_SIZE_GRANULARITY);
- gpu_state_print_fl(GL_SMOOTH_POINT_SIZE_RANGE);
- gpu_state_print_fl(GL_STENCIL_BACK_FAIL);
- gpu_state_print_fl(GL_STENCIL_BACK_FUNC);
- gpu_state_print_fl(GL_STENCIL_BACK_PASS_DEPTH_FAIL);
- gpu_state_print_fl(GL_STENCIL_BACK_PASS_DEPTH_PASS);
- gpu_state_print_fl(GL_STENCIL_BACK_REF);
- gpu_state_print_fl(GL_STENCIL_BACK_VALUE_MASK);
- gpu_state_print_fl(GL_STENCIL_BACK_WRITEMASK);
- gpu_state_print_fl(GL_STENCIL_BITS);
- gpu_state_print_fl(GL_STENCIL_CLEAR_VALUE);
- gpu_state_print_fl(GL_STENCIL_FAIL);
- gpu_state_print_fl(GL_STENCIL_FUNC);
- gpu_state_print_fl(GL_STENCIL_PASS_DEPTH_FAIL);
- gpu_state_print_fl(GL_STENCIL_PASS_DEPTH_PASS);
- gpu_state_print_fl(GL_STENCIL_REF);
- gpu_state_print_fl(GL_STENCIL_TEST);
- gpu_state_print_fl(GL_STENCIL_VALUE_MASK);
- gpu_state_print_fl(GL_STENCIL_WRITEMASK);
- gpu_state_print_fl(GL_STEREO);
- gpu_state_print_fl(GL_SUBPIXEL_BITS);
- gpu_state_print_fl(GL_TEXTURE_1D);
- gpu_state_print_fl(GL_TEXTURE_2D);
- gpu_state_print_fl(GL_TEXTURE_3D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_1D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_2D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_3D);
- gpu_state_print_fl(GL_TEXTURE_BINDING_CUBE_MAP);
- gpu_state_print_fl(GL_TEXTURE_COMPRESSION_HINT);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_SIZE);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_STRIDE);
- gpu_state_print_fl(GL_TEXTURE_COORD_ARRAY_TYPE);
- gpu_state_print_fl(GL_TEXTURE_CUBE_MAP);
- gpu_state_print_fl(GL_TEXTURE_CUBE_MAP_ARB);
- gpu_state_print_fl(GL_TEXTURE_GEN_Q);
- gpu_state_print_fl(GL_TEXTURE_GEN_R);
- gpu_state_print_fl(GL_TEXTURE_GEN_S);
- gpu_state_print_fl(GL_TEXTURE_GEN_T);
- gpu_state_print_fl(GL_TEXTURE_MATRIX);
- gpu_state_print_fl(GL_TEXTURE_STACK_DEPTH);
- gpu_state_print_fl(GL_TRANSPOSE_COLOR_MATRIX);
- gpu_state_print_fl(GL_TRANSPOSE_MODELVIEW_MATRIX);
- gpu_state_print_fl(GL_TRANSPOSE_PROJECTION_MATRIX);
- gpu_state_print_fl(GL_TRANSPOSE_TEXTURE_MATRIX);
- gpu_state_print_fl(GL_UNPACK_ALIGNMENT);
- gpu_state_print_fl(GL_UNPACK_IMAGE_HEIGHT);
- gpu_state_print_fl(GL_UNPACK_LSB_FIRST);
- gpu_state_print_fl(GL_UNPACK_ROW_LENGTH);
- gpu_state_print_fl(GL_UNPACK_SKIP_IMAGES);
- gpu_state_print_fl(GL_UNPACK_SKIP_PIXELS);
- gpu_state_print_fl(GL_UNPACK_SKIP_ROWS);
- gpu_state_print_fl(GL_UNPACK_SWAP_BYTES);
- gpu_state_print_fl(GL_VERTEX_ARRAY);
- gpu_state_print_fl(GL_VERTEX_ARRAY_BUFFER_BINDING);
- gpu_state_print_fl(GL_VERTEX_ARRAY_SIZE);
- gpu_state_print_fl(GL_VERTEX_ARRAY_STRIDE);
- gpu_state_print_fl(GL_VERTEX_ARRAY_TYPE);
- gpu_state_print_fl(GL_VERTEX_PROGRAM_POINT_SIZE);
- gpu_state_print_fl(GL_VERTEX_PROGRAM_TWO_SIDE);
- gpu_state_print_fl(GL_VIEWPORT);
- gpu_state_print_fl(GL_ZOOM_X);
- gpu_state_print_fl(GL_ZOOM_Y);
-}
-
-#undef gpu_state_print_fl
-
-#endif
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 04f8e68431a..63f0bc37acf 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -33,8 +33,6 @@
*/
-#include "GPU_glew.h"
-
#include "DNA_image_types.h"
#include "MEM_guardedalloc.h"
@@ -45,12 +43,14 @@
#include "BKE_global.h"
+#include "GPU_glew.h"
+#include "GPU_debug.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
+#include "GPU_compositing.h"
#include "GPU_simple_shader.h"
-#include "intern/gpu_codegen.h"
-#include "intern/gpu_extensions_private.h"
+#include "intern/gpu_private.h"
#include <stdlib.h>
#include <stdio.h>
@@ -79,10 +79,18 @@ extern char datatoc_gpu_shader_vsm_store_vert_glsl[];
extern char datatoc_gpu_shader_vsm_store_frag_glsl[];
extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[];
extern char datatoc_gpu_shader_sep_gaussian_blur_frag_glsl[];
+extern char datatoc_gpu_shader_fx_vert_glsl[];
+extern char datatoc_gpu_shader_fx_ssao_frag_glsl[];
+extern char datatoc_gpu_shader_fx_dof_frag_glsl[];
+extern char datatoc_gpu_shader_fx_dof_vert_glsl[];
+extern char datatoc_gpu_shader_fx_depth_resolve_glsl[];
+extern char datatoc_gpu_shader_fx_lib_glsl[];
typedef struct GPUShaders {
GPUShader *vsm_store;
GPUShader *sep_gaussian_blur;
+ /* cache for shader fx. Those can exist in combinations so store them here */
+ GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
} GPUShaders;
static struct GPUGlobal {
@@ -103,6 +111,16 @@ static struct GPUGlobal {
GPUTexture *invalid_tex_3D;
} GG = {1, 0};
+/* Number of maximum output slots. We support 4 outputs for now (usually we wouldn't need more to preserve fill rate) */
+#define GPU_FB_MAX_SLOTS 4
+
+struct GPUFrameBuffer {
+ GLuint object;
+ GPUTexture *colortex[GPU_FB_MAX_SLOTS];
+ GPUTexture *depthtex;
+};
+
+
/* GPU Types */
int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver)
@@ -245,6 +263,11 @@ int GPU_non_power_of_two_support(void)
return GLEW_ARB_texture_non_power_of_two;
}
+int GPU_vertex_buffer_support(void)
+{
+ return GLEW_ARB_vertex_buffer_object || GLEW_VERSION_1_5;
+}
+
int GPU_display_list_support(void)
{
return !GG.dlistsdisabled;
@@ -255,20 +278,6 @@ int GPU_color_depth(void)
return GG.colordepth;
}
-int GPU_print_error(const char *str)
-{
- GLenum errCode;
-
- if (G.debug & G_DEBUG) {
- if ((errCode = glGetError()) != GL_NO_ERROR) {
- fprintf(stderr, "%s opengl error: %s\n", str, gluErrorString(errCode));
- return 1;
- }
- }
-
- return 0;
-}
-
static void GPU_print_framebuffer_error(GLenum status, char err_out[256])
{
const char *err= "unknown";
@@ -323,6 +332,7 @@ struct GPUTexture {
int fromblender; /* we got the texture from Blender */
GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
+ int fb_attachment; /* slot the texture is attached to */
int depth; /* is a depth texture? */
};
@@ -354,7 +364,9 @@ static void GPU_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, i
MEM_freeN(pixels);
}
-static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, int depth, char err_out[256])
+static GPUTexture *GPU_texture_create_nD(
+ int w, int h, int n, float *fpixels, int depth, GPUHDRType hdr_type, int components,
+ char err_out[256])
{
GPUTexture *tex;
GLenum type, format, internalformat;
@@ -370,6 +382,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in
tex->refcount = 1;
tex->target = (n == 1)? GL_TEXTURE_1D: GL_TEXTURE_2D;
tex->depth = depth;
+ tex->fb_attachment = -1;
glGenTextures(1, &tex->bindcode);
@@ -400,12 +413,45 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in
internalformat = GL_DEPTH_COMPONENT;
}
else {
- type = GL_UNSIGNED_BYTE;
- format = GL_RGBA;
- internalformat = GL_RGBA8;
+ type = GL_FLOAT;
+
+ if (components == 4) {
+ format = GL_RGBA;
+ switch (hdr_type) {
+ case GPU_HDR_NONE:
+ internalformat = GL_RGBA8;
+ break;
+ case GPU_HDR_HALF_FLOAT:
+ internalformat = GL_RGBA16F;
+ break;
+ case GPU_HDR_FULL_FLOAT:
+ internalformat = GL_RGBA32F;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (components == 2) {
+ format = GL_RG;
+ switch (hdr_type) {
+ case GPU_HDR_NONE:
+ internalformat = GL_RG8;
+ break;
+ case GPU_HDR_HALF_FLOAT:
+ internalformat = GL_RG16F;
+ break;
+ case GPU_HDR_FULL_FLOAT:
+ internalformat = GL_RG32F;
+ break;
+ default:
+ break;
+ }
+ }
- if (fpixels)
+ if (fpixels && hdr_type == GPU_HDR_NONE) {
+ type = GL_UNSIGNED_BYTE;
pixels = GPU_texture_convert_pixels(w*h, fpixels);
+ }
}
if (tex->target == GL_TEXTURE_1D) {
@@ -451,15 +497,8 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in
}
if (tex->target != GL_TEXTURE_1D) {
- /* CLAMP_TO_BORDER is an OpenGL 1.3 core feature */
- GLenum wrapmode = (depth || tex->h == 1)? GL_CLAMP_TO_EDGE: GL_CLAMP_TO_BORDER;
- glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, wrapmode);
- glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, wrapmode);
-
-#if 0
- float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
- glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
-#endif
+ glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
else
glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -504,7 +543,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *
tex->number = 0;
glBindTexture(tex->target, tex->bindcode);
- GPU_print_error("3D glBindTexture");
+ GPU_ASSERT_NO_GL_ERRORS("3D glBindTexture");
type = GL_FLOAT;
if (channels == 4) {
@@ -521,7 +560,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->depth, 0, format, type, NULL);
- GPU_print_error("3D glTexImage3D");
+ GPU_ASSERT_NO_GL_ERRORS("3D glTexImage3D");
if (fpixels) {
if (!GPU_non_power_of_two_support() && (w != tex->w || h != tex->h || depth != tex->depth)) {
@@ -532,19 +571,19 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *
}
glTexSubImage3D(tex->target, 0, 0, 0, 0, w, h, depth, format, type, fpixels);
- GPU_print_error("3D glTexSubImage3D");
+ GPU_ASSERT_NO_GL_ERRORS("3D glTexSubImage3D");
}
glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, vfBorderColor);
- GPU_print_error("3D GL_TEXTURE_BORDER_COLOR");
+ GPU_ASSERT_NO_GL_ERRORS("3D GL_TEXTURE_BORDER_COLOR");
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- GPU_print_error("3D GL_LINEAR");
+ GPU_ASSERT_NO_GL_ERRORS("3D GL_LINEAR");
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- GPU_print_error("3D GL_CLAMP_TO_BORDER");
+ GPU_ASSERT_NO_GL_ERRORS("3D GL_CLAMP_TO_BORDER");
if (pixels)
MEM_freeN(pixels);
@@ -581,7 +620,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, bool is_data,
ima->gputexture= tex;
if (!glIsTexture(tex->bindcode)) {
- GPU_print_error("Blender Texture Not Loaded");
+ GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
}
else {
glBindTexture(GL_TEXTURE_2D, tex->bindcode);
@@ -628,7 +667,7 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
prv->gputexture[0]= tex;
if (!glIsTexture(tex->bindcode)) {
- GPU_print_error("Blender Texture Not Loaded");
+ GPU_ASSERT_NO_GL_ERRORS("Blender Texture Not Loaded");
}
else {
glBindTexture(GL_TEXTURE_2D, tex->bindcode);
@@ -647,7 +686,7 @@ GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
GPUTexture *GPU_texture_create_1D(int w, float *fpixels, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0, err_out);
+ GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0, GPU_HDR_NONE, 4, err_out);
if (tex)
GPU_texture_unbind(tex);
@@ -655,9 +694,9 @@ GPUTexture *GPU_texture_create_1D(int w, float *fpixels, char err_out[256])
return tex;
}
-GPUTexture *GPU_texture_create_2D(int w, int h, float *fpixels, char err_out[256])
+GPUTexture *GPU_texture_create_2D(int w, int h, float *fpixels, GPUHDRType hdr, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0, err_out);
+ GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0, hdr, 4, err_out);
if (tex)
GPU_texture_unbind(tex);
@@ -667,7 +706,7 @@ GPUTexture *GPU_texture_create_2D(int w, int h, float *fpixels, char err_out[256
GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1, err_out);
+ GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1, GPU_HDR_NONE, 1, err_out);
if (tex)
GPU_texture_unbind(tex);
@@ -680,13 +719,45 @@ GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
*/
GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(size, size, 2, NULL, 0, err_out);
+ GPUTexture *tex = GPU_texture_create_nD(size, size, 2, NULL, 0, GPU_HDR_FULL_FLOAT, 2, err_out);
if (tex) {
/* Now we tweak some of the settings */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, size, size, 0, GL_RG, GL_FLOAT, NULL);
+
+ GPU_texture_unbind(tex);
+ }
+
+ return tex;
+}
+
+GPUTexture *GPU_texture_create_2D_procedural(int w, int h, float *pixels, char err_out[256])
+{
+ GPUTexture *tex = GPU_texture_create_nD(w, h, 2, pixels, 0, GPU_HDR_HALF_FLOAT, 2, err_out);
+
+ if (tex) {
+ /* Now we tweak some of the settings */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ GPU_texture_unbind(tex);
+ }
+
+ return tex;
+}
+
+GPUTexture *GPU_texture_create_1D_procedural(int w, float *pixels, char err_out[256])
+{
+ GPUTexture *tex = GPU_texture_create_nD(w, 0, 1, pixels, 0, GPU_HDR_HALF_FLOAT, 2, err_out);
+
+ if (tex) {
+ /* Now we tweak some of the settings */
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
GPU_texture_unbind(tex);
}
@@ -698,7 +769,7 @@ void GPU_invalid_tex_init(void)
{
float color[4] = {1.0f, 0.0f, 1.0f, 1.0};
GG.invalid_tex_1D = GPU_texture_create_1D(1, color, NULL);
- GG.invalid_tex_2D = GPU_texture_create_2D(1, 1, color, NULL);
+ GG.invalid_tex_2D = GPU_texture_create_2D(1, 1, color, GPU_HDR_NONE, NULL);
GG.invalid_tex_3D = GPU_texture_create_3D(1, 1, 1, 4, color);
}
@@ -733,14 +804,20 @@ void GPU_texture_bind(GPUTexture *tex, int number)
GLenum arbnumber;
if (number >= GG.maxtextures) {
- GPU_print_error("Not enough texture slots.");
+ fprintf(stderr, "Not enough texture slots.");
return;
}
- if (number == -1)
+ if ((G.debug & G_DEBUG)) {
+ if (tex->fb && tex->fb->object == GG.currentfb) {
+ fprintf(stderr, "Feedback loop warning!: Attempting to bind texture attached to current framebuffer!\n");
+ }
+ }
+
+ if (number < 0)
return;
- GPU_print_error("Pre Texture Bind");
+ GPU_ASSERT_NO_GL_ERRORS("Pre Texture Bind");
arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + number);
if (number != 0) glActiveTextureARB(arbnumber);
@@ -754,7 +831,7 @@ void GPU_texture_bind(GPUTexture *tex, int number)
tex->number = number;
- GPU_print_error("Post Texture Bind");
+ GPU_ASSERT_NO_GL_ERRORS("Post Texture Bind");
}
void GPU_texture_unbind(GPUTexture *tex)
@@ -762,14 +839,14 @@ void GPU_texture_unbind(GPUTexture *tex)
GLenum arbnumber;
if (tex->number >= GG.maxtextures) {
- GPU_print_error("Not enough texture slots.");
+ fprintf(stderr, "Not enough texture slots.");
return;
}
if (tex->number == -1)
return;
- GPU_print_error("Pre Texture Unbind");
+ GPU_ASSERT_NO_GL_ERRORS("Pre Texture Unbind");
arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
if (tex->number != 0) glActiveTextureARB(arbnumber);
@@ -779,7 +856,46 @@ void GPU_texture_unbind(GPUTexture *tex)
tex->number = -1;
- GPU_print_error("Post Texture Unbind");
+ GPU_ASSERT_NO_GL_ERRORS("Post Texture Unbind");
+}
+
+void GPU_depth_texture_mode(GPUTexture *tex, bool compare, bool use_filter)
+{
+ GLenum arbnumber;
+
+ if (tex->number >= GG.maxtextures) {
+ fprintf(stderr, "Not enough texture slots.");
+ return;
+ }
+
+ if (!tex->depth) {
+ fprintf(stderr, "Not a depth texture.");
+ return;
+ }
+
+ if (tex->number == -1)
+ return;
+
+ GPU_ASSERT_NO_GL_ERRORS("Pre Texture Unbind");
+
+ arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
+ if (tex->number != 0) glActiveTextureARB(arbnumber);
+ if (compare)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ else
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
+
+ if (use_filter) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
+ else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+ if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
+
+ GPU_ASSERT_NO_GL_ERRORS("Post Texture Unbind");
}
void GPU_texture_free(GPUTexture *tex)
@@ -791,7 +907,7 @@ void GPU_texture_free(GPUTexture *tex)
if (tex->refcount == 0) {
if (tex->fb)
- GPU_framebuffer_texture_detach(tex->fb, tex);
+ GPU_framebuffer_texture_detach(tex);
if (tex->bindcode && !tex->fromblender)
glDeleteTextures(1, &tex->bindcode);
@@ -831,12 +947,6 @@ GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex)
/* GPUFrameBuffer */
-struct GPUFrameBuffer {
- GLuint object;
- GPUTexture *colortex;
- GPUTexture *depthtex;
-};
-
GPUFrameBuffer *GPU_framebuffer_create(void)
{
GPUFrameBuffer *fb;
@@ -854,19 +964,35 @@ GPUFrameBuffer *GPU_framebuffer_create(void)
return NULL;
}
+ /* make sure no read buffer is enabled, so completeness check will not fail. We set those at binding time */
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ glReadBuffer(GL_NONE);
+ glDrawBuffer(GL_NONE);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
return fb;
}
-int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err_out[256])
+int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, char err_out[256])
{
- GLenum status;
GLenum attachment;
GLenum error;
+ if (slot >= GPU_FB_MAX_SLOTS) {
+ fprintf(stderr, "Attaching to index %d framebuffer slot unsupported in blender use at most %d\n", slot, GPU_FB_MAX_SLOTS);
+ return 0;
+ }
+
+ if ((G.debug & G_DEBUG)) {
+ if (tex->number != -1) {
+ fprintf(stderr, "Feedback loop warning!: Attempting to attach texture to framebuffer while still bound to texture unit for drawing!");
+ }
+ }
+
if (tex->depth)
attachment = GL_DEPTH_ATTACHMENT_EXT;
else
- attachment = GL_COLOR_ATTACHMENT0_EXT;
+ attachment = GL_COLOR_ATTACHMENT0_EXT + slot;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
GG.currentfb = fb->object;
@@ -885,42 +1011,29 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err
return 0;
}
- if (tex->depth) {
- glDrawBuffer(GL_NONE);
- glReadBuffer(GL_NONE);
- }
- else {
- glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
- glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
- }
-
- status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
-
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- GPU_framebuffer_restore();
- GPU_print_framebuffer_error(status, err_out);
- return 0;
- }
-
if (tex->depth)
fb->depthtex = tex;
else
- fb->colortex = tex;
+ fb->colortex[slot] = tex;
tex->fb= fb;
+ tex->fb_attachment = slot;
return 1;
}
-void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
+void GPU_framebuffer_texture_detach(GPUTexture *tex)
{
GLenum attachment;
+ GPUFrameBuffer *fb;
if (!tex->fb)
return;
- if (GG.currentfb != tex->fb->object) {
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
+ fb = tex->fb;
+
+ if (GG.currentfb != fb->object) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
GG.currentfb = tex->fb->object;
}
@@ -929,18 +1042,25 @@ void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
attachment = GL_DEPTH_ATTACHMENT_EXT;
}
else {
- fb->colortex = NULL;
- attachment = GL_COLOR_ATTACHMENT0_EXT;
+ BLI_assert(fb->colortex[tex->fb_attachment] == tex);
+ fb->colortex[tex->fb_attachment] = NULL;
+ attachment = GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment;
}
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
tex->target, 0, 0);
tex->fb = NULL;
+ tex->fb_attachment = -1;
}
-void GPU_framebuffer_texture_bind(GPUFrameBuffer *UNUSED(fb), GPUTexture *tex, int w, int h)
+void GPU_texture_bind_as_framebuffer(GPUTexture *tex)
{
+ if (!tex->fb) {
+ fprintf(stderr, "Error, texture not bound to framebuffer!");
+ return;
+ }
+
/* push attributes */
glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT);
glDisable(GL_SCISSOR_TEST);
@@ -948,8 +1068,18 @@ void GPU_framebuffer_texture_bind(GPUFrameBuffer *UNUSED(fb), GPUTexture *tex, i
/* bind framebuffer */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tex->fb->object);
+ if (tex->depth) {
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+ }
+ else {
+ /* last bound prevails here, better allow explicit control here too */
+ glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment);
+ glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + tex->fb_attachment);
+ }
+
/* push matrices and set default viewport and matrix */
- glViewport(0, 0, w, h);
+ glViewport(0, 0, tex->w, tex->h);
GG.currentfb = tex->fb->object;
glMatrixMode(GL_PROJECTION);
@@ -958,6 +1088,45 @@ void GPU_framebuffer_texture_bind(GPUFrameBuffer *UNUSED(fb), GPUTexture *tex, i
glPushMatrix();
}
+void GPU_framebuffer_slots_bind(GPUFrameBuffer *fb, int slot)
+{
+ int numslots = 0, i;
+ GLenum attachments[4];
+
+ if (!fb->colortex[slot]) {
+ fprintf(stderr, "Error, framebuffer slot empty!");
+ return;
+ }
+
+ for (i = 0 ; i < 4; i++) {
+ if (fb->colortex[i]) {
+ attachments[numslots] = GL_COLOR_ATTACHMENT0_EXT + i;
+ numslots++;
+ }
+ }
+
+ /* push attributes */
+ glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT);
+ glDisable(GL_SCISSOR_TEST);
+
+ /* bind framebuffer */
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+
+ /* last bound prevails here, better allow explicit control here too */
+ glDrawBuffers(numslots, attachments);
+ glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
+
+ /* push matrices and set default viewport and matrix */
+ glViewport(0, 0, fb->colortex[slot]->w, fb->colortex[slot]->h);
+ GG.currentfb = fb->object;
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+}
+
+
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex))
{
/* restore matrix */
@@ -968,15 +1137,53 @@ void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUS
/* restore attributes */
glPopAttrib();
- glEnable(GL_SCISSOR_TEST);
+}
+
+void GPU_framebuffer_bind_no_save(GPUFrameBuffer *fb, int slot)
+{
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ /* last bound prevails here, better allow explicit control here too */
+ glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
+ glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + slot);
+
+ /* push matrices and set default viewport and matrix */
+ glViewport(0, 0, fb->colortex[slot]->w, fb->colortex[slot]->h);
+ GG.currentfb = fb->object;
+ GG.currentfb = fb->object;
+}
+
+bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
+{
+ GLenum status;
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ GG.currentfb = fb->object;
+
+ /* Clean glError buffer. */
+ while (glGetError() != GL_NO_ERROR) {}
+
+ status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ GPU_framebuffer_restore();
+ GPU_print_framebuffer_error(status, err_out);
+ return false;
+ }
+
+ return true;
}
void GPU_framebuffer_free(GPUFrameBuffer *fb)
{
+ int i;
if (fb->depthtex)
- GPU_framebuffer_texture_detach(fb, fb->depthtex);
- if (fb->colortex)
- GPU_framebuffer_texture_detach(fb, fb->colortex);
+ GPU_framebuffer_texture_detach(fb->depthtex);
+
+ for (i = 0; i < GPU_FB_MAX_SLOTS; i++) {
+ if (fb->colortex[i]) {
+ GPU_framebuffer_texture_detach(fb->colortex[i]);
+ }
+ }
if (fb->object) {
glDeleteFramebuffersEXT(1, &fb->object);
@@ -1000,8 +1207,8 @@ void GPU_framebuffer_restore(void)
void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *blurfb, GPUTexture *blurtex)
{
- float scaleh[2] = {1.0f/GPU_texture_opengl_width(blurtex), 0.0f};
- float scalev[2] = {0.0f, 1.0f/GPU_texture_opengl_height(tex)};
+ const float scaleh[2] = {1.0f / GPU_texture_opengl_width(blurtex), 0.0f};
+ const float scalev[2] = {0.0f, 1.0f / GPU_texture_opengl_height(tex)};
GPUShader *blur_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SEP_GAUSSIAN_BLUR);
int scale_uniform, texture_source_uniform;
@@ -1017,9 +1224,13 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b
/* We do the bind ourselves rather than using GPU_framebuffer_texture_bind() to avoid
* pushing unnecessary matrices onto the OpenGL stack. */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, blurfb->object);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0);
+
+ /* avoid warnings from texture binding */
+ GG.currentfb = blurfb->object;
GPU_shader_bind(blur_shader);
- GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float *)scaleh);
+ GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scaleh);
GPU_shader_uniform_texture(blur_shader, texture_source_uniform, tex);
glViewport(0, 0, GPU_texture_opengl_width(blurtex), GPU_texture_opengl_height(blurtex));
@@ -1042,12 +1253,16 @@ void GPU_framebuffer_blur(GPUFrameBuffer *fb, GPUTexture *tex, GPUFrameBuffer *b
glTexCoord2d(1, 1); glVertex2f(-1, -1);
glTexCoord2d(0, 1); glVertex2f(1, -1);
glEnd();
-
+
/* Blurring vertically */
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->object);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0);
+
+ GG.currentfb = fb->object;
+
glViewport(0, 0, GPU_texture_opengl_width(tex), GPU_texture_opengl_height(tex));
- GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, (float *)scalev);
+ GPU_shader_uniform_vector(blur_shader, scale_uniform, 2, 1, scalev);
GPU_shader_uniform_texture(blur_shader, texture_source_uniform, blurtex);
GPU_texture_bind(blurtex, 0);
@@ -1067,10 +1282,6 @@ struct GPUOffScreen {
GPUFrameBuffer *fb;
GPUTexture *color;
GPUTexture *depth;
-
- /* requested width/height, may be smaller than actual texture size due
- * to missing non-power of two support, so we compensate for that */
- int w, h;
};
GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256])
@@ -1078,8 +1289,6 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256])
GPUOffScreen *ofs;
ofs= MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen");
- ofs->w= width;
- ofs->h= height;
ofs->fb = GPU_framebuffer_create();
if (!ofs->fb) {
@@ -1093,21 +1302,27 @@ GPUOffScreen *GPU_offscreen_create(int width, int height, char err_out[256])
return NULL;
}
- if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, err_out)) {
+ if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, 0, err_out)) {
GPU_offscreen_free(ofs);
return NULL;
}
- ofs->color = GPU_texture_create_2D(width, height, NULL, err_out);
+ ofs->color = GPU_texture_create_2D(width, height, NULL, GPU_HDR_NONE, err_out);
if (!ofs->color) {
GPU_offscreen_free(ofs);
return NULL;
}
- if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, err_out)) {
+ if (!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, 0, err_out)) {
GPU_offscreen_free(ofs);
return NULL;
}
+
+ /* check validity at the very end! */
+ if (!GPU_framebuffer_check_valid(ofs->fb, err_out)) {
+ GPU_offscreen_free(ofs);
+ return NULL;
+ }
GPU_framebuffer_restore();
@@ -1126,32 +1341,37 @@ void GPU_offscreen_free(GPUOffScreen *ofs)
MEM_freeN(ofs);
}
-void GPU_offscreen_bind(GPUOffScreen *ofs)
+void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
{
glDisable(GL_SCISSOR_TEST);
- GPU_framebuffer_texture_bind(ofs->fb, ofs->color, ofs->w, ofs->h);
+ if (save)
+ GPU_texture_bind_as_framebuffer(ofs->color);
+ else {
+ GPU_framebuffer_bind_no_save(ofs->fb, 0);
+ }
}
-void GPU_offscreen_unbind(GPUOffScreen *ofs)
+void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore)
{
- GPU_framebuffer_texture_unbind(ofs->fb, ofs->color);
+ if (restore)
+ GPU_framebuffer_texture_unbind(ofs->fb, ofs->color);
GPU_framebuffer_restore();
glEnable(GL_SCISSOR_TEST);
}
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
{
- glReadPixels(0, 0, ofs->w, ofs->h, GL_RGBA, type, pixels);
+ glReadPixels(0, 0, ofs->color->w, ofs->color->h, GL_RGBA, type, pixels);
}
int GPU_offscreen_width(GPUOffScreen *ofs)
{
- return ofs->w;
+ return ofs->color->w;
}
int GPU_offscreen_height(GPUOffScreen *ofs)
{
- return ofs->h;
+ return ofs->color->h;
}
/* GPUShader */
@@ -1162,6 +1382,7 @@ struct GPUShader {
GLhandleARB fragment; /* handle for fragment shader */
GLhandleARB lib; /* handle for libment shader */
int totattrib; /* total number of attributes */
+ int uniforms; /* required uniforms */
};
static void shader_print_errors(const char *task, char *log, const char **code, int totcode)
@@ -1173,8 +1394,8 @@ static void shader_print_errors(const char *task, char *log, const char **code,
for (i = 0; i < totcode; i++) {
const char *c, *pos, *end = code[i] + strlen(code[i]);
int line = 1;
-
- if (G.debug & G_DEBUG) {
+
+ if ((G.debug & G_DEBUG)) {
fprintf(stderr, "===== shader string %d ====\n", i + 1);
c = code[i];
@@ -1376,16 +1597,16 @@ GPUShader *GPU_shader_create_lib(const char *code)
void GPU_shader_bind(GPUShader *shader)
{
- GPU_print_error("Pre Shader Bind");
+ GPU_ASSERT_NO_GL_ERRORS("Pre Shader Bind");
glUseProgramObjectARB(shader->object);
- GPU_print_error("Post Shader Bind");
+ GPU_ASSERT_NO_GL_ERRORS("Post Shader Bind");
}
void GPU_shader_unbind(void)
{
- GPU_print_error("Pre Shader Unbind");
+ GPU_ASSERT_NO_GL_ERRORS("Pre Shader Unbind");
glUseProgramObjectARB(0);
- GPU_print_error("Post Shader Unbind");
+ GPU_ASSERT_NO_GL_ERRORS("Post Shader Unbind");
}
void GPU_shader_free(GPUShader *shader)
@@ -1406,12 +1627,12 @@ int GPU_shader_get_uniform(GPUShader *shader, const char *name)
return glGetUniformLocationARB(shader->object, name);
}
-void GPU_shader_uniform_vector(GPUShader *UNUSED(shader), int location, int length, int arraysize, float *value)
+void GPU_shader_uniform_vector(GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value)
{
if (location == -1)
return;
- GPU_print_error("Pre Uniform Vector");
+ GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Vector");
if (length == 1) glUniform1fvARB(location, arraysize, value);
else if (length == 2) glUniform2fvARB(location, arraysize, value);
@@ -1420,7 +1641,7 @@ void GPU_shader_uniform_vector(GPUShader *UNUSED(shader), int location, int leng
else if (length == 9) glUniformMatrix3fvARB(location, arraysize, 0, value);
else if (length == 16) glUniformMatrix4fvARB(location, arraysize, 0, value);
- GPU_print_error("Post Uniform Vector");
+ GPU_ASSERT_NO_GL_ERRORS("Post Uniform Vector");
}
void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
@@ -1428,9 +1649,7 @@ void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
if (location == -1)
return;
- GPU_print_error("Pre Uniform Int");
- glUniform1iARB(location, value);
- GPU_print_error("Post Uniform Int");
+ GPU_CHECK_ERRORS_AROUND(glUniform1iARB(location, value));
}
void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUTexture *tex)
@@ -1438,7 +1657,7 @@ void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUText
GLenum arbnumber;
if (tex->number >= GG.maxtextures) {
- GPU_print_error("Not enough texture slots.");
+ fprintf(stderr, "Not enough texture slots.");
return;
}
@@ -1448,7 +1667,7 @@ void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUText
if (location == -1)
return;
- GPU_print_error("Pre Uniform Texture");
+ GPU_ASSERT_NO_GL_ERRORS("Pre Uniform Texture");
arbnumber = (GLenum)((GLuint)GL_TEXTURE0_ARB + tex->number);
@@ -1461,18 +1680,14 @@ void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUText
glEnable(tex->target);
if (tex->number != 0) glActiveTextureARB(GL_TEXTURE0_ARB);
- GPU_print_error("Post Uniform Texture");
+ GPU_ASSERT_NO_GL_ERRORS("Post Uniform Texture");
}
int GPU_shader_get_attribute(GPUShader *shader, const char *name)
{
int index;
- GPU_print_error("Pre Get Attribute");
-
- index = glGetAttribLocationARB(shader->object, name);
-
- GPU_print_error("Post Get Attribute");
+ GPU_CHECK_ERRORS_AROUND(index = glGetAttribLocationARB(shader->object, name));
return index;
}
@@ -1500,8 +1715,67 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
return retval;
}
+#define MAX_DEFINES 100
+
+GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp)
+{
+ int offset;
+ char defines[MAX_DEFINES] = "";
+ /* avoid shaders out of range */
+ if (effects >= MAX_FX_SHADERS)
+ return NULL;
+
+ offset = 2 * effects;
+
+ if (persp) {
+ offset += 1;
+ strcat(defines, "#define PERSP_MATRIX\n");
+ }
+
+ if (!GG.shaders.fx_shaders[offset]) {
+ switch(effects) {
+ case GPU_SHADER_FX_SSAO:
+ GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
+ break;
+
+ case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE:
+ strcat(defines, "#define FIRST_PASS\n");
+ GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
+ break;
+
+ case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO:
+ strcat(defines, "#define SECOND_PASS\n");
+ GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
+ break;
+
+ case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE:
+ strcat(defines, "#define THIRD_PASS\n");
+ GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
+ break;
+
+ case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR:
+ strcat(defines, "#define FOURTH_PASS\n");
+ GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
+ break;
+
+ case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE:
+ strcat(defines, "#define FIFTH_PASS\n");
+ GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
+ break;
+
+ case GPU_SHADER_FX_DEPTH_RESOLVE:
+ GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, defines);
+ }
+ }
+
+ return GG.shaders.fx_shaders[offset];
+}
+
+
void GPU_shader_free_builtin_shaders(void)
{
+ int i;
+
if (GG.shaders.vsm_store) {
MEM_freeN(GG.shaders.vsm_store);
GG.shaders.vsm_store = NULL;
@@ -1511,6 +1785,13 @@ void GPU_shader_free_builtin_shaders(void)
MEM_freeN(GG.shaders.sep_gaussian_blur);
GG.shaders.sep_gaussian_blur = NULL;
}
+
+ for (i = 0; i < 2 * MAX_FX_SHADERS; i++) {
+ if (GG.shaders.fx_shaders[i]) {
+ MEM_freeN(GG.shaders.fx_shaders[i]);
+ GG.shaders.fx_shaders[i] = NULL;
+ }
+ }
}
#if 0
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index 912774cd345..a93c1a21130 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -31,10 +31,9 @@
#include "BLI_sys_types.h"
#include "GPU_init_exit.h" /* interface */
-#include "GPU_extensions.h" /* library */
#include "intern/gpu_codegen.h"
-#include "intern/gpu_extensions_private.h"
+#include "intern/gpu_private.h"
/**
* although the order of initialization and shutdown should not matter
@@ -54,12 +53,15 @@ void GPU_init(void)
gpu_extensions_init(); /* must come first */
gpu_codegen_init();
+
+ GPU_DEBUG_INIT();
}
void GPU_exit(void)
{
+ GPU_DEBUG_EXIT();
gpu_codegen_exit();
gpu_extensions_exit(); /* must come last */
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 32d7e04aeea..c754f63664f 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -76,10 +76,15 @@ typedef enum DynMatProperty {
DYN_LAMP_PERSMAT = 8,
} DynMatProperty;
+
struct GPUMaterial {
Scene *scene;
Material *ma;
+ /* material for mesh surface, worlds or something else.
+ * some code generation is done differently depending on the use case */
+ int type;
+
/* for creating the material */
ListBase nodes;
GPUNodeLink *outlink;
@@ -96,6 +101,7 @@ struct GPUMaterial {
int viewmatloc, invviewmatloc;
int obmatloc, invobmatloc;
int obcolloc, obautobumpscaleloc;
+ int cameratexcofacloc;
ListBase lamps;
};
@@ -194,7 +200,7 @@ static void gpu_material_set_attrib_id(GPUMaterial *material)
attribs->totlayer = b;
}
-static int GPU_material_construct_end(GPUMaterial *material)
+static int GPU_material_construct_end(GPUMaterial *material, const char *passname)
{
if (material->outlink) {
GPUNodeLink *outlink;
@@ -202,7 +208,7 @@ static int GPU_material_construct_end(GPUMaterial *material)
outlink = material->outlink;
material->pass = GPU_generate_pass(&material->nodes, outlink,
- &material->attribs, &material->builtins, material->ma->id.name);
+ &material->attribs, &material->builtins, material->type, passname);
if (!material->pass)
return 0;
@@ -223,18 +229,20 @@ static int GPU_material_construct_end(GPUMaterial *material)
material->obcolloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBCOLOR));
if (material->builtins & GPU_AUTO_BUMPSCALE)
material->obautobumpscaleloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_AUTO_BUMPSCALE));
+ if (material->builtins & GPU_CAMERA_TEXCO_FACTORS)
+ material->cameratexcofacloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_CAMERA_TEXCO_FACTORS));
return 1;
}
return 0;
}
-void GPU_material_free(Material *ma)
+void GPU_material_free(ListBase *gpumaterial)
{
LinkData *link;
LinkData *nlink, *mlink, *next;
- for (link=ma->gpumaterial.first; link; link=link->next) {
+ for (link=gpumaterial->first; link; link=link->next) {
GPUMaterial *material = link->data;
if (material->pass)
@@ -243,19 +251,23 @@ void GPU_material_free(Material *ma)
for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
GPULamp *lamp = nlink->data;
- for (mlink=lamp->materials.first; mlink; mlink=next) {
- next = mlink->next;
- if (mlink->data == ma)
- BLI_freelinkN(&lamp->materials, mlink);
+ if (material->ma) {
+ Material *ma = material->ma;
+
+ for (mlink=lamp->materials.first; mlink; mlink=next) {
+ next = mlink->next;
+ if (mlink->data == ma)
+ BLI_freelinkN(&lamp->materials, mlink);
+ }
}
}
-
+
BLI_freelistN(&material->lamps);
MEM_freeN(material);
}
- BLI_freelistN(&ma->gpumaterial);
+ BLI_freelistN(gpumaterial);
}
bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
@@ -268,7 +280,7 @@ bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *m
return true;
}
-void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4], bool scenelock)
+void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4], float camerafactors[4], bool scenelock)
{
if (material->pass) {
LinkData *nlink;
@@ -280,42 +292,44 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
viewlay &= srl->lay;
/* handle layer lamps */
- for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
- lamp= nlink->data;
-
- if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))
- && GPU_lamp_override_visible(lamp, srl, material->ma)) {
- lamp->dynenergy = lamp->energy;
- copy_v3_v3(lamp->dyncol, lamp->col);
- }
- else {
- lamp->dynenergy = 0.0f;
- lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f;
- }
-
- if (material->dynproperty & DYN_LAMP_VEC) {
- copy_v3_v3(lamp->dynvec, lamp->vec);
- normalize_v3(lamp->dynvec);
- negate_v3(lamp->dynvec);
- mul_mat3_m4_v3(viewmat, lamp->dynvec);
- }
-
- if (material->dynproperty & DYN_LAMP_CO) {
- copy_v3_v3(lamp->dynco, lamp->co);
- mul_m4_v3(viewmat, lamp->dynco);
- }
-
- if (material->dynproperty & DYN_LAMP_IMAT) {
- mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
- }
-
- if (material->dynproperty & DYN_LAMP_PERSMAT) {
- if (!GPU_lamp_has_shadow_buffer(lamp)) /* The lamp matrices are already updated if we're using shadow buffers */
- GPU_lamp_update_buffer_mats(lamp);
- mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
+ if (material->type == GPU_MATERIAL_TYPE_MESH) {
+ for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
+ lamp= nlink->data;
+
+ if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))
+ && GPU_lamp_override_visible(lamp, srl, material->ma)) {
+ lamp->dynenergy = lamp->energy;
+ copy_v3_v3(lamp->dyncol, lamp->col);
+ }
+ else {
+ lamp->dynenergy = 0.0f;
+ lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f;
+ }
+
+ if (material->dynproperty & DYN_LAMP_VEC) {
+ copy_v3_v3(lamp->dynvec, lamp->vec);
+ normalize_v3(lamp->dynvec);
+ negate_v3(lamp->dynvec);
+ mul_mat3_m4_v3(viewmat, lamp->dynvec);
+ }
+
+ if (material->dynproperty & DYN_LAMP_CO) {
+ copy_v3_v3(lamp->dynco, lamp->co);
+ mul_m4_v3(viewmat, lamp->dynco);
+ }
+
+ if (material->dynproperty & DYN_LAMP_IMAT) {
+ mul_m4_m4m4(lamp->dynimat, lamp->imat, viewinv);
+ }
+
+ if (material->dynproperty & DYN_LAMP_PERSMAT) {
+ if (!GPU_lamp_has_shadow_buffer(lamp)) /* The lamp matrices are already updated if we're using shadow buffers */
+ GPU_lamp_update_buffer_mats(lamp);
+ mul_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
+ }
}
}
-
+
/* note material must be bound before setting uniforms */
GPU_pass_bind(material->pass, time, mipmap);
@@ -326,6 +340,16 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
if (material->builtins & GPU_INVERSE_VIEW_MATRIX) {
GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float*)viewinv);
}
+ if (material->builtins & GPU_CAMERA_TEXCO_FACTORS) {
+ if (camerafactors) {
+ GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float*)camerafactors);
+ }
+ else {
+ /* use default, no scaling no offset */
+ float borders[4] = {1.0f, 1.0f, 0.0f, 0.0f};
+ GPU_shader_uniform_vector(shader, material->cameratexcofacloc, 4, 1, (float*)borders);
+ }
+ }
GPU_pass_update_uniforms(material->pass);
@@ -376,6 +400,12 @@ Scene *GPU_material_scene(GPUMaterial *material)
return material->scene;
}
+GPUMatType GPU_Material_get_type(GPUMaterial *material)
+{
+ return material->type;
+}
+
+
void GPU_material_vertex_attributes(GPUMaterial *material, GPUVertexAttribs *attribs)
{
*attribs = material->attribs;
@@ -1204,7 +1234,6 @@ static void do_material_tex(GPUShadeInput *shi)
float imag_tspace_dimension_x = 1024.0f; // only used for texture space variant
float aspect = 1.0f;
- GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION);
GPUNodeLink *vR1, *vR2;
GPUNodeLink *dBs, *dBt, *fDet;
@@ -1261,7 +1290,8 @@ static void do_material_tex(GPUShadeInput *shi)
// re-initialize if bump space changed
if ( iBumpSpacePrev != iBumpSpace ) {
-
+ GPUNodeLink *surf_pos = GPU_builtin(GPU_VIEW_POSITION);
+
if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
GPU_link(mat, "mtex_bump_init_objspace",
surf_pos, vNorg,
@@ -1426,6 +1456,7 @@ void GPU_shadeinput_set(GPUMaterial *mat, Material *ma, GPUShadeInput *shi)
GPU_link(mat, "set_value", GPU_uniform(&ma->emit), &shi->emit);
GPU_link(mat, "set_value", GPU_uniform(&hard), &shi->har);
GPU_link(mat, "set_value", GPU_uniform(&ma->amb), &shi->amb);
+ GPU_link(mat, "set_value", GPU_uniform(&ma->spectra), &shi->spectra);
GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &shi->view);
GPU_link(mat, "vcol_attribute", GPU_attribute(CD_MCOL, ""), &shi->vcol);
if (GPU_material_do_color_management(mat))
@@ -1497,6 +1528,12 @@ void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
}
}
+ if (ma->mode & MA_TRANSP && (ma->mode & (MA_ZTRANSP|MA_RAYTRANSP))) {
+ if (GPU_link_changed(shi->spectra) || ma->spectra != 0.0f)
+ GPU_link(mat, "alpha_spec_correction", shr->spec, shi->spectra,
+ shi->alpha, &shr->alpha);
+ }
+
if (ma->mode & MA_RAMP_COL) ramp_diffuse_result(shi, &shr->combined);
if (ma->mode & MA_RAMP_SPEC) ramp_spec_result(shi, &shr->spec);
@@ -1582,6 +1619,7 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma)
/* allocate material */
mat = GPU_material_construct_begin(ma);
mat->scene = scene;
+ mat->type = GPU_MATERIAL_TYPE_MESH;
if (ma->preview && ma->preview->rect[0]) {
outlink = gpu_material_preview_matcap(mat, ma);
@@ -1592,7 +1630,7 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma)
GPU_material_output_link(mat, outlink);
- GPU_material_construct_end(mat);
+ GPU_material_construct_end(mat, "matcap_pass");
/* note that even if building the shader fails in some way, we still keep
* it to avoid trying to compile again and again, and simple do not use
@@ -1605,6 +1643,45 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma)
return mat;
}
+GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
+{
+ LinkData *link;
+ GPUMaterial *mat;
+
+ for (link=wo->gpumaterial.first; link; link=link->next)
+ if (((GPUMaterial*)link->data)->scene == scene)
+ return link->data;
+
+ /* allocate material */
+ mat = GPU_material_construct_begin(NULL);
+ mat->scene = scene;
+ mat->type = GPU_MATERIAL_TYPE_WORLD;
+
+ /* create nodes */
+ if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes)
+ ntreeGPUMaterialNodes(wo->nodetree, mat, NODE_NEW_SHADING);
+ else {
+ /* old fixed function world */
+ }
+
+ if (GPU_material_do_color_management(mat))
+ if (mat->outlink)
+ GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
+
+ GPU_material_construct_end(mat, wo->id.name);
+
+ /* note that even if building the shader fails in some way, we still keep
+ * it to avoid trying to compile again and again, and simple do not use
+ * the actual shader on drawing */
+
+ link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
+ link->data = mat;
+ BLI_addtail(&wo->gpumaterial, link);
+
+ return mat;
+}
+
+
GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
{
GPUMaterial *mat;
@@ -1618,6 +1695,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
/* allocate material */
mat = GPU_material_construct_begin(ma);
mat->scene = scene;
+ mat->type = GPU_MATERIAL_TYPE_MESH;
/* render pipeline option */
if (ma->mode & MA_TRANSP)
@@ -1647,7 +1725,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
if (mat->outlink)
GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
- GPU_material_construct_end(mat);
+ GPU_material_construct_end(mat, ma->id.name);
/* note that even if building the shader fails in some way, we still keep
* it to avoid trying to compile again and again, and simple do not use
@@ -1664,12 +1742,16 @@ void GPU_materials_free(void)
{
Object *ob;
Material *ma;
+ World *wo;
extern Material defmaterial;
for (ma=G.main->mat.first; ma; ma=ma->id.next)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
- GPU_material_free(&defmaterial);
+ for (wo=G.main->world.first; wo; wo=wo->id.next)
+ GPU_material_free(&wo->gpumaterial);
+
+ GPU_material_free(&defmaterial.gpumaterial);
for (ob=G.main->object.first; ob; ob=ob->id.next)
GPU_lamp_free(ob);
@@ -1686,10 +1768,10 @@ static void gpu_lamp_calc_winmat(GPULamp *lamp)
orthographic_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
}
else {
- angle= saacos(lamp->spotsi);
- temp= 0.5f*lamp->size*cosf(angle)/sinf(angle);
- pixsize= (lamp->d)/temp;
- wsize= pixsize*0.5f*lamp->size;
+ angle = saacos(lamp->spotsi);
+ temp = 0.5f * lamp->size * cosf(angle) / sinf(angle);
+ pixsize = lamp->d / temp;
+ wsize = pixsize * 0.5f * lamp->size;
perspective_m4(lamp->winmat, -wsize, wsize, -wsize, wsize, lamp->d, lamp->clipend);
}
}
@@ -1844,7 +1926,7 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
return lamp;
}
- if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, NULL)) {
+ if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->depthtex, 0, NULL)) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
@@ -1856,11 +1938,16 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
return lamp;
}
- if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) {
+ if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
+ if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
/* FBO and texture for blurring */
lamp->blurfb = GPU_framebuffer_create();
if (!lamp->blurfb) {
@@ -1874,10 +1961,20 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
return lamp;
}
- if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, NULL)) {
+ if (!GPU_framebuffer_texture_attach(lamp->blurfb, lamp->blurtex, 0, NULL)) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
+
+ /* we need to properly bind to test for completeness */
+ GPU_texture_bind_as_framebuffer(lamp->blurtex);
+
+ if (!GPU_framebuffer_check_valid(lamp->blurfb, NULL)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
+
+ GPU_framebuffer_texture_unbind(lamp->blurfb, lamp->blurtex);
}
else {
lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
@@ -1886,10 +1983,15 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
return lamp;
}
- if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) {
+ if (!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, 0, NULL)) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
+
+ if (!GPU_framebuffer_check_valid(lamp->fb, NULL)) {
+ gpu_lamp_shadow_free(lamp);
+ return lamp;
+ }
}
GPU_framebuffer_restore();
@@ -1923,7 +2025,7 @@ void GPU_lamp_free(Object *ob)
BLI_freelinkN(&lamp->materials, nlink);
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
}
gpu_lamp_shadow_free(lamp);
@@ -1972,8 +2074,7 @@ void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsiz
/* opengl */
glDisable(GL_SCISSOR_TEST);
- GPU_framebuffer_texture_bind(lamp->fb, lamp->tex,
- GPU_texture_opengl_width(lamp->tex), GPU_texture_opengl_height(lamp->tex));
+ GPU_texture_bind_as_framebuffer(lamp->tex);
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE)
GPU_shader_bind(GPU_shader_get_builtin_shader(GPU_SHADER_VSM_STORE));
@@ -2008,13 +2109,14 @@ int GPU_lamp_shadow_layer(GPULamp *lamp)
return -1;
}
-GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **col, GPUNodeLink **lv, GPUNodeLink **dist, GPUNodeLink **shadow)
+GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **col, GPUNodeLink **lv, GPUNodeLink **dist, GPUNodeLink **shadow, GPUNodeLink **energy)
{
GPUNodeLink *visifac;
*col = GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob);
+ *energy = GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob);
visifac = lamp_get_visibility(mat, lamp, lv, dist);
- /* looks like it's not used? psy-fi */
+
shade_light_textures(mat, lamp, col);
if (GPU_lamp_has_shadow_buffer(lamp)) {
@@ -2026,18 +2128,18 @@ GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **co
if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) {
GPU_link(mat, "shadows_only_vsm",
- GPU_builtin(GPU_VIEW_POSITION),
- GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
- GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
- GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias),
- GPU_uniform(lamp->shadow_color), inp, shadow);
+ GPU_builtin(GPU_VIEW_POSITION),
+ GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
+ GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
+ GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias),
+ GPU_uniform(lamp->shadow_color), inp, shadow);
}
else {
GPU_link(mat, "shadows_only",
- GPU_builtin(GPU_VIEW_POSITION),
- GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
- GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
- GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, shadow);
+ GPU_builtin(GPU_VIEW_POSITION),
+ GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob),
+ GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob),
+ GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, shadow);
}
}
else {
@@ -2120,30 +2222,46 @@ GPUShaderExport *GPU_shader_export(struct Scene *scene, struct Material *ma)
glBindTexture(GL_TEXTURE_2D, lastbindcode);
}
break;
+
+ case GPU_NONE:
+ case GPU_FLOAT:
+ case GPU_VEC2:
+ case GPU_VEC3:
+ case GPU_VEC4:
+ case GPU_MAT3:
+ case GPU_MAT4:
+ case GPU_ATTRIB:
+ break;
}
}
else {
uniform->type = input->dynamictype;
BLI_strncpy(uniform->varname, input->shadername, sizeof(uniform->varname));
switch (input->type) {
- case 1:
+ case GPU_FLOAT:
uniform->datatype = GPU_DATA_1F;
break;
- case 2:
+ case GPU_VEC2:
uniform->datatype = GPU_DATA_2F;
break;
- case 3:
+ case GPU_VEC3:
uniform->datatype = GPU_DATA_3F;
break;
- case 4:
+ case GPU_VEC4:
uniform->datatype = GPU_DATA_4F;
break;
- case 9:
+ case GPU_MAT3:
uniform->datatype = GPU_DATA_9F;
break;
- case 16:
+ case GPU_MAT4:
uniform->datatype = GPU_DATA_16F;
break;
+
+ case GPU_NONE:
+ case GPU_TEX2D:
+ case GPU_SHADOW2D:
+ case GPU_ATTRIB:
+ break;
}
if (uniform->type >= GPU_DYNAMIC_LAMP_FIRST && uniform->type <= GPU_DYNAMIC_LAMP_LAST)
diff --git a/source/blender/gpu/intern/gpu_private.h b/source/blender/gpu/intern/gpu_private.h
new file mode 100644
index 00000000000..11bc2bd3119
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_private.h
@@ -0,0 +1,49 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gpu_extensions_private.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_PRIVATE_H__
+#define __GPU_PRIVATE_H__
+
+/* call this before running any of the functions below */
+void gpu_extensions_init(void);
+void gpu_extensions_exit(void);
+
+
+/* gpu_debug.c */
+#ifdef WITH_GPU_DEBUG
+
+void gpu_debug_init(void);
+void gpu_debug_exit(void);
+
+# define GPU_DEBUG_INIT() gpu_debug_init()
+# define GPU_DEBUG_EXIT() gpu_debug_exit()
+
+#else
+
+# define GPU_DEBUG_INIT() ((void)0)
+# define GPU_DEBUG_EXIT() ((void)0)
+
+#endif
+
+#endif /* __GPU_PRIVATE_H__ */
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index afd6af9efae..4978229a350 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -33,12 +33,12 @@
#include "GPU_extensions.h"
#include "GPU_glew.h"
-#include "BLI_utildefines.h"
-
#include "MEM_guardedalloc.h"
#include "DNA_userdef_types.h"
+#include "BLI_utildefines.h"
+
/* Ad hoc number of queries to allocate to skip doing many glGenQueries */
#define ALLOC_QUERIES 200
@@ -59,6 +59,7 @@ typedef struct GPUQueryState {
bool use_gpu_select;
/* cache on initialization */
unsigned int *buffer;
+ /* buffer size (stores number of integers, for actual size multiply by sizeof integer)*/
unsigned int bufsize;
/* mode of operation */
char mode;
@@ -82,7 +83,7 @@ void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, rctf *input, c
g_query_state.oldhits = oldhits;
if (!g_query_state.use_gpu_select) {
- glSelectBuffer( bufsize, (GLuint *)buffer);
+ glSelectBuffer(bufsize, (GLuint *)buffer);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(-1);
@@ -92,8 +93,8 @@ void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, rctf *input, c
g_query_state.num_of_queries = ALLOC_QUERIES;
- g_query_state.queries = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.queries) , "gpu selection queries");
- g_query_state.id = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.id) , "gpu selection ids");
+ g_query_state.queries = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.queries), "gpu selection queries");
+ g_query_state.id = MEM_mallocN(g_query_state.num_of_queries * sizeof(*g_query_state.id), "gpu selection ids");
glGenQueriesARB(g_query_state.num_of_queries, g_query_state.queries);
glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT);
@@ -135,7 +136,7 @@ void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, rctf *input, c
bool GPU_select_load_id(unsigned int id)
{
/* if no selection mode active, ignore */
- if(!g_query_state.select_is_active)
+ if (!g_query_state.select_is_active)
return true;
if (!g_query_state.use_gpu_select) {
@@ -158,7 +159,7 @@ bool GPU_select_load_id(unsigned int id)
g_query_state.active_query++;
g_query_state.query_issued = true;
- if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS) {
+ if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS && g_query_state.index < g_query_state.oldhits) {
if (g_query_state.buffer[g_query_state.index * 4 + 3] == id) {
g_query_state.index++;
return true;
@@ -191,7 +192,9 @@ unsigned int GPU_select_end(void)
glGetQueryObjectuivARB(g_query_state.queries[i], GL_QUERY_RESULT_ARB, &result);
if (result > 0) {
if (g_query_state.mode != GPU_SELECT_NEAREST_SECOND_PASS) {
- if(hits < g_query_state.bufsize) {
+ int maxhits = g_query_state.bufsize / 4;
+
+ if (hits < maxhits) {
g_query_state.buffer[hits * 4] = 1;
g_query_state.buffer[hits * 4 + 1] = 0xFFFF;
g_query_state.buffer[hits * 4 + 2] = 0xFFFF;
diff --git a/source/blender/gpu/intern/gpu_simple_shader.c b/source/blender/gpu/intern/gpu_simple_shader.c
index c0d7ebd4abb..3fa5975ef15 100644
--- a/source/blender/gpu/intern/gpu_simple_shader.c
+++ b/source/blender/gpu/intern/gpu_simple_shader.c
@@ -47,9 +47,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "DNA_mesh_types.h"
-#include "DNA_object_types.h"
-
#include "GPU_extensions.h"
#include "GPU_simple_shader.h"
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
new file mode 100644
index 00000000000..e04cd7d3306
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
@@ -0,0 +1,14 @@
+uniform sampler2D depthbuffer;
+varying vec4 uvcoordsvar;
+
+void main(void)
+{
+ float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
+
+ /* XRay background, discard */
+ if (depth >= 1.0) {
+ discard;
+ }
+
+ gl_FragDepth = depth;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
new file mode 100644
index 00000000000..e9dab04de5d
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
@@ -0,0 +1,208 @@
+/* amount of offset to move one pixel left-right.
+ * In second pass some dimensions are zero to control verical/horizontal convolution */
+uniform vec2 invrendertargetdim;
+// color buffer
+uniform sampler2D colorbuffer;
+//blurred color buffer for DOF effect
+uniform sampler2D blurredcolorbuffer;
+// slightly blurred buffer
+uniform sampler2D mblurredcolorbuffer;
+// depth buffer
+uniform sampler2D depthbuffer;
+
+// this includes focal distance in x and aperture size in y
+uniform vec4 dof_params;
+
+// viewvectors for reconstruction of world space
+uniform vec4 viewvecs[3];
+
+// coordinates on framebuffer in normalized (0.0-1.0) uv space
+varying vec4 uvcoordsvar;
+
+/* color texture coordinates, offset by a small amount */
+varying vec2 color_uv1;
+varying vec2 color_uv2;
+
+varying vec2 depth_uv1;
+varying vec2 depth_uv2;
+varying vec2 depth_uv3;
+varying vec2 depth_uv4;
+
+
+float calculate_far_coc(in float zdepth)
+{
+ float coc = dof_params.x * max(1.0 - dof_params.y / zdepth, 0.0);
+
+ /* multiply by 1.0 / sensor size to get the normalized size */
+ return coc * dof_params.z;
+}
+
+/* near coc only! when distance is nearer than focus plane first term is bigger than one */
+vec4 calculate_near_coc(in vec4 zdepth)
+{
+ vec4 coc = dof_params.x * max(vec4(dof_params.y) / zdepth - vec4(1.0), vec4(0.0));
+
+ /* multiply by 1.0 / sensor size to get the normalized size */
+ return coc * dof_params.z;
+}
+
+/* first pass blurs the color buffer heavily and gets the near coc only.
+ * There are many texture accesses here but they are done on a
+ * lower resolution image so overall bandwidth is not a concern */
+void first_pass()
+{
+ vec4 depth;
+ vec4 zdepth;
+ vec4 coc;
+ float final_coc;
+
+ /* amount to add to uvs so that they move one row further */
+ vec2 offset_row[3];
+ offset_row[0] = vec2(0.0, invrendertargetdim.y);
+ offset_row[1] = 2.0 * offset_row[0];
+ offset_row[2] = 3.0 * offset_row[0];
+
+ /* heavily blur the image */
+ vec4 color = texture2D(colorbuffer, color_uv1);
+ color += texture2D(colorbuffer, color_uv1 + offset_row[1]);
+ color += texture2D(colorbuffer, color_uv2);
+ color += texture2D(colorbuffer, color_uv2 + offset_row[1]);
+ color /= 4.0;
+
+ depth.r = texture2D(depthbuffer, depth_uv1).r;
+ depth.g = texture2D(depthbuffer, depth_uv2).r;
+ depth.b = texture2D(depthbuffer, depth_uv3).r;
+ depth.a = texture2D(depthbuffer, depth_uv4).r;
+
+ zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth);
+ coc = calculate_near_coc(zdepth);
+
+ depth.r = texture2D(depthbuffer, depth_uv1 + offset_row[0]).r;
+ depth.g = texture2D(depthbuffer, depth_uv2 + offset_row[0]).r;
+ depth.b = texture2D(depthbuffer, depth_uv3 + offset_row[0]).r;
+ depth.a = texture2D(depthbuffer, depth_uv4 + offset_row[0]).r;
+
+ zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth);
+ coc = max(calculate_near_coc(zdepth), coc);
+
+ depth.r = texture2D(depthbuffer, depth_uv1 + offset_row[1]).r;
+ depth.g = texture2D(depthbuffer, depth_uv2 + offset_row[1]).r;
+ depth.b = texture2D(depthbuffer, depth_uv3 + offset_row[1]).r;
+ depth.a = texture2D(depthbuffer, depth_uv4 + offset_row[1]).r;
+
+ zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth);
+ coc = max(calculate_near_coc(zdepth), coc);
+
+ depth.r = texture2D(depthbuffer, depth_uv1 + offset_row[2]).r;
+ depth.g = texture2D(depthbuffer, depth_uv2 + offset_row[2]).r;
+ depth.b = texture2D(depthbuffer, depth_uv3 + offset_row[2]).r;
+ depth.a = texture2D(depthbuffer, depth_uv4 + offset_row[2]).r;
+
+ zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), depth);
+ coc = max(calculate_near_coc(zdepth), coc);
+
+ final_coc = max(max(coc.x, coc.y), max(coc.z, coc.w));
+ gl_FragColor = vec4(color.rgb, final_coc);
+}
+
+/* second pass, gaussian blur the downsampled image */
+void second_pass()
+{
+ vec4 depth = vec4(texture2D(depthbuffer, uvcoordsvar.xy).r);
+
+ /* clever sampling to sample 2 pixels at once. Of course it's not real gaussian sampling this way */
+ vec4 color = texture2D(colorbuffer, uvcoordsvar.xy) * 0.3125;
+ color += texture2D(colorbuffer, uvcoordsvar.xy + invrendertargetdim) * 0.234375;
+ color += texture2D(colorbuffer, uvcoordsvar.xy + 2.5 * invrendertargetdim) * 0.09375;
+ color += texture2D(colorbuffer, uvcoordsvar.xy + 4.5 * invrendertargetdim) * 0.015625;
+ color += texture2D(colorbuffer, uvcoordsvar.xy -invrendertargetdim) * 0.234375;
+ color += texture2D(colorbuffer, uvcoordsvar.xy -2.5 * invrendertargetdim) * 0.09375;
+ color += texture2D(colorbuffer, uvcoordsvar.xy -4.5 * invrendertargetdim) * 0.015625;
+
+ gl_FragColor = color;
+}
+
+
+/* third pass, calculate the final coc from blurred and unblurred images */
+void third_pass()
+{
+ vec4 color = texture2D(colorbuffer, uvcoordsvar.xy);
+ vec4 color_blurred = texture2D(blurredcolorbuffer, uvcoordsvar.xy);
+ float coc = 2.0 * max(color_blurred.a, color.a); - color.a;
+ gl_FragColor = vec4(color.rgb, coc);
+}
+
+
+/* fourth pass, blur the final coc once to get rid of discontinuities */
+void fourth_pass()
+{
+ vec4 color = texture2D(colorbuffer, uvcoordsvar.xz);
+ color += texture2D(colorbuffer, uvcoordsvar.yz);
+ color += texture2D(colorbuffer, uvcoordsvar.xw);
+ color += texture2D(colorbuffer, uvcoordsvar.yw);
+
+ gl_FragColor = color / 4.0;
+}
+
+vec4 small_sample_blur(in sampler2D colorbuffer, in vec2 uv, in vec4 color)
+{
+ float weight = 1.0/ 17.0;
+ vec4 result = weight * color;
+ weight *= 4.0;
+
+ result += weight * texture2D(colorbuffer, uv + color_uv1.xy);
+ result += weight * texture2D(colorbuffer, uv - color_uv1.xy);
+ result += weight * texture2D(colorbuffer, uv + color_uv1.yx);
+ result += weight * texture2D(colorbuffer, uv - color_uv1.yx);
+
+ return result;
+}
+
+
+/* fourth pass, just visualize the third pass contents */
+void fifth_pass()
+{
+ vec4 factors;
+ vec4 color_orig = texture2D(colorbuffer, uvcoordsvar.xy);
+ vec4 highblurred = texture2D(blurredcolorbuffer, uvcoordsvar.xy);
+ vec4 mediumblurred = texture2D(mblurredcolorbuffer, uvcoordsvar.xy);
+ vec4 smallblurred = small_sample_blur(colorbuffer, uvcoordsvar.xy, color_orig);
+ float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
+
+ float zdepth = get_view_space_z_from_depth(vec4(viewvecs[0].z), vec4(viewvecs[1].z), vec4(depth)).r;
+ float coc_far = clamp(calculate_far_coc(zdepth), 0.0, 1.0);
+
+ /* calculate final coc here */
+ float coc = max(max(coc_far, mediumblurred.a), 0.0);
+
+ float width = 2.5;
+ float radius = 0.2;
+
+ factors.x = 1.0 - clamp(width * coc, 0.0, 1.0);
+ factors.y = 1.0 - clamp(abs(width * (coc - 2.0 * radius)), 0.0, 1.0);
+ factors.z = 1.0 - clamp(abs(width * (coc - 3.0 * radius)), 0.0, 1.0);
+ factors.w = 1.0 - clamp(abs(width * (coc - 4.0 * radius)), 0.0, 1.0);
+ /* blend! */
+ vec4 color = factors.x * color_orig + factors.y * smallblurred + factors.z * mediumblurred + factors.w * highblurred;
+
+ color /= dot(factors, vec4(1.0));
+ /* using original color is not correct, but use that for now because alpha of
+ * blurred buffers uses CoC instead */
+ gl_FragColor = vec4(color.rgb, color_orig.a);
+}
+
+
+void main()
+{
+#ifdef FIRST_PASS
+ first_pass();
+#elif defined(SECOND_PASS)
+ second_pass();
+#elif defined(THIRD_PASS)
+ third_pass();
+#elif defined(FOURTH_PASS)
+ fourth_pass();
+#elif defined(FIFTH_PASS)
+ fifth_pass();
+#endif
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
new file mode 100644
index 00000000000..a2ef990c4e8
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl
@@ -0,0 +1,68 @@
+uniform vec2 invrendertargetdim;
+
+//texture coordinates for framebuffer read
+varying vec4 uvcoordsvar;
+
+/* color texture coordinates, offset by a small amount */
+varying vec2 color_uv1;
+varying vec2 color_uv2;
+
+varying vec2 depth_uv1;
+varying vec2 depth_uv2;
+varying vec2 depth_uv3;
+varying vec2 depth_uv4;
+
+//very simple shader for gull screen FX, just pass values on
+
+void vert_generic()
+{
+ uvcoordsvar = gl_MultiTexCoord0;
+ gl_Position = gl_Vertex;
+}
+
+void vert_dof_first_pass()
+{
+ /* we offset the texture coordinates by 1.5 pixel,
+ * then we reuse that to sample the surrounding pixels */
+ color_uv1 = gl_MultiTexCoord0.xy + vec2(-1.5, -1.5) * invrendertargetdim;
+ color_uv2 = gl_MultiTexCoord0.xy + vec2(0.5, -1.5) * invrendertargetdim;
+
+ depth_uv1 = gl_MultiTexCoord0.xy + vec2(-1.5, -1.5) * invrendertargetdim;
+ depth_uv2 = gl_MultiTexCoord0.xy + vec2(-0.5, -1.5) * invrendertargetdim;
+ depth_uv3 = gl_MultiTexCoord0.xy + vec2(0.5, -1.5) * invrendertargetdim;
+ depth_uv4 = gl_MultiTexCoord0.xy + vec2(1.5, -1.5) * invrendertargetdim;
+
+ gl_Position = gl_Vertex;
+}
+
+void vert_dof_fourth_pass()
+{
+ vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5);
+ uvcoordsvar = gl_MultiTexCoord0.xxyy + halfpixel * vec4(invrendertargetdim.x,
+ invrendertargetdim.x, invrendertargetdim.y, invrendertargetdim.y);
+
+ gl_Position = gl_Vertex;
+}
+
+void vert_dof_fifth_pass()
+{
+ vec4 halfpixel = vec4(-0.5, 0.5, -0.5, 0.5);
+ color_uv1 = vec2(0.5, 1.5) * invrendertargetdim;
+
+ uvcoordsvar = gl_MultiTexCoord0;
+ gl_Position = gl_Vertex;
+}
+
+void main()
+{
+#ifdef FIRST_PASS
+ vert_dof_first_pass();
+#elif defined(FOURTH_PASS)
+ vert_dof_fourth_pass();
+#elif defined(FIFTH_PASS)
+ vert_dof_fifth_pass();
+#else
+ vert_generic();
+#endif
+}
+
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
new file mode 100644
index 00000000000..6c4bf3bb7a0
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
@@ -0,0 +1,47 @@
+vec3 calculate_view_space_normal(in vec3 viewposition)
+{
+ vec3 normal = cross(normalize(dFdx(viewposition)),
+ normalize(dFdy(viewposition)));
+ normalize(normal);
+ return normal;
+}
+
+/* simple depth reconstruction, see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer
+ * we change the factors from the article to fit the OpennGL model. */
+#ifdef PERSP_MATRIX
+
+/* perspective camera code */
+
+vec3 get_view_space_from_depth(in vec2 uvcoords, in vec3 viewvec_origin, in vec3 viewvec_diff, in float depth)
+{
+ float d = 2.0 * depth - 1.0;
+
+ float zview = -gl_ProjectionMatrix[3][2] / (d + gl_ProjectionMatrix[2][2]);
+
+ return zview * (viewvec_origin + vec3(uvcoords, 0.0) * viewvec_diff);
+}
+
+vec4 get_view_space_z_from_depth(in vec4 near, in vec4 range, in vec4 depth)
+{
+ vec4 d = 2.0 * depth - vec4(1.0);
+
+ /* return positive value, so sign differs! */
+ return vec4(gl_ProjectionMatrix[3][2]) / (d + vec4(gl_ProjectionMatrix[2][2]));
+}
+
+#else
+/* orthographic camera code */
+
+vec3 get_view_space_from_depth(in vec2 uvcoords, in vec3 viewvec_origin, in vec3 viewvec_diff, in float depth)
+{
+ vec3 offset = vec3(uvcoords, depth);
+
+ return vec3(viewvec_origin + offset * viewvec_diff);
+}
+
+vec4 get_view_space_z_from_depth(in vec4 near, in vec4 range, in vec4 depth)
+{
+ return -(near + depth * range);
+}
+
+#endif
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
new file mode 100644
index 00000000000..5e2512b6a46
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
@@ -0,0 +1,86 @@
+// color buffer
+uniform sampler2D colorbuffer;
+
+// jitter texture for ssao
+uniform sampler2D jitter_tex;
+
+// concentric sample texture for ssao
+uniform sampler1D ssao_concentric_tex;
+
+// depth buffer
+uniform sampler2D depthbuffer;
+// coordinates on framebuffer in normalized (0.0-1.0) uv space
+varying vec4 uvcoordsvar;
+
+/* ssao_params.x : pixel scale for the ssao radious */
+/* ssao_params.y : factor for the ssao darkening */
+uniform vec4 ssao_params;
+uniform vec4 ssao_sample_params;
+uniform vec4 ssao_color;
+
+/* store the view space vectors for the corners of the view frustum here.
+ * It helps to quickly reconstruct view space vectors by using uv coordinates,
+ * see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+uniform vec4 viewvecs[3];
+
+float calculate_ssao_factor(float depth)
+{
+ /* take the normalized ray direction here */
+ vec2 rotX = texture2D(jitter_tex, uvcoordsvar.xy * ssao_sample_params.zw).rg;
+ vec2 rotY = vec2(-rotX.y, rotX.x);
+
+ /* occlusion is zero in full depth */
+ if (depth == 1.0)
+ return 0.0;
+
+ vec3 position = get_view_space_from_depth(uvcoordsvar.xy, viewvecs[0].xyz, viewvecs[1].xyz, depth);
+ vec3 normal = calculate_view_space_normal(position);
+
+ // find the offset in screen space by multiplying a point in camera space at the depth of the point by the projection matrix.
+ vec2 offset;
+ float homcoord = gl_ProjectionMatrix[2][3] * position.z + gl_ProjectionMatrix[3][3];
+ offset.x = gl_ProjectionMatrix[0][0] * ssao_params.x / homcoord;
+ offset.y = gl_ProjectionMatrix[1][1] * ssao_params.x / homcoord;
+ /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
+ offset *= 0.5;
+
+ float factor = 0.0;
+ int x;
+ int num_samples = int(ssao_sample_params.x);
+
+ for (x = 0; x < num_samples; x++) {
+ vec2 dir_sample = texture1D(ssao_concentric_tex, (float(x) + 0.5) / ssao_sample_params.x).rg;
+
+ /* rotate with random direction to get jittered result */
+ vec2 dir_jittered = vec2(dot(dir_sample, rotX), dot(dir_sample, rotY));
+
+ vec2 uvcoords = uvcoordsvar.xy + dir_jittered * offset;
+
+ if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0)
+ continue;
+
+ float depth_new = texture2D(depthbuffer, uvcoords).r;
+ if (depth_new != 1.0) {
+ vec3 pos_new = get_view_space_from_depth(uvcoords, viewvecs[0].xyz, viewvecs[1].xyz, depth_new);
+ vec3 dir = pos_new - position;
+ float len = length(dir);
+ float f = dot(dir, normal);
+
+ /* use minor bias here to avoid self shadowing */
+ if (f > 0.05 * len + 0.0001)
+ factor += f * 1.0/(len * (1.0 + len * len * ssao_params.z));
+ }
+ }
+
+ factor /= ssao_sample_params.x;
+
+ return clamp(factor * ssao_params.y, 0.0, 1.0);
+}
+
+void main()
+{
+ float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
+ vec4 scene_col = texture2D(colorbuffer, uvcoordsvar.xy);
+ vec3 final_color = mix(scene_col.rgb, ssao_color.rgb, calculate_ssao_factor(depth));
+ gl_FragColor = vec4(final_color.rgb, scene_col.a);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl
new file mode 100644
index 00000000000..5194e414520
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_vert.glsl
@@ -0,0 +1,9 @@
+varying vec4 uvcoordsvar;
+
+//very simple shader for full screen FX, just pass values on
+
+void main()
+{
+ uvcoordsvar = gl_MultiTexCoord0;
+ gl_Position = gl_Vertex;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 5a0812cb367..945b7ef303f 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -169,9 +169,9 @@ void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
outview = normalize(co);
}
-void lamp(vec4 col, vec3 lv, float dist, vec3 shadow, float visifac, out vec4 outcol, out vec3 outlv, out float outdist, out vec4 outshadow, out float outvisifac)
+void lamp(vec4 col, float energy, vec3 lv, float dist, vec3 shadow, float visifac, out vec4 outcol, out vec3 outlv, out float outdist, out vec4 outshadow, out float outvisifac)
{
- outcol = col;
+ outcol = col * energy;
outlv = lv;
outdist = dist;
outshadow = vec4(shadow, 1.0);
@@ -297,6 +297,10 @@ void math_modulo(float val1, float val2, out float outval)
outval = 0.0;
else
outval = mod(val1, val2);
+
+ /* change sign to match C convention, mod in GLSL will take absolute for negative numbers,
+ * see https://www.opengl.org/sdk/docs/man/html/mod.xhtml */
+ outval = (val1 > 0.0) ? outval : -outval;
}
void math_abs(float val1, out float outval)
@@ -338,6 +342,7 @@ void vec_math_cross(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
{
outvec = cross(v1, v2);
outval = length(outvec);
+ outvec /= outval;
}
void vec_math_normalize(vec3 v, out vec3 outvec, out float outval)
@@ -357,6 +362,12 @@ void normal(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
outdot = -dot(dir, nor);
}
+void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
+{
+ outnor = normalize(nor);
+ outdot = dot(normalize(dir), nor);
+}
+
void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec)
{
outvec.x = texture2D(curvemap, vec2((vec.x + 1.0)*0.5, 0.0)).x;
@@ -722,6 +733,16 @@ void invert(float fac, vec4 col, out vec4 outcol)
outcol.w = col.w;
}
+void clamp_vec3(vec3 vec, vec3 min, vec3 max, out vec3 out_vec)
+{
+ out_vec = clamp(vec, min, max);
+}
+
+void clamp_val(float value, float min, float max, out float out_value)
+{
+ out_value = clamp(value, min, max);
+}
+
void hue_sat(float hue, float sat, float value, float fac, vec4 col, out vec4 outcol)
{
vec4 hsv;
@@ -1925,6 +1946,17 @@ void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol)
outcol = t*lampcol*speccol;
}
+void alpha_spec_correction(vec3 spec, float spectra, float alpha, out float outalpha)
+{
+ if (spectra > 0.0) {
+ float t = clamp(max(max(spec.r, spec.g), spec.b) * spectra, 0.0, 1.0);
+ outalpha = (1.0 - t) * alpha + t;
+ }
+ else {
+ outalpha = alpha;
+ }
+}
+
void shade_add(vec4 col1, vec4 col2, out vec4 outcol)
{
outcol = col1 + col2;
@@ -2235,6 +2267,22 @@ void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
result = color*strength;
}
+/* background */
+
+void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
+{
+ vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+
+ vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+ worldvec = (gl_ModelViewMatrixInverse * co).xyz;
+}
+
+void node_background(vec4 color, float strength, vec3 N, out vec4 result)
+{
+ result = color*strength;
+}
+
/* closures */
void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader)
@@ -2264,10 +2312,12 @@ void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float
{
/* fresnel */
float eta = max(1.0 - blend, 0.00001);
- fresnel = fresnel_dielectric(normalize(I), N, (gl_FrontFacing)? 1.0/eta : eta );
+ vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(I): vec3(0.0, 0.0, -1.0);
+
+ fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing)? 1.0/eta : eta );
/* facing */
- facing = abs(dot(normalize(I), N));
+ facing = abs(dot(I_view, N));
if(blend != 0.5) {
blend = clamp(blend, 0.0, 0.99999);
blend = (blend < 0.5)? 2.0*blend: 0.5/(1.0 - blend);
@@ -2307,7 +2357,7 @@ void node_uvmap(vec3 attr_uv, out vec3 outvec)
void node_geometry(vec3 I, vec3 N, mat4 toworld,
out vec3 position, out vec3 normal, out vec3 tangent,
out vec3 true_normal, out vec3 incoming, out vec3 parametric,
- out float backfacing)
+ out float backfacing, out float pointiness)
{
position = (toworld*vec4(I, 1.0)).xyz;
normal = (toworld*vec4(N, 0.0)).xyz;
@@ -2320,20 +2370,21 @@ void node_geometry(vec3 I, vec3 N, mat4 toworld,
parametric = vec3(0.0);
backfacing = (gl_FrontFacing)? 0.0: 1.0;
+ pointiness = 0.0;
}
-void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat,
+void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
vec3 attr_orco, vec3 attr_uv,
out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
out vec3 camera, out vec3 window, out vec3 reflection)
{
- generated = mtex_2d_mapping(attr_orco);
+ generated = attr_orco * 0.5 + vec3(0.5);
normal = normalize((obinvmat*(viewinvmat*vec4(N, 0.0))).xyz);
uv = attr_uv;
object = (obinvmat*(viewinvmat*vec4(I, 1.0))).xyz;
- camera = I;
+ camera = vec3(I.xy, -I.z);
vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0);
- window = mtex_2d_mapping(projvec.xyz/projvec.w);
+ window = vec3(mtex_2d_mapping(projvec.xyz/projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
vec3 shade_I;
shade_view(I, shade_I);
@@ -2341,6 +2392,32 @@ void node_tex_coord(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat,
reflection = (viewinvmat*vec4(view_reflection, 0.0)).xyz;
}
+void node_tex_coord_background(vec3 I, vec3 N, mat4 viewinvmat, mat4 obinvmat, vec4 camerafac,
+ vec3 attr_orco, vec3 attr_uv,
+ out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
+ out vec3 camera, out vec3 window, out vec3 reflection)
+{
+ vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+
+ vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+
+ co = normalize(co);
+ vec3 coords = (gl_ModelViewMatrixInverse * co).xyz;
+
+ generated = coords;
+ normal = -coords;
+ uv = vec3(attr_uv.xy, 0.0);
+ object = coords;
+
+ camera = vec3(co.xy, -co.z);
+ window = (gl_ProjectionMatrix[3][3] == 0.0) ?
+ vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) :
+ vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0);
+
+ reflection = -coords;
+}
+
/* textures */
void node_tex_gradient(vec3 co, out vec4 color, out float fac)
@@ -2367,17 +2444,34 @@ void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
fac = 1.0;
}
-void node_tex_environment(vec3 co, sampler2D ima, out vec4 color)
+void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color)
{
- float u = (atan(co.y, co.x) + M_PI)/(2.0*M_PI);
- float v = atan(co.z, hypot(co.x, co.y))/M_PI + 0.5;
+ vec3 nco = normalize(co);
+ float u = -atan(nco.y, nco.x)/(2.0*M_PI) + 0.5;
+ float v = atan(nco.z, hypot(nco.x, nco.y))/M_PI + 0.5;
+
+ color = texture2D(ima, vec2(u, v));
+}
+
+void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
+{
+ vec3 nco = normalize(co);
+
+ nco.y -= 1.0;
+
+ float div = 2.0*sqrt(max(-0.5*nco.y, 0.0));
+ if(div > 0.0)
+ nco /= div;
+
+ float u = 0.5*(nco.x + 1.0);
+ float v = 0.5*(nco.z + 1.0);
color = texture2D(ima, vec2(u, v));
}
void node_tex_environment_empty(vec3 co, out vec4 color)
{
- color = vec4(0.0);
+ color = vec4(1.0, 0.0, 1.0, 1.0);
}
void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
@@ -2485,6 +2579,11 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec
result = surface;
}
+void node_output_world(vec4 surface, vec4 volume, out vec4 result)
+{
+ result = surface;
+}
+
/* ********************** matcap style render ******************** */
void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
diff --git a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
index 978b6db1b9a..5f406c959f1 100644
--- a/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl
@@ -10,7 +10,7 @@ void main()
color += texture2D( textureSource, gl_TexCoord[0].st + vec2(0.0, 0.0)) * 0.3125;
color += texture2D( textureSource, gl_TexCoord[0].st + vec2(1.0 * ScaleU.x, 1.0 * ScaleU.y ) ) * 0.234375;
color += texture2D( textureSource, gl_TexCoord[0].st + vec2(2.0 * ScaleU.x, 2.0 * ScaleU.y ) ) * 0.09375;
- color += texture2D( textureSource, gl_TexCoord[0].st + vec2(3.0 * ScaleU.x, -3.0 * ScaleU.y ) ) * 0.015625;
+ color += texture2D( textureSource, gl_TexCoord[0].st + vec2(3.0 * ScaleU.x, 3.0 * ScaleU.y ) ) * 0.015625;
gl_FragColor = color;
}
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
new file mode 100644
index 00000000000..9dbcaeb7a32
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_vertex_world.glsl
@@ -0,0 +1,13 @@
+
+varying vec3 varposition;
+varying vec3 varnormal;
+
+void main()
+{
+ /* position does not need to be transformed, we already have it */
+ gl_Position = gl_Vertex;
+
+ varposition = gl_Vertex.xyz;
+
+ varnormal = normalize(-varposition);
+
diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c
index 2ca50afb0f2..0f81fb34a63 100644
--- a/source/blender/ikplugin/intern/ikplugin_api.c
+++ b/source/blender/ikplugin/intern/ikplugin_api.c
@@ -30,19 +30,12 @@
* \ingroup ikplugin
*/
-
-
#include "BIK_api.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
-
-#include "BKE_armature.h"
#include "DNA_object_types.h"
#include "DNA_action_types.h"
#include "DNA_scene_types.h"
-#include "DNA_constraint_types.h"
-#include "DNA_armature_types.h"
#include "ikplugin_api.h"
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index cd09b56b262..5da06ed91ec 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -307,8 +307,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
/* compute rest basis and its inverse */
copy_m3_m3(rest_basis, bone->bone_mat);
- copy_m3_m3(irest_basis, bone->bone_mat);
- transpose_m3(irest_basis);
+ transpose_m3_m3(irest_basis, bone->bone_mat);
/* compute basis with rest_basis removed */
invert_m3_m3(iR_parmat, R_parmat);
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index ce6a7eb1c47..447a14b95c3 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -86,6 +86,7 @@ struct anim;
struct ColorManagedDisplay;
+struct GSet;
/**
*
* \attention Defined in allocimbuf.c
@@ -125,6 +126,13 @@ struct ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y,
unsigned char d, unsigned int flags);
/**
+ * Create a copy of a pixel buffer and wrap it to a new ImBuf
+ * \attention Defined in allocimbuf.c
+ */
+struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect, const float *rectf,
+ unsigned int w, unsigned int h);
+
+/**
*
* Increase reference count to imbuf
* (to delete an imbuf you have to call freeImBuf as many times as it
@@ -236,11 +244,14 @@ void IMB_anim_set_index_dir(struct anim *anim, const char *dir);
int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc,
int position);
+IMB_Proxy_Size IMB_anim_proxy_get_existing(struct anim *anim);
+
struct IndexBuildContext;
/* prepare context for proxies/imecodes builder */
struct IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecode_Type tcs_in_use,
- IMB_Proxy_Size proxy_sizes_in_use, int quality);
+ IMB_Proxy_Size proxy_sizes_in_use, int quality,
+ const bool overwite, struct GSet *file_list);
/* will rebuild all used indices and proxies at once */
void IMB_anim_index_rebuild(struct IndexBuildContext *context,
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 44cb7f1211e..9e7201f53b4 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -47,8 +47,6 @@
* contains an Amiga-format file).
*/
-struct ImMetaData;
-
#define IB_MIPMAP_LEVELS 20
#define IB_FILENAME_SIZE 1024
@@ -111,7 +109,7 @@ typedef struct ImBuf {
/* externally used data */
int index; /* reference index for ImBuf lists */
int userflags; /* used to set imbuf to dirty and other stuff */
- struct ImMetaData *metadata; /* image metadata */
+ struct IDProperty *metadata; /* image metadata */
void *userdata; /* temporary storage, only used by baking at the moment */
/* file information */
@@ -204,7 +202,7 @@ typedef struct ImBuf {
#define OPENEXR (1 << 22)
#define OPENEXR_HALF (1 << 8 )
-#define OPENEXR_COMPRESS (7)
+#define OPENEXR_COMPRESS (15)
#ifdef WITH_CINEON
#define CINEON (1 << 21)
diff --git a/source/blender/imbuf/intern/IMB_metadata.h b/source/blender/imbuf/intern/IMB_metadata.h
index a717764b44f..5d4a0028ee1 100644
--- a/source/blender/imbuf/intern/IMB_metadata.h
+++ b/source/blender/imbuf/intern/IMB_metadata.h
@@ -35,13 +35,6 @@
struct ImBuf;
-typedef struct ImMetaData {
- struct ImMetaData *next, *prev;
- char *key;
- char *value;
- int len;
-} ImMetaData;
-
/** The metadata is a list of key/value pairs (both char *) that can me
* saved in the header of several image formats.
* Apart from some common keys like
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 612517775f4..b28d19e3e15 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -47,8 +47,8 @@
#include "MEM_guardedalloc.h"
-#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLI_threads.h"
static SpinLock refcounter_spin;
@@ -362,6 +362,30 @@ bool imb_addrectImBuf(ImBuf *ibuf)
return false;
}
+struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect, const float *rectf,
+ unsigned int w, unsigned int h)
+{
+ ImBuf *ibuf = NULL;
+
+ if (!(rect || rectf))
+ return NULL;
+
+ ibuf = IMB_allocImBuf(w, h, 32, 0);
+
+ if (rectf) {
+ ibuf->rect_float = MEM_dupallocN(rectf);
+ ibuf->flags |= IB_rectfloat;
+ ibuf->mall |= IB_rectfloat;
+ }
+ if (rect) {
+ ibuf->rect = MEM_dupallocN(rect);
+ ibuf->flags |= IB_rect;
+ ibuf->mall |= IB_rect;
+ }
+
+ return ibuf;
+}
+
bool imb_addtilesImBuf(ImBuf *ibuf)
{
if (ibuf == NULL) return false;
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index eef7964ef3f..ffdecb793aa 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -70,12 +70,8 @@
#include "MEM_guardedalloc.h"
-#include "DNA_userdef_types.h"
-
#include "BKE_global.h"
-#include "imbuf.h"
-
#ifdef WITH_AVI
# include "AVI_avi.h"
#endif
@@ -89,7 +85,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_allocimbuf.h"
#include "IMB_anim.h"
#include "IMB_indexer.h"
@@ -1319,25 +1314,27 @@ struct ImBuf *IMB_anim_absolute(struct anim *anim, int position,
filter_y = (anim->ib_flags & IB_animdeinterlace);
- if (anim->curtype == 0) {
- ibuf = anim_getnew(anim);
- if (ibuf == NULL) {
- return(NULL);
+ if (preview_size == IMB_PROXY_NONE) {
+ if (anim->curtype == 0) {
+ ibuf = anim_getnew(anim);
+ if (ibuf == NULL) {
+ return(NULL);
+ }
+
+ IMB_freeImBuf(ibuf); /* ???? */
+ ibuf = NULL;
}
- IMB_freeImBuf(ibuf); /* ???? */
- ibuf = NULL;
+ if (position < 0) return(NULL);
+ if (position >= anim->duration) return(NULL);
}
-
- if (position < 0) return(NULL);
- if (position >= anim->duration) return(NULL);
-
- if (preview_size != IMB_PROXY_NONE) {
+ else {
struct anim *proxy = IMB_anim_open_proxy(anim, preview_size);
if (proxy) {
position = IMB_anim_index_get_frame_index(
anim, tc, position);
+
return IMB_anim_absolute(
proxy, position,
IMB_TC_NONE, IMB_PROXY_NONE);
diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c
index dabeec74a62..19e655a0b3d 100644
--- a/source/blender/imbuf/intern/bmp.c
+++ b/source/blender/imbuf/intern/bmp.c
@@ -36,7 +36,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_allocimbuf.h"
#include "IMB_filetype.h"
#include "IMB_colormanagement.h"
@@ -73,22 +72,24 @@ typedef struct BMPHEADER {
#define BMP_FILEHEADER_SIZE 14
+#define CHECK_HEADER_FIELD(_mem, _field) ((_mem[0] == _field[0]) && (_mem[1] == _field[1]))
+#define CHECK_HEADER_FIELD_BMP(_mem) \
+ (CHECK_HEADER_FIELD(_mem, "BM") || \
+ CHECK_HEADER_FIELD(_mem, "BA") || \
+ CHECK_HEADER_FIELD(_mem, "CI") || \
+ CHECK_HEADER_FIELD(_mem, "CP") || \
+ CHECK_HEADER_FIELD(_mem, "IC") || \
+ CHECK_HEADER_FIELD(_mem, "PT"))
+
static int checkbmp(unsigned char *mem)
{
-#define CHECK_HEADER_FIELD(mem, field) ((mem[0] == field[0]) && (mem[1] == field[1]))
int ret_val = 0;
BMPINFOHEADER bmi;
unsigned int u;
if (mem) {
- if (CHECK_HEADER_FIELD(mem, "BM") ||
- CHECK_HEADER_FIELD(mem, "BA") ||
- CHECK_HEADER_FIELD(mem, "CI") ||
- CHECK_HEADER_FIELD(mem, "CP") ||
- CHECK_HEADER_FIELD(mem, "IC") ||
- CHECK_HEADER_FIELD(mem, "PT"))
- {
+ if (CHECK_HEADER_FIELD_BMP(mem)) {
/* skip fileheader */
mem += BMP_FILEHEADER_SIZE;
}
@@ -104,7 +105,7 @@ static int checkbmp(unsigned char *mem)
if (u >= sizeof(BMPINFOHEADER)) {
if (bmi.biCompression == 0) {
u = LITTLE_SHORT(bmi.biBitCount);
- if (u >= 8) {
+ if (u > 0 && u <= 32) {
ret_val = 1;
}
}
@@ -112,8 +113,6 @@ static int checkbmp(unsigned char *mem)
}
return(ret_val);
-
-#undef CHECK_HEADER_FIELD
}
int imb_is_a_bmp(unsigned char *buf)
@@ -125,10 +124,11 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
{
struct ImBuf *ibuf = NULL;
BMPINFOHEADER bmi;
- int x, y, depth, ibuf_depth, skip, i;
+ int x, y, depth, ibuf_depth, skip, i, j;
unsigned char *bmp, *rect;
unsigned short col;
double xppm, yppm;
+ bool top_to_bottom = false;
(void)size; /* unused */
@@ -136,10 +136,15 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
- if ((mem[0] == 'B') && (mem[1] == 'M')) {
+ bmp = mem + LITTLE_LONG(*(int*)(mem + 10));
+
+ if (CHECK_HEADER_FIELD_BMP(mem)) {
/* skip fileheader */
mem += BMP_FILEHEADER_SIZE;
}
+ else {
+ return NULL;
+ }
/* for systems where an int needs to be 4 bytes aligned */
memcpy(&bmi, mem, sizeof(bmi));
@@ -158,11 +163,14 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
ibuf_depth = depth;
}
+ if (y < 0) {
+ /* Negative height means bitmap is stored top-to-bottom... */
+ y = -y;
+ top_to_bottom = true;
+ }
+
#if 0
- printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y,
- depth, bmi.biBitCount);
- printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y,
- depth, bmi.biBitCount);
+ printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y, depth, bmi.biBitCount);
#endif
if (flags & IB_test) {
@@ -170,44 +178,67 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
}
else {
ibuf = IMB_allocImBuf(x, y, ibuf_depth, IB_rect);
- bmp = mem + skip;
rect = (unsigned char *) ibuf->rect;
- if (depth == 8) {
- const int x_pad = (4 - (x % 4)) % 4;
- const char (*palette)[4] = (void *)bmp;
- bmp += bmi.biClrUsed * 4;
+ if (depth <= 8) {
+ const int rowsize = (depth * x + 31) / 32 * 4;
+ const char (*palette)[4] = (void *)(mem + skip);
+ const int startmask = ((1 << depth) - 1) << 8;
for (i = y; i > 0; i--) {
- int j;
+ int index;
+ int bitoffs = 8;
+ int bitmask = startmask;
+ int nbytes = 0;
+ const char *pcol;
+ if (top_to_bottom) {
+ rect = (unsigned char *) &ibuf->rect[(i - 1) * x];
+ }
for (j = x; j > 0; j--) {
- const char *pcol = palette[bmp[0]];
- rect[0] = pcol[0];
+ bitoffs -= depth;
+ bitmask >>= depth;
+ index = (bmp[0] & bitmask) >> bitoffs;
+ pcol = palette[index];
+ /* intentionally BGR -> RGB */
+ rect[0] = pcol[2];
rect[1] = pcol[1];
- rect[2] = pcol[2];
+ rect[2] = pcol[0];
rect[3] = 255;
- rect += 4; bmp += 1;
+ rect += 4;
+ if (bitoffs == 0) {
+ /* Advance to the next byte */
+ bitoffs = 8;
+ bitmask = startmask;
+ nbytes += 1;
+ bmp += 1;
+ }
}
- /* rows are padded to multiples of 4 */
- bmp += x_pad;
+ /* Advance to the next row */
+ bmp += (rowsize - nbytes);
}
}
else if (depth == 16) {
- for (i = x * y; i > 0; i--) {
- col = bmp[0] + (bmp[1] << 8);
- rect[0] = ((col >> 10) & 0x1f) << 3;
- rect[1] = ((col >> 5) & 0x1f) << 3;
- rect[2] = ((col >> 0) & 0x1f) << 3;
-
- rect[3] = 255;
- rect += 4; bmp += 2;
- }
+ for (i = y; i > 0; i--) {
+ if (top_to_bottom) {
+ rect = (unsigned char *) &ibuf->rect[(i - 1) * x];
+ }
+ for (j = x; j > 0; j--) {
+ col = bmp[0] + (bmp[1] << 8);
+ rect[0] = ((col >> 10) & 0x1f) << 3;
+ rect[1] = ((col >> 5) & 0x1f) << 3;
+ rect[2] = ((col >> 0) & 0x1f) << 3;
+ rect[3] = 255;
+ rect += 4; bmp += 2;
+ }
+ }
}
else if (depth == 24) {
const int x_pad = x % 4;
for (i = y; i > 0; i--) {
- int j;
+ if (top_to_bottom) {
+ rect = (unsigned char *) &ibuf->rect[(i - 1) * x];
+ }
for (j = x; j > 0; j--) {
rect[0] = bmp[2];
rect[1] = bmp[1];
@@ -221,12 +252,17 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
}
}
else if (depth == 32) {
- for (i = x * y; i > 0; i--) {
- rect[0] = bmp[2];
- rect[1] = bmp[1];
- rect[2] = bmp[0];
- rect[3] = bmp[3];
- rect += 4; bmp += 4;
+ for (i = y; i > 0; i--) {
+ if (top_to_bottom) {
+ rect = (unsigned char *) &ibuf->rect[(i - 1) * x];
+ }
+ for (j = x; j > 0; j--) {
+ rect[0] = bmp[2];
+ rect[1] = bmp[1];
+ rect[2] = bmp[0];
+ rect[3] = bmp[3];
+ rect += 4; bmp += 4;
+ }
}
}
}
@@ -240,6 +276,9 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
return(ibuf);
}
+#undef CHECK_HEADER_FIELD_BMP
+#undef CHECK_HEADER_FIELD
+
/* Couple of helper functions for writing our data */
static int putIntLSB(unsigned int ui, FILE *ofile)
{
@@ -299,7 +338,9 @@ int imb_savebmp(struct ImBuf *ibuf, const char *name, int flags)
if (putc(data[ptr], ofile) == EOF) return 0;
}
/* add padding here */
- for (t = 0; t < extrabytes; t++) if (putc(0, ofile) == EOF) return 0;
+ for (t = 0; t < extrabytes; t++) {
+ if (putc(0, ofile) == EOF) return 0;
+ }
}
if (ofile) {
fflush(ofile);
diff --git a/source/blender/imbuf/intern/cache.c b/source/blender/imbuf/intern/cache.c
index 677c3dbe700..759f8cc82c2 100644
--- a/source/blender/imbuf/intern/cache.c
+++ b/source/blender/imbuf/intern/cache.c
@@ -22,7 +22,6 @@
* \ingroup imbuf
*/
-
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
@@ -31,8 +30,6 @@
#include "BLI_memarena.h"
#include "BLI_threads.h"
-
-
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_filetype.h"
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index 880df0ce5c3..0e71206517e 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -135,7 +135,7 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t
{
CineonMainHeader header;
LogImageFile *cineon = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
- char *filename = (char *)byteStuff;
+ const char *filename = (const char *)byteStuff;
int i;
unsigned int dataOffset;
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index 626d05b05c5..23e5517bb09 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -67,7 +67,7 @@ static void fillDpxMainHeader(LogImageFile *dpx, DpxMainHeader *header, const ch
/* --- File header --- */
header->fileHeader.magic_num = swap_uint(DPX_FILE_MAGIC, dpx->isMSB);
header->fileHeader.offset = swap_uint(dpx->element[0].dataOffset, dpx->isMSB);
- strcpy(header->fileHeader.version, "v2.0");
+ strcpy(header->fileHeader.version, "V2.0");
header->fileHeader.file_size = swap_uint(dpx->element[0].dataOffset + dpx->height * getRowLength(dpx->width, dpx->element[0]), dpx->isMSB);
header->fileHeader.ditto_key = 0;
header->fileHeader.gen_hdr_size = swap_uint(sizeof(DpxFileHeader) + sizeof(DpxImageHeader) + sizeof(DpxOrientationHeader), dpx->isMSB);
@@ -134,7 +134,7 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
{
DpxMainHeader header;
LogImageFile *dpx = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
- char *filename = (char *)byteStuff;
+ const char *filename = (const char *)byteStuff;
int i;
if (dpx == NULL) {
@@ -183,8 +183,10 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
if (verbose) printf("DPX: File is LSB.\n");
}
else {
- if (verbose) printf("DPX: Bad magic number %lu in \"%s\".\n",
- (uintptr_t)header.fileHeader.magic_num, byteStuff);
+ if (verbose) {
+ printf("DPX: Bad magic number %lu in \"%s\".\n",
+ (uintptr_t)header.fileHeader.magic_num, byteStuff);
+ }
logImageClose(dpx);
return NULL;
}
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 5dd6b366a93..95e166b2f8b 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -44,7 +44,6 @@
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
-#include "IMB_filter.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_filetype.h"
@@ -53,14 +52,13 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_fileops.h"
#include "BLI_math.h"
#include "BLI_math_color.h"
-#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_threads.h"
#include "BLI_rect.h"
+#include "BKE_appdir.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_image.h"
@@ -245,7 +243,7 @@ static ColormnaageCacheData *colormanage_cachedata_get(const ImBuf *ibuf)
static unsigned int colormanage_hashhash(const void *key_v)
{
- ColormanageCacheKey *key = (ColormanageCacheKey *)key_v;
+ const ColormanageCacheKey *key = key_v;
unsigned int rval = (key->display << 16) | (key->view % 0xffff);
@@ -254,8 +252,8 @@ static unsigned int colormanage_hashhash(const void *key_v)
static bool colormanage_hashcmp(const void *av, const void *bv)
{
- const ColormanageCacheKey *a = (ColormanageCacheKey *) av;
- const ColormanageCacheKey *b = (ColormanageCacheKey *) bv;
+ const ColormanageCacheKey *a = av;
+ const ColormanageCacheKey *b = bv;
return ((a->view != b->view) ||
(a->display != b->display));
@@ -625,7 +623,7 @@ void colormanagement_init(void)
}
if (config == NULL) {
- configdir = BLI_get_folder(BLENDER_DATAFILES, "colormanagement");
+ configdir = BKE_appdir_folder_id(BLENDER_DATAFILES, "colormanagement");
if (configdir) {
BLI_join_dirfile(configfile, sizeof(configfile), configdir, BCM_CONFIG_FILE);
@@ -1143,7 +1141,7 @@ void IMB_colormanagement_validate_settings(ColorManagedDisplaySettings *display_
for (view_link = display->views.first; view_link; view_link = view_link->next) {
ColorManagedView *view = view_link->data;
- if (!strcmp(view->name, view_settings->view_transform))
+ if (STREQ(view->name, view_settings->view_transform))
break;
}
@@ -1498,7 +1496,7 @@ static bool is_ibuf_rect_in_display_space(ImBuf *ibuf, const ColorManagedViewSet
const char *from_colorspace = ibuf->rect_colorspace->name;
const char *to_colorspace = IMB_colormanagement_get_display_colorspace_name(view_settings, display_settings);
- if (to_colorspace && !strcmp(from_colorspace, to_colorspace))
+ if (to_colorspace && STREQ(from_colorspace, to_colorspace))
return true;
}
@@ -1627,7 +1625,7 @@ static void colormanagement_transform_ex(float *buffer, int width, int height, i
return;
}
- if (!strcmp(from_colorspace, to_colorspace)) {
+ if (STREQ(from_colorspace, to_colorspace)) {
/* if source and destination color spaces are identical, skip
* threading overhead and simply do nothing
*/
@@ -1668,7 +1666,7 @@ void IMB_colormanagement_transform_v4(float pixel[4], const char *from_colorspac
return;
}
- if (!strcmp(from_colorspace, to_colorspace)) {
+ if (STREQ(from_colorspace, to_colorspace)) {
/* if source and destination color spaces are identical, skip
* threading overhead and simply do nothing
*/
@@ -1920,7 +1918,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, bool save_as_render, boo
* should be pretty safe since this image buffer is supposed to be used for
* saving only and ftype would be overwritten a bit later by BKE_imbuf_write
*/
- colormanaged_ibuf->ftype = BKE_imtype_to_ftype(image_format_data->imtype);
+ colormanaged_ibuf->ftype = BKE_image_imtype_to_ftype(image_format_data->imtype);
/* if file format isn't able to handle float buffer itself,
* we need to allocate byte buffer and store color managed
@@ -2154,7 +2152,7 @@ ColorManagedDisplay *colormanage_display_get_named(const char *name)
ColorManagedDisplay *display;
for (display = global_displays.first; display; display = display->next) {
- if (!strcmp(display->name, name))
+ if (STREQ(display->name, name))
return display;
}
@@ -2259,7 +2257,7 @@ ColorManagedView *colormanage_view_get_named(const char *name)
ColorManagedView *view;
for (view = global_views.first; view; view = view->next) {
- if (!strcmp(view->name, name))
+ if (STREQ(view->name, name))
return view;
}
@@ -2375,7 +2373,7 @@ ColorSpace *colormanage_colorspace_get_named(const char *name)
ColorSpace *colorspace;
for (colorspace = global_colorspaces.first; colorspace; colorspace = colorspace->next) {
- if (!strcmp(colorspace->name, name))
+ if (STREQ(colorspace->name, name))
return colorspace;
}
@@ -2461,7 +2459,7 @@ ColorManagedLook *colormanage_look_get_named(const char *name)
ColorManagedLook *look;
for (look = global_looks.first; look; look = look->next) {
- if (!strcmp(look->name, name)) {
+ if (STREQ(look->name, name)) {
return look;
}
}
diff --git a/source/blender/imbuf/intern/dds/Stream.cpp b/source/blender/imbuf/intern/dds/Stream.cpp
index 57a251261a1..d8387b92530 100644
--- a/source/blender/imbuf/intern/dds/Stream.cpp
+++ b/source/blender/imbuf/intern/dds/Stream.cpp
@@ -30,10 +30,13 @@
#include <stdio.h> // printf
#include <string.h> // memcpy
+static const char *msg_error_seek = "DDS: trying to seek beyond end of stream (corrupt file?)";
+static const char *msg_error_read = "DDS: trying to read beyond end of stream (corrupt file?)";
+
unsigned int Stream::seek(unsigned int p)
{
if (p > size) {
- printf("DDS: trying to seek beyond end of stream (corrupt file?)");
+ puts(msg_error_seek);
}
else {
pos = p;
@@ -45,7 +48,7 @@ unsigned int Stream::seek(unsigned int p)
unsigned int mem_read(Stream & mem, unsigned long long & i)
{
if (mem.pos + 8 > mem.size) {
- printf("DDS: trying to read beyond end of stream (corrupt file?)");
+ puts(msg_error_seek);
return(0);
}
memcpy(&i, mem.mem + mem.pos, 8); // @@ todo: make sure little endian
@@ -56,7 +59,7 @@ unsigned int mem_read(Stream & mem, unsigned long long & i)
unsigned int mem_read(Stream & mem, unsigned int & i)
{
if (mem.pos + 4 > mem.size) {
- printf("DDS: trying to read beyond end of stream (corrupt file?)");
+ puts(msg_error_read);
return(0);
}
memcpy(&i, mem.mem + mem.pos, 4); // @@ todo: make sure little endian
@@ -67,7 +70,7 @@ unsigned int mem_read(Stream & mem, unsigned int & i)
unsigned int mem_read(Stream & mem, unsigned short & i)
{
if (mem.pos + 2 > mem.size) {
- printf("DDS: trying to read beyond end of stream (corrupt file?)");
+ puts(msg_error_read);
return(0);
}
memcpy(&i, mem.mem + mem.pos, 2); // @@ todo: make sure little endian
@@ -78,7 +81,7 @@ unsigned int mem_read(Stream & mem, unsigned short & i)
unsigned int mem_read(Stream & mem, unsigned char & i)
{
if (mem.pos + 1 > mem.size) {
- printf("DDS: trying to read beyond end of stream (corrupt file?)");
+ puts(msg_error_read);
return(0);
}
i = (mem.mem + mem.pos)[0];
@@ -89,7 +92,7 @@ unsigned int mem_read(Stream & mem, unsigned char & i)
unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt)
{
if (mem.pos + cnt > mem.size) {
- printf("DDS: trying to read beyond end of stream (corrupt file?)");
+ puts(msg_error_read);
return(0);
}
memcpy(i, mem.mem + mem.pos, cnt);
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 03cd5ecd646..65abf22ff2c 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -37,7 +37,6 @@
#include "imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_allocimbuf.h"
#include "IMB_filter.h"
#include "IMB_colormanagement.h"
@@ -123,16 +122,6 @@ static void clear_dither_context(DitherContext *di)
MEM_freeN(di);
}
-MINLINE float dither_random_value(float s, float t)
-{
- static float vec[2] = {12.9898f, 78.233f};
- float st[2];
- float value;
- copy_v2_fl2(st, s, t);
-
- value = sinf(dot_v2v2(st, vec)) * 43758.5453f;
- return value - floorf(value);
-}
/************************* Generic Buffer Conversion *************************/
@@ -180,8 +169,8 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
float tmp[4];
int x, y;
DitherContext *di = NULL;
- float inv_width = 1.0f / width,
- inv_height = 1.0f / height;
+ float inv_width = 1.0f / width;
+ float inv_height = 1.0f / height;
/* we need valid profiles */
BLI_assert(profile_to != IB_PROFILE_NONE);
diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c
index b6b46c72384..c6e358dd3d2 100644
--- a/source/blender/imbuf/intern/filetype.c
+++ b/source/blender/imbuf/intern/filetype.c
@@ -51,8 +51,6 @@
#include "quicktime_import.h"
#endif
-#include "imbuf.h"
-
static int imb_ftype_default(ImFileType *type, ImBuf *ibuf)
{
return (ibuf->ftype & type->filetype);
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 547a8df4438..d0281744830 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -35,6 +35,7 @@
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_fileops.h"
+#include "BLI_ghash.h"
#include "IMB_indexer.h"
#include "IMB_anim.h"
@@ -1148,19 +1149,64 @@ static void index_rebuild_fallback(FallbackIndexBuilderContext *context,
* ---------------------------------------------------------------------- */
IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecode_Type tcs_in_use,
- IMB_Proxy_Size proxy_sizes_in_use, int quality)
+ IMB_Proxy_Size proxy_sizes_in_use, int quality,
+ const bool overwrite, GSet *file_list)
{
IndexBuildContext *context = NULL;
+ IMB_Proxy_Size proxy_sizes_to_build = proxy_sizes_in_use;
+ int i;
+
+ /* Don't generate the same file twice! */
+ if (file_list) {
+ for (i = 0; i < IMB_PROXY_MAX_SLOT; ++i) {
+ IMB_Proxy_Size proxy_size = proxy_sizes[i];
+ if (proxy_size & proxy_sizes_to_build) {
+ char filename[FILE_MAX];
+ get_proxy_filename(anim, proxy_size, filename, false);
+
+ if (BLI_gset_haskey(file_list, filename)) {
+ proxy_sizes_to_build &= ~proxy_size;
+ printf("Proxy: %s already registered for generation, skipping\n", filename);
+ }
+ else {
+ BLI_gset_insert(file_list, BLI_strdup(filename));
+ }
+ }
+ }
+ }
+
+ if (!overwrite) {
+ IMB_Proxy_Size built_proxies = IMB_anim_proxy_get_existing(anim);
+ if (built_proxies != 0) {
+
+ for (i = 0; i < IMB_PROXY_MAX_SLOT; ++i) {
+ IMB_Proxy_Size proxy_size = proxy_sizes[i];
+ if (proxy_size & built_proxies) {
+ char filename[FILE_MAX];
+ get_proxy_filename(anim, proxy_size, filename, false);
+ printf("Skipping proxy: %s\n", filename);
+ }
+ }
+ }
+ proxy_sizes_to_build &= ~built_proxies;
+ }
+
+ fflush(stdout);
+
+ if (proxy_sizes_to_build == 0) {
+ return NULL;
+ }
+
switch (anim->curtype) {
#ifdef WITH_FFMPEG
case ANIM_FFMPEG:
- context = index_ffmpeg_create_context(anim, tcs_in_use, proxy_sizes_in_use, quality);
+ context = index_ffmpeg_create_context(anim, tcs_in_use, proxy_sizes_to_build, quality);
break;
#endif
#ifdef WITH_AVI
default:
- context = index_fallback_create_context(anim, tcs_in_use, proxy_sizes_in_use, quality);
+ context = index_fallback_create_context(anim, tcs_in_use, proxy_sizes_to_build, quality);
break;
#endif
}
@@ -1170,7 +1216,7 @@ IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecod
return context;
- (void)tcs_in_use, (void)proxy_sizes_in_use, (void)quality;
+ UNUSED_VARS(tcs_in_use, proxy_sizes_in_use, quality);
}
void IMB_anim_index_rebuild(struct IndexBuildContext *context,
@@ -1189,7 +1235,7 @@ void IMB_anim_index_rebuild(struct IndexBuildContext *context,
#endif
}
- (void)stop, (void)do_update, (void)progress;
+ UNUSED_VARS(stop, do_update, progress);
}
void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop)
@@ -1207,8 +1253,8 @@ void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop)
#endif
}
- (void)stop;
- (void)proxy_sizes; /* static defined at top of the file */
+ /* static defined at top of the file */
+ UNUSED_VARS(stop, proxy_sizes);
}
@@ -1237,7 +1283,7 @@ void IMB_free_indices(struct anim *anim)
void IMB_anim_set_index_dir(struct anim *anim, const char *dir)
{
- if (strcmp(anim->index_dir, dir) == 0) {
+ if (STREQ(anim->index_dir, dir)) {
return;
}
BLI_strncpy(anim->index_dir, dir, sizeof(anim->index_dir));
@@ -1304,3 +1350,18 @@ int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc,
return IMB_indexer_get_frame_index(idx, position);
}
+IMB_Proxy_Size IMB_anim_proxy_get_existing(struct anim *anim)
+{
+ const int num_proxy_sizes = IMB_PROXY_MAX_SLOT;
+ IMB_Proxy_Size existing = 0;
+ int i;
+ for (i = 0; i < num_proxy_sizes; ++i) {
+ IMB_Proxy_Size proxy_size = proxy_sizes[i];
+ char filename[FILE_MAX];
+ get_proxy_filename(anim, proxy_size, filename, false);
+ if (BLI_exists(filename)) {
+ existing |= proxy_size;
+ }
+ }
+ return existing;
+}
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index 8f98f240053..ea5acf27e99 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -40,7 +40,6 @@
#include "imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_allocimbuf.h"
#include "IMB_filetype.h"
#include "IMB_colormanagement.h"
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index 18c096450af..8750b825fb6 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -29,11 +29,8 @@
#include "BLI_math.h"
#include "BLI_fileops.h"
-#include "imbuf.h"
-
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_allocimbuf.h"
#include "IMB_filetype.h"
#include "IMB_colormanagement.h"
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index f4b5f987869..310e517e38d 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -37,9 +37,12 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_fileops.h"
+#include "BKE_idprop.h"
+
#include "imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -267,7 +270,7 @@ handle_app1(j_decompress_ptr cinfo)
if (length < 16) {
for (i = 0; i < length; i++) INPUT_BYTE(cinfo, neogeo[i], return false);
length = 0;
- if (strncmp(neogeo, "NeoGeo", 6) == 0) memcpy(&ibuf_ftype, neogeo + 6, 4);
+ if (STREQLEN(neogeo, "NeoGeo", 6)) memcpy(&ibuf_ftype, neogeo + 6, 4);
ibuf_ftype = BIG_LONG(ibuf_ftype);
}
INPUT_SYNC(cinfo); /* do before skip_input_data */
@@ -385,7 +388,7 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
* That is why we need split it to the
* common key/value here.
*/
- if (strncmp(str, "Blender", 7)) {
+ if (!STREQLEN(str, "Blender", 7)) {
/*
* Maybe the file have text that
* we don't know "what it's", in that
@@ -478,7 +481,6 @@ static void write_jpeg(struct jpeg_compress_struct *cinfo, struct ImBuf *ibuf)
uchar *rect;
int x, y;
char neogeo[128];
- ImMetaData *iptr;
char *text;
jpeg_start_compress(cinfo, true);
@@ -490,28 +492,28 @@ static void write_jpeg(struct jpeg_compress_struct *cinfo, struct ImBuf *ibuf)
jpeg_write_marker(cinfo, 0xe1, (JOCTET *) neogeo, 10);
if (ibuf->metadata) {
+ IDProperty *prop;
/* key + max value + "Blender" */
text = MEM_mallocN(530, "stamp info read");
- iptr = ibuf->metadata;
- while (iptr) {
- if (!strcmp(iptr->key, "None")) {
- jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) iptr->value, strlen(iptr->value) + 1);
- goto next_stamp_info;
- }
+ for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_STRING) {
+ int text_len;
+ if (!strcmp(prop->name, "None")) {
+ jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) IDP_String(prop), prop->len + 1);
+ }
- /*
- * The JPEG format don't support a pair "key/value"
- * like PNG, so we "encode" the stamp in a
- * single string:
- * "Blender:key:value"
- *
- * The first "Blender" is a simple identify to help
- * in the read process.
- */
- sprintf(text, "Blender:%s:%s", iptr->key, iptr->value);
- jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) text, strlen(text) + 1);
-next_stamp_info:
- iptr = iptr->next;
+ /*
+ * The JPEG format don't support a pair "key/value"
+ * like PNG, so we "encode" the stamp in a
+ * single string:
+ * "Blender:key:value"
+ *
+ * The first "Blender" is a simple identify to help
+ * in the read process.
+ */
+ text_len = sprintf(text, "Blender:%s:%s", prop->name, IDP_String(prop));
+ jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) text, text_len + 1);
+ }
}
MEM_freeN(text);
}
diff --git a/source/blender/imbuf/intern/metadata.c b/source/blender/imbuf/intern/metadata.c
index 797d34d118b..8cb5070dd62 100644
--- a/source/blender/imbuf/intern/metadata.c
+++ b/source/blender/imbuf/intern/metadata.c
@@ -36,6 +36,8 @@
#include "BLI_utildefines.h"
#include "BLI_string.h"
+#include "BKE_idprop.h"
+
#include "MEM_guardedalloc.h"
#include "IMB_imbuf_types.h"
@@ -47,119 +49,84 @@
void IMB_metadata_free(struct ImBuf *img)
{
- ImMetaData *info;
-
if (!img)
return;
if (!img->metadata) {
return;
}
- info = img->metadata;
- while (info) {
- ImMetaData *next = info->next;
- MEM_freeN(info->key);
- MEM_freeN(info->value);
- MEM_freeN(info);
- info = next;
- }
+
+ IDP_FreeProperty(img->metadata);
+ MEM_freeN(img->metadata);
}
bool IMB_metadata_get_field(struct ImBuf *img, const char *key, char *field, const size_t len)
{
- ImMetaData *info;
+ IDProperty *prop;
+
bool retval = false;
if (!img)
return false;
- if (!img->metadata) {
+ if (!img->metadata)
return false;
- }
- info = img->metadata;
- while (info) {
- if (strcmp(key, info->key) == 0) {
- BLI_strncpy(field, info->value, len);
- retval = true;
- break;
- }
- info = info->next;
+
+ prop = IDP_GetPropertyFromGroup(img->metadata, key);
+
+ if (prop && prop->type == IDP_STRING) {
+ BLI_strncpy(field, IDP_String(prop), len);
+ retval = true;
}
return retval;
}
bool IMB_metadata_add_field(struct ImBuf *img, const char *key, const char *value)
{
- ImMetaData *info;
- ImMetaData *last;
+ IDProperty *prop;
if (!img)
return false;
if (!img->metadata) {
- img->metadata = MEM_callocN(sizeof(ImMetaData), "ImMetaData");
- info = img->metadata;
- }
- else {
- info = img->metadata;
- last = info;
- while (info) {
- last = info;
- info = info->next;
- }
- info = MEM_callocN(sizeof(ImMetaData), "ImMetaData");
- last->next = info;
+ IDPropertyTemplate val;
+ img->metadata = IDP_New(IDP_GROUP, &val, "metadata");
}
- info->key = BLI_strdup(key);
- info->value = BLI_strdup(value);
- return true;
+
+ prop = IDP_NewString(value, key, 512);
+ return IDP_AddToGroup(img->metadata, prop);
}
bool IMB_metadata_del_field(struct ImBuf *img, const char *key)
{
- ImMetaData *p, *p1;
+ IDProperty *prop;
if ((!img) || (!img->metadata))
return false;
- p = img->metadata;
- p1 = NULL;
- while (p) {
- if (!strcmp(key, p->key)) {
- if (p1)
- p1->next = p->next;
- else
- img->metadata = p->next;
-
- MEM_freeN(p->key);
- MEM_freeN(p->value);
- MEM_freeN(p);
- return true;
- }
- p1 = p;
- p = p->next;
+ prop = IDP_GetPropertyFromGroup(img->metadata, key);
+
+ if (prop) {
+ IDP_FreeFromGroup(img->metadata, prop);
}
return false;
}
bool IMB_metadata_change_field(struct ImBuf *img, const char *key, const char *field)
{
- ImMetaData *p;
+ IDProperty *prop;
if (!img)
return false;
- if (!img->metadata)
- return (IMB_metadata_add_field(img, key, field));
+ prop = (img->metadata) ? IDP_GetPropertyFromGroup(img->metadata, key) : NULL;
- p = img->metadata;
- while (p) {
- if (!strcmp(key, p->key)) {
- MEM_freeN(p->value);
- p->value = BLI_strdup(field);
- return true;
- }
- p = p->next;
+ if (!prop) {
+ return (IMB_metadata_add_field(img, key, field));
+ }
+ else if (prop->type == IDP_STRING) {
+ IDP_AssignString(prop, field, 1024);
+ return true;
+ }
+ else {
+ return false;
}
-
- return (IMB_metadata_add_field(img, key, field));
}
-
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index 1641bd3089b..29bb35986e8 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -99,22 +99,22 @@ typedef struct MovieCacheItem {
static unsigned int moviecache_hashhash(const void *keyv)
{
- MovieCacheKey *key = (MovieCacheKey *)keyv;
+ const MovieCacheKey *key = keyv;
return key->cache_owner->hashfp(key->userkey);
}
static bool moviecache_hashcmp(const void *av, const void *bv)
{
- const MovieCacheKey *a = (MovieCacheKey *)av;
- const MovieCacheKey *b = (MovieCacheKey *)bv;
+ const MovieCacheKey *a = av;
+ const MovieCacheKey *b = bv;
return a->cache_owner->cmpfp(a->userkey, b->userkey);
}
static void moviecache_keyfree(void *val)
{
- MovieCacheKey *key = (MovieCacheKey *)val;
+ MovieCacheKey *key = val;
BLI_mempool_free(key->cache_owner->userkeys_pool, key->userkey);
@@ -142,15 +142,16 @@ static void moviecache_valfree(void *val)
static void check_unused_keys(MovieCache *cache)
{
- GHashIterator *iter;
+ GHashIterator gh_iter;
- iter = BLI_ghashIterator_new(cache->hash);
- while (!BLI_ghashIterator_done(iter)) {
- MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
- MovieCacheItem *item = BLI_ghashIterator_getValue(iter);
- int remove = 0;
+ BLI_ghashIterator_init(&gh_iter, cache->hash);
+
+ while (!BLI_ghashIterator_done(&gh_iter)) {
+ MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
+ MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
+ bool remove;
- BLI_ghashIterator_step(iter);
+ BLI_ghashIterator_step(&gh_iter);
remove = !item->ibuf;
@@ -161,14 +162,12 @@ static void check_unused_keys(MovieCache *cache)
if (remove)
BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
}
-
- BLI_ghashIterator_free(iter);
}
static int compare_int(const void *av, const void *bv)
{
- const int *a = (int *)av;
- const int *b = (int *)bv;
+ const int *a = av;
+ const int *b = bv;
return *a - *b;
}
@@ -363,8 +362,7 @@ static void do_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf, boo
item->priority_data = cache->getprioritydatafp(userkey);
}
- BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
- BLI_ghash_insert(cache->hash, key, item);
+ BLI_ghash_reinsert(cache->hash, key, item, moviecache_keyfree, moviecache_valfree);
if (cache->last_userkey) {
memcpy(cache->last_userkey, userkey, cache->keysize);
@@ -474,16 +472,17 @@ void IMB_moviecache_free(MovieCache *cache)
void IMB_moviecache_cleanup(MovieCache *cache, bool (cleanup_check_cb) (ImBuf *ibuf, void *userkey, void *userdata), void *userdata)
{
- GHashIterator *iter;
+ GHashIterator gh_iter;
check_unused_keys(cache);
- iter = BLI_ghashIterator_new(cache->hash);
- while (!BLI_ghashIterator_done(iter)) {
- MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
- MovieCacheItem *item = BLI_ghashIterator_getValue(iter);
+ BLI_ghashIterator_init(&gh_iter, cache->hash);
+
+ while (!BLI_ghashIterator_done(&gh_iter)) {
+ MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
+ MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
- BLI_ghashIterator_step(iter);
+ BLI_ghashIterator_step(&gh_iter);
if (cleanup_check_cb(item->ibuf, key->userkey, userdata)) {
PRINT("%s: cache '%s' remove item %p\n", __func__, cache->name, item);
@@ -491,8 +490,6 @@ void IMB_moviecache_cleanup(MovieCache *cache, bool (cleanup_check_cb) (ImBuf *i
BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
}
}
-
- BLI_ghashIterator_free(iter);
}
/* get segments of cached frames. useful for debugging cache policies */
@@ -519,13 +516,12 @@ void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_
int totframe = BLI_ghash_size(cache->hash);
int *frames = MEM_callocN(totframe * sizeof(int), "movieclip cache frames");
int a, totseg = 0;
- GHashIterator *iter;
+ GHashIterator gh_iter;
- iter = BLI_ghashIterator_new(cache->hash);
a = 0;
- while (!BLI_ghashIterator_done(iter)) {
- MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
- MovieCacheItem *item = BLI_ghashIterator_getValue(iter);
+ GHASH_ITER(gh_iter, cache->hash) {
+ MovieCacheKey *key = BLI_ghashIterator_getKey(&gh_iter);
+ MovieCacheItem *item = BLI_ghashIterator_getValue(&gh_iter);
int framenr, curproxy, curflags;
if (item->ibuf) {
@@ -534,12 +530,8 @@ void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_
if (curproxy == proxy && curflags == render_flags)
frames[a++] = framenr;
}
-
- BLI_ghashIterator_step(iter);
}
- BLI_ghashIterator_free(iter);
-
qsort(frames, totframe, sizeof(int), compare_int);
/* count */
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index ba1bda640a6..45eae89ad9d 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -38,6 +38,8 @@
#include <errno.h>
#include <algorithm>
+#include "DNA_scene_types.h" /* For OpenEXR compression constants */
+
#include <openexr_api.h>
#if defined (WIN32) && !defined(FREE_WINDOWS)
@@ -60,6 +62,8 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
#include "BLI_math_color.h"
#include "BLI_threads.h"
+#include "BKE_idprop.h"
+
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_allocimbuf.h"
@@ -282,21 +286,38 @@ int imb_is_a_openexr(unsigned char *mem)
static void openexr_header_compression(Header *header, int compression)
{
switch (compression) {
- case 0:
+ case R_IMF_EXR_CODEC_NONE:
header->compression() = NO_COMPRESSION;
break;
- case 1:
+ case R_IMF_EXR_CODEC_PXR24:
header->compression() = PXR24_COMPRESSION;
break;
- case 2:
+ case R_IMF_EXR_CODEC_ZIP:
header->compression() = ZIP_COMPRESSION;
break;
- case 3:
+ case R_IMF_EXR_CODEC_PIZ:
header->compression() = PIZ_COMPRESSION;
break;
- case 4:
+ case R_IMF_EXR_CODEC_RLE:
header->compression() = RLE_COMPRESSION;
break;
+ case R_IMF_EXR_CODEC_ZIPS:
+ header->compression() = ZIPS_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_B44:
+ header->compression() = B44_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_B44A:
+ header->compression() = B44A_COMPRESSION;
+ break;
+#if OPENEXR_VERSION_MAJOR >= 2 && OPENEXR_VERSION_MINOR >= 2
+ case R_IMF_EXR_CODEC_DWAA:
+ header->compression() = DWAA_COMPRESSION;
+ break;
+ case R_IMF_EXR_CODEC_DWAB:
+ header->compression() = DWAB_COMPRESSION;
+ break;
+#endif
default:
header->compression() = ZIP_COMPRESSION;
break;
@@ -305,10 +326,15 @@ static void openexr_header_compression(Header *header, int compression)
static void openexr_header_metadata(Header *header, struct ImBuf *ibuf)
{
- ImMetaData *info;
+ if (ibuf->metadata) {
+ IDProperty *prop;
- for (info = ibuf->metadata; info; info = info->next)
- header->insert(info->key, StringAttribute(info->value));
+ for (prop = (IDProperty *)ibuf->metadata->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_STRING) {
+ header->insert(prop->name, StringAttribute(IDP_String(prop)));
+ }
+ }
+ }
if (ibuf->ppm[0] > 0.0)
addXDensity(*header, ibuf->ppm[0] / 39.3700787); /* 1 meter = 39.3700787 inches */
@@ -784,7 +810,7 @@ void IMB_exr_read_channels(void *handle)
/* check if exr was saved with previous versions of blender which flipped images */
const StringAttribute *ta = data->ifile->header().findTypedAttribute <StringAttribute> ("BlenderMultiChannel");
- short flip = (ta && strncmp(ta->value().c_str(), "Blender V2.43", 13) == 0); /* 'previous multilayer attribute, flipped */
+ short flip = (ta && STREQLEN(ta->value().c_str(), "Blender V2.43", 13)); /* 'previous multilayer attribute, flipped */
for (echan = (ExrChannel *)data->channels.first; echan; echan = echan->next) {
@@ -982,7 +1008,7 @@ static ExrPass *imb_exr_get_pass(ListBase *lb, char *passname)
if (pass == NULL) {
pass = (ExrPass *)MEM_callocN(sizeof(ExrPass), "exr pass");
- if (strcmp(passname, "Combined") == 0)
+ if (STREQ(passname, "Combined"))
BLI_addhead(lb, pass);
else
BLI_addtail(lb, pass);
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index d00a836667e..683bdabcd6c 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -38,11 +38,10 @@
#include "BLI_math.h"
#include "BKE_global.h"
+#include "BKE_idprop.h"
#include "MEM_guardedalloc.h"
-#include "imbuf.h"
-
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -399,24 +398,25 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
/* image text info */
if (ibuf->metadata) {
png_text *metadata;
- ImMetaData *iptr;
+ IDProperty *prop;
+
int num_text = 0;
- iptr = ibuf->metadata;
- while (iptr) {
- num_text++;
- iptr = iptr->next;
+
+ for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_STRING) {
+ num_text++;
+ }
}
metadata = MEM_callocN(num_text * sizeof(png_text), "png_metadata");
- iptr = ibuf->metadata;
num_text = 0;
- while (iptr) {
-
- metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
- metadata[num_text].key = iptr->key;
- metadata[num_text].text = iptr->value;
- num_text++;
- iptr = iptr->next;
+ for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
+ if (prop->type == IDP_STRING) {
+ metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
+ metadata[num_text].key = prop->name;
+ metadata[num_text].text = IDP_String(prop);
+ num_text++;
+ }
}
png_set_text(png_ptr, info_ptr, metadata, num_text);
@@ -492,7 +492,7 @@ static void imb_png_warning(png_structp UNUSED(png_ptr), png_const_charp message
* and with new libpng it became too much picky, giving a warning on
* the splash screen even.
*/
- if ((G.debug & G_DEBUG) == 0 && !strncmp(message, "iCCP", 4)) {
+ if ((G.debug & G_DEBUG) == 0 && STREQLEN(message, "iCCP", 4)) {
return;
}
fprintf(stderr, "libpng warning: %s\n", message);
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index db268546480..318bb7e96e3 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -38,7 +38,7 @@
*/
#ifdef WIN32
-# include <io.h>
+# include "BLI_utildefines.h"
#endif
#include "MEM_guardedalloc.h"
@@ -72,10 +72,13 @@ typedef float fCOLOR[3];
#define COPY_RGBE(c1, c2) (c2[RED] = c1[RED], c2[GRN] = c1[GRN], c2[BLU] = c1[BLU], c2[EXP] = c1[EXP])
/* read routines */
-static unsigned char *oldreadcolrs(RGBE *scan, unsigned char *mem, int xmax)
+static unsigned char *oldreadcolrs(RGBE *scan, unsigned char *mem, int xmax, unsigned char *mem_eof)
{
int i, rshift = 0, len = xmax;
while (len > 0) {
+ if (mem_eof - mem < 4) {
+ return NULL;
+ }
scan[0][RED] = *mem++;
scan[0][GRN] = *mem++;
scan[0][BLU] = *mem++;
@@ -97,34 +100,62 @@ static unsigned char *oldreadcolrs(RGBE *scan, unsigned char *mem, int xmax)
return mem;
}
-static unsigned char *freadcolrs(RGBE *scan, unsigned char *mem, int xmax)
+static unsigned char *freadcolrs(RGBE *scan, unsigned char *mem, int xmax, unsigned char *mem_eof)
{
int i, j, code, val;
- if ((xmax < MINELEN) | (xmax > MAXELEN)) return oldreadcolrs(scan, mem, xmax);
+ if (mem_eof - mem < 4) {
+ return NULL;
+ }
+
+ if ((xmax < MINELEN) | (xmax > MAXELEN)) {
+ return oldreadcolrs(scan, mem, xmax, mem_eof);
+ }
i = *mem++;
- if (i != 2) return oldreadcolrs(scan, mem - 1, xmax);
+ if (i != 2) {
+ return oldreadcolrs(scan, mem - 1, xmax, mem_eof);
+ }
scan[0][GRN] = *mem++;
scan[0][BLU] = *mem++;
i = *mem++;
- if (((scan[0][BLU] << 8) | i) != xmax) return NULL;
- for (i = 0; i < 4; i++)
+ if (scan[0][GRN] != 2 || scan[0][BLU] & 128) {
+ scan[0][RED] = 2;
+ scan[0][EXP] = i;
+ return oldreadcolrs(scan + 1, mem, xmax - 1, mem_eof);
+ }
+
+ if (((scan[0][BLU] << 8) | i) != xmax) {
+ return NULL;
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (mem_eof - mem < 2) {
+ return NULL;
+ }
for (j = 0; j < xmax; ) {
code = *mem++;
if (code > 128) {
code &= 127;
val = *mem++;
- while (code--)
+ while (code--) {
scan[j++][i] = (unsigned char)val;
+ }
}
- else
- while (code--)
+ else {
+ if (mem_eof - mem < code) {
+ return NULL;
+ }
+ while (code--) {
scan[j++][i] = *mem++;
+ }
+ }
}
+ }
+
return mem;
}
@@ -182,7 +213,7 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags, char color
int found = 0;
int width = 0, height = 0;
int x, y;
- unsigned char *ptr;
+ unsigned char *ptr, *mem_eof = mem + size;
char oriY[80], oriX[80];
if (imb_is_a_hdr((void *)mem)) {
@@ -218,15 +249,14 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, size_t size, int flags, char color
if (flags & IB_test) return ibuf;
/* read in and decode the actual data */
- sline = (RGBE *)MEM_mallocN(sizeof(RGBE) * width, "radhdr_read_tmpscan");
+ sline = (RGBE *)MEM_mallocN(sizeof(*sline) * width, __func__);
rect_float = ibuf->rect_float;
for (y = 0; y < height; y++) {
- ptr = freadcolrs(sline, ptr, width);
+ ptr = freadcolrs(sline, ptr, width, mem_eof);
if (ptr == NULL) {
- printf("HDR decode error\n");
- MEM_freeN(sline);
- return ibuf;
+ printf("WARNING! HDR decode error, image may be just truncated, or completely wrong...\n");
+ break;
}
for (x = 0; x < width; x++) {
/* convert to ldr */
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index dd2406e234e..4001b681ad9 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -39,11 +39,9 @@
#include "BLI_math_color_blend.h"
#include "BLI_math_vector.h"
-#include "imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_allocimbuf.h"
#include "IMB_colormanagement.h"
void IMB_blend_color_byte(unsigned char dst[4], unsigned char src1[4], unsigned char src2[4], IMB_BlendMode mode)
diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c
index e98757883be..886944f6190 100644
--- a/source/blender/imbuf/intern/rotate.c
+++ b/source/blender/imbuf/intern/rotate.c
@@ -39,8 +39,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_allocimbuf.h"
-
void IMB_flipy(struct ImBuf *ibuf)
{
int x, y;
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index e480f06da2b..2601fe62c2f 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -33,7 +33,6 @@
#include "BLI_utildefines.h"
-#include "BLI_math_base.h"
#include "BLI_math_color.h"
#include "BLI_math_interp.h"
#include "MEM_guardedalloc.h"
@@ -42,7 +41,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_allocimbuf.h"
#include "IMB_filter.h"
#include "BLI_sys_types.h" // for intptr_t support
diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c
index 2dcb27a05d4..70b71ec4182 100644
--- a/source/blender/imbuf/intern/targa.c
+++ b/source/blender/imbuf/intern/targa.c
@@ -44,7 +44,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_allocimbuf.h"
#include "IMB_filetype.h"
#include "IMB_colormanagement.h"
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index 9a97a142198..118f0405303 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -30,12 +30,13 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
-#include "BLI_md5.h"
+#include "BLI_hash_md5.h"
#include "BLI_system.h"
#include BLI_SYSTEM_PID_H
@@ -243,9 +244,9 @@ static void thumbname_from_uri(const char *uri, char *thumb, const int thumb_len
char hexdigest[33];
unsigned char digest[16];
- md5_buffer(uri, strlen(uri), digest);
+ BLI_hash_md5_buffer(uri, strlen(uri), digest);
hexdigest[0] = '\0';
- BLI_snprintf(thumb, thumb_len, "%s.png", md5_to_hexdigest(digest, hexdigest));
+ BLI_snprintf(thumb, thumb_len, "%s.png", BLI_hash_md5_to_hexdigest(digest, hexdigest));
// printf("%s: '%s' --> '%s'\n", __func__, uri, thumb);
}
@@ -342,8 +343,9 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im
}
if (img != NULL) {
- BLI_stat(path, &info);
- BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime);
+ if (BLI_stat(path, &info) != -1) {
+ BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime);
+ }
BLI_snprintf(cwidth, sizeof(cwidth), "%d", img->x);
BLI_snprintf(cheight, sizeof(cheight), "%d", img->y);
}
@@ -362,8 +364,9 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im
}
IMB_free_anim(anim);
}
- BLI_stat(path, &info);
- BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime);
+ if (BLI_stat(path, &info) != -1) {
+ BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime);
+ }
}
if (!img) return NULL;
@@ -460,7 +463,7 @@ ImBuf *IMB_thumb_manage(const char *path, ThumbSize size, ThumbSource source)
BLI_stat_t st;
ImBuf *img = NULL;
- if (BLI_stat(path, &st)) {
+ if (BLI_stat(path, &st) == -1) {
return NULL;
}
if (!uri_from_filename(path, uri)) {
diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c
index 73ced4095f9..aee465c49cc 100644
--- a/source/blender/imbuf/intern/thumbs_blend.c
+++ b/source/blender/imbuf/intern/thumbs_blend.c
@@ -29,8 +29,6 @@
#include "zlib.h"
-#include "MEM_guardedalloc.h"
-
#include "BLI_utildefines.h"
#include "BLI_endian_switch.h"
#include "BLI_fileops.h"
@@ -57,7 +55,7 @@ static ImBuf *loadblend_thumb(gzFile gzfile)
/* read the blend file header */
if (gzread(gzfile, buf, 12) != 12)
return NULL;
- if (strncmp(buf, "BLENDER", 7))
+ if (!STREQLEN(buf, "BLENDER", 7))
return NULL;
if (buf[7] == '-')
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index eb8f94cbc6e..4d58642e9c4 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -53,9 +53,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "IMB_allocimbuf.h"
#include "IMB_filetype.h"
-#include "IMB_filter.h"
#include "IMB_colormanagement.h"
#include "IMB_colormanagement_intern.h"
@@ -311,8 +309,8 @@ int imb_is_a_tiff(unsigned char *mem)
char big_endian[IMB_TIFF_NCB] = { 0x4d, 0x4d, 0x00, 0x2a };
char lil_endian[IMB_TIFF_NCB] = { 0x49, 0x49, 0x2a, 0x00 };
- return ( (memcmp(big_endian, mem, IMB_TIFF_NCB) == 0) ||
- (memcmp(lil_endian, mem, IMB_TIFF_NCB) == 0) );
+ return ((memcmp(big_endian, mem, IMB_TIFF_NCB) == 0) ||
+ (memcmp(lil_endian, mem, IMB_TIFF_NCB) == 0));
}
static void scanline_contig_16bit(float *rectf, const unsigned short *sbuf, int scanline_w, int spp)
@@ -596,7 +594,7 @@ ImBuf *imb_loadtiff(unsigned char *mem, size_t size, int flags, char colorspace[
format = NULL;
TIFFGetField(image, TIFFTAG_PIXAR_TEXTUREFORMAT, &format);
- if (format && strcmp(format, "Plain Texture") == 0 && TIFFIsTiled(image)) {
+ if (format && STREQ(format, "Plain Texture") && TIFFIsTiled(image)) {
int numlevel = TIFFNumberOfDirectories(image);
/* create empty mipmap levels in advance */
diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c
index d4a9bf7dc09..087330d10d2 100644
--- a/source/blender/imbuf/intern/writeimage.c
+++ b/source/blender/imbuf/intern/writeimage.c
@@ -41,8 +41,6 @@
#include "IMB_colormanagement.h"
#include "IMB_colormanagement_intern.h"
-#include "imbuf.h"
-
static ImBuf *prepare_write_imbuf(ImFileType *type, ImBuf *ibuf)
{
ImBuf *write_ibuf = ibuf;
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 33d1445fb93..b51b53cc801 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -44,54 +44,65 @@ struct FileData;
struct ID;
struct PackedFile;
struct GPUTexture;
-
+
typedef struct IDPropertyData {
void *pointer;
ListBase group;
- int val, val2; /*note, we actually fit a double into these two ints*/
+ int val, val2; /* note, we actually fit a double into these two ints */
} IDPropertyData;
typedef struct IDProperty {
struct IDProperty *next, *prev;
char type, subtype;
short flag;
- char name[64]; /* MAX_IDPROP_NAME */
- int saved; /* saved is used to indicate if this struct has been saved yet.
- * seemed like a good idea as a pad var was needed anyway :)*/
- IDPropertyData data; /* note, alignment for 64 bits */
- int len; /* array length, also (this is important!) string length + 1.
- * the idea is to be able to reuse array realloc functions on strings.*/
+ char name[64]; /* MAX_IDPROP_NAME */
+
+ /* saved is used to indicate if this struct has been saved yet.
+ * seemed like a good idea as a pad var was needed anyway :) */
+ int saved;
+ IDPropertyData data; /* note, alignment for 64 bits */
+
+ /* array length, also (this is important!) string length + 1.
+ * the idea is to be able to reuse array realloc functions on strings.*/
+ int len;
+
+ /* Strings and arrays are both buffered, though the buffer isn't saved. */
/* totallen is total length of allocated array/string, including a buffer.
- * Note that the buffering is mild; the code comes from python's list implementation.*/
- int totallen; /*strings and arrays are both buffered, though the buffer isn't saved.*/
+ * Note that the buffering is mild; the code comes from python's list implementation. */
+ int totallen;
} IDProperty;
-#define MAX_IDPROP_NAME 64
-#define DEFAULT_ALLOC_FOR_NULL_STRINGS 64
+#define MAX_IDPROP_NAME 64
+#define DEFAULT_ALLOC_FOR_NULL_STRINGS 64
/*->type*/
-#define IDP_STRING 0
-#define IDP_INT 1
-#define IDP_FLOAT 2
-#define IDP_ARRAY 5
-#define IDP_GROUP 6
-/* the ID link property type hasn't been implemented yet, this will require
- * some cleanup of blenkernel, most likely.*/
-#define IDP_ID 7
-#define IDP_DOUBLE 8
-#define IDP_IDPARRAY 9
-#define IDP_NUMTYPES 10
+enum {
+ IDP_STRING = 0,
+ IDP_INT = 1,
+ IDP_FLOAT = 2,
+ IDP_ARRAY = 5,
+ IDP_GROUP = 6,
+ /* the ID link property type hasn't been implemented yet, this will require
+ * some cleanup of blenkernel, most likely. */
+ IDP_ID = 7,
+ IDP_DOUBLE = 8,
+ IDP_IDPARRAY = 9,
+ IDP_NUMTYPES = 10,
+};
/*->subtype */
/* IDP_STRING */
-#define IDP_STRING_SUB_UTF8 0 /* default */
-#define IDP_STRING_SUB_BYTE 1 /* arbitrary byte array, _not_ null terminated */
-/*->flag*/
-#define IDP_FLAG_GHOST (1<<7) /* this means the property is set but RNA will return
- * false when checking 'RNA_property_is_set',
- * currently this is a runtime flag */
+enum {
+ IDP_STRING_SUB_UTF8 = 0, /* default */
+ IDP_STRING_SUB_BYTE = 1, /* arbitrary byte array, _not_ null terminated */
+};
+/*->flag*/
+enum {
+ IDP_FLAG_GHOST = 1 << 7, /* this means the property is set but RNA will return false when checking
+ * 'RNA_property_is_set', currently this is a runtime flag */
+};
/* add any future new id property types here.*/
@@ -102,7 +113,7 @@ typedef struct IDProperty {
* */
/* 2 characters for ID code and 64 for actual name */
-#define MAX_ID_NAME 66
+#define MAX_ID_NAME 66
/* There's a nasty circular dependency here.... 'void *' to the rescue! I
* really wonder why this is needed. */
@@ -129,14 +140,14 @@ typedef struct Library {
ID id;
ID *idblock;
struct FileData *filedata;
- char name[1024]; /* path name used for reading, can be relative and edited in the outliner */
- char filepath[1024]; /* absolute filepath, this is only for convenience,
- * 'name' is the real path used on file read but in
- * some cases its useful to access the absolute one,
- * This is set on file read.
- * Use BKE_library_filepath_set() rather than
- * setting 'name' directly and it will be kept in
- * sync - campbell */
+ char name[1024]; /* path name used for reading, can be relative and edited in the outliner */
+
+ /* absolute filepath, this is only for convenience, 'name' is the real path used on file read but in
+ * some cases its useful to access the absolute one.
+ * This is set on file read.
+ * Use BKE_library_filepath_set() rather than setting 'name' directly and it will be kept in sync - campbell */
+ char filepath[1024];
+
struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */
struct PackedFile *packedfile;
@@ -232,33 +243,36 @@ typedef struct PreviewImage {
#ifdef GS
# undef GS
#endif
-// #define GS(a) (*((short *)(a)))
-#define GS(a) (CHECK_TYPE_INLINE(a, char *), (*((short *)(a))))
+#define GS(a) (CHECK_TYPE_ANY(a, char *, const char *, char [66], const char[66]), (*((const short *)(a))))
#define ID_NEW(a) if ( (a) && (a)->id.newid ) (a) = (void *)(a)->id.newid
#define ID_NEW_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; }
#define ID_NEW_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; }
-/* id->flag: set frist 8 bits always at zero while reading */
-#define LIB_LOCAL 0
-#define LIB_EXTERN 1
-#define LIB_INDIRECT 2
-#define LIB_NEED_EXPAND 8
-#define LIB_TESTEXT (LIB_NEED_EXPAND | LIB_EXTERN)
-#define LIB_TESTIND (LIB_NEED_EXPAND | LIB_INDIRECT)
-#define LIB_READ 16
-#define LIB_NEED_LINK 32
-
-#define LIB_NEW 256
-#define LIB_FAKEUSER 512
-/* free test flag */
-#define LIB_DOIT 1024
-/* tag existing data before linking so we know what is new */
-#define LIB_PRE_EXISTING 2048
-/* runtime */
-#define LIB_ID_RECALC 4096
-#define LIB_ID_RECALC_DATA 8192
-#define LIB_ANIM_NO_RECALC 16384
+/* id->flag: set first 8 bits always at zero while reading */
+enum {
+ LIB_LOCAL = 0,
+ LIB_EXTERN = 1 << 0,
+ LIB_INDIRECT = 1 << 1,
+ LIB_NEED_EXPAND = 1 << 3,
+ LIB_TESTEXT = (LIB_NEED_EXPAND | LIB_EXTERN),
+ LIB_TESTIND = (LIB_NEED_EXPAND | LIB_INDIRECT),
+ LIB_READ = 1 << 4,
+ LIB_NEED_LINK = 1 << 5,
+
+ LIB_NEW = 1 << 8,
+ LIB_FAKEUSER = 1 << 9,
+ /* free test flag */
+ LIB_DOIT = 1 << 10,
+ /* tag existing data before linking so we know what is new */
+ LIB_PRE_EXISTING = 1 << 11,
+ /* runtime */
+ LIB_ID_RECALC = 1 << 12,
+ LIB_ID_RECALC_DATA = 1 << 13,
+ LIB_ANIM_NO_RECALC = 1 << 14,
+
+ LIB_ID_RECALC_ALL = (LIB_ID_RECALC|LIB_ID_RECALC_DATA),
+};
#ifdef __cplusplus
}
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index dab825c856e..7b331181a58 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -250,6 +250,7 @@ typedef enum ePchan_Flag {
POSE_ROT = (1 << 1),
POSE_SIZE = (1 << 2),
/* old IK/cache stuff... */
+#if 0
POSE_IK_MAT = (1 << 3),
POSE_UNUSED2 = (1 << 4),
POSE_UNUSED3 = (1 << 5),
@@ -257,6 +258,7 @@ typedef enum ePchan_Flag {
POSE_UNUSED5 = (1 << 7),
/* has Standard IK */
POSE_HAS_IK = (1 << 8),
+#endif
/* IK/Pose solving*/
POSE_CHAIN = (1 << 9),
POSE_DONE = (1 << 10),
@@ -265,8 +267,10 @@ typedef enum ePchan_Flag {
POSE_STRIDE = (1 << 12),
/* standard IK solving */
POSE_IKTREE = (1 << 13),
+#if 0
/* has Spline IK */
POSE_HAS_IKS = (1 << 14),
+#endif
/* spline IK solving */
POSE_IKSPLINE = (1 << 15)
} ePchan_Flag;
@@ -487,7 +491,7 @@ typedef struct bAction {
ID id; /* ID-serialisation for relinking */
ListBase curves; /* function-curves (FCurve) */
- ListBase chanbase; /* legacy data - Action Channels (bActionChannel) in pre-2.5 animation system */
+ ListBase chanbase DNA_DEPRECATED; /* legacy data - Action Channels (bActionChannel) in pre-2.5 animation system */
ListBase groups; /* groups of function-curves (bActionGroup) */
ListBase markers; /* markers local to the Action (used to provide Pose-Libraries) */
@@ -541,7 +545,7 @@ typedef enum eDopeSheet_FilterFlag {
ADS_FILTER_ONLYNLA = (1 << 2), /* for 'NLA' editor - only include NLA data from AnimData */
ADS_FILTER_SELEDIT = (1 << 3), /* for Graph Editor - used to indicate whether to include a filtering flag or not */
- /* general filtering 2 */
+ /* general filtering */
ADS_FILTER_SUMMARY = (1 << 4), /* for 'DopeSheet' Editors - include 'summary' line */
ADS_FILTER_ONLYOBGROUP = (1 << 5), /* only the objects in the specified object group get used */
@@ -564,6 +568,8 @@ typedef enum eDopeSheet_FilterFlag {
ADS_FILTER_NOSPK = (1 << 21),
ADS_FILTER_NOLINESTYLE = (1 << 22),
ADS_FILTER_NOMODIFIERS = (1 << 23),
+ ADS_FILTER_NOGPENCIL = (1 << 24),
+ /* NOTE: all new datablock filters will have to go in filterflag2 (see below) */
/* NLA-specific filters */
ADS_FILTER_NLA_NOACT = (1 << 25), /* if the AnimData block has no NLA data, don't include to just show Action-line */
@@ -581,6 +587,8 @@ typedef enum eDopeSheet_FilterFlag {
typedef enum eDopeSheet_Flag {
ADS_FLAG_SUMMARY_COLLAPSED = (1 << 0), /* when summary is shown, it is collapsed, so all other channels get hidden */
ADS_FLAG_SHOW_DBFILTERS = (1 << 1) /* show filters for datablocks */
+
+ /* NOTE: datablock filter flags continued (1 << 10) onwards... */
} eDopeSheet_Flag;
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index dcde9007cd8..9af0c1dac10 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -57,7 +57,7 @@ typedef struct bActionActuator {
short blendin; /* Number of frames of blending */
short priority; /* Execution priority */
short layer; /* Animation layer */
- short end_reset; /* Ending the actuator (negative pulse) wont reset the the action to its starting frame */
+ short end_reset; /* Ending the actuator (negative pulse) wont reset the action to its starting frame */
short strideaxis; /* Displacement axis */
short blend_mode; /* Layer blending mode */
float stridelength; /* Displacement incurred by cycle */ // not in use
@@ -570,6 +570,7 @@ typedef struct bActuator {
#define ACT_STEERING_ENABLEVISUALIZATION 2
#define ACT_STEERING_AUTOMATICFACING 4
#define ACT_STEERING_NORMALUP 8
+#define ACT_STEERING_LOCKZVEL 16
/* mouseactuator->type */
#define ACT_MOUSE_VISIBILITY 0
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 3d0d6b820d7..9e6b71fcbac 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -719,13 +719,13 @@ typedef struct KS_Path {
int idtype; /* ID-type that path can be used on */
short groupmode; /* group naming (eKSP_Grouping) */
- short pad;
+ short flag; /* various settings, etc. */
char *rna_path; /* dynamically (or statically in the case of predefined sets) path */
int array_index; /* index that path affects */
- short flag; /* various settings, etc. */
- short keyingflag; /* settings to supply insertkey() with */
+ short keyingflag; /* (eInsertKeyFlags) settings to supply insertkey() with */
+ short keyingoverride; /* (eInsertKeyFlags) for each flag set, the relevant keyingflag bit overrides the default */
} KS_Path;
/* KS_Path->flag */
@@ -770,10 +770,14 @@ typedef struct KeyingSet {
char description[240]; /* (RNA_DYN_DESCR_MAX) short help text. */
char typeinfo[64]; /* name of the typeinfo data used for the relative paths */
+ int active_path; /* index of the active path */
+
short flag; /* settings for KeyingSet */
- short keyingflag; /* settings to supply insertkey() with */
- int active_path; /* index of the active path */
+ short keyingflag; /* (eInsertKeyFlags) settings to supply insertkey() with */
+ short keyingoverride; /* (eInsertKeyFlags) for each flag set, the relevant keyingflag bit overrides the default */
+
+ char pad[6];
} KeyingSet;
/* KeyingSet settings */
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index b6d4a8c9db8..6b7e70f454b 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -188,7 +188,7 @@ typedef enum eBone_Flag {
BONE_SELECTED = (1 << 0),
BONE_ROOTSEL = (1 << 1),
BONE_TIPSEL = (1 << 2),
- BONE_TRANSFORM = (1 << 3), /* Used instead of BONE_SELECTED during transform */
+ BONE_TRANSFORM = (1 << 3), /* Used instead of BONE_SELECTED during transform (clear before use) */
BONE_CONNECTED = (1 << 4), /* when bone has a parent, connect head of bone to parent's tail*/
/* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */
BONE_HIDDEN_P = (1 << 6), /* hidden Bones when drawing PoseChannels */
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index b14861fcf47..89c8316002b 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -93,7 +93,7 @@ typedef struct Brush {
float plane_offset; /* offset for plane brushes (clay, flatten, fill, scrape) */
- float pad;
+ int flag2;
int gradient_spacing;
int gradient_stroke_mode; /* source for stroke color gradient application */
int gradient_fill_mode; /* source for fill tool color gradient application */
@@ -102,7 +102,7 @@ typedef struct Brush {
char vertexpaint_tool; /* active vertex/weight paint blend mode (poorly named) */
char imagepaint_tool; /* active image paint tool */
char mask_tool; /* enum BrushMaskTool, only used if sculpt_tool is SCULPT_TOOL_MASK */
-
+
float autosmooth_factor;
float crease_pinch_factor;
@@ -192,7 +192,7 @@ typedef enum BrushFlags {
BRUSH_JITTER_PRESSURE = (1 << 4),
BRUSH_SPACING_PRESSURE = (1 << 5),
BRUSH_UNUSED = (1 << 6),
- BRUSH_RAKE = (1 << 7),
+// BRUSH_RAKE = (1 << 7), deprecated, use brush_angle_mode
BRUSH_ANCHORED = (1 << 8),
BRUSH_DIR_IN = (1 << 9),
BRUSH_SPACE = (1 << 10),
@@ -209,7 +209,7 @@ typedef enum BrushFlags {
BRUSH_EDGE_TO_EDGE = (1 << 22),
BRUSH_DRAG_DOT = (1 << 23),
BRUSH_INVERSE_SMOOTH_PRESSURE = (1 << 24),
- BRUSH_RANDOM_ROTATION = (1 << 25),
+// BRUSH_RANDOM_ROTATION = (1 << 25), deprecated, use brush_angle_mode
BRUSH_PLANE_TRIM = (1 << 26),
BRUSH_FRONTFACE = (1 << 27),
BRUSH_CUSTOM_ICON = (1 << 28),
diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h
index c99494ce00e..c67a356a708 100644
--- a/source/blender/makesdna/DNA_camera_types.h
+++ b/source/blender/makesdna/DNA_camera_types.h
@@ -33,7 +33,7 @@
#define __DNA_CAMERA_TYPES_H__
#include "DNA_defs.h"
-
+#include "DNA_gpu_types.h"
#include "DNA_ID.h"
#ifdef __cplusplus
@@ -56,7 +56,7 @@ typedef struct Camera {
float lens, ortho_scale, drawsize;
float sensor_x, sensor_y;
float shiftx, shifty;
-
+
/* yafray: dof params */
/* qdn: yafray var 'YF_dofdist' now enabled for defocus composite node as well.
* The name was not changed so that no other files need to be modified */
@@ -65,6 +65,7 @@ typedef struct Camera {
struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */
struct Object *dof_ob;
+ struct GPUDOFSettings gpu_dof;
char sensor_fit;
char pad[7];
@@ -96,12 +97,13 @@ enum {
CAM_SHOWLIMITS = (1 << 0),
CAM_SHOWMIST = (1 << 1),
CAM_SHOWPASSEPARTOUT = (1 << 2),
- CAM_SHOWTITLESAFE = (1 << 3),
+ CAM_SHOW_SAFE_MARGINS = (1 << 3),
CAM_SHOWNAME = (1 << 4),
CAM_ANGLETOGGLE = (1 << 5),
CAM_DS_EXPAND = (1 << 6),
CAM_PANORAMA = (1 << 7), /* deprecated */
CAM_SHOWSENSOR = (1 << 8),
+ CAM_SHOW_SAFE_CENTER = (1 << 9),
};
#if (DNA_DEPRECATED_GCC_POISON == 1)
diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h
index 6c7d500e4e2..07bc2478837 100644
--- a/source/blender/makesdna/DNA_cloth_types.h
+++ b/source/blender/makesdna/DNA_cloth_types.h
@@ -32,6 +32,8 @@
#ifndef __DNA_CLOTH_TYPES_H__
#define __DNA_CLOTH_TYPES_H__
+#include "DNA_defs.h"
+
/**
* This struct contains all the global data required to run a simulation.
* At the time of this writing, this structure contains data appropriate
@@ -69,14 +71,23 @@ typedef struct ClothSimSettings {
float goalspring;
float goalfrict;
float velocity_smooth; /* smoothing of velocities for hair */
+ float density_target; /* minimum density for hair */
+ float density_strength; /* influence of hair density */
float collider_friction; /* friction with colliders */
float vel_damping; /* damp the velocity to speed up getting to the resting position */
float shrink_min; /* min amount to shrink cloth by 0.0f (no shrink) - 1.0f (shrink to nothing) */
float shrink_max; /* max amount to shrink cloth by 0.0f (no shrink) - 1.0f (shrink to nothing) */
+
+ /* XXX various hair stuff
+ * should really be separate, this struct is a horrible mess already
+ */
+ float bending_damping; /* damping of bending springs */
+ float voxel_cell_size; /* size of voxel grid cells for continuum dynamics */
+ int pad;
int stepsPerFrame; /* Number of time steps per frame. */
int flags; /* flags, see CSIMSETT_FLAGS enum above. */
- int preroll; /* How many frames of simulation to do before we start. */
+ int preroll DNA_DEPRECATED; /* How many frames of simulation to do before we start. */
int maxspringlen; /* in percent!; if tearing enabled, a spring will get cut */
short solver_type; /* which solver should be used? txold */
short vgroup_bend; /* vertex group for scaling bending stiffness */
@@ -86,7 +97,6 @@ typedef struct ClothSimSettings {
short shapekey_rest; /* vertex group for scaling structural stiffness */
short presets; /* used for presets on GUI */
short reset;
- char pad[4];
struct EffectorWeights *effector_weights;
} ClothSimSettings;
@@ -97,15 +107,16 @@ typedef struct ClothCollSettings {
float epsilon; /* min distance for collisions. */
float self_friction; /* Fiction/damping with self contact. */
float friction; /* Friction/damping applied on contact with other object.*/
+ float damping; /* Collision restitution on contact with other object.*/
float selfepsilon; /* for selfcollision */
float repel_force, distance_repel;
int flags; /* collision flags defined in BKE_cloth.h */
short self_loop_count; /* How many iterations for the selfcollision loop */
short loop_count; /* How many iterations for the collision loop. */
+ int pad;
struct Group *group; /* Only use colliders from this group of objects */
short vgroup_selfcol; /* vgroup to paint which vertices are used for self collisions */
- short pad;
- int pad2;
+ short pad2[3];
} ClothCollSettings;
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index fb33879e2c1..86991245068 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -173,6 +173,12 @@ typedef struct bSplineIKConstraint {
/* settings */
short flag; /* general settings for constraint */
short xzScaleMode; /* method used for determining the x & z scaling of the bones */
+
+ /* volume preservation settings */
+ float bulge;
+ float bulge_min;
+ float bulge_max;
+ float bulge_smooth;
} bSplineIKConstraint;
@@ -680,15 +686,19 @@ typedef enum eKinematic_Flags {
/* bSplineIKConstraint->flag */
typedef enum eSplineIK_Flags {
/* chain has been attached to spline */
- CONSTRAINT_SPLINEIK_BOUND = (1<<0),
+ CONSTRAINT_SPLINEIK_BOUND = (1 << 0),
/* root of chain is not influenced by the constraint */
- CONSTRAINT_SPLINEIK_NO_ROOT = (1<<1),
+ CONSTRAINT_SPLINEIK_NO_ROOT = (1 << 1),
/* bones in the chain should not scale to fit the curve */
- CONSTRAINT_SPLINEIK_SCALE_LIMITED = (1<<2),
+ CONSTRAINT_SPLINEIK_SCALE_LIMITED = (1 << 2),
/* evenly distribute the bones along the path regardless of length */
- CONSTRAINT_SPLINEIK_EVENSPLITS = (1<<3),
+ CONSTRAINT_SPLINEIK_EVENSPLITS = (1 << 3),
/* don't adjust the x and z scaling of the bones by the curve radius */
- CONSTRAINT_SPLINEIK_NO_CURVERAD = (1<<4)
+ CONSTRAINT_SPLINEIK_NO_CURVERAD = (1 << 4),
+
+ /* for "volumetric" xz scale mode, limit the minimum or maximum scale values */
+ CONSTRAINT_SPLINEIK_USE_BULGE_MIN = (1 << 5),
+ CONSTRAINT_SPLINEIK_USE_BULGE_MAX = (1 << 6),
} eSplineIK_Flags;
/* bSplineIKConstraint->xzScaleMode */
@@ -698,7 +708,9 @@ typedef enum eSplineIK_XZScaleModes {
/* bones in the chain should take their x/z scales from the original scaling */
CONSTRAINT_SPLINEIK_XZS_ORIGINAL = 1,
/* x/z scales are the inverse of the y-scale */
- CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC = 2
+ CONSTRAINT_SPLINEIK_XZS_INVERSE = 2,
+ /* x/z scales are computed using a volume preserving technique (from Stretch To constraint) */
+ CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC = 3
} eSplineIK_XZScaleModes;
/* MinMax (floor) flags */
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 87496fb491f..288743d5e2f 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -270,86 +270,101 @@ typedef struct Curve {
/* **************** CURVE ********************* */
-/* texflag */
-#define CU_AUTOSPACE 1
-
-/* drawflag */
-#define CU_HIDE_HANDLES (1 << 0)
-#define CU_HIDE_NORMALS (1 << 1)
-
-/* flag */
-#define CU_3D 1
-#define CU_FRONT 2
-#define CU_BACK 4
-#define CU_PATH 8
-#define CU_FOLLOW 16
-#define CU_UV_ORCO 32
-#define CU_DEFORM_BOUNDS_OFF 64
-#define CU_STRETCH 128
-/* #define CU_OFFS_PATHDIST 256 */ /* DEPRECATED */
-#define CU_FAST 512 /* Font: no filling inside editmode */
-/* #define CU_RETOPO 1024 */ /* DEPRECATED */
-#define CU_DS_EXPAND 2048
-#define CU_PATH_RADIUS 4096 /* make use of the path radius if this is enabled (default for new curves) */
-#define CU_DEFORM_FILL 8192 /* fill 2d curve after deformation */
-#define CU_FILL_CAPS 16384 /* fill bevel caps */
-#define CU_MAP_TAPER 32768 /* map taper object to beveled area */
-
-/* twist mode */
-#define CU_TWIST_Z_UP 0
-// #define CU_TWIST_Y_UP 1 // not used yet
-// #define CU_TWIST_X_UP 2
-#define CU_TWIST_MINIMUM 3
-#define CU_TWIST_TANGENT 4
-
-/* bevel factor mapping */
+/* Curve.texflag */
enum {
- CU_BEVFAC_MAP_RESOLU = 0,
+ CU_AUTOSPACE = 1,
+};
+
+/* Curve.drawflag */
+enum {
+ CU_HIDE_HANDLES = 1 << 0,
+ CU_HIDE_NORMALS = 1 << 1,
+};
+
+/* Curve.flag */
+enum {
+ CU_3D = 1 << 0,
+ CU_FRONT = 1 << 1,
+ CU_BACK = 1 << 2,
+ CU_PATH = 1 << 3,
+ CU_FOLLOW = 1 << 4,
+ CU_UV_ORCO = 1 << 5,
+ CU_DEFORM_BOUNDS_OFF = 1 << 6,
+ CU_STRETCH = 1 << 7,
+ /* CU_OFFS_PATHDIST = 1 << 8, */ /* DEPRECATED */
+ CU_FAST = 1 << 9, /* Font: no filling inside editmode */
+ /* CU_RETOPO = 1 << 10, */ /* DEPRECATED */
+ CU_DS_EXPAND = 1 << 11,
+ CU_PATH_RADIUS = 1 << 12, /* make use of the path radius if this is enabled (default for new curves) */
+ CU_DEFORM_FILL = 1 << 13, /* fill 2d curve after deformation */
+ CU_FILL_CAPS = 1 << 14, /* fill bevel caps */
+ CU_MAP_TAPER = 1 << 15, /* map taper object to beveled area */
+};
+
+/* Curve.twist_mode */
+enum {
+ CU_TWIST_Z_UP = 0,
+ /* CU_TWIST_Y_UP = 1, */ /* not used yet */
+ /* CU_TWIST_X_UP = 2, */
+ CU_TWIST_MINIMUM = 3,
+ CU_TWIST_TANGENT = 4,
+};
+
+/* Curve.bevfac1_mapping, Curve.bevfac2_mapping, bevel factor mapping */
+enum {
+ CU_BEVFAC_MAP_RESOLU = 0,
CU_BEVFAC_MAP_SEGMENT = 1,
- CU_BEVFAC_MAP_SPLINE = 2
+ CU_BEVFAC_MAP_SPLINE = 2,
+};
+
+/* Curve.spacemode */
+enum {
+ CU_LEFT = 0,
+ CU_MIDDLE = 1,
+ CU_RIGHT = 2,
+ CU_JUSTIFY = 3,
+ CU_FLUSH = 4,
};
-/* spacemode */
-#define CU_LEFT 0
-#define CU_MIDDLE 1
-#define CU_RIGHT 2
-#define CU_JUSTIFY 3
-#define CU_FLUSH 4
-
-/* flag (nurb) */
-#define CU_SMOOTH 1
-#define CU_2D 8 /* moved from type since 2.4x */
-
-/* type (nurb) */
-#define CU_POLY 0
-#define CU_BEZIER 1
-#define CU_BSPLINE 2
-#define CU_CARDINAL 3
-#define CU_NURBS 4
-#define CU_TYPE (CU_POLY|CU_BEZIER|CU_BSPLINE|CU_CARDINAL|CU_NURBS)
-
- /* only for adding */
-#define CU_PRIMITIVE 0xF00
-
- /* 2 or 4 points */
-#define CU_PRIM_CURVE 0x100
- /* 8 points circle */
-#define CU_PRIM_CIRCLE 0x200
- /* 4x4 patch Nurb */
-#define CU_PRIM_PATCH 0x300
-#define CU_PRIM_TUBE 0x400
-#define CU_PRIM_SPHERE 0x500
-#define CU_PRIM_DONUT 0x600
- /* 5 points, 5th order straight line (for anim path) */
-#define CU_PRIM_PATH 0x700
-
-
-/* flagu flagv (nurb) */
-#define CU_NURB_CYCLIC 1
-#define CU_NURB_ENDPOINT 2
-#define CU_NURB_BEZIER 4
-
-#define CU_ACT_NONE -1
+/* Nurb.flag */
+enum {
+ CU_SMOOTH = 1 << 0,
+ CU_2D = 1 << 3, /* moved from type since 2.4x */
+};
+
+/* Nurb.type */
+enum {
+ CU_POLY = 0,
+ CU_BEZIER = 1,
+ CU_BSPLINE = 2,
+ CU_CARDINAL = 3,
+ CU_NURBS = 4,
+ CU_TYPE = (CU_POLY | CU_BEZIER | CU_BSPLINE | CU_CARDINAL | CU_NURBS),
+
+ /* only for adding */
+ CU_PRIMITIVE = 0xF00,
+
+ /* 2 or 4 points */
+ CU_PRIM_CURVE = 0x100,
+ /* 8 points circle */
+ CU_PRIM_CIRCLE = 0x200,
+ /* 4x4 patch Nurb */
+ CU_PRIM_PATCH = 0x300,
+ CU_PRIM_TUBE = 0x400,
+ CU_PRIM_SPHERE = 0x500,
+ CU_PRIM_DONUT = 0x600,
+ /* 5 points, 5th order straight line (for anim path) */
+ CU_PRIM_PATH = 0x700,
+};
+
+/* Nurb.flagu, Nurb.flagv */
+enum {
+ CU_NURB_CYCLIC = 1 << 0,
+ CU_NURB_ENDPOINT = 1 << 1,
+ CU_NURB_BEZIER = 1 << 2,
+};
+
+#define CU_ACT_NONE -1
/* *************** BEZTRIPLE **************** */
@@ -366,9 +381,9 @@ typedef enum eBezTriple_Handle {
/* interpolation modes (used only for BezTriple->ipo) */
typedef enum eBezTriple_Interpolation {
/* traditional interpolation */
- BEZT_IPO_CONST = 0, /* constant interpolation */
- BEZT_IPO_LIN = 1, /* linear interpolation */
- BEZT_IPO_BEZ = 2, /* bezier interpolation */
+ BEZT_IPO_CONST = 0, /* constant interpolation */
+ BEZT_IPO_LIN = 1, /* linear interpolation */
+ BEZT_IPO_BEZ = 2, /* bezier interpolation */
/* easing equations */
BEZT_IPO_BACK = 3,
@@ -380,7 +395,7 @@ typedef enum eBezTriple_Interpolation {
BEZT_IPO_QUAD = 9,
BEZT_IPO_QUART = 10,
BEZT_IPO_QUINT = 11,
- BEZT_IPO_SINE = 12
+ BEZT_IPO_SINE = 12,
} eBezTriple_Interpolation;
/* easing modes (used only for Keyframes - BezTriple->easing) */
@@ -389,15 +404,15 @@ typedef enum eBezTriple_Easing {
BEZT_IPO_EASE_IN = 1,
BEZT_IPO_EASE_OUT = 2,
- BEZT_IPO_EASE_IN_OUT = 3
+ BEZT_IPO_EASE_IN_OUT = 3,
} eBezTriple_Easing;
/* types of keyframe (used only for BezTriple->hide when BezTriple is used in F-Curves) */
typedef enum eBezTriple_KeyframeType {
- BEZT_KEYTYPE_KEYFRAME = 0, /* default - 'proper' Keyframe */
- BEZT_KEYTYPE_EXTREME = 1, /* 'extreme' keyframe */
- BEZT_KEYTYPE_BREAKDOWN = 2, /* 'breakdown' keyframe */
- BEZT_KEYTYPE_JITTER = 3, /* 'jitter' keyframe (for adding 'filler' secondary motion) */
+ BEZT_KEYTYPE_KEYFRAME = 0, /* default - 'proper' Keyframe */
+ BEZT_KEYTYPE_EXTREME = 1, /* 'extreme' keyframe */
+ BEZT_KEYTYPE_BREAKDOWN = 2, /* 'breakdown' keyframe */
+ BEZT_KEYTYPE_JITTER = 3, /* 'jitter' keyframe (for adding 'filler' secondary motion) */
} eBezTriple_KeyframeType;
/* checks if the given BezTriple is selected */
@@ -406,14 +421,16 @@ typedef enum eBezTriple_KeyframeType {
/* *************** CHARINFO **************** */
-/* flag */
-/* note: CU_CHINFO_WRAP and CU_CHINFO_SMALLCAPS_TEST are set dynamically */
-#define CU_CHINFO_BOLD (1<<0)
-#define CU_CHINFO_ITALIC (1<<1)
-#define CU_CHINFO_UNDERLINE (1<<2)
-#define CU_CHINFO_WRAP (1<<3) /* wordwrap occurred here */
-#define CU_CHINFO_SMALLCAPS (1<<4)
-#define CU_CHINFO_SMALLCAPS_CHECK (1<<5) /* set at runtime, checks if case switching is needed */
+/* CharInfo.flag */
+enum {
+ /* note: CU_CHINFO_WRAP and CU_CHINFO_SMALLCAPS_TEST are set dynamically */
+ CU_CHINFO_BOLD = 1 << 0,
+ CU_CHINFO_ITALIC = 1 << 1,
+ CU_CHINFO_UNDERLINE = 1 << 2,
+ CU_CHINFO_WRAP = 1 << 3, /* wordwrap occurred here */
+ CU_CHINFO_SMALLCAPS = 1 << 4,
+ CU_CHINFO_SMALLCAPS_CHECK = 1 << 5, /* set at runtime, checks if case switching is needed */
+};
/* mixed with KEY_LINEAR but define here since only curve supports */
#define KEY_CU_EASE 3
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 70dc43676ac..74f5967db13 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -63,9 +63,10 @@ typedef struct CustomDataExternal {
* layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */
typedef struct CustomData {
CustomDataLayer *layers; /* CustomDataLayers, ordered by type */
- int typemap[41]; /* runtime only! - maps types to indices of first layer of that type,
+ int typemap[42]; /* runtime only! - maps types to indices of first layer of that type,
* MUST be >= CD_NUMTYPES, but we cant use a define here.
* Correct size is ensured in CustomData_update_typemap assert() */
+ int pad_i1;
int totlayer, maxlayer; /* number of layers, size of layers array */
int totsize; /* in editmode, total size of all data layers */
struct BLI_mempool *pool; /* (BMesh Only): Memory pool for allocation of blocks */
@@ -73,7 +74,7 @@ typedef struct CustomData {
} CustomData;
/* CustomData.type */
-enum {
+typedef enum CustomDataType {
CD_MVERT = 0,
CD_MSTICKY = 1, /* DEPRECATED */
CD_MDEFORMVERT = 2,
@@ -119,9 +120,10 @@ enum {
CD_FREESTYLE_FACE = 38,
CD_MLOOPTANGENT = 39,
CD_TESSLOOPNORMAL = 40,
+ CD_CUSTOMLOOPNORMAL = 41,
- CD_NUMTYPES = 41
-};
+ CD_NUMTYPES = 42
+} CustomDataType;
/* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT)
@@ -167,6 +169,7 @@ enum {
#define CD_MASK_FREESTYLE_FACE (1LL << CD_FREESTYLE_FACE)
#define CD_MASK_MLOOPTANGENT (1LL << CD_MLOOPTANGENT)
#define CD_MASK_TESSLOOPNORMAL (1LL << CD_TESSLOOPNORMAL)
+#define CD_MASK_CUSTOMLOOPNORMAL (1LL << CD_CUSTOMLOOPNORMAL)
/* CustomData.flag */
enum {
diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h
index d2b95c959b3..dece93af122 100644
--- a/source/blender/makesdna/DNA_dynamicpaint_types.h
+++ b/source/blender/makesdna/DNA_dynamicpaint_types.h
@@ -33,55 +33,71 @@ struct CurveMapping;
struct PaintSurfaceData;
/* surface format */
-#define MOD_DPAINT_SURFACE_F_PTEX 0
-#define MOD_DPAINT_SURFACE_F_VERTEX 1
-#define MOD_DPAINT_SURFACE_F_IMAGESEQ 2
+enum {
+ MOD_DPAINT_SURFACE_F_PTEX = 0,
+ MOD_DPAINT_SURFACE_F_VERTEX = 1,
+ MOD_DPAINT_SURFACE_F_IMAGESEQ = 2,
+};
/* surface type */
-#define MOD_DPAINT_SURFACE_T_PAINT 0
-#define MOD_DPAINT_SURFACE_T_DISPLACE 1
-#define MOD_DPAINT_SURFACE_T_WEIGHT 2
-#define MOD_DPAINT_SURFACE_T_WAVE 3
+enum {
+ MOD_DPAINT_SURFACE_T_PAINT = 0,
+ MOD_DPAINT_SURFACE_T_DISPLACE = 1,
+ MOD_DPAINT_SURFACE_T_WEIGHT = 2,
+ MOD_DPAINT_SURFACE_T_WAVE = 3,
+};
/* surface flags */
-#define MOD_DPAINT_ACTIVE (1<<0) /* Is surface enabled */
+enum {
+ MOD_DPAINT_ACTIVE = 1 << 0, /* Is surface enabled */
-#define MOD_DPAINT_ANTIALIAS (1<<1) /* do antialiasing */
-#define MOD_DPAINT_DISSOLVE (1<<2) /* do dissolve */
-#define MOD_DPAINT_MULALPHA (1<<3) /* Multiply color by alpha when saving image */
-#define MOD_DPAINT_DISSOLVE_LOG (1<<4) /* Use 1/x for surface dissolve */
-#define MOD_DPAINT_DRY_LOG (1<<5) /* Use 1/x for drying paint */
-#define MOD_DPAINT_PREVIEW (1<<6) /* preview this surface on viewport*/
+ MOD_DPAINT_ANTIALIAS = 1 << 1, /* do antialiasing */
+ MOD_DPAINT_DISSOLVE = 1 << 2, /* do dissolve */
+ MOD_DPAINT_MULALPHA = 1 << 3, /* Multiply color by alpha when saving image */
+ MOD_DPAINT_DISSOLVE_LOG = 1 << 4, /* Use 1/x for surface dissolve */
+ MOD_DPAINT_DRY_LOG = 1 << 5, /* Use 1/x for drying paint */
+ MOD_DPAINT_PREVIEW = 1 << 6, /* preview this surface on viewport*/
-#define MOD_DPAINT_WAVE_OPEN_BORDERS (1<<7) /* passes waves through mesh edges */
-#define MOD_DPAINT_DISP_INCREMENTAL (1<<8) /* builds displace on top of earlier values */
-#define MOD_DPAINT_USE_DRYING (1<<9) /* use drying */
+ MOD_DPAINT_WAVE_OPEN_BORDERS = 1 << 7, /* passes waves through mesh edges */
+ MOD_DPAINT_DISP_INCREMENTAL = 1 << 8, /* builds displace on top of earlier values */
+ MOD_DPAINT_USE_DRYING = 1 << 9, /* use drying */
-#define MOD_DPAINT_OUT1 (1<<10) /* output primary surface */
-#define MOD_DPAINT_OUT2 (1<<11) /* output secondary surface */
+ MOD_DPAINT_OUT1 = 1 << 10, /* output primary surface */
+ MOD_DPAINT_OUT2 = 1 << 11, /* output secondary surface */
+};
/* image_fileformat */
-#define MOD_DPAINT_IMGFORMAT_PNG 0
-#define MOD_DPAINT_IMGFORMAT_OPENEXR 1
+enum {
+ MOD_DPAINT_IMGFORMAT_PNG = 0,
+ MOD_DPAINT_IMGFORMAT_OPENEXR = 1,
+};
/* disp_format */
-#define MOD_DPAINT_DISP_DISPLACE 0 /* displacement output displace map */
-#define MOD_DPAINT_DISP_DEPTH 1 /* displacement output depth data */
+enum {
+ MOD_DPAINT_DISP_DISPLACE = 0, /* displacement output displace map */
+ MOD_DPAINT_DISP_DEPTH = 1, /* displacement output depth data */
+};
/* effect */
-#define MOD_DPAINT_EFFECT_DO_SPREAD (1<<0) /* do spread effect */
-#define MOD_DPAINT_EFFECT_DO_DRIP (1<<1) /* do drip effect */
-#define MOD_DPAINT_EFFECT_DO_SHRINK (1<<2) /* do shrink effect */
+enum {
+ MOD_DPAINT_EFFECT_DO_SPREAD = 1 << 0, /* do spread effect */
+ MOD_DPAINT_EFFECT_DO_DRIP = 1 << 1, /* do drip effect */
+ MOD_DPAINT_EFFECT_DO_SHRINK = 1 << 2, /* do shrink effect */
+};
/* preview_id */
-#define MOD_DPAINT_SURFACE_PREV_PAINT 0
-#define MOD_DPAINT_SURFACE_PREV_WETMAP 1
+enum {
+ MOD_DPAINT_SURFACE_PREV_PAINT = 0,
+ MOD_DPAINT_SURFACE_PREV_WETMAP = 1,
+};
/* init_color_type */
-#define MOD_DPAINT_INITIAL_NONE 0
-#define MOD_DPAINT_INITIAL_COLOR 1
-#define MOD_DPAINT_INITIAL_TEXTURE 2
-#define MOD_DPAINT_INITIAL_VERTEXCOLOR 3
+enum {
+ MOD_DPAINT_INITIAL_NONE = 0,
+ MOD_DPAINT_INITIAL_COLOR = 1,
+ MOD_DPAINT_INITIAL_TEXTURE = 2,
+ MOD_DPAINT_INITIAL_VERTEXCOLOR = 3,
+};
typedef struct DynamicPaintSurface {
@@ -136,11 +152,14 @@ typedef struct DynamicPaintSurface {
} DynamicPaintSurface;
/* canvas flags */
-#if 0 /* This should not be needed, having a valid WEIGHT_MCOL layer should be enough.
- * And if not, should be a general flag. But seems unnecessary for now... */
-#define MOD_DPAINT_PREVIEW_READY (1<<0) /* if viewport preview is ready */
+enum {
+ /* This should not be needed, having a valid WEIGHT_MCOL layer should be enough.
+ * And if not, should be a general flag. But seems unnecessary for now... */
+#if 0
+ MOD_DPAINT_PREVIEW_READY = 1 << 0, /* if viewport preview is ready */
#endif
-#define MOD_DPAINT_BAKING (1<<1) /* surface is already baking, so it wont get updated (loop) */
+ MOD_DPAINT_BAKING = 1 << 1, /* surface is already baking, so it wont get updated (loop) */
+};
/* Canvas settings */
typedef struct DynamicPaintCanvasSettings {
@@ -157,47 +176,56 @@ typedef struct DynamicPaintCanvasSettings {
/* flags */
-#define MOD_DPAINT_PART_RAD (1<<0) /* use particle radius */
-#define MOD_DPAINT_USE_MATERIAL (1<<1) /* use object material */
-#define MOD_DPAINT_ABS_ALPHA (1<<2) /* don't increase alpha unless
- * paint alpha is higher than existing */
-#define MOD_DPAINT_ERASE (1<<3) /* removes paint */
-
-#define MOD_DPAINT_RAMP_ALPHA (1<<4) /* only read falloff ramp alpha */
-#define MOD_DPAINT_PROX_PROJECT (1<<5) /* do proximity check only in defined dir */
-#define MOD_DPAINT_INVERSE_PROX (1<<6) /* inverse proximity painting */
-#define MOD_DPAINT_NEGATE_VOLUME (1<<7) /* negates volume influence on "volume + prox" mode */
-
-#define MOD_DPAINT_DO_SMUDGE (1<<8) /* brush smudges existing paint */
-#define MOD_DPAINT_VELOCITY_ALPHA (1<<9) /* multiply brush influence by velocity */
-#define MOD_DPAINT_VELOCITY_COLOR (1<<10) /* replace brush color by velocity color ramp */
-#define MOD_DPAINT_VELOCITY_DEPTH (1<<11) /* multiply brush intersection depth by velocity */
-
-#define MOD_DPAINT_USES_VELOCITY ((1<<8)|(1<<9)|(1<<10)|(1<<11))
+enum {
+ MOD_DPAINT_PART_RAD = 1 << 0, /* use particle radius */
+ MOD_DPAINT_USE_MATERIAL = 1 << 1, /* use object material */
+ MOD_DPAINT_ABS_ALPHA = 1 << 2, /* don't increase alpha unless paint alpha is higher than existing */
+ MOD_DPAINT_ERASE = 1 << 3, /* removes paint */
+
+ MOD_DPAINT_RAMP_ALPHA = 1 << 4, /* only read falloff ramp alpha */
+ MOD_DPAINT_PROX_PROJECT = 1 << 5, /* do proximity check only in defined dir */
+ MOD_DPAINT_INVERSE_PROX = 1 << 6, /* inverse proximity painting */
+ MOD_DPAINT_NEGATE_VOLUME = 1 << 7, /* negates volume influence on "volume + prox" mode */
+
+ MOD_DPAINT_DO_SMUDGE = 1 << 8, /* brush smudges existing paint */
+ MOD_DPAINT_VELOCITY_ALPHA = 1 << 9, /* multiply brush influence by velocity */
+ MOD_DPAINT_VELOCITY_COLOR = 1 << 10, /* replace brush color by velocity color ramp */
+ MOD_DPAINT_VELOCITY_DEPTH = 1 << 11, /* multiply brush intersection depth by velocity */
+
+ MOD_DPAINT_USES_VELOCITY = (MOD_DPAINT_DO_SMUDGE | MOD_DPAINT_VELOCITY_ALPHA |
+ MOD_DPAINT_VELOCITY_COLOR | MOD_DPAINT_VELOCITY_DEPTH),
+};
/* collision type */
-#define MOD_DPAINT_COL_VOLUME 0 /* paint with mesh volume */
-#define MOD_DPAINT_COL_DIST 1 /* paint using distance to mesh surface */
-#define MOD_DPAINT_COL_VOLDIST 2 /* use both volume and distance */
-#define MOD_DPAINT_COL_PSYS 3 /* use particle system */
-#define MOD_DPAINT_COL_POINT 4 /* use distance to object center point */
+enum {
+ MOD_DPAINT_COL_VOLUME = 0, /* paint with mesh volume */
+ MOD_DPAINT_COL_DIST = 1, /* paint using distance to mesh surface */
+ MOD_DPAINT_COL_VOLDIST = 2, /* use both volume and distance */
+ MOD_DPAINT_COL_PSYS = 3, /* use particle system */
+ MOD_DPAINT_COL_POINT = 4, /* use distance to object center point */
+};
/* proximity_falloff */
-#define MOD_DPAINT_PRFALL_CONSTANT 0 /* no-falloff */
-#define MOD_DPAINT_PRFALL_SMOOTH 1 /* smooth, linear falloff */
-#define MOD_DPAINT_PRFALL_RAMP 2 /* use color ramp */
+enum {
+ MOD_DPAINT_PRFALL_CONSTANT = 0, /* no-falloff */
+ MOD_DPAINT_PRFALL_SMOOTH = 1, /* smooth, linear falloff */
+ MOD_DPAINT_PRFALL_RAMP = 2, /* use color ramp */
+};
/* wave_brush_type */
-#define MOD_DPAINT_WAVEB_DEPTH 0 /* use intersection depth */
-#define MOD_DPAINT_WAVEB_FORCE 1 /* act as a force on intersection area */
-#define MOD_DPAINT_WAVEB_REFLECT 2 /* obstacle that reflects waves */
-#define MOD_DPAINT_WAVEB_CHANGE 3 /* use change of intersection depth from previous frame */
+enum {
+ MOD_DPAINT_WAVEB_DEPTH = 0, /* use intersection depth */
+ MOD_DPAINT_WAVEB_FORCE = 1, /* act as a force on intersection area */
+ MOD_DPAINT_WAVEB_REFLECT = 2, /* obstacle that reflects waves */
+ MOD_DPAINT_WAVEB_CHANGE = 3, /* use change of intersection depth from previous frame */
+};
/* brush ray_dir */
-#define MOD_DPAINT_RAY_CANVAS 0
-#define MOD_DPAINT_RAY_BRUSH_AVG 1
-#define MOD_DPAINT_RAY_ZPLUS 2
-
+enum {
+ MOD_DPAINT_RAY_CANVAS = 0,
+ MOD_DPAINT_RAY_BRUSH_AVG = 1,
+ MOD_DPAINT_RAY_ZPLUS = 2,
+};
/* Brush settings */
typedef struct DynamicPaintBrushSettings {
diff --git a/source/blender/makesdna/DNA_fileglobal_types.h b/source/blender/makesdna/DNA_fileglobal_types.h
index 040b55d9eb6..fc7959c0043 100644
--- a/source/blender/makesdna/DNA_fileglobal_types.h
+++ b/source/blender/makesdna/DNA_fileglobal_types.h
@@ -41,9 +41,9 @@ struct Scene;
*/
typedef struct FileGlobal {
char subvstr[4]; /* needs to be here, for human fileformat recognition */
- short subversion, pads;
+ short subversion;
short minversion, minsubversion;
- short displaymode, winpos;
+ char pad[6];
struct bScreen *curscreen;
struct Scene *curscene;
int fileflags;
diff --git a/source/blender/makesdna/DNA_freestyle_types.h b/source/blender/makesdna/DNA_freestyle_types.h
index d099511a088..2359d1e9738 100644
--- a/source/blender/makesdna/DNA_freestyle_types.h
+++ b/source/blender/makesdna/DNA_freestyle_types.h
@@ -44,60 +44,74 @@ struct Group;
struct Text;
/* FreestyleConfig::flags */
-#define FREESTYLE_SUGGESTIVE_CONTOURS_FLAG (1 << 0)
-#define FREESTYLE_RIDGES_AND_VALLEYS_FLAG (1 << 1)
-#define FREESTYLE_MATERIAL_BOUNDARIES_FLAG (1 << 2)
-#define FREESTYLE_FACE_SMOOTHNESS_FLAG (1 << 3)
-#define FREESTYLE_ADVANCED_OPTIONS_FLAG (1 << 4)
-#define FREESTYLE_CULLING (1 << 5)
-#define FREESTYLE_VIEW_MAP_CACHE (1 << 6)
+enum {
+ FREESTYLE_SUGGESTIVE_CONTOURS_FLAG = 1 << 0,
+ FREESTYLE_RIDGES_AND_VALLEYS_FLAG = 1 << 1,
+ FREESTYLE_MATERIAL_BOUNDARIES_FLAG = 1 << 2,
+ FREESTYLE_FACE_SMOOTHNESS_FLAG = 1 << 3,
+ FREESTYLE_ADVANCED_OPTIONS_FLAG = 1 << 4,
+ FREESTYLE_CULLING = 1 << 5,
+ FREESTYLE_VIEW_MAP_CACHE = 1 << 6,
+};
/* FreestyleConfig::mode */
-#define FREESTYLE_CONTROL_SCRIPT_MODE 1
-#define FREESTYLE_CONTROL_EDITOR_MODE 2
+enum {
+ FREESTYLE_CONTROL_SCRIPT_MODE = 1,
+ FREESTYLE_CONTROL_EDITOR_MODE = 2,
+};
/* FreestyleLineSet::flags */
-#define FREESTYLE_LINESET_CURRENT (1 << 0)
-#define FREESTYLE_LINESET_ENABLED (1 << 1)
-#define FREESTYLE_LINESET_FE_NOT (1 << 2)
-#define FREESTYLE_LINESET_FE_AND (1 << 3)
-#define FREESTYLE_LINESET_GR_NOT (1 << 4)
-#define FREESTYLE_LINESET_FM_NOT (1 << 5)
-#define FREESTYLE_LINESET_FM_BOTH (1 << 6)
+enum {
+ FREESTYLE_LINESET_CURRENT = 1 << 0,
+ FREESTYLE_LINESET_ENABLED = 1 << 1,
+ FREESTYLE_LINESET_FE_NOT = 1 << 2,
+ FREESTYLE_LINESET_FE_AND = 1 << 3,
+ FREESTYLE_LINESET_GR_NOT = 1 << 4,
+ FREESTYLE_LINESET_FM_NOT = 1 << 5,
+ FREESTYLE_LINESET_FM_BOTH = 1 << 6,
+};
/* FreestyleLineSet::selection */
-#define FREESTYLE_SEL_VISIBILITY (1 << 0)
-#define FREESTYLE_SEL_EDGE_TYPES (1 << 1)
-#define FREESTYLE_SEL_GROUP (1 << 2)
-#define FREESTYLE_SEL_IMAGE_BORDER (1 << 3)
-#define FREESTYLE_SEL_FACE_MARK (1 << 4)
+enum {
+ FREESTYLE_SEL_VISIBILITY = 1 << 0,
+ FREESTYLE_SEL_EDGE_TYPES = 1 << 1,
+ FREESTYLE_SEL_GROUP = 1 << 2,
+ FREESTYLE_SEL_IMAGE_BORDER = 1 << 3,
+ FREESTYLE_SEL_FACE_MARK = 1 << 4,
+};
/* FreestyleLineSet::edge_types, exclude_edge_types */
-#define FREESTYLE_FE_SILHOUETTE (1 << 0)
-#define FREESTYLE_FE_BORDER (1 << 1)
-#define FREESTYLE_FE_CREASE (1 << 2)
-#define FREESTYLE_FE_RIDGE_VALLEY (1 << 3)
-/* Note: FREESTYLE_FE_VALLEY = (1 << 4) is no longer used */
-#define FREESTYLE_FE_SUGGESTIVE_CONTOUR (1 << 5)
-#define FREESTYLE_FE_MATERIAL_BOUNDARY (1 << 6)
-#define FREESTYLE_FE_CONTOUR (1 << 7)
-#define FREESTYLE_FE_EXTERNAL_CONTOUR (1 << 8)
-#define FREESTYLE_FE_EDGE_MARK (1 << 9)
+enum {
+ FREESTYLE_FE_SILHOUETTE = 1 << 0,
+ FREESTYLE_FE_BORDER = 1 << 1,
+ FREESTYLE_FE_CREASE = 1 << 2,
+ FREESTYLE_FE_RIDGE_VALLEY = 1 << 3,
+ /* FREESTYLE_FE_VALLEY = 1 << 4, */ /* No longer used */
+ FREESTYLE_FE_SUGGESTIVE_CONTOUR = 1 << 5,
+ FREESTYLE_FE_MATERIAL_BOUNDARY = 1 << 6,
+ FREESTYLE_FE_CONTOUR = 1 << 7,
+ FREESTYLE_FE_EXTERNAL_CONTOUR = 1 << 8,
+ FREESTYLE_FE_EDGE_MARK = 1 << 9,
+};
/* FreestyleLineSet::qi */
-#define FREESTYLE_QI_VISIBLE 1
-#define FREESTYLE_QI_HIDDEN 2
-#define FREESTYLE_QI_RANGE 3
+enum {
+ FREESTYLE_QI_VISIBLE = 1,
+ FREESTYLE_QI_HIDDEN = 2,
+ FREESTYLE_QI_RANGE = 3,
+};
/* FreestyleConfig::raycasting_algorithm */
/* Defines should be replaced with ViewMapBuilder::visibility_algo */
-#define FREESTYLE_ALGO_REGULAR 1
-#define FREESTYLE_ALGO_FAST 2
-#define FREESTYLE_ALGO_VERYFAST 3
-#define FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL 4
-#define FREESTYLE_ALGO_ADAPTIVE_TRADITIONAL 5
-#define FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE 6
-#define FREESTYLE_ALGO_ADAPTIVE_CUMULATIVE 7
+enum {
+ FREESTYLE_ALGO_REGULAR = 1,
+ FREESTYLE_ALGO_FAST = 2,
+ FREESTYLE_ALGO_VERYFAST = 3,
+ FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL = 4,
+ FREESTYLE_ALGO_ADAPTIVE_TRADITIONAL = 5,
+ FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE = 6,
+ FREESTYLE_ALGO_ADAPTIVE_CUMULATIVE = 7,
+};
typedef struct FreestyleLineSet {
struct FreestyleLineSet *next, *prev;
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 2bf874d3a85..beffbc4c017 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -33,6 +33,9 @@
#include "DNA_listBase.h"
#include "DNA_ID.h"
+struct AnimData;
+
+
/* Grease-Pencil Annotations - 'Stroke Point'
* -> Coordinates may either be 2d or 3d depending on settings at the time
* -> Coordinates of point on stroke, in proportions of window size
@@ -42,8 +45,15 @@ typedef struct bGPDspoint {
float x, y, z; /* co-ordinates of point (usually 2d, but can be 3d as well) */
float pressure; /* pressure of input device (from 0 to 1) at this point */
float time; /* seconds since start of stroke */
+ int flag; /* additional options (NOTE: can shrink this field down later if needed) */
} bGPDspoint;
+/* bGPDspoint->flag */
+typedef enum eGPDspoint_Flag {
+ /* stroke point is selected (for editing) */
+ GP_SPOINT_SELECT = (1 << 0)
+} eGPSPoint_Flag;
+
/* Grease-Pencil Annotations - 'Stroke'
* -> A stroke represents a (simplified version) of the curve
* drawn by the user in one 'mousedown'->'mouseup' operation
@@ -61,15 +71,18 @@ typedef struct bGPDstroke {
} bGPDstroke;
/* bGPDstroke->flag */
+typedef enum eGPDstroke_Flag {
/* stroke is in 3d-space */
-#define GP_STROKE_3DSPACE (1<<0)
+ GP_STROKE_3DSPACE = (1 << 0),
/* stroke is in 2d-space */
-#define GP_STROKE_2DSPACE (1<<1)
+ GP_STROKE_2DSPACE = (1 << 1),
/* stroke is in 2d-space (but with special 'image' scaling) */
-#define GP_STROKE_2DIMAGE (1<<2)
+ GP_STROKE_2DIMAGE = (1 << 2),
+ /* stroke is selected */
+ GP_STROKE_SELECT = (1 << 3),
/* only for use with stroke-buffer (while drawing eraser) */
-#define GP_STROKE_ERASER (1<<15)
-
+ GP_STROKE_ERASER = (1 << 15)
+} eGPDstroke_Flag;
/* Grease-Pencil Annotations - 'Frame'
* -> Acts as storage for the 'image' formed by strokes
@@ -80,15 +93,18 @@ typedef struct bGPDframe {
ListBase strokes; /* list of the simplified 'strokes' that make up the frame's data */
int framenum; /* frame number of this frame */
- int flag; /* temp settings */
+
+ short flag; /* temp settings */
+ short key_type; /* keyframe type (eBezTriple_KeyframeType) */
} bGPDframe;
-/* bGPDframe->flag */
+/* bGPDframe->flag */
+typedef enum eGPDframe_Flag {
/* frame is being painted on */
-#define GP_FRAME_PAINT (1<<0)
+ GP_FRAME_PAINT = (1 << 0),
/* for editing in Action Editor */
-#define GP_FRAME_SELECT (1<<1)
-
+ GP_FRAME_SELECT = (1 << 1)
+} eGPDframe_Flag;
/* Grease-Pencil Annotations - 'Layer' */
typedef struct bGPDlayer {
@@ -97,38 +113,52 @@ typedef struct bGPDlayer {
ListBase frames; /* list of annotations to display for frames (bGPDframe list) */
bGPDframe *actframe; /* active frame (should be the frame that is currently being displayed) */
- int flag; /* settings for layer */
+ short flag; /* settings for layer */
short thickness; /* current thickness to apply to strokes */
- short gstep; /* max number of frames between active and ghost to show (0=only those on either side) */
+
+ short gstep; /* Ghosts Before: max number of ghost frames to show between active frame and the one before it (0 = only the ghost itself) */
+ short gstep_next; /* Ghosts After: max number of ghost frames to show after active frame and the following it (0 = only the ghost itself) */
+
+ float gcolor_prev[3]; /* optional color for ghosts before the active frame */
+ float gcolor_next[3]; /* optional color for ghosts after the active frame */
float color[4]; /* color that should be used to draw all the strokes in this layer */
+ float fill[4]; /* color that should be used for drawing "fills" for strokes */
char info[128]; /* optional reference info about this layer (i.e. "director's comments, 12/3")
* this is used for the name of the layer too and kept unique. */
} bGPDlayer;
/* bGPDlayer->flag */
+typedef enum eGPDlayer_Flag {
/* don't display layer */
-#define GP_LAYER_HIDE (1<<0)
+ GP_LAYER_HIDE = (1 << 0),
/* protected from further editing */
-#define GP_LAYER_LOCKED (1<<1)
+ GP_LAYER_LOCKED = (1 << 1),
/* layer is 'active' layer being edited */
-#define GP_LAYER_ACTIVE (1<<2)
+ GP_LAYER_ACTIVE = (1 << 2),
/* draw points of stroke for debugging purposes */
-#define GP_LAYER_DRAWDEBUG (1<<3)
- /* do onionskinning */
-#define GP_LAYER_ONIONSKIN (1<<4)
+ GP_LAYER_DRAWDEBUG = (1 << 3),
+ /* do onion skinning */
+ GP_LAYER_ONIONSKIN = (1 << 4),
/* for editing in Action Editor */
-#define GP_LAYER_SELECT (1<<5)
+ GP_LAYER_SELECT = (1 << 5),
/* current frame for layer can't be changed */
-#define GP_LAYER_FRAMELOCK (1<<6)
+ GP_LAYER_FRAMELOCK = (1 << 6),
/* don't render xray (which is default) */
-#define GP_LAYER_NO_XRAY (1<<7)
-
+ GP_LAYER_NO_XRAY = (1 << 7),
+ /* use custom color for ghosts before current frame */
+ GP_LAYER_GHOST_PREVCOL = (1 << 8),
+ /* use custom color for ghosts after current frame */
+ GP_LAYER_GHOST_NEXTCOL = (1 << 9),
+ /* "volumetric" strokes (i.e. GLU Quadric discs in 3D) */
+ GP_LAYER_VOLUMETRIC = (1 << 10),
+} eGPDlayer_Flag;
/* Grease-Pencil Annotations - 'DataBlock' */
typedef struct bGPdata {
- ID id; /* Grease Pencil data is */
+ ID id; /* Grease Pencil data is a datablock */
+ struct AnimData *adt; /* animation data - for animating draw settings */
/* saved Grease-Pencil data */
ListBase layers; /* bGPDlayers */
@@ -144,23 +174,33 @@ typedef struct bGPdata {
} bGPdata;
/* bGPdata->flag */
-// XXX many of these flags should be deprecated for more general ideas in 2.5
+/* NOTE: A few flags have been deprecated since early 2.5,
+ * since they have been made redundant by interaction
+ * changes made during the porting process.
+ */
+typedef enum eGPdata_Flag {
/* don't allow painting to occur at all */
- // XXX is deprecated - not well understood
-// #define GP_DATA_LMBPLOCK (1<<0)
+ /* GP_DATA_LMBPLOCK = (1 << 0), */
+
/* show debugging info in viewport (i.e. status print) */
-#define GP_DATA_DISPINFO (1<<1)
+ GP_DATA_DISPINFO = (1 << 1),
/* in Action Editor, show as expanded channel */
-#define GP_DATA_EXPAND (1<<2)
+ GP_DATA_EXPAND = (1 << 2),
+
/* is the block overriding all clicks? */
- // XXX is deprecated - nasty old concept
-// #define GP_DATA_EDITPAINT (1<<3)
+ /* 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)
+ GP_DATA_VIEWALIGN = (1 << 4),
+
+ /* Project into the screen's Z values */
+ GP_DATA_DEPTH_VIEW = (1 << 5),
+ GP_DATA_DEPTH_STROKE = (1 << 6),
-#define GP_DATA_DEPTH_STROKE_ENDPOINTS (1<<7)
+ GP_DATA_DEPTH_STROKE_ENDPOINTS = (1 << 7),
+
+ /* Stroke Editing Mode - Toggle to enable alternative keymap for easier editing of stroke points */
+ GP_DATA_STROKE_EDITMODE = (1 << 8)
+} eGPdata_Flag;
#endif /* __DNA_GPENCIL_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_gpu_types.h b/source/blender/makesdna/DNA_gpu_types.h
new file mode 100644
index 00000000000..b6009b3f899
--- /dev/null
+++ b/source/blender/makesdna/DNA_gpu_types.h
@@ -0,0 +1,66 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file DNA_gpu_types.h
+ * \ingroup DNA
+ */
+
+#ifndef __DNA_GPU_TYPES_H__
+#define __DNA_GPU_TYPES_H__
+
+/* properties for dof effect */
+typedef struct GPUDOFSettings {
+ float focus_distance; /* focal distance for depth of field */
+ float fstop;
+ float focal_length;
+ float sensor;
+} GPUDOFSettings;
+
+/* properties for SSAO effect */
+typedef struct GPUSSAOSettings {
+ float factor;
+ float color[3];
+ float distance_max;
+ float attenuation;
+ int samples; /* ray samples, we use presets here for easy control instead of */
+ int pad;
+} GPUSSAOSettings;
+
+typedef struct GPUFXSettings {
+ GPUDOFSettings *dof;
+ GPUSSAOSettings *ssao;
+ char fx_flag; /* eGPUFXFlags */
+ char pad[7];
+} GPUFXSettings;
+
+/* shaderfx enables */
+typedef enum eGPUFXFlags {
+ GPU_FX_FLAG_DOF = (1 << 0),
+ GPU_FX_FLAG_SSAO = (1 << 1),
+} eGPUFXFlags;
+
+#endif /* __DNA_GPU_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index fcb894c9ebf..dca1c8330b0 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -143,6 +143,7 @@ enum {
IMA_USER_FRAME_IN_RANGE = (1 << 10), /* for image user, but these flags are mixed */
IMA_VIEW_AS_RENDER = (1 << 11),
IMA_IGNORE_ALPHA = (1 << 12),
+ IMA_DEINTERLACE = (1 << 13),
};
#if (DNA_DEPRECATED_GCC_POISON == 1)
diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h
index f5ce3c8d8c1..60ab01c901b 100644
--- a/source/blender/makesdna/DNA_key_types.h
+++ b/source/blender/makesdna/DNA_key_types.h
@@ -91,10 +91,10 @@ typedef struct Key {
ID *from;
- short type; /* absolute or relative shape key */
- short totkey; /* (totkey == BLI_countlist(&key->block)) */
- short slurph; /* quaint feature to delay moving points based on their order (Key->type == KEY_NORMAL) only */
+ int totkey; /* (totkey == BLI_listbase_count(&key->block)) */
short flag;
+ char type; /* absolute or relative shape key */
+ char pad2;
/* only used when (Key->type == KEY_NORMAL), this value is used as a time slider,
* rather then using the scenes time, this value can be animated to give greater control */
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 3f94a9cfebb..c3270430a3a 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -438,6 +438,7 @@ typedef struct Material {
#define MAP_PA_CLUMP 128
#define MAP_PA_KINK 256
#define MAP_PA_ROUGH 512
+#define MAP_PA_FREQ 1024
/* pr_type */
#define MA_FLAT 0
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index e535e6012b3..8067fa5db2d 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -148,16 +148,20 @@ typedef struct TFace {
/* **************** MESH ********************* */
/* texflag */
-#define ME_AUTOSPACE 1
+enum {
+ ME_AUTOSPACE = 1,
+};
/* me->editflag */
-#define ME_EDIT_MIRROR_X (1 << 0)
-#define ME_EDIT_MIRROR_Y (1 << 1) // unused so far
-#define ME_EDIT_MIRROR_Z (1 << 2) // unused so far
+enum {
+ ME_EDIT_MIRROR_X = 1 << 0,
+ ME_EDIT_MIRROR_Y = 1 << 1, /* unused so far */
+ ME_EDIT_MIRROR_Z = 1 << 2, /* unused so far */
-#define ME_EDIT_PAINT_FACE_SEL (1 << 3)
-#define ME_EDIT_MIRROR_TOPO (1 << 4)
-#define ME_EDIT_PAINT_VERT_SEL (1 << 5)
+ ME_EDIT_PAINT_FACE_SEL = 1 << 3,
+ ME_EDIT_MIRROR_TOPO = 1 << 4,
+ ME_EDIT_PAINT_VERT_SEL = 1 << 5,
+};
/* we cant have both flags enabled at once,
* flags defined in DNA_scene_types.h */
@@ -168,57 +172,65 @@ typedef struct TFace {
)
/* me->flag */
-/* #define ME_ISDONE 1 */
-/* #define ME_DEPRECATED 2 */
-#define ME_TWOSIDED 4
-#define ME_UVEFFECT 8
-#define ME_VCOLEFFECT 16
-#define ME_AUTOSMOOTH 32
-#define ME_SMESH 64
-#define ME_SUBSURF 128
-#define ME_OPT_EDGES 256
-#define ME_DS_EXPAND 512
-#define ME_SCULPT_DYNAMIC_TOPOLOGY 1024
+enum {
+/* ME_ISDONE = 1 << 0, */
+/* ME_DEPRECATED = 1 << 1, */
+ ME_TWOSIDED = 1 << 2,
+ ME_UVEFFECT = 1 << 3,
+ ME_VCOLEFFECT = 1 << 4,
+ ME_AUTOSMOOTH = 1 << 5,
+ ME_SMESH = 1 << 6,
+ ME_SUBSURF = 1 << 7,
+ ME_OPT_EDGES = 1 << 8,
+ ME_DS_EXPAND = 1 << 9,
+ ME_SCULPT_DYNAMIC_TOPOLOGY = 1 << 10,
+};
/* me->cd_flag */
-#define ME_CDFLAG_VERT_BWEIGHT (1 << 0)
-#define ME_CDFLAG_EDGE_BWEIGHT (1 << 1)
-#define ME_CDFLAG_EDGE_CREASE (1 << 2)
+enum {
+ ME_CDFLAG_VERT_BWEIGHT = 1 << 0,
+ ME_CDFLAG_EDGE_BWEIGHT = 1 << 1,
+ ME_CDFLAG_EDGE_CREASE = 1 << 2,
+};
/* me->drawflag, short */
-#define ME_DRAWEDGES (1 << 0)
-#define ME_DRAWFACES (1 << 1)
-#define ME_DRAWNORMALS (1 << 2)
-#define ME_DRAW_VNORMALS (1 << 3)
+enum {
+ ME_DRAWEDGES = 1 << 0,
+ ME_DRAWFACES = 1 << 1,
+ ME_DRAWNORMALS = 1 << 2,
+ ME_DRAW_VNORMALS = 1 << 3,
-#define ME_DRAWEIGHT (1 << 4)
-#define ME_HIDDENEDGES (1 << 5)
+ ME_DRAWEIGHT = 1 << 4,
+ /* ME_HIDDENEDGES = 1 << 5, */ /* DEPRECATED */
-#define ME_DRAWCREASES (1 << 6)
-#define ME_DRAWSEAMS (1 << 7)
-#define ME_DRAWSHARP (1 << 8)
-#define ME_DRAWBWEIGHTS (1 << 9)
+ ME_DRAWCREASES = 1 << 6,
+ ME_DRAWSEAMS = 1 << 7,
+ ME_DRAWSHARP = 1 << 8,
+ ME_DRAWBWEIGHTS = 1 << 9,
-#define ME_DRAWEXTRA_EDGELEN (1 << 10)
-#define ME_DRAWEXTRA_FACEAREA (1 << 11)
-#define ME_DRAWEXTRA_FACEANG (1 << 12)
-#define ME_DRAWEXTRA_EDGEANG (1 << 13)
+ ME_DRAWEXTRA_EDGELEN = 1 << 10,
+ ME_DRAWEXTRA_FACEAREA = 1 << 11,
+ ME_DRAWEXTRA_FACEANG = 1 << 12,
+ ME_DRAWEXTRA_EDGEANG = 1 << 13,
/* debug only option */
-#define ME_DRAWEXTRA_INDICES (1 << 14)
+ ME_DRAWEXTRA_INDICES = 1 << 14,
-#define ME_DRAW_FREESTYLE_EDGE (1 << 15)
-#define ME_DRAW_FREESTYLE_FACE (1 << 16)
+ ME_DRAW_FREESTYLE_EDGE = 1 << 15,
+ ME_DRAW_FREESTYLE_FACE = 1 << 16,
/* draw stats */
-#define ME_DRAW_STATVIS (1 << 17)
+ ME_DRAW_STATVIS = 1 << 17,
/* draw loop normals */
-#define ME_DRAW_LNORMALS (1 << 18)
+ ME_DRAW_LNORMALS = 1 << 18,
+};
/* Subsurf Type */
-#define ME_CC_SUBSURF 0
-#define ME_SIMPLE_SUBSURF 1
+enum {
+ ME_CC_SUBSURF = 0,
+ ME_SIMPLE_SUBSURF = 1,
+};
#define MESH_MAX_VERTS 2000000000L
@@ -229,6 +241,6 @@ typedef struct TFace {
#define USE_BMESH_SAVE_WITHOUT_MFACE
/* enable this so meshes get tessfaces calculated by default */
-// #define USE_TESSFACE_DEFAULT
+/* #define USE_TESSFACE_DEFAULT */
#endif
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 47782bb3ae1..b32b228fda4 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -82,6 +82,8 @@ typedef enum ModifierType {
eModifierType_MeshCache = 46,
eModifierType_LaplacianDeform = 47,
eModifierType_Wireframe = 48,
+ eModifierType_DataTransfer = 49,
+ eModifierType_NormalEdit = 50,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -534,16 +536,39 @@ typedef struct ArmatureModifierData {
char defgrp_name[64]; /* MAX_VGROUP_NAME */
} ArmatureModifierData;
+enum {
+ MOD_HOOK_UNIFORM_SPACE = (1 << 0),
+};
+
+/* same as WarpModifierFalloff */
+typedef enum {
+ eHook_Falloff_None = 0,
+ eHook_Falloff_Curve = 1,
+ eHook_Falloff_Sharp = 2, /* PROP_SHARP */
+ eHook_Falloff_Smooth = 3, /* PROP_SMOOTH */
+ eHook_Falloff_Root = 4, /* PROP_ROOT */
+ eHook_Falloff_Linear = 5, /* PROP_LIN */
+ eHook_Falloff_Const = 6, /* PROP_CONST */
+ eHook_Falloff_Sphere = 7, /* PROP_SPHERE */
+ eHook_Falloff_InvSquare = 8, /* PROP_INVSQUARE */
+ /* PROP_RANDOM not used */
+} HookModifierFalloff;
+
typedef struct HookModifierData {
ModifierData modifier;
struct Object *object;
char subtarget[64]; /* optional name of bone target, MAX_ID_NAME-2 */
+ char flag;
+ char falloff_type; /* use enums from WarpModifier (exact same functionality) */
+ char pad[6];
float parentinv[4][4]; /* matrix making current transform unmodified */
float cent[3]; /* visualization of hook */
float falloff; /* if not zero, falloff is distance where influence zero */
+ struct CurveMapping *curfalloff;
+
int *indexar; /* if NULL, it's using vertexgroup */
int totindex;
float force;
@@ -563,6 +588,15 @@ typedef struct ClothModifierData {
struct ClothCollSettings *coll_parms; /* definition is in DNA_cloth_types.h */
struct PointCache *point_cache; /* definition is in DNA_object_force.h */
struct ListBase ptcaches;
+ /* XXX nasty hack, remove once hair can be separated from cloth modifier data */
+ struct ClothHairData *hairdata;
+ /* grid geometry values of hair continuum */
+ float hair_grid_min[3];
+ float hair_grid_max[3];
+ int hair_grid_res[3];
+ float hair_grid_cellsize;
+
+ struct ClothSolverResult *solver_result;
} ClothModifierData;
typedef struct CollisionModifierData {
@@ -968,6 +1002,7 @@ typedef enum {
eWarp_Falloff_Linear = 5, /* PROP_LIN */
eWarp_Falloff_Const = 6, /* PROP_CONST */
eWarp_Falloff_Sphere = 7, /* PROP_SPHERE */
+ eWarp_Falloff_InvSquare = 8, /* PROP_INVSQUARE */
/* PROP_RANDOM not used */
} WarpModifierFalloff;
@@ -1367,5 +1402,79 @@ enum {
};
+typedef struct DataTransferModifierData {
+ ModifierData modifier;
+
+ struct Object *ob_source;
+
+ int data_types; /* See DT_TYPE_ enum in ED_object.h */
+
+ /* See MREMAP_MODE_ enum in BKE_mesh_mapping.h */
+ int vmap_mode;
+ int emap_mode;
+ int lmap_mode;
+ int pmap_mode;
+
+ float map_max_distance;
+ float map_ray_radius;
+ float islands_precision;
+
+ int pad_i1;
+
+ int layers_select_src[4]; /* DT_MULTILAYER_INDEX_MAX; See DT_FROMLAYERS_ enum in ED_object.h */
+ int layers_select_dst[4]; /* DT_MULTILAYER_INDEX_MAX; See DT_TOLAYERS_ enum in ED_object.h */
+
+ int mix_mode; /* See CDT_MIX_ enum in BKE_customdata.h */
+ float mix_factor;
+ char defgrp_name[64]; /* MAX_VGROUP_NAME */
+
+ int flags;
+} DataTransferModifierData;
+
+/* DataTransferModifierData.flags */
+enum {
+ MOD_DATATRANSFER_OBSRC_TRANSFORM = 1 << 0,
+ MOD_DATATRANSFER_MAP_MAXDIST = 1 << 1,
+ MOD_DATATRANSFER_INVERT_VGROUP = 1 << 2,
+
+ /* Only for UI really. */
+ MOD_DATATRANSFER_USE_VERT = 1 << 28,
+ MOD_DATATRANSFER_USE_EDGE = 1 << 29,
+ MOD_DATATRANSFER_USE_LOOP = 1 << 30,
+ MOD_DATATRANSFER_USE_POLY = 1 << 31,
+};
+
+/* Set Split Normals modifier */
+typedef struct NormalEditModifierData {
+ ModifierData modifier;
+ char defgrp_name[64]; /* MAX_VGROUP_NAME */
+ struct Object *target; /* Source of normals, or center of ellipsoid. */
+ short mode;
+ short flag;
+ short mix_mode;
+ char pad[2];
+ float mix_factor;
+ float offset[3];
+} NormalEditModifierData;
+
+/* NormalEditModifierData.mode */
+enum {
+ MOD_NORMALEDIT_MODE_RADIAL = 0,
+ MOD_NORMALEDIT_MODE_DIRECTIONAL = 1,
+};
+
+/* NormalEditModifierData.flags */
+enum {
+ MOD_NORMALEDIT_INVERT_VGROUP = (1 << 0),
+ MOD_NORMALEDIT_USE_DIRECTION_PARALLEL = (1 << 1),
+};
+
+/* NormalEditModifierData.mix_mode */
+enum {
+ MOD_NORMALEDIT_MIX_COPY = 0,
+ MOD_NORMALEDIT_MIX_ADD = 1,
+ MOD_NORMALEDIT_MIX_SUB = 2,
+ MOD_NORMALEDIT_MIX_MUL = 3,
+};
#endif /* __DNA_MODIFIER_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index e0d25e763d4..f08b3ea9590 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -825,6 +825,10 @@ typedef struct NodeTranslateData {
typedef struct NodePlaneTrackDeformData {
char tracking_object[64];
char plane_track_name[64];
+ char flag;
+ char motion_blur_samples;
+ char pad[2];
+ float motion_blur_shutter;
} NodePlaneTrackDeformData;
typedef struct NodeShaderScript {
@@ -962,6 +966,8 @@ typedef struct NodeSunBeams {
/* image texture */
#define SHD_PROJ_FLAT 0
#define SHD_PROJ_BOX 1
+#define SHD_PROJ_SPHERE 2
+#define SHD_PROJ_TUBE 3
/* image texture interpolation */
#define SHD_INTERP_LINEAR 0
@@ -985,6 +991,36 @@ typedef struct NodeSunBeams {
#define SHD_NORMAL_MAP_BLENDER_OBJECT 3
#define SHD_NORMAL_MAP_BLENDER_WORLD 4
+/* math node clamp */
+#define SHD_MATH_CLAMP 1
+
+/* Math node operation/ */
+enum {
+ NODE_MATH_ADD = 0,
+ NODE_MATH_SUB = 1,
+ NODE_MATH_MUL = 2,
+ NODE_MATH_DIVIDE = 3,
+ NODE_MATH_SIN = 4,
+ NODE_MATH_COS = 5,
+ NODE_MATH_TAN = 6,
+ NODE_MATH_ASIN = 7,
+ NODE_MATH_ACOS = 8,
+ NODE_MATH_ATAN = 9,
+ NODE_MATH_POW = 10,
+ NODE_MATH_LOG = 11,
+ NODE_MATH_MIN = 12,
+ NODE_MATH_MAX = 13,
+ NODE_MATH_ROUND = 14,
+ NODE_MATH_LESS = 15,
+ NODE_MATH_GREATER = 16,
+ NODE_MATH_MOD = 17,
+ NODE_MATH_ABS = 18,
+};
+
+/* mix rgb node flags */
+#define SHD_MIXRGB_USE_ALPHA 1
+#define SHD_MIXRGB_CLAMP 2
+
/* subsurface */
enum {
SHD_SUBSURFACE_COMPATIBLE = 0, // Deprecated
@@ -1048,4 +1084,11 @@ enum {
/* viewer and cmposite output */
#define CMP_NODE_OUTPUT_IGNORE_ALPHA 1
+/* Plane track deform node */
+enum {
+ CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR = 1,
+};
+
+#define CMP_NODE_PLANETRACKDEFORM_MBLUR_SAMPLES_MAX 64
+
#endif
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 0bcc6bfd70e..2699bb5f22f 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -510,7 +510,7 @@ enum {
#define OB_FROMDUPLI (1 << 9)
-#define OB_DONE (1 << 10)
+#define OB_DONE (1 << 10) /* unknown state, clear before use */
/* #define OB_RADIO (1 << 11) */ /* deprecated */
#define OB_FROMGROUP (1 << 12)
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index a2a724b6a32..95cb5c84bed 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -44,6 +44,7 @@ typedef struct HairKey {
float weight; /* softbody weight */
short editflag; /* saved particled edit mode flags */
short pad;
+ float world_co[3];
} HairKey;
typedef struct ParticleKey { /* when changed update size of struct to copy_particleKey()!! */
@@ -207,6 +208,8 @@ typedef struct ParticleSettings {
/* length */
float randlength;
/* children */
+ int child_flag;
+ int pad3;
int child_nbr, ren_child_nbr;
float parents, childsize, childrandsize;
float childrad, childflat;
@@ -215,6 +218,8 @@ typedef struct ParticleSettings {
/* kink */
float kink_amp, kink_freq, kink_shape, kink_flat;
float kink_amp_clump;
+ int kink_extra_steps, pad4;
+ float kink_axis_random, kink_amp_random;
/* rough */
float rough1, rough1_size;
float rough2, rough2_size, rough2_thres;
@@ -232,6 +237,12 @@ typedef struct ParticleSettings {
int trail_count;
/* keyed particles */
int keyed_loops;
+ struct CurveMapping *clumpcurve;
+ struct CurveMapping *roughcurve;
+ float clump_noise_size;
+
+ /* hair dynamics */
+ float bending_random;
struct MTex *mtex[18]; /* MAX_MTEX */
@@ -246,7 +257,7 @@ typedef struct ParticleSettings {
/* modified dm support */
short use_modifier_stack;
- short pad[3];
+ short pad5[3];
} ParticleSettings;
@@ -293,7 +304,7 @@ typedef struct ParticleSystem {
short vgroup[12], vg_neg, rt3; /* vertex groups, 0==disable, 1==starting index */
/* temporary storage during render */
- void *renderdata;
+ struct ParticleRenderData *renderdata;
/* point cache */
struct PointCache *pointcache;
@@ -313,6 +324,29 @@ typedef struct ParticleSystem {
float _pad; /* spare capacity */
} ParticleSystem;
+typedef enum eParticleDrawFlag {
+ PART_DRAW_VEL = (1 << 0),
+ PART_DRAW_GLOBAL_OB = (1 << 1),
+ PART_DRAW_SIZE = (1 << 2),
+ PART_DRAW_EMITTER = (1 << 3), /* render emitter also */
+ PART_DRAW_HEALTH = (1 << 4),
+ PART_ABS_PATH_TIME = (1 << 5),
+ PART_DRAW_COUNT_GR = (1 << 6),
+ PART_DRAW_BB_LOCK = (1 << 7), /* used with billboards */
+ PART_DRAW_ROTATE_OB = (1 << 7), /* used with dupliobjects/groups */
+ PART_DRAW_PARENT = (1 << 8),
+ PART_DRAW_NUM = (1 << 9),
+ PART_DRAW_RAND_GR = (1 << 10),
+ PART_DRAW_REN_ADAPT = (1 << 11),
+ PART_DRAW_VEL_LENGTH = (1 << 12),
+ PART_DRAW_MAT_COL = (1 << 13), /* deprecated, but used in do_versions */
+ PART_DRAW_WHOLE_GR = (1 << 14),
+ PART_DRAW_REN_STRAND = (1 << 15),
+ PART_DRAW_NO_SCALE_OB = (1 << 16), /* used with dupliobjects/groups */
+ PART_DRAW_GUIDE_HAIRS = (1 << 17),
+ PART_DRAW_HAIR_GRID = (1 << 18),
+} eParticleDrawFlag;
+
/* part->type */
/* hair is allways baked static in object/geometry space */
/* other types (normal particles) are in global space and not static baked */
@@ -385,31 +419,21 @@ typedef struct ParticleSystem {
#define PART_PHYS_FLUID 4
/* part->kink */
-#define PART_KINK_NO 0
-#define PART_KINK_CURL 1
-#define PART_KINK_RADIAL 2
-#define PART_KINK_WAVE 3
-#define PART_KINK_BRAID 4
-
-/* part->draw */
-#define PART_DRAW_VEL 1
-#define PART_DRAW_GLOBAL_OB 2
-#define PART_DRAW_SIZE 4
-#define PART_DRAW_EMITTER 8 /* render emitter also */
-#define PART_DRAW_HEALTH 16
-#define PART_ABS_PATH_TIME 32
-#define PART_DRAW_COUNT_GR 64
-#define PART_DRAW_BB_LOCK 128 /* used with billboards */
-#define PART_DRAW_ROTATE_OB 128 /* used with dupliobjects/groups */
-#define PART_DRAW_PARENT 256
-#define PART_DRAW_NUM 512
-#define PART_DRAW_RAND_GR 1024
-#define PART_DRAW_REN_ADAPT 2048
-#define PART_DRAW_VEL_LENGTH (1<<12)
-#define PART_DRAW_MAT_COL (1<<13) /* deprecated, but used in do_versions */
-#define PART_DRAW_WHOLE_GR (1<<14)
-#define PART_DRAW_REN_STRAND (1<<15)
-#define PART_DRAW_NO_SCALE_OB (1<<16) /* used with dupliobjects/groups */
+typedef enum eParticleKink {
+ PART_KINK_NO = 0,
+ PART_KINK_CURL = 1,
+ PART_KINK_RADIAL = 2,
+ PART_KINK_WAVE = 3,
+ PART_KINK_BRAID = 4,
+ PART_KINK_SPIRAL = 5,
+} eParticleKink;
+
+/* part->child_flag */
+typedef enum eParticleChildFlag {
+ PART_CHILD_USE_CLUMP_NOISE = (1<<0),
+ PART_CHILD_USE_CLUMP_CURVE = (1<<1),
+ PART_CHILD_USE_ROUGH_CURVE = (1<<2),
+} eParticleChildFlag;
/* part->draw_col */
#define PART_DRAW_COL_NONE 0
@@ -561,24 +585,27 @@ typedef struct ParticleSystem {
#define PTARGET_MODE_ENEMY 2
/* mapto */
-/* init */
-#define PAMAP_INIT (PAMAP_TIME | PAMAP_LIFE | PAMAP_DENS | PAMAP_SIZE)
-#define PAMAP_TIME (1<<0) /* emission time */
-#define PAMAP_LIFE (1<<1) /* life time */
-#define PAMAP_DENS (1<<2) /* density */
-#define PAMAP_SIZE (1<<3) /* physical size */
-/* reset */
-#define PAMAP_IVEL (1<<5) /* initial velocity */
-/* physics */
-#define PAMAP_PHYSICS (PAMAP_FIELD | PAMAP_GRAVITY | PAMAP_DAMP)
-#define PAMAP_FIELD (1<<6) /* force fields */
-#define PAMAP_GRAVITY (1<<10)
-#define PAMAP_DAMP (1<<11)
-/* children */
-#define PAMAP_CHILD (PAMAP_CLUMP | PAMAP_KINK | PAMAP_ROUGH | PAMAP_LENGTH)
-#define PAMAP_CLUMP (1<<7)
-#define PAMAP_KINK (1<<8)
-#define PAMAP_ROUGH (1<<9)
-#define PAMAP_LENGTH (1<<4)
+typedef enum eParticleTextureInfluence {
+ /* init */
+ PAMAP_TIME = (1<<0), /* emission time */
+ PAMAP_LIFE = (1<<1), /* life time */
+ PAMAP_DENS = (1<<2), /* density */
+ PAMAP_SIZE = (1<<3), /* physical size */
+ PAMAP_INIT = (PAMAP_TIME | PAMAP_LIFE | PAMAP_DENS | PAMAP_SIZE),
+ /* reset */
+ PAMAP_IVEL = (1<<5), /* initial velocity */
+ /* physics */
+ PAMAP_FIELD = (1<<6), /* force fields */
+ PAMAP_GRAVITY = (1<<10),
+ PAMAP_DAMP = (1<<11),
+ PAMAP_PHYSICS = (PAMAP_FIELD | PAMAP_GRAVITY | PAMAP_DAMP),
+ /* children */
+ PAMAP_CLUMP = (1<<7),
+ PAMAP_KINK_FREQ = (1<<8),
+ PAMAP_KINK_AMP = (1<<12),
+ PAMAP_ROUGH = (1<<9),
+ PAMAP_LENGTH = (1<<4),
+ PAMAP_CHILD = (PAMAP_CLUMP | PAMAP_KINK_FREQ | PAMAP_KINK_AMP | PAMAP_ROUGH | PAMAP_LENGTH),
+} eParticleTextureInfluence;
#endif
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index f8f962107f6..0eae50a2562 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -46,7 +46,9 @@ extern "C" {
#include "DNA_listBase.h"
#include "DNA_ID.h"
#include "DNA_freestyle_types.h"
+#include "DNA_gpu_types.h"
+struct CurveMapping;
struct Object;
struct Brush;
struct World;
@@ -348,6 +350,12 @@ typedef struct ImageFormatData {
#define R_IMF_EXR_CODEC_ZIP 2
#define R_IMF_EXR_CODEC_PIZ 3
#define R_IMF_EXR_CODEC_RLE 4
+#define R_IMF_EXR_CODEC_ZIPS 5
+#define R_IMF_EXR_CODEC_B44 6
+#define R_IMF_EXR_CODEC_B44A 7
+#define R_IMF_EXR_CODEC_DWAA 8
+#define R_IMF_EXR_CODEC_DWAB 9
+#define R_IMF_EXR_CODEC_MAX 10
/* ImageFormatData.jp2_flag */
#define R_IMF_JP2_FLAG_YCC (1<<0) /* when disabled use RGB */ /* was R_JPEG2K_YCC */
@@ -813,6 +821,7 @@ typedef struct TimeMarker {
typedef struct Paint {
struct Brush *brush;
struct Palette *palette;
+ struct CurveMapping *cavity_curve; /* cavity curve */
/* WM Paint cursor */
void *paint_cursor;
@@ -849,7 +858,7 @@ typedef struct ImagePaintSettings {
struct Image *clone; /* clone layer for image mode for projective texture painting */
struct Image *canvas; /* canvas when the explicit system is used for painting */
float stencil_col[3];
- float pad1;
+ float dither; /* dither amount used when painting on byte images */
} ImagePaintSettings;
/* ------------------------------------------- */
@@ -882,6 +891,7 @@ typedef struct ParticleEditSettings {
struct Scene *scene;
struct Object *object;
+ struct Object *shape_object;
} ParticleEditSettings;
/* ------------------------------------------- */
@@ -985,25 +995,36 @@ typedef struct UnifiedPaintSettings {
/* record movement of mouse so that rake can start at an intuitive angle */
float last_rake[2];
+ float last_rake_angle;
+
+ int last_stroke_valid;
+ float average_stroke_accum[3];
+ int average_stroke_counter;
+
float brush_rotation;
+ float brush_rotation_sec;
/*********************************************************************************
* all data below are used to communicate with cursor drawing and tex sampling *
*********************************************************************************/
- int draw_anchored;
int anchored_size;
- char draw_inverted;
- char pad3[7];
-
float overlap_factor; /* normalization factor due to accumulated value of curve along spacing.
* Calculated when brush spacing changes to dampen strength of stroke
* if space attenuation is used*/
+ char draw_inverted;
+ /* check is there an ongoing stroke right now */
+ char stroke_active;
+
+ char draw_anchored;
+ char do_linear_conversion;
+
float anchored_initial_mouse[2];
- /* check is there an ongoing stroke right now */
- int stroke_active;
+ /* radius of brush, premultiplied with pressure.
+ * In case of anchored brushes contains the anchored radius */
+ float pixel_radius;
/* drawing pressure */
float size_pressure_value;
@@ -1015,13 +1036,7 @@ typedef struct UnifiedPaintSettings {
float mask_tex_mouse[2];
/* ColorSpace cache to avoid locking up during sampling */
- int do_linear_conversion;
struct ColorSpace *colorspace;
-
- /* radius of brush, premultiplied with pressure.
- * In case of anchored brushes contains the anchored radius */
- float pixel_radius;
- int pad4;
} UnifiedPaintSettings;
typedef enum {
@@ -1093,9 +1108,10 @@ typedef struct ToolSettings {
short autoik_chainlen; /* runtime only */
/* Grease Pencil */
- char gpencil_flags;
+ char gpencil_flags; /* flags/options for how the tool works */
+ char gpencil_src; /* for main 3D view Grease Pencil, where data comes from */
- char pad[5];
+ char pad[4];
/* Image Paint (8 byttse aligned please!) */
struct ImagePaintSettings imapaint;
@@ -1210,6 +1226,21 @@ typedef struct PhysicsSettings {
int flag, quick_cache_step, rt;
} PhysicsSettings;
+/* ------------------------------------------- */
+/* Safe Area options used in Camera View & VSE
+ */
+typedef struct DisplaySafeAreas {
+ /* each value represents the (x,y) margins as a multiplier.
+ * 'center' in this context is just the name for a different kind of safe-area */
+
+ float title[2]; /* Title Safe */
+ float action[2]; /* Image/Graphics Safe */
+
+ /* use for alternate aspect ratio */
+ float title_center[2];
+ float action_center[2];
+} DisplaySafeAreas;
+
/* *************************************************************** */
/* Scene ID-Block */
@@ -1245,6 +1276,7 @@ typedef struct Scene {
struct ToolSettings *toolsettings; /* default allocated now */
struct SceneStats *stats; /* default allocated now */
+ struct DisplaySafeAreas safe_areas;
/* migrate or replace? depends on some internal things... */
/* no, is on the right place (ton) */
@@ -1484,7 +1516,10 @@ enum {
/* sequencer seq_prev_type seq_rend_type */
-
+/* scene->r.engine (scene.c) */
+extern const char *RE_engine_id_BLENDER_RENDER;
+extern const char *RE_engine_id_BLENDER_GAME;
+extern const char *RE_engine_id_CYCLES;
/* **************** SCENE ********************* */
@@ -1599,7 +1634,8 @@ enum {
#define PROP_LIN 4
#define PROP_CONST 5
#define PROP_RANDOM 6
-#define PROP_MODE_MAX 7
+#define PROP_INVSQUARE 7
+#define PROP_MODE_MAX 8
/* toolsettings->proportional */
#define PROP_EDIT_OFF 0
@@ -1666,7 +1702,8 @@ enum {
typedef enum {
PAINT_SHOW_BRUSH = (1 << 0),
PAINT_FAST_NAVIGATE = (1 << 1),
- PAINT_SHOW_BRUSH_ON_SURFACE = (1 << 2)
+ PAINT_SHOW_BRUSH_ON_SURFACE = (1 << 2),
+ PAINT_USE_CAVITY_MASK = (1 << 3)
} PaintFlags;
/* Paint.symmetry_flags
@@ -1727,12 +1764,13 @@ typedef enum ImagePaintMode {
// #define IMAGEPAINT_DRAW_TOOL_DRAWING 4 // deprecated
/* projection painting only */
-#define IMAGEPAINT_PROJECT_XRAY 16
-#define IMAGEPAINT_PROJECT_BACKFACE 32
-#define IMAGEPAINT_PROJECT_FLAT 64
-#define IMAGEPAINT_PROJECT_LAYER_CLONE 128
-#define IMAGEPAINT_PROJECT_LAYER_STENCIL 256
-#define IMAGEPAINT_PROJECT_LAYER_STENCIL_INV 512
+#define IMAGEPAINT_PROJECT_XRAY (1 << 4)
+#define IMAGEPAINT_PROJECT_BACKFACE (1 << 5)
+#define IMAGEPAINT_PROJECT_FLAT (1 << 6)
+#define IMAGEPAINT_PROJECT_LAYER_CLONE (1 << 7)
+#define IMAGEPAINT_PROJECT_LAYER_STENCIL (1 << 8)
+#define IMAGEPAINT_PROJECT_LAYER_STENCIL_INV (1 << 9)
+
#define IMAGEPAINT_MISSING_UVS (1 << 0)
#define IMAGEPAINT_MISSING_MATERIAL (1 << 1)
@@ -1766,6 +1804,12 @@ typedef enum ImagePaintMode {
/* toolsettings->gpencil_flags */
#define GP_TOOL_FLAG_PAINTSESSIONS_ON (1<<0)
+/* toolsettings->gpencil_src */
+typedef enum eGPencil_Source_3D {
+ GP_TOOL_SOURCE_SCENE = 0,
+ GP_TOOL_SOURCE_OBJECT = 1
+} eGPencil_Source_3d;
+
/* toolsettings->particle flag */
#define PE_KEEP_LENGTHS 1
#define PE_LOCK_FIRST 2
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 47a08c62f95..3e02071c3dd 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -57,24 +57,23 @@ typedef struct bScreen {
struct Scene *scene;
struct Scene *newscene; /* temporary when switching */
- int redraws_flag; /* user-setting for which editors get redrawn during anim playback (used to be time->redraws) */
- int pad1;
-
- short state; /* temp screen for image render display or fileselect */
- short temp; /* temp screen in a temp window, don't save (like user prefs) */
short winid; /* winid from WM, starts with 1 */
- short do_draw; /* notifier for drawing edges */
- short do_refresh; /* notifier for scale screen, changed screen, etc */
- short do_draw_gesture; /* notifier for gesture draw. */
- short do_draw_paintcursor; /* notifier for paint cursor draw. */
- short do_draw_drag; /* notifier for dragging draw. */
- short swap; /* indicator to survive swap-exchange systems */
+ short redraws_flag; /* user-setting for which editors get redrawn during anim playback (used to be time->redraws) */
+
+ char temp; /* temp screen in a temp window, don't save (like user prefs) */
+ char state; /* temp screen for image render display or fileselect */
+ char do_draw; /* notifier for drawing edges */
+ char do_refresh; /* notifier for scale screen, changed screen, etc */
+ char do_draw_gesture; /* notifier for gesture draw. */
+ char do_draw_paintcursor; /* notifier for paint cursor draw. */
+ char do_draw_drag; /* notifier for dragging draw. */
+ char swap; /* indicator to survive swap-exchange systems */
+ char skip_handling; /* set to delay screen handling after switching back from maximized area */
+ char pad[7];
short mainwin; /* screensize subwindow, for screenedges and global menus */
short subwinactive; /* active subwindow */
-
- short pad;
-
+
struct wmTimer *animtimer; /* if set, screen has timer handler added in window */
void *context; /* context callback */
} bScreen;
@@ -215,7 +214,7 @@ typedef struct ScrArea {
short do_refresh; /* private, for spacetype refresh callback */
short flag;
short region_active_win; /* index of last used region of 'RGN_TYPE_WINDOW'
- * runtuime variable, updated by executing operators */
+ * runtime variable, updated by executing operators */
char temp, pad;
struct SpaceType *type; /* callbacks for this space type */
@@ -272,12 +271,18 @@ typedef struct ARegion {
// #define WIN_EQUAL 3 // UNUSED
/* area->flag */
-#define HEADER_NO_PULLDOWN (1 << 0)
-#define AREA_FLAG_DRAWJOINTO (1 << 1)
-#define AREA_FLAG_DRAWJOINFROM (1 << 2)
-#define AREA_TEMP_INFO (1 << 3)
-#define AREA_FLAG_DRAWSPLIT_H (1 << 4)
-#define AREA_FLAG_DRAWSPLIT_V (1 << 5)
+enum {
+ HEADER_NO_PULLDOWN = (1 << 0),
+ AREA_FLAG_DRAWJOINTO = (1 << 1),
+ AREA_FLAG_DRAWJOINFROM = (1 << 2),
+ AREA_TEMP_INFO = (1 << 3),
+ AREA_FLAG_DRAWSPLIT_H = (1 << 4),
+ AREA_FLAG_DRAWSPLIT_V = (1 << 5),
+ /* used to check if we should switch back to prevspace (of a different type) */
+ AREA_FLAG_TEMP_TYPE = (1 << 6),
+ /* for temporary fullscreens (file browser, image editor render) that are opened above user set fullscreens */
+ AREA_FLAG_STACKED_FULLSCREEN = (1 << 7),
+};
#define EDGEWIDTH 1
#define AREAGRID 4
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index af33ae80ed9..c6748cca8e1 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -94,6 +94,8 @@ typedef struct StripProxy {
// to build
short build_tc_flags; // time code flags (see below) of all tc indices
// to build
+ short build_flags;
+ char pad[6];
} StripProxy;
typedef struct Strip {
@@ -131,10 +133,11 @@ typedef struct Sequence {
int flag, type; /*flags bitmap (see below) and the type of sequence*/
int len; /* the length of the contents of this strip - before handles are applied */
- int start, startofs, endofs;
- int startstill, endstill;
+ int start; /* start frame of contents of strip in absolute frame coordinates. For metastrips start of first strip startdisp */
+ int startofs, endofs; /* frames after the first frame where display starts, frames before the last frame where display ends */
+ int startstill, endstill; /* frames that use the first frame before data begins, frames that use the last frame after data ends */
int machine, depth; /*machine - the strip channel, depth - the depth in the sequence when dealing with metastrips */
- int startdisp, enddisp; /*starting and ending points in the sequence*/
+ int startdisp, enddisp; /* starting and ending points of the strip in the sequence*/
float sat;
float mul, handsize;
@@ -362,6 +365,9 @@ enum {
SEQ_AUDIO_PITCH_ANIMATED = (1 << 25),
SEQ_AUDIO_PAN_ANIMATED = (1 << 26),
SEQ_AUDIO_DRAW_WAVEFORM = (1 << 27),
+
+ /* don't include Grease Pencil in OpenGL previews of Scene strips */
+ SEQ_SCENE_NO_GPENCIL = (1 << 28),
SEQ_INVALID_EFFECT = (1 << 31),
};
@@ -394,6 +400,11 @@ enum {
#define SEQ_PROXY_TC_RECORD_RUN_NO_GAPS 8
#define SEQ_PROXY_TC_ALL 15
+/* SeqProxy->build_flags */
+enum {
+ SEQ_PROXY_SKIP_EXISTING = 1,
+};
+
/* seq->alpha_mode */
enum {
SEQ_ALPHA_STRAIGHT = 0,
diff --git a/source/blender/makesdna/DNA_sound_types.h b/source/blender/makesdna/DNA_sound_types.h
index d7a51359777..cb132c1b550 100644
--- a/source/blender/makesdna/DNA_sound_types.h
+++ b/source/blender/makesdna/DNA_sound_types.h
@@ -95,6 +95,8 @@ typedef struct bSound {
*/
void *playback_handle;
+ /* spinlock for asynchronous loading of sounds */
+ void *spinlock;
/* XXX unused currently (SOUND_TYPE_LIMITER) */
/* float start, end; */
} bSound;
@@ -116,9 +118,10 @@ enum {
};
enum {
- SOUND_FLAGS_3D = (1 << 3), /* deprecated! used for sound actuator loading */
- SOUND_FLAGS_CACHING = (1 << 4),
- SOUND_FLAGS_MONO = (1 << 5),
+ SOUND_FLAGS_3D = (1 << 3), /* deprecated! used for sound actuator loading */
+ SOUND_FLAGS_CACHING = (1 << 4),
+ SOUND_FLAGS_MONO = (1 << 5),
+ SOUND_FLAGS_WAVEFORM_LOADING = (1 << 6),
};
#if (DNA_DEPRECATED_GCC_POISON == 1)
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index a267217abf6..69affc74ed7 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -273,6 +273,7 @@ typedef enum eSpaceOutliner_Flag {
SO_NEWSELECTED = (1 << 1),
SO_HIDE_RESTRICTCOLS = (1 << 2),
SO_HIDE_KEYINGSETINFO = (1 << 3),
+ SO_SKIP_SORT_ALPHA = (1 << 4),
} eSpaceOutliner_Flag;
/* SpaceOops->outlinevis */
@@ -291,6 +292,7 @@ typedef enum eSpaceOutliner_Mode {
SO_DATABLOCKS = 11,
SO_USERDEF = 12,
/* SO_KEYMAP = 13, */ /* deprecated! */
+ SO_ID_ORPHANS = 14,
} eSpaceOutliner_Mode;
/* SpaceOops->storeflag */
@@ -461,6 +463,8 @@ typedef enum eScreen_Redraws_Flag {
// TIME_CONTINUE_PHYSICS = (1 << 7), /* UNUSED */
TIME_NODES = (1 << 8),
TIME_CLIPS = (1 << 9),
+
+ TIME_FOLLOW = (1 << 15),
} eScreen_Redraws_Flag;
/* time->cache */
@@ -490,13 +494,15 @@ typedef struct SpaceSeq {
float xof DNA_DEPRECATED, yof DNA_DEPRECATED; /* deprecated: offset for drawing the image preview */
short mainb; /* weird name for the sequencer subtype (seq, image, luma... etc) */
- short render_size;
+ short render_size; /* eSpaceSeq_Proxy_RenderSize */
short chanshown;
short zebra;
int flag;
float zoom DNA_DEPRECATED; /* deprecated, handled by View2D now */
int view; /* see SEQ_VIEW_* below */
int overlay_type;
+ int draw_flag; /* overlay an image of the editing on below the strips */
+ int pad;
struct bGPdata *gpd; /* grease-pencil data */
@@ -513,15 +519,25 @@ typedef enum eSpaceSeq_RegionType {
SEQ_DRAW_IMG_HISTOGRAM = 4,
} eSpaceSeq_RegionType;
+/* sseq->draw_flag */
+typedef enum eSpaceSeq_DrawFlag {
+ SEQ_DRAW_BACKDROP = (1 << 0),
+ SEQ_DRAW_OFFSET_EXT = (1 << 1),
+} eSpaceSeq_DrawFlag;
+
+
/* sseq->flag */
typedef enum eSpaceSeq_Flag {
SEQ_DRAWFRAMES = (1 << 0),
SEQ_MARKER_TRANS = (1 << 1),
SEQ_DRAW_COLOR_SEPARATED = (1 << 2),
- SEQ_DRAW_SAFE_MARGINS = (1 << 3),
+ SEQ_SHOW_SAFE_MARGINS = (1 << 3),
SEQ_SHOW_GPENCIL = (1 << 4),
SEQ_NO_DRAW_CFRANUM = (1 << 5),
SEQ_USE_ALPHA = (1 << 6), /* use RGBA display mode for preview */
+ SEQ_ALL_WAVEFORMS = (1 << 7), /* draw all waveforms */
+ SEQ_NO_WAVEFORMS = (1 << 8), /* draw no waveforms */
+ SEQ_SHOW_SAFE_CENTER = (1 << 9),
} eSpaceSeq_Flag;
/* sseq->view */
@@ -565,14 +581,17 @@ typedef enum eSpaceSeq_OverlayType {
/* Config and Input for File Selector */
typedef struct FileSelectParams {
char title[96]; /* title, also used for the text of the execute button */
- char dir[1056]; /* directory, FILE_MAX_LIBEXTRA, 1024 + 32, this is for extreme case when 1023 length path
+ char dir[1090]; /* directory, FILE_MAX_LIBEXTRA, 1024 + 66, this is for extreme case when 1023 length path
* needs to be linked in, where foo.blend/Armature need adding */
+ char pad_c1[2];
char file[256]; /* file */
char renamefile[256];
char renameedit[256]; /* annoying but the first is only used for initialization */
char filter_glob[64]; /* list of filetypes to filter */
+ char filter_search[64]; /* text items' name must match to be shown. */
+
int active_file;
int sel_first;
int sel_last;
@@ -618,9 +637,19 @@ typedef struct SpaceFile {
struct FileLayout *layout;
short recentnr, bookmarknr;
- short systemnr, pad2;
+ short systemnr, system_bookmarknr;
} SpaceFile;
+/* FSMenuEntry's without paths indicate seperators */
+typedef struct FSMenuEntry {
+ struct FSMenuEntry *next;
+
+ char *path;
+ char name[256]; /* FILE_MAXFILE */
+ short save;
+ short valid;
+ short pad[2];
+} FSMenuEntry;
/* FileSelectParams.display */
enum FileDisplayTypeE {
@@ -680,28 +709,28 @@ typedef enum eFileSel_Params_Flag {
/* files in filesel list: file types */
typedef enum eFileSel_File_Types {
- BLENDERFILE = (1 << 2),
- BLENDERFILE_BACKUP = (1 << 3),
- IMAGEFILE = (1 << 4),
- MOVIEFILE = (1 << 5),
- PYSCRIPTFILE = (1 << 6),
- FTFONTFILE = (1 << 7),
- SOUNDFILE = (1 << 8),
- TEXTFILE = (1 << 9),
- MOVIEFILE_ICON = (1 << 10), /* movie file that preview can't load */
- FOLDERFILE = (1 << 11), /* represents folders for filtering */
- BTXFILE = (1 << 12),
- COLLADAFILE = (1 << 13),
- OPERATORFILE = (1 << 14), /* from filter_glob operator property */
- APPLICATIONBUNDLE = (1 << 15),
+ FILE_TYPE_BLENDER = (1 << 2),
+ FILE_TYPE_BLENDER_BACKUP = (1 << 3),
+ FILE_TYPE_IMAGE = (1 << 4),
+ FILE_TYPE_MOVIE = (1 << 5),
+ FILE_TYPE_PYSCRIPT = (1 << 6),
+ FILE_TYPE_FTFONT = (1 << 7),
+ FILE_TYPE_SOUND = (1 << 8),
+ FILE_TYPE_TEXT = (1 << 9),
+ FILE_TYPE_MOVIE_ICON = (1 << 10), /* movie file that preview can't load */
+ FILE_TYPE_FOLDER = (1 << 11), /* represents folders for filtering */
+ FILE_TYPE_BTX = (1 << 12),
+ FILE_TYPE_COLLADA = (1 << 13),
+ FILE_TYPE_OPERATOR = (1 << 14), /* from filter_glob operator property */
+ FILE_TYPE_APPLICATIONBUNDLE = (1 << 15),
} eFileSel_File_Types;
/* Selection Flags in filesel: struct direntry, unsigned char selflag */
typedef enum eDirEntry_SelectFlag {
-/* ACTIVE_FILE = (1 << 1), */ /* UNUSED */
- HILITED_FILE = (1 << 2),
- SELECTED_FILE = (1 << 3),
- EDITING_FILE = (1 << 4),
+/* FILE_SEL_ACTIVE = (1 << 1), */ /* UNUSED */
+ FILE_SEL_HIGHLIGHTED = (1 << 2),
+ FILE_SEL_SELECTED = (1 << 3),
+ FILE_SEL_EDITING = (1 << 4),
} eDirEntry_SelectFlag;
/* Image/UV Editor ======================================== */
@@ -809,7 +838,7 @@ typedef enum eSpaceImage_Flag {
SI_COLOR_CORRECTION = (1 << 24),
- SI_NO_DRAW_TEXPAINT = (1 << 25)
+ SI_NO_DRAW_TEXPAINT = (1 << 25),
} eSpaceImage_Flag;
/* Text Editor ============================================ */
@@ -918,7 +947,7 @@ typedef struct bNodeTreePath {
bNodeInstanceKey parent_key; /* base key for nodes in this tree instance */
int pad;
float view_center[2]; /* v2d center point, so node trees can have different offsets in editors */
- /* XXX this is not automatically updated when node names are changed! */
+
char node_name[64]; /* MAX_NAME */
} bNodeTreePath;
@@ -1186,6 +1215,9 @@ typedef enum eSpace_Type {
SPACEICONMAX = SPACE_CLIP
} eSpace_Type;
+/* use for function args */
+#define SPACE_TYPE_ANY -1
+
// TODO: SPACE_SCRIPT
#if (DNA_DEPRECATED_GCC_POISON == 1)
#pragma GCC poison SPACE_IMASEL SPACE_SOUND
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index d256cfb2e85..af6adbecd83 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -62,11 +62,12 @@ typedef struct MTex {
char uvname[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
char projx, projy, projz, mapping;
- float ofs[3], size[3], rot;
-
+ char brush_map_mode, brush_angle_mode;
+ char pad[2];
+ float ofs[3], size[3], rot, random_angle;
+
short texflag, colormodel, pmapto, pmaptoneg;
short normapspace, which_output;
- char brush_map_mode, pad[7];
float r, g, b, k;
float def_var, rt;
@@ -83,8 +84,9 @@ typedef struct MTex {
/* particles */
float timefac, lengthfac, clumpfac, dampfac;
- float kinkfac, roughfac, padensfac, gravityfac;
+ float kinkfac, kinkampfac, roughfac, padensfac, gravityfac;
float lifefac, sizefac, ivelfac, fieldfac;
+ int pad2;
/* lamp */
float shadowfac;
@@ -174,8 +176,8 @@ typedef struct VoxelData {
short flag;
short extend;
short smoked_type;
+ short hair_type;
short data_type;
- short pad;
int _pad;
struct Object *object; /* for rendering smoke sims */
@@ -512,6 +514,10 @@ typedef struct ColorMapping {
#define MTEX_MAP_MODE_RANDOM 4
#define MTEX_MAP_MODE_STENCIL 5
+/* brush_angle_mode */
+#define MTEX_ANGLE_RANDOM 1
+#define MTEX_ANGLE_RAKE 2
+
/* **************** ColorBand ********************* */
/* colormode */
@@ -612,6 +618,7 @@ enum {
#define TEX_VD_RAW_16BIT 2
#define TEX_VD_IMAGE_SEQUENCE 3
#define TEX_VD_SMOKE 4
+#define TEX_VD_HAIR 5
/* for voxels which use VoxelData->source_path */
#define TEX_VD_IS_SOURCE_PATH(_format) (ELEM(_format, TEX_VD_BLENDERVOXEL, TEX_VD_RAW_8BIT, TEX_VD_RAW_16BIT))
@@ -621,6 +628,11 @@ enum {
#define TEX_VD_SMOKEVEL 2
#define TEX_VD_SMOKEFLAME 3
+#define TEX_VD_HAIRDENSITY 0
+#define TEX_VD_HAIRVELOCITY 1
+#define TEX_VD_HAIRENERGY 2
+#define TEX_VD_HAIRRESTDENSITY 3
+
/* data_type */
#define TEX_VD_INTENSITY 0
#define TEX_VD_RGBA_PREMUL 1
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 769e2573aa4..afa1f03a8ca 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -168,11 +168,13 @@ typedef struct ThemeUI {
uiPanelColors panel; /* depricated, but we keep it for do_versions (2.66.1) */
+ char widget_emboss[4];
+
/* fac: 0 - 1 for blend factor, width in pixels */
float menu_shadow_fac;
short menu_shadow_width;
- short pad;
+ short pad[3];
char iconfile[256]; // FILE_MAXFILE length
float icon_alpha;
@@ -249,6 +251,7 @@ typedef struct ThemeSpace {
char bone_solid[4], bone_pose[4], bone_pose_active[4];
char strip[4], strip_select[4];
char cframe[4];
+ char time_keyframe[4], time_gp_keyframe[4];
char freestyle_edge_mark[4], freestyle_face_mark[4];
char nurb_uline[4], nurb_vline[4];
@@ -285,15 +288,19 @@ typedef struct ThemeSpace {
char handle_vertex[4];
char handle_vertex_select[4];
- char pad2[4];
char handle_vertex_size;
+
+ char clipping_border_3d[4];
char marker_outline[4], marker[4], act_marker[4], sel_marker[4], dis_marker[4], lock_marker[4];
char bundle_solid[4];
char path_before[4], path_after[4];
char camera_path[4];
- char hpad[3];
+ char hpad[2];
+
+ char gp_vertex_size;
+ char gp_vertex[4], gp_vertex_select[4];
char preview_back[4];
char preview_stitch_face[4];
@@ -455,7 +462,7 @@ typedef struct UserDef {
int scrollback; /* console scrollback limit */
int dpi; /* range 48-128? */
- short encoding;
+ char pad2[2];
short transopts;
short menuthreshold1, menuthreshold2;
@@ -660,9 +667,10 @@ typedef enum eUserpref_UI_Flag {
/* uiflag2 */
typedef enum eUserpref_UI_Flag2 {
- USER_KEEP_SESSION = (1 << 0),
- USER_REGION_OVERLAP = (1 << 1),
- USER_TRACKPAD_NATURAL = (1 << 2)
+ USER_KEEP_SESSION = (1 << 0),
+ USER_REGION_OVERLAP = (1 << 1),
+ USER_TRACKPAD_NATURAL = (1 << 2),
+ USER_OPENGL_NO_WARN_SUPPORT = (1 << 3)
} eUserpref_UI_Flag2;
/* Auto-Keying mode */
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 3efba488299..210deddc854 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -46,6 +46,7 @@ struct bGPdata;
struct SmoothView3DStore;
struct wmTimer;
struct Material;
+struct GPUFX;
/* This is needed to not let VC choke on near and far... old
* proprietary MS extensions... */
@@ -60,6 +61,7 @@ struct Material;
#include "DNA_listBase.h"
#include "DNA_image_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_gpu_types.h"
/* ******************************** */
@@ -74,10 +76,11 @@ typedef struct BGpic {
struct ImageUser iuser;
struct MovieClip *clip;
struct MovieClipUser cuser;
- float xof, yof, size, blend;
+ float xof, yof, size, blend, rotation;
short view;
short flag;
- short source, pad;
+ short source;
+ char pad[6];
} BGpic;
/* ********************************* */
@@ -89,12 +92,12 @@ typedef struct RegionView3D {
float viewinv[4][4]; /* inverse of viewmat */
float persmat[4][4]; /* viewmat*winmat */
float persinv[4][4]; /* inverse of persmat */
+ float viewcamtexcofac[4]; /* offset/scale for camera glsl texcoords */
/* viewmat/persmat multiplied with object matrix, while drawing and selection */
float viewmatob[4][4];
float persmatob[4][4];
-
/* user defined clipping planes */
float clip[6][4];
float clip_local[6][4]; /* clip in object space, means we can test for clipping in editmode without first going into worldspace */
@@ -145,6 +148,7 @@ typedef struct RegionView3D {
float rot_angle;
float rot_axis[3];
+ struct GPUFX *compositor;
} RegionView3D;
/* 3D ViewPort Struct */
@@ -201,17 +205,25 @@ typedef struct View3D {
char gridflag;
/* transform widget info */
- char twtype, twmode, twflag, pad2[2];
+ char twtype, twmode, twflag;
+
+ short flag3;
/* afterdraw, for xray & transparent */
struct ListBase afterdraw_transp;
struct ListBase afterdraw_xray;
struct ListBase afterdraw_xraytransp;
-
+
/* drawflags, denoting state */
char zbuf, transp, xray;
+
+ /* built-in shader effects (eGPUFXFlags) */
char pad3[5];
+ /* note, 'fx_settings.dof' is currently _not_ allocated,
+ * instead set (temporarily) from camera */
+ struct GPUFXSettings fx_settings;
+
void *properties_storage; /* Nkey panel stores stuff here (runtime only!) */
struct Material *defmaterial; /* used by matcap now */
@@ -267,21 +279,24 @@ typedef struct View3D {
((view >= RV3D_VIEW_FRONT) && (view <= RV3D_VIEW_BOTTOM))
/* View3d->flag2 (short) */
-#define V3D_RENDER_OVERRIDE 4
-#define V3D_SOLID_TEX 8
-#define V3D_SHOW_GPENCIL 16
-#define V3D_LOCK_CAMERA 32
-#define V3D_RENDER_SHADOW 64 /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */
-#define V3D_SHOW_RECONSTRUCTION 128
-#define V3D_SHOW_CAMERAPATH 256
-#define V3D_SHOW_BUNDLENAME 512
-#define V3D_BACKFACE_CULLING 1024
-#define V3D_RENDER_BORDER 2048
-#define V3D_SOLID_MATCAP 4096 /* user flag */
-#define V3D_SHOW_SOLID_MATCAP 8192 /* runtime flag */
-#define V3D_OCCLUDE_WIRE 16384
-#define V3D_SHADELESS_TEX 32768
-
+#define V3D_RENDER_OVERRIDE (1 << 2)
+#define V3D_SOLID_TEX (1 << 3)
+#define V3D_SHOW_GPENCIL (1 << 4)
+#define V3D_LOCK_CAMERA (1 << 5)
+#define V3D_RENDER_SHADOW (1 << 6) /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */
+#define V3D_SHOW_RECONSTRUCTION (1 << 7)
+#define V3D_SHOW_CAMERAPATH (1 << 8)
+#define V3D_SHOW_BUNDLENAME (1 << 9)
+#define V3D_BACKFACE_CULLING (1 << 10)
+#define V3D_RENDER_BORDER (1 << 11)
+#define V3D_SOLID_MATCAP (1 << 12) /* user flag */
+#define V3D_SHOW_SOLID_MATCAP (1 << 13) /* runtime flag */
+#define V3D_OCCLUDE_WIRE (1 << 14)
+#define V3D_SHADELESS_TEX (1 << 15)
+
+
+/* View3d->flag3 (short) */
+#define V3D_SHOW_WORLD (1 << 0)
/* View3D->around */
#define V3D_CENTER 0
@@ -335,7 +350,11 @@ enum {
/* Camera framing options */
V3D_BGPIC_CAMERA_ASPECT = (1 << 5), /* don't stretch to fit the camera view */
- V3D_BGPIC_CAMERA_CROP = (1 << 6) /* crop out the image */
+ V3D_BGPIC_CAMERA_CROP = (1 << 6), /* crop out the image */
+
+ /* Axis flip options */
+ V3D_BGPIC_FLIP_X = (1 << 7),
+ V3D_BGPIC_FLIP_Y = (1 << 8),
};
#define V3D_BGPIC_EXPANDED (V3D_BGPIC_EXPANDED | V3D_BGPIC_CAMERACLIP)
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 4cf6bfe9a8f..1a0562ae8c5 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -165,6 +165,13 @@ enum {
WM_INIT_KEYMAP = (1<<1),
};
+/* IME is win32 only! */
+#ifndef WIN32
+# ifdef __GNUC__
+# define ime_data ime_data __attribute__ ((deprecated))
+# endif
+#endif
+
/* the savable part, rest of data is local in ghostwinlay */
typedef struct wmWindow {
struct wmWindow *next, *prev;
@@ -197,6 +204,10 @@ typedef struct wmWindow {
struct wmGesture *tweak; /* internal for wm_operators.c */
+ /* Input Method Editor data - complex character input (esp. for asian character input)
+ * Currently WIN32, runtime-only data */
+ struct wmIMEData *ime_data;
+
int drawmethod, drawfail; /* internal for wm_draw.c only */
void *drawdata; /* internal for wm_draw.c only */
@@ -208,6 +219,10 @@ typedef struct wmWindow {
ListBase gesture; /* gesture stuff */
} wmWindow;
+#ifdef ime_data
+# undef ime_data
+#endif
+
/* These two Lines with # tell makesdna this struct can be excluded. */
/* should be something like DNA_EXCLUDE
* but the preprocessor first removes all comments, spaces etc */
@@ -352,13 +367,22 @@ enum {
OPERATOR_RUNNING_MODAL = (1 << 0),
OPERATOR_CANCELLED = (1 << 1),
OPERATOR_FINISHED = (1 << 2),
-/* add this flag if the event should pass through */
+ /* add this flag if the event should pass through */
OPERATOR_PASS_THROUGH = (1 << 3),
-/* in case operator got executed outside WM code... like via fileselect */
+ /* in case operator got executed outside WM code... like via fileselect */
OPERATOR_HANDLED = (1 << 4),
+ /* used for operators that act indirectly (eg. popup menu)
+ * note: this isn't great design (using operators to trigger UI) avoid where possible. */
+ OPERATOR_INTERFACE = (1 << 5),
};
-#define OPERATOR_FLAGS_ALL (OPERATOR_RUNNING_MODAL | OPERATOR_CANCELLED | OPERATOR_FINISHED | \
- OPERATOR_PASS_THROUGH | OPERATOR_HANDLED)
+#define OPERATOR_FLAGS_ALL ( \
+ OPERATOR_RUNNING_MODAL | \
+ OPERATOR_CANCELLED | \
+ OPERATOR_FINISHED | \
+ OPERATOR_PASS_THROUGH | \
+ OPERATOR_HANDLED | \
+ OPERATOR_INTERFACE | \
+ 0)
/* sanity checks for debug mode only */
#define OPERATOR_RETVAL_CHECK(ret) (void)ret, BLI_assert(ret != 0 && (ret & OPERATOR_FLAGS_ALL) == ret)
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 50542797f0b..2a9bcc20a9f 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -128,6 +128,7 @@ typedef struct World {
/* nodes */
struct bNodeTree *nodetree;
+ ListBase gpumaterial; /* runtime */
} World;
/* **************** WORLD ********************* */
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index f60562f1ac9..4615a1ce9e4 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -92,7 +92,7 @@
*
* While writing a file, the names of a struct is indicated with a type number,
* to be found with: ``type = DNA_struct_find_nr(SDNA *, const char *)``
- * The value of ``type`` corresponds with the the index within the structs array
+ * The value of ``type`` corresponds with the index within the structs array
*
* For the moment: the complete DNA file is included in a .blend file. For
* the future we can think of smarter methods, like only included the used
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 51a0c5a7b0f..7f3e9b7c196 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -73,6 +73,7 @@ static const char *includefiles[] = {
"DNA_key_types.h",
"DNA_text_types.h",
"DNA_packedFile_types.h",
+ "DNA_gpu_types.h",
"DNA_camera_types.h",
"DNA_image_types.h",
"DNA_texture_types.h",
@@ -909,7 +910,7 @@ static void dna_write(FILE *file, const void *pntr, const int size)
int i;
const char *data;
- data = (char *) pntr;
+ data = (const char *)pntr;
for (i = 0; i < size; i++) {
fprintf(file, "%d, ", data[i]);
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index f0582b39819..577f27f564e 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -199,9 +199,11 @@ extern StructRNA RNA_CurveMapping;
extern StructRNA RNA_CurveModifier;
extern StructRNA RNA_CurvePoint;
extern StructRNA RNA_DampedTrackConstraint;
+extern StructRNA RNA_DataTransferModifier;
extern StructRNA RNA_DecimateModifier;
extern StructRNA RNA_DelaySensor;
extern StructRNA RNA_DisplaceModifier;
+extern StructRNA RNA_DisplaySafeAreas;
extern StructRNA RNA_DistortedNoiseTexture;
extern StructRNA RNA_DomainFluidSettings;
extern StructRNA RNA_DopeSheet;
@@ -238,6 +240,7 @@ extern StructRNA RNA_FModifierNoise;
extern StructRNA RNA_FModifierPython;
extern StructRNA RNA_FModifierStepped;
extern StructRNA RNA_FieldSettings;
+extern StructRNA RNA_FileBrowserFSMenuEntry;
extern StructRNA RNA_FileSelectParams;
extern StructRNA RNA_FloatProperty;
extern StructRNA RNA_FloorConstraint;
@@ -492,6 +495,7 @@ extern StructRNA RNA_SequenceEditor;
extern StructRNA RNA_SequenceElement;
extern StructRNA RNA_SequenceProxy;
extern StructRNA RNA_SequenceTransform;
+extern StructRNA RNA_NormalEditModifier;
extern StructRNA RNA_ShaderNode;
extern StructRNA RNA_ShaderNodeCameraData;
extern StructRNA RNA_ShaderNodeCombineRGB;
@@ -505,6 +509,7 @@ extern StructRNA RNA_ShaderNodeMaterial;
extern StructRNA RNA_ShaderNodeMath;
extern StructRNA RNA_ShaderNodeMixRGB;
extern StructRNA RNA_ShaderNodeNormal;
+extern StructRNA RNA_ShaderNodeGamma;
extern StructRNA RNA_ShaderNodeOutput;
extern StructRNA RNA_ShaderNodeScript;
extern StructRNA RNA_ShaderNodeRGB;
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 3d4ed0d6f51..4d836601ac4 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -184,6 +184,14 @@ extern EnumPropertyItem linestyle_geometry_modifier_type_items[];
extern EnumPropertyItem window_cursor_items[];
+extern EnumPropertyItem DT_method_vertex_items[];
+extern EnumPropertyItem DT_method_edge_items[];
+extern EnumPropertyItem DT_method_loop_items[];
+extern EnumPropertyItem DT_method_poly_items[];
+extern EnumPropertyItem DT_mix_mode_items[];
+extern EnumPropertyItem DT_layers_select_src_items[];
+extern EnumPropertyItem DT_layers_select_dst_items[];
+
struct bContext;
struct PointerRNA;
struct PropertyRNA;
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 83f3870c29a..a9c0f591858 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -147,7 +147,7 @@ typedef enum PropertySubType {
} PropertySubType;
/* Make sure enums are updated with these */
-/* HIGHEST FLAG IN USE: 1 << 30 */
+/* HIGHEST FLAG IN USE: 1 << 31 */
typedef enum PropertyFlag {
/* editable means the property is editable in the user
* interface, properties are editable by default except
@@ -165,6 +165,10 @@ typedef enum PropertyFlag {
* and collections */
PROP_ANIMATABLE = (1 << 1),
+ /* This flag means when the property's widget is in 'textedit' mode, it will be updated after every typed char,
+ * instead of waiting final validation. Used e.g. for text searchbox. */
+ PROP_TEXTEDIT_UPDATE = (1 << 31),
+
/* icon */
PROP_ICONS_CONSECUTIVE = (1 << 12),
diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript
index 4e7a564e9d4..e366c9bbe2b 100644
--- a/source/blender/makesrna/SConscript
+++ b/source/blender/makesrna/SConscript
@@ -53,6 +53,7 @@ incs = [
'../imbuf',
'../makesdna',
'../nodes',
+ '../physics',
'../render/extern/include',
'../windowmanager',
]
@@ -122,6 +123,9 @@ if env['WITH_BF_CYCLES']:
defs.append('WITH_CYCLES_DEBUG')
if env['WITH_BF_SDL']:
+ if env['WITH_BF_SDL_DYNLOAD']:
+ defs.append('WITH_SDL_DYNLOAD')
+ incs += ' #extern/sdlew/include'
defs.append('WITH_SDL')
if env['WITH_BF_OPENAL']:
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 738e4f7fa07..fa94e345e3f 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -28,8 +28,6 @@ if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration")
endif()
-# message(STATUS "Configuring makesrna")
-
# files rna_access.c rna_define.c makesrna.c intentionally excluded.
set(DEFSRC
rna_ID.c
@@ -117,15 +115,35 @@ set(APISRC
rna_scene_api.c
rna_sensor_api.c
rna_sequencer_api.c
+ rna_sound_api.c
rna_space_api.c
rna_text_api.c
rna_ui_api.c
+ rna_vfont_api.c
rna_wm_api.c
)
string(REGEX REPLACE "rna_([a-zA-Z0-9_-]*).c" "${CMAKE_CURRENT_BINARY_DIR}/rna_\\1_gen.c" GENSRC "${DEFSRC}")
+list(APPEND GENSRC
+ "${CMAKE_CURRENT_BINARY_DIR}/rna_prototypes_gen.h"
+)
set_source_files_properties(${GENSRC} PROPERTIES GENERATED TRUE)
+# --------------------------
+# CFLAGS for Generated Files
+#
+# less strict flags for generated source
+set(GENSRC_CFLAGS)
+if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
+ set(GENSRC_CFLAGS "-Wno-missing-prototypes")
+endif()
+
+if(GENSRC_CFLAGS)
+ set_source_files_properties(${GENSRC} PROPERTIES COMPILE_FLAGS "${GENSRC_CFLAGS}")
+endif()
+unset(GENSRC_CFLAGS)
+
+
set(SRC_RNA_INC
../RNA_access.h
../RNA_define.h
@@ -245,6 +263,12 @@ if(WITH_MOD_OCEANSIM)
endif()
if(WITH_SDL)
+ if(WITH_SDL_DYNLOAD)
+ add_definitions(-DWITH_SDL_DYNLOAD)
+ list(APPEND INC
+ ../../../../extern/sdlew/include
+ )
+ endif()
add_definitions(-DWITH_SDL)
endif()
@@ -291,6 +315,7 @@ blender_include_dirs(
../../ikplugin
../../makesdna
../../nodes/
+ ../../physics
../../windowmanager
../../editors/include
../../render/extern/include
@@ -311,9 +336,6 @@ add_executable(makesrna ${SRC} ${SRC_RNA_INC} ${SRC_DNA_INC})
target_link_libraries(makesrna bf_dna)
target_link_libraries(makesrna bf_dna_blenlib)
-# too many warnings with clang
-remove_cc_flag("-Wmissing-prototypes")
-
# Output rna_*_gen.c
# note (linux only): with crashes try add this after COMMAND: valgrind --leak-check=full --track-origins=yes
add_custom_command(
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index 415f5497a7e..e3dbab0ffa7 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -73,6 +73,7 @@ incs = [
'../../imbuf',
'../../makesdna',
'../../makesrna',
+ '../../physics',
'../../render/extern/include',
'../../windowmanager',
]
@@ -127,6 +128,9 @@ if env['WITH_BF_FFTW3']:
defs.append('WITH_FFTW3')
if env['WITH_BF_SDL']:
+ if env['WITH_BF_SDL_DYNLOAD']:
+ defs.append('WITH_SDL_DYNLOAD')
+ incs += ' #extern/sdlew/include'
defs.append('WITH_SDL')
if env['WITH_BF_OPENAL']:
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 9023f25e3d5..e0075414615 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -35,7 +35,6 @@
#include "BLI_utildefines.h"
-#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_types.h"
@@ -47,6 +46,14 @@
# endif
#endif
+/* stub for BLI_abort() */
+#ifndef NDEBUG
+void BLI_system_backtrace(FILE *fp)
+{
+ (void)fp;
+}
+#endif
+
/* Replace if different */
#define TMP_EXT ".tmp"
@@ -214,11 +221,11 @@ static int replace_if_different(const char *tmpfile, const char *dep_files[])
static const char *rna_safe_id(const char *id)
{
- if (strcmp(id, "default") == 0)
+ if (STREQ(id, "default"))
return "default_value";
- else if (strcmp(id, "operator") == 0)
+ else if (STREQ(id, "operator"))
return "operator_value";
- else if (strcmp(id, "new") == 0)
+ else if (STREQ(id, "new"))
return "create";
return id;
@@ -239,11 +246,11 @@ static int cmp_property(const void *a, const void *b)
const PropertyRNA *propa = *(const PropertyRNA **)a;
const PropertyRNA *propb = *(const PropertyRNA **)b;
- if (strcmp(propa->identifier, "rna_type") == 0) return -1;
- else if (strcmp(propb->identifier, "rna_type") == 0) return 1;
+ if (STREQ(propa->identifier, "rna_type")) return -1;
+ else if (STREQ(propb->identifier, "rna_type")) return 1;
- if (strcmp(propa->identifier, "name") == 0) return -1;
- else if (strcmp(propb->identifier, "name") == 0) return 1;
+ if (STREQ(propa->identifier, "name")) return -1;
+ else if (STREQ(propb->identifier, "name")) return 1;
return strcmp(propa->name, propb->name);
}
@@ -365,7 +372,7 @@ static StructRNA *rna_find_struct(const char *identifier)
StructDefRNA *ds;
for (ds = DefRNA.structs.first; ds; ds = ds->cont.next)
- if (strcmp(ds->srna->identifier, identifier) == 0)
+ if (STREQ(ds->srna->identifier, identifier))
return ds->srna;
return NULL;
@@ -376,7 +383,7 @@ static const char *rna_find_type(const char *type)
StructDefRNA *ds;
for (ds = DefRNA.structs.first; ds; ds = ds->cont.next)
- if (ds->dnaname && strcmp(ds->dnaname, type) == 0)
+ if (ds->dnaname && STREQ(ds->dnaname, type))
return ds->srna->identifier;
return NULL;
@@ -387,7 +394,7 @@ static const char *rna_find_dna_type(const char *type)
StructDefRNA *ds;
for (ds = DefRNA.structs.first; ds; ds = ds->cont.next)
- if (strcmp(ds->srna->identifier, type) == 0)
+ if (STREQ(ds->srna->identifier, type))
return ds->dnaname;
return NULL;
@@ -614,9 +621,9 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr
fprintf(f, "static PointerRNA %s(CollectionPropertyIterator *iter)\n", func);
fprintf(f, "{\n");
if (manualfunc) {
- if (strcmp(manualfunc, "rna_iterator_listbase_get") == 0 ||
- strcmp(manualfunc, "rna_iterator_array_get") == 0 ||
- strcmp(manualfunc, "rna_iterator_array_dereference_get") == 0)
+ if (STREQ(manualfunc, "rna_iterator_listbase_get") ||
+ STREQ(manualfunc, "rna_iterator_array_get") ||
+ STREQ(manualfunc, "rna_iterator_array_dereference_get"))
{
fprintf(f, " return rna_pointer_inherit_refine(&iter->parent, &RNA_%s, %s(iter));\n",
(cprop->item_type) ? (const char *)cprop->item_type : "UnknownType", manualfunc);
@@ -1150,7 +1157,7 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property
const char *manualfunc, const char *nextfunc)
{
/* note on indices, this is for external functions and ignores skipped values.
- * so the the index can only be checked against the length when there is no 'skip' function. */
+ * so the index can only be checked against the length when there is no 'skip' function. */
char *func;
if (prop->flag & PROP_IDPROPERTY && manualfunc == NULL)
@@ -1161,8 +1168,8 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property
return NULL;
/* only supported in case of standard next functions */
- if (strcmp(nextfunc, "rna_iterator_array_next") == 0) {}
- else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) {}
+ if (STREQ(nextfunc, "rna_iterator_array_next")) {}
+ else if (STREQ(nextfunc, "rna_iterator_listbase_next")) {}
else return NULL;
}
@@ -1183,7 +1190,7 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property
fprintf(f, " %s_%s_begin(&iter, ptr);\n\n", srna->identifier, rna_safe_id(prop->identifier));
fprintf(f, " if (iter.valid) {\n");
- if (strcmp(nextfunc, "rna_iterator_array_next") == 0) {
+ if (STREQ(nextfunc, "rna_iterator_array_next")) {
fprintf(f, " ArrayIterator *internal = &iter.internal.array;\n");
fprintf(f, " if (index < 0 || index >= internal->length) {\n");
fprintf(f, "#ifdef __GNUC__\n");
@@ -1203,7 +1210,7 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property
fprintf(f, " found = 1;\n");
fprintf(f, " }\n");
}
- else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) {
+ else if (STREQ(nextfunc, "rna_iterator_listbase_next")) {
fprintf(f, " ListBaseIterator *internal = &iter.internal.listbase;\n");
fprintf(f, " if (internal->skip) {\n");
fprintf(f, " while (index-- > 0 && iter.valid) {\n");
@@ -1389,23 +1396,23 @@ static void rna_set_raw_property(PropertyDefRNA *dp, PropertyRNA *prop)
if (!dp->dnatype || !dp->dnaname || !dp->dnastructname)
return;
- if (strcmp(dp->dnatype, "char") == 0) {
+ if (STREQ(dp->dnatype, "char")) {
prop->rawtype = PROP_RAW_CHAR;
prop->flag |= PROP_RAW_ACCESS;
}
- else if (strcmp(dp->dnatype, "short") == 0) {
+ else if (STREQ(dp->dnatype, "short")) {
prop->rawtype = PROP_RAW_SHORT;
prop->flag |= PROP_RAW_ACCESS;
}
- else if (strcmp(dp->dnatype, "int") == 0) {
+ else if (STREQ(dp->dnatype, "int")) {
prop->rawtype = PROP_RAW_INT;
prop->flag |= PROP_RAW_ACCESS;
}
- else if (strcmp(dp->dnatype, "float") == 0) {
+ else if (STREQ(dp->dnatype, "float")) {
prop->rawtype = PROP_RAW_FLOAT;
prop->flag |= PROP_RAW_ACCESS;
}
- else if (strcmp(dp->dnatype, "double") == 0) {
+ else if (STREQ(dp->dnatype, "double")) {
prop->rawtype = PROP_RAW_DOUBLE;
prop->flag |= PROP_RAW_ACCESS;
}
@@ -1518,7 +1525,7 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
const char *nextfunc = (const char *)cprop->next;
const char *item_type = (const char *)cprop->item_type;
- if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) {
+ if (dp->dnatype && STREQ(dp->dnatype, "ListBase")) {
/* pass */
}
else if (dp->dnalengthname || dp->dnalengthfixed) {
@@ -1528,8 +1535,8 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
/* test if we can allow raw array access, if it is using our standard
* array get/next function, we can be sure it is an actual array */
if (cprop->next && cprop->get)
- if (strcmp((const char *)cprop->next, "rna_iterator_array_next") == 0 &&
- strcmp((const char *)cprop->get, "rna_iterator_array_get") == 0)
+ if (STREQ((const char *)cprop->next, "rna_iterator_array_next") &&
+ STREQ((const char *)cprop->get, "rna_iterator_array_get"))
{
prop->flag |= PROP_RAW_ARRAY;
}
@@ -1621,7 +1628,7 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR
EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
int i;
- if (eprop->item) {
+ if (eprop->item && eprop->totitem) {
fprintf(f, "enum {\n");
for (i = 0; i < eprop->totitem; i++)
@@ -2412,11 +2419,11 @@ static void rna_auto_types(void)
for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
/* DNA name for Screen is patched in 2.5, we do the reverse here .. */
- if (ds->dnaname && strcmp(ds->dnaname, "Screen") == 0)
+ if (ds->dnaname && STREQ(ds->dnaname, "Screen"))
ds->dnaname = "bScreen";
for (dp = ds->cont.properties.first; dp; dp = dp->next) {
- if (dp->dnastructname && strcmp(dp->dnastructname, "Screen") == 0)
+ if (dp->dnastructname && STREQ(dp->dnastructname, "Screen"))
dp->dnastructname = "bScreen";
if (dp->dnatype) {
@@ -2436,7 +2443,7 @@ static void rna_auto_types(void)
else if (dp->prop->type == PROP_COLLECTION) {
CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)dp->prop;
- if (!cprop->item_type && !cprop->get && strcmp(dp->dnatype, "ListBase") == 0)
+ if (!cprop->item_type && !cprop->get && STREQ(dp->dnatype, "ListBase"))
cprop->item_type = (StructRNA *)rna_find_type(dp->dnatype);
}
}
@@ -2779,7 +2786,7 @@ static void rna_generate_struct_prototypes(FILE *f)
const char *struct_name = rna_parameter_type_name(dp->prop);
for (a = 0; a < all_structures; a++) {
- if (strcmp(struct_name, structures[a]) == 0) {
+ if (STREQ(struct_name, structures[a])) {
found = 1;
break;
}
@@ -3318,10 +3325,10 @@ static RNAProcessItem PROCESS_ITEMS[] = {
{"rna_test.c", NULL, RNA_def_test},
{"rna_text.c", "rna_text_api.c", RNA_def_text},
{"rna_timeline.c", NULL, RNA_def_timeline_marker},
- {"rna_sound.c", NULL, RNA_def_sound},
+ {"rna_sound.c", "rna_sound_api.c", RNA_def_sound},
{"rna_ui.c", "rna_ui_api.c", RNA_def_ui},
{"rna_userdef.c", NULL, RNA_def_userdef},
- {"rna_vfont.c", NULL, RNA_def_vfont},
+ {"rna_vfont.c", "rna_vfont_api.c", RNA_def_vfont},
{"rna_wm.c", "rna_wm_api.c", RNA_def_wm},
{"rna_world.c", NULL, RNA_def_world},
{"rna_movieclip.c", NULL, RNA_def_movieclip},
@@ -3365,7 +3372,9 @@ static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const
fprintf(f, "#include \"RNA_types.h\"\n");
fprintf(f, "#include \"rna_internal.h\"\n\n");
- rna_generate_prototypes(brna, f);
+
+ /* include the generated prototypes header */
+ fprintf(f, "#include \"rna_prototypes_gen.h\"\n\n");
fprintf(f, "#include \"%s\"\n", filename);
if (api_filename)
@@ -3410,7 +3419,7 @@ static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const
if (!filename || ds->filename == filename)
rna_generate_struct(brna, ds->srna, f);
- if (strcmp(filename, "rna_ID.c") == 0) {
+ if (STREQ(filename, "rna_ID.c")) {
/* this is ugly, but we cannot have c files compiled for both
* makesrna and blender with some build systems at the moment */
fprintf(f, "#include \"rna_define.c\"\n\n");
@@ -3675,7 +3684,7 @@ static const char *cpp_classes = ""
" int length;\n"
"\n"
" DynamicArray() : data(NULL), length(0) {}\n"
-" DynamicArray(int new_length) : data(NULL), length(new_length) { data = (float *)malloc(sizeof(T) * new_length); }\n"
+" DynamicArray(int new_length) : data(NULL), length(new_length) { data = (T *)malloc(sizeof(T) * new_length); }\n"
" DynamicArray(const DynamicArray<T>& other) { copy_from(other); }\n"
" const DynamicArray<T>& operator = (const DynamicArray<T>& other) { copy_from(other); return *this; }\n"
"\n"
@@ -3686,7 +3695,7 @@ static const char *cpp_classes = ""
"protected:\n"
" void copy_from(const DynamicArray<T>& other) {\n"
" if (data) free(data);\n"
-" data = (float *)malloc(sizeof(T) * other.length);\n"
+" data = (T *)malloc(sizeof(T) * other.length);\n"
" memcpy(data, other.data, sizeof(T) * other.length);\n"
" length = other.length;\n"
" }\n"
@@ -3772,7 +3781,7 @@ static int rna_is_collection_functions_struct(const char **collection_structs, c
int a = 0, found = 0;
while (collection_structs[a]) {
- if (!strcmp(collection_structs[a], struct_name)) {
+ if (STREQ(collection_structs[a], struct_name)) {
found = 1;
break;
}
@@ -3873,7 +3882,7 @@ static void rna_generate_header_cpp(BlenderRNA *UNUSED(brna), FILE *f)
for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
srna = ds->srna;
- if (!strcmp(srna->identifier, first_collection_func_struct)) {
+ if (STREQ(srna->identifier, first_collection_func_struct)) {
StructDefRNA *ds2;
StructRNA *srna2;
@@ -3960,6 +3969,26 @@ static int rna_preprocess(const char *outfile)
status = (DefRNA.error != 0);
+ /* create rna prototype header file */
+ strcpy(deffile, outfile);
+ strcat(deffile, "rna_prototypes_gen.h");
+ if (status) {
+ make_bad_file(deffile, __LINE__);
+ }
+ file = fopen(deffile, "w");
+ if (!file) {
+ fprintf(stderr, "Unable to open file: %s\n", deffile);
+ status = 1;
+ }
+ else {
+ fprintf(file,
+ "/* Automatically generated function declarations for the Data API.\n"
+ " * Do not edit manually, changes will be overwritten. */\n\n");
+ rna_generate_prototypes(brna, file);
+ fclose(file);
+ status = (DefRNA.error != 0);
+ }
+
/* create rna_gen_*.c files */
for (i = 0; PROCESS_ITEMS[i].filename; i++) {
strcpy(deffile, outfile);
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 51d81295f8c..009e3799c49 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -64,6 +64,7 @@ EnumPropertyItem id_type_items[] = {
{ID_MA, "MATERIAL", ICON_MATERIAL_DATA, "Material", ""},
{ID_MB, "META", ICON_META_DATA, "MetaBall", ""},
{ID_ME, "MESH", ICON_MESH_DATA, "Mesh", ""},
+ {ID_MC, "MOVIECLIP", ICON_CLIP, "MovieClip", ""},
{ID_NT, "NODETREE", ICON_NODETREE, "NodeTree", ""},
{ID_OB, "OBJECT", ICON_OBJECT_DATA, "Object", ""},
{ID_PC, "PAINTCURVE", ICON_CURVE_BEZCURVE, "Paint Curve", ""},
@@ -71,12 +72,12 @@ EnumPropertyItem id_type_items[] = {
{ID_PA, "PARTICLE", ICON_PARTICLE_DATA, "Particle", ""},
{ID_SCE, "SCENE", ICON_SCENE_DATA, "Scene", ""},
{ID_SCR, "SCREEN", ICON_SPLITSCREEN, "Screen", ""},
+ {ID_SO, "SOUND", ICON_PLAY_AUDIO, "Sound", ""},
{ID_SPK, "SPEAKER", ICON_SPEAKER, "Speaker", ""},
- {ID_SO, "SOUND", ICON_PLAY_AUDIO, "Sound", ""},
{ID_TXT, "TEXT", ICON_TEXT, "Text", ""},
{ID_TE, "TEXTURE", ICON_TEXTURE_DATA, "Texture", ""},
- {ID_WO, "WORLD", ICON_WORLD_DATA, "World", ""},
{ID_WM, "WINDOWMANAGER", ICON_FULLSCREEN, "Window Manager", ""},
+ {ID_WO, "WORLD", ICON_WORLD_DATA, "World", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -141,23 +142,23 @@ short RNA_type_to_ID_code(StructRNA *type)
if (RNA_struct_is_a(type, &RNA_Lattice)) return ID_LT;
if (RNA_struct_is_a(type, &RNA_Material)) return ID_MA;
if (RNA_struct_is_a(type, &RNA_MetaBall)) return ID_MB;
- if (RNA_struct_is_a(type, &RNA_NodeTree)) return ID_NT;
+ if (RNA_struct_is_a(type, &RNA_MovieClip)) return ID_MC;
if (RNA_struct_is_a(type, &RNA_Mesh)) return ID_ME;
+ if (RNA_struct_is_a(type, &RNA_Mask)) return ID_MSK;
+ if (RNA_struct_is_a(type, &RNA_NodeTree)) return ID_NT;
if (RNA_struct_is_a(type, &RNA_Object)) return ID_OB;
if (RNA_struct_is_a(type, &RNA_ParticleSettings)) return ID_PA;
+ if (RNA_struct_is_a(type, &RNA_Palette)) return ID_PAL;
+ if (RNA_struct_is_a(type, &RNA_PaintCurve)) return ID_PC;
if (RNA_struct_is_a(type, &RNA_Scene)) return ID_SCE;
if (RNA_struct_is_a(type, &RNA_Screen)) return ID_SCR;
- if (RNA_struct_is_a(type, &RNA_Speaker)) return ID_SPK;
if (RNA_struct_is_a(type, &RNA_Sound)) return ID_SO;
- if (RNA_struct_is_a(type, &RNA_Text)) return ID_TXT;
+ if (RNA_struct_is_a(type, &RNA_Speaker)) return ID_SPK;
if (RNA_struct_is_a(type, &RNA_Texture)) return ID_TE;
+ if (RNA_struct_is_a(type, &RNA_Text)) return ID_TXT;
if (RNA_struct_is_a(type, &RNA_VectorFont)) return ID_VF;
if (RNA_struct_is_a(type, &RNA_World)) return ID_WO;
if (RNA_struct_is_a(type, &RNA_WindowManager)) return ID_WM;
- if (RNA_struct_is_a(type, &RNA_MovieClip)) return ID_MC;
- if (RNA_struct_is_a(type, &RNA_Mask)) return ID_MSK;
- if (RNA_struct_is_a(type, &RNA_Palette)) return ID_PAL;
- if (RNA_struct_is_a(type, &RNA_PaintCurve)) return ID_PC;
return 0;
}
@@ -180,23 +181,23 @@ StructRNA *ID_code_to_RNA_type(short idcode)
case ID_LT: return &RNA_Lattice;
case ID_MA: return &RNA_Material;
case ID_MB: return &RNA_MetaBall;
- case ID_NT: return &RNA_NodeTree;
+ case ID_MC: return &RNA_MovieClip;
case ID_ME: return &RNA_Mesh;
+ case ID_MSK: return &RNA_Mask;
+ case ID_NT: return &RNA_NodeTree;
case ID_OB: return &RNA_Object;
case ID_PA: return &RNA_ParticleSettings;
+ case ID_PAL: return &RNA_Palette;
+ case ID_PC: return &RNA_PaintCurve;
case ID_SCE: return &RNA_Scene;
case ID_SCR: return &RNA_Screen;
- case ID_SPK: return &RNA_Speaker;
case ID_SO: return &RNA_Sound;
- case ID_TXT: return &RNA_Text;
+ case ID_SPK: return &RNA_Speaker;
case ID_TE: return &RNA_Texture;
+ case ID_TXT: return &RNA_Text;
case ID_VF: return &RNA_VectorFont;
- case ID_WO: return &RNA_World;
case ID_WM: return &RNA_WindowManager;
- case ID_MC: return &RNA_MovieClip;
- case ID_MSK: return &RNA_Mask;
- case ID_PAL: return &RNA_Palette;
- case ID_PC: return &RNA_PaintCurve;
+ case ID_WO: return &RNA_World;
default: return &RNA_ID;
}
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 806b9d0d5ad..2a0fd14e13b 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -241,13 +241,13 @@ static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
IDProperty *idprop;
for (idprop = ((IDProperty *)prop)->prev; idprop; idprop = idprop->prev) {
- if (strcmp(RNA_IDP_UI, idprop->name) == 0)
+ if (STREQ(RNA_IDP_UI, idprop->name))
break;
}
if (idprop == NULL) {
for (idprop = ((IDProperty *)prop)->next; idprop; idprop = idprop->next) {
- if (strcmp(RNA_IDP_UI, idprop->name) == 0)
+ if (STREQ(RNA_IDP_UI, idprop->name))
break;
}
}
@@ -466,7 +466,7 @@ static const char *rna_ensure_property_identifier(const PropertyRNA *prop)
if (prop->magic == RNA_MAGIC)
return prop->identifier;
else
- return ((IDProperty *)prop)->name;
+ return ((const IDProperty *)prop)->name;
}
static const char *rna_ensure_property_description(PropertyRNA *prop)
@@ -499,7 +499,7 @@ static const char *rna_ensure_property_name(const PropertyRNA *prop)
if (prop->magic == RNA_MAGIC)
name = prop->name;
else
- name = ((IDProperty *)prop)->name;
+ name = ((const IDProperty *)prop)->name;
return name;
}
@@ -511,7 +511,7 @@ StructRNA *RNA_struct_find(const char *identifier)
StructRNA *type;
if (identifier) {
for (type = BLENDER_RNA.structs.first; type; type = type->cont.next)
- if (strcmp(type->identifier, identifier) == 0)
+ if (STREQ(type->identifier, identifier))
return type;
}
return NULL;
@@ -719,7 +719,7 @@ FunctionRNA *RNA_struct_find_function(StructRNA *srna, const char *identifier)
RNA_PROP_BEGIN (&tptr, funcptr, iterprop)
{
- if (strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
+ if (STREQ(identifier, RNA_function_identifier(funcptr.data))) {
func = funcptr.data;
break;
}
@@ -1630,9 +1630,10 @@ bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
if (RNA_property_array_check(prop))
len = RNA_property_array_length(ptr, prop);
- for (index = 0; index < len; index++)
- if (rna_get_fcurve(ptr, prop, index, NULL, &driven))
+ for (index = 0; index < len; index++) {
+ if (rna_get_fcurve(ptr, prop, index, NULL, NULL, &driven))
return true;
+ }
return false;
}
@@ -1825,18 +1826,23 @@ int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
{
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
IDProperty *idprop;
+ int value;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
BLI_assert(RNA_property_array_check(prop) == false);
if ((idprop = rna_idproperty_check(&prop, ptr)))
- return IDP_Int(idprop);
+ value = IDP_Int(idprop);
else if (bprop->get)
- return bprop->get(ptr);
+ value = bprop->get(ptr);
else if (bprop->get_ex)
- return bprop->get_ex(ptr, prop);
+ value = bprop->get_ex(ptr, prop);
else
- return bprop->defaultvalue;
+ value = bprop->defaultvalue;
+
+ BLI_assert(ELEM(value, false, true));
+
+ return value;
}
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
@@ -1846,6 +1852,7 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
BLI_assert(RNA_property_array_check(prop) == false);
+ BLI_assert(ELEM(value, false, true));
/* just in case other values are passed */
if (value) value = 1;
@@ -1902,25 +1909,29 @@ int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index
{
int tmp[RNA_MAX_ARRAY_LENGTH];
int len = rna_ensure_property_array_length(ptr, prop);
+ int value;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
BLI_assert(RNA_property_array_check(prop) != false);
BLI_assert(index >= 0);
+ BLI_assert(index < len);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_boolean_get_array(ptr, prop, tmp);
- return tmp[index];
+ value = tmp[index];
}
else {
- int *tmparray, value;
+ int *tmparray;
- tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_boolean_get_index");
+ tmparray = MEM_mallocN(sizeof(int) * len, __func__);
RNA_property_boolean_get_array(ptr, prop, tmparray);
value = tmparray[index];
MEM_freeN(tmparray);
-
- return value;
}
+
+ BLI_assert(ELEM(value, false, true));
+
+ return value;
}
void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
@@ -1969,6 +1980,8 @@ void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int inde
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
BLI_assert(RNA_property_array_check(prop) != false);
BLI_assert(index >= 0);
+ BLI_assert(index < len);
+ BLI_assert(ELEM(value, false, true));
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_boolean_get_array(ptr, prop, tmp);
@@ -1978,7 +1991,7 @@ void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int inde
else {
int *tmparray;
- tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_boolean_get_index");
+ tmparray = MEM_mallocN(sizeof(int) * len, __func__);
RNA_property_boolean_get_array(ptr, prop, tmparray);
tmparray[index] = value;
RNA_property_boolean_set_array(ptr, prop, tmparray);
@@ -1992,6 +2005,7 @@ int RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
BLI_assert(RNA_property_array_check(prop) == false);
+ BLI_assert(ELEM(bprop->defaultvalue, false, true));
return bprop->defaultvalue;
}
@@ -2019,6 +2033,7 @@ int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
BLI_assert(RNA_property_array_check(prop) != false);
BLI_assert(index >= 0);
+ BLI_assert(index < prop->totarraylength);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_boolean_get_default_array(ptr, prop, tmp);
@@ -2027,7 +2042,7 @@ int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i
else {
int *tmparray, value;
- tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_boolean_get_default_index");
+ tmparray = MEM_mallocN(sizeof(int) * len, __func__);
RNA_property_boolean_get_default_array(ptr, prop, tmparray);
value = tmparray[index];
MEM_freeN(tmparray);
@@ -2131,7 +2146,7 @@ void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int va
int i;
if (array_len > 32) {
- arr = MEM_mallocN(sizeof(int) * array_len, "RNA_property_int_get_array_range");
+ arr = MEM_mallocN(sizeof(int) * array_len, __func__);
}
else {
arr = arr_stack;
@@ -2158,6 +2173,7 @@ int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
BLI_assert(RNA_property_type(prop) == PROP_INT);
BLI_assert(RNA_property_array_check(prop) != false);
BLI_assert(index >= 0);
+ BLI_assert(index < len);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_int_get_array(ptr, prop, tmp);
@@ -2166,7 +2182,7 @@ int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
else {
int *tmparray, value;
- tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_int_get_index");
+ tmparray = MEM_mallocN(sizeof(int) * len, __func__);
RNA_property_int_get_array(ptr, prop, tmparray);
value = tmparray[index];
MEM_freeN(tmparray);
@@ -2224,6 +2240,7 @@ void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, i
BLI_assert(RNA_property_type(prop) == PROP_INT);
BLI_assert(RNA_property_array_check(prop) != false);
BLI_assert(index >= 0);
+ BLI_assert(index < len);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_int_get_array(ptr, prop, tmp);
@@ -2233,7 +2250,7 @@ void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, i
else {
int *tmparray;
- tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_int_get_index");
+ tmparray = MEM_mallocN(sizeof(int) * len, __func__);
RNA_property_int_get_array(ptr, prop, tmparray);
tmparray[index] = value;
RNA_property_int_set_array(ptr, prop, tmparray);
@@ -2270,6 +2287,7 @@ int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int i
BLI_assert(RNA_property_type(prop) == PROP_INT);
BLI_assert(RNA_property_array_check(prop) != false);
BLI_assert(index >= 0);
+ BLI_assert(index < prop->totarraylength);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_int_get_default_array(ptr, prop, tmp);
@@ -2278,7 +2296,7 @@ int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int i
else {
int *tmparray, value;
- tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_int_get_default_index");
+ tmparray = MEM_mallocN(sizeof(int) * len, __func__);
RNA_property_int_get_default_array(ptr, prop, tmparray);
value = tmparray[index];
MEM_freeN(tmparray);
@@ -2398,7 +2416,7 @@ void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, floa
int i;
if (array_len > 32) {
- arr = MEM_mallocN(sizeof(float) * array_len, "RNA_property_float_get_array_range");
+ arr = MEM_mallocN(sizeof(float) * array_len, __func__);
}
else {
arr = arr_stack;
@@ -2425,6 +2443,7 @@ float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
BLI_assert(RNA_property_array_check(prop) != false);
BLI_assert(index >= 0);
+ BLI_assert(index < len);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_float_get_array(ptr, prop, tmp);
@@ -2433,7 +2452,7 @@ float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index
else {
float *tmparray, value;
- tmparray = MEM_callocN(sizeof(float) * len, "RNA_property_float_get_index");
+ tmparray = MEM_mallocN(sizeof(float) * len, __func__);
RNA_property_float_get_array(ptr, prop, tmparray);
value = tmparray[index];
MEM_freeN(tmparray);
@@ -2503,6 +2522,7 @@ void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index,
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
BLI_assert(RNA_property_array_check(prop) != false);
BLI_assert(index >= 0);
+ BLI_assert(index < len);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_float_get_array(ptr, prop, tmp);
@@ -2512,7 +2532,7 @@ void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index,
else {
float *tmparray;
- tmparray = MEM_callocN(sizeof(float) * len, "RNA_property_float_get_index");
+ tmparray = MEM_mallocN(sizeof(float) * len, __func__);
RNA_property_float_get_array(ptr, prop, tmparray);
tmparray[index] = value;
RNA_property_float_set_array(ptr, prop, tmparray);
@@ -2553,6 +2573,7 @@ float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
BLI_assert(RNA_property_array_check(prop) != false);
BLI_assert(index >= 0);
+ BLI_assert(index < prop->totarraylength);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_float_get_default_array(ptr, prop, tmp);
@@ -2561,7 +2582,7 @@ float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i
else {
float *tmparray, value;
- tmparray = MEM_callocN(sizeof(float) * len, "RNA_property_float_get_default_index");
+ tmparray = MEM_mallocN(sizeof(float) * len, __func__);
RNA_property_float_get_default_array(ptr, prop, tmparray);
value = tmparray[index];
MEM_freeN(tmparray);
@@ -3228,7 +3249,7 @@ int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, co
nameptr = RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name), &namelen);
- if ((keylen == namelen) && (strcmp(nameptr, key) == 0)) {
+ if ((keylen == namelen) && STREQ(nameptr, key)) {
*r_ptr = iter.ptr;
found = 1;
}
@@ -3546,7 +3567,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro
tmparray = NULL;
}
if (!tmparray) {
- tmparray = MEM_callocN(sizeof(float) * itemlen, "RNA tmparray\n");
+ tmparray = MEM_callocN(sizeof(float) * itemlen, "RNA tmparray");
tmplen = itemlen;
}
@@ -3889,7 +3910,7 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int
if (len + 1 < fixedlen)
buf = fixedbuf;
else
- buf = MEM_callocN(sizeof(char) * (len + 1), "rna_path_token");
+ buf = MEM_mallocN(sizeof(char) * (len + 1), "rna_path_token");
/* copy string, taking into account escaped ] */
if (bracket) {
@@ -4283,7 +4304,7 @@ char *RNA_path_append(const char *path, PointerRNA *UNUSED(ptr), PropertyRNA *pr
/* add .identifier */
if (path) {
- BLI_dynstr_append(dynstr, (char *)path);
+ BLI_dynstr_append(dynstr, path);
if (*path)
BLI_dynstr_append(dynstr, ".");
}
@@ -4739,8 +4760,9 @@ char *RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
/* this may not be an ID at all, check for simple when pointer owns property.
* TODO, more complex nested case */
if (!RNA_struct_is_ID(ptr->type)) {
- if (RNA_struct_find_property(ptr, RNA_property_identifier(prop)) == prop) {
- data_path = BLI_strdup(RNA_property_identifier(prop));
+ const char *prop_identifier = RNA_property_identifier(prop);
+ if (RNA_struct_find_property(ptr, prop_identifier) == prop) {
+ data_path = BLI_strdup(prop_identifier);
}
}
}
@@ -4959,7 +4981,7 @@ bool RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const cha
if (prop) {
int i;
- bool cmp;
+ bool cmp = false;
RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
i = RNA_enum_from_identifier(item, enumname);
@@ -5263,7 +5285,7 @@ char *RNA_pointer_as_string_id(bContext *C, PointerRNA *ptr)
{
propname = RNA_property_identifier(prop);
- if (strcmp(propname, "rna_type") == 0)
+ if (STREQ(propname, "rna_type"))
continue;
if (first_time == 0)
@@ -5334,7 +5356,7 @@ char *RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr,
arg_name = RNA_property_identifier(prop);
- if (strcmp(arg_name, "rna_type") == 0) {
+ if (STREQ(arg_name, "rna_type")) {
continue;
}
@@ -5440,14 +5462,20 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop, in
BLI_dynstr_append(dynstr, bool_as_py_string(RNA_property_boolean_get_index(ptr, prop, index)));
}
else {
+ int fixedbuf[RNA_MAX_ARRAY_LENGTH];
+ int *buf = ARRAY_SIZE(fixedbuf) >= len ? fixedbuf : MEM_mallocN(sizeof(*buf) * len, __func__);
+
+ RNA_property_boolean_get_array(ptr, prop, buf);
BLI_dynstr_append(dynstr, "(");
for (i = 0; i < len; i++) {
- BLI_dynstr_appendf(dynstr, i ? ", %s" : "%s",
- bool_as_py_string(RNA_property_boolean_get_index(ptr, prop, i)));
+ BLI_dynstr_appendf(dynstr, i ? ", %s" : "%s", bool_as_py_string(buf[i]));
}
if (len == 1)
BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
BLI_dynstr_append(dynstr, ")");
+ if (buf != fixedbuf) {
+ MEM_freeN(buf);
+ }
}
}
break;
@@ -5460,13 +5488,20 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop, in
BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get_index(ptr, prop, index));
}
else {
+ int fixedbuf[RNA_MAX_ARRAY_LENGTH];
+ int *buf = ARRAY_SIZE(fixedbuf) >= len ? fixedbuf : MEM_mallocN(sizeof(*buf) * len, __func__);
+
+ RNA_property_int_get_array(ptr, prop, buf);
BLI_dynstr_append(dynstr, "(");
for (i = 0; i < len; i++) {
- BLI_dynstr_appendf(dynstr, i ? ", %d" : "%d", RNA_property_int_get_index(ptr, prop, i));
+ BLI_dynstr_appendf(dynstr, i ? ", %d" : "%d", buf[i]);
}
if (len == 1)
BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
BLI_dynstr_append(dynstr, ")");
+ if (buf != fixedbuf) {
+ MEM_freeN(buf);
+ }
}
}
break;
@@ -5479,13 +5514,20 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop, in
BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get_index(ptr, prop, index));
}
else {
+ float fixedbuf[RNA_MAX_ARRAY_LENGTH];
+ float *buf = ARRAY_SIZE(fixedbuf) >= len ? fixedbuf : MEM_mallocN(sizeof(*buf) * len, __func__);
+
+ RNA_property_float_get_array(ptr, prop, buf);
BLI_dynstr_append(dynstr, "(");
for (i = 0; i < len; i++) {
- BLI_dynstr_appendf(dynstr, i ? ", %g" : "%g", RNA_property_float_get_index(ptr, prop, i));
+ BLI_dynstr_appendf(dynstr, i ? ", %g" : "%g", buf[i]);
}
if (len == 1)
BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
BLI_dynstr_append(dynstr, ")");
+ if (buf != fixedbuf) {
+ MEM_freeN(buf);
+ }
}
}
break;
@@ -5631,7 +5673,7 @@ PropertyRNA *RNA_function_find_parameter(PointerRNA *UNUSED(ptr), FunctionRNA *f
parm = func->cont.properties.first;
for (; parm; parm = parm->next)
- if (strcmp(RNA_property_identifier(parm), identifier) == 0)
+ if (STREQ(RNA_property_identifier(parm), identifier))
break;
return parm;
@@ -5829,7 +5871,7 @@ void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void
parm = parms->func->cont.properties.first;
for (; parm; parm = parm->next)
- if (strcmp(RNA_property_identifier(parm), identifier) == 0)
+ if (STREQ(RNA_property_identifier(parm), identifier))
break;
if (parm)
@@ -5885,7 +5927,7 @@ void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, cons
parm = parms->func->cont.properties.first;
for (; parm; parm = parm->next)
- if (strcmp(RNA_property_identifier(parm), identifier) == 0)
+ if (STREQ(RNA_property_identifier(parm), identifier))
break;
if (parm)
@@ -6629,8 +6671,8 @@ bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNAEq
int *array_a, *array_b;
bool equals;
- array_a = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals") : fixed_a;
- array_b = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals") : fixed_b;
+ array_a = (len > 16) ? MEM_mallocN(sizeof(int) * len, "RNA equals") : fixed_a;
+ array_b = (len > 16) ? MEM_mallocN(sizeof(int) * len, "RNA equals") : fixed_b;
RNA_property_boolean_get_array(a, prop, array_a);
RNA_property_boolean_get_array(b, prop, array_b);
@@ -6655,8 +6697,8 @@ bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNAEq
int *array_a, *array_b;
bool equals;
- array_a = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals") : fixed_a;
- array_b = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals") : fixed_b;
+ array_a = (len > 16) ? MEM_mallocN(sizeof(int) * len, "RNA equals") : fixed_a;
+ array_b = (len > 16) ? MEM_mallocN(sizeof(int) * len, "RNA equals") : fixed_b;
RNA_property_int_get_array(a, prop, array_a);
RNA_property_int_get_array(b, prop, array_b);
@@ -6681,8 +6723,8 @@ bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNAEq
float *array_a, *array_b;
bool equals;
- array_a = (len > 16) ? MEM_callocN(sizeof(float) * len, "RNA equals") : fixed_a;
- array_b = (len > 16) ? MEM_callocN(sizeof(float) * len, "RNA equals") : fixed_b;
+ array_a = (len > 16) ? MEM_mallocN(sizeof(float) * len, "RNA equals") : fixed_a;
+ array_b = (len > 16) ? MEM_mallocN(sizeof(float) * len, "RNA equals") : fixed_b;
RNA_property_float_get_array(a, prop, array_a);
RNA_property_float_get_array(b, prop, array_b);
@@ -6712,7 +6754,7 @@ bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, eRNAEq
int len_a, len_b;
char *value_a = RNA_property_string_get_alloc(a, prop, fixed_a, sizeof(fixed_a), &len_a);
char *value_b = RNA_property_string_get_alloc(b, prop, fixed_b, sizeof(fixed_b), &len_b);
- bool equals = strcmp(value_a, value_b) == 0;
+ bool equals = STREQ(value_a, value_b);
if (value_a != fixed_a) MEM_freeN(value_a);
if (value_b != fixed_b) MEM_freeN(value_b);
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 750c98a536d..3fed505b9d6 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -60,7 +60,7 @@ static void rna_ActionGroup_channels_next(CollectionPropertyIterator *iter)
FCurve *fcu = (FCurve *)internal->link;
bActionGroup *grp = fcu->grp;
- /* only continue if the next F-Curve (if existant) belongs in the same group */
+ /* only continue if the next F-Curve (if existent) belongs in the same group */
if ((fcu->next) && (fcu->next->grp == grp))
internal->link = (Link *)fcu->next;
else
@@ -197,7 +197,7 @@ static void rna_Action_active_pose_marker_index_range(PointerRNA *ptr, int *min,
bAction *act = (bAction *)ptr->data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&act->markers) - 1);
+ *max = max_ii(0, BLI_listbase_count(&act->markers) - 1);
}
@@ -462,6 +462,12 @@ static void rna_def_dopesheet(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Display Speaker", "Include visualization of speaker related animation data");
RNA_def_property_ui_icon(prop, ICON_SPEAKER, 0);
RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
+ prop = RNA_def_property(srna, "show_gpencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOGPENCIL);
+ RNA_def_property_ui_text(prop, "Display Grease Pencil", "Include visualization of Grease Pencil related animation data and frames");
+ RNA_def_property_ui_icon(prop, ICON_GREASEPENCIL, 0);
+ RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
static void rna_def_action_group(BlenderRNA *brna)
@@ -527,7 +533,7 @@ static void rna_def_action_groups(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_struct_ui_text(srna, "Action Groups", "Collection of action groups");
func = RNA_def_function(srna, "new", "rna_Action_groups_new");
- RNA_def_function_ui_description(func, "Add a keyframe to the curve");
+ RNA_def_function_ui_description(func, "Create a new action group and add it to the action");
parm = RNA_def_string(func, "name", "Group", 0, "", "New name for the action group");
RNA_def_property_flag(parm, PROP_REQUIRED);
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index 0114ffa35c0..83a6d728d80 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -55,16 +55,16 @@ static EnumPropertyItem actuator_type_items[] = {
{ACT_2DFILTER, "FILTER_2D", 0, "Filter 2D", ""},
{ACT_GAME, "GAME", 0, "Game", ""},
{ACT_MESSAGE, "MESSAGE", 0, "Message", ""},
- {ACT_MOUSE, "MOUSE", 0, "Mouse", ""},
{ACT_OBJECT, "MOTION", 0, "Motion", ""},
+ {ACT_MOUSE, "MOUSE", 0, "Mouse", ""},
{ACT_PARENT, "PARENT", 0, "Parent", ""},
{ACT_PROPERTY, "PROPERTY", 0, "Property", ""},
{ACT_RANDOM, "RANDOM", 0, "Random", ""},
{ACT_SCENE, "SCENE", 0, "Scene", ""},
{ACT_SOUND, "SOUND", 0, "Sound", ""},
{ACT_STATE, "STATE", 0, "State", ""},
- {ACT_VISIBILITY, "VISIBILITY", 0, "Visibility", ""},
{ACT_STEERING, "STEERING", 0, "Steering", ""},
+ {ACT_VISIBILITY, "VISIBILITY", 0, "Visibility", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -120,14 +120,10 @@ static StructRNA *rna_Actuator_refine(struct PointerRNA *ptr)
static void rna_Actuator_name_set(PointerRNA *ptr, const char *value)
{
- bActuator *act = (bActuator *)ptr->data;
-
+ Object *ob = ptr->id.data;
+ bActuator *act = ptr->data;
BLI_strncpy_utf8(act->name, value, sizeof(act->name));
-
- if (ptr->id.data) {
- Object *ob = (Object *)ptr->id.data;
- BLI_uniquename(&ob->actuators, act, DATA_("Actuator"), '.', offsetof(bActuator, name), sizeof(act->name));
- }
+ BLI_uniquename(&ob->actuators, act, DATA_("Actuator"), '.', offsetof(bActuator, name), sizeof(act->name));
}
static void rna_Actuator_type_set(struct PointerRNA *ptr, int value)
@@ -494,11 +490,11 @@ static void rna_Actuator_Armature_update(Main *UNUSED(bmain), Scene *UNUSED(scen
bPoseChannel *pchan;
bPose *pose = ob->pose;
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- if (!strcmp(pchan->name, posechannel)) {
+ if (STREQ(pchan->name, posechannel)) {
/* found it, now look for constraint channel */
bConstraint *con;
for (con = pchan->constraints.first; con; con = con->next) {
- if (!strcmp(con->name, constraint)) {
+ if (STREQ(con->name, constraint)) {
/* found it, all ok */
return;
}
@@ -535,14 +531,6 @@ static void rna_Actuator_editobject_mesh_set(PointerRNA *ptr, PointerRNA value)
eoa->me = value.data;
}
-static void rna_Actuator_action_action_set(PointerRNA *ptr, PointerRNA value)
-{
- bActuator *act = (bActuator *)ptr->data;
- bActionActuator *aa = (bActionActuator *) act->data;
-
- aa->act = value.data;
-}
-
#else
static void rna_def_actuator(BlenderRNA *brna)
@@ -622,10 +610,8 @@ static void rna_def_action_actuator(BlenderRNA *brna)
prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "act");
RNA_def_property_struct_type(prop, "Action");
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Action", "");
- /* note: custom set function is ONLY to avoid rna setting a user for this. */
- RNA_def_property_pointer_funcs(prop, NULL, "rna_Actuator_action_action_set", NULL, NULL);
RNA_def_property_update(prop, NC_LOGIC, NULL);
prop = RNA_def_property(srna, "use_continue_last_frame", PROP_BOOLEAN, PROP_NONE);
@@ -2070,6 +2056,11 @@ static void rna_def_steering_actuator(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_STEERING_NORMALUP);
RNA_def_property_ui_text(prop, "N", "Use normal of the navmesh to set \"UP\" vector");
RNA_def_property_update(prop, NC_LOGIC, NULL);
+
+ prop = RNA_def_property(srna, "lock_z_velocity", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_STEERING_LOCKZVEL);
+ RNA_def_property_ui_text(prop, "Lock Z velocity", "Disable simulation of linear motion along Z axis");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
}
static void rna_def_mouse_actuator(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index f2881bf2541..df1e6dd55dd 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -343,7 +343,7 @@ static void rna_KeyingSet_name_set(PointerRNA *ptr, const char *value)
KeyingSet *ks = (KeyingSet *)ptr->data;
/* update names of corresponding groups if name changes */
- if (strcmp(ks->name, value)) {
+ if (!STREQ(ks->name, value)) {
KS_Path *ksp;
for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
@@ -359,7 +359,7 @@ static void rna_KeyingSet_name_set(PointerRNA *ptr, const char *value)
* conflicts
*/
for (agrp = adt->action->groups.first; agrp; agrp = agrp->next) {
- if (strcmp(ks->name, agrp->name) == 0) {
+ if (STREQ(ks->name, agrp->name)) {
/* there should only be one of these in the action, so can stop... */
BLI_strncpy(agrp->name, value, sizeof(agrp->name));
break;
@@ -414,7 +414,7 @@ static void rna_KeyingSet_active_ksPath_index_range(PointerRNA *ptr, int *min, i
KeyingSet *ks = (KeyingSet *)ptr->data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&ks->paths) - 1);
+ *max = max_ii(0, BLI_listbase_count(&ks->paths) - 1);
}
static PointerRNA rna_KeyingSet_typeinfo_get(PointerRNA *ptr)
@@ -445,7 +445,7 @@ static KS_Path *rna_KeyingSet_paths_add(KeyingSet *keyingset, ReportList *report
/* if data is valid, call the API function for this */
if (keyingset) {
ksp = BKE_keyingset_add_path(keyingset, id, group_name, rna_path, index, flag, group_method);
- keyingset->active_path = BLI_countlist(&keyingset->paths);
+ keyingset->active_path = BLI_listbase_count(&keyingset->paths);
}
else {
BKE_report(reports, RPT_ERROR, "Keying set path could not be added");
@@ -554,16 +554,46 @@ static FCurve *rna_Driver_from_existing(AnimData *adt, bContext *C, FCurve *src_
#else
/* helper function for Keying Set -> keying settings */
-/* TODO: use reg option! */
-static void rna_def_common_keying_flags(StructRNA *srna, short UNUSED(reg))
+static void rna_def_common_keying_flags(StructRNA *srna, short reg)
{
PropertyRNA *prop;
-
- prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "keyingflag");
- RNA_def_property_enum_items(prop, keying_flag_items);
- RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
- RNA_def_property_ui_text(prop, "Options", "Keying set options");
+
+ /* override scene/userpref defaults? */
+ prop = RNA_def_property(srna, "use_insertkey_override_needed", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "keyingoverride", INSERTKEY_NEEDED);
+ RNA_def_property_ui_text(prop, "Override Insert Keyframes Default- Only Needed",
+ "Override default setting to only insert keyframes where they're needed in the relevant F-Curves");
+ if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+ prop = RNA_def_property(srna, "use_insertkey_override_visual", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "keyingoverride", INSERTKEY_MATRIX);
+ RNA_def_property_ui_text(prop, "Override Insert Keyframes Default - Visual",
+ "Override default setting to insert keyframes based on 'visual transforms'");
+ if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+ prop = RNA_def_property(srna, "use_insertkey_override_xyz_to_rgb", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "keyingoverride", INSERTKEY_XYZ2RGB);
+ RNA_def_property_ui_text(prop, "Override F-Curve Colors - XYZ to RGB",
+ "Override default setting to set color for newly added transformation F-Curves "
+ "(Location, Rotation, Scale) to be based on the transform axis");
+ if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+
+ /* value to override defaults with */
+ prop = RNA_def_property(srna, "use_insertkey_needed", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_NEEDED);
+ RNA_def_property_ui_text(prop, "Insert Keyframes - Only Needed", "Only insert keyframes where they're needed in the relevant F-Curves");
+ if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+ prop = RNA_def_property(srna, "use_insertkey_visual", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_MATRIX);
+ RNA_def_property_ui_text(prop, "Insert Keyframes - Visual", "Insert keyframes based on 'visual transforms'");
+ if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
+ prop = RNA_def_property(srna, "use_insertkey_xyz_to_rgb", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_XYZ2RGB);
+ RNA_def_property_ui_text(prop, "F-Curve Colors - XYZ to RGB", "Color for newly added transformation F-Curves (Location, Rotation, Scale) is based on the transform axis");
+ if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
}
/* --- */
@@ -610,7 +640,20 @@ static void rna_def_keyingset_info(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
RNA_def_property_ui_text(prop, "Description", "A short description of the keying set");
- rna_def_common_keying_flags(srna, 1); /* '1' arg here is to indicate that we need these to be set on registering */
+ /* Regarding why we don't use rna_def_common_keying_flags() here:
+ * - Using it would keep this case in sync with the other places
+ * where these options are exposed (which are optimised for being
+ * used in the UI).
+ * - Unlike all the other places, this case is used for defining
+ * new "built in" Keying Sets via the Python API. In that case,
+ * it makes more sense to expose these in a way more similar to
+ * other places featuring bl_idname/label/description (i.e. operators)
+ */
+ prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "keyingflag");
+ RNA_def_property_enum_items(prop, keying_flag_items);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
+ RNA_def_property_ui_text(prop, "Options", "Keying Set options to use when inserting keyframes");
RNA_define_verify_sdna(1);
diff --git a/source/blender/makesrna/intern/rna_animviz.c b/source/blender/makesrna/intern/rna_animviz.c
index ee107fdfe9f..719eb9f8a20 100644
--- a/source/blender/makesrna/intern/rna_animviz.c
+++ b/source/blender/makesrna/intern/rna_animviz.c
@@ -66,33 +66,33 @@ 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;
+ CLAMP(data->ghost_ef, data->ghost_sf, MAXFRAME / 2);
}
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;
+ CLAMP(data->ghost_sf, 1, data->ghost_ef);
}
static void rna_AnimViz_path_start_frame_set(PointerRNA *ptr, int value)
{
bAnimVizSettings *data = (bAnimVizSettings *)ptr->data;
- CLAMP(value, 1, data->path_ef - 1);
+ /* XXX: watchit! Path Start > MAXFRAME/2 could be a problem... */
data->path_sf = value;
+ CLAMP(data->path_ef, data->path_sf + 1, MAXFRAME / 2);
}
static void rna_AnimViz_path_end_frame_set(PointerRNA *ptr, int value)
{
bAnimVizSettings *data = (bAnimVizSettings *)ptr->data;
- /* XXX: watchit! Path Start > MAXFRAME/2 could be a problem... */
- CLAMP(value, data->path_sf + 1, (int)(MAXFRAMEF / 2));
data->path_ef = value;
+ CLAMP(data->path_sf, 1, data->path_ef - 1);
}
#else
diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c
index 6233649fb12..33048a7196b 100644
--- a/source/blender/makesrna/intern/rna_boid.c
+++ b/source/blender/makesrna/intern/rna_boid.c
@@ -169,7 +169,7 @@ static void rna_BoidState_active_boid_rule_index_range(PointerRNA *ptr, int *min
{
BoidState *state = (BoidState *)ptr->data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&state->rules) - 1);
+ *max = max_ii(0, BLI_listbase_count(&state->rules) - 1);
}
static int rna_BoidState_active_boid_rule_index_get(PointerRNA *ptr)
@@ -235,7 +235,7 @@ static void rna_BoidSettings_active_boid_state_index_range(PointerRNA *ptr, int
{
BoidSettings *boids = (BoidSettings *)ptr->data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&boids->states) - 1);
+ *max = max_ii(0, BLI_listbase_count(&boids->states) - 1);
}
static int rna_BoidSettings_active_boid_state_index_get(PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index bbc2e0572fa..81ba3a9066f 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -194,14 +194,20 @@ static int rna_SculptToolCapabilities_has_random_texture_angle_get(PointerRNA *p
SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
}
-static int rna_BrushCapabilities_has_random_texture_angle_get(PointerRNA *ptr)
+static int rna_TextureCapabilities_has_random_texture_angle_get(PointerRNA *ptr)
{
- Brush *br = (Brush *)ptr->data;
- return (ELEM(br->mtex.brush_map_mode,
+ MTex *mtex = (MTex *)ptr->data;
+ return ELEM(mtex->brush_map_mode,
MTEX_MAP_MODE_VIEW,
MTEX_MAP_MODE_AREA,
- MTEX_MAP_MODE_RANDOM) &&
- !(br->flag & BRUSH_ANCHORED));
+ MTEX_MAP_MODE_RANDOM);
+}
+
+
+static int rna_BrushCapabilities_has_random_texture_angle_get(PointerRNA *ptr)
+{
+ Brush *br = (Brush *)ptr->data;
+ return !(br->flag & BRUSH_ANCHORED);
}
static int rna_SculptToolCapabilities_has_sculpt_plane_get(PointerRNA *ptr)
@@ -270,15 +276,10 @@ static int rna_SculptToolCapabilities_has_strength_pressure_get(PointerRNA *ptr)
return !ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK);
}
-static int rna_BrushCapabilities_has_texture_angle_get(PointerRNA *ptr)
+static int rna_TextureCapabilities_has_texture_angle_get(PointerRNA *ptr)
{
- Brush *br = (Brush *)ptr->data;
- return ELEM(br->mtex.brush_map_mode,
- MTEX_MAP_MODE_VIEW,
- MTEX_MAP_MODE_AREA,
- MTEX_MAP_MODE_TILED,
- MTEX_MAP_MODE_STENCIL,
- MTEX_MAP_MODE_RANDOM);
+ MTex *mtex = (MTex *)ptr->data;
+ return mtex->brush_map_mode != MTEX_MAP_MODE_3D;
}
static int rna_SculptToolCapabilities_has_gravity_get(PointerRNA *ptr)
@@ -287,10 +288,10 @@ static int rna_SculptToolCapabilities_has_gravity_get(PointerRNA *ptr)
return !ELEM(br->sculpt_tool, SCULPT_TOOL_MASK, SCULPT_TOOL_SMOOTH);
}
-static int rna_BrushCapabilities_has_texture_angle_source_get(PointerRNA *ptr)
+static int rna_TextureCapabilities_has_texture_angle_source_get(PointerRNA *ptr)
{
- Brush *br = (Brush *)ptr->data;
- return ELEM(br->mtex.brush_map_mode,
+ MTex *mtex = (MTex *)ptr->data;
+ return ELEM(mtex->brush_map_mode,
MTEX_MAP_MODE_VIEW,
MTEX_MAP_MODE_AREA,
MTEX_MAP_MODE_RANDOM);
@@ -627,6 +628,15 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+#define TEXTURE_CAPABILITY(prop_name_, ui_name_) \
+ prop = RNA_def_property(srna, #prop_name_, \
+ PROP_BOOLEAN, PROP_NONE); \
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); \
+ RNA_def_property_boolean_funcs(prop, "rna_TextureCapabilities_" \
+ #prop_name_ "_get", NULL); \
+ RNA_def_property_ui_text(prop, ui_name_, NULL)
+
+
srna = RNA_def_struct(brna, "BrushTextureSlot", "TextureSlot");
RNA_def_struct_sdna(srna, "MTex");
RNA_def_struct_ui_text(srna, "Brush Texture Slot", "Texture slot for textures in a Brush datablock");
@@ -654,6 +664,25 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_mask_paint_map_mode_items);
RNA_def_property_ui_text(prop, "Mode", "");
RNA_def_property_update(prop, 0, "rna_TextureSlot_brush_update");
+
+ prop = RNA_def_property(srna, "use_rake", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "brush_angle_mode", MTEX_ANGLE_RAKE);
+ RNA_def_property_ui_text(prop, "Rake", "");
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_brush_update");
+
+ prop = RNA_def_property(srna, "use_random", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "brush_angle_mode", MTEX_ANGLE_RANDOM);
+ RNA_def_property_ui_text(prop, "Random", "");
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_brush_update");
+
+ prop = RNA_def_property(srna, "random_angle", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_range(prop, 0, M_PI * 2);
+ RNA_def_property_ui_text(prop, "Random Angle", "Brush texture random angle");
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_brush_update");
+
+ TEXTURE_CAPABILITY(has_texture_angle_source, "Has Texture Angle Source");
+ TEXTURE_CAPABILITY(has_random_texture_angle, "Has Random Texture Angle");
+ TEXTURE_CAPABILITY(has_texture_angle, "Has Texture Angle Source");
}
static void rna_def_sculpt_capabilities(BlenderRNA *brna)
@@ -717,8 +746,6 @@ static void rna_def_brush_capabilities(BlenderRNA *brna)
BRUSH_CAPABILITY(has_overlay, "Has Overlay");
BRUSH_CAPABILITY(has_random_texture_angle, "Has Random Texture Angle");
- BRUSH_CAPABILITY(has_texture_angle, "Has Texture Angle");
- BRUSH_CAPABILITY(has_texture_angle_source, "Has Texture Angle Source");
BRUSH_CAPABILITY(has_spacing, "Has Spacing");
BRUSH_CAPABILITY(has_smooth_stroke, "Has Smooth Stroke");
@@ -786,19 +813,6 @@ static void rna_def_brush(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
- static EnumPropertyItem texture_angle_source_items[] = {
- {0, "USER", 0, "User", "Rotate the brush texture by given angle"},
- {BRUSH_RAKE, "RAKE", 0, "Rake", "Rotate the brush texture to match the stroke direction"},
- {BRUSH_RANDOM_ROTATION, "RANDOM", 0, "Random", "Rotate the brush texture at random"},
- {0, NULL, 0, NULL, NULL}
- };
-
- static EnumPropertyItem texture_angle_source_no_random_items[] = {
- {0, "USER", 0, "User", "Rotate the brush texture by given angle"},
- {BRUSH_RAKE, "RAKE", 0, "Rake", "Rotate the brush texture to match the stroke direction"},
- {0, NULL, 0, NULL, NULL}
- };
-
static EnumPropertyItem brush_sculpt_plane_items[] = {
{SCULPT_DISP_DIR_AREA, "AREA", 0, "Area Plane", ""},
{SCULPT_DISP_DIR_VIEW, "VIEW", 0, "View Plane", ""},
@@ -881,18 +895,6 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Stroke Method", "");
RNA_def_property_update(prop, 0, "rna_Brush_stroke_update");
- prop = RNA_def_property(srna, "texture_angle_source_random", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
- RNA_def_property_enum_items(prop, texture_angle_source_items);
- RNA_def_property_ui_text(prop, "Texture Angle Source", "");
- RNA_def_property_update(prop, 0, "rna_Brush_update");
-
- prop = RNA_def_property(srna, "texture_angle_source_no_random", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
- RNA_def_property_enum_items(prop, texture_angle_source_no_random_items);
- RNA_def_property_ui_text(prop, "Texture Angle Source", "");
- RNA_def_property_update(prop, 0, "rna_Brush_update");
-
prop = RNA_def_property(srna, "sculpt_plane", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, brush_sculpt_plane_items);
RNA_def_property_ui_text(prop, "Sculpt Plane", "");
@@ -1158,22 +1160,12 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Inverse Smooth Pressure", "Lighter pressure causes more smoothing to be applied");
RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop = RNA_def_property(srna, "use_rake", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RAKE);
- RNA_def_property_ui_text(prop, "Rake", "Rotate the brush texture to match the stroke direction");
- RNA_def_property_update(prop, 0, "rna_Brush_update");
-
prop = RNA_def_property(srna, "use_relative_jitter", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BRUSH_ABSOLUTE_JITTER);
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, true);
RNA_def_property_ui_text(prop, "Absolute Jitter", "Jittering happens in screen space, not relative to brush size");
RNA_def_property_update(prop, 0, "rna_Brush_update");
- prop = RNA_def_property(srna, "use_random_rotation", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RANDOM_ROTATION);
- RNA_def_property_ui_text(prop, "Random Rotation", "Rotate the brush texture at random");
- RNA_def_property_update(prop, 0, "rna_Brush_update");
-
prop = RNA_def_property(srna, "use_plane_trim", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_PLANE_TRIM);
RNA_def_property_ui_text(prop, "Use Plane Trim", "Enable Plane Trim");
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index be973ab33f8..31e991dd2b6 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -137,7 +137,7 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_draw_type_extra_items);
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
RNA_def_property_ui_text(prop, "Composition Guides", "Draw overlay");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+ RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL);
prop = RNA_def_property(srna, "sensor_fit", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "sensor_fit");
@@ -150,7 +150,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "passepartout_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "passepartalpha");
RNA_def_property_ui_text(prop, "Passepartout Alpha", "Opacity (alpha) of the darkened overlay in Camera view");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+ RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL);
prop = RNA_def_property(srna, "angle_x", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_range(prop, DEG2RAD(0.367), DEG2RAD(172.847));
@@ -256,22 +256,27 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOWPASSEPARTOUT);
RNA_def_property_ui_text(prop, "Show Passepartout",
"Show a darkened overlay outside the image area in Camera view");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+ RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL);
- prop = RNA_def_property(srna, "show_title_safe", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOWTITLESAFE);
- RNA_def_property_ui_text(prop, "Show Safe Areas", "Show TV title safe and action safe zones in Camera view");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+ prop = RNA_def_property(srna, "show_safe_areas", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOW_SAFE_MARGINS);
+ RNA_def_property_ui_text(prop, "Show Safe Areas", "Show TV title safe and action safe areas in Camera view");
+ RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL);
+
+ prop = RNA_def_property(srna, "show_safe_center", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOW_SAFE_CENTER);
+ RNA_def_property_ui_text(prop, "Show Center-cut safe areas", "Show safe areas to fit content in a different aspect ratio");
+ RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL);
prop = RNA_def_property(srna, "show_name", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOWNAME);
RNA_def_property_ui_text(prop, "Show Name", "Show the active Camera's name in Camera view");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+ RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL);
prop = RNA_def_property(srna, "show_sensor", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOWSENSOR);
RNA_def_property_ui_text(prop, "Show Sensor Size", "Show sensor size (film gate) in Camera view");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+ RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL);
prop = RNA_def_property(srna, "lens_unit", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
@@ -279,8 +284,6 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Lens Unit", "Unit to edit lens in for the user interface");
/* pointers */
- rna_def_animdata_common(srna);
-
prop = RNA_def_property(srna, "dof_object", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_pointer_sdna(prop, NULL, "dof_ob");
@@ -288,6 +291,13 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "DOF Object", "Use this object to define the depth of field focal point");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+ prop = RNA_def_property(srna, "gpu_dof", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "GPUDOFSettings");
+ RNA_def_property_ui_text(prop, "GPU Depth Of Field", "");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+ rna_def_animdata_common(srna);
+
/* Camera API */
RNA_api_camera(srna);
}
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index cecc39c8e15..bcb3544049c 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -38,6 +38,8 @@
#include "BKE_cloth.h"
#include "BKE_modifier.h"
+#include "BPH_mass_spring.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -66,17 +68,6 @@ static void rna_cloth_pinning_changed(Main *UNUSED(bmain), Scene *UNUSED(scene),
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
}
-static void rna_cloth_reset(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
-{
- Object *ob = (Object *)ptr->id.data;
- ClothSimSettings *settings = (ClothSimSettings *)ptr->data;
-
- settings->reset = 1;
-
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
-}
-
static void rna_ClothSettings_max_bend_set(struct PointerRNA *ptr, float value)
{
@@ -268,6 +259,64 @@ static char *rna_ClothCollisionSettings_path(PointerRNA *ptr)
#else
+static void rna_def_cloth_solver_result(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem status_items[] = {
+ {BPH_SOLVER_SUCCESS, "SUCCESS", 0, "Success", "Computation was successful"},
+ {BPH_SOLVER_NUMERICAL_ISSUE, "NUMERICAL_ISSUE", 0, "Numerical Issue", "The provided data did not satisfy the prerequisites"},
+ {BPH_SOLVER_NO_CONVERGENCE, "NO_CONVERGENCE", 0, "No Convergence", "Iterative procedure did not converge"},
+ {BPH_SOLVER_INVALID_INPUT, "INVALID_INPUT", 0, "Invalid Input", "The inputs are invalid, or the algorithm has been improperly called"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "ClothSolverResult", NULL);
+ RNA_def_struct_ui_text(srna, "Solver Result", "Result of cloth solver iteration");
+
+ RNA_define_verify_sdna(0);
+
+ prop = RNA_def_property(srna, "status", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, status_items);
+ RNA_def_property_enum_sdna(prop, NULL, "status");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Status", "Status of the solver iteration");
+
+ prop = RNA_def_property(srna, "max_error", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "max_error");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Maximum Error", "Maximum error during substeps");
+
+ prop = RNA_def_property(srna, "min_error", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "min_error");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Minimum Error", "Minimum error during substeps");
+
+ prop = RNA_def_property(srna, "avg_error", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "avg_error");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Average Error", "Average error during substeps");
+
+ prop = RNA_def_property(srna, "max_iterations", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "max_iterations");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Maximum Iterations", "Maximum iterations during substeps");
+
+ prop = RNA_def_property(srna, "min_iterations", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "min_iterations");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Minimum Iterations", "Minimum iterations during substeps");
+
+ prop = RNA_def_property(srna, "avg_iterations", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "avg_iterations");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Average Iterations", "Average iterations during substeps");
+
+ RNA_define_verify_sdna(1);
+}
+
static void rna_def_cloth_sim_settings(BlenderRNA *brna)
{
StructRNA *srna;
@@ -325,6 +374,18 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Collider Friction", "");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+ prop = RNA_def_property(srna, "density_target", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "density_target");
+ RNA_def_property_range(prop, 0.0f, 10000.0f);
+ RNA_def_property_ui_text(prop, "Target Density", "Maximum density of hair");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
+ prop = RNA_def_property(srna, "density_strength", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "density_strength");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Target Density Strength", "Influence of target density on the simulation");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
/* mass */
prop = RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
@@ -375,7 +436,7 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "quality", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "stepsPerFrame");
- RNA_def_property_range(prop, 4, 80);
+ RNA_def_property_range(prop, 1, 80);
RNA_def_property_ui_text(prop, "Quality",
"Quality of the simulation in steps per frame (higher is better quality but slower)");
RNA_def_property_update(prop, 0, "rna_cloth_update");
@@ -398,6 +459,13 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Shrink Factor Max", "Max amount to shrink cloth by");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+ prop = RNA_def_property(srna, "voxel_cell_size", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_float_sdna(prop, NULL, "voxel_cell_size");
+ RNA_def_property_range(prop, 0.0001f, 10000.0f);
+ RNA_def_property_float_default(prop, 0.1f);
+ RNA_def_property_ui_text(prop, "Voxel Grid Cell Size", "Size of the voxel grid cells for interaction effects");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
/* springs */
prop = RNA_def_property(srna, "use_stiffness_scale", PROP_BOOLEAN, PROP_NONE);
@@ -456,6 +524,13 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Bending Stiffness Maximum", "Maximum bending stiffness value");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+ prop = RNA_def_property(srna, "bending_damping", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "bending_damping");
+ RNA_def_property_range(prop, 0.0f, 1000.0f);
+ RNA_def_property_ui_text(prop, "Bending Spring Damping",
+ "Damping of bending motion");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
prop = RNA_def_property(srna, "use_sewing_springs", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_SEW);
RNA_def_property_ui_text(prop, "Sew Cloth", "Pulls loose edges together");
@@ -473,12 +548,6 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Effector Weights", "");
- prop = RNA_def_property(srna, "pre_roll", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "preroll");
- RNA_def_property_range(prop, 0, MAXFRAME);
- RNA_def_property_ui_text(prop, "Pre Roll", "Start simulation a number of frames earlier to let the cloth settle in");
- RNA_def_property_update(prop, 0, "rna_cloth_reset");
-
prop = RNA_def_property(srna, "rest_shape_key", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "ShapeKey");
@@ -577,6 +646,13 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Friction", "Friction force if a collision happened (higher = less movement)");
RNA_def_property_update(prop, 0, "rna_cloth_update");
+ prop = RNA_def_property(srna, "damping", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "damping");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_text(prop, "Restitution", "Amount of velocity lost on collision");
+ RNA_def_property_update(prop, 0, "rna_cloth_update");
+
prop = RNA_def_property(srna, "collision_quality", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "loop_count");
RNA_def_property_range(prop, 1, 20);
@@ -625,6 +701,7 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
void RNA_def_cloth(BlenderRNA *brna)
{
+ rna_def_cloth_solver_result(brna);
rna_def_cloth_sim_settings(brna);
rna_def_cloth_collision_settings(brna);
}
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index fa2a3258d1a..5e114a51ceb 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -46,6 +46,8 @@
#include "DNA_material_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
#include "DNA_sequence_types.h"
#include "MEM_guardedalloc.h"
@@ -345,6 +347,13 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
WM_main_add_notifier(NC_LINESTYLE, linestyle);
break;
}
+ case ID_PA:
+ {
+ ParticleSettings *part = ptr->id.data;
+
+ DAG_id_tag_update(&part->id, OB_RECALC_DATA | PSYS_RECALC_REDO);
+ WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, part);
+ }
default:
break;
}
@@ -614,6 +623,10 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain)
IMB_free_anim(seq->anim);
seq->anim = NULL;
}
+ if (seq->strip->proxy && seq->strip->proxy->anim) {
+ IMB_free_anim(seq->strip->proxy->anim);
+ seq->strip->proxy->anim = NULL;
+ }
BKE_sequence_invalidate_cache(scene, seq);
BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 77355dbad0e..aaacf07567e 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -1388,7 +1388,7 @@ static void rna_def_constraint_stretch_to(BlenderRNA *brna)
prop = RNA_def_property(srna, "bulge_smooth", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_range(prop, 0.0, 1.0f);
- RNA_def_property_ui_text(prop, "Volume Variation Smoothness", "");
+ RNA_def_property_ui_text(prop, "Volume Variation Smoothness", "Strength of volume stretching clamping");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
}
@@ -2272,8 +2272,10 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
{CONSTRAINT_SPLINEIK_XZS_NONE, "NONE", 0, "None", "Don't scale the X and Z axes (Default)"},
{CONSTRAINT_SPLINEIK_XZS_ORIGINAL, "BONE_ORIGINAL", 0, "Bone Original",
"Use the original scaling of the bones"},
+ {CONSTRAINT_SPLINEIK_XZS_INVERSE, "INVERSE_PRESERVE", 0, "Inverse Scale",
+ "Scale of the X and Z axes is the inverse of the Y-Scale"},
{CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC, "VOLUME_PRESERVE", 0, "Volume Preservation",
- "Scale of the X and Z axes is the inverse of the Y-Scale"},
+ "Scale of the X and Z axes are adjusted to preserve the volume of the bones"},
{0, NULL, 0, NULL, NULL}
};
@@ -2284,6 +2286,7 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
/* target chain */
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tar");
+ RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Curve_object_poll");
RNA_def_property_ui_text(prop, "Target", "Curve that controls this relationship");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
@@ -2333,12 +2336,44 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
"on top of XZ Scale mode");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+ /* xz scaling mode */
prop = RNA_def_property(srna, "xz_scale_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "xzScaleMode");
RNA_def_property_enum_items(prop, splineik_xz_scale_mode);
RNA_def_property_ui_text(prop, "XZ Scale Mode",
"Method used for determining the scaling of the X and Z axes of the bones");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ /* volume presevation for "volumetric" scale mode */
+ prop = RNA_def_property(srna, "bulge", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0, 100.f);
+ RNA_def_property_ui_text(prop, "Volume Variation", "Factor between volume variation and stretching");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "use_bulge_min", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_USE_BULGE_MIN);
+ RNA_def_property_ui_text(prop, "Use Volume Variation Minimum", "Use lower limit for volume variation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "use_bulge_max", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_USE_BULGE_MAX);
+ RNA_def_property_ui_text(prop, "Use Volume Variation Maximum", "Use upper limit for volume variation");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "bulge_min", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0, 1.0f);
+ RNA_def_property_ui_text(prop, "Volume Variation Minimum", "Minimum volume stretching factor");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "bulge_max", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 1.0, 100.0f);
+ RNA_def_property_ui_text(prop, "Volume Variation Maximum", "Maximum volume stretching factor");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop = RNA_def_property(srna, "bulge_smooth", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_range(prop, 0.0, 1.0f);
+ RNA_def_property_ui_text(prop, "Volume Variation Smoothness", "Strength of volume stretching clamping");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
}
static void rna_def_constraint_pivot(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_controller.c b/source/blender/makesrna/intern/rna_controller.c
index 8b5074eaf0d..ba0214d36ec 100644
--- a/source/blender/makesrna/intern/rna_controller.c
+++ b/source/blender/makesrna/intern/rna_controller.c
@@ -85,15 +85,10 @@ static StructRNA *rna_Controller_refine(struct PointerRNA *ptr)
static void rna_Constroller_name_set(PointerRNA *ptr, const char *value)
{
- bController *cont = (bController *)ptr->data;
-
+ Object *ob = ptr->id.data;
+ bController *cont = ptr->data;
BLI_strncpy_utf8(cont->name, value, sizeof(cont->name));
-
- if (ptr->id.data) {
- Object *ob = (Object *)ptr->id.data;
- BLI_uniquename(&ob->controllers, cont, DATA_("Controller"), '.', offsetof(bController, name),
- sizeof(cont->name));
- }
+ BLI_uniquename(&ob->controllers, cont, DATA_("Controller"), '.', offsetof(bController, name), sizeof(cont->name));
}
static void rna_Controller_type_set(struct PointerRNA *ptr, int value)
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 6668ce812cf..6a0ae0a60f8 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -65,15 +65,15 @@ BlenderDefRNA DefRNA = {NULL, {NULL, NULL}, {NULL, NULL}, NULL, 0, 0, 0, 1, 1};
/* Duplicated code since we can't link in blenkernel or blenlib */
-/* pedantic check for '.', do this since its a hassle for translators */
+/* pedantic check for final '.', note '...' are allowed though. */
#ifndef NDEBUG
-# define DESCR_CHECK(description, id1, id2) \
- if (description && (description)[0]) { \
- int i = strlen(description); \
- if ((description)[i - 1] == '.') { \
- fprintf(stderr, "%s: '%s' '%s' description ends with a '.' !\n", \
- __func__, id1 ? id1 : "", id2 ? id2 : ""); \
- } \
+# define DESCR_CHECK(description, id1, id2) \
+ if (description && (description)[0]) { \
+ int i = strlen(description); \
+ if (i > 3 && (description)[i - 1] == '.' && (description)[i - 3] != '.') { \
+ fprintf(stderr, "%s: '%s' '%s' description ends with a '.' !\n", \
+ __func__, id1 ? id1 : "", id2 ? id2 : ""); \
+ } \
} (void)0
#else
@@ -109,7 +109,7 @@ PropertyDefRNA *rna_findlink(ListBase *listbase, const char *identifier)
for (link = listbase->first; link; link = link->next) {
PropertyRNA *prop = ((PropertyDefRNA *)link)->prop;
- if (prop && (strcmp(prop->identifier, identifier) == 0)) {
+ if (prop && (STREQ(prop->identifier, identifier))) {
return (PropertyDefRNA *)link;
}
}
@@ -428,7 +428,7 @@ static int rna_validate_identifier(const char *identifier, char *error, bool pro
}
for (a = 0; kwlist[a]; a++) {
- if (strcmp(identifier, kwlist[a]) == 0) {
+ if (STREQ(identifier, kwlist[a])) {
strcpy(error, "this keyword is reserved by python");
return 0;
}
@@ -442,7 +442,7 @@ static int rna_validate_identifier(const char *identifier, char *error, bool pro
};
for (a = 0; kwlist_prop[a]; a++) {
- if (strcmp(identifier, kwlist_prop[a]) == 0) {
+ if (STREQ(identifier, kwlist_prop[a])) {
strcpy(error, "this keyword is reserved by python");
return 0;
}
@@ -496,7 +496,7 @@ void RNA_identifier_sanitize(char *identifier, int property)
}
for (a = 0; kwlist[a]; a++) {
- if (strcmp(identifier, kwlist[a]) == 0) {
+ if (STREQ(identifier, kwlist[a])) {
/* this keyword is reserved by python.
* just replace the last character by '_' to keep it readable.
*/
@@ -513,7 +513,7 @@ void RNA_identifier_sanitize(char *identifier, int property)
};
for (a = 0; kwlist_prop[a]; a++) {
- if (strcmp(identifier, kwlist_prop[a]) == 0) {
+ if (STREQ(identifier, kwlist_prop[a])) {
/* this keyword is reserved by python.
* just replace the last character by '_' to keep it readable.
*/
@@ -639,7 +639,7 @@ void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
if (srna->flag & STRUCT_RUNTIME)
rna_freelinkN(&brna->structs, srna);
#else
- (void)brna, (void)srna;
+ UNUSED_VARS(brna, srna);
#endif
}
@@ -814,7 +814,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
if (from) {
/* find struct to derive from */
for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
- if (strcmp(srnafrom->identifier, from) == 0)
+ if (STREQ(srnafrom->identifier, from))
break;
if (!srnafrom) {
@@ -896,7 +896,7 @@ void RNA_def_struct_nested(BlenderRNA *brna, StructRNA *srna, const char *struct
/* find struct to derive from */
for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
- if (strcmp(srnafrom->identifier, structname) == 0)
+ if (STREQ(srnafrom->identifier, structname))
break;
if (!srnafrom) {
@@ -1550,6 +1550,7 @@ void RNA_def_property_boolean_default(PropertyRNA *prop, int value)
case PROP_BOOLEAN:
{
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
+ BLI_assert(ELEM(value, false, true));
bprop->defaultvalue = value;
break;
}
@@ -1871,15 +1872,15 @@ void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const
}
/* SDNA doesn't pass us unsigned unfortunately .. */
- if (dp->dnatype && strcmp(dp->dnatype, "char") == 0) {
+ if (dp->dnatype && STREQ(dp->dnatype, "char")) {
iprop->hardmin = iprop->softmin = CHAR_MIN;
iprop->hardmax = iprop->softmax = CHAR_MAX;
}
- else if (dp->dnatype && strcmp(dp->dnatype, "short") == 0) {
+ else if (dp->dnatype && STREQ(dp->dnatype, "short")) {
iprop->hardmin = iprop->softmin = SHRT_MIN;
iprop->hardmax = iprop->softmax = SHRT_MAX;
}
- else if (dp->dnatype && strcmp(dp->dnatype, "int") == 0) {
+ else if (dp->dnatype && STREQ(dp->dnatype, "int")) {
iprop->hardmin = INT_MIN;
iprop->hardmax = INT_MAX;
@@ -1923,7 +1924,7 @@ void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, cons
}
}
- if (dp->dnatype && strcmp(dp->dnatype, "char") == 0) {
+ if (dp->dnatype && STREQ(dp->dnatype, "char")) {
fprop->hardmin = fprop->softmin = 0.0f;
fprop->hardmax = fprop->softmax = 1.0f;
}
@@ -2060,7 +2061,7 @@ void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname,
}
}
- if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) {
+ if (dp->dnatype && STREQ(dp->dnatype, "ListBase")) {
cprop->next = (PropCollectionNextFunc)"rna_iterator_listbase_next";
cprop->get = (PropCollectionGetFunc)"rna_iterator_listbase_get";
cprop->end = (PropCollectionEndFunc)"rna_iterator_listbase_end";
@@ -3427,7 +3428,7 @@ int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *ide
PropertyRNA *prop;
for (prop = cont->properties.first; prop; prop = prop->next) {
- if (strcmp(prop->identifier, identifier) == 0) {
+ if (STREQ(prop->identifier, identifier)) {
if (prop->flag & PROP_RUNTIME) {
rna_def_property_free(cont_, prop);
return 1;
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index 4288bf2dddb..229cdaa6005 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -203,7 +203,7 @@ static void rna_Surface_active_point_range(PointerRNA *ptr, int *min, int *max,
DynamicPaintCanvasSettings *canvas = (DynamicPaintCanvasSettings *)ptr->data;
*min = 0;
- *max = BLI_countlist(&canvas->surfaces) - 1;
+ *max = BLI_listbase_count(&canvas->surfaces) - 1;
}
/* uvlayer */
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 3b9078153f3..6c893255601 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1948,6 +1948,10 @@ static void rna_def_fcurve(BlenderRNA *brna)
parm = RNA_def_pointer(func, "data", "AnyType", "Data",
"Data containing the property controlled by given FCurve");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
+
+
+ /* Functions */
+ RNA_api_fcurves(srna);
}
/* *********************** */
diff --git a/source/blender/makesrna/intern/rna_fcurve_api.c b/source/blender/makesrna/intern/rna_fcurve_api.c
index ab96f6f384d..8551ca609f4 100644
--- a/source/blender/makesrna/intern/rna_fcurve_api.c
+++ b/source/blender/makesrna/intern/rna_fcurve_api.c
@@ -39,6 +39,7 @@
#include "RNA_define.h"
#include "DNA_anim_types.h"
+#include "DNA_scene_types.h"
#include "rna_internal.h" /* own include */
@@ -49,8 +50,115 @@
#include "BKE_animsys.h"
#include "BKE_fcurve.h"
+#include "BLI_math.h"
+
+static void rna_FCurve_convert_to_samples(FCurve *fcu, ReportList *reports, int start, int end)
+{
+ /* XXX fcurve_store_samples uses end frame included, which is not consistent with usual behavior in Blender,
+ * nor python slices, etc. Let have public py API be consistent here at least. */
+ end--;
+ if (start > end) {
+ BKE_reportf(reports, RPT_ERROR, "Invalid frame range (%d - %d)", start, end + 1);
+ }
+ else if (fcu->fpt) {
+ BKE_report(reports, RPT_WARNING, "FCurve has already sample points");
+ }
+ else if (!fcu->bezt) {
+ BKE_report(reports, RPT_WARNING, "FCurve has no keyframes");
+ }
+ else {
+ fcurve_store_samples(fcu, NULL, start, end, fcurve_samplingcb_evalcurve);
+ WM_main_add_notifier(NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ }
+}
+
+static void rna_FCurve_convert_to_keyframes(FCurve *fcu, ReportList *reports, int start, int end)
+{
+ if (start >= end) {
+ BKE_reportf(reports, RPT_ERROR, "Invalid frame range (%d - %d)", start, end);
+ }
+ else if (fcu->bezt) {
+ BKE_report(reports, RPT_WARNING, "FCurve has already keyframes");
+ }
+ else if (!fcu->fpt) {
+ BKE_report(reports, RPT_WARNING, "FCurve has no sample points");
+ }
+ else {
+ BezTriple *bezt;
+ FPoint *fpt = fcu->fpt;
+ int tot_kf = end - start;
+ int tot_sp = fcu->totvert;
+
+ bezt = fcu->bezt = MEM_callocN(sizeof(*fcu->bezt) * (size_t)tot_kf, __func__);
+ fcu->totvert = tot_kf;
+
+ /* Get first sample point to 'copy' as keyframe. */
+ for (; tot_sp && (fpt->vec[0] < (float)start); fpt++, tot_sp--);
+
+ /* Add heading dummy flat points if needed. */
+ for (; tot_kf && (fpt->vec[0] > (float)start); start++, bezt++, tot_kf--) {
+ /* Linear interpolation, of course. */
+ bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
+ bezt->ipo = BEZT_IPO_LIN;
+ bezt->h1 = bezt->h2 = HD_AUTO_ANIM;
+ bezt->vec[1][0] = (float)start;
+ bezt->vec[1][1] = fpt->vec[1];
+ }
+
+ /* Copy actual sample points. */
+ for (; tot_kf && tot_sp; start++, bezt++, tot_kf--, fpt++, tot_sp--) {
+ /* Linear interpolation, of course. */
+ bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
+ bezt->ipo = BEZT_IPO_LIN;
+ bezt->h1 = bezt->h2 = HD_AUTO_ANIM;
+ copy_v2_v2(bezt->vec[1], fpt->vec);
+ }
+
+ /* Add leading dummy flat points if needed. */
+ for (fpt--; tot_kf; start++, bezt++, tot_kf--) {
+ /* Linear interpolation, of course. */
+ bezt->f1 = bezt->f2 = bezt->f3 = SELECT;
+ bezt->ipo = BEZT_IPO_LIN;
+ bezt->h1 = bezt->h2 = HD_AUTO_ANIM;
+ bezt->vec[1][0] = (float)start;
+ bezt->vec[1][1] = fpt->vec[1];
+ }
+
+ MEM_SAFE_FREE(fcu->fpt);
+
+ /* Not strictly needed since we use linear interpolation, but better be consistent here. */
+ calchandles_fcurve(fcu);
+ WM_main_add_notifier(NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ }
+}
+
#else
+void RNA_api_fcurves(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func = RNA_def_function(srna, "convert_to_samples", "rna_FCurve_convert_to_samples");
+ RNA_def_function_ui_description(func,
+ "Convert current FCurve from keyframes to sample points, if necessary");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_int(func, "start", 0, MINAFRAME, MAXFRAME, "Start Frame", "", MINAFRAME, MAXFRAME);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_int(func, "end", 0, MINAFRAME, MAXFRAME, "End Frame", "", MINAFRAME, MAXFRAME);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func = RNA_def_function(srna, "convert_to_keyframes", "rna_FCurve_convert_to_keyframes");
+ RNA_def_function_ui_description(func,
+ "Convert current FCurve from sample points to keyframes (linear interpolation), "
+ "if necessary");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_int(func, "start", 0, MINAFRAME, MAXFRAME, "Start Frame", "", MINAFRAME, MAXFRAME);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_int(func, "end", 0, MINAFRAME, MAXFRAME, "End Frame", "", MINAFRAME, MAXFRAME);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+
void RNA_api_drivers(StructRNA *UNUSED(srna))
{
/* FunctionRNA *func; */
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index c4677710676..6b61b37ce5c 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -44,6 +44,8 @@
#ifdef RNA_RUNTIME
+#include "BLI_math.h"
+
#include "WM_api.h"
#include "BKE_gpencil.h"
@@ -53,6 +55,16 @@ static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
}
+static char *rna_GPencilLayer_path(PointerRNA *ptr)
+{
+ bGPDlayer *gpl = (bGPDlayer *)ptr->data;
+ char name_esc[sizeof(gpl->info) * 2];
+
+ BLI_strescape(name_esc, gpl->info, sizeof(name_esc));
+
+ return BLI_sprintfN("layers[\"%s\"]", name_esc);
+}
+
static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr)
{
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
@@ -64,9 +76,54 @@ static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr)
return 1;
}
-static PointerRNA rna_GPencil_active_layer_get(PointerRNA *ptr)
+static void rna_GPencilLayer_line_width_range(PointerRNA *ptr, int *min, int *max,
+ int *softmin, int *softmax)
{
+ bGPDlayer *gpl = ptr->data;
+
+ /* The restrictions on max width here are due to OpenGL on Windows not supporting
+ * any widths greater than 10 (for driver-drawn) strokes/points.
+ *
+ * Although most of our 2D strokes also don't suffer from this restriction,
+ * it's relatively hard to test for that. So, for now, only volumetric strokes
+ * get to be larger...
+ */
+ if (gpl->flag & GP_LAYER_VOLUMETRIC) {
+ *min = 1;
+ *max = 300;
+
+ *softmin = 1;
+ *softmax = 100;
+ }
+ else {
+ *min = 1;
+ *max = 10;
+
+ *softmin = 1;
+ *softmax = 10;
+ }
+}
+static int rna_GPencilLayer_is_stroke_visible_get(PointerRNA *ptr)
+{
+ /* see drawgpencil.c -> gp_draw_data_layers() for more details
+ * about this limit for showing/not showing
+ */
+ bGPDlayer *gpl = (bGPDlayer *)ptr->data;
+ return (gpl->color[3] > 0.001f);
+}
+
+static int rna_GPencilLayer_is_fill_visible_get(PointerRNA *ptr)
+{
+ /* see drawgpencil.c -> gp_draw_data_layers() for more details
+ * about this limit for showing/not showing
+ */
+ bGPDlayer *gpl = (bGPDlayer *)ptr->data;
+ return (gpl->fill[3] > 0.001f);
+}
+
+static PointerRNA rna_GPencil_active_layer_get(PointerRNA *ptr)
+{
bGPdata *gpd = ptr->id.data;
if (GS(gpd->id.name) == ID_GD) { /* why would this ever be not GD */
@@ -106,6 +163,33 @@ static void rna_GPencil_active_layer_set(PointerRNA *ptr, PointerRNA value)
}
}
+static int rna_GPencil_active_layer_index_get(PointerRNA *ptr)
+{
+ bGPdata *gpd = (bGPdata *)ptr->id.data;
+ bGPDlayer *gpl = gpencil_layer_getactive(gpd);
+
+ return BLI_findindex(&gpd->layers, gpl);
+}
+
+static void rna_GPencil_active_layer_index_set(PointerRNA *ptr, int value)
+{
+ bGPdata *gpd = (bGPdata *)ptr->id.data;
+ bGPDlayer *gpl = BLI_findlink(&gpd->layers, value);
+
+ gpencil_layer_setactive(gpd, gpl);
+}
+
+static void rna_GPencil_active_layer_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+{
+ bGPdata *gpd = (bGPdata *)ptr->id.data;
+
+ *min = 0;
+ *max = max_ii(0, BLI_listbase_count(&gpd->layers) - 1);
+
+ *softmin = *min;
+ *softmax = *max;
+}
+
static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value)
{
bGPdata *gpd = ptr->id.data;
@@ -117,6 +201,63 @@ static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value)
BLI_uniquename(&gpd->layers, gpl, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
}
+
+static bGPDstroke *rna_GPencil_stroke_point_find_stroke(const bGPdata *gpd, const bGPDspoint *pt, bGPDlayer **r_gpl, bGPDframe **r_gpf)
+{
+ bGPDlayer *gpl;
+ bGPDstroke *gps;
+
+ /* sanity checks */
+ if (ELEM(NULL, gpd, pt)) {
+ return NULL;
+ }
+
+ if (r_gpl) *r_gpl = NULL;
+ if (r_gpf) *r_gpf = NULL;
+
+ /* there's no faster alternative than just looping over everything... */
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if (gpl->actframe) {
+ for (gps = gpl->actframe->strokes.first; gps; gps = gps->next) {
+ if ((pt >= gps->points) && (pt < &gps->points[gps->totpoints])) {
+ /* found it */
+ if (r_gpl) *r_gpl = gpl;
+ if (r_gpf) *r_gpf = gpl->actframe;
+
+ return gps;
+ }
+ }
+ }
+ }
+
+ /* didn't find it */
+ return NULL;
+}
+
+static void rna_GPencil_stroke_point_select_set(PointerRNA *ptr, const int value)
+{
+ bGPdata *gpd = ptr->id.data;
+ bGPDspoint *pt = ptr->data;
+ bGPDstroke *gps = NULL;
+
+ /* Ensure that corresponding stroke is set
+ * - Since we don't have direct access, we're going to have to search
+ * - We don't apply selection value unless we can find the corresponding
+ * stroke, so that they don't get out of sync
+ */
+ gps = rna_GPencil_stroke_point_find_stroke(gpd, pt, NULL, NULL);
+ if (gps) {
+ /* Set the new selection state for the point */
+ if (value)
+ pt->flag |= GP_SPOINT_SELECT;
+ else
+ pt->flag &= ~GP_SPOINT_SELECT;
+
+ /* Check if the stroke should be selected or not... */
+ gpencil_stroke_sync_selection(gps);
+ }
+}
+
static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count)
{
if (count > 0) {
@@ -180,6 +321,27 @@ static void rna_GPencil_stroke_remove(bGPDframe *frame, ReportList *reports, Poi
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
}
+static void rna_GPencil_stroke_select_set(PointerRNA *ptr, const int value)
+{
+ bGPDstroke *gps = ptr->data;
+ bGPDspoint *pt;
+ int i;
+
+ /* set new value */
+ if (value)
+ gps->flag |= GP_STROKE_SELECT;
+ else
+ gps->flag &= ~GP_STROKE_SELECT;
+
+ /* ensure that the stroke's points are selected in the same way */
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (value)
+ pt->flag |= GP_SPOINT_SELECT;
+ else
+ pt->flag &= ~GP_SPOINT_SELECT;
+ }
+}
+
static bGPDframe *rna_GPencil_frame_new(bGPDlayer *layer, ReportList *reports, int frame_number)
{
bGPDframe *frame;
@@ -291,6 +453,12 @@ static void rna_def_gpencil_stroke_point(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SPOINT_SELECT);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_stroke_point_select_set");
+ RNA_def_property_ui_text(prop, "Select", "Point is selected for viewport editing");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
}
static void rna_def_gpencil_stroke_points_api(BlenderRNA *brna, PropertyRNA *cprop)
@@ -338,12 +506,19 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "GPencilStrokePoint");
RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points");
rna_def_gpencil_stroke_points_api(brna, prop);
-
+
+ /* Settings */
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, stroke_draw_mode_items);
RNA_def_property_ui_text(prop, "Draw Mode", "");
RNA_def_property_update(prop, 0, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STROKE_SELECT);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_stroke_select_set");
+ RNA_def_property_ui_text(prop, "Select", "Stroke is selected for viewport editing");
+ RNA_def_property_update(prop, 0, "rna_GPencil_update");
}
static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop)
@@ -455,6 +630,7 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
srna = RNA_def_struct(brna, "GPencilLayer", NULL);
RNA_def_struct_sdna(srna, "bGPDlayer");
RNA_def_struct_ui_text(srna, "Grease Pencil Layer", "Collection of related sketches");
+ RNA_def_struct_path_func(srna, "rna_GPencilLayer_path");
/* Name */
prop = RNA_def_property(srna, "info", PROP_STRING, PROP_NONE);
@@ -477,7 +653,14 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_editable_func(prop, "rna_GPencilLayer_active_frame_editable");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
- /* Drawing Color */
+ /* Draw Style */
+ // TODO: replace these with a "draw type" combo (i.e. strokes only, filled strokes, strokes + fills, volumetric)?
+ prop = RNA_def_property(srna, "use_volumetric_strokes", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_VOLUMETRIC);
+ RNA_def_property_ui_text(prop, "Volumetric Strokes", "Draw strokes as a series of circular blobs, resulting in a volumetric effect");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ /* Stroke Drawing Color */
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -486,14 +669,29 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "color[3]");
- RNA_def_property_range(prop, 0.3, 1.0f);
+ RNA_def_property_range(prop, 0.0, 1.0f);
RNA_def_property_ui_text(prop, "Opacity", "Layer Opacity");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+ /* Fill Drawing Color */
+ prop = RNA_def_property(srna, "fill_color", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "fill");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Fill Color", "Color for filling region bounded by each stroke");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "fill_alpha", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "fill[3]");
+ RNA_def_property_range(prop, 0.0, 1.0f);
+ RNA_def_property_ui_text(prop, "Fill Opacity", "Opacity for filling region bounded by each stroke");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
/* Line Thickness */
prop = RNA_def_property(srna, "line_width", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "thickness");
- RNA_def_property_range(prop, 1, 10);
+ //RNA_def_property_range(prop, 1, 10); /* 10 px limit comes from Windows OpenGL limits for natively-drawn strokes */
+ RNA_def_property_int_funcs(prop, NULL, NULL, "rna_GPencilLayer_line_width_range");
RNA_def_property_ui_text(prop, "Thickness", "Thickness of strokes (in pixels)");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
@@ -503,29 +701,59 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Onion Skinning", "Ghost frames on either side of frame");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
- prop = RNA_def_property(srna, "ghost_range_max", PROP_INT, PROP_NONE);
+ prop = RNA_def_property(srna, "ghost_before_range", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gstep");
RNA_def_property_range(prop, 0, 120);
- RNA_def_property_ui_text(prop, "Max Ghost Range",
- "Maximum number of frames on either side of the active frame to show "
- "(0 = show the 'first' available sketch on either side)");
+ RNA_def_property_ui_text(prop, "Frames Before",
+ "Maximum number of frames to show before current frame "
+ "(0 = show only the previous sketch)");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "ghost_after_range", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "gstep_next");
+ RNA_def_property_range(prop, 0, 120);
+ RNA_def_property_ui_text(prop, "Frames After",
+ "Maximum number of frames to show after current frame "
+ "(0 = show only the next sketch)");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "use_ghost_custom_colors", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_GHOST_PREVCOL | GP_LAYER_GHOST_NEXTCOL);
+ RNA_def_property_ui_text(prop, "Use Custom Ghost Colors", "Use custom colors for ghost frames");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "before_color", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "gcolor_prev");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Before Color", "Base color for ghosts before the active frame");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+
+ prop = RNA_def_property(srna, "after_color", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "gcolor_next");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "After Color", "Base color for ghosts after the active frame");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
/* Flags */
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE);
+ RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1);
RNA_def_property_ui_text(prop, "Hide", "Set layer Visibility");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_LOCKED);
+ RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1);
RNA_def_property_ui_text(prop, "Locked", "Protect layer from further editing and/or frame changes");
- RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
prop = RNA_def_property(srna, "lock_frame", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_FRAMELOCK);
+ RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1);
RNA_def_property_ui_text(prop, "Frame Locked", "Lock current frame displayed by layer");
- RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
/* expose as layers.active */
#if 0
@@ -539,7 +767,7 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SELECT);
RNA_def_property_ui_text(prop, "Select", "Layer is selected for editing in the Dope Sheet");
- RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
/* XXX keep this option? */
prop = RNA_def_property(srna, "show_points", PROP_BOOLEAN, PROP_NONE);
@@ -554,6 +782,17 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
+ /* Read-only state props (for simpler UI code) */
+ prop = RNA_def_property(srna, "is_stroke_visible", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_GPencilLayer_is_stroke_visible_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Is Stroke Visible", "True when opacity of stroke is set high enough to be visible");
+
+ prop = RNA_def_property(srna, "is_fill_visible", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_GPencilLayer_is_fill_visible_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Is Fill Visible", "True when opacity of fill is set high enough to be visible");
+
/* Layers API */
func = RNA_def_function(srna, "clear", "rna_GPencil_layer_clear");
RNA_def_function_ui_description(func, "Remove all the grease pencil layer data");
@@ -592,6 +831,14 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_pointer_funcs(prop, "rna_GPencil_active_layer_get", "rna_GPencil_active_layer_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active Layer", "Active grease pencil layer");
+
+ prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
+
+ RNA_def_property_int_funcs(prop,
+ "rna_GPencil_active_layer_index_get",
+ "rna_GPencil_active_layer_index_set",
+ "rna_GPencil_active_layer_index_range");
+ RNA_def_property_ui_text(prop, "Active Layer Index", "Index of active grease pencil layer");
}
static void rna_def_gpencil_data(BlenderRNA *brna)
@@ -620,6 +867,9 @@ static void rna_def_gpencil_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Layers", "");
rna_def_gpencil_layers_api(brna, prop);
+ /* Animation Data */
+ rna_def_animdata_common(srna);
+
/* Flags */
prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
@@ -631,7 +881,13 @@ static void rna_def_gpencil_data(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_DEPTH_STROKE_ENDPOINTS);
RNA_def_property_ui_text(prop, "Only Endpoints", "Only use the first and last parts of the stroke for snapping");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
-
+
+ prop = RNA_def_property(srna, "use_stroke_edit_mode", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_EDITMODE);
+ RNA_def_property_ui_text(prop, "Stroke Edit Mode", "Enable alternative keymap to make editing stroke points easier");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_update");
+
+ /* API Functions */
func = RNA_def_function(srna, "clear", "rna_GPencil_clear");
RNA_def_function_ui_description(func, "Remove all the grease pencil data");
}
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 141de511a09..cf2973c49a7 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -193,7 +193,7 @@ static int rna_Image_file_format_get(PointerRNA *ptr)
{
Image *image = (Image *)ptr->data;
ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
- int imtype = BKE_ftype_to_imtype(ibuf ? ibuf->ftype : 0);
+ int imtype = BKE_image_ftype_to_imtype(ibuf ? ibuf->ftype : 0);
BKE_image_release_ibuf(image, ibuf, NULL);
@@ -204,7 +204,7 @@ static void rna_Image_file_format_set(PointerRNA *ptr, int value)
{
Image *image = (Image *)ptr->data;
if (BKE_imtype_is_movie(value) == 0) { /* should be able to throw an error here */
- int ftype = BKE_imtype_to_ftype(value);
+ int ftype = BKE_image_imtype_to_ftype(value);
BKE_image_file_format_set(image, ftype);
}
}
@@ -292,11 +292,21 @@ static int rna_Image_depth_get(PointerRNA *ptr)
static int rna_Image_frame_duration_get(PointerRNA *ptr)
{
- Image *im = (Image *)ptr->data;
+ Image *ima = ptr->id.data;
+ int duration = 1;
+
+ if (!ima->anim) {
+ /* acquire ensures ima->anim is set, if possible! */
+ void *lock;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+ BKE_image_release_ibuf(ima, ibuf, lock);
+ }
- if (im->anim)
- return IMB_anim_get_duration(im->anim, IMB_TC_RECORD_RUN);
- return 1;
+ if (ima->anim) {
+ duration = IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN);
+ }
+
+ return duration;
}
static int rna_Image_pixels_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
@@ -630,6 +640,11 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Use Alpha", "Use the alpha channel information from the image or make image fully opaque");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_colormanage_update");
+ prop = RNA_def_property(srna, "use_deinterlace", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", IMA_DEINTERLACE);
+ RNA_def_property_ui_text(prop, "Deinterlace", "Deinterlace movie file on load");
+ RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_reload_update");
+
prop = RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Image_dirty_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -665,7 +680,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- prop = RNA_def_property(srna, "generated_color", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "generated_color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "gen_color");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Color", "Fill color for the generated image");
@@ -694,13 +709,13 @@ static void rna_def_image(BlenderRNA *brna)
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "twsta");
- RNA_def_property_range(prop, 0, 128);
+ RNA_def_property_range(prop, 0, 255);
RNA_def_property_ui_text(prop, "Animation Start", "Start frame of an animated texture");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_animated_update");
prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "twend");
- RNA_def_property_range(prop, 0, 128);
+ RNA_def_property_range(prop, 0, 255);
RNA_def_property_ui_text(prop, "Animation End", "End frame of an animated texture");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_animated_update");
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index d9a59c4dc55..357490924f2 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -52,8 +52,6 @@
#include "BKE_packedFile.h"
#include "BKE_main.h"
-#include "BKE_global.h" /* grr: G.main->name */
-
#include "IMB_imbuf.h"
#include "IMB_colormanagement.h"
@@ -74,7 +72,7 @@ static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports
}
if (scene) {
- ImageUser iuser;
+ ImageUser iuser = {NULL};
void *lock;
iuser.scene = scene;
@@ -109,13 +107,13 @@ static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports
}
}
-static void rna_Image_save(Image *image, bContext *C, ReportList *reports)
+static void rna_Image_save(Image *image, Main *bmain, bContext *C, ReportList *reports)
{
ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
if (ibuf) {
char filename[FILE_MAX];
BLI_strncpy(filename, image->name, sizeof(filename));
- BLI_path_abs(filename, ID_BLEND_PATH(G.main, &image->id));
+ BLI_path_abs(filename, ID_BLEND_PATH(bmain, &image->id));
if (image->packedfile) {
if (writePackedFile(reports, image->name, image->packedfile, 0) != RET_OK) {
@@ -144,7 +142,9 @@ static void rna_Image_save(Image *image, bContext *C, ReportList *reports)
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, image);
}
-static void rna_Image_pack(Image *image, bContext *C, ReportList *reports, int as_png)
+static void rna_Image_pack(
+ Image *image, Main *bmain, bContext *C, ReportList *reports,
+ int as_png, const char *data, int data_len)
{
ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
@@ -152,11 +152,20 @@ static void rna_Image_pack(Image *image, bContext *C, ReportList *reports, int a
BKE_report(reports, RPT_ERROR, "Cannot pack edited image from disk, only as internal PNG");
}
else {
+ if (image->packedfile) {
+ freePackedFile(image->packedfile);
+ image->packedfile = NULL;
+ }
if (as_png) {
BKE_image_memorypack(image);
}
+ else if (data) {
+ char *data_dup = MEM_mallocN(sizeof(*data_dup) * (size_t)data_len, __func__);
+ memcpy(data_dup, data, (size_t)data_len);
+ image->packedfile = newPackedFileMemory(data_dup, data_len);
+ }
else {
- image->packedfile = newPackedFile(reports, image->name, ID_BLEND_PATH(G.main, &image->id));
+ image->packedfile = newPackedFile(reports, image->name, ID_BLEND_PATH(bmain, &image->id));
}
}
@@ -301,12 +310,16 @@ void RNA_api_image(StructRNA *srna)
func = RNA_def_function(srna, "save", "rna_Image_save");
RNA_def_function_ui_description(func, "Save image to its source path");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
func = RNA_def_function(srna, "pack", "rna_Image_pack");
RNA_def_function_ui_description(func, "Pack an image as embedded data into the .blend file");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
RNA_def_boolean(func, "as_png", 0, "as_png", "Pack the image as PNG (needed for generated/dirty images)");
+ parm = RNA_def_property(func, "data", PROP_STRING, PROP_BYTESTRING);
+ RNA_def_property_ui_text(parm, "data", "Raw data (bytes, exact content of the embedded file)");
+ RNA_def_int(func, "data_len", 0, 0, INT_MAX,
+ "data_len", "length of given data (mandatory if data is provided)", 0, INT_MAX);
func = RNA_def_function(srna, "unpack", "rna_Image_unpack");
RNA_def_function_ui_description(func, "Save an image packed in the .blend file to disk");
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 051e7277425..f225387baa4 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -259,6 +259,7 @@ void RNA_api_armature_edit_bone(StructRNA *srna);
void RNA_api_bone(StructRNA *srna);
void RNA_api_camera(StructRNA *srna);
void RNA_api_curve(StructRNA *srna);
+void RNA_api_fcurves(StructRNA *srna);
void RNA_api_drivers(StructRNA *srna);
void RNA_api_image(struct StructRNA *srna);
void RNA_api_lattice(struct StructRNA *srna);
@@ -287,6 +288,7 @@ void RNA_api_ui_layout(struct StructRNA *srna);
void RNA_api_window(struct StructRNA *srna);
void RNA_api_wm(struct StructRNA *srna);
void RNA_api_space_node(struct StructRNA *srna);
+void RNA_api_space_text(struct StructRNA *srna);
void RNA_api_region_view3d(struct StructRNA *srna);
void RNA_api_sensor(struct StructRNA *srna);
void RNA_api_controller(struct StructRNA *srna);
@@ -295,6 +297,8 @@ void RNA_api_texture(struct StructRNA *srna);
void RNA_api_environment_map(struct StructRNA *srna);
void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_api_sequence_elements(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_api_sound(struct StructRNA *srna);
+void RNA_api_vfont(struct StructRNA *srna);
/* main collection functions */
void RNA_def_main_cameras(BlenderRNA *brna, PropertyRNA *cprop);
@@ -322,6 +326,7 @@ 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_palettes(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop);
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index 7d10511d1c4..8a3626de81d 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -675,13 +675,6 @@ static void rna_def_key(BlenderRNA *brna)
RNA_def_property_range(prop, MINFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "Evaluation Time", "Evaluation time for absolute shape keys");
RNA_def_property_update(prop, 0, "rna_Key_update_data");
-
- prop = RNA_def_property(srna, "slurph", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_int_sdna(prop, NULL, "slurph");
- RNA_def_property_range(prop, -500, 500);
- RNA_def_property_ui_text(prop, "Slurph",
- "Create a delay (in frames) in applying key positions, first vertex goes first");
- RNA_def_property_update(prop, 0, "rna_Key_update_data");
}
void RNA_def_key(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index e9861b90956..c915acdeeac 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -93,23 +93,21 @@ static int rna_use_shadow_get(PointerRNA *ptr)
{
Lamp *la = (Lamp *)ptr->data;
- if (la->type == LA_SPOT)
- return la->mode & LA_SHAD_BUF;
- else
- return la->mode & LA_SHAD_RAY;
+ if (la->type == LA_SPOT) {
+ return (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY)) != 0;
+ }
+ else {
+ return (la->mode & LA_SHAD_RAY) != 0;
+ }
}
static void rna_use_shadow_set(PointerRNA *ptr, int value)
{
Lamp *la = (Lamp *)ptr->data;
+ la->mode &= ~(LA_SHAD_BUF | LA_SHAD_RAY);
if (value) {
- if (la->type == LA_SPOT)
- la->mode |= LA_SHAD_BUF;
- else
- la->mode |= LA_SHAD_RAY;
+ la->mode |= LA_SHAD_RAY;
}
- else
- la->mode &= ~(LA_SHAD_BUF | LA_SHAD_RAY);
}
static StructRNA *rna_Lamp_refine(struct PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 65d81359045..348fa3c8302 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -251,6 +251,12 @@ static void rna_Main_particle_begin(CollectionPropertyIterator *iter, PointerRNA
rna_iterator_listbase_begin(iter, &bmain->particle, NULL);
}
+static void rna_Main_palettes_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Main *bmain = (Main *)ptr->data;
+ rna_iterator_listbase_begin(iter, &bmain->palettes, NULL);
+}
+
static void rna_Main_gpencil_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
Main *bmain = (Main *)ptr->data;
@@ -350,6 +356,7 @@ void RNA_def_main(BlenderRNA *brna)
{"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks", RNA_def_main_armatures},
{"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks", RNA_def_main_actions},
{"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks", RNA_def_main_particles},
+ {"palettes", "Palette", "rna_Main_palettes_begin", "Palettes", "Palette datablocks", RNA_def_main_palettes},
{"grease_pencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks", RNA_def_main_gpencil},
{"movieclips", "MovieClip", "rna_Main_movieclips_begin", "Movie Clips", "Movie Clip datablocks", RNA_def_main_movieclips},
{"masks", "Mask", "rna_Main_masks_begin", "Masks", "Masks datablocks", RNA_def_main_masks},
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index b4c332be373..ed8b85f724e 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -69,6 +69,7 @@
#include "BKE_mball.h"
#include "BKE_world.h"
#include "BKE_particle.h"
+#include "BKE_paint.h"
#include "BKE_font.h"
#include "BKE_node.h"
#include "BKE_depsgraph.h"
@@ -631,6 +632,25 @@ static void rna_Main_particles_remove(Main *bmain, ReportList *reports, PointerR
}
}
+static Palette *rna_Main_palettes_new(Main *bmain, const char *name)
+{
+ Palette *palette = BKE_palette_add(bmain, name);
+ id_us_min(&palette->id);
+ return (Palette *)palette;
+}
+static void rna_Main_palettes_remove(Main *bmain, ReportList *reports, PointerRNA *palette_ptr)
+{
+ Palette *palette = palette_ptr->data;
+ if (ID_REAL_USERS(palette) <= 0) {
+ BKE_libblock_free(bmain, palette);
+ RNA_POINTER_INVALIDATE(palette_ptr);
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR, "Palette settings '%s' must have zero users to be removed, found %d",
+ palette->id.name + 2, ID_REAL_USERS(palette));
+ }
+}
+
static MovieClip *rna_Main_movieclip_load(Main *bmain, ReportList *reports, const char *filepath)
{
MovieClip *clip;
@@ -729,38 +749,40 @@ static void rna_Main_sounds_tag(Main *bmain, int value) { BKE_main_id_tag_listba
static void rna_Main_armatures_tag(Main *bmain, int value) { BKE_main_id_tag_listbase(&bmain->armature, value); }
static void rna_Main_actions_tag(Main *bmain, int value) { BKE_main_id_tag_listbase(&bmain->action, value); }
static void rna_Main_particles_tag(Main *bmain, int value) { BKE_main_id_tag_listbase(&bmain->particle, value); }
+static void rna_Main_palettes_tag(Main *bmain, int value) { BKE_main_id_tag_listbase(&bmain->palettes, value); }
static void rna_Main_gpencil_tag(Main *bmain, int value) { BKE_main_id_tag_listbase(&bmain->gpencil, value); }
static void rna_Main_movieclips_tag(Main *bmain, int value) { BKE_main_id_tag_listbase(&bmain->movieclip, value); }
static void rna_Main_masks_tag(Main *bmain, int value) { BKE_main_id_tag_listbase(&bmain->mask, value); }
static void rna_Main_linestyle_tag(Main *bmain, int value) { BKE_main_id_tag_listbase(&bmain->linestyle, value); }
-static int rna_Main_cameras_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CA); }
-static int rna_Main_scenes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCE); }
-static int rna_Main_objects_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_OB); }
-static int rna_Main_materials_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_MA); }
-static int rna_Main_node_groups_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_NT); }
-static int rna_Main_meshes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_ME); }
-static int rna_Main_lamps_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LA); }
-static int rna_Main_libraries_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LI); }
-static int rna_Main_screens_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCR); }
-static int rna_Main_window_managers_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_WM); }
-static int rna_Main_images_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_IM); }
-static int rna_Main_lattices_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LT); }
-static int rna_Main_curves_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CU); }
-static int rna_Main_metaballs_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_MB); }
-static int rna_Main_fonts_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_VF); }
-static int rna_Main_textures_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_TE); }
-static int rna_Main_brushes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_BR); }
-static int rna_Main_worlds_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_WO); }
-static int rna_Main_groups_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_GR); }
-static int rna_Main_texts_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_TXT); }
-static int rna_Main_speakers_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SPK); }
-static int rna_Main_sounds_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SO); }
-static int rna_Main_armatures_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_AR); }
-static int rna_Main_actions_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_AC); }
-static int rna_Main_particles_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_PA); }
-static int rna_Main_gpencil_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_GD); }
-static int rna_Main_linestyle_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LS); }
+static int rna_Main_cameras_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CA) != 0; }
+static int rna_Main_scenes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCE) != 0; }
+static int rna_Main_objects_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_OB) != 0; }
+static int rna_Main_materials_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_MA) != 0; }
+static int rna_Main_node_groups_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_NT) != 0; }
+static int rna_Main_meshes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_ME) != 0; }
+static int rna_Main_lamps_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LA) != 0; }
+static int rna_Main_libraries_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LI) != 0; }
+static int rna_Main_screens_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCR) != 0; }
+static int rna_Main_window_managers_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_WM) != 0; }
+static int rna_Main_images_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_IM) != 0; }
+static int rna_Main_lattices_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LT) != 0; }
+static int rna_Main_curves_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CU) != 0; }
+static int rna_Main_metaballs_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_MB) != 0; }
+static int rna_Main_fonts_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_VF) != 0; }
+static int rna_Main_textures_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_TE) != 0; }
+static int rna_Main_brushes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_BR) != 0; }
+static int rna_Main_worlds_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_WO) != 0; }
+static int rna_Main_groups_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_GR) != 0; }
+static int rna_Main_texts_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_TXT) != 0; }
+static int rna_Main_speakers_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SPK) != 0; }
+static int rna_Main_sounds_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SO) != 0; }
+static int rna_Main_armatures_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_AR) != 0; }
+static int rna_Main_actions_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_AC) != 0; }
+static int rna_Main_particles_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_PA) != 0; }
+static int rna_Main_palettes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_PAL) != 0; }
+static int rna_Main_gpencil_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_GD) != 0; }
+static int rna_Main_linestyle_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LS) != 0; }
#else
@@ -1678,7 +1700,41 @@ void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Main_particles_is_updated_get", NULL);
}
+void RNA_def_main_palettes(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+ PropertyRNA *prop;
+
+ RNA_def_property_srna(cprop, "BlendDataPalettes");
+ srna = RNA_def_struct(brna, "BlendDataPalettes", NULL);
+ RNA_def_struct_sdna(srna, "Main");
+ RNA_def_struct_ui_text(srna, "Main Palettes", "Collection of palettes");
+ func = RNA_def_function(srna, "new", "rna_Main_palettes_new");
+ RNA_def_function_ui_description(func, "Add a new palette to the main database");
+ parm = RNA_def_string(func, "name", "Palette", 0, "", "New name for the datablock");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ /* return type */
+ parm = RNA_def_pointer(func, "palette", "Palette", "", "New palette datablock");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "remove", "rna_Main_palettes_remove");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_ui_description(func, "Remove a palette from the current blendfile");
+ parm = RNA_def_pointer(func, "palette", "Palette", "", "Palette to remove");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+ RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+
+ func = RNA_def_function(srna, "tag", "rna_Main_palettes_tag");
+ parm = RNA_def_boolean(func, "value", 0, "Value", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_boolean_funcs(prop, "rna_Main_palettes_is_updated_get", NULL);
+}
void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 2e4f24fc0ce..7a06b647ae3 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -181,7 +181,7 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s
bScreen *sc;
Material *ma = ptr->id.data;
- if (ma->use_nodes && ma->nodetree && BKE_scene_use_new_shading_nodes(scene)) {
+ if (ma->use_nodes && ma->nodetree) {
struct bNode *node;
int index = 0;
for (node = ma->nodetree->nodes.first; node; node = node->next) {
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index b0b99dcd2ca..b1f0adb0d98 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -207,6 +207,11 @@ static void rna_MeshAnyLayer_name_set(PointerRNA *ptr, const char *value)
rna_cd_layer_name_set(cd, (CustomDataLayer *)ptr->data, value);
}
+static int rna_Mesh_has_custom_normals_get(PointerRNA *ptr)
+{
+ Mesh *me = ptr->data;
+ return (int)BKE_mesh_has_custom_loop_normals(me);
+}
/* -------------------------------------------------------------------- */
/* Update Callbacks */
@@ -338,6 +343,17 @@ static void rna_MeshLoop_normal_get(PointerRNA *ptr, float *values)
}
}
+static void rna_MeshLoop_normal_set(PointerRNA *ptr, const float *values)
+{
+ Mesh *me = rna_mesh(ptr);
+ MLoop *ml = (MLoop *)ptr->data;
+ float (*vec)[3] = CustomData_get(&me->ldata, (int)(ml - me->mloop), CD_NORMAL);
+
+ if (vec) {
+ normalize_v3_v3(*vec, values);
+ }
+}
+
static void rna_MeshLoop_tangent_get(PointerRNA *ptr, float *values)
{
Mesh *me = rna_mesh(ptr);
@@ -696,7 +712,7 @@ static void rna_MeshVertex_undeformed_co_get(PointerRNA *ptr, float values[3])
copy_v3_v3(values, mvert->co);
}
-static int rna_CustomDataLayer_active_get(PointerRNA *ptr, CustomData *data, int type, int render)
+static int rna_CustomDataLayer_active_get(PointerRNA *ptr, CustomData *data, int type, bool render)
{
int n = ((CustomDataLayer *)ptr->data) - data->layers;
@@ -1011,25 +1027,18 @@ static void rna_MeshLoopColorLayer_active_set(PointerRNA *ptr, int value)
rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPCOL, 0);
}
-static void rna_MeshFloatPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
-{
- Mesh *me = rna_mesh(ptr);
- CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
- rna_iterator_array_begin(iter, layer->data, sizeof(MFloatProperty), me->totpoly, 0, NULL);
-}
-
-static int rna_MeshFloatPropertyLayer_data_length(PointerRNA *ptr)
-{
- Mesh *me = rna_mesh(ptr);
- return me->totpoly;
-}
-
static int rna_float_layer_check(CollectionPropertyIterator *UNUSED(iter), void *data)
{
CustomDataLayer *layer = (CustomDataLayer *)data;
return (layer->type != CD_PROP_FLT);
}
+static void rna_Mesh_vertex_float_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ CustomData *vdata = rna_mesh_vdata(ptr);
+ rna_iterator_array_begin(iter, (void *)vdata->layers, sizeof(CustomDataLayer), vdata->totlayer, 0,
+ rna_float_layer_check);
+}
static void rna_Mesh_polygon_float_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
CustomData *pdata = rna_mesh_pdata(ptr);
@@ -1037,6 +1046,10 @@ static void rna_Mesh_polygon_float_layers_begin(CollectionPropertyIterator *iter
rna_float_layer_check);
}
+static int rna_Mesh_vertex_float_layers_length(PointerRNA *ptr)
+{
+ return CustomData_number_of_layers(rna_mesh_vdata(ptr), CD_PROP_FLT);
+}
static int rna_Mesh_polygon_float_layers_length(PointerRNA *ptr)
{
return CustomData_number_of_layers(rna_mesh_pdata(ptr), CD_PROP_FLT);
@@ -1048,19 +1061,12 @@ static int rna_int_layer_check(CollectionPropertyIterator *UNUSED(iter), void *d
return (layer->type != CD_PROP_INT);
}
-static void rna_MeshIntPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
-{
- Mesh *me = rna_mesh(ptr);
- CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
- rna_iterator_array_begin(iter, layer->data, sizeof(MIntProperty), me->totpoly, 0, NULL);
-}
-
-static int rna_MeshIntPropertyLayer_data_length(PointerRNA *ptr)
+static void rna_Mesh_vertex_int_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
- Mesh *me = rna_mesh(ptr);
- return me->totpoly;
+ CustomData *vdata = rna_mesh_vdata(ptr);
+ rna_iterator_array_begin(iter, (void *)vdata->layers, sizeof(CustomDataLayer), vdata->totlayer, 0,
+ rna_int_layer_check);
}
-
static void rna_Mesh_polygon_int_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
CustomData *pdata = rna_mesh_pdata(ptr);
@@ -1068,6 +1074,10 @@ static void rna_Mesh_polygon_int_layers_begin(CollectionPropertyIterator *iter,
rna_int_layer_check);
}
+static int rna_Mesh_vertex_int_layers_length(PointerRNA *ptr)
+{
+ return CustomData_number_of_layers(rna_mesh_vdata(ptr), CD_PROP_INT);
+}
static int rna_Mesh_polygon_int_layers_length(PointerRNA *ptr)
{
return CustomData_number_of_layers(rna_mesh_pdata(ptr), CD_PROP_INT);
@@ -1079,19 +1089,12 @@ static int rna_string_layer_check(CollectionPropertyIterator *UNUSED(iter), void
return (layer->type != CD_PROP_STR);
}
-static void rna_MeshStringPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
-{
- Mesh *me = rna_mesh(ptr);
- CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
- rna_iterator_array_begin(iter, layer->data, sizeof(MStringProperty), me->totpoly, 0, NULL);
-}
-
-static int rna_MeshStringPropertyLayer_data_length(PointerRNA *ptr)
+static void rna_Mesh_vertex_string_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
- Mesh *me = rna_mesh(ptr);
- return me->totpoly;
+ CustomData *vdata = rna_mesh_vdata(ptr);
+ rna_iterator_array_begin(iter, (void *)vdata->layers, sizeof(CustomDataLayer), vdata->totlayer, 0,
+ rna_string_layer_check);
}
-
static void rna_Mesh_polygon_string_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
CustomData *pdata = rna_mesh_pdata(ptr);
@@ -1099,6 +1102,10 @@ static void rna_Mesh_polygon_string_layers_begin(CollectionPropertyIterator *ite
rna_string_layer_check);
}
+static int rna_Mesh_vertex_string_layers_length(PointerRNA *ptr)
+{
+ return CustomData_number_of_layers(rna_mesh_vdata(ptr), CD_PROP_STR);
+}
static int rna_Mesh_polygon_string_layers_length(PointerRNA *ptr)
{
return CustomData_number_of_layers(rna_mesh_pdata(ptr), CD_PROP_STR);
@@ -1415,8 +1422,6 @@ static char *rna_FaceCustomData_data_path(PointerRNA *ptr, const char *collectio
}
-
-
static char *rna_MeshUVLoop_path(PointerRNA *ptr)
{
return rna_LoopCustomData_data_path(ptr, "uv_layers", CD_MLOOPUV);
@@ -1453,43 +1458,151 @@ static char *rna_MeshColor_path(PointerRNA *ptr)
return rna_LoopCustomData_data_path(ptr, "vertex_colors", CD_MLOOPCOL);
}
-static char *rna_MeshIntPropertyLayer_path(PointerRNA *ptr)
+/**** Float Property Layer API ****/
+static char *rna_MeshVertexFloatPropertyLayer_path(PointerRNA *ptr)
+{
+ CustomDataLayer *cdl = ptr->data;
+ char name_esc[sizeof(cdl->name) * 2];
+ BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ return BLI_sprintfN("vertex_float_layers[\"%s\"]", name_esc);
+}
+static char *rna_MeshPolygonFloatPropertyLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
- return BLI_sprintfN("int_layers[\"%s\"]", name_esc);
+ return BLI_sprintfN("polygon_float_layers[\"%s\"]", name_esc);
}
-static char *rna_MeshIntProperty_path(PointerRNA *ptr)
+static char *rna_MeshVertexFloatProperty_path(PointerRNA *ptr)
+{
+ return rna_VertCustomData_data_path(ptr, "vertex_layers_float", CD_PROP_FLT);
+}
+static char *rna_MeshPolygonFloatProperty_path(PointerRNA *ptr)
{
- return rna_PolyCustomData_data_path(ptr, "layers_int", CD_PROP_INT);
+ return rna_PolyCustomData_data_path(ptr, "polygon_layers_float", CD_PROP_FLT);
}
-static char *rna_MeshFloatPropertyLayer_path(PointerRNA *ptr)
+static void rna_MeshVertexFloatPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
+ rna_iterator_array_begin(iter, layer->data, sizeof(MFloatProperty), me->totvert, 0, NULL);
+}
+static void rna_MeshPolygonFloatPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
+ rna_iterator_array_begin(iter, layer->data, sizeof(MFloatProperty), me->totpoly, 0, NULL);
+}
+
+static int rna_MeshVertexFloatPropertyLayer_data_length(PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ return me->totvert;
+}
+static int rna_MeshPolygonFloatPropertyLayer_data_length(PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ return me->totpoly;
+}
+
+/**** Int Property Layer API ****/
+static char *rna_MeshVertexIntPropertyLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
- return BLI_sprintfN("float_layers[\"%s\"]", name_esc);
+ return BLI_sprintfN("vertex_int_layers[\"%s\"]", name_esc);
+}
+static char *rna_MeshPolygonIntPropertyLayer_path(PointerRNA *ptr)
+{
+ CustomDataLayer *cdl = ptr->data;
+ char name_esc[sizeof(cdl->name) * 2];
+ BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ return BLI_sprintfN("polygon_int_layers[\"%s\"]", name_esc);
+}
+
+static char *rna_MeshVertexIntProperty_path(PointerRNA *ptr)
+{
+ return rna_VertCustomData_data_path(ptr, "vertex_layers_int", CD_PROP_INT);
+}
+static char *rna_MeshPolygonIntProperty_path(PointerRNA *ptr)
+{
+ return rna_PolyCustomData_data_path(ptr, "polygon_layers_int", CD_PROP_INT);
+}
+
+static void rna_MeshVertexIntPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
+ rna_iterator_array_begin(iter, layer->data, sizeof(MIntProperty), me->totvert, 0, NULL);
+}
+static void rna_MeshPolygonIntPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
+ rna_iterator_array_begin(iter, layer->data, sizeof(MIntProperty), me->totpoly, 0, NULL);
}
-static char *rna_MeshFloatProperty_path(PointerRNA *ptr)
+static int rna_MeshVertexIntPropertyLayer_data_length(PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ return me->totvert;
+}
+static int rna_MeshPolygonIntPropertyLayer_data_length(PointerRNA *ptr)
{
- return rna_PolyCustomData_data_path(ptr, "layers_float", CD_PROP_FLT);
+ Mesh *me = rna_mesh(ptr);
+ return me->totpoly;
}
-static char *rna_MeshStringPropertyLayer_path(PointerRNA *ptr)
+/**** String Property Layer API ****/
+static char *rna_MeshVertexStringPropertyLayer_path(PointerRNA *ptr)
+{
+ CustomDataLayer *cdl = ptr->data;
+ char name_esc[sizeof(cdl->name) * 2];
+ BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
+ return BLI_sprintfN("vertex_string_layers[\"%s\"]", name_esc);
+}
+static char *rna_MeshPolygonStringPropertyLayer_path(PointerRNA *ptr)
{
CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
BLI_strescape(name_esc, cdl->name, sizeof(name_esc));
- return BLI_sprintfN("string_layers[\"%s\"]", name_esc);
+ return BLI_sprintfN("polygon_string_layers[\"%s\"]", name_esc);
+}
+
+static char *rna_MeshVertexStringProperty_path(PointerRNA *ptr)
+{
+ return rna_VertCustomData_data_path(ptr, "vertex_layers_string", CD_PROP_STR);
+}
+static char *rna_MeshPolygonStringProperty_path(PointerRNA *ptr)
+{
+ return rna_PolyCustomData_data_path(ptr, "polygon_layers_string", CD_PROP_STR);
}
-static char *rna_MeshStringProperty_path(PointerRNA *ptr)
+static void rna_MeshVertexStringPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
+ rna_iterator_array_begin(iter, layer->data, sizeof(MStringProperty), me->totvert, 0, NULL);
+}
+static void rna_MeshPolygonStringPropertyLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
- return rna_PolyCustomData_data_path(ptr, "layers_string", CD_PROP_STR);
+ Mesh *me = rna_mesh(ptr);
+ CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
+ rna_iterator_array_begin(iter, layer->data, sizeof(MStringProperty), me->totpoly, 0, NULL);
+}
+
+static int rna_MeshVertexStringPropertyLayer_data_length(PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ return me->totvert;
+}
+static int rna_MeshPolygonStringPropertyLayer_data_length(PointerRNA *ptr)
+{
+ Mesh *me = rna_mesh(ptr);
+ return me->totpoly;
}
/* XXX, we dont have propper byte string support yet, so for now use the (bytes + 1)
@@ -1511,6 +1624,7 @@ void rna_MeshStringProperty_s_set(PointerRNA *ptr, const char *value)
MStringProperty *ms = (MStringProperty *)ptr->data;
BLI_strncpy(ms->s, value, sizeof(ms->s));
}
+/***************************************/
static int rna_Mesh_tot_vert_get(PointerRNA *ptr)
{
@@ -1579,50 +1693,29 @@ static PointerRNA rna_Mesh_tessface_vertex_color_new(struct Mesh *me, ReportList
return ptr;
}
-static PointerRNA rna_Mesh_polygon_int_property_new(struct Mesh *me, const char *name)
-{
- PointerRNA ptr;
- CustomDataLayer *cdl = NULL;
- int index;
-
- CustomData_add_layer_named(&me->pdata, CD_PROP_INT, CD_DEFAULT, NULL, me->totpoly, name);
- index = CustomData_get_named_layer_index(&me->pdata, CD_PROP_INT, name);
-
- cdl = (index == -1) ? NULL : &(me->pdata.layers[index]);
-
- RNA_pointer_create(&me->id, &RNA_MeshIntPropertyLayer, cdl, &ptr);
- return ptr;
-}
-
-static PointerRNA rna_Mesh_polygon_float_property_new(struct Mesh *me, const char *name)
-{
- PointerRNA ptr;
- CustomDataLayer *cdl = NULL;
- int index;
-
- CustomData_add_layer_named(&me->pdata, CD_PROP_FLT, CD_DEFAULT, NULL, me->totpoly, name);
- index = CustomData_get_named_layer_index(&me->pdata, CD_PROP_FLT, name);
-
- cdl = (index == -1) ? NULL : &(me->pdata.layers[index]);
-
- RNA_pointer_create(&me->id, &RNA_MeshFloatPropertyLayer, cdl, &ptr);
- return ptr;
-}
-
-static PointerRNA rna_Mesh_polygon_string_property_new(struct Mesh *me, const char *name)
-{
- PointerRNA ptr;
- CustomDataLayer *cdl = NULL;
- int index;
-
- CustomData_add_layer_named(&me->pdata, CD_PROP_STR, CD_DEFAULT, NULL, me->totpoly, name);
- index = CustomData_get_named_layer_index(&me->pdata, CD_PROP_STR, name);
-
- cdl = (index == -1) ? NULL : &(me->pdata.layers[index]);
-
- RNA_pointer_create(&me->id, &RNA_MeshStringPropertyLayer, cdl, &ptr);
- return ptr;
-}
+#define DEFINE_CUSTOMDATA_PROPERTY_API(elemname, datatype, cd_prop_type, cdata, countvar, layertype) \
+static PointerRNA rna_Mesh_##elemname##_##datatype##_property_new(struct Mesh *me, const char *name) \
+{ \
+ PointerRNA ptr; \
+ CustomDataLayer *cdl = NULL; \
+ int index; \
+ \
+ CustomData_add_layer_named(&me->cdata, cd_prop_type, CD_DEFAULT, NULL, me->countvar, name); \
+ index = CustomData_get_named_layer_index(&me->cdata, cd_prop_type, name); \
+ \
+ cdl = (index == -1) ? NULL : &(me->cdata.layers[index]); \
+ \
+ RNA_pointer_create(&me->id, &RNA_##layertype, cdl, &ptr); \
+ return ptr; \
+}
+
+DEFINE_CUSTOMDATA_PROPERTY_API(vertex, float, CD_PROP_FLT, vdata, totvert, MeshVertexFloatPropertyLayer)
+DEFINE_CUSTOMDATA_PROPERTY_API(vertex, int, CD_PROP_INT, vdata, totvert, MeshVertexIntPropertyLayer)
+DEFINE_CUSTOMDATA_PROPERTY_API(vertex, string, CD_PROP_STR, vdata, totvert, MeshVertexStringPropertyLayer)
+DEFINE_CUSTOMDATA_PROPERTY_API(polygon, float, CD_PROP_FLT, pdata, totpoly, MeshPolygonFloatPropertyLayer)
+DEFINE_CUSTOMDATA_PROPERTY_API(polygon, int, CD_PROP_INT, pdata, totpoly, MeshPolygonIntPropertyLayer)
+DEFINE_CUSTOMDATA_PROPERTY_API(polygon, string, CD_PROP_STR, pdata, totpoly, MeshPolygonStringPropertyLayer)
+#undef DEFINE_CUSTOMDATA_PROPERTY_API
static PointerRNA rna_Mesh_uv_texture_new(struct Mesh *me, const char *name)
{
@@ -1976,8 +2069,7 @@ static void rna_def_mloop(BlenderRNA *brna)
prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, -1.0f, 1.0f);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_float_funcs(prop, "rna_MeshLoop_normal_get", NULL, NULL);
+ RNA_def_property_float_funcs(prop, "rna_MeshLoop_normal_get", "rna_MeshLoop_normal_set", NULL);
RNA_def_property_ui_text(prop, "Normal",
"Local space unit length split normal vector of this vertex for this polygon "
"(must be computed beforehand using calc_normals_split or calc_tangents)");
@@ -2449,96 +2541,108 @@ static void rna_def_mproperties(BlenderRNA *brna)
PropertyRNA *prop;
/* Float */
- srna = RNA_def_struct(brna, "MeshFloatPropertyLayer", NULL);
- RNA_def_struct_sdna(srna, "CustomDataLayer");
- RNA_def_struct_ui_text(srna, "Mesh Float Property Layer", "User defined layer of floating point number values");
- RNA_def_struct_path_func(srna, "rna_MeshFloatPropertyLayer_path");
-
- prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_struct_name_property(srna, prop);
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set");
- RNA_def_property_ui_text(prop, "Name", "");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
- prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_struct_type(prop, "MeshFloatProperty");
- RNA_def_property_ui_text(prop, "Data", "");
- RNA_def_property_collection_funcs(prop, "rna_MeshFloatPropertyLayer_data_begin", "rna_iterator_array_next",
- "rna_iterator_array_end", "rna_iterator_array_get",
- "rna_MeshFloatPropertyLayer_data_length", NULL, NULL, NULL);
-
- srna = RNA_def_struct(brna, "MeshFloatProperty", NULL);
- RNA_def_struct_sdna(srna, "MFloatProperty");
- RNA_def_struct_ui_text(srna, "Mesh Float Property",
- "User defined floating point number value in a float properties layer");
- RNA_def_struct_path_func(srna, "rna_MeshFloatProperty_path");
-
- prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "f");
- RNA_def_property_ui_text(prop, "Value", "");
+#define MESH_FLOAT_PROPERTY_LAYER(elemname) \
+ srna = RNA_def_struct(brna, "Mesh" elemname "FloatPropertyLayer", NULL); \
+ RNA_def_struct_sdna(srna, "CustomDataLayer"); \
+ RNA_def_struct_ui_text(srna, "Mesh " elemname " Float Property Layer", "User defined layer of floating point number values"); \
+ RNA_def_struct_path_func(srna, "rna_Mesh" elemname "FloatPropertyLayer_path"); \
+ \
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); \
+ RNA_def_struct_name_property(srna, prop); \
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set"); \
+ RNA_def_property_ui_text(prop, "Name", ""); \
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); \
+ \
+ prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); \
+ RNA_def_property_struct_type(prop, "Mesh" elemname "FloatProperty"); \
+ RNA_def_property_ui_text(prop, "Data", ""); \
+ RNA_def_property_collection_funcs(prop, "rna_Mesh" elemname "FloatPropertyLayer_data_begin", "rna_iterator_array_next", \
+ "rna_iterator_array_end", "rna_iterator_array_get", \
+ "rna_Mesh" elemname "FloatPropertyLayer_data_length", NULL, NULL, NULL); \
+ \
+ srna = RNA_def_struct(brna, "Mesh" elemname "FloatProperty", NULL); \
+ RNA_def_struct_sdna(srna, "MFloatProperty"); \
+ RNA_def_struct_ui_text(srna, "Mesh " elemname " Float Property", \
+ "User defined floating point number value in a float properties layer"); \
+ RNA_def_struct_path_func(srna, "rna_Mesh" elemname "FloatProperty_path"); \
+ \
+ prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE); \
+ RNA_def_property_float_sdna(prop, NULL, "f"); \
+ RNA_def_property_ui_text(prop, "Value", ""); \
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
/* Int */
- srna = RNA_def_struct(brna, "MeshIntPropertyLayer", NULL);
- RNA_def_struct_sdna(srna, "CustomDataLayer");
- RNA_def_struct_ui_text(srna, "Mesh Int Property Layer", "User defined layer of integer number values");
- RNA_def_struct_path_func(srna, "rna_MeshIntPropertyLayer_path");
-
- prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_struct_name_property(srna, prop);
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set");
- RNA_def_property_ui_text(prop, "Name", "");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
- prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_struct_type(prop, "MeshIntProperty");
- RNA_def_property_ui_text(prop, "Data", "");
- RNA_def_property_collection_funcs(prop, "rna_MeshIntPropertyLayer_data_begin", "rna_iterator_array_next",
- "rna_iterator_array_end", "rna_iterator_array_get",
- "rna_MeshIntPropertyLayer_data_length", NULL, NULL, NULL);
-
- srna = RNA_def_struct(brna, "MeshIntProperty", NULL);
- RNA_def_struct_sdna(srna, "MIntProperty");
- RNA_def_struct_ui_text(srna, "Mesh Int Property",
- "User defined integer number value in an integer properties layer");
- RNA_def_struct_path_func(srna, "rna_MeshIntProperty_path");
-
- prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "i");
- RNA_def_property_ui_text(prop, "Value", "");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+#define MESH_INT_PROPERTY_LAYER(elemname) \
+ srna = RNA_def_struct(brna, "Mesh" elemname "IntPropertyLayer", NULL); \
+ RNA_def_struct_sdna(srna, "CustomDataLayer"); \
+ RNA_def_struct_ui_text(srna, "Mesh " elemname " Int Property Layer", "User defined layer of integer number values"); \
+ RNA_def_struct_path_func(srna, "rna_Mesh" elemname "IntPropertyLayer_path"); \
+ \
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); \
+ RNA_def_struct_name_property(srna, prop); \
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set"); \
+ RNA_def_property_ui_text(prop, "Name", ""); \
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); \
+ \
+ prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); \
+ RNA_def_property_struct_type(prop, "Mesh" elemname "IntProperty"); \
+ RNA_def_property_ui_text(prop, "Data", ""); \
+ RNA_def_property_collection_funcs(prop, "rna_Mesh" elemname "IntPropertyLayer_data_begin", "rna_iterator_array_next", \
+ "rna_iterator_array_end", "rna_iterator_array_get", \
+ "rna_Mesh" elemname "IntPropertyLayer_data_length", NULL, NULL, NULL); \
+ \
+ srna = RNA_def_struct(brna, "Mesh" elemname "IntProperty", NULL); \
+ RNA_def_struct_sdna(srna, "MIntProperty"); \
+ RNA_def_struct_ui_text(srna, "Mesh " elemname " Int Property", \
+ "User defined integer number value in an integer properties layer"); \
+ RNA_def_struct_path_func(srna, "rna_Mesh" elemname "IntProperty_path"); \
+ \
+ prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE); \
+ RNA_def_property_int_sdna(prop, NULL, "i"); \
+ RNA_def_property_ui_text(prop, "Value", ""); \
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); \
/* String */
- srna = RNA_def_struct(brna, "MeshStringPropertyLayer", NULL);
- RNA_def_struct_sdna(srna, "CustomDataLayer");
- RNA_def_struct_ui_text(srna, "Mesh String Property Layer", "User defined layer of string text values");
- RNA_def_struct_path_func(srna, "rna_MeshStringPropertyLayer_path");
-
- prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_struct_name_property(srna, prop);
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set");
- RNA_def_property_ui_text(prop, "Name", "");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
-
- prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_struct_type(prop, "MeshStringProperty");
- RNA_def_property_ui_text(prop, "Data", "");
- RNA_def_property_collection_funcs(prop, "rna_MeshStringPropertyLayer_data_begin", "rna_iterator_array_next",
- "rna_iterator_array_end", "rna_iterator_array_get",
- "rna_MeshStringPropertyLayer_data_length", NULL, NULL, NULL);
+#define MESH_STRING_PROPERTY_LAYER(elemname) \
+ srna = RNA_def_struct(brna, "Mesh" elemname "StringPropertyLayer", NULL); \
+ RNA_def_struct_sdna(srna, "CustomDataLayer"); \
+ RNA_def_struct_ui_text(srna, "Mesh " elemname " String Property Layer", "User defined layer of string text values"); \
+ RNA_def_struct_path_func(srna, "rna_Mesh" elemname "StringPropertyLayer_path"); \
+ \
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); \
+ RNA_def_struct_name_property(srna, prop); \
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set"); \
+ RNA_def_property_ui_text(prop, "Name", ""); \
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); \
+ \
+ prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); \
+ RNA_def_property_struct_type(prop, "Mesh" elemname "StringProperty"); \
+ RNA_def_property_ui_text(prop, "Data", ""); \
+ RNA_def_property_collection_funcs(prop, "rna_Mesh" elemname "StringPropertyLayer_data_begin", "rna_iterator_array_next", \
+ "rna_iterator_array_end", "rna_iterator_array_get", \
+ "rna_Mesh" elemname "StringPropertyLayer_data_length", NULL, NULL, NULL); \
+ \
+ srna = RNA_def_struct(brna, "Mesh" elemname "StringProperty", NULL); \
+ RNA_def_struct_sdna(srna, "MStringProperty"); \
+ RNA_def_struct_ui_text(srna, "Mesh " elemname " String Property", \
+ "User defined string text value in a string properties layer"); \
+ RNA_def_struct_path_func(srna, "rna_Mesh" elemname "StringProperty_path"); \
+ \
+ /* low level mesh data access, treat as bytes */ \
+ prop = RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING); \
+ RNA_def_property_string_sdna(prop, NULL, "s"); \
+ RNA_def_property_string_funcs(prop, "rna_MeshStringProperty_s_get", "rna_MeshStringProperty_s_length", "rna_MeshStringProperty_s_set"); \
+ RNA_def_property_ui_text(prop, "Value", ""); \
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); \
+
+ MESH_FLOAT_PROPERTY_LAYER("Vertex")
+ MESH_FLOAT_PROPERTY_LAYER("Polygon")
+ MESH_INT_PROPERTY_LAYER("Vertex")
+ MESH_INT_PROPERTY_LAYER("Polygon")
+ MESH_STRING_PROPERTY_LAYER("Vertex")
+ MESH_STRING_PROPERTY_LAYER("Polygon")
+#undef MESH_PROPERTY_LAYER
- srna = RNA_def_struct(brna, "MeshStringProperty", NULL);
- RNA_def_struct_sdna(srna, "MStringProperty");
- RNA_def_struct_ui_text(srna, "Mesh String Property",
- "User defined string text value in a string properties layer");
- RNA_def_struct_path_func(srna, "rna_MeshStringProperty_path");
-
- /* low level mesh data access, treat as bytes */
- prop = RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING);
- RNA_def_property_string_sdna(prop, NULL, "s");
- RNA_def_property_string_funcs(prop, "rna_MeshStringProperty_s_get", "rna_MeshStringProperty_s_length", "rna_MeshStringProperty_s_set");
- RNA_def_property_ui_text(prop, "Value", "");
- RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
}
void rna_def_texmat_common(StructRNA *srna, const char *texspace_editable)
@@ -2814,23 +2918,65 @@ static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
}
+/* mesh float layers */
+static void rna_def_vertex_float_layers(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "VertexFloatProperties");
+ srna = RNA_def_struct(brna, "VertexFloatProperties", NULL);
+ RNA_def_struct_sdna(srna, "Mesh");
+ RNA_def_struct_ui_text(srna, "Vertex Float Properties", "Collection of float properties");
+
+ func = RNA_def_function(srna, "new", "rna_Mesh_vertex_float_property_new");
+ RNA_def_function_ui_description(func, "Add a float property layer to Mesh");
+ RNA_def_string(func, "name", "Float Prop", 0, "", "Float property name");
+ parm = RNA_def_pointer(func, "layer", "MeshVertexFloatPropertyLayer", "", "The newly created layer");
+ RNA_def_property_flag(parm, PROP_RNAPTR);
+ RNA_def_function_return(func, parm);
+}
+
/* mesh int layers */
-static void rna_def_polygon_int_layers(BlenderRNA *brna, PropertyRNA *cprop)
+static void rna_def_vertex_int_layers(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
- RNA_def_property_srna(cprop, "IntProperties");
- srna = RNA_def_struct(brna, "IntProperties", NULL);
+ RNA_def_property_srna(cprop, "VertexIntProperties");
+ srna = RNA_def_struct(brna, "VertexIntProperties", NULL);
RNA_def_struct_sdna(srna, "Mesh");
- RNA_def_struct_ui_text(srna, "Int Properties", "Collection of int properties");
+ RNA_def_struct_ui_text(srna, "Vertex Int Properties", "Collection of int properties");
- func = RNA_def_function(srna, "new", "rna_Mesh_polygon_int_property_new");
+ func = RNA_def_function(srna, "new", "rna_Mesh_vertex_int_property_new");
RNA_def_function_ui_description(func, "Add a integer property layer to Mesh");
RNA_def_string(func, "name", "Int Prop", 0, "", "Int property name");
- parm = RNA_def_pointer(func, "layer", "MeshIntPropertyLayer", "", "The newly created layer");
+ parm = RNA_def_pointer(func, "layer", "MeshVertexIntPropertyLayer", "", "The newly created layer");
+ RNA_def_property_flag(parm, PROP_RNAPTR);
+ RNA_def_function_return(func, parm);
+}
+
+/* mesh string layers */
+static void rna_def_vertex_string_layers(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "VertexStringProperties");
+ srna = RNA_def_struct(brna, "VertexStringProperties", NULL);
+ RNA_def_struct_sdna(srna, "Mesh");
+ RNA_def_struct_ui_text(srna, "Vertex String Properties", "Collection of string properties");
+
+ func = RNA_def_function(srna, "new", "rna_Mesh_vertex_string_property_new");
+ RNA_def_function_ui_description(func, "Add a string property layer to Mesh");
+ RNA_def_string(func, "name", "String Prop", 0, "", "String property name");
+ parm = RNA_def_pointer(func, "layer", "MeshVertexStringPropertyLayer", "", "The newly created layer");
RNA_def_property_flag(parm, PROP_RNAPTR);
RNA_def_function_return(func, parm);
}
@@ -2843,15 +2989,36 @@ static void rna_def_polygon_float_layers(BlenderRNA *brna, PropertyRNA *cprop)
FunctionRNA *func;
PropertyRNA *parm;
- RNA_def_property_srna(cprop, "FloatProperties");
- srna = RNA_def_struct(brna, "FloatProperties", NULL);
+ RNA_def_property_srna(cprop, "PolygonFloatProperties");
+ srna = RNA_def_struct(brna, "PolygonFloatProperties", NULL);
RNA_def_struct_sdna(srna, "Mesh");
- RNA_def_struct_ui_text(srna, "Float Properties", "Collection of float properties");
+ RNA_def_struct_ui_text(srna, "Polygon Float Properties", "Collection of float properties");
func = RNA_def_function(srna, "new", "rna_Mesh_polygon_float_property_new");
RNA_def_function_ui_description(func, "Add a float property layer to Mesh");
RNA_def_string(func, "name", "Float Prop", 0, "", "Float property name");
- parm = RNA_def_pointer(func, "layer", "MeshFloatPropertyLayer", "", "The newly created layer");
+ parm = RNA_def_pointer(func, "layer", "MeshPolygonFloatPropertyLayer", "", "The newly created layer");
+ RNA_def_property_flag(parm, PROP_RNAPTR);
+ RNA_def_function_return(func, parm);
+}
+
+/* mesh int layers */
+static void rna_def_polygon_int_layers(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "PolygonIntProperties");
+ srna = RNA_def_struct(brna, "PolygonIntProperties", NULL);
+ RNA_def_struct_sdna(srna, "Mesh");
+ RNA_def_struct_ui_text(srna, "Polygon Int Properties", "Collection of int properties");
+
+ func = RNA_def_function(srna, "new", "rna_Mesh_polygon_int_property_new");
+ RNA_def_function_ui_description(func, "Add a integer property layer to Mesh");
+ RNA_def_string(func, "name", "Int Prop", 0, "", "Int property name");
+ parm = RNA_def_pointer(func, "layer", "MeshPolygonIntPropertyLayer", "", "The newly created layer");
RNA_def_property_flag(parm, PROP_RNAPTR);
RNA_def_function_return(func, parm);
}
@@ -2864,15 +3031,15 @@ static void rna_def_polygon_string_layers(BlenderRNA *brna, PropertyRNA *cprop)
FunctionRNA *func;
PropertyRNA *parm;
- RNA_def_property_srna(cprop, "StringProperties");
- srna = RNA_def_struct(brna, "StringProperties", NULL);
+ RNA_def_property_srna(cprop, "PolygonStringProperties");
+ srna = RNA_def_struct(brna, "PolygonStringProperties", NULL);
RNA_def_struct_sdna(srna, "Mesh");
- RNA_def_struct_ui_text(srna, "String Properties", "Collection of string properties");
+ RNA_def_struct_ui_text(srna, "Polygon String Properties", "Collection of string properties");
func = RNA_def_function(srna, "new", "rna_Mesh_polygon_string_property_new");
RNA_def_function_ui_description(func, "Add a string property layer to Mesh");
RNA_def_string(func, "name", "String Prop", 0, "", "String property name");
- parm = RNA_def_pointer(func, "layer", "MeshStringPropertyLayer", "", "The newly created layer");
+ parm = RNA_def_pointer(func, "layer", "MeshPolygonStringPropertyLayer", "", "The newly created layer");
RNA_def_property_flag(parm, PROP_RNAPTR);
RNA_def_function_return(func, parm);
}
@@ -3150,12 +3317,36 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Vertex Colors", "All vertex colors");
rna_def_loop_colors(brna, prop);
- /* TODO, vertex, edge customdata layers (bmesh py api can access already) */
+ /* TODO, edge customdata layers (bmesh py api can access already) */
+ prop = RNA_def_property(srna, "vertex_layers_float", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer");
+ RNA_def_property_collection_funcs(prop, "rna_Mesh_vertex_float_layers_begin", NULL, NULL, NULL,
+ "rna_Mesh_vertex_float_layers_length", NULL, NULL, NULL);
+ RNA_def_property_struct_type(prop, "MeshVertexFloatPropertyLayer");
+ RNA_def_property_ui_text(prop, "Float Property Layers", "");
+ rna_def_vertex_float_layers(brna, prop);
+
+ prop = RNA_def_property(srna, "vertex_layers_int", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer");
+ RNA_def_property_collection_funcs(prop, "rna_Mesh_vertex_int_layers_begin", NULL, NULL, NULL,
+ "rna_Mesh_vertex_int_layers_length", NULL, NULL, NULL);
+ RNA_def_property_struct_type(prop, "MeshVertexIntPropertyLayer");
+ RNA_def_property_ui_text(prop, "Int Property Layers", "");
+ rna_def_vertex_int_layers(brna, prop);
+
+ prop = RNA_def_property(srna, "vertex_layers_string", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer");
+ RNA_def_property_collection_funcs(prop, "rna_Mesh_vertex_string_layers_begin", NULL, NULL, NULL,
+ "rna_Mesh_vertex_string_layers_length", NULL, NULL, NULL);
+ RNA_def_property_struct_type(prop, "MeshVertexStringPropertyLayer");
+ RNA_def_property_ui_text(prop, "String Property Layers", "");
+ rna_def_vertex_string_layers(brna, prop);
+
prop = RNA_def_property(srna, "polygon_layers_float", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer");
RNA_def_property_collection_funcs(prop, "rna_Mesh_polygon_float_layers_begin", NULL, NULL, NULL,
"rna_Mesh_polygon_float_layers_length", NULL, NULL, NULL);
- RNA_def_property_struct_type(prop, "MeshFloatPropertyLayer");
+ RNA_def_property_struct_type(prop, "MeshPolygonFloatPropertyLayer");
RNA_def_property_ui_text(prop, "Float Property Layers", "");
rna_def_polygon_float_layers(brna, prop);
@@ -3163,7 +3354,7 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer");
RNA_def_property_collection_funcs(prop, "rna_Mesh_polygon_int_layers_begin", NULL, NULL, NULL,
"rna_Mesh_polygon_int_layers_length", NULL, NULL, NULL);
- RNA_def_property_struct_type(prop, "MeshIntPropertyLayer");
+ RNA_def_property_struct_type(prop, "MeshPolygonIntPropertyLayer");
RNA_def_property_ui_text(prop, "Int Property Layers", "");
rna_def_polygon_int_layers(brna, prop);
@@ -3171,7 +3362,7 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer");
RNA_def_property_collection_funcs(prop, "rna_Mesh_polygon_string_layers_begin", NULL, NULL, NULL,
"rna_Mesh_polygon_string_layers_length", NULL, NULL, NULL);
- RNA_def_property_struct_type(prop, "MeshStringPropertyLayer");
+ RNA_def_property_struct_type(prop, "MeshPolygonStringPropertyLayer");
RNA_def_property_ui_text(prop, "String Property Layers", "");
rna_def_polygon_string_layers(brna, prop);
@@ -3188,8 +3379,8 @@ static void rna_def_mesh(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_auto_smooth", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_AUTOSMOOTH);
RNA_def_property_ui_text(prop, "Auto Smooth",
- "Treat all set-smoothed faces with angles less than the specified angle "
- "as 'smooth', unless they are linked by a sharp edge");
+ "Auto smooth (based on smooth/sharp faces/edges and angle between faces), "
+ "or use custom split normals data if available");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
prop = RNA_def_property(srna, "auto_smooth_angle", PROP_FLOAT, PROP_ANGLE);
@@ -3198,9 +3389,19 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, DEG2RADF(180.0f));
RNA_def_property_ui_range(prop, DEG2RADF(0.0f), DEG2RADF(180.0f), 1.0, 1);
RNA_def_property_ui_text(prop, "Auto Smooth Angle",
- "Maximum angle between face normals that 'Auto Smooth' will operate on");
+ "Maximum angle between face normals that will be considered as smooth "
+ "(unused if custom split normals data are available)");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+ RNA_define_verify_sdna(false);
+ prop = RNA_def_property(srna, "has_custom_normals", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "", 0);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Has Custom Normals",
+ "True if there are custom split normals data in this mesh");
+ RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_custom_normals_get", NULL);
+ RNA_define_verify_sdna(true);
+
prop = RNA_def_property(srna, "show_double_sided", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_TWOSIDED);
RNA_def_property_ui_text(prop, "Double Sided", "Render/display the mesh with double or single sided lighting");
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index cc1f57d8a14..a994bf5e9d1 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -61,10 +61,19 @@ static const char *rna_Mesh_unit_test_compare(struct Mesh *mesh, struct Mesh *me
return ret;
}
-static void rna_Mesh_calc_normals_split(Mesh *mesh, float min_angle)
+static void rna_Mesh_create_normals_split(Mesh *mesh)
+{
+ if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
+ CustomData_add_layer(&mesh->ldata, CD_NORMAL, CD_CALLOC, NULL, mesh->totloop);
+ CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
+}
+
+static void rna_Mesh_calc_normals_split(Mesh *mesh)
{
float (*r_loopnors)[3];
float (*polynors)[3];
+ short (*clnors)[2] = NULL;
bool free_polynors = false;
if (CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
@@ -76,6 +85,9 @@ static void rna_Mesh_calc_normals_split(Mesh *mesh, float min_angle)
CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
}
+ /* may be NULL */
+ clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
+
if (CustomData_has_layer(&mesh->pdata, CD_NORMAL)) {
/* This assume that layer is always up to date, not sure this is the case (esp. in Edit mode?)... */
polynors = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
@@ -88,9 +100,10 @@ static void rna_Mesh_calc_normals_split(Mesh *mesh, float min_angle)
free_polynors = true;
}
- BKE_mesh_normals_loop_split(mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge,
- mesh->mloop, r_loopnors, mesh->totloop, mesh->mpoly, polynors, mesh->totpoly,
- min_angle);
+ BKE_mesh_normals_loop_split(
+ mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge,
+ mesh->mloop, r_loopnors, mesh->totloop, mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly,
+ (mesh->flag & ME_AUTOSMOOTH) != 0, mesh->smoothresh, NULL, clnors, NULL);
if (free_polynors) {
MEM_freeN(polynors);
@@ -117,7 +130,7 @@ static void rna_Mesh_calc_tangents(Mesh *mesh, ReportList *reports, const char *
/* Compute loop normals if needed. */
if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
- rna_Mesh_calc_normals_split(mesh, (float)M_PI);
+ rna_Mesh_calc_normals_split(mesh);
}
BKE_mesh_loop_tangents(mesh, uvmap, r_looptangents, reports);
@@ -128,6 +141,11 @@ static void rna_Mesh_free_tangents(Mesh *mesh)
CustomData_free_layers(&mesh->ldata, CD_MLOOPTANGENT, mesh->totloop);
}
+static void rna_Mesh_calc_tessface(Mesh *mesh, int free_mpoly)
+{
+ ED_mesh_calc_tessface(mesh, free_mpoly != 0);
+}
+
static void rna_Mesh_calc_smooth_groups(Mesh *mesh, int use_bitflags, int *r_poly_group_len,
int **r_poly_group, int *r_group_total)
{
@@ -139,6 +157,78 @@ static void rna_Mesh_calc_smooth_groups(Mesh *mesh, int use_bitflags, int *r_pol
r_group_total, use_bitflags);
}
+static void rna_Mesh_normals_split_custom_do(Mesh *mesh, float (*custom_loopnors)[3], const bool use_vertices)
+{
+ float (*polynors)[3];
+ short (*clnors)[2];
+ const int numloops = mesh->totloop;
+ bool free_polynors = false;
+
+ clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
+ if (clnors) {
+ memset(clnors, 0, sizeof(*clnors) * numloops);
+ }
+ else {
+ clnors = CustomData_add_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_DEFAULT, NULL, numloops);
+ }
+
+ if (CustomData_has_layer(&mesh->pdata, CD_NORMAL)) {
+ polynors = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
+ }
+ else {
+ polynors = MEM_mallocN(sizeof(float[3]) * mesh->totpoly, __func__);
+ BKE_mesh_calc_normals_poly(mesh->mvert, mesh->totvert, mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
+ polynors, false);
+ free_polynors = true;
+ }
+
+ if (use_vertices) {
+ BKE_mesh_normals_loop_custom_from_vertices_set(
+ mesh->mvert, custom_loopnors, mesh->totvert, mesh->medge, mesh->totedge, mesh->mloop, mesh->totloop,
+ mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly, clnors);
+ }
+ else {
+ BKE_mesh_normals_loop_custom_set(
+ mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge, mesh->mloop, custom_loopnors, mesh->totloop,
+ mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly, clnors);
+ }
+
+ if (free_polynors) {
+ MEM_freeN(polynors);
+ }
+}
+
+static void rna_Mesh_normals_split_custom_set(Mesh *mesh, ReportList *reports, int normals_len, float *normals)
+{
+ float (*loopnors)[3] = (float (*)[3])normals;
+ const int numloops = mesh->totloop;
+
+ if (normals_len != numloops * 3) {
+ BKE_reportf(reports, RPT_ERROR,
+ "Number of custom normals is not number of loops (%f / %d)",
+ (float)normals_len / 3.0f, numloops);
+ return;
+ }
+
+ rna_Mesh_normals_split_custom_do(mesh, loopnors, false);
+}
+
+static void rna_Mesh_normals_split_custom_set_from_vertices(
+ Mesh *mesh, ReportList *reports, int normals_len, float *normals)
+{
+ float (*vertnors)[3] = (float (*)[3])normals;
+ const int numverts = mesh->totvert;
+
+ if (normals_len != numverts * 3) {
+ BKE_reportf(reports, RPT_ERROR,
+ "Number of custom normals is not number of vertices (%f / %d)",
+ (float)normals_len / 3.0f, numverts);
+ return;
+ }
+
+ rna_Mesh_normals_split_custom_do(mesh, vertnors, true);
+}
+
static void rna_Mesh_transform(Mesh *mesh, float *mat, int shape_keys)
{
BKE_mesh_transform(mesh, (float (*)[4])mat, shape_keys);
@@ -152,6 +242,7 @@ void RNA_api_mesh(StructRNA *srna)
{
FunctionRNA *func;
PropertyRNA *parm;
+ const int normals_array_dim[] = {1, 3};
func = RNA_def_function(srna, "transform", "rna_Mesh_transform");
RNA_def_function_ui_description(func, "Transform mesh vertices by a matrix");
@@ -162,12 +253,11 @@ void RNA_api_mesh(StructRNA *srna)
func = RNA_def_function(srna, "calc_normals", "BKE_mesh_calc_normals");
RNA_def_function_ui_description(func, "Calculate vertex normals");
+ func = RNA_def_function(srna, "create_normals_split", "rna_Mesh_create_normals_split");
+ RNA_def_function_ui_description(func, "Empty split vertex normals");
+
func = RNA_def_function(srna, "calc_normals_split", "rna_Mesh_calc_normals_split");
RNA_def_function_ui_description(func, "Calculate split vertex normals, which preserve sharp edges");
- parm = RNA_def_float(func, "split_angle", M_PI, 0.0f, M_PI, "",
- "Angle between polys' normals above which an edge is always sharp (180° to disable)",
- 0.0f, M_PI);
- RNA_def_property_subtype(parm, (PropertySubType)PROP_UNIT_ROTATION);
func = RNA_def_function(srna, "free_normals_split", "rna_Mesh_free_normals_split");
RNA_def_function_ui_description(func, "Free split vertex normals");
@@ -184,8 +274,12 @@ void RNA_api_mesh(StructRNA *srna)
func = RNA_def_function(srna, "free_tangents", "rna_Mesh_free_tangents");
RNA_def_function_ui_description(func, "Free tangents");
- func = RNA_def_function(srna, "calc_tessface", "ED_mesh_calc_tessface");
+ func = RNA_def_function(srna, "calc_tessface", "rna_Mesh_calc_tessface");
RNA_def_function_ui_description(func, "Calculate face tessellation (supports editmode too)");
+ RNA_def_boolean(func, "free_mpoly", 0, "Free MPoly", "Free data used by polygons and loops. "
+ "WARNING: This destructive operation removes regular faces, "
+ "only used on temporary mesh data-blocks to reduce memory footprint of render "
+ "engines and export scripts.");
func = RNA_def_function(srna, "calc_smooth_groups", "rna_Mesh_calc_smooth_groups");
RNA_def_function_ui_description(func, "Calculate smooth groups from sharp edges");
@@ -196,6 +290,26 @@ void RNA_api_mesh(StructRNA *srna)
parm = RNA_def_int(func, "groups", 0, 0, INT_MAX, "groups", "Total number of groups", 0, INT_MAX);
RNA_def_property_flag(parm, PROP_OUTPUT);
+ func = RNA_def_function(srna, "normals_split_custom_set", "rna_Mesh_normals_split_custom_set");
+ RNA_def_function_ui_description(func,
+ "Define custom split normals of this mesh "
+ "(use zero-vectors to keep auto ones)");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ /* TODO, see how array size of 0 works, this shouldnt be used */
+ parm = RNA_def_float_array(func, "normals", 1, NULL, -1.0f, 1.0f, "", "Normals", 0.0f, 0.0f);
+ RNA_def_property_multi_array(parm, 2, normals_array_dim);
+ RNA_def_property_flag(parm, PROP_DYNAMIC | PROP_REQUIRED);
+
+ func = RNA_def_function(srna, "normals_split_custom_set_from_vertices",
+ "rna_Mesh_normals_split_custom_set_from_vertices");
+ RNA_def_function_ui_description(func,
+ "Define custom split normals of this mesh, from vertices' normals "
+ "(use zero-vectors to keep auto ones)");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ /* TODO, see how array size of 0 works, this shouldnt be used */
+ parm = RNA_def_float_array(func, "normals", 1, NULL, -1.0f, 1.0f, "", "Normals", 0.0f, 0.0f);
+ RNA_def_property_multi_array(parm, 2, normals_array_dim);
+ RNA_def_property_flag(parm, PROP_DYNAMIC | PROP_REQUIRED);
func = RNA_def_function(srna, "update", "ED_mesh_update");
RNA_def_boolean(func, "calc_edges", 0, "Calculate Edges", "Force recalculation of edges");
@@ -211,7 +325,9 @@ void RNA_api_mesh(StructRNA *srna)
func = RNA_def_function(srna, "validate", "BKE_mesh_validate");
RNA_def_function_ui_description(func, "Validate geometry, return True when the mesh has had "
"invalid geometry corrected/removed");
- RNA_def_boolean(func, "verbose", 0, "Verbose", "Output information about the errors found");
+ RNA_def_boolean(func, "verbose", false, "Verbose", "Output information about the errors found");
+ RNA_def_boolean(func, "clean_customdata", true, "Clean Custom Data",
+ "Remove temp/cached custom-data layers, like e.g. normals...");
parm = RNA_def_boolean(func, "result", 0, "Result", "");
RNA_def_function_return(func, parm);
diff --git a/source/blender/makesrna/intern/rna_mesh_utils.h b/source/blender/makesrna/intern/rna_mesh_utils.h
index c0ea1a153ff..f68a48c075b 100644
--- a/source/blender/makesrna/intern/rna_mesh_utils.h
+++ b/source/blender/makesrna/intern/rna_mesh_utils.h
@@ -20,7 +20,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/source/blender/makesrna/intern/rna_mesh_utils.h
+/** \file blender/makesrna/intern/rna_mesh_utils.h
* \ingroup RNA
*/
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 4911c106f53..656c19e8108 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -43,10 +43,16 @@
#include "BLF_translation.h"
#include "BKE_animsys.h"
+#include "BKE_data_transfer.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_dynamicpaint.h"
+#include "BKE_effect.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_remap.h"
#include "BKE_multires.h"
#include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */
+#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -57,7 +63,9 @@
EnumPropertyItem modifier_type_items[] = {
{0, "", 0, N_("Modify"), ""},
+ {eModifierType_DataTransfer, "DATA_TRANSFER", ICON_MOD_DATA_TRANSFER, "Data Transfer", ""},
{eModifierType_MeshCache, "MESH_CACHE", ICON_MOD_MESHDEFORM, "Mesh Cache", ""},
+ {eModifierType_NormalEdit, "NORMAL_EDIT", ICON_MOD_NORMALEDIT, "Normal Edit", ""},
{eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""},
{eModifierType_UVWarp, "UV_WARP", ICON_MOD_UVPROJECT, "UV Warp", ""},
{eModifierType_WeightVGEdit, "VERTEX_WEIGHT_EDIT", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Edit", ""},
@@ -127,9 +135,130 @@ EnumPropertyItem modifier_triangulate_ngon_method_items[] = {
{0, NULL, 0, NULL, NULL}
};
+#ifndef RNA_RUNTIME
+/* use eWarp_Falloff_*** & eHook_Falloff_***, they're in sync */
+static EnumPropertyItem modifier_warp_falloff_items[] = {
+ {eWarp_Falloff_None, "NONE", 0, "No Falloff", ""},
+ {eWarp_Falloff_Curve, "CURVE", 0, "Curve", ""},
+ {eWarp_Falloff_Smooth, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", ""},
+ {eWarp_Falloff_Sphere, "SPHERE", ICON_SPHERECURVE, "Sphere", ""},
+ {eWarp_Falloff_Root, "ROOT", ICON_ROOTCURVE, "Root", ""},
+ {eWarp_Falloff_InvSquare, "INVERSE_SQUARE", ICON_ROOTCURVE, "Inverse Square", ""},
+ {eWarp_Falloff_Sharp, "SHARP", ICON_SHARPCURVE, "Sharp", ""},
+ {eWarp_Falloff_Linear, "LINEAR", ICON_LINCURVE, "Linear", ""},
+ {eWarp_Falloff_Const, "CONSTANT", ICON_NOCURVE, "Constant", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+#endif
+
+/* ***** Data Transfer ***** */
+
+EnumPropertyItem DT_method_vertex_items[] = {
+ {MREMAP_MODE_TOPOLOGY, "TOPOLOGY", 0, "Topology",
+ "Copy from identical topology meshes"},
+ {MREMAP_MODE_VERT_NEAREST, "NEAREST", 0, "Nearest vertex",
+ "Copy from closest vertex"},
+ {MREMAP_MODE_VERT_EDGE_NEAREST, "EDGE_NEAREST", 0, "Nearest Edge Vertex",
+ "Copy from closest vertex of closest edge"},
+ {MREMAP_MODE_VERT_EDGEINTERP_NEAREST, "EDGEINTERP_NEAREST", 0, "Nearest Edge Interpolated",
+ "Copy from interpolated values of vertices from closest point on closest edge"},
+ {MREMAP_MODE_VERT_POLY_NEAREST, "POLY_NEAREST", 0, "Nearest Face Vertex",
+ "Copy from closest vertex of closest face"},
+ {MREMAP_MODE_VERT_POLYINTERP_NEAREST, "POLYINTERP_NEAREST", 0, "Nearest Face Interpolated",
+ "Copy from interpolated values of vertices from closest point on closest face"},
+ {MREMAP_MODE_VERT_POLYINTERP_VNORPROJ, "POLYINTERP_VNORPROJ", 0, "Projected Face Interpolated",
+ "Copy from interpolated values of vertices from point on closest face hit by normal-projection"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem DT_method_edge_items[] = {
+ {MREMAP_MODE_TOPOLOGY, "TOPOLOGY", 0, "Topology",
+ "Copy from identical topology meshes"},
+ {MREMAP_MODE_EDGE_VERT_NEAREST, "VERT_NEAREST", 0, "Nearest Vertices",
+ "Copy from most similar edge (edge which vertices are the closest of destination edge’s ones)"},
+ {MREMAP_MODE_EDGE_NEAREST, "NEAREST", 0, "Nearest Edge",
+ "Copy from closest edge (using midpoints)"},
+ {MREMAP_MODE_EDGE_POLY_NEAREST, "POLY_NEAREST", 0, "Nearest Face Edge",
+ "Copy from closest edge of closest face (using midpoints)"},
+ {MREMAP_MODE_EDGE_EDGEINTERP_VNORPROJ, "EDGEINTERP_VNORPROJ", 0, "Projected Edge Interpolated",
+ "Interpolate all source edges hit by the projection of destination one along its own normal (from vertices)"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem DT_method_loop_items[] = {
+ {MREMAP_MODE_TOPOLOGY, "TOPOLOGY", 0, "Topology",
+ "Copy from identical topology meshes"},
+ {MREMAP_MODE_LOOP_NEAREST_LOOPNOR, "NEAREST_NORMAL", 0, "Nearest Corner And Best Matching Normal",
+ "Copy from nearest corner which has the best matching normal"},
+ {MREMAP_MODE_LOOP_NEAREST_POLYNOR, "NEAREST_POLYNOR", 0, "Nearest Corner And Best Matching Face Normal",
+ "Copy from nearest corner which has the face with the best matching normal to destination corner's face one"},
+ {MREMAP_MODE_LOOP_POLY_NEAREST, "NEAREST_POLY", 0, "Nearest Corner Of Nearest Face",
+ "Copy from nearest corner of nearest polygon"},
+ {MREMAP_MODE_LOOP_POLYINTERP_NEAREST, "POLYINTERP_NEAREST", 0, "Nearest Face Interpolated",
+ "Copy from interpolated corners of the nearest source polygon"},
+ {MREMAP_MODE_LOOP_POLYINTERP_LNORPROJ, "POLYINTERP_LNORPROJ", 0, "Projected Face Interpolated",
+ "Copy from interpolated corners of the source polygon hit by corner normal projection"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem DT_method_poly_items[] = {
+ {MREMAP_MODE_TOPOLOGY, "TOPOLOGY", 0, "Topology",
+ "Copy from identical topology meshes"},
+ {MREMAP_MODE_POLY_NEAREST, "NEAREST", 0, "Nearest Face",
+ "Copy from nearest polygon (using center points)"},
+ {MREMAP_MODE_POLY_NOR, "NORMAL", 0, "Best Normal-Matching",
+ "Copy from source polygon which normal is the closest to destination one"},
+ {MREMAP_MODE_POLY_POLYINTERP_PNORPROJ, "POLYINTERP_PNORPROJ", 0, "Projected Face Interpolated",
+ "Interpolate all source polygons intersected by the projection of destination one along its own normal"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem DT_mix_mode_items[] = {
+ {CDT_MIX_TRANSFER, "REPLACE", 0, "Replace",
+ "Overwrite all elements' data"},
+ {CDT_MIX_REPLACE_ABOVE_THRESHOLD, "ABOVE_THRESHOLD", 0, "Above Threshold",
+ "Only replace destination elements where data is above given threshold (exact behavior depends on data type)"},
+ {CDT_MIX_REPLACE_BELOW_THRESHOLD, "BELOW_THRESHOLD", 0, "Below Threshold",
+ "Only replace destination elements where data is below given threshold (exact behavior depends on data type)"},
+ {CDT_MIX_MIX, "MIX", 0, "Mix",
+ "Mix source value into destination one, using given threshold as factor"},
+ {CDT_MIX_ADD, "ADD", 0, "Add",
+ "Add source value to destination one, using given threshold as factor"},
+ {CDT_MIX_SUB, "SUB", 0, "Subtract",
+ "Subtract source value to destination one, using given threshold as factor"},
+ {CDT_MIX_MUL, "MUL", 0, "Multiply",
+ "Multiply source value to destination one, using given threshold as factor"},
+ /* etc. etc. */
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem DT_layers_select_src_items[] = {
+ {DT_LAYERS_ACTIVE_SRC, "ACTIVE", 0, "Active Layer",
+ "Only transfer active data layer"},
+ {DT_LAYERS_ALL_SRC, "ALL", 0, "All Layers",
+ "Transfer all data layers"},
+ {DT_LAYERS_VGROUP_SRC_BONE_SELECT, "BONE_SELECT", 0, "Selected Pose Bones",
+ "Transfer all vertex groups used by selected pose bones"},
+ {DT_LAYERS_VGROUP_SRC_BONE_DEFORM, "BONE_DEFORM", 0, "Deform Pose Bones",
+ "Transfer all vertex groups used by deform bones"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem DT_layers_select_dst_items[] = {
+ {DT_LAYERS_ACTIVE_DST, "ACTIVE", 0, "Active Layer",
+ "Affect active data layer of all targets"},
+ {DT_LAYERS_NAME_DST, "NAME", 0, "By Name",
+ "Match target data layers to affect by name"},
+ {DT_LAYERS_INDEX_DST, "INDEX", 0, "By Order",
+ "Match target data layers to affect by order (indices)"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+
#ifdef RNA_RUNTIME
#include "DNA_particle_types.h"
+#include "DNA_curve_types.h"
#include "DNA_smoke_types.h"
#include "BKE_context.h"
@@ -244,6 +373,10 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
return &RNA_LaplacianDeformModifier;
case eModifierType_Wireframe:
return &RNA_WireframeModifier;
+ case eModifierType_DataTransfer:
+ return &RNA_DataTransferModifier;
+ case eModifierType_NormalEdit:
+ return &RNA_NormalEditModifier;
/* Default */
case eModifierType_None:
case eModifierType_ShapeKey:
@@ -309,6 +442,7 @@ RNA_MOD_VGROUP_NAME_SET(Armature, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Bevel, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Cast, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Curve, name);
+RNA_MOD_VGROUP_NAME_SET(DataTransfer, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Decimate, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Displace, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Hook, name);
@@ -317,6 +451,7 @@ RNA_MOD_VGROUP_NAME_SET(LaplacianSmooth, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Lattice, name);
RNA_MOD_VGROUP_NAME_SET(Mask, vgroup);
RNA_MOD_VGROUP_NAME_SET(MeshDeform, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(NormalEdit, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Shrinkwrap, vgroup_name);
RNA_MOD_VGROUP_NAME_SET(SimpleDeform, vgroup_name);
RNA_MOD_VGROUP_NAME_SET(Smooth, defgrp_name);
@@ -399,9 +534,11 @@ RNA_MOD_OBJECT_SET(Array, curve_ob, OB_CURVE);
RNA_MOD_OBJECT_SET(Boolean, object, OB_MESH);
RNA_MOD_OBJECT_SET(Cast, object, OB_EMPTY);
RNA_MOD_OBJECT_SET(Curve, object, OB_CURVE);
+RNA_MOD_OBJECT_SET(DataTransfer, ob_source, OB_MESH);
RNA_MOD_OBJECT_SET(Lattice, object, OB_LATTICE);
RNA_MOD_OBJECT_SET(Mask, ob_arm, OB_ARMATURE);
RNA_MOD_OBJECT_SET(MeshDeform, object, OB_MESH);
+RNA_MOD_OBJECT_SET(NormalEdit, target, OB_EMPTY);
RNA_MOD_OBJECT_SET(Shrinkwrap, target, OB_MESH);
RNA_MOD_OBJECT_SET(Shrinkwrap, auxTarget, OB_MESH);
@@ -495,7 +632,7 @@ static void rna_MultiresModifier_filepath_set(PointerRNA *ptr, const char *value
Object *ob = (Object *)ptr->id.data;
CustomDataExternal *external = ((Mesh *)ob->data)->ldata.external;
- if (external && strcmp(external->filename, value)) {
+ if (external && !STREQ(external->filename, value)) {
BLI_strncpy(external->filename, value, sizeof(external->filename));
multires_force_external_reload(ob);
}
@@ -604,6 +741,299 @@ static int rna_LaplacianDeformModifier_is_bind_get(PointerRNA *ptr)
return ((lmd->flag & MOD_LAPLACIANDEFORM_BIND) && (lmd->cache_system != NULL));
}
+/* NOTE: Curve and array modifiers requires curve path to be evaluated,
+ * dependency graph will make sure that curve eval would create such a path,
+ * but if curve was already evaluated we might miss path.
+ *
+ * So what we do here is: if path was not calculated for target curve we
+ * tag it for update.
+ */
+
+static void rna_CurveModifier_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ CurveModifierData *cmd = (CurveModifierData *)ptr->data;
+ rna_Modifier_update(bmain, scene, ptr);
+ DAG_relations_tag_update(bmain);
+ if (cmd->object != NULL) {
+ Curve *curve = cmd->object->data;
+ if ((curve->flag & CU_PATH) == 0) {
+ DAG_id_tag_update(&curve->id, OB_RECALC_DATA);
+ }
+ }
+}
+
+static void rna_ArrayModifier_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ ArrayModifierData *amd = (ArrayModifierData *)ptr->data;
+ rna_Modifier_update(bmain, scene, ptr);
+ DAG_relations_tag_update(bmain);
+ if (amd->curve_ob != NULL) {
+ Curve *curve = amd->curve_ob->data;
+ if ((curve->flag & CU_PATH) == 0) {
+ DAG_id_tag_update(&curve->id, OB_RECALC_DATA);
+ }
+ }
+}
+
+
+static void rna_DataTransferModifier_use_data_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)ptr->data;
+
+ if (!(dtmd->flags & MOD_DATATRANSFER_USE_VERT)) {
+ dtmd->data_types &= ~DT_TYPE_VERT_ALL;
+ }
+ if (!(dtmd->flags & MOD_DATATRANSFER_USE_EDGE)) {
+ dtmd->data_types &= ~DT_TYPE_EDGE_ALL;
+ }
+ if (!(dtmd->flags & MOD_DATATRANSFER_USE_LOOP)) {
+ dtmd->data_types &= ~DT_TYPE_LOOP_ALL;
+ }
+ if (!(dtmd->flags & MOD_DATATRANSFER_USE_POLY)) {
+ dtmd->data_types &= ~DT_TYPE_POLY_ALL;
+ }
+
+ rna_Modifier_update(bmain, scene, ptr);
+}
+
+static void rna_DataTransferModifier_data_types_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)ptr->data;
+ const int item_types = BKE_object_data_transfer_get_dttypes_item_types(dtmd->data_types);
+
+ if (item_types & ME_VERT) {
+ dtmd->flags |= MOD_DATATRANSFER_USE_VERT;
+ }
+ if (item_types & ME_EDGE) {
+ dtmd->flags |= MOD_DATATRANSFER_USE_EDGE;
+ }
+ if (item_types & ME_LOOP) {
+ dtmd->flags |= MOD_DATATRANSFER_USE_LOOP;
+ }
+ if (item_types & ME_POLY) {
+ dtmd->flags |= MOD_DATATRANSFER_USE_POLY;
+ }
+
+ rna_Modifier_update(bmain, scene, ptr);
+}
+
+static EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)ptr->data;
+ EnumPropertyItem *item = NULL, tmp_item = {0};
+ int totitem = 0;
+
+ if (!C) { /* needed for docs and i18n tools */
+ return DT_layers_select_src_items;
+ }
+
+ /* No active here! */
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_ALL_SRC);
+
+ if (STREQ(RNA_property_identifier(prop), "layers_vgroup_select_src")) {
+ Object *ob_src = dtmd->ob_source;
+
+#if 0 /* XXX Don't think we want this in modifier version... */
+ if (BKE_object_pose_armature_get(ob_src)) {
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_SELECT);
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_DEFORM);
+ }
+#endif
+
+ if (ob_src) {
+ bDeformGroup *dg;
+ int i;
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0, dg = ob_src->defbase.first; dg; i++, dg = dg->next) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = dg->name;
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_shapekey_select_src")) {
+ /* TODO */
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_uv_select_src")) {
+ Object *ob_src = dtmd->ob_source;
+
+ if (ob_src) {
+ DerivedMesh *dm_src;
+ CustomData *pdata;
+ int num_data, i;
+
+ /* XXX Is this OK? */
+ dm_src = mesh_get_derived_final(dtmd->modifier.scene, ob_src, CD_MASK_BAREMESH | CD_MTEXPOLY);
+ pdata = dm_src->getPolyDataLayout(dm_src);
+ num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_vcol_select_src")) {
+ Object *ob_src = dtmd->ob_source;
+
+ if (ob_src) {
+ DerivedMesh *dm_src;
+ CustomData *ldata;
+ int num_data, i;
+
+ /* XXX Is this OK? */
+ dm_src = mesh_get_derived_final(dtmd->modifier.scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL);
+ ldata = dm_src->getLoopDataLayout(dm_src);
+ num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPCOL, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+static EnumPropertyItem *rna_DataTransferModifier_layers_select_dst_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)ptr->data;
+ EnumPropertyItem *item = NULL, tmp_item = {0};
+ int totitem = 0;
+
+ if (!C) { /* needed for docs and i18n tools */
+ return DT_layers_select_dst_items;
+ }
+
+ /* No active here! */
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_dst_items, DT_LAYERS_NAME_DST);
+ RNA_enum_items_add_value(&item, &totitem, DT_layers_select_dst_items, DT_LAYERS_INDEX_DST);
+
+ if (STREQ(RNA_property_identifier(prop), "layers_vgroup_select_dst")) {
+ /* Only list destination layers if we have a single source! */
+ if (dtmd->layers_select_src[DT_MULTILAYER_INDEX_MDEFORMVERT] >= 0) {
+ Object *ob_dst = CTX_data_active_object(C); /* XXX Is this OK? */
+
+ if (ob_dst) {
+ bDeformGroup *dg;
+ int i;
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0, dg = ob_dst->defbase.first; dg; i++, dg = dg->next) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = dg->name;
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_shapekey_select_dst")) {
+ /* TODO */
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_uv_select_dst")) {
+ /* Only list destination layers if we have a single source! */
+ if (dtmd->layers_select_src[DT_MULTILAYER_INDEX_UV] >= 0) {
+ Object *ob_dst = CTX_data_active_object(C); /* XXX Is this OK? */
+
+ if (ob_dst && ob_dst->data) {
+ Mesh *me_dst;
+ CustomData *pdata;
+ int num_data, i;
+
+ me_dst = ob_dst->data;
+ pdata = &me_dst->pdata;
+ num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ }
+ else if (STREQ(RNA_property_identifier(prop), "layers_vcol_select_dst")) {
+ /* Only list destination layers if we have a single source! */
+ if (dtmd->layers_select_src[DT_MULTILAYER_INDEX_VCOL] >= 0) {
+ Object *ob_dst = CTX_data_active_object(C); /* XXX Is this OK? */
+
+ if (ob_dst && ob_dst->data) {
+ Mesh *me_dst;
+ CustomData *ldata;
+ int num_data, i;
+
+ me_dst = ob_dst->data;
+ ldata = &me_dst->ldata;
+ num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
+
+ RNA_enum_item_add_separator(&item, &totitem);
+
+ for (i = 0; i < num_data; i++) {
+ tmp_item.value = i;
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPCOL, i);
+ RNA_enum_item_add(&item, &totitem, &tmp_item);
+ }
+ }
+ }
+ }
+
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+static EnumPropertyItem *rna_DataTransferModifier_mix_mode_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *)ptr->data;
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
+
+ bool support_advanced_mixing, support_threshold;
+
+ if (!C) { /* needed for docs and i18n tools */
+ return DT_mix_mode_items;
+ }
+
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_TRANSFER);
+
+ BKE_object_data_transfer_get_dttypes_capacity(dtmd->data_types, &support_advanced_mixing, &support_threshold);
+
+ if (support_threshold) {
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_REPLACE_ABOVE_THRESHOLD);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_REPLACE_BELOW_THRESHOLD);
+ }
+
+ if (support_advanced_mixing) {
+ RNA_enum_item_add_separator(&item, &totitem);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_MIX);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_ADD);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_SUB);
+ RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_MUL);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
#else
static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[])
@@ -702,18 +1132,6 @@ static void rna_def_modifier_warp(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem prop_falloff_items[] = {
- {eWarp_Falloff_None, "NONE", 0, "No Falloff", ""},
- {eWarp_Falloff_Curve, "CURVE", 0, "Curve", ""},
- {eWarp_Falloff_Smooth, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", ""},
- {eWarp_Falloff_Sphere, "SPHERE", ICON_SPHERECURVE, "Sphere", ""},
- {eWarp_Falloff_Root, "ROOT", ICON_ROOTCURVE, "Root", ""},
- {eWarp_Falloff_Sharp, "SHARP", ICON_SHARPCURVE, "Sharp", ""},
- {eWarp_Falloff_Linear, "LINEAR", ICON_LINCURVE, "Linear", ""},
- {eWarp_Falloff_Const, "CONSTANT", ICON_NOCURVE, "Constant", ""},
- {0, NULL, 0, NULL, NULL}
- };
-
srna = RNA_def_struct(brna, "WarpModifier", "Modifier");
RNA_def_struct_ui_text(srna, "Warp Modifier", "Warp modifier");
RNA_def_struct_sdna(srna, "WarpModifierData");
@@ -736,7 +1154,7 @@ static void rna_def_modifier_warp(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, prop_falloff_items);
+ RNA_def_property_enum_items(prop, modifier_warp_falloff_items);
RNA_def_property_ui_text(prop, "Falloff Type", "");
RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -876,7 +1294,7 @@ static void rna_def_modifier_curve(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Object", "Curve object to deform with");
RNA_def_property_pointer_funcs(prop, NULL, "rna_CurveModifier_object_set", NULL, "rna_Curve_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
- RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+ RNA_def_property_update(prop, 0, "rna_CurveModifier_dependency_update");
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "name");
@@ -1268,15 +1686,28 @@ static void rna_def_modifier_hook(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "HookModifierData");
RNA_def_struct_ui_icon(srna, ICON_HOOK);
- prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_DISTANCE);
+ prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "force");
+ RNA_def_property_range(prop, 0, 1);
+ RNA_def_property_ui_text(prop, "Strength", "Relative force of the hook");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, modifier_warp_falloff_items); /* share the enum */
+ RNA_def_property_ui_text(prop, "Falloff Type", "");
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "falloff_radius", PROP_FLOAT, PROP_DISTANCE);
+ RNA_def_property_float_sdna(prop, NULL, "falloff");
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 100, 100, 2);
- RNA_def_property_ui_text(prop, "Falloff", "If not zero, the distance from the hook where influence ends");
+ RNA_def_property_ui_text(prop, "Radius", "If not zero, the distance from the hook where influence ends");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
- prop = RNA_def_property(srna, "force", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0, 1);
- RNA_def_property_ui_text(prop, "Force", "Relative force of the hook");
+ prop = RNA_def_property(srna, "falloff_curve", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "curfalloff");
+ RNA_def_property_ui_text(prop, "Falloff Curve", "Custom Lamp Falloff Curve");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_NONE);
@@ -1296,6 +1727,11 @@ static void rna_def_modifier_hook(BlenderRNA *brna)
"Name of Parent Bone for hook (if applicable), also recalculates and clears offset");
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+ prop = RNA_def_property(srna, "use_falloff_uniform", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_HOOK_UNIFORM_SPACE);
+ RNA_def_property_ui_text(prop, "Uniform Falloff", "Compensate for non-uniform object scale");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Vertex Group",
@@ -1399,7 +1835,7 @@ static void rna_def_modifier_array(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Curve", "Curve object to fit array length to");
RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_curve_ob_set", NULL, "rna_Curve_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
- RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+ RNA_def_property_update(prop, 0, "rna_ArrayModifier_dependency_update");
/* Offset parameters */
prop = RNA_def_property(srna, "use_constant_offset", PROP_BOOLEAN, PROP_NONE);
@@ -1840,7 +2276,7 @@ static void rna_def_modifier_meshdeform(BlenderRNA *brna)
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Object", "Mesh object to deform with");
- RNA_def_property_pointer_funcs(prop, NULL, "rna_MeshDeformModifier_object_set", NULL, NULL);
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_MeshDeformModifier_object_set", NULL, "rna_Mesh_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
@@ -1916,6 +2352,7 @@ static void rna_def_modifier_particleinstance(BlenderRNA *brna)
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "ob");
+ RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Mesh_object_poll");
RNA_def_property_ui_text(prop, "Object", "Object that has the particle system");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
@@ -2057,9 +2494,29 @@ static void rna_def_modifier_cloth(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "coll_parms");
RNA_def_property_ui_text(prop, "Cloth Collision Settings", "");
+ prop = RNA_def_property(srna, "solver_result", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "ClothSolverResult");
+ RNA_def_property_pointer_sdna(prop, NULL, "solver_result");
+ RNA_def_property_ui_text(prop, "Solver Result", "");
+
prop = RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_ui_text(prop, "Point Cache", "");
+
+ prop = RNA_def_property(srna, "hair_grid_min", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "hair_grid_min");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Hair Grid Minimum", "");
+
+ prop = RNA_def_property(srna, "hair_grid_max", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "hair_grid_max");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Hair Grid Maximum", "");
+
+ prop = RNA_def_property(srna, "hair_grid_resolution", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "hair_grid_res");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Hair Grid Resolution", "");
}
static void rna_def_modifier_smoke(BlenderRNA *brna)
@@ -2453,7 +2910,7 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "origin", PROP_POINTER, PROP_NONE);
- RNA_def_property_ui_text(prop, "Origin", "Origin of modifier space coordinates");
+ RNA_def_property_ui_text(prop, "Origin", "Offset the origin and orientation of the deformation");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
@@ -2747,24 +3204,24 @@ static void rna_def_modifier_uvwarp(BlenderRNA *brna)
prop = RNA_def_property(srna, "object_from", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "object_src");
- RNA_def_property_ui_text(prop, "Target", "Object defining offset");
+ RNA_def_property_ui_text(prop, "Object From", "Object defining offset");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "bone_from", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "bone_src");
- RNA_def_property_ui_text(prop, "Sub-Target", "Bone defining offset");
+ RNA_def_property_ui_text(prop, "Bone From", "Bone defining offset");
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "object_to", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "object_dst");
- RNA_def_property_ui_text(prop, "Target", "Object defining offset");
+ RNA_def_property_ui_text(prop, "Object To", "Object defining offset");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "bone_to", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "bone_dst");
- RNA_def_property_ui_text(prop, "Sub-Target", "Bone defining offset");
+ RNA_def_property_ui_text(prop, "Bone To", "Bone defining offset");
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
@@ -3664,6 +4121,323 @@ static void rna_def_modifier_wireframe(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
+static void rna_def_modifier_datatransfer(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem DT_layer_vert_items[] = {
+#if 0 /* XXX When SkinModifier is enabled, it seems to erase its own CD_MVERT_SKIN layer from final DM :( */
+ {DT_TYPE_SKIN, "SKIN", 0, "Skin Weight", "Transfer skin weights"},
+#endif
+ {DT_TYPE_BWEIGHT_VERT, "BEVEL_WEIGHT_VERT", 0, "Bevel Weight", "Transfer bevel weights"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ static EnumPropertyItem DT_layer_vert_vgroup_items[] = {
+ {DT_TYPE_MDEFORMVERT, "VGROUP_WEIGHTS", 0, "Vertex Group(s)", "Transfer active or all vertex groups"},
+ {0, NULL, 0, NULL, NULL}
+ };
+#if 0 /* XXX For now, would like to finish/merge work from 2014 gsoc first. */
+ static EnumPropertyItem DT_layer_vert_shapekey_items[] = {
+ {DT_TYPE_SHAPEKEY, "SHAPEKEYS", 0, "Shapekey(s)", "Transfer active or all shape keys"},
+ {0, NULL, 0, NULL, NULL}
+ };
+#endif
+
+ static EnumPropertyItem DT_layer_edge_items[] = {
+ {DT_TYPE_SHARP_EDGE, "SHARP_EDGE", 0, "Sharp", "Transfer sharp mark"},
+ {DT_TYPE_SEAM, "SEAM", 0, "UV Seam", "Transfer UV seam mark"},
+ {DT_TYPE_CREASE, "CREASE", 0, "Subsurf Crease", "Transfer crease values"},
+ {DT_TYPE_BWEIGHT_EDGE, "BEVEL_WEIGHT_EDGE", 0, "Bevel Weight", "Transfer bevel weights"},
+ {DT_TYPE_FREESTYLE_EDGE, "FREESTYLE_EDGE", 0, "Freestyle Mark", "Transfer Freestyle edge mark"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem DT_layer_loop_items[] = {
+ {DT_TYPE_LNOR, "CUSTOM_NORMAL", 0, "Custom Normals", "Transfer custom normals"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ static EnumPropertyItem DT_layer_loop_vcol_items[] = {
+ {DT_TYPE_VCOL, "VCOL", 0, "VCol", "Vertex (face corners) colors"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ static EnumPropertyItem DT_layer_loop_uv_items[] = {
+ {DT_TYPE_UV, "UV", 0, "UVs", "Transfer UV layers"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem DT_layer_poly_items[] = {
+ {DT_TYPE_SHARP_FACE, "SMOOTH", 0, "Smooth", "Transfer flat/smooth mark"},
+ {DT_TYPE_FREESTYLE_FACE, "FREESTYLE_FACE", 0, "Freestyle Mark", "Transfer Freestyle face mark"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "DataTransferModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "Data Transfer Modifier", "Modifier transferring some data from a source mesh");
+ RNA_def_struct_sdna(srna, "DataTransferModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_DATA_TRANSFER);
+
+ prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "ob_source");
+ RNA_def_property_ui_text(prop, "Source Object", "Object to transfer data from");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_DataTransferModifier_ob_source_set", NULL, "rna_Mesh_object_poll");
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+ prop = RNA_def_boolean(srna, "use_object_transform", true, "Object Transform",
+ "Evaluate source and destination meshes in their respective object spaces");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_OBSRC_TRANSFORM);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* Generic, UI-only data types toggles. */
+ prop = RNA_def_boolean(srna, "use_vert_data", false, "Vertex Data", "Enable vertex data transfer");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_USE_VERT);
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_use_data_update");
+
+ prop = RNA_def_boolean(srna, "use_edge_data", false, "Edge Data", "Enable edge data transfer");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_USE_EDGE);
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_use_data_update");
+
+ prop = RNA_def_boolean(srna, "use_loop_data", false, "Face Corner Data", "Enable face corner data transfer");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_USE_LOOP);
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_use_data_update");
+
+ prop = RNA_def_boolean(srna, "use_poly_data", false, "Face Data", "Enable face data transfer");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_USE_POLY);
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_use_data_update");
+
+ /* Actual data types selection. */
+ prop = RNA_def_enum(srna, "data_types_verts", DT_layer_vert_items, 0, "Vertex Data Types",
+ "Which vertex data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+ prop = RNA_def_enum(srna, "data_types_verts_vgroup", DT_layer_vert_vgroup_items, 0, "Vertex Data Types",
+ "Which vertex data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+
+ prop = RNA_def_enum(srna, "data_types_edges", DT_layer_edge_items, 0, "Edge Data Types",
+ "Which edge data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+
+ prop = RNA_def_enum(srna, "data_types_loops", DT_layer_loop_items, 0, "Face Corner Data Types",
+ "Which face corner data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+ prop = RNA_def_enum(srna, "data_types_loops_vcol", DT_layer_loop_vcol_items, 0, "Face Corner Data Types",
+ "Which face corner data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+ prop = RNA_def_enum(srna, "data_types_loops_uv", DT_layer_loop_uv_items, 0, "Face Corner Data Types",
+ "Which face corner data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+
+ prop = RNA_def_enum(srna, "data_types_polys", DT_layer_poly_items, 0, "Poly Data Types",
+ "Which poly data layers to transfer");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_enum_sdna(prop, NULL, "data_types");
+ RNA_def_property_update(prop, 0, "rna_DataTransferModifier_data_types_update");
+
+ /* Mapping methods. */
+ prop = RNA_def_enum(srna, "vert_mapping", DT_method_vertex_items, MREMAP_MODE_VERT_NEAREST, "Vertex Mapping",
+ "Method used to map source vertices to destination ones");
+ RNA_def_property_enum_sdna(prop, NULL, "vmap_mode");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "edge_mapping", DT_method_edge_items, MREMAP_MODE_EDGE_NEAREST, "Edge Mapping",
+ "Method used to map source edges to destination ones");
+ RNA_def_property_enum_sdna(prop, NULL, "emap_mode");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "loop_mapping", DT_method_loop_items, MREMAP_MODE_LOOP_NEAREST_POLYNOR,
+ "Face Corner Mapping", "Method used to map source faces' corners to destination ones");
+ RNA_def_property_enum_sdna(prop, NULL, "lmap_mode");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "poly_mapping", DT_method_poly_items, MREMAP_MODE_POLY_NEAREST, "Face Mapping",
+ "Method used to map source faces to destination ones");
+ RNA_def_property_enum_sdna(prop, NULL, "pmap_mode");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* Mapping options and filtering. */
+ prop = RNA_def_boolean(srna, "use_max_distance", false, "Only Neighbor Geometry",
+ "Source elements must be closer than given distance from destination one");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_MAP_MAXDIST);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_float(srna, "max_distance", 1.0f, 0.0f, FLT_MAX, "Max Distance",
+ "Maximum allowed distance between source and destination element, for non-topology mappings",
+ 0.0f, 100.0f);
+ RNA_def_property_float_sdna(prop, NULL, "map_max_distance");
+ RNA_def_property_subtype(prop, PROP_DISTANCE);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_float(srna, "ray_radius", 0.0f, 0.0f, FLT_MAX, "Ray Radius",
+ "'Width' of rays (especially useful when raycasting against vertices or edges)", 0.0f, 10.0f);
+ RNA_def_property_float_sdna(prop, NULL, "map_ray_radius");
+ RNA_def_property_subtype(prop, PROP_DISTANCE);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_float(srna, "islands_precision", 0.0f, 0.0f, 1.0f, "Islands Handling Refinement",
+ "Factor controlling precision of islands handling "
+ "(typically, 0.1 should be enough, higher values can make things really slow)", 0.0f, 1.0f);
+ RNA_def_property_subtype(prop, PROP_DISTANCE);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* How to handle multi-layers types of data. */
+ prop = RNA_def_enum(srna, "layers_vgroup_select_src", DT_layers_select_src_items, DT_LAYERS_ALL_SRC,
+ "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_src[DT_MULTILAYER_INDEX_MDEFORMVERT]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_src_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+#if 0
+ prop = RNA_def_enum(srna, "layers_shapekey_select_src", DT_layers_select_src_items, DT_LAYERS_ALL_SRC,
+ "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_src[DT_MULTILAYER_INDEX_SHAPEKEY]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_src_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+#endif
+
+ prop = RNA_def_enum(srna, "layers_vcol_select_src", DT_layers_select_src_items, DT_LAYERS_ALL_SRC,
+ "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_src[DT_MULTILAYER_INDEX_VCOL]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_src_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "layers_uv_select_src", DT_layers_select_src_items, DT_LAYERS_ALL_SRC,
+ "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_src[DT_MULTILAYER_INDEX_UV]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_src_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "layers_vgroup_select_dst", DT_layers_select_dst_items, DT_LAYERS_NAME_DST,
+ "Destination Layers Matching", "How to match source and destination layers");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_dst[DT_MULTILAYER_INDEX_MDEFORMVERT]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_dst_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+#if 0
+ prop = RNA_def_enum(srna, "layers_shapekey_select_dst", DT_layers_select_dst_items, DT_LAYERS_NAME_DST,
+ "Destination Layers Matching", "How to match source and destination layers");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_dst[DT_MULTILAYER_INDEX_SHAPEKEY]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_dst_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+#endif
+
+ prop = RNA_def_enum(srna, "layers_vcol_select_dst", DT_layers_select_dst_items, DT_LAYERS_NAME_DST,
+ "Destination Layers Matching", "How to match source and destination layers");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_dst[DT_MULTILAYER_INDEX_VCOL]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_dst_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_enum(srna, "layers_uv_select_dst", DT_layers_select_dst_items, DT_LAYERS_NAME_DST,
+ "Destination Layers Matching", "How to match source and destination layers");
+ RNA_def_property_enum_sdna(prop, NULL, "layers_select_dst[DT_MULTILAYER_INDEX_UV]");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_layers_select_dst_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* Mix stuff */
+ prop = RNA_def_enum(srna, "mix_mode", DT_mix_mode_items, CDT_MIX_TRANSFER, "Mix Mode",
+ "How to affect destination elements with source values");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_DataTransferModifier_mix_mode_itemf");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_float(srna, "mix_factor", 1.0f, 0.0f, 1.0f, "Mix Factor",
+ "Factor to use when applying data to destination (exact behavior depends on mix mode)",
+ 0.0f, 1.0f);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_string(srna, "vertex_group", NULL, MAX_VGROUP_NAME, "Vertex Group",
+ "Vertex group name for selecting the affected areas");
+ RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DataTransferModifier_defgrp_name_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_boolean(srna, "invert_vertex_group", false, "Invert", "Invert vertex group influence");
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_DATATRANSFER_INVERT_VGROUP);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}
+
+static void rna_def_modifier_normaledit(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_mode_items[] = {
+ {MOD_NORMALEDIT_MODE_RADIAL, "RADIAL", 0, "Radial",
+ "From an ellipsoid (shape defined by the boundbox's dimensions, target is optional)"},
+ {MOD_NORMALEDIT_MODE_DIRECTIONAL, "DIRECTIONAL", 0, "Directional",
+ "Normals 'track' (point to) the target object"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_mix_mode_items[] = {
+ {MOD_NORMALEDIT_MIX_COPY, "COPY", 0, "Copy", "Copy new normals (overwrite existing)"},
+ {MOD_NORMALEDIT_MIX_ADD, "ADD", 0, "Add", "Copy sum of new and old normals"},
+ {MOD_NORMALEDIT_MIX_SUB, "SUB", 0, "Subtract", "Copy new normals minus old normals"},
+ {MOD_NORMALEDIT_MIX_MUL, "MUL", 0, "Multiply", "Copy product of old and new normals (*not* cross product)"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
+ srna = RNA_def_struct(brna, "NormalEditModifier", "Modifier");
+ RNA_def_struct_ui_text(srna, "Normal Edit Modifier", "Modifier affecting/generating custom normals");
+ RNA_def_struct_sdna(srna, "NormalEditModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_NORMALEDIT);
+
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "How to affect (generate) normals");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_float_array(srna, "offset", 3, NULL, -FLT_MAX, FLT_MAX, "Offset",
+ "Offset from object's center", -100.0f, 100.0f);
+ RNA_def_property_subtype(prop, PROP_COORDS);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "mix_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_mix_mode_items);
+ RNA_def_property_ui_text(prop, "Mix Mode", "How to mix generated normals with existing ones");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_float(srna, "mix_factor", 1.0f, 0.0f, 1.0f, "Mix Factor",
+ "How much of generated normals to mix with exiting ones", 0.0f, 1.0f);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+ RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for selecting/weighting the affected areas");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NormalEditModifier_defgrp_name_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "use_invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_NORMALEDIT_INVERT_VGROUP);
+ RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Target", "Target object used to affect normals");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_NormalEditModifier_target_set", NULL, NULL);
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+ prop = RNA_def_property(srna, "use_direction_parallel", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_NORMALEDIT_USE_DIRECTION_PARALLEL);
+ RNA_def_property_boolean_default(prop, true);
+ RNA_def_property_ui_text(prop, "Parallel Normals",
+ "Use same direction for all normals, from origin to target's center "
+ "(Directional mode only)");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}
+
void RNA_def_modifier(BlenderRNA *brna)
{
StructRNA *srna;
@@ -3777,6 +4551,8 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_meshcache(brna);
rna_def_modifier_laplaciandeform(brna);
rna_def_modifier_wireframe(brna);
+ rna_def_modifier_datatransfer(brna);
+ rna_def_modifier_normaledit(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c
index 170856a3061..e891ab520f9 100644
--- a/source/blender/makesrna/intern/rna_movieclip.c
+++ b/source/blender/makesrna/intern/rna_movieclip.c
@@ -317,8 +317,8 @@ static void rna_def_movieclip(BlenderRNA *brna)
/* grease pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
- RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "GreasePencil");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this movie clip");
RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index e90de3631d6..eb2cb9e9312 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -112,25 +112,25 @@ EnumPropertyItem node_icon_items[] = {
#undef DEF_VICO
EnumPropertyItem node_math_items[] = {
- { 0, "ADD", 0, "Add", ""},
- { 1, "SUBTRACT", 0, "Subtract", ""},
- { 2, "MULTIPLY", 0, "Multiply", ""},
- { 3, "DIVIDE", 0, "Divide", ""},
- { 4, "SINE", 0, "Sine", ""},
- { 5, "COSINE", 0, "Cosine", ""},
- { 6, "TANGENT", 0, "Tangent", ""},
- { 7, "ARCSINE", 0, "Arcsine", ""},
- { 8, "ARCCOSINE", 0, "Arccosine", ""},
- { 9, "ARCTANGENT", 0, "Arctangent", ""},
- {10, "POWER", 0, "Power", ""},
- {11, "LOGARITHM", 0, "Logarithm", ""},
- {12, "MINIMUM", 0, "Minimum", ""},
- {13, "MAXIMUM", 0, "Maximum", ""},
- {14, "ROUND", 0, "Round", ""},
- {15, "LESS_THAN", 0, "Less Than", ""},
- {16, "GREATER_THAN", 0, "Greater Than", ""},
- {17, "MODULO", 0, "Modulo", ""},
- {18, "ABSOLUTE", 0, "Absolute", ""},
+ {NODE_MATH_ADD, "ADD", 0, "Add", ""},
+ {NODE_MATH_SUB, "SUBTRACT", 0, "Subtract", ""},
+ {NODE_MATH_MUL, "MULTIPLY", 0, "Multiply", ""},
+ {NODE_MATH_DIVIDE, "DIVIDE", 0, "Divide", ""},
+ {NODE_MATH_SIN, "SINE", 0, "Sine", ""},
+ {NODE_MATH_COS, "COSINE", 0, "Cosine", ""},
+ {NODE_MATH_TAN, "TANGENT", 0, "Tangent", ""},
+ {NODE_MATH_ASIN, "ARCSINE", 0, "Arcsine", ""},
+ {NODE_MATH_ACOS, "ARCCOSINE", 0, "Arccosine", ""},
+ {NODE_MATH_ATAN, "ARCTANGENT", 0, "Arctangent", ""},
+ {NODE_MATH_POW, "POWER", 0, "Power", ""},
+ {NODE_MATH_LOG, "LOGARITHM", 0, "Logarithm", ""},
+ {NODE_MATH_MIN, "MINIMUM", 0, "Minimum", ""},
+ {NODE_MATH_MAX, "MAXIMUM", 0, "Maximum", ""},
+ {NODE_MATH_ROUND, "ROUND", 0, "Round", ""},
+ {NODE_MATH_LESS, "LESS_THAN", 0, "Less Than", ""},
+ {NODE_MATH_GREATER, "GREATER_THAN", 0, "Greater Than", ""},
+ {NODE_MATH_MOD, "MODULO", 0, "Modulo", ""},
+ {NODE_MATH_ABS, "ABSOLUTE", 0, "Absolute", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -2199,6 +2199,10 @@ static void rna_NodeSocketStandard_float_range(PointerRNA *ptr, float *min, floa
bNodeSocketValueFloat *dval = sock->default_value;
int subtype = sock->typeinfo->subtype;
+ if (dval->max < dval->min) {
+ dval->max = dval->min;
+ }
+
*min = (subtype == PROP_UNSIGNED ? 0.0f : -FLT_MAX);
*max = FLT_MAX;
*softmin = dval->min;
@@ -2211,6 +2215,10 @@ static void rna_NodeSocketStandard_int_range(PointerRNA *ptr, int *min, int *max
bNodeSocketValueInt *dval = sock->default_value;
int subtype = sock->typeinfo->subtype;
+ if (dval->max < dval->min) {
+ dval->max = dval->min;
+ }
+
*min = (subtype == PROP_UNSIGNED ? 0 : INT_MIN);
*max = INT_MAX;
*softmin = dval->min;
@@ -2222,6 +2230,10 @@ static void rna_NodeSocketStandard_vector_range(PointerRNA *ptr, float *min, flo
bNodeSocket *sock = ptr->data;
bNodeSocketValueVector *dval = sock->default_value;
+ if (dval->max < dval->min) {
+ dval->max = dval->min;
+ }
+
*min = -FLT_MAX;
*max = FLT_MAX;
*softmin = dval->min;
@@ -3026,6 +3038,13 @@ static void def_frame(StructRNA *srna)
{
PropertyRNA *prop;
+ prop = RNA_def_property(srna, "text", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "Text");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Text", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
RNA_def_struct_sdna_from(srna, "NodeFrame", "storage");
prop = RNA_def_property(srna, "shrink", PROP_BOOLEAN, PROP_NONE);
@@ -3051,7 +3070,7 @@ static void def_math(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom2", SHD_MATH_CLAMP);
RNA_def_property_ui_text(prop, "Clamp", "Clamp result of the node to 0..1 range");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
@@ -3132,12 +3151,12 @@ static void def_mix_rgb(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom2", SHD_MIXRGB_USE_ALPHA);
RNA_def_property_ui_text(prop, "Alpha", "Include alpha of second input in this operation");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "custom2", 2);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom2", SHD_MIXRGB_CLAMP);
RNA_def_property_ui_text(prop, "Clamp", "Clamp result of the node to 0..1 range");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
@@ -3419,10 +3438,14 @@ static void def_sh_tex_image(StructRNA *srna)
};
static const EnumPropertyItem prop_projection_items[] = {
- {SHD_PROJ_FLAT, "FLAT", 0, "Flat",
- "Image is projected flat using the X and Y coordinates of the texture vector"},
- {SHD_PROJ_BOX, "BOX", 0, "Box",
- "Image is projected using different components for each side of the object space bounding box"},
+ {SHD_PROJ_FLAT, "FLAT", 0, "Flat",
+ "Image is projected flat using the X and Y coordinates of the texture vector"},
+ {SHD_PROJ_BOX, "BOX", 0, "Box",
+ "Image is projected using different components for each side of the object space bounding box"},
+ {SHD_PROJ_SPHERE, "SPHERE", 0, "Sphere",
+ "Image is projected spherically using the Z axis as central"},
+ {SHD_PROJ_TUBE, "TUBE", 0, "Tube",
+ "Image is projected from the tube using the Z axis as central"},
{0, NULL, 0, NULL, NULL}
};
@@ -3432,7 +3455,7 @@ static void def_sh_tex_image(StructRNA *srna)
{SHD_INTERP_CLOSEST, "Closest", 0, "Closest",
"No interpolation (sample closest texel)"},
{SHD_INTERP_CUBIC, "Cubic", 0, "Cubic",
- "Cubic interpolation (OSL only)"},
+ "Cubic interpolation (CPU only)"},
{SHD_INTERP_SMART, "Smart", 0, "Smart",
"Bicubic when magnifying, else bilinear (OSL only)"},
{0, NULL, 0, NULL, NULL}
@@ -3631,7 +3654,14 @@ static void def_sh_tex_wave(StructRNA *srna)
static void def_sh_tex_coord(StructRNA *srna)
{
PropertyRNA *prop;
-
+
+ prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Object", "Use coordinates from this object (for object texture coordinates output)");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
prop = RNA_def_property(srna, "from_dupli", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
RNA_def_property_ui_text(prop, "From Dupli", "Use the parent of the dupli object if possible");
@@ -4957,7 +4987,7 @@ static void def_cmp_defocus(StructRNA *srna)
prop = RNA_def_property(srna, "f_stop", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "fstop");
RNA_def_property_range(prop, 0.0f, 128.0f);
- RNA_def_property_ui_text(prop, "fStop",
+ RNA_def_property_ui_text(prop, "F-stop",
"Amount of focal blur, 128=infinity=perfect focus, half the value doubles "
"the blur radius");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
@@ -5714,7 +5744,7 @@ static void def_cmp_bokehblur(StructRNA *srna)
prop = RNA_def_property(srna, "f_stop", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "custom3");
RNA_def_property_range(prop, 0.0f, 128.0f);
- RNA_def_property_ui_text(prop, "fStop",
+ RNA_def_property_ui_text(prop, "F-stop",
"Amount of focal blur, 128=infinity=perfect focus, half the value doubles "
"the blur radius");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
@@ -6201,6 +6231,21 @@ static void def_cmp_planetrackdeform(StructRNA *srna)
RNA_def_property_string_sdna(prop, NULL, "plane_track_name");
RNA_def_property_ui_text(prop, "Plane Track", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "use_motion_blur", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR);
+ RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled motion blur of the mask");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 1, CMP_NODE_PLANETRACKDEFORM_MBLUR_SAMPLES_MAX);
+ RNA_def_property_ui_text(prop, "Samples", "Number of motion blur samples");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0, 1.0f);
+ RNA_def_property_ui_text(prop, "Shutter", "Exposure for motion blur as a factor of FPS");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_cmp_sunbeams(StructRNA *srna)
@@ -7093,7 +7138,13 @@ static void rna_def_node(BlenderRNA *brna)
static EnumPropertyItem dummy_static_type_items[] = {
{NODE_CUSTOM, "CUSTOM", 0, "Custom", "Custom Node"},
{0, NULL, 0, NULL, NULL}};
-
+
+ static EnumPropertyItem node_shading_compatibilities[] = {
+ {NODE_OLD_SHADING, "OLD_SHADING", 0, "Old Shading", "Old shading system compatibility"},
+ {NODE_NEW_SHADING, "NEW_SHADING", 0, "New Shading", "New shading system compatibility"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "Node", NULL);
RNA_def_struct_ui_text(srna, "Node", "Node in a node tree");
RNA_def_struct_sdna(srna, "bNode");
@@ -7233,6 +7284,12 @@ static void rna_def_node(BlenderRNA *brna)
parm = RNA_def_boolean(func, "result", false, "Result", "");
RNA_def_function_return(func, parm);
+ prop = RNA_def_property(srna, "shading_compatibility", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_enum_sdna(prop, NULL, "typeinfo->compatibility");
+ RNA_def_property_enum_items(prop, node_shading_compatibilities);
+
/* registration */
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "typeinfo->idname");
@@ -7572,8 +7629,8 @@ static void rna_def_nodetree(BlenderRNA *brna)
/* Grease Pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
- RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "GreasePencil");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil datablock");
RNA_def_property_update(prop, NC_NODE, NULL);
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 690468a5278..d8aa659b68e 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -42,10 +42,13 @@
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
+#include "BKE_camera.h"
#include "BKE_paint.h"
#include "BKE_editmesh.h"
#include "BKE_group.h" /* needed for BKE_group_object_exists() */
#include "BKE_object.h" /* Needed for BKE_object_matrix_local_get() */
+#include "BKE_object_deform.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -231,21 +234,21 @@ static void rna_Object_matrix_local_get(PointerRNA *ptr, float values[16])
static void rna_Object_matrix_local_set(PointerRNA *ptr, const float values[16])
{
Object *ob = ptr->id.data;
+ float local_mat[4][4];
- /* localspace matrix is truly relative to the parent, but parameters
- * stored in object are relative to parentinv matrix. Undo the parent
- * inverse part before updating obmat and calling apply_obmat() */
+ /* localspace matrix is truly relative to the parent, but parameters stored in object are
+ * relative to parentinv matrix. Undo the parent inverse part before applying it as local matrix. */
if (ob->parent) {
float invmat[4][4];
invert_m4_m4(invmat, ob->parentinv);
- mul_m4_m4m4(ob->obmat, invmat, (float(*)[4])values);
+ mul_m4_m4m4(local_mat, invmat, (float(*)[4])values);
}
else {
- copy_m4_m4(ob->obmat, (float(*)[4])values);
+ copy_m4_m4(local_mat, (float(*)[4])values);
}
- /* don't use compat so we get predictable rotation */
- BKE_object_apply_mat4(ob, ob->obmat, false, false);
+ /* don't use compat so we get predictable rotation, and do not use parenting either, because it's a local matrix! */
+ BKE_object_apply_mat4(ob, local_mat, false, false);
}
static void rna_Object_matrix_basis_get(PointerRNA *ptr, float values[16])
@@ -505,7 +508,9 @@ static EnumPropertyItem *rna_Object_collision_bounds_itemf(bContext *UNUSED(C),
EnumPropertyItem *item = NULL;
int totitem = 0;
- RNA_enum_items_add_value(&item, &totitem, collision_bounds_items, OB_BOUND_TRIANGLE_MESH);
+ if (ob->body_type != OB_BODY_TYPE_CHARACTER) {
+ RNA_enum_items_add_value(&item, &totitem, collision_bounds_items, OB_BOUND_TRIANGLE_MESH);
+ }
RNA_enum_items_add_value(&item, &totitem, collision_bounds_items, OB_BOUND_CONVEX_HULL);
if (ob->body_type != OB_BODY_TYPE_SOFT) {
@@ -583,7 +588,7 @@ static void rna_Object_active_vertex_group_index_range(PointerRNA *ptr, int *min
Object *ob = (Object *)ptr->id.data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&ob->defbase) - 1);
+ *max = max_ii(0, BLI_listbase_count(&ob->defbase) - 1);
}
void rna_object_vgroup_name_index_get(PointerRNA *ptr, char *value, int index)
@@ -637,7 +642,7 @@ void rna_object_uvlayer_name_set(PointerRNA *ptr, const char *value, char *resul
for (a = 0; a < me->pdata.totlayer; a++) {
layer = &me->pdata.layers[a];
- if (layer->type == CD_MTEXPOLY && strcmp(layer->name, value) == 0) {
+ if (layer->type == CD_MTEXPOLY && STREQ(layer->name, value)) {
BLI_strncpy(result, value, maxlen);
return;
}
@@ -660,7 +665,7 @@ void rna_object_vcollayer_name_set(PointerRNA *ptr, const char *value, char *res
for (a = 0; a < me->fdata.totlayer; a++) {
layer = &me->fdata.layers[a];
- if (layer->type == CD_MCOL && strcmp(layer->name, value) == 0) {
+ if (layer->type == CD_MCOL && STREQ(layer->name, value)) {
BLI_strncpy(result, value, maxlen);
return;
}
@@ -736,7 +741,7 @@ static void rna_Object_active_particle_system_index_range(PointerRNA *ptr, int *
{
Object *ob = (Object *)ptr->id.data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&ob->particlesystem) - 1);
+ *max = max_ii(0, BLI_listbase_count(&ob->particlesystem) - 1);
}
static int rna_Object_active_particle_system_index_get(PointerRNA *ptr)
@@ -775,7 +780,7 @@ static void rna_Object_rotation_axis_angle_set(PointerRNA *ptr, const float *val
/* for now, assume that rotation mode is axis-angle */
ob->rotAngle = value[0];
- copy_v3_v3(ob->rotAxis, (float *)&value[1]);
+ copy_v3_v3(ob->rotAxis, &value[1]);
/* TODO: validate axis? */
}
@@ -941,6 +946,7 @@ static void rna_MaterialSlot_name_get(PointerRNA *ptr, char *str)
static void rna_MaterialSlot_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
rna_Object_internal_update(bmain, scene, ptr);
+
WM_main_add_notifier(NC_OBJECT | ND_OB_SHADING, ptr->id.data);
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_LINKS, NULL);
}
@@ -1179,7 +1185,7 @@ static void rna_GameObjectSettings_col_group_get(PointerRNA *ptr, int *values)
int i;
for (i = 0; i < OB_MAX_COL_MASKS; i++) {
- values[i] = (ob->col_group & (1 << i));
+ values[i] = (ob->col_group & (1 << i)) != 0;
}
}
@@ -1208,7 +1214,7 @@ static void rna_GameObjectSettings_col_mask_get(PointerRNA *ptr, int *values)
int i;
for (i = 0; i < OB_MAX_COL_MASKS; i++) {
- values[i] = (ob->col_mask & (1 << i));
+ values[i] = (ob->col_mask & (1 << i)) != 0;
}
}
@@ -1240,7 +1246,7 @@ static void rna_Object_active_shape_key_index_range(PointerRNA *ptr, int *min, i
*min = 0;
if (key) {
- *max = BLI_countlist(&key->block) - 1;
+ *max = BLI_listbase_count(&key->block) - 1;
if (*max < 0) *max = 0;
}
else {
@@ -1388,7 +1394,7 @@ static void rna_Object_boundbox_get(PointerRNA *ptr, float *values)
static bDeformGroup *rna_Object_vgroup_new(Object *ob, const char *name)
{
- bDeformGroup *defgroup = ED_vgroup_add_name(ob, name);
+ bDeformGroup *defgroup = BKE_object_defgroup_add_name(ob, name);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
@@ -1403,7 +1409,7 @@ static void rna_Object_vgroup_remove(Object *ob, ReportList *reports, PointerRNA
return;
}
- ED_vgroup_delete(ob, defgroup);
+ BKE_object_defgroup_remove(ob, defgroup);
RNA_POINTER_INVALIDATE(defgroup_ptr);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
@@ -1411,7 +1417,7 @@ static void rna_Object_vgroup_remove(Object *ob, ReportList *reports, PointerRNA
static void rna_Object_vgroup_clear(Object *ob)
{
- ED_vgroup_clear(ob);
+ BKE_object_defgroup_remove_all(ob);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}
@@ -1421,7 +1427,7 @@ static void rna_VertexGroup_vertex_add(ID *id, bDeformGroup *def, ReportList *re
{
Object *ob = (Object *)id;
- if (ED_vgroup_object_is_edit_mode(ob)) {
+ if (BKE_object_is_in_editmode_vgroup(ob)) {
BKE_report(reports, RPT_ERROR, "VertexGroup.add(): cannot be called while object is in edit mode");
return;
}
@@ -1436,7 +1442,7 @@ static void rna_VertexGroup_vertex_remove(ID *id, bDeformGroup *dg, ReportList *
{
Object *ob = (Object *)id;
- if (ED_vgroup_object_is_edit_mode(ob)) {
+ if (BKE_object_is_in_editmode_vgroup(ob)) {
BKE_report(reports, RPT_ERROR, "VertexGroup.remove(): cannot be called while object is in edit mode");
return;
}
@@ -1627,7 +1633,7 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
{OB_BODY_TYPE_DYNAMIC, "DYNAMIC", 0, "Dynamic", "Linear physics"},
{OB_BODY_TYPE_RIGID, "RIGID_BODY", 0, "Rigid Body", "Linear and angular physics"},
{OB_BODY_TYPE_SOFT, "SOFT_BODY", 0, "Soft Body", "Soft body"},
- {OB_BODY_TYPE_OCCLUDER, "OCCLUDE", 0, "Occlude", "Occluder for optimizing scene rendering"},
+ {OB_BODY_TYPE_OCCLUDER, "OCCLUDER", 0, "Occluder", "Occluder for optimizing scene rendering"},
{OB_BODY_TYPE_SENSOR, "SENSOR", 0, "Sensor",
"Collision Sensor, detects static and dynamic objects but not the other "
"collision sensor objects"},
@@ -1812,7 +1818,7 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "gameflag", OB_ANISOTROPIC_FRICTION);
RNA_def_property_ui_text(prop, "Anisotropic Friction", "Enable anisotropic friction");
- prop = RNA_def_property(srna, "friction_coefficients", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "friction_coefficients", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "anisotropicFriction");
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_ui_text(prop, "Friction Coefficients",
@@ -1828,7 +1834,7 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "collision_boundtype");
RNA_def_property_enum_items(prop, collision_bounds_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Object_collision_bounds_itemf");
- RNA_def_property_ui_text(prop, "Collision Bounds", "Select the collision type");
+ RNA_def_property_ui_text(prop, "Collision Shape", "Select the collision shape that better fits the object");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
prop = RNA_def_property(srna, "use_collision_compound", PROP_BOOLEAN, PROP_NONE);
@@ -2426,7 +2432,9 @@ static void rna_def_object(BlenderRNA *brna)
prop = RNA_def_property(srna, "matrix_local", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Local Matrix", "Parent relative transformation matrix");
+ RNA_def_property_ui_text(prop, "Local Matrix", "Parent relative transformation matrix - "
+ "WARNING: Only takes into account 'Object' parenting, so e.g. in case of bone parenting "
+ "you get a matrix relative to the Armature object, not to the actual parent bone");
RNA_def_property_float_funcs(prop, "rna_Object_matrix_local_get", "rna_Object_matrix_local_set", NULL);
RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, NULL);
@@ -2726,16 +2734,16 @@ static void rna_def_object(BlenderRNA *brna)
/* Grease Pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
- RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "GreasePencil");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil datablock");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
/* pose */
prop = RNA_def_property(srna, "pose_library", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "poselib");
- RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Action");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Pose Library", "Action used as a pose library for armatures");
prop = RNA_def_property(srna, "pose", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 831e5486236..2306682ca01 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -109,7 +109,29 @@ static void rna_Scene_mat_convert_space(Object *ob, ReportList *reports, bPoseCh
}
}
- BKE_constraint_mat_convertspace(ob, pchan, (float (*)[4])mat_ret, from, to);
+ BKE_constraint_mat_convertspace(ob, pchan, (float (*)[4])mat_ret, from, to, false);
+}
+
+static void rna_Object_calc_matrix_camera(
+ Object *ob, float mat_ret[16], int width, int height, float scalex, float scaley)
+{
+ CameraParams params;
+
+ /* setup parameters */
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_object(&params, ob);
+
+ /* compute matrix, viewplane, .. */
+ BKE_camera_params_compute_viewplane(&params, width, height, scalex, scaley);
+ BKE_camera_params_compute_matrix(&params);
+
+ copy_m4_m4((float (*)[4])mat_ret, params.winmat);
+}
+
+static void rna_Object_camera_fit_coords(
+ Object *ob, Scene *scene, int num_cos, float *cos, float co_ret[3], float *scale_ret)
+{
+ BKE_camera_view_frame_fit_to_coords(scene, (float (*)[3])cos, num_cos / 3, ob, co_ret, scale_ret);
}
/* copied from Mesh_getFromObject and adapted to RNA interface */
@@ -203,10 +225,9 @@ static void rna_Object_free_duplilist(Object *ob)
static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList *reports,
const char *name, int from_mix)
{
- Scene *scene = CTX_data_scene(C);
KeyBlock *kb = NULL;
- if ((kb = BKE_object_insert_shape_key(scene, ob, name, from_mix))) {
+ if ((kb = BKE_object_insert_shape_key(ob, name, from_mix))) {
PointerRNA keyptr;
RNA_pointer_create((ID *)ob->data, &RNA_ShapeKey, kb, &keyptr);
@@ -468,6 +489,35 @@ void RNA_api_object(StructRNA *srna)
parm = RNA_def_enum(func, "to_space", space_items, CONSTRAINT_SPACE_WORLD, "",
"The space to which you want to transform 'matrix'");
+ /* Camera-related operations */
+ func = RNA_def_function(srna, "calc_matrix_camera", "rna_Object_calc_matrix_camera");
+ RNA_def_function_ui_description(func, "Generate the camera projection matrix of this object "
+ "(mostly useful for Camera and Lamp types)");
+ parm = RNA_def_property(func, "result", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_ui_text(parm, "", "The camera projection matrix");
+ RNA_def_function_output(func, parm);
+ parm = RNA_def_int(func, "x", 1, 0, INT_MAX, "", "Width of the render area", 0, 10000);
+ parm = RNA_def_int(func, "y", 1, 0, INT_MAX, "", "Height of the render area", 0, 10000);
+ parm = RNA_def_float(func, "scale_x", 1.0f, 1.0e-6f, FLT_MAX, "", "Width scaling factor", 1.0e-2f, 100.0f);
+ parm = RNA_def_float(func, "scale_y", 1.0f, 1.0e-6f, FLT_MAX, "", "height scaling factor", 1.0e-2f, 100.0f);
+
+ func = RNA_def_function(srna, "camera_fit_coords", "rna_Object_camera_fit_coords");
+ RNA_def_function_ui_description(func, "Compute the coordinate (and scale for ortho cameras) "
+ "given object should be to 'see' all given coordinates");
+ parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene to get render size information from, if available");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_float_array(func, "coordinates", 1, NULL, -FLT_MAX, FLT_MAX, "", "Coordinates to fit in",
+ -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_DYNAMIC);
+ parm = RNA_def_property(func, "co_return", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_array(parm, 3);
+ RNA_def_property_ui_text(parm, "", "The location to aim to be able to see all given points");
+ RNA_def_property_flag(parm, PROP_OUTPUT);
+ parm = RNA_def_property(func, "scale_return", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(parm, "", "The ortho scale to aim to be able to see all given points (if relevant)");
+ RNA_def_property_flag(parm, PROP_OUTPUT);
+
/* mesh */
func = RNA_def_function(srna, "to_mesh", "rna_Object_to_mesh");
RNA_def_function_ui_description(func, "Create a Mesh datablock with modifiers applied");
@@ -507,7 +557,7 @@ void RNA_api_object(StructRNA *srna)
func = RNA_def_function(srna, "shape_key_add", "rna_Object_shape_key_add");
RNA_def_function_ui_description(func, "Add shape key to an object");
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
- RNA_def_string(func, "name", "Key", 0, "", "Unique name for the new keylock"); /* optional */
+ RNA_def_string(func, "name", "Key", 0, "", "Unique name for the new keyblock"); /* optional */
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);
@@ -605,6 +655,9 @@ void RNA_api_object(StructRNA *srna)
RNA_def_function_ui_description(func, "Load the objects edit-mode data intp the object data");
parm = RNA_def_boolean(func, "result", 0, "", "Success");
RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "cache_release", "BKE_object_free_caches");
+ RNA_def_function_ui_description(func, "Release memory used by caches associated with this object. Intended to be used by render engines only");
}
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 8da869417ff..4cc098fb4a6 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -190,7 +190,7 @@ static void rna_Cache_idname_change(Main *UNUSED(bmain), Scene *UNUSED(scene), P
for (pid = pidlist.first; pid; pid = pid->next) {
if (pid->cache == cache)
pid2 = pid;
- else if (cache->name[0] != '\0' && strcmp(cache->name, pid->cache->name) == 0) {
+ else if (cache->name[0] != '\0' && STREQ(cache->name, pid->cache->name)) {
/*TODO: report "name exists" to user */
BLI_strncpy(cache->name, cache->prev_name, sizeof(cache->name));
new_name = 0;
@@ -243,7 +243,7 @@ static void rna_Cache_active_point_cache_index_range(PointerRNA *ptr, int *min,
for (pid = pidlist.first; pid; pid = pid->next) {
if (pid->cache == cache) {
- *max = max_ii(0, BLI_countlist(pid->ptcaches) - 1);
+ *max = max_ii(0, BLI_listbase_count(pid->ptcaches) - 1);
break;
}
}
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 113311383f4..029563ad9c3 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -131,6 +131,7 @@ static EnumPropertyItem part_hair_ren_as_items[] = {
#include "BKE_context.h"
#include "BKE_cloth.h"
+#include "BKE_colortools.h"
#include "BKE_deform.h"
#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
@@ -356,13 +357,15 @@ static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *o
return;
if (part->ren_as == PART_DRAW_PATH && particlesystem->pathcache)
- path_nbr = (int)pow(2.0, step_nbr);
+ path_nbr = 1 << step_nbr;
+ if (part->kink == PART_KINK_SPIRAL)
+ path_nbr += part->kink_extra_steps;
if (particle_no < totpart) {
if (path_nbr) {
cache = particlesystem->pathcache[particle_no];
- max_k = (int)cache->steps;
+ max_k = (int)cache->segments;
}
}
@@ -371,10 +374,10 @@ static void rna_ParticleSystem_co_hair(ParticleSystem *particlesystem, Object *o
if (path_nbr) {
cache = particlesystem->childcache[particle_no - totpart];
- if (cache->steps < 0)
+ if (cache->segments < 0)
max_k = 0;
else
- max_k = (int)cache->steps;
+ max_k = (int)cache->segments;
}
}
@@ -589,8 +592,14 @@ static void rna_ParticleSystem_set_resolution(ParticleSystem *particlesystem, Sc
particle_system_update(scene, object, particlesystem);
}
else {
- if (particlesystem->renderdata)
+ ParticleSystemModifierData *psmd = psys_get_modifier(object, particlesystem);
+
+ if (particlesystem->renderdata) {
psys_render_restore(object, particlesystem);
+ }
+
+ psmd->flag &= ~eParticleSystemFlag_psys_updated;
+ particle_system_update(scene, object, particlesystem);
}
}
@@ -639,6 +648,15 @@ static void rna_Particle_redo_child(Main *bmain, Scene *scene, PointerRNA *ptr)
particle_recalc(bmain, scene, ptr, PSYS_RECALC_CHILD);
}
+static void rna_Particle_cloth_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ Object *ob = (Object *)ptr->id.data;
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
+}
+
+
static ParticleSystem *rna_particle_system_for_target(Object *ob, ParticleTarget *target)
{
ParticleSystem *psys;
@@ -858,6 +876,32 @@ static int rna_PartSettings_is_fluid_get(PointerRNA *ptr)
return part->type == PART_FLUID;
}
+static void rna_ParticleSettings_use_clump_curve_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ ParticleSettings *part = ptr->data;
+
+ if (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) {
+ if (!part->clumpcurve) {
+ BKE_particlesettings_clump_curve_init(part);
+ }
+ }
+
+ rna_Particle_redo_child(bmain, scene, ptr);
+}
+
+static void rna_ParticleSettings_use_roughness_curve_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ ParticleSettings *part = ptr->data;
+
+ if (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) {
+ if (!part->roughcurve) {
+ BKE_particlesettings_rough_curve_init(part);
+ }
+ }
+
+ rna_Particle_redo_child(bmain, scene, ptr);
+}
+
static void rna_ParticleSystem_name_set(PointerRNA *ptr, const char *value)
{
Object *ob = ptr->id.data;
@@ -886,7 +930,7 @@ static void rna_ParticleSystem_active_particle_target_index_range(PointerRNA *pt
{
ParticleSystem *psys = (ParticleSystem *)ptr->data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&psys->targets) - 1);
+ *max = max_ii(0, BLI_listbase_count(&psys->targets) - 1);
}
static int rna_ParticleSystem_active_particle_target_index_get(PointerRNA *ptr)
@@ -1009,7 +1053,7 @@ static void rna_ParticleDupliWeight_active_index_range(PointerRNA *ptr, int *min
{
ParticleSettings *part = (ParticleSettings *)ptr->id.data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&part->dupliweights) - 1);
+ *max = max_ii(0, BLI_listbase_count(&part->dupliweights) - 1);
}
static int rna_ParticleDupliWeight_active_index_get(PointerRNA *ptr)
@@ -1770,9 +1814,14 @@ static void rna_def_particle_settings_mtex(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Clump", "Affect the child clumping");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
- prop = RNA_def_property(srna, "use_map_kink", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_KINK);
- RNA_def_property_ui_text(prop, "Kink", "Affect the child kink");
+ prop = RNA_def_property(srna, "use_map_kink_amp", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_KINK_AMP);
+ RNA_def_property_ui_text(prop, "Kink Amplitude", "Affect the child kink amplitude");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
+ prop = RNA_def_property(srna, "use_map_kink_freq", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_KINK_FREQ);
+ RNA_def_property_ui_text(prop, "Kink Frequency", "Affect the child kink frequency");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
prop = RNA_def_property(srna, "use_map_rough", PROP_BOOLEAN, PROP_NONE);
@@ -1849,10 +1898,16 @@ static void rna_def_particle_settings_mtex(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Clump Factor", "Amount texture affects child clump");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
- prop = RNA_def_property(srna, "kink_factor", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "kink_amp_factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "kinkampfac");
+ RNA_def_property_ui_range(prop, 0, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Kink Amplitude Factor", "Amount texture affects child kink amplitude");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
+ prop = RNA_def_property(srna, "kink_freq_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "kinkfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
- RNA_def_property_ui_text(prop, "Kink Factor", "Amount texture affects child kink");
+ RNA_def_property_ui_text(prop, "Kink Frequency Factor", "Amount texture affects child kink frequency");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
prop = RNA_def_property(srna, "rough_factor", PROP_FLOAT, PROP_NONE);
@@ -1938,6 +1993,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
{PART_KINK_RADIAL, "RADIAL", 0, "Radial", ""},
{PART_KINK_WAVE, "WAVE", 0, "Wave", ""},
{PART_KINK_BRAID, "BRAID", 0, "Braid", ""},
+ {PART_KINK_SPIRAL, "SPIRAL", 0, "Spiral", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -2170,6 +2226,16 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Particle_reset");
/*draw flag*/
+ prop = RNA_def_property(srna, "show_guide_hairs", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_GUIDE_HAIRS);
+ RNA_def_property_ui_text(prop, "Guide Hairs", "Show guide hairs");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo");
+
+ prop = RNA_def_property(srna, "show_hair_grid", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_HAIR_GRID);
+ RNA_def_property_ui_text(prop, "Guide Hairs", "Show guide hairs");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo");
+
prop = RNA_def_property(srna, "show_velocity", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_VEL);
RNA_def_property_ui_text(prop, "Velocity", "Show particle velocity");
@@ -2301,6 +2367,11 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Segments", "Number of hair segments");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
+ prop = RNA_def_property(srna, "bending_random", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "bending_random");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Random Bending Stiffness", "Random stiffness of hairs");
+ RNA_def_property_update(prop, 0, "rna_Particle_cloth_update");
/*TODO: not found in UI, readonly? */
prop = RNA_def_property(srna, "keys_step", PROP_INT, PROP_NONE);
@@ -2766,6 +2837,29 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Shape", "Shape of clumping");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+ prop = RNA_def_property(srna, "use_clump_curve", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "child_flag", PART_CHILD_USE_CLUMP_CURVE);
+ RNA_def_property_ui_text(prop, "Use Clump Curve", "Use a curve to define clump tapering");
+ RNA_def_property_update(prop, 0, "rna_ParticleSettings_use_clump_curve_update");
+
+ prop = RNA_def_property(srna, "clump_curve", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "clumpcurve");
+ RNA_def_property_struct_type(prop, "CurveMapping");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Clump Curve", "Curve defining clump tapering");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
+ prop = RNA_def_property(srna, "use_clump_noise", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "child_flag", PART_CHILD_USE_CLUMP_NOISE);
+ RNA_def_property_ui_text(prop, "Use Clump Noise", "Create random clumps around the parent");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
+ prop = RNA_def_property(srna, "clump_noise_size", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "clump_noise_size");
+ RNA_def_property_range(prop, 0.00001f, 100000.0f);
+ RNA_def_property_ui_range(prop, 0.01f, 10.0f, 0.1f, 3);
+ RNA_def_property_ui_text(prop, "Clump Noise Size", "Size of clump noise");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
/* kink */
prop = RNA_def_property(srna, "kink_amplitude", PROP_FLOAT, PROP_NONE);
@@ -2781,6 +2875,12 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Amplitude Clump", "How much clump affects kink amplitude");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+ prop = RNA_def_property(srna, "kink_amplitude_random", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "kink_amp_random");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Amplitude Random", "Random variation of the amplitude");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
prop = RNA_def_property(srna, "kink_frequency", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "kink_freq");
RNA_def_property_range(prop, -100000.0f, 100000.0f);
@@ -2798,6 +2898,17 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Flatness", "How flat the hairs are");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+ prop = RNA_def_property(srna, "kink_extra_steps", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 100, 1, -1);
+ RNA_def_property_ui_text(prop, "Extra Steps", "Extra steps for resolution of special kink features");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
+ prop = RNA_def_property(srna, "kink_axis_random", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Axis Random", "Random variation of the orientation");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
/* rough */
prop = RNA_def_property(srna, "roughness_1", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rough1");
@@ -2846,6 +2957,18 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Shape", "Shape of end point rough");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+ prop = RNA_def_property(srna, "use_roughness_curve", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "child_flag", PART_CHILD_USE_ROUGH_CURVE);
+ RNA_def_property_ui_text(prop, "Use Roughness Curve", "Use a curve to define roughness");
+ RNA_def_property_update(prop, 0, "rna_ParticleSettings_use_roughness_curve_update");
+
+ prop = RNA_def_property(srna, "roughness_curve", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "roughcurve");
+ RNA_def_property_struct_type(prop, "CurveMapping");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Roughness Curve", "Curve defining roughness");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
+
prop = RNA_def_property(srna, "child_length", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clength");
RNA_def_property_range(prop, 0.0f, 1.0f);
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index f9d0e86183e..0428f5d8a9f 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -183,7 +183,7 @@ int rna_ActionGroup_is_custom_colorset_get(PointerRNA *ptr)
{
bActionGroup *grp = ptr->data;
- return (bool)(grp->customCol < 0);
+ return (grp->customCol < 0);
}
static void rna_BoneGroup_name_set(PointerRNA *ptr, const char *value)
@@ -258,7 +258,7 @@ static void rna_PoseChannel_rotation_axis_angle_set(PointerRNA *ptr, const float
/* for now, assume that rotation mode is axis-angle */
pchan->rotAngle = value[0];
- copy_v3_v3(pchan->rotAxis, (float *)&value[1]);
+ copy_v3_v3(pchan->rotAxis, &value[1]);
/* TODO: validate axis? */
}
@@ -421,7 +421,7 @@ static void rna_PoseChannel_bone_group_index_range(PointerRNA *ptr, int *min, in
bPose *pose = (ob) ? ob->pose : NULL;
*min = 0;
- *max = pose ? max_ii(0, BLI_countlist(&pose->agroups) - 1) : 0;
+ *max = pose ? max_ii(0, BLI_listbase_count(&pose->agroups) - 1) : 0;
}
static PointerRNA rna_Pose_active_bone_group_get(PointerRNA *ptr)
@@ -454,7 +454,7 @@ static void rna_Pose_active_bone_group_index_range(PointerRNA *ptr, int *min, in
bPose *pose = (bPose *)ptr->data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&pose->agroups) - 1);
+ *max = max_ii(0, BLI_listbase_count(&pose->agroups) - 1);
}
#if 0
diff --git a/source/blender/makesrna/intern/rna_property.c b/source/blender/makesrna/intern/rna_property.c
index c6b8e89c282..a2c19e55056 100644
--- a/source/blender/makesrna/intern/rna_property.c
+++ b/source/blender/makesrna/intern/rna_property.c
@@ -28,6 +28,11 @@
#include <stdlib.h>
#include "DNA_property_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_path_util.h"
+
+#include "BLF_translation.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -97,9 +102,11 @@ static void rna_GameProperty_type_set(PointerRNA *ptr, int value)
static void rna_GameProperty_name_set(PointerRNA *ptr, const char *value)
{
- bProperty *prop = (bProperty *)(ptr->data);
+ Object *ob = ptr->id.data;
+ bProperty *prop = ptr->data;
BLI_strncpy_utf8(prop->name, value, sizeof(prop->name));
- BKE_bproperty_unique(NULL, prop, 1);
+
+ BLI_uniquename(&ob->prop, prop, DATA_("Property"), '.', offsetof(bProperty, name), sizeof(prop->name));
}
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 0ee654d4ecc..124a83a5f30 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -38,7 +38,6 @@
#include "RE_engine.h"
#include "RE_pipeline.h"
-#include "RE_engine.h"
EnumPropertyItem render_pass_type_items[] = {
@@ -268,7 +267,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
/* check if we have registered this engine type before, and remove it */
for (et = R_engines.first; et; et = et->next) {
- if (strcmp(et->idname, dummyet.idname) == 0) {
+ if (STREQ(et->idname, dummyet.idname)) {
if (et->ext.srna)
rna_RenderEngine_unregister(bmain, et->ext.srna);
break;
@@ -520,6 +519,11 @@ static void rna_def_render_engine(BlenderRNA *brna)
prop = RNA_def_string(func, "message", NULL, 0, "Report Message", "");
RNA_def_property_flag(prop, PROP_REQUIRED);
+ func = RNA_def_function(srna, "error_set", "RE_engine_set_error_message");
+ RNA_def_function_ui_description(func, "Set error message displaying after the render is finished");
+ prop = RNA_def_string(func, "message", NULL, 0, "Report Message", "");
+ RNA_def_property_flag(prop, PROP_REQUIRED);
+
func = RNA_def_function(srna, "bind_display_space_shader", "engine_bind_display_space_shader");
RNA_def_function_ui_description(func, "Bind GLSL fragment shader that converts linear colors to display space colors using scene color management settings");
prop = RNA_def_pointer(func, "scene", "Scene", "", "");
diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c
index 86a8b162614..58a12f62644 100644
--- a/source/blender/makesrna/intern/rna_rigidbody.c
+++ b/source/blender/makesrna/intern/rna_rigidbody.c
@@ -644,8 +644,7 @@ static void rna_RigidBodyWorld_convex_sweep_test(
BKE_report(reports, RPT_ERROR, "Rigidbody world was not properly initialized, need to step the simulation first");
}
#else
- (void)rbw, (void)reports, (void)object, (void)ray_start, (void)ray_end;
- (void)r_location, (void)r_hitpoint, (void)r_normal, (void)r_hit;
+ UNUSED_VARS(rbw, reports, object, ray_start, ray_end, r_location, r_hitpoint, r_normal, r_hit);
#endif
}
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 8f2537105c1..42e231fa76f 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -179,7 +179,7 @@ static int rna_idproperty_known(CollectionPropertyIterator *iter, void *data)
* for the second loop where we go over unknown id properties */
do {
for (prop = ptype->cont.properties.first; prop; prop = prop->next)
- if ((prop->flag & PROP_BUILTIN) == 0 && strcmp(prop->identifier, idprop->name) == 0)
+ if ((prop->flag & PROP_BUILTIN) == 0 && STREQ(prop->identifier, idprop->name))
return 1;
} while ((ptype = ptype->base));
@@ -386,7 +386,7 @@ int rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key, Point
}
else {
for (prop = srna->cont.properties.first; prop; prop = prop->next) {
- if (!(prop->flag & PROP_BUILTIN) && strcmp(prop->identifier, key) == 0) {
+ if (!(prop->flag & PROP_BUILTIN) && STREQ(prop->identifier, key)) {
propptr.type = &RNA_Property;
propptr.data = prop;
@@ -408,7 +408,7 @@ int rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key, Point
if (group) {
for (idp = group->data.group.first; idp; idp = idp->next) {
- if (strcmp(idp->name, key) == 0) {
+ if (STREQ(idp->name, key)) {
propptr.type = &RNA_Property;
propptr.data = idp;
@@ -545,7 +545,7 @@ static int rna_Property_readonly_get(PointerRNA *ptr)
* data for introspection we only need to know if it can be edited so the
* flag is better for this */
/* return RNA_property_editable(ptr, prop); */
- return prop->flag & PROP_EDITABLE ? 0 : 1;
+ return (prop->flag & PROP_EDITABLE) == 0;
}
static int rna_Property_animatable_get(PointerRNA *ptr)
@@ -558,50 +558,50 @@ static int rna_Property_animatable_get(PointerRNA *ptr)
static int rna_Property_use_output_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_OUTPUT ? 1 : 0;
+ return (prop->flag & PROP_OUTPUT) != 0;
}
static int rna_Property_is_required_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_REQUIRED ? 1 : 0;
+ return (prop->flag & PROP_REQUIRED) != 0;
}
static int rna_Property_is_argument_optional_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_PYFUNC_OPTIONAL ? 1 : 0;
+ return (prop->flag & PROP_PYFUNC_OPTIONAL) != 0;
}
static int rna_Property_is_never_none_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_NEVER_NULL ? 1 : 0;
+ return (prop->flag & PROP_NEVER_NULL) != 0;
}
static int rna_Property_is_hidden_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_HIDDEN ? 1 : 0;
+ return (prop->flag & PROP_HIDDEN) != 0;
}
static int rna_Property_is_skip_save_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_SKIP_SAVE ? 1 : 0;
+ return (prop->flag & PROP_SKIP_SAVE) != 0;
}
static int rna_Property_is_enum_flag_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_ENUM_FLAG ? 1 : 0;
+ return (prop->flag & PROP_ENUM_FLAG) != 0;
}
static int rna_Property_is_library_editable_flag_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_LIB_EXCEPTION ? 1 : 0;
+ return (prop->flag & PROP_LIB_EXCEPTION) != 0;
}
static int rna_Property_array_length_get(PointerRNA *ptr)
@@ -611,22 +611,22 @@ static int rna_Property_array_length_get(PointerRNA *ptr)
return prop->totarraylength;
}
-static int rna_Property_registered_get(PointerRNA *ptr)
+static int rna_Property_is_registered_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_REGISTER;
+ return (prop->flag & PROP_REGISTER) != 0;
}
-static int rna_Property_registered_optional_get(PointerRNA *ptr)
+static int rna_Property_is_registered_optional_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_REGISTER_OPTIONAL;
+ return (prop->flag & PROP_REGISTER_OPTIONAL) != 0;
}
-static int rna_Property_runtime_get(PointerRNA *ptr)
+static int rna_Property_is_runtime_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
- return prop->flag & PROP_RUNTIME;
+ return (prop->flag & PROP_RUNTIME) != 0;
}
@@ -813,7 +813,7 @@ static EnumPropertyItem *rna_EnumProperty_default_itemf(bContext *C, PointerRNA
/* incompatible default attributes */
if ((prop_parent->flag & PROP_ENUM_FLAG) != (prop->flag & PROP_ENUM_FLAG)) {
- return NULL;
+ return DummyRNA_NULL_items;
}
if ((eprop->itemf == NULL) ||
@@ -984,7 +984,7 @@ static void rna_BlenderRNA_structs_begin(CollectionPropertyIterator *iter, Point
/* optional, for faster lookups */
static int rna_BlenderRNA_structs_length(PointerRNA *ptr)
{
- return BLI_countlist(&((BlenderRNA *)ptr->data)->structs);
+ return BLI_listbase_count(&((BlenderRNA *)ptr->data)->structs);
}
static int rna_BlenderRNA_structs_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
{
@@ -1002,7 +1002,7 @@ static int rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr, const char *key
{
StructRNA *srna = ((BlenderRNA *)ptr->data)->structs.first;
for (; srna; srna = srna->cont.next) {
- if (key[0] == srna->identifier[0] && strcmp(key, srna->identifier) == 0) {
+ if (key[0] == srna->identifier[0] && STREQ(key, srna->identifier)) {
RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr);
return true;
}
@@ -1210,18 +1210,18 @@ static void rna_def_property(BlenderRNA *brna)
prop = RNA_def_property(srna, "is_registered", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_boolean_funcs(prop, "rna_Property_registered_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_Property_is_registered_get", NULL);
RNA_def_property_ui_text(prop, "Registered", "Property is registered as part of type registration");
prop = RNA_def_property(srna, "is_registered_optional", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_boolean_funcs(prop, "rna_Property_registered_optional_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_Property_is_registered_optional_get", NULL);
RNA_def_property_ui_text(prop, "Registered Optionally",
"Property is optionally registered as part of type registration");
prop = RNA_def_property(srna, "is_runtime", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_boolean_funcs(prop, "rna_Property_runtime_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_Property_is_runtime_get", NULL);
RNA_def_property_ui_text(prop, "Runtime", "Property has been dynamically created at runtime");
prop = RNA_def_property(srna, "is_enum_flag", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 70ce87ab68b..3e7ffcd8cf0 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -82,6 +82,11 @@ EnumPropertyItem exr_codec_items[] = {
{R_IMF_EXR_CODEC_ZIP, "ZIP", 0, "ZIP (lossless)", ""},
{R_IMF_EXR_CODEC_PIZ, "PIZ", 0, "PIZ (lossless)", ""},
{R_IMF_EXR_CODEC_RLE, "RLE", 0, "RLE (lossless)", ""},
+ {R_IMF_EXR_CODEC_ZIPS, "ZIPS", 0, "ZIPS (lossless)", ""},
+ {R_IMF_EXR_CODEC_B44, "B44", 0, "B44 (lossy)", ""},
+ {R_IMF_EXR_CODEC_B44A, "B44A", 0, "B44A (lossy)", ""},
+ {R_IMF_EXR_CODEC_DWAA, "DWAA", 0, "DWAA (lossy)", ""},
+ {R_IMF_EXR_CODEC_DWAB, "DWAB", 0, "DWAB (lossy)", ""},
{0, NULL, 0, NULL, NULL}
};
#endif
@@ -112,6 +117,7 @@ EnumPropertyItem proportional_falloff_items[] = {
{PROP_SMOOTH, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", "Smooth falloff"},
{PROP_SPHERE, "SPHERE", ICON_SPHERECURVE, "Sphere", "Spherical falloff"},
{PROP_ROOT, "ROOT", ICON_ROOTCURVE, "Root", "Root falloff"},
+ {PROP_INVSQUARE, "INVERSE_SQUARE", ICON_ROOTCURVE, "Inverse Square", "Inverse Square falloff"},
{PROP_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", "Sharp falloff"},
{PROP_LIN, "LINEAR", ICON_LINCURVE, "Linear", "Linear falloff"},
{PROP_CONST, "CONSTANT", ICON_NOCURVE, "Constant", "Constant falloff"},
@@ -385,7 +391,7 @@ static int rna_Scene_object_bases_lookup_string(PointerRNA *ptr, const char *key
Base *base;
for (base = scene->base.first; base; base = base->next) {
- if (strncmp(base->object->id.name + 2, key, sizeof(base->object->id.name) - 2) == 0) {
+ if (STREQLEN(base->object->id.name + 2, key, sizeof(base->object->id.name) - 2)) {
*r_ptr = rna_pointer_inherit_refine(ptr, &RNA_ObjectBase, base);
return true;
}
@@ -737,7 +743,7 @@ static int rna_RenderSettings_threads_mode_get(PointerRNA *ptr)
return (rd->mode & R_FIXED_THREADS);
}
-static int rna_RenderSettings_is_movie_fomat_get(PointerRNA *ptr)
+static int rna_RenderSettings_is_movie_format_get(PointerRNA *ptr)
{
RenderData *rd = (RenderData *)ptr->data;
return BKE_imtype_is_movie(rd->im_format.imtype);
@@ -753,7 +759,7 @@ static int rna_RenderSettings_save_buffers_get(PointerRNA *ptr)
else if (!BKE_scene_use_new_shading_nodes(scene))
return (rd->scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE)) != 0;
else
- return (rd->scemode & R_EXR_TILE_FILE);
+ return (rd->scemode & R_EXR_TILE_FILE) != 0;
}
static int rna_RenderSettings_full_sample_get(PointerRNA *ptr)
@@ -937,12 +943,41 @@ static EnumPropertyItem *rna_ImageFormatSettings_color_depth_itemf(bContext *UNU
}
}
+#ifdef WITH_OPENEXR
+ /* OpenEXR */
+
+static EnumPropertyItem *rna_ImageFormatSettings_exr_codec_itemf(bContext *UNUSED(C), PointerRNA *ptr,
+PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ ImageFormatData *imf = (ImageFormatData *)ptr->data;
+
+ EnumPropertyItem *item = NULL;
+ int i = 1, totitem = 0;
+
+ if (imf->depth == 16)
+ return exr_codec_items; /* All compression types are defined for halfs */
+
+ for (i = 0; i < R_IMF_EXR_CODEC_MAX; i++) {
+ if ((i == R_IMF_EXR_CODEC_B44 || i == R_IMF_EXR_CODEC_B44A)) {
+ continue; /* B44 and B44A are not defined for 32 bit floats */
+ }
+
+ RNA_enum_item_add(&item, &totitem, &exr_codec_items[i]);
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
+
+#endif
static int rna_SceneRender_file_ext_length(PointerRNA *ptr)
{
RenderData *rd = (RenderData *)ptr->data;
char ext[8];
ext[0] = '\0';
- BKE_add_image_extension(ext, &rd->im_format);
+ BKE_image_path_ensure_ext_from_imformat(ext, &rd->im_format);
return strlen(ext);
}
@@ -950,7 +985,7 @@ static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *str)
{
RenderData *rd = (RenderData *)ptr->data;
str[0] = '\0';
- BKE_add_image_extension(str, &rd->im_format);
+ BKE_image_path_ensure_ext_from_imformat(str, &rd->im_format);
}
#ifdef WITH_QUICKTIME
@@ -1063,7 +1098,7 @@ static int rna_RenderSettings_active_layer_index_get(PointerRNA *ptr)
static void rna_RenderSettings_active_layer_index_set(PointerRNA *ptr, int value)
{
RenderData *rd = (RenderData *)ptr->data;
- int num_layers = BLI_countlist(&rd->layers);
+ int num_layers = BLI_listbase_count(&rd->layers);
rd->actlay = min_ff(value, num_layers - 1);
}
@@ -1073,7 +1108,7 @@ static void rna_RenderSettings_active_layer_index_range(PointerRNA *ptr, int *mi
RenderData *rd = (RenderData *)ptr->data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&rd->layers) - 1);
+ *max = max_ii(0, BLI_listbase_count(&rd->layers) - 1);
}
static PointerRNA rna_RenderSettings_active_layer_get(PointerRNA *ptr)
@@ -1158,7 +1193,7 @@ static int rna_RenderSettings_engine_get(PointerRNA *ptr)
int a = 0;
for (type = R_engines.first; type; type = type->next, a++)
- if (strcmp(type->idname, rd->engine) == 0)
+ if (STREQ(type->idname, rd->engine))
return a;
return 0;
@@ -1228,7 +1263,7 @@ static char *rna_SceneRenderLayer_path(PointerRNA *ptr)
static int rna_RenderSettings_multiple_engines_get(PointerRNA *UNUSED(ptr))
{
- return (BLI_countlist(&R_engines) > 1);
+ return (BLI_listbase_count(&R_engines) > 1);
}
static int rna_RenderSettings_use_shading_nodes_get(PointerRNA *ptr)
@@ -1243,8 +1278,8 @@ static int rna_RenderSettings_use_game_engine_get(PointerRNA *ptr)
RenderEngineType *type;
for (type = R_engines.first; type; type = type->next)
- if (strcmp(type->idname, rd->engine) == 0)
- return (type->flag & RE_GAME);
+ if (STREQ(type->idname, rd->engine))
+ return (type->flag & RE_GAME) != 0;
return 0;
}
@@ -1375,7 +1410,7 @@ static void rna_Scene_use_persistent_data_update(Main *UNUSED(bmain), Scene *UNU
static int rna_Scene_use_audio_get(PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->data;
- return scene->audio.flag & AUDIO_MUTE;
+ return (scene->audio.flag & AUDIO_MUTE) != 0;
}
static void rna_Scene_use_audio_set(PointerRNA *ptr, int value)
@@ -1417,10 +1452,7 @@ static void rna_Scene_sync_mode_set(PointerRNA *ptr, int value)
static int rna_GameSettings_auto_start_get(PointerRNA *UNUSED(ptr))
{
- if (G.fileflags & G_FILE_AUTOPLAY)
- return 1;
-
- return 0;
+ return (G.fileflags & G_FILE_AUTOPLAY) != 0;
}
static void rna_GameSettings_auto_start_set(PointerRNA *UNUSED(ptr), int value)
@@ -1485,7 +1517,7 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons
ks = BKE_keyingset_add(&sce->keyingsets, idname, name, KEYINGSET_ABSOLUTE, 0);
if (ks) {
- sce->active_keyingset = BLI_countlist(&sce->keyingsets);
+ sce->active_keyingset = BLI_listbase_count(&sce->keyingsets);
return ks;
}
else {
@@ -1645,7 +1677,7 @@ static void rna_FreestyleSettings_active_lineset_index_range(PointerRNA *ptr, in
FreestyleConfig *config = (FreestyleConfig *)ptr->data;
*min = 0;
- *max = max_ii(0, BLI_countlist(&config->linesets) - 1);
+ *max = max_ii(0, BLI_listbase_count(&config->linesets) - 1);
}
static int rna_FreestyleSettings_active_lineset_index_get(PointerRNA *ptr)
@@ -1691,6 +1723,28 @@ static void rna_FreestyleSettings_module_remove(ID *id, FreestyleSettings *confi
WM_main_add_notifier(NC_SCENE | ND_RENDER_OPTIONS, NULL);
}
+char *rna_GPUDOF_path(PointerRNA *ptr)
+{
+ /* if there is ID-data, resolve the path using the index instead of by name,
+ * since the name used is the name of the texture assigned, but the texture
+ * may be used multiple times in the same stack
+ */
+ if (ptr->id.data) {
+ if (GS(((ID *)ptr->id.data)->name) == ID_CA) {
+ return BLI_strdup("gpu_dof");
+ }
+ }
+
+ return BLI_strdup("");;
+}
+
+static void rna_GPUFXSettings_fx_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ GPUFXSettings *fx_settings = ptr->data;
+
+ BKE_screen_gpu_fx_validate(fx_settings);
+}
+
#else
static void rna_def_transform_orientation(BlenderRNA *brna)
@@ -1773,6 +1827,14 @@ static void rna_def_tool_settings(BlenderRNA *brna)
{WT_VGROUP_BONE_DEFORM_OFF, "OTHER_DEFORM", 0, "Other", "Vertex Groups assigned to non Deform Bones"},
{0, NULL, 0, NULL, NULL}
};
+
+ static EnumPropertyItem gpencil_source_3d_items[] = {
+ {GP_TOOL_SOURCE_SCENE, "SCENE", 0, "Scene",
+ "Grease Pencil data attached to the current scene is used, unless the active object already has Grease Pencil data (i.e. for old files)"},
+ {GP_TOOL_SOURCE_OBJECT, "OBJECT", 0, "Object",
+ "Grease Pencil datablocks attached to the active object are used (required using pre 2.73 add-ons, e.g. BSurfaces)"},
+ {0, NULL, 0, NULL, NULL}
+ };
srna = RNA_def_struct(brna, "ToolSettings", NULL);
@@ -1965,6 +2027,13 @@ static void rna_def_tool_settings(BlenderRNA *brna)
"Allow drawing multiple strokes at a time with Grease Pencil");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); /* xxx: need toolbar to be redrawn... */
+ prop = RNA_def_property(srna, "grease_pencil_source", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_src");
+ RNA_def_property_enum_items(prop, gpencil_source_3d_items);
+ RNA_def_property_ui_text(prop, "Grease Pencil Source",
+ "Datablock where active Grease Pencil data is found from");
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
+
/* Auto Keying */
prop = RNA_def_property(srna, "use_keyframe_insert_auto", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "autokey_mode", AUTOKEY_ON);
@@ -3192,7 +3261,7 @@ static void rna_def_scene_game_recast_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "slope_max", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "agentmaxslope");
- RNA_def_property_range(prop, 0, M_PI / 2);
+ RNA_def_property_range(prop, 0, M_PI_2);
RNA_def_property_ui_text(prop, "Max Slope", "Maximum walkable slope angle");
RNA_def_property_update(prop, NC_SCENE, NULL);
@@ -3607,8 +3676,8 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "logic_step_max", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "maxlogicstep");
- RNA_def_property_ui_range(prop, 1, 5, 1, 1);
- RNA_def_property_range(prop, 1, 5);
+ RNA_def_property_range(prop, 1, 10000);
+ RNA_def_property_ui_range(prop, 1, 50, 1, 1);
RNA_def_property_ui_text(prop, "Max Logic Steps",
"Maximum number of logic frame per game frame if graphics slows down the game, "
"higher value allows better synchronization with physics");
@@ -3616,8 +3685,8 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "physics_step_max", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "maxphystep");
- RNA_def_property_ui_range(prop, 1, 5, 1, 1);
- RNA_def_property_range(prop, 1, 5);
+ RNA_def_property_range(prop, 1, 10000);
+ RNA_def_property_ui_range(prop, 1, 50, 1, 1);
RNA_def_property_ui_text(prop, "Max Physics Steps",
"Maximum number of physics step per game frame if graphics slows down the game, "
"higher value allows physics to keep up with realtime");
@@ -3806,6 +3875,114 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
rna_def_scene_game_recast_data(brna);
}
+static void rna_def_gpu_dof_fx(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "GPUDOFSettings", NULL);
+ RNA_def_struct_ui_text(srna, "GPU DOF", "Settings for GPU based depth of field");
+ RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS);
+ RNA_def_struct_path_func(srna, "rna_GPUDOF_path");
+
+ prop = RNA_def_property(srna, "focus_distance", PROP_FLOAT, PROP_DISTANCE);
+ RNA_def_property_ui_text(prop, "Focus distance", "Viewport depth of field focus distance");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0f, 5000.0f, 1, 2);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "focal_length", PROP_FLOAT, PROP_DISTANCE_CAMERA);
+ RNA_def_property_ui_text(prop, "Focal Length", "Focal length for dof effect");
+ RNA_def_property_range(prop, 1.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 1.0f, 5000.0f, 1, 2);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "sensor", PROP_FLOAT, PROP_DISTANCE_CAMERA);
+ RNA_def_property_ui_text(prop, "Sensor", "Size of sensor");
+ RNA_def_property_range(prop, 1.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 1.0f, 5000.0f, 1, 2);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "fstop", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Viewport F-stop", "F-stop for dof effect");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.1f, 128.0f, 10, 1);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+}
+
+static void rna_def_gpu_ssao_fx(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "GPUSSAOSettings", NULL);
+ RNA_def_struct_ui_text(srna, "GPU SSAO", "Settings for GPU based screen space ambient occlusion");
+ RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS);
+
+ prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Strength", "Strength of the SSAO effect");
+ RNA_def_property_range(prop, 0.0f, 250.0f);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "distance_max", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Distance", "Distance of object that contribute to the SSAO effect");
+ RNA_def_property_range(prop, 0.0f, 100000.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "attenuation", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Attenuation", "Attenuation constant");
+ RNA_def_property_range(prop, 1.0f, 100000.0f);
+ RNA_def_property_ui_range(prop, 1.0f, 100.0f, 1, 3);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "samples", PROP_INT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Samples", "Number of samples");
+ RNA_def_property_range(prop, 1, 500);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_ui_text(prop, "Color", "Color for screen space ambient occlusion effect");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+}
+
+
+static void rna_def_gpu_fx(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ rna_def_gpu_ssao_fx(brna);
+ rna_def_gpu_dof_fx(brna);
+
+ srna = RNA_def_struct(brna, "GPUFXSettings", NULL);
+ RNA_def_struct_ui_text(srna, "GPU FX Settings", "Settings for GPU based compositing");
+ RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS);
+
+ prop = RNA_def_property(srna, "dof", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "GPUDOFSettings");
+ RNA_def_property_ui_text(prop, "Depth Of Field settings", "");
+
+ prop = RNA_def_property(srna, "use_dof", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "fx_flag", GPU_FX_FLAG_DOF);
+ RNA_def_property_ui_text(prop, "Depth Of Field", "Use depth of field on viewport using the values from active camera");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUFXSettings_fx_update");
+
+
+ prop = RNA_def_property(srna, "ssao", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "GPUSSAOSettings");
+ RNA_def_property_ui_text(prop, "Screen Space Ambient Occlusion settings", "");
+
+ prop = RNA_def_property(srna, "use_ssao", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "fx_flag", GPU_FX_FLAG_SSAO);
+ RNA_def_property_ui_text(prop, "SSAO", "Use screen space ambient occlusion of field on viewport");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUFXSettings_fx_update");
+}
+
+
static void rna_def_scene_render_layer(BlenderRNA *brna)
{
StructRNA *srna;
@@ -3958,6 +4135,7 @@ static void rna_def_scene_image_format_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "exr_codec", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "exr_codec");
RNA_def_property_enum_items(prop, exr_codec_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_ImageFormatSettings_exr_codec_itemf");
RNA_def_property_ui_text(prop, "Codec", "Codec settings for OpenEXR");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
@@ -4666,6 +4844,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "use_freestyle", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_EDGE_FRS);
RNA_def_property_ui_text(prop, "Edge", "Draw stylized strokes using Freestyle");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_freestyle_update");
@@ -4801,7 +4980,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "is_movie_format", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_is_movie_fomat_get", NULL);
+ RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_is_movie_format_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Movie Format", "When true the format is a movie");
@@ -5375,6 +5554,55 @@ static void rna_def_selected_uv_element(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Face Index", "");
}
+static void rna_def_display_safe_areas(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static float default_title[2] = {0.035f, 0.035f};
+ static float default_action[2] = {0.1f, 0.05f};
+
+ static float default_title_center[2] = {0.175f, 0.05f};
+ static float default_action_center[2] = {0.15f, 0.05f};
+
+ srna = RNA_def_struct(brna, "DisplaySafeAreas", NULL);
+ RNA_def_struct_ui_text(srna, "Safe Areas", "Safe Areas used in 3D view and the VSE");
+ RNA_def_struct_sdna(srna, "DisplaySafeAreas");
+
+ /* SAFE AREAS */
+ prop = RNA_def_property(srna, "title", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "title");
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_array_default(prop, default_title);
+ RNA_def_property_ui_text(prop, "Title Safe margins", "Safe area for text and graphics");
+ RNA_def_property_update(prop, NC_SCENE | ND_DRAW_RENDER_VIEWPORT, NULL);
+
+ prop = RNA_def_property(srna, "action", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "action");
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_float_array_default(prop, default_action);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Action Safe Margins", "Safe area for general elements");
+ RNA_def_property_update(prop, NC_SCENE | ND_DRAW_RENDER_VIEWPORT, NULL);
+
+
+ prop = RNA_def_property(srna, "title_center", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "title_center");
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_float_array_default(prop, default_title_center);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Center Title Safe Margins", "Safe area for text and graphics in a different aspect ratio");
+ RNA_def_property_update(prop, NC_SCENE | ND_DRAW_RENDER_VIEWPORT, NULL);
+
+ prop = RNA_def_property(srna, "action_center", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "action_center");
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_float_array_default(prop, default_action_center);
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(prop, "Center Action Safe Margins", "Safe area for general elements in a different aspect ratio");
+ RNA_def_property_update(prop, NC_SCENE | ND_DRAW_RENDER_VIEWPORT, NULL);
+}
void RNA_def_scene(BlenderRNA *brna)
@@ -5459,7 +5687,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "lay", 1);
RNA_def_property_array(prop, 20);
RNA_def_property_boolean_funcs(prop, NULL, "rna_Scene_layer_set");
- RNA_def_property_ui_text(prop, "Layers", "Visible layers - Shift-Click to select multiple layers");
+ RNA_def_property_ui_text(prop, "Layers", "Visible layers - Shift-Click/Drag to select multiple layers");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_Scene_layer_update");
/* active layer */
@@ -5670,6 +5898,13 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "RenderSettings");
RNA_def_property_ui_text(prop, "Render Data", "");
+ /* Safe Areas */
+ prop = RNA_def_property(srna, "safe_areas", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "safe_areas");
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "DisplaySafeAreas");
+ RNA_def_property_ui_text(prop, "Safe Areas", "");
+
/* Markers */
prop = RNA_def_property(srna, "timeline_markers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "markers", NULL);
@@ -5717,7 +5952,7 @@ void RNA_def_scene(BlenderRNA *brna)
prop = RNA_def_property(srna, "audio_volume", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "audio.volume");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Volume", "Audio volume");
RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_SOUND);
RNA_def_property_update(prop, NC_SCENE, NULL);
@@ -5738,10 +5973,10 @@ void RNA_def_scene(BlenderRNA *brna)
/* Grease Pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
- RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "GreasePencil");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Grease Pencil Data", "Grease Pencil datablock");
- RNA_def_property_update(prop, NC_SCENE, NULL);
+ RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
/* Transform Orientations */
prop = RNA_def_property(srna, "orientations", PROP_COLLECTION, PROP_NONE);
@@ -5784,11 +6019,14 @@ void RNA_def_scene(BlenderRNA *brna)
rna_def_scene_game_data(brna);
rna_def_transform_orientation(brna);
rna_def_selected_uv_element(brna);
+ rna_def_display_safe_areas(brna);
RNA_define_animate_sdna(true);
/* *** Animated *** */
rna_def_scene_render_data(brna);
rna_def_scene_render_layer(brna);
-
+
+ rna_def_gpu_fx(brna);
+
/* Scene API */
RNA_api_scene(srna);
}
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 84134e7cd3a..36657c8a898 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -47,12 +47,14 @@
#include "BKE_animsys.h"
#include "BKE_depsgraph.h"
+#include "BKE_editmesh.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_scene.h"
#include "BKE_writeavi.h"
#include "ED_transform.h"
+#include "ED_uvedit.h"
#ifdef WITH_PYTHON
# include "BPY_extern.h"
@@ -90,6 +92,20 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
}
}
+static void rna_Scene_uvedit_aspect(Scene *scene, Object *ob, float *aspect)
+{
+ if ((ob->type == OB_MESH) && (ob->mode == OB_MODE_EDIT)) {
+ BMEditMesh *em;
+ em = BKE_editmesh_from_object(ob);
+ if (EDBM_mtexpoly_check(em)) {
+ ED_uvedit_get_aspect(scene, ob, em->bm, aspect, aspect + 1);
+ return;
+ }
+ }
+
+ aspect[0] = aspect[1] = 1.0f;
+}
+
static void rna_Scene_update_tagged(Scene *scene)
{
#ifdef WITH_PYTHON
@@ -105,11 +121,14 @@ static void rna_Scene_update_tagged(Scene *scene)
static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name)
{
- if (BKE_imtype_is_movie(rd->im_format.imtype))
+ if (BKE_imtype_is_movie(rd->im_format.imtype)) {
BKE_movie_filepath_get(name, rd);
- else
- BKE_makepicstring(name, rd->pic, G.main->name, (frame == INT_MIN) ? rd->cfra : frame,
- &rd->im_format, (rd->scemode & R_EXTENSION) != 0, true);
+ }
+ else {
+ BKE_image_path_from_imformat(
+ name, rd->pic, G.main->name, (frame == INT_MIN) ? rd->cfra : frame,
+ &rd->im_format, (rd->scemode & R_EXTENSION) != 0, true);
+ }
}
static void rna_Scene_ray_cast(Scene *scene, float ray_start[3], float ray_end[3],
@@ -191,6 +210,15 @@ void RNA_api_scene(StructRNA *srna)
RNA_def_function_ui_description(func,
"Update data tagged to be updated from previous access to data or operators");
+ func = RNA_def_function(srna, "uvedit_aspect", "rna_Scene_uvedit_aspect");
+ RNA_def_function_ui_description(func, "Get uv aspect for current object");
+ parm = RNA_def_pointer(func, "object", "Object", "", "Object");
+ RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+
+ parm = RNA_def_float_vector(func, "result", 2, NULL, 0.0f, FLT_MAX, "", "aspect", 0.0f, FLT_MAX);
+ RNA_def_property_flag(parm, PROP_THICK_WRAP);
+ RNA_def_function_output(func, parm);
+
/* Ray Cast */
func = RNA_def_function(srna, "ray_cast", "rna_Scene_ray_cast");
RNA_def_function_ui_description(func, "Cast a ray onto in object space");
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 86a28fb80bf..477a9dbca4f 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -110,7 +110,9 @@ static void rna_Screen_redraw_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
static int rna_Screen_is_animation_playing_get(PointerRNA *UNUSED(ptr))
{
- return (ED_screen_animation_playing(G.main->wm.first) != NULL);
+ /* can be NULL on file load, T42619 */
+ wmWindowManager *wm = G.main->wm.first;
+ return wm ? (ED_screen_animation_playing(wm) != NULL) : 0;
}
static int rna_Screen_fullscreen_get(PointerRNA *ptr)
@@ -411,6 +413,11 @@ static void rna_def_screen(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "All 3D View Editors", "");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, "rna_Screen_redraw_update");
+ prop = RNA_def_property(srna, "use_follow", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "redraws_flag", TIME_FOLLOW);
+ RNA_def_property_ui_text(prop, "Follow", "Follow current frame in editors");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, "rna_Screen_redraw_update");
+
prop = RNA_def_property(srna, "use_play_animation_editors", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "redraws_flag", TIME_ALL_ANIM_WIN);
RNA_def_property_ui_text(prop, "Animation Editors", "");
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 09e42e48e93..e09e0354e0b 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -289,9 +289,10 @@ static char *rna_ParticleBrush_path(PointerRNA *UNUSED(ptr))
static void rna_Paint_brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
- Brush *br = (Brush *)ptr->data;
+ Paint *paint = ptr->data;
+ Brush *br = paint->brush;
BKE_paint_invalidate_overlay_all();
- WM_main_add_notifier(NC_BRUSH | NA_EDITED, br);
+ WM_main_add_notifier(NC_BRUSH | NA_SELECTED, br);
}
static void rna_ImaPaint_viewport_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
@@ -303,22 +304,27 @@ static void rna_ImaPaint_viewport_update(Main *UNUSED(bmain), Scene *UNUSED(scen
static void rna_ImaPaint_mode_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
Object *ob = OBACT;
-
- /* of course we need to invalidate here */
- BKE_texpaint_slots_refresh_object(scene, ob);
- /* we assume that changing the current mode will invalidate the uv layers so we need to refresh display */
- GPU_drawobject_free(ob->derivedFinal);
- BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
- WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
+ if (ob && ob->type == OB_MESH) {
+ /* of course we need to invalidate here */
+ BKE_texpaint_slots_refresh_object(scene, ob);
+
+ /* we assume that changing the current mode will invalidate the uv layers so we need to refresh display */
+ GPU_drawobject_free(ob->derivedFinal);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
+ }
}
static void rna_ImaPaint_stencil_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
- Object *ob = OBACT;
- GPU_drawobject_free(ob->derivedFinal);
- BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
- WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
+ Object *ob = OBACT;
+
+ if (ob && ob->type == OB_MESH) {
+ GPU_drawobject_free(ob->derivedFinal);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
+ }
}
static void rna_ImaPaint_canvas_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
@@ -342,9 +348,11 @@ static void rna_ImaPaint_canvas_update(Main *bmain, Scene *scene, PointerRNA *UN
}
}
- GPU_drawobject_free(ob->derivedFinal);
- BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
- WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
+ if (ob && ob->type == OB_MESH) {
+ GPU_drawobject_free(ob->derivedFinal);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
+ }
}
static int rna_ImaPaint_detect_data(ImagePaintSettings *imapaint)
@@ -467,6 +475,17 @@ static void rna_def_paint(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Symmetry Feathering",
"Reduce the strength of the brush where it overlaps symmetrical daubs");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "cavity_curve", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_ui_text(prop, "Curve", "Editable cavity curve");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
+ prop = RNA_def_property(srna, "use_cavity", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", PAINT_USE_CAVITY_MASK);
+ RNA_def_property_ui_text(prop, "Cavity Mask", "Mask painting according to mesh geometry cavity");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
}
static void rna_def_sculpt(BlenderRNA *brna)
@@ -673,7 +692,7 @@ static void rna_def_image_paint(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_STENCIL);
RNA_def_property_ui_text(prop, "Stencil Layer", "Set the mask layer from the UV map buttons");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_viewport_update");
-
+
prop = RNA_def_property(srna, "invert_stencil", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_STENCIL_INV);
RNA_def_property_ui_text(prop, "Invert", "Invert the stencil layer");
@@ -701,12 +720,17 @@ static void rna_def_image_paint(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "stencil_col");
RNA_def_property_ui_text(prop, "Stencil Color", "Stencil color in the viewport");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_viewport_update");
+
+ prop = RNA_def_property(srna, "dither", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0, 2.0);
+ RNA_def_property_ui_text(prop, "Dither", "Amount of dithering when painting on byte images");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "use_clone_layer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_CLONE);
RNA_def_property_ui_text(prop, "Clone Map",
"Use another UV map as clone source, otherwise use the 3D cursor as the source");
- RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_viewport_update");
/* integers */
@@ -880,6 +904,10 @@ static void rna_def_particle_edit(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Object", "The edited object");
+ prop = RNA_def_property(srna, "shape_object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Shape Object", "Outer shape to use for tools");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_ParticleEdit_redo");
/* brush */
diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c
index 3944b59dff7..5d7bb6d2d94 100644
--- a/source/blender/makesrna/intern/rna_sensor.c
+++ b/source/blender/makesrna/intern/rna_sensor.c
@@ -107,14 +107,10 @@ static StructRNA *rna_Sensor_refine(struct PointerRNA *ptr)
static void rna_Sensor_name_set(PointerRNA *ptr, const char *value)
{
- bSensor *sens = (bSensor *)ptr->data;
-
+ Object *ob = ptr->id.data;
+ bSensor *sens = ptr->data;
BLI_strncpy_utf8(sens->name, value, sizeof(sens->name));
-
- if (ptr->id.data) {
- Object *ob = (Object *)ptr->id.data;
- BLI_uniquename(&ob->sensors, sens, DATA_("Sensor"), '.', offsetof(bSensor, name), sizeof(sens->name));
- }
+ BLI_uniquename(&ob->sensors, sens, DATA_("Sensor"), '.', offsetof(bSensor, name), sizeof(sens->name));
}
static void rna_Sensor_type_set(struct PointerRNA *ptr, int value)
@@ -246,11 +242,11 @@ static void rna_Sensor_Armature_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
bPoseChannel *pchan;
bPose *pose = ob->pose;
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- if (!strcmp(pchan->name, posechannel)) {
+ if (STREQ(pchan->name, posechannel)) {
/* found it, now look for constraint channel */
bConstraint *con;
for (con = pchan->constraints.first; con; con = con->next) {
- if (!strcmp(con->name, constraint)) {
+ if (STREQ(con->name, constraint)) {
/* found it, all ok */
return;
}
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 00f0a6ff487..8ad7d313c1e 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -290,11 +290,14 @@ static void rna_Sequence_channel_set(PointerRNA *ptr, int value)
Scene *scene = (Scene *)ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, false);
ListBase *seqbase = BKE_sequence_seqbase(&ed->seqbase, seq);
-
- seq->machine = value;
+ /* check channel increment or decrement */
+ const int channel_delta = (value >= seq->machine) ? 1 : -1;
+ seq->machine = value;
+
if (BKE_sequence_test_overlap(seqbase, seq)) {
- BKE_sequence_base_shuffle(seqbase, seq, scene); /* XXX - BROKEN!, uses context seqbasep */
+ /* XXX - BROKEN!, uses context seqbasep */
+ BKE_sequence_base_shuffle_ex(seqbase, seq, scene, channel_delta);
}
BKE_sequencer_sort(scene);
}
@@ -310,18 +313,7 @@ static void rna_Sequence_frame_offset_range(PointerRNA *ptr, int *min, int *max,
static void rna_Sequence_use_proxy_set(PointerRNA *ptr, int value)
{
Sequence *seq = (Sequence *)ptr->data;
- if (value) {
- seq->flag |= SEQ_USE_PROXY;
- if (seq->strip->proxy == NULL) {
- seq->strip->proxy = MEM_callocN(sizeof(struct StripProxy), "StripProxy");
- seq->strip->proxy->quality = 90;
- seq->strip->proxy->build_tc_flags = SEQ_PROXY_TC_ALL;
- seq->strip->proxy->build_size_flags = SEQ_PROXY_IMAGE_SIZE_25;
- }
- }
- else {
- seq->flag ^= SEQ_USE_PROXY;
- }
+ BKE_sequencer_proxy_set(seq, value != 0);
}
static void rna_Sequence_use_translation_set(PointerRNA *ptr, int value)
@@ -1187,6 +1179,10 @@ static void rna_def_strip_proxy(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceProxy_update");
+ prop = RNA_def_property(srna, "use_overwrite", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "build_flags", SEQ_PROXY_SKIP_EXISTING);
+ RNA_def_property_ui_text(prop, "Overwrite", "Overwrite existing proxy files when building");
+
prop = RNA_def_property(srna, "build_25", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "build_size_flags", SEQ_PROXY_IMAGE_SIZE_25);
RNA_def_property_ui_text(prop, "25%", "Build 25% proxy resolution");
@@ -1503,7 +1499,7 @@ static void rna_def_sequence(BlenderRNA *brna)
prop = RNA_def_property(srna, "channel", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "machine");
- RNA_def_property_range(prop, 0, MAXSEQ - 1);
+ RNA_def_property_range(prop, 1, MAXSEQ);
RNA_def_property_ui_text(prop, "Channel", "Y position of the sequence strip");
RNA_def_property_int_funcs(prop, NULL, "rna_Sequence_channel_set", NULL); /* overlap test */
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
@@ -1846,6 +1842,11 @@ static void rna_def_scene(BlenderRNA *brna)
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Camera_object_poll");
RNA_def_property_ui_text(prop, "Camera Override", "Override the scenes active camera");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
+
+ prop = RNA_def_property(srna, "use_grease_pencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SEQ_SCENE_NO_GPENCIL);
+ RNA_def_property_ui_text(prop, "Use Grease Pencil", "Show Grease Pencil strokes in OpenGL previews");
+ RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
rna_def_filter_video(srna);
rna_def_proxy(srna);
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 70370f1ae36..351a15c0171 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -313,6 +313,7 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor
seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
+ BKE_sequence_calc(scene, seq);
BKE_sequence_calc_disp(scene, seq);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
@@ -484,8 +485,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_pointer(func, "clip", "MovieClip", "", "Movie clip to add");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
- parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
- "The channel for the new sequence", 0, MAXSEQ - 1);
+ parm = RNA_def_int(func, "channel", 0, 1, MAXSEQ, "Channel",
+ "The channel for the new sequence", 1, MAXSEQ);
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
@@ -501,8 +502,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_pointer(func, "mask", "Mask", "", "Mask to add");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
- parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
- "The channel for the new sequence", 0, MAXSEQ - 1);
+ parm = RNA_def_int(func, "channel", 0, 1, MAXSEQ, "Channel",
+ "The channel for the new sequence", 1, MAXSEQ);
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
@@ -518,8 +519,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene to add");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
- parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
- "The channel for the new sequence", 0, MAXSEQ - 1);
+ parm = RNA_def_int(func, "channel", 0, 1, MAXSEQ, "Channel",
+ "The channel for the new sequence", 1, MAXSEQ);
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
@@ -535,8 +536,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to image");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
- "The channel for the new sequence", 0, MAXSEQ - 1);
+ parm = RNA_def_int(func, "channel", 0, 1, MAXSEQ, "Channel",
+ "The channel for the new sequence", 1, MAXSEQ);
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
@@ -552,8 +553,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to movie");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
- "The channel for the new sequence", 0, MAXSEQ - 1);
+ parm = RNA_def_int(func, "channel", 0, 1, MAXSEQ, "Channel",
+ "The channel for the new sequence", 1, MAXSEQ);
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
@@ -569,8 +570,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to movie");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
- "The channel for the new sequence", 0, MAXSEQ - 1);
+ parm = RNA_def_int(func, "channel", 0, 1, MAXSEQ, "Channel",
+ "The channel for the new sequence", 1, MAXSEQ);
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "frame_start", 0, -MAXFRAME, MAXFRAME, "",
"The start frame for the new sequence", -MAXFRAME, MAXFRAME);
@@ -587,8 +588,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_enum(func, "type", seq_effect_items, 0, "Type",
"type for the new sequence");
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel",
- "The channel for the new sequence", 0, MAXSEQ - 1);
+ parm = RNA_def_int(func, "channel", 0, 1, MAXSEQ, "Channel",
+ "The channel for the new sequence", 1, MAXSEQ);
/* don't use MAXFRAME since it makes importer scripts fail */
RNA_def_property_flag(parm, PROP_REQUIRED);
parm = RNA_def_int(func, "frame_start", 0, INT_MIN, INT_MAX, "",
diff --git a/source/blender/makesrna/intern/rna_sound.c b/source/blender/makesrna/intern/rna_sound.c
index 206a72a01b0..4b745c60b5b 100644
--- a/source/blender/makesrna/intern/rna_sound.c
+++ b/source/blender/makesrna/intern/rna_sound.c
@@ -38,6 +38,7 @@
#include "BKE_sound.h"
#include "BKE_context.h"
+#include "BKE_sequencer.h"
static void rna_Sound_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
@@ -59,9 +60,9 @@ static void rna_Sound_caching_set(PointerRNA *ptr, const int value)
sound_delete_cache(sound);
}
-static void rna_Sound_caching_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_Sound_caching_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
{
- sound_update_sequencer(bmain, (bSound *)(ptr->data));
+ BKE_sequencer_update_sound(scene, (bSound *)(ptr->data));
}
#else
@@ -97,6 +98,8 @@ static void rna_def_sound(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mono",
"If the file contains multiple audio channels they are rendered to a single one");
RNA_def_property_update(prop, 0, "rna_Sound_update");
+
+ RNA_api_sound(srna);
}
void RNA_def_sound(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_sound_api.c b/source/blender/makesrna/intern/rna_sound_api.c
new file mode 100644
index 00000000000..0164daa98d0
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_sound_api.c
@@ -0,0 +1,73 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2015 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Kevin Dietrich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/makesrna/intern/rna_sound_api.c
+ * \ingroup RNA
+ */
+
+#include "DNA_packedFile_types.h"
+
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
+#ifdef RNA_RUNTIME
+
+#include "BKE_packedFile.h"
+
+static void rna_Sound_pack(bSound *sound, Main *bmain, ReportList *reports)
+{
+ sound->packedfile = newPackedFile(reports, sound->name, ID_BLEND_PATH(bmain, &sound->id));
+}
+
+static void rna_Sound_unpack(bSound *sound, Main *bmain, ReportList *reports, int method)
+{
+ if (!sound->packedfile) {
+ BKE_report(reports, RPT_ERROR, "Sound not packed");
+ }
+ else {
+ /* reports its own error on failure */
+ unpackSound(bmain, reports, sound, method);
+ }
+}
+
+#else
+
+void RNA_api_sound(StructRNA *srna)
+{
+ FunctionRNA *func;
+
+ func = RNA_def_function(srna, "pack", "rna_Sound_pack");
+ RNA_def_function_ui_description(func, "Pack the sound into the current blend file");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN);
+
+ func = RNA_def_function(srna, "unpack", "rna_Sound_unpack");
+ RNA_def_function_ui_description(func, "Unpack the sound to the samples filename");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN);
+ RNA_def_enum(func, "method", unpack_method_items, PF_USE_LOCAL, "method", "How to unpack");
+}
+
+#endif
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index a314e995ba3..9e7d70ab3b2 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -34,6 +34,7 @@
#include "BKE_key.h"
#include "BKE_movieclip.h"
#include "BKE_node.h"
+#include "BKE_screen.h"
#include "DNA_action_types.h"
#include "DNA_key_types.h"
@@ -56,6 +57,8 @@
#include "RE_engine.h"
#include "RE_pipeline.h"
+#include "ED_fileselect.h"
+
#include "RNA_enum_types.h"
@@ -204,6 +207,7 @@ static EnumPropertyItem buttons_texture_context_items[] = {
#include "BKE_icons.h"
#include "ED_buttons.h"
+#include "ED_fileselect.h"
#include "ED_image.h"
#include "ED_node.h"
#include "ED_screen.h"
@@ -266,13 +270,7 @@ static ScrArea *rna_area_from_space(PointerRNA *ptr)
{
bScreen *sc = (bScreen *)ptr->id.data;
SpaceLink *link = (SpaceLink *)ptr->data;
- ScrArea *sa;
-
- for (sa = sc->areabase.first; sa; sa = sa->next)
- if (BLI_findindex(&sa->spacedata, link) != -1)
- return sa;
-
- return NULL;
+ return BKE_screen_find_area_from_space(sc, link);
}
static void area_region_from_regiondata(bScreen *sc, void *regiondata, ScrArea **r_sa, ARegion **r_ar)
@@ -485,7 +483,7 @@ static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(sce
BKE_previewimg_free(&ma->preview);
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_DRAW, ma);
}
@@ -797,7 +795,7 @@ static void rna_SpaceImageEditor_cursor_location_set(PointerRNA *ptr, const floa
}
}
-static void rna_SpaceImageEditor_scopes_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+static void rna_SpaceImageEditor_scopes_update(struct bContext *C, struct PointerRNA *ptr)
{
SpaceImage *sima = (SpaceImage *)ptr->data;
ImBuf *ibuf;
@@ -805,7 +803,7 @@ static void rna_SpaceImageEditor_scopes_update(Main *UNUSED(bmain), Scene *scene
ibuf = ED_space_image_acquire_buffer(sima, &lock);
if (ibuf) {
- scopes_update(&sima->scopes, ibuf, &scene->view_settings, &scene->display_settings);
+ ED_space_image_scopes_update(C, sima, ibuf, true);
WM_main_add_notifier(NC_IMAGE, sima->image);
}
ED_space_image_release_buffer(sima, ibuf, lock);
@@ -856,7 +854,6 @@ static void rna_SpaceTextEditor_updateEdited(Main *UNUSED(bmain), Scene *UNUSED(
WM_main_add_notifier(NC_TEXT | NA_EDITED, st->text);
}
-
/* Space Properties */
/* note: this function exists only to avoid id refcounting */
@@ -1117,12 +1114,12 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *UNUSED(bmain), Scene *s
if (saction->mode == SACTCONT_ACTION) {
/* TODO: context selector could help decide this with more control? */
- adt = BKE_id_add_animdata(&obact->id); /* this only adds if non-existant */
+ adt = BKE_id_add_animdata(&obact->id); /* this only adds if non-existent */
}
else if (saction->mode == SACTCONT_SHAPEKEY) {
Key *key = BKE_key_from_object(obact);
if (key)
- adt = BKE_id_add_animdata(&key->id); /* this only adds if non-existant */
+ adt = BKE_id_add_animdata(&key->id); /* this only adds if non-existent */
}
/* set action */
@@ -1130,7 +1127,7 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *UNUSED(bmain), Scene *s
/* fix id-count of action we're replacing */
id_us_min(&adt->action->id);
- /* show new id-count of action we're replacing */
+ /* assign new action, and adjust the usercounts accordingly */
adt->action = saction->action;
id_us_plus(&adt->action->id);
@@ -1256,7 +1253,7 @@ static int rna_SpaceNodeEditor_node_tree_poll(PointerRNA *ptr, const PointerRNA
bNodeTree *ntree = (bNodeTree *)value.data;
/* node tree type must match the selected type in node editor */
- return (strcmp(snode->tree_idname, ntree->idname) == 0);
+ return (STREQ(snode->tree_idname, ntree->idname));
}
static void rna_SpaceNodeEditor_node_tree_update(const bContext *C, PointerRNA *UNUSED(ptr))
@@ -1375,6 +1372,271 @@ static void rna_SpaceClipEditor_view_type_update(Main *UNUSED(bmain), Scene *UNU
ED_area_tag_refresh(sa);
}
+/* File browser. */
+
+static void rna_FileBrowser_FSMenuEntry_path_get(PointerRNA *ptr, char *value)
+{
+ char *path = ED_fsmenu_entry_get_path(ptr->data);
+
+ strcpy(value, path ? path : "");
+}
+
+static int rna_FileBrowser_FSMenuEntry_path_length(PointerRNA *ptr)
+{
+ char *path = ED_fsmenu_entry_get_path(ptr->data);
+
+ return (int)(path ? strlen(path) : 0);
+}
+
+static void rna_FileBrowser_FSMenuEntry_path_set(PointerRNA *ptr, const char *value)
+{
+ FSMenuEntry *fsm = ptr->data;
+
+ /* Note: this will write to file immediately.
+ * Not nice (and to be fixed ultimately), but acceptable in this case for now. */
+ ED_fsmenu_entry_set_path(fsm, value);
+}
+
+static void rna_FileBrowser_FSMenuEntry_name_get(PointerRNA *ptr, char *value)
+{
+ strcpy(value, ED_fsmenu_entry_get_name(ptr->data));
+}
+
+static int rna_FileBrowser_FSMenuEntry_name_length(PointerRNA *ptr)
+{
+ return (int)strlen(ED_fsmenu_entry_get_name(ptr->data));
+}
+
+static void rna_FileBrowser_FSMenuEntry_name_set(PointerRNA *ptr, const char *value)
+{
+ FSMenuEntry *fsm = ptr->data;
+
+ /* Note: this will write to file immediately.
+ * Not nice (and to be fixed ultimately), but acceptable in this case for now. */
+ ED_fsmenu_entry_set_name(fsm, value);
+}
+
+static int rna_FileBrowser_FSMenuEntry_name_get_editable(PointerRNA *ptr)
+{
+ FSMenuEntry *fsm = ptr->data;
+
+ return fsm->save;
+}
+
+static void rna_FileBrowser_FSMenu_next(CollectionPropertyIterator *iter)
+{
+ ListBaseIterator *internal = &iter->internal.listbase;
+
+ if (internal->skip) {
+ do {
+ internal->link = (Link *)(((FSMenuEntry *)(internal->link))->next);
+ iter->valid = (internal->link != NULL);
+ } while (iter->valid && internal->skip(iter, internal->link));
+ }
+ else {
+ internal->link = (Link *)(((FSMenuEntry *)(internal->link))->next);
+ iter->valid = (internal->link != NULL);
+ }
+}
+
+static void rna_FileBrowser_FSMenu_begin(CollectionPropertyIterator *iter, FSMenuCategory category)
+{
+ ListBaseIterator *internal = &iter->internal.listbase;
+
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+ struct FSMenuEntry *fsmentry = ED_fsmenu_get_category(fsmenu, category);
+
+ internal->link = (fsmentry) ? (Link *)fsmentry : NULL;
+ internal->skip = NULL;
+
+ iter->valid = (internal->link != NULL);
+}
+
+static PointerRNA rna_FileBrowser_FSMenu_get(CollectionPropertyIterator *iter)
+{
+ ListBaseIterator *internal = &iter->internal.listbase;
+ PointerRNA r_ptr;
+
+ RNA_pointer_create(NULL, &RNA_FileBrowserFSMenuEntry, internal->link, &r_ptr);
+
+ return r_ptr;
+}
+
+static void rna_FileBrowser_FSMenu_end(CollectionPropertyIterator *UNUSED(iter))
+{
+}
+
+static void rna_FileBrowser_FSMenuSystem_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr))
+{
+ rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_SYSTEM);
+}
+
+static int rna_FileBrowser_FSMenuSystem_data_length(PointerRNA *UNUSED(ptr))
+{
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+
+ return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_SYSTEM);
+}
+
+static void rna_FileBrowser_FSMenuSystemBookmark_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr))
+{
+ rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_SYSTEM_BOOKMARKS);
+}
+
+static int rna_FileBrowser_FSMenuSystemBookmark_data_length(PointerRNA *UNUSED(ptr))
+{
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+
+ return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuBookmark_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr))
+{
+ rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_BOOKMARKS);
+}
+
+static int rna_FileBrowser_FSMenuBookmark_data_length(PointerRNA *UNUSED(ptr))
+{
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+
+ return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuRecent_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr))
+{
+ rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_RECENT);
+}
+
+static int rna_FileBrowser_FSMenuRecent_data_length(PointerRNA *UNUSED(ptr))
+{
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+
+ return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_RECENT);
+}
+
+static int rna_FileBrowser_FSMenu_active_get(PointerRNA *ptr, const FSMenuCategory category)
+{
+ SpaceFile *sf = ptr->data;
+ int actnr = -1;
+
+ switch (category) {
+ case FS_CATEGORY_SYSTEM:
+ actnr = sf->systemnr;
+ break;
+ case FS_CATEGORY_SYSTEM_BOOKMARKS:
+ actnr = sf->system_bookmarknr;
+ break;
+ case FS_CATEGORY_BOOKMARKS:
+ actnr = sf->bookmarknr;
+ break;
+ case FS_CATEGORY_RECENT:
+ actnr = sf->recentnr;
+ break;
+ }
+
+ return actnr;
+}
+
+static void rna_FileBrowser_FSMenu_active_set(PointerRNA *ptr, int value, const FSMenuCategory category)
+{
+ SpaceFile *sf = ptr->data;
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+ FSMenuEntry *fsm = ED_fsmenu_get_entry(fsmenu, category, value);
+
+ if (fsm && sf->params) {
+ switch (category) {
+ case FS_CATEGORY_SYSTEM:
+ sf->systemnr = value;
+ break;
+ case FS_CATEGORY_SYSTEM_BOOKMARKS:
+ sf->system_bookmarknr = value;
+ break;
+ case FS_CATEGORY_BOOKMARKS:
+ sf->bookmarknr = value;
+ break;
+ case FS_CATEGORY_RECENT:
+ sf->recentnr = value;
+ break;
+ }
+
+ BLI_strncpy(sf->params->dir, fsm->path, sizeof(sf->params->dir));
+ }
+}
+
+static void rna_FileBrowser_FSMenu_active_range(
+ PointerRNA *UNUSED(ptr), int *min, int *max, int *softmin, int *softmax, const FSMenuCategory category)
+{
+ struct FSMenu *fsmenu = ED_fsmenu_get();
+
+ *min = *softmin = -1;
+ *max = *softmax = ED_fsmenu_get_nentries(fsmenu, category) - 1;
+}
+
+static void rna_FileBrowser_FSMenu_active_update(struct bContext *C, PointerRNA *UNUSED(ptr))
+{
+ ED_file_change_dir(C, true);
+}
+
+static int rna_FileBrowser_FSMenuSystem_active_get(PointerRNA *ptr)
+{
+ return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_SYSTEM);
+}
+
+static void rna_FileBrowser_FSMenuSystem_active_set(PointerRNA *ptr, int value)
+{
+ rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_SYSTEM);
+}
+
+static void rna_FileBrowser_FSMenuSystem_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+{
+ rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_SYSTEM);
+}
+
+static int rna_FileBrowser_FSMenuSystemBookmark_active_get(PointerRNA *ptr)
+{
+ return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_SYSTEM_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuSystemBookmark_active_set(PointerRNA *ptr, int value)
+{
+ rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_SYSTEM_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuSystemBookmark_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+{
+ rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_SYSTEM_BOOKMARKS);
+}
+
+static int rna_FileBrowser_FSMenuBookmark_active_get(PointerRNA *ptr)
+{
+ return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuBookmark_active_set(PointerRNA *ptr, int value)
+{
+ rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_BOOKMARKS);
+}
+
+static void rna_FileBrowser_FSMenuBookmark_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+{
+ rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_BOOKMARKS);
+}
+
+static int rna_FileBrowser_FSMenuRecent_active_get(PointerRNA *ptr)
+{
+ return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_RECENT);
+}
+
+static void rna_FileBrowser_FSMenuRecent_active_set(PointerRNA *ptr, int value)
+{
+ rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_RECENT);
+}
+
+static void rna_FileBrowser_FSMenuRecent_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
+{
+ rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_RECENT);
+}
+
#else
static EnumPropertyItem dt_uv_items[] = {
@@ -1572,6 +1834,8 @@ static void rna_def_space_outliner(BlenderRNA *brna)
{SO_LIBRARIES, "LIBRARIES", 0, "Blender File", "Display data of current file and linked libraries"},
{SO_DATABLOCKS, "DATABLOCKS", 0, "Datablocks", "Display all raw datablocks"},
{SO_USERDEF, "USER_PREFERENCES", 0, "User Preferences", "Display the user preference datablocks"},
+ {SO_ID_ORPHANS, "ORPHAN_DATA", 0, "Orphan Data",
+ "Display datablocks which are unused and/or will be lost when the file is reloaded"},
{0, NULL, 0, NULL, NULL}
};
@@ -1588,6 +1852,7 @@ static void rna_def_space_outliner(BlenderRNA *brna)
prop = RNA_def_property(srna, "filter_text", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "search_string");
RNA_def_property_ui_text(prop, "Display Filter", "Live search filtering string");
+ RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
prop = RNA_def_property(srna, "use_filter_case_sensitive", PROP_BOOLEAN, PROP_NONE);
@@ -1599,7 +1864,12 @@ static void rna_def_space_outliner(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "search_flags", SO_FIND_COMPLETE);
RNA_def_property_ui_text(prop, "Complete Matches Only", "Only use complete matches of search string");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
-
+
+ prop = RNA_def_property(srna, "use_sort_alpha", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SO_SKIP_SORT_ALPHA);
+ RNA_def_property_ui_text(prop, "Sort Alphabetically", "");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
+
prop = RNA_def_property(srna, "show_restrict_columns", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SO_HIDE_RESTRICTCOLS);
RNA_def_property_ui_text(prop, "Show Restriction Columns", "Show column");
@@ -1701,7 +1971,22 @@ static void rna_def_background_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Size", "Scaling factor for the background image");
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
+ prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER);
+ RNA_def_property_float_sdna(prop, NULL, "rotation");
+ RNA_def_property_ui_text(prop, "Rotation", "Rotation for the background image");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "use_flip_x", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_BGPIC_FLIP_X);
+ RNA_def_property_ui_text(prop, "Flip Horizontally", "Flip the background image horizontally");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "use_flip_y", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_BGPIC_FLIP_Y);
+ RNA_def_property_ui_text(prop, "Flip Vertically", "Flip the background image vertically");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "opacity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "blend");
RNA_def_property_float_funcs(prop, "rna_BackgroundImage_opacity_get", "rna_BackgroundImage_opacity_set", NULL);
@@ -1839,7 +2124,6 @@ static void rna_def_space_view3d(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
-
srna = RNA_def_struct(brna, "SpaceView3D", "Space");
RNA_def_struct_sdna(srna, "View3D");
RNA_def_struct_ui_text(srna, "3D View Space", "3D View space data");
@@ -2041,6 +2325,11 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Only Render", "Display only objects which will be rendered");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ prop = RNA_def_property(srna, "show_world", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_SHOW_WORLD);
+ RNA_def_property_ui_text(prop, "World Background", "Display world colors in the background");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
prop = RNA_def_property(srna, "use_occlude_geometry", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_ZBUF_SELECT);
RNA_def_property_ui_text(prop, "Occlude Geometry", "Limit selection to visible (clipped with depth buffer)");
@@ -2176,6 +2465,10 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Matcap", "Image to use for Material Capture, active objects only");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_matcap_update");
+ prop = RNA_def_property(srna, "fx_settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(prop, "FX Options", "Options used for real time compositing");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
/* region */
srna = RNA_def_struct(brna, "RegionView3D", NULL);
@@ -2201,13 +2494,20 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "persmat");
RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* XXX: for now, it's too risky for users to do this */
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
- RNA_def_property_ui_text(prop, "Perspective Matrix", "Current perspective matrix of the 3D region");
+ RNA_def_property_ui_text(prop, "Perspective Matrix",
+ "Current perspective matrix (``window_matrix * view_matrix``)");
+
+ prop = RNA_def_property(srna, "window_matrix", PROP_FLOAT, PROP_MATRIX);
+ RNA_def_property_float_sdna(prop, NULL, "winmat");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
+ RNA_def_property_ui_text(prop, "Window Matrix", "Current window matrix");
prop = RNA_def_property(srna, "view_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "viewmat");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_float_funcs(prop, NULL, "rna_RegionView3D_view_matrix_set", NULL);
- RNA_def_property_ui_text(prop, "View Matrix", "Current view matrix of the 3D region");
+ RNA_def_property_ui_text(prop, "View Matrix", "Current view matrix");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "view_perspective", PROP_ENUM, PROP_NONE);
@@ -2355,6 +2655,7 @@ static void rna_def_space_image(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "scopes");
RNA_def_property_struct_type(prop, "Scopes");
RNA_def_property_ui_text(prop, "Scopes", "Scopes to visualize image statistics");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, "rna_SpaceImageEditor_scopes_update");
prop = RNA_def_property(srna, "use_image_pin", PROP_BOOLEAN, PROP_NONE);
@@ -2425,8 +2726,8 @@ static void rna_def_space_image(BlenderRNA *brna)
/* grease pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
- RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "GreasePencil");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
@@ -2509,6 +2810,16 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem waveform_type_draw_items[] = {
+ {SEQ_NO_WAVEFORMS, "NO_WAVEFORMS", 0, "Waveforms Off",
+ "No waveforms drawn for any sound strips"},
+ {SEQ_ALL_WAVEFORMS, "ALL_WAVEFORMS", 0, "Waveforms On",
+ "Waveforms drawn for all sound strips"},
+ {0, "DEFAULT_WAVEFORMS", 0, "Use Strip Option",
+ "Waveforms drawn according to strip setting"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "SpaceSequenceEditor", "Space");
RNA_def_struct_sdna(srna, "SpaceSeq");
RNA_def_struct_ui_text(srna, "Space Sequence Editor", "Sequence editor space data");
@@ -2549,11 +2860,16 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Separate Colors", "Separate color channels in preview");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
- prop = RNA_def_property(srna, "show_safe_margin", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_DRAW_SAFE_MARGINS);
- RNA_def_property_ui_text(prop, "Safe Margin", "Draw title safe margins in preview");
+ prop = RNA_def_property(srna, "show_safe_areas", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_SAFE_MARGINS);
+ RNA_def_property_ui_text(prop, "Safe Areas", "Show TV title safe and action safe areas in preview");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
-
+
+ prop = RNA_def_property(srna, "show_safe_center", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_SAFE_CENTER);
+ RNA_def_property_ui_text(prop, "Center-Cut Safe Areas", "Show safe areas to fit content in a different aspect ratio");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+
prop = RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SEQ_DRAWFRAMES);
RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
@@ -2578,6 +2894,12 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Draw Channels", "Channels of the preview to draw");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+ prop = RNA_def_property(srna, "waveform_draw_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, waveform_type_draw_items);
+ RNA_def_property_ui_text(prop, "Waveform Drawing", "How Waveforms are drawn");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+
prop = RNA_def_property(srna, "draw_overexposed", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "zebra");
RNA_def_property_ui_text(prop, "Show Overexposed", "Show overexposed areas with zebra stripes");
@@ -2594,8 +2916,8 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
/* grease pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
- RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "GreasePencil");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
@@ -2604,6 +2926,16 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
RNA_def_property_enum_items(prop, overlay_type_items);
RNA_def_property_ui_text(prop, "Overlay Type", "Overlay draw type");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+
+ prop = RNA_def_property(srna, "show_backdrop", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "draw_flag", SEQ_DRAW_BACKDROP);
+ RNA_def_property_ui_text(prop, "Use Backdrop", "Display result under strips");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+
+ prop = RNA_def_property(srna, "show_strip_offset", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "draw_flag", SEQ_DRAW_OFFSET_EXT);
+ RNA_def_property_ui_text(prop, "Show Offsets", "Display strip in/out offsets");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
}
static void rna_def_space_text(BlenderRNA *brna)
@@ -2716,6 +3048,8 @@ static void rna_def_space_text(BlenderRNA *brna)
RNA_def_property_string_sdna(prop, NULL, "replacestr");
RNA_def_property_ui_text(prop, "Replace Text", "Text to replace selected text with using the replace tool");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TEXT, NULL);
+
+ RNA_api_space_text(srna);
}
static void rna_def_space_dopesheet(BlenderRNA *brna)
@@ -2780,7 +3114,8 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_group_colors", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SACTION_NODRAWGCOLORS);
RNA_def_property_ui_text(prop, "Show Group Colors",
- "Draw groups and channels with colors matching their corresponding groups");
+ "Draw groups and channels with colors matching their corresponding groups "
+ "(pose bones only currently)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
/* editing */
@@ -2935,14 +3270,12 @@ static void rna_def_space_graph(BlenderRNA *brna)
RNA_def_property_enum_items(prop, autosnap_items);
RNA_def_property_ui_text(prop, "Auto Snap", "Automatic time snapping settings for transformations");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
/* readonly state info */
prop = RNA_def_property(srna, "has_ghost_curves", PROP_BOOLEAN, PROP_NONE);
- /* XXX: hack to make this compile, since this property doesn't actually exist*/
- RNA_def_property_boolean_sdna(prop, NULL, "flag", 0);
RNA_def_property_boolean_funcs(prop, "rna_SpaceGraphEditor_has_ghost_curves_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Has Ghost Curves", "Graph Editor instance has some ghost curves stored");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
/* nromalize curves */
prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE);
@@ -3078,7 +3411,6 @@ static void rna_def_console_line(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ConsoleLine", NULL);
RNA_def_struct_ui_text(srna, "Console Input", "Input line for the interactive console");
- /* XXX using non-inited "prop", uh? RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CONSOLE, NULL); */
prop = RNA_def_property(srna, "body", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_ConsoleLine_body_get", "rna_ConsoleLine_body_length",
@@ -3203,55 +3535,55 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "use_filter_image", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "filter", IMAGEFILE);
+ RNA_def_property_boolean_sdna(prop, NULL, "filter", FILE_TYPE_IMAGE);
RNA_def_property_ui_text(prop, "Filter Images", "Show image files");
RNA_def_property_ui_icon(prop, ICON_FILE_IMAGE, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "use_filter_blender", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "filter", BLENDERFILE);
+ RNA_def_property_boolean_sdna(prop, NULL, "filter", FILE_TYPE_BLENDER);
RNA_def_property_ui_text(prop, "Filter Blender", "Show .blend files");
RNA_def_property_ui_icon(prop, ICON_FILE_BLEND, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "use_filter_backup", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "filter", BLENDERFILE_BACKUP);
+ RNA_def_property_boolean_sdna(prop, NULL, "filter", FILE_TYPE_BLENDER_BACKUP);
RNA_def_property_ui_text(prop, "Filter BlenderBackup files", "Show .blend1, .blend2, etc. files");
RNA_def_property_ui_icon(prop, ICON_FILE_BACKUP, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "use_filter_movie", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "filter", MOVIEFILE);
+ RNA_def_property_boolean_sdna(prop, NULL, "filter", FILE_TYPE_MOVIE);
RNA_def_property_ui_text(prop, "Filter Movies", "Show movie files");
RNA_def_property_ui_icon(prop, ICON_FILE_MOVIE, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "use_filter_script", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "filter", PYSCRIPTFILE);
+ RNA_def_property_boolean_sdna(prop, NULL, "filter", FILE_TYPE_PYSCRIPT);
RNA_def_property_ui_text(prop, "Filter Script", "Show script files");
RNA_def_property_ui_icon(prop, ICON_FILE_SCRIPT, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "use_filter_font", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "filter", FTFONTFILE);
+ RNA_def_property_boolean_sdna(prop, NULL, "filter", FILE_TYPE_FTFONT);
RNA_def_property_ui_text(prop, "Filter Fonts", "Show font files");
RNA_def_property_ui_icon(prop, ICON_FILE_FONT, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "use_filter_sound", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "filter", SOUNDFILE);
+ RNA_def_property_boolean_sdna(prop, NULL, "filter", FILE_TYPE_SOUND);
RNA_def_property_ui_text(prop, "Filter Sound", "Show sound files");
RNA_def_property_ui_icon(prop, ICON_FILE_SOUND, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "use_filter_text", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "filter", TEXTFILE);
+ RNA_def_property_boolean_sdna(prop, NULL, "filter", FILE_TYPE_TEXT);
RNA_def_property_ui_text(prop, "Filter Text", "Show text files");
RNA_def_property_ui_icon(prop, ICON_FILE_TEXT, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "use_filter_folder", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "filter", FOLDERFILE);
+ RNA_def_property_boolean_sdna(prop, NULL, "filter", FILE_TYPE_FOLDER);
RNA_def_property_ui_text(prop, "Filter Folder", "Show folders");
RNA_def_property_ui_icon(prop, ICON_FILE_FOLDER, 0);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
@@ -3261,6 +3593,47 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Extension Filter", "");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
+ prop = RNA_def_property(srna, "filter_search", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "filter_search");
+ RNA_def_property_ui_text(prop, "Name Filter", "Filter by name, supports '*' wildcard");
+ RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
+}
+
+static void rna_def_filemenu_entry(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "FileBrowserFSMenuEntry", NULL);
+ RNA_def_struct_sdna(srna, "FSMenuEntry");
+ RNA_def_struct_ui_text(srna, "File Select Parameters", "File Select Parameters");
+
+ prop = RNA_def_property(srna, "path", PROP_STRING, PROP_FILEPATH);
+ RNA_def_property_string_sdna(prop, NULL, "path");
+ RNA_def_property_string_funcs(prop, "rna_FileBrowser_FSMenuEntry_path_get",
+ "rna_FileBrowser_FSMenuEntry_path_length",
+ "rna_FileBrowser_FSMenuEntry_path_set");
+ RNA_def_property_ui_text(prop, "Path", "");
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "name");
+ RNA_def_property_string_funcs(prop, "rna_FileBrowser_FSMenuEntry_name_get",
+ "rna_FileBrowser_FSMenuEntry_name_length",
+ "rna_FileBrowser_FSMenuEntry_name_set");
+ RNA_def_property_editable_func(prop, "rna_FileBrowser_FSMenuEntry_name_get_editable");
+ RNA_def_property_ui_text(prop, "Name", "");
+ RNA_def_struct_name_property(srna, prop);
+
+ prop = RNA_def_property(srna, "use_save", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "save", 1);
+ RNA_def_property_ui_text(prop, "Save", "Whether this path is saved in bookmarks, or generated from OS");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "is_valid", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "valid", 1);
+ RNA_def_property_ui_text(prop, "Valid", "Whether this path is currently reachable");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
}
static void rna_def_space_filebrowser(BlenderRNA *brna)
@@ -3285,6 +3658,67 @@ static void rna_def_space_filebrowser(BlenderRNA *brna)
prop = RNA_def_property(srna, "operator", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "op");
RNA_def_property_ui_text(prop, "Active Operator", "");
+
+ /* bookmarks, recent files etc. */
+ prop = RNA_def_collection(srna, "system_folders", "FileBrowserFSMenuEntry", "System Folders",
+ "System's folders (usually root, available hard drives, etc)");
+ RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuSystem_data_begin", "rna_FileBrowser_FSMenu_next",
+ "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get",
+ "rna_FileBrowser_FSMenuSystem_data_length", NULL, NULL, NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_int(srna, "system_folders_active", -1, -1, INT_MAX, "Active System Folder",
+ "Index of active system folder (-1 if none)", -1, INT_MAX);
+ RNA_def_property_int_sdna(prop, NULL, "systemnr");
+ RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuSystem_active_get",
+ "rna_FileBrowser_FSMenuSystem_active_set", "rna_FileBrowser_FSMenuSystem_active_range");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update");
+
+ prop = RNA_def_collection(srna, "system_bookmarks", "FileBrowserFSMenuEntry", "System Bookmarks",
+ "System's bookmarks");
+ RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuSystemBookmark_data_begin", "rna_FileBrowser_FSMenu_next",
+ "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get",
+ "rna_FileBrowser_FSMenuSystemBookmark_data_length", NULL, NULL, NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_int(srna, "system_bookmarks_active", -1, -1, INT_MAX, "Active System Bookmark",
+ "Index of active system bookmark (-1 if none)", -1, INT_MAX);
+ RNA_def_property_int_sdna(prop, NULL, "system_bookmarknr");
+ RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuSystemBookmark_active_get",
+ "rna_FileBrowser_FSMenuSystemBookmark_active_set", "rna_FileBrowser_FSMenuSystemBookmark_active_range");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update");
+
+ prop = RNA_def_collection(srna, "bookmarks", "FileBrowserFSMenuEntry", "Bookmarks",
+ "User's bookmarks");
+ RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuBookmark_data_begin", "rna_FileBrowser_FSMenu_next",
+ "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get",
+ "rna_FileBrowser_FSMenuBookmark_data_length", NULL, NULL, NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_int(srna, "bookmarks_active", -1, -1, INT_MAX, "Active Bookmark",
+ "Index of active bookmark (-1 if none)", -1, INT_MAX);
+ RNA_def_property_int_sdna(prop, NULL, "bookmarknr");
+ RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuBookmark_active_get",
+ "rna_FileBrowser_FSMenuBookmark_active_set", "rna_FileBrowser_FSMenuBookmark_active_range");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update");
+
+ prop = RNA_def_collection(srna, "recent_folders", "FileBrowserFSMenuEntry", "Recent Folders",
+ "");
+ RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuRecent_data_begin", "rna_FileBrowser_FSMenu_next",
+ "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get",
+ "rna_FileBrowser_FSMenuRecent_data_length", NULL, NULL, NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_int(srna, "recent_folders_active", -1, -1, INT_MAX, "Active Recent Folder",
+ "Index of active recent folder (-1 if none)", -1, INT_MAX);
+ RNA_def_property_int_sdna(prop, NULL, "recentnr");
+ RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuRecent_active_get",
+ "rna_FileBrowser_FSMenuRecent_active_set", "rna_FileBrowser_FSMenuRecent_active_range");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update");
}
static void rna_def_space_info(BlenderRNA *brna)
@@ -3345,6 +3779,7 @@ static void rna_def_space_userpref(BlenderRNA *brna)
prop = RNA_def_property(srna, "filter_text", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "filter");
+ RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
RNA_def_property_ui_text(prop, "Filter", "Search term for filtering in the UI");
}
@@ -3887,6 +4322,7 @@ void RNA_def_space(BlenderRNA *brna)
rna_def_space_sequencer(brna);
rna_def_space_text(brna);
rna_def_fileselect_params(brna);
+ rna_def_filemenu_entry(brna);
rna_def_space_filebrowser(brna);
rna_def_space_outliner(brna);
rna_def_background_image(brna);
diff --git a/source/blender/makesrna/intern/rna_space_api.c b/source/blender/makesrna/intern/rna_space_api.c
index aed77378241..3cfbd798ad6 100644
--- a/source/blender/makesrna/intern/rna_space_api.c
+++ b/source/blender/makesrna/intern/rna_space_api.c
@@ -31,6 +31,8 @@
#ifdef RNA_RUNTIME
+#include "ED_text.h"
+
static void rna_RegionView3D_update(ID *id, RegionView3D *rv3d)
{
bScreen *sc = (bScreen *)id;
@@ -49,6 +51,19 @@ static void rna_RegionView3D_update(ID *id, RegionView3D *rv3d)
}
}
+static void rna_SpaceTextEditor_region_location_from_cursor(
+ ID *id, SpaceText *st,
+ int line, int column, int r_pixel_pos[2])
+{
+ bScreen *sc = (bScreen *)id;
+ ScrArea *sa = BKE_screen_find_area_from_space(sc, (SpaceLink *)st);
+ if (sa) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ const int cursor_co[2] = {line, column};
+ ED_text_region_location_from_cursor(st, ar, cursor_co, r_pixel_pos);
+ }
+}
+
#else
void RNA_api_region_view3d(StructRNA *srna)
@@ -74,4 +89,20 @@ void RNA_api_space_node(StructRNA *srna)
RNA_def_property_flag(parm, PROP_REQUIRED);
}
+void RNA_api_space_text(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func = RNA_def_function(srna, "region_location_from_cursor", "rna_SpaceTextEditor_region_location_from_cursor");
+ RNA_def_function_ui_description(func, "Retrieve the region position from the given line and character position");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ parm = RNA_def_int(func, "line", 0, INT_MIN, INT_MAX, "Line", "Line index", 0, INT_MAX);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_int(func, "column", 0, INT_MIN, INT_MAX, "Column", "Column index", 0, INT_MAX);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm = RNA_def_int_array(func, "result", 2, NULL, -1, INT_MAX, "", "Region coordinates", -1, INT_MAX);
+ RNA_def_function_output(func, parm);
+}
+
#endif
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index f098a659671..c1882e7767d 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -119,6 +119,7 @@ static EnumPropertyItem blend_type_items[] = {
#include "BKE_main.h"
#include "ED_node.h"
+#include "ED_render.h"
static StructRNA *rna_Texture_refine(struct PointerRNA *ptr)
{
@@ -439,13 +440,13 @@ static void rna_ImageTexture_mipmap_set(PointerRNA *ptr, int value)
else tex->imaflag &= ~TEX_MIPMAP;
}
-static void rna_Envmap_source_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_Envmap_update_generic(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Tex *tex = ptr->id.data;
-
- if (tex->env)
+ if (tex->env) {
+ ED_preview_kill_jobs(bmain->wm.first, bmain);
BKE_free_envmapdata(tex->env);
-
+ }
rna_Texture_update(bmain, scene, ptr);
}
@@ -803,7 +804,7 @@ static void rna_def_environment_map(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "stype");
RNA_def_property_enum_items(prop, prop_source_items);
RNA_def_property_ui_text(prop, "Source", "");
- RNA_def_property_update(prop, 0, "rna_Envmap_source_update");
+ RNA_def_property_update(prop, 0, "rna_Envmap_update_generic");
prop = RNA_def_property(srna, "viewpoint_object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "object");
@@ -1391,7 +1392,7 @@ static void rna_def_texture_environment_map(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "Image");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Image", "Source image file to read the environment map from");
- RNA_def_property_update(prop, 0, "rna_Texture_update");
+ RNA_def_property_update(prop, 0, "rna_Envmap_update_generic");
prop = RNA_def_property(srna, "image_user", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "iuser");
@@ -1848,6 +1849,7 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna)
{TEX_VD_IMAGE_SEQUENCE, "IMAGE_SEQUENCE", 0, "Image Sequence",
"Generate voxels from a sequence of image slices"},
{TEX_VD_SMOKE, "SMOKE", 0, "Smoke", "Render voxels from a Blender smoke simulation"},
+ {TEX_VD_HAIR, "HAIR", 0, "Hair", "Render voxels from a Blender hair simulation"},
{0, NULL, 0, NULL, NULL}
};
@@ -1866,6 +1868,14 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem hair_type_items[] = {
+ {TEX_VD_HAIRDENSITY, "HAIRDENSITY", 0, "Density", "Use hair density as texture data"},
+ {TEX_VD_HAIRRESTDENSITY, "HAIRRESTDENSITY", 0, "Rest Density", "Use hair rest density as texture data"},
+ {TEX_VD_HAIRVELOCITY, "HAIRVELOCITY", 0, "Velocity", "Use hair velocity as texture data"},
+ {TEX_VD_HAIRENERGY, "HAIRENERGY", 0, "Energy", "Use potential hair energy as texture data"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "VoxelData", NULL);
RNA_def_struct_sdna(srna, "VoxelData");
RNA_def_struct_ui_text(srna, "VoxelData", "Voxel data settings");
@@ -1883,6 +1893,12 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Source", "Simulation value to be used as a texture");
RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update");
+ prop = RNA_def_property(srna, "hair_data_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "hair_type");
+ RNA_def_property_enum_items(prop, hair_type_items);
+ RNA_def_property_ui_text(prop, "Source", "Simulation value to be used as a texture");
+ RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update");
+
prop = RNA_def_property(srna, "extension", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "extend");
RNA_def_property_enum_items(prop, voxeldata_extension);
diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c
index 695a3e0548e..acf8333d6dc 100644
--- a/source/blender/makesrna/intern/rna_texture_api.c
+++ b/source/blender/makesrna/intern/rna_texture_api.c
@@ -74,7 +74,7 @@ static void texture_evaluate(struct Tex *tex, float value[3], float r_color[4])
TexResult texres = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
/* TODO(sergey): always use color management now. */
- multitex_ext(tex, value, NULL, NULL, 1, &texres, NULL, true);
+ multitex_ext(tex, value, NULL, NULL, 1, &texres, NULL, true, false);
r_color[0] = texres.tr;
r_color[1] = texres.tg;
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 899da62d9d3..5a70d47a19a 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -1435,8 +1435,8 @@ static void rna_def_trackingTrack(BlenderRNA *brna)
/* grease pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
- RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "GreasePencil");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this track");
RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 92c5530202b..fde43abe9fb 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -221,7 +221,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
/* check if we have registered this panel type before, and remove it */
for (pt = art->paneltypes.first; pt; pt = pt->next) {
- if (strcmp(pt->idname, dummypt.idname) == 0) {
+ if (STREQ(pt->idname, dummypt.idname)) {
if (pt->ext.srna)
rna_Panel_unregister(bmain, pt->ext.srna);
else
@@ -587,7 +587,7 @@ static StructRNA *rna_Header_register(Main *bmain, ReportList *reports, void *da
/* check if we have registered this header type before, and remove it */
for (ht = art->headertypes.first; ht; ht = ht->next) {
- if (strcmp(ht->idname, dummyht.idname) == 0) {
+ if (STREQ(ht->idname, dummyht.idname)) {
if (ht->ext.srna)
rna_Header_unregister(bmain, ht->ext.srna);
break;
@@ -1062,6 +1062,7 @@ static void rna_def_uilist(BlenderRNA *brna)
prop = RNA_def_property(srna, "filter_name", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "filter_byname");
+ RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
RNA_def_property_ui_text(prop, "Filter by Name", "Only show items matching this name (use '*' as wildcard)");
prop = RNA_def_property(srna, "use_filter_invert", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index b13bdedaffd..fea8b630af6 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -137,9 +137,7 @@ static void rna_uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, NULL, prop, translate);
-
- /* XXX This will search property again :( */
- uiItemMenuEnumR(layout, ptr, propname, name, icon);
+ uiItemMenuEnumR_prop(layout, ptr, prop, name, icon);
}
static void rna_uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *value,
@@ -178,7 +176,7 @@ static void rna_uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const c
}
static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *name, const char *text_ctxt,
- int translate, int icon, int emboss)
+ int translate, int icon, int emboss, int icon_value)
{
wmOperatorType *ot;
int flag;
@@ -192,6 +190,10 @@ static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char *
/* Get translated name (label). */
name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate);
+ if (icon_value && !icon) {
+ icon = icon_value;
+ }
+
flag = UI_ITEM_O_RETURN_PROPS;
flag |= (emboss) ? 0 : UI_ITEM_R_NO_BG;
@@ -293,7 +295,7 @@ static const char *rna_ui_get_enum_name(bContext *C, PointerRNA *ptr, const char
if (items) {
for (item = items; item->identifier; item++) {
- if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
+ if (item->identifier[0] && STREQ(item->identifier, identifier)) {
name = item->name;
break;
}
@@ -324,7 +326,7 @@ static const char *rna_ui_get_enum_description(bContext *C, PointerRNA *ptr, con
if (items) {
for (item = items; item->identifier; item++) {
- if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
+ if (item->identifier[0] && STREQ(item->identifier, identifier)) {
desc = item->description;
break;
}
@@ -354,7 +356,7 @@ static int rna_ui_get_enum_icon(bContext *C, PointerRNA *ptr, const char *propna
if (items) {
for (item = items; item->identifier; item++) {
- if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
+ if (item->identifier[0] && STREQ(item->identifier, identifier)) {
icon = item->icon;
break;
}
@@ -551,6 +553,10 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "operator", "rna_uiItemO");
api_ui_item_op_common(func);
RNA_def_boolean(func, "emboss", true, "", "Draw the button itself, just the icon/text");
+ parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_ui_text(parm, "Icon Value",
+ "Override automatic icon of the item "
+ "(use it e.g. with custom material icons returned by icon()...)");
parm = RNA_def_pointer(func, "properties", "OperatorProperties", "",
"Operator properties to fill in, return when 'properties' is set to true");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR);
@@ -676,14 +682,14 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "template_modifier", "uiTemplateModifier");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
- RNA_def_function_ui_description(func, "Layout . Generates the UI layout for modifiers");
+ RNA_def_function_ui_description(func, "Generates the UI layout for modifiers");
parm = RNA_def_pointer(func, "data", "Modifier", "", "Modifier data");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "template_constraint", "uiTemplateConstraint");
- RNA_def_function_ui_description(func, "Layout . Generates the UI layout for constraints");
+ RNA_def_function_ui_description(func, "Generates the UI layout for constraints");
parm = RNA_def_pointer(func, "data", "Constraint", "", "Constraint data");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL);
parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in");
@@ -820,6 +826,8 @@ void RNA_api_ui_layout(StructRNA *srna)
parm = RNA_def_string(func, "active_propname", NULL, 0, "",
"Identifier of the integer property in active_data, index of the active item");
RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_string(func, "item_dyntip_propname", NULL, 0, "",
+ "Identifier of a string property in items, to use as tooltip content");
RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Default and minimum number of rows to display", 0, INT_MAX);
RNA_def_int(func, "maxrows", 5, 0, INT_MAX, "", "Default maximum number of rows to display", 0, INT_MAX);
RNA_def_enum(func, "type", uilist_layout_type_items, UILST_LAYOUT_DEFAULT, "Type", "Type of layout to use");
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 1bad9570893..e60af76851e 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -35,6 +35,8 @@
#include "BLI_utildefines.h"
+#include "BKE_appdir.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_sound.h"
#include "BKE_addon.h"
@@ -48,6 +50,7 @@
#include "WM_types.h"
#include "BLF_translation.h"
+#include "GPU_buffers.h"
#ifdef WITH_CYCLES
static EnumPropertyItem compute_device_type_items[] = {
@@ -104,6 +107,10 @@ EnumPropertyItem navigation_mode_items[] = {
#include "BKE_addon.h"
+#ifdef WITH_SDL_DYNLOAD
+# include "sdlew.h"
+#endif
+
static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -137,6 +144,15 @@ static void rna_userdef_language_update(Main *UNUSED(bmain), Scene *UNUSED(scene
UI_reinit_font();
}
+static void rna_userdef_vbo_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
+{
+ Object *ob;
+
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ GPU_drawobject_free(ob->derivedFinal);
+ }
+}
+
static void rna_userdef_show_manipulator_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
UserDef *userdef = (UserDef *)ptr->data;
@@ -209,6 +225,14 @@ static void rna_userdef_gl_use_16bit_textures(Main *bmain, Scene *scene, Pointer
rna_userdef_update(bmain, scene, ptr);
}
+static void rna_userdef_undo_steps_set(PointerRNA *ptr, int value)
+{
+ UserDef *userdef = (UserDef *)ptr->data;
+
+ /* Do not allow 1 undo steps, useless and breaks undo/redo process (see T42531). */
+ userdef->undosteps = (value == 1) ? 2 : value;
+}
+
static void rna_userdef_select_mouse_set(PointerRNA *ptr, int value)
{
UserDef *userdef = (UserDef *)ptr->data;
@@ -402,7 +426,7 @@ static void rna_userdef_pathcompare_remove(ReportList *reports, PointerRNA *path
static void rna_userdef_temp_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
- BLI_temp_dir_init(U.tempdir);
+ BKE_tempdir_init(U.tempdir);
}
static void rna_userdef_text_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
@@ -502,37 +526,38 @@ static EnumPropertyItem *rna_userdef_compute_device_itemf(bContext *UNUSED(C), P
static EnumPropertyItem *rna_userdef_audio_device_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop), bool *r_free)
{
-#ifdef WITH_JACK
- int jack_supported = sound_is_jack_supported();
-
- if (jack_supported) {
- return audio_device_items;
- }
- else {
- int index = 0;
- int totitem = 0;
- EnumPropertyItem *item = NULL;
+ int index = 0;
+ int totitem = 0;
+ EnumPropertyItem *item = NULL;
- /* NONE */
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
+ /* NONE */
+ RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
#ifdef WITH_SDL
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
+# ifdef WITH_SDL_DYNLOAD
+ if (sdlewInit() == SDLEW_SUCCESS)
+# endif
+ {
+ RNA_enum_item_add(&item, &totitem, &audio_device_items[index]);
+ }
+ index++;
#endif
#ifdef WITH_OPENAL
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
+ RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
#endif
- RNA_enum_item_end(&item, &totitem);
- *r_free = true;
-
- return item;
+#ifdef WITH_JACK
+ if (sound_is_jack_supported()) {
+ RNA_enum_item_add(&item, &totitem, &audio_device_items[index]);
}
-#else
- (void)r_free;
- return audio_device_items;
+ index++;
#endif
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
}
#ifdef WITH_INTERNATIONAL
@@ -1018,6 +1043,12 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Icon Alpha", "Transparency of icons in the interface, to reduce contrast");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+ prop = RNA_def_property(srna, "widget_emboss", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "widget_emboss");
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Widget Emboss", "Color of the 1px shadow line underlying widgets");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
/* axis */
prop = RNA_def_property(srna, "axis_x", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "xaxis");
@@ -1457,6 +1488,26 @@ static void rna_def_userdef_theme_spaces_curves(StructRNA *srna, bool incl_nurbs
}
}
+static void rna_def_userdef_theme_spaces_gpencil(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "gp_vertex", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Grease Pencil Vertex", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "gp_vertex_select", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Grease Pencil Vertex Select", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "gp_vertex_size", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 1, 10);
+ RNA_def_property_ui_text(prop, "Grease Pencil Vertex Size", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+}
+
static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1485,6 +1536,8 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Wire Edit", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ rna_def_userdef_theme_spaces_gpencil(srna);
prop = RNA_def_property(srna, "lamp", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
@@ -1629,6 +1682,11 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Skin Root", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+ prop = RNA_def_property(srna, "clipping_border_3d", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Clipping Border", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
rna_def_userdef_theme_spaces_paint_curves(srna);
}
@@ -2015,6 +2073,8 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna)
rna_def_userdef_theme_spaces_main(srna);
rna_def_userdef_theme_spaces_list_main(srna);
+
+ rna_def_userdef_theme_spaces_gpencil(srna);
prop = RNA_def_property(srna, "node_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "select");
@@ -2219,6 +2279,18 @@ static void rna_def_userdef_theme_space_time(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "time_keyframe", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "time_keyframe");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Keyframe", "Base color for keyframe indicator lines");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "time_grease_pencil", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "time_gp_keyframe");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Grease Pencil", "Color of Grease Pencil keyframes");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_space_image(BlenderRNA *brna)
@@ -2234,8 +2306,10 @@ static void rna_def_userdef_theme_space_image(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Theme Image Editor", "Theme settings for the Image Editor");
rna_def_userdef_theme_spaces_main(srna);
+ rna_def_userdef_theme_spaces_gpencil(srna);
rna_def_userdef_theme_spaces_vertex(srna);
rna_def_userdef_theme_spaces_face(srna);
+
prop = RNA_def_property(srna, "editmesh_active", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
@@ -2330,6 +2404,7 @@ static void rna_def_userdef_theme_space_seq(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Theme Sequence Editor", "Theme settings for the Sequence Editor");
rna_def_userdef_theme_spaces_main(srna);
+ rna_def_userdef_theme_spaces_gpencil(srna);
prop = RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
@@ -2741,6 +2816,8 @@ static void rna_def_userdef_theme_space_clip(BlenderRNA *brna)
rna_def_userdef_theme_spaces_main(srna);
rna_def_userdef_theme_spaces_list_main(srna);
+
+ rna_def_userdef_theme_spaces_gpencil(srna);
prop = RNA_def_property(srna, "marker_outline", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "marker_outline");
@@ -3259,7 +3336,12 @@ static void rna_def_userdef_view(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_quit_dialog", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_QUIT_PROMPT);
RNA_def_property_ui_text(prop, "Prompt Quit",
- "Asks for confirmation when quitting through the window close button");
+ "Ask for confirmation when quitting through the window close button");
+
+ prop = RNA_def_property(srna, "use_gl_warn_support", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag2", USER_OPENGL_NO_WARN_SUPPORT);
+ RNA_def_property_ui_text(prop, "Warn On Deprecated OpenGL",
+ "Pop up a warning when an old OpenGL version is detected");
/* Toolbox click-hold delay */
prop = RNA_def_property(srna, "open_left_mouse_delay", PROP_INT, PROP_NONE);
@@ -3458,7 +3540,8 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
/* Undo */
prop = RNA_def_property(srna, "undo_steps", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "undosteps");
- RNA_def_property_range(prop, 0, 64);
+ RNA_def_property_range(prop, 0, 256);
+ RNA_def_property_int_funcs(prop, NULL, "rna_userdef_undo_steps_set", NULL);
RNA_def_property_ui_text(prop, "Undo Steps", "Number of undo steps available (smaller values conserve memory)");
prop = RNA_def_property(srna, "undo_memory_limit", PROP_INT, PROP_NONE);
@@ -3790,6 +3873,11 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Virtual Pixel Mode", "Modify the pixel size for hi-res devices");
RNA_def_property_update(prop, 0, "rna_userdef_virtual_pixel_update");
+ prop = RNA_def_property(srna, "pixel_size", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_float_sdna(prop, NULL, "pixelsize");
+ RNA_def_property_ui_text(prop, "Pixel Size", "");
+
prop = RNA_def_property(srna, "font_path_ui", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "font_path_ui");
RNA_def_property_ui_text(prop, "Interface Font", "Path to interface font");
@@ -3931,7 +4019,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "VBOs",
"Use Vertex Buffer Objects (or Vertex Arrays, if unsupported) for viewport rendering");
/* this isn't essential but nice to check if VBO draws any differently */
- RNA_def_property_update(prop, NC_WINDOW, NULL);
+ RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_vbo_update");
prop = RNA_def_property(srna, "anisotropic_filter", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "anisotropic_filter");
@@ -4428,18 +4516,18 @@ static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cpro
RNA_def_property_srna(cprop, "Addons");
srna = RNA_def_struct(brna, "Addons", NULL);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
- RNA_def_struct_ui_text(srna, "User Addons", "Collection of addons");
+ RNA_def_struct_ui_text(srna, "User Add-ons", "Collection of add-ons");
func = RNA_def_function(srna, "new", "rna_userdef_addon_new");
RNA_def_function_flag(func, FUNC_NO_SELF);
- RNA_def_function_ui_description(func, "Add a new addon");
+ RNA_def_function_ui_description(func, "Add a new add-on");
/* return type */
parm = RNA_def_pointer(func, "addon", "Addon", "", "Addon datablock");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "remove", "rna_userdef_addon_remove");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_REPORTS);
- RNA_def_function_ui_description(func, "Remove addon");
+ RNA_def_function_ui_description(func, "Remove add-on");
parm = RNA_def_pointer(func, "addon", "Addon", "", "Addon to remove");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
@@ -4480,7 +4568,7 @@ void RNA_def_userdef(BlenderRNA *brna)
{USER_SECTION_INTERFACE, "INTERFACE", 0, "Interface", ""},
{USER_SECTION_EDIT, "EDITING", 0, "Editing", ""},
{USER_SECTION_INPUT, "INPUT", 0, "Input", ""},
- {USER_SECTION_ADDONS, "ADDONS", 0, "Addons", ""},
+ {USER_SECTION_ADDONS, "ADDONS", 0, "Add-ons", ""},
{USER_SECTION_THEME, "THEMES", 0, "Themes", ""},
{USER_SECTION_FILE, "FILES", 0, "File", ""},
{USER_SECTION_SYSTEM, "SYSTEM", 0, "System", ""},
diff --git a/source/blender/makesrna/intern/rna_vfont.c b/source/blender/makesrna/intern/rna_vfont.c
index f24f94282b6..0879f4d355d 100644
--- a/source/blender/makesrna/intern/rna_vfont.c
+++ b/source/blender/makesrna/intern/rna_vfont.c
@@ -84,6 +84,8 @@ void RNA_def_vfont(BlenderRNA *brna)
prop = RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "packedfile");
RNA_def_property_ui_text(prop, "Packed File", "");
+
+ RNA_api_vfont(srna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_vfont_api.c b/source/blender/makesrna/intern/rna_vfont_api.c
new file mode 100644
index 00000000000..d92e75daf0a
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_vfont_api.c
@@ -0,0 +1,73 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2015 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Kevin Dietrich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/makesrna/intern/rna_vfont_api.c
+ * \ingroup RNA
+ */
+
+#include "DNA_packedFile_types.h"
+
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
+#ifdef RNA_RUNTIME
+
+#include "BKE_packedFile.h"
+
+static void rna_VectorFont_pack(VFont *vfont, Main *bmain, ReportList *reports)
+{
+ vfont->packedfile = newPackedFile(reports, vfont->name, ID_BLEND_PATH(bmain, &vfont->id));
+}
+
+static void rna_VectorFont_unpack(VFont *vfont, ReportList *reports, int method)
+{
+ if (!vfont->packedfile) {
+ BKE_report(reports, RPT_ERROR, "Font not packed");
+ }
+ else {
+ /* reports its own error on failure */
+ unpackVFont(reports, vfont, method);
+ }
+}
+
+#else
+
+void RNA_api_vfont(StructRNA *srna)
+{
+ FunctionRNA *func;
+
+ func = RNA_def_function(srna, "pack", "rna_VectorFont_pack");
+ RNA_def_function_ui_description(func, "Pack the font into the current blend file");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN);
+
+ func = RNA_def_function(srna, "unpack", "rna_VectorFont_unpack");
+ RNA_def_function_ui_description(func, "Unpack the font to the samples filename");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_enum(func, "method", unpack_method_items, PF_USE_LOCAL, "method", "How to unpack");
+}
+
+#endif
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 7513a687978..6119bc968e6 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -429,6 +429,7 @@ EnumPropertyItem operator_return_items[] = {
{OPERATOR_FINISHED, "FINISHED", 0, "Finished", "When the operator is complete, operator exits"},
/* used as a flag */
{OPERATOR_PASS_THROUGH, "PASS_THROUGH", 0, "Pass Through", "Do nothing and pass the event on"},
+ {OPERATOR_INTERFACE, "INTERFACE", 0, "Interface", "Handled but not executed (popup menus)"},
{0, NULL, 0, NULL, NULL}
};
@@ -525,21 +526,21 @@ static PointerRNA rna_OperatorMacro_properties_get(PointerRNA *ptr)
static void rna_Event_ascii_get(PointerRNA *ptr, char *value)
{
- wmEvent *event = (wmEvent *)ptr->data;
+ const wmEvent *event = ptr->data;
value[0] = event->ascii;
value[1] = '\0';
}
static int rna_Event_ascii_length(PointerRNA *ptr)
{
- wmEvent *event = (wmEvent *)ptr->data;
+ const wmEvent *event = ptr->data;
return (event->ascii) ? 1 : 0;
}
static void rna_Event_unicode_get(PointerRNA *ptr, char *value)
{
/* utf8 buf isn't \0 terminated */
- wmEvent *event = (wmEvent *)ptr->data;
+ const wmEvent *event = ptr->data;
size_t len = 0;
if (event->utf8_buf[0]) {
@@ -555,7 +556,7 @@ static void rna_Event_unicode_get(PointerRNA *ptr, char *value)
static int rna_Event_unicode_length(PointerRNA *ptr)
{
- wmEvent *event = (wmEvent *)ptr->data;
+ const wmEvent *event = ptr->data;
if (event->utf8_buf[0]) {
/* invalid value is checked on assignment so we don't need to account for this */
return BLI_str_utf8_size(event->utf8_buf);
@@ -567,13 +568,13 @@ static int rna_Event_unicode_length(PointerRNA *ptr)
static float rna_Event_pressure_get(PointerRNA *ptr)
{
- wmEvent *event = ptr->data;
+ const wmEvent *event = ptr->data;
return WM_event_tablet_data(event, NULL, NULL);
}
static int rna_Event_is_tablet_get(PointerRNA *ptr)
{
- wmEvent *event = ptr->data;
+ const wmEvent *event = ptr->data;
return WM_event_is_tablet(event);
}
@@ -586,7 +587,7 @@ static void rna_Event_tilt_get(PointerRNA *ptr, float *values)
static PointerRNA rna_PopupMenu_layout_get(PointerRNA *ptr)
{
struct uiPopupMenu *pup = ptr->data;
- uiLayout *layout = uiPupMenuLayout(pup);
+ uiLayout *layout = UI_popup_menu_layout(pup);
PointerRNA rptr;
RNA_pointer_create(ptr->id.data, &RNA_UILayout, layout, &rptr);
@@ -597,7 +598,7 @@ static PointerRNA rna_PopupMenu_layout_get(PointerRNA *ptr)
static PointerRNA rna_PieMenu_layout_get(PointerRNA *ptr)
{
struct uiPieMenu *pie = ptr->data;
- uiLayout *layout = uiPieMenuLayout(pie);
+ uiLayout *layout = UI_pie_menu_layout(pie);
PointerRNA rptr;
RNA_pointer_create(ptr->id.data, &RNA_UILayout, layout, &rptr);
@@ -761,7 +762,7 @@ static EnumPropertyItem *rna_KeyMapItem_propvalue_itemf(bContext *C, PointerRNA
return keymap_propvalue_items; /* ERROR */
}
-static int rna_KeyMapItem_any_getf(PointerRNA *ptr)
+static int rna_KeyMapItem_any_get(PointerRNA *ptr)
{
wmKeyMapItem *kmi = (wmKeyMapItem *)ptr->data;
@@ -777,7 +778,7 @@ static int rna_KeyMapItem_any_getf(PointerRNA *ptr)
}
}
-static void rna_KeyMapItem_any_setf(PointerRNA *ptr, int value)
+static void rna_KeyMapItem_any_set(PointerRNA *ptr, int value)
{
wmKeyMapItem *kmi = (wmKeyMapItem *)ptr->data;
@@ -834,7 +835,7 @@ static void rna_wmKeyMapItem_idname_set(PointerRNA *ptr, const char *value)
WM_operator_bl_idname(idname, value);
- if (strcmp(idname, kmi->idname) != 0) {
+ if (!STREQ(idname, kmi->idname)) {
BLI_strncpy(kmi->idname, idname, sizeof(kmi->idname));
WM_keymap_properties_reset(kmi, NULL);
@@ -2027,7 +2028,7 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop = RNA_def_property(srna, "any", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_any_getf", "rna_KeyMapItem_any_setf");
+ RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_any_get", "rna_KeyMapItem_any_set");
RNA_def_property_ui_text(prop, "Any", "Any modifier keys pressed");
RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index ad638f2187c..e819d331124 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -298,7 +298,7 @@ static PointerRNA rna_PupMenuBegin(bContext *C, const char *title, int icon)
PointerRNA r_ptr;
void *data;
- data = (void *)uiPupMenuBegin(C, title, icon);
+ data = (void *)UI_popup_menu_begin(C, title, icon);
RNA_pointer_create(NULL, &RNA_UIPopupMenu, data, &r_ptr);
@@ -307,7 +307,7 @@ static PointerRNA rna_PupMenuBegin(bContext *C, const char *title, int icon)
static void rna_PupMenuEnd(bContext *C, PointerRNA *handle)
{
- uiPupMenuEnd(C, handle->data);
+ UI_popup_menu_end(C, handle->data);
}
/* pie menu wrapper */
@@ -316,7 +316,7 @@ static PointerRNA rna_PieMenuBegin(bContext *C, const char *title, int icon, Poi
PointerRNA r_ptr;
void *data;
- data = (void *)uiPieMenuBegin(C, title, icon, event->data);
+ data = (void *)UI_pie_menu_begin(C, title, icon, event->data);
RNA_pointer_create(NULL, &RNA_UIPieMenu, data, &r_ptr);
@@ -325,7 +325,7 @@ static PointerRNA rna_PieMenuBegin(bContext *C, const char *title, int icon, Poi
static void rna_PieMenuEnd(bContext *C, PointerRNA *handle)
{
- uiPieMenuEnd(C, handle->data);
+ UI_pie_menu_end(C, handle->data);
}
#else
@@ -462,7 +462,7 @@ void RNA_api_wm(StructRNA *srna)
rna_generic_op_invoke(func, WM_GEN_INVOKE_EVENT | WM_GEN_INVOKE_RETURN);
- /* wrap uiPupMenuBegin */
+ /* wrap UI_popup_menu_begin */
func = RNA_def_function(srna, "pupmenu_begin__internal", "rna_PupMenuBegin");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
parm = RNA_def_string(func, "title", NULL, 0, "", "");
@@ -474,7 +474,7 @@ void RNA_api_wm(StructRNA *srna)
RNA_def_property_flag(parm, PROP_RNAPTR | PROP_NEVER_NULL);
RNA_def_function_return(func, parm);
- /* wrap uiPupMenuEnd */
+ /* wrap UI_popup_menu_end */
func = RNA_def_function(srna, "pupmenu_end__internal", "rna_PupMenuEnd");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "menu", "UIPopupMenu", "", "");
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index f63350ea0ae..721cbaf21c7 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -89,7 +89,7 @@ static void rna_World_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR
World *wo = ptr->id.data;
DAG_id_tag_update(&wo->id, 0);
- WM_main_add_notifier(NC_WORLD, wo);
+ WM_main_add_notifier(NC_WORLD | ND_WORLD, wo);
}
static void rna_World_draw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 06e9f8f5b67..57e927fffed 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -52,6 +52,7 @@ set(SRC
intern/MOD_cloth.c
intern/MOD_collision.c
intern/MOD_curve.c
+ intern/MOD_datatransfer.c
intern/MOD_decimate.c
intern/MOD_displace.c
intern/MOD_dynamicpaint.c
@@ -72,6 +73,7 @@ set(SRC
intern/MOD_mirror.c
intern/MOD_multires.c
intern/MOD_none.c
+ intern/MOD_normal_edit.c
intern/MOD_ocean.c
intern/MOD_particleinstance.c
intern/MOD_particlesystem.c
diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h
index 9c7c21cc839..66e613be68a 100644
--- a/source/blender/modifiers/MOD_modifiertypes.h
+++ b/source/blender/modifiers/MOD_modifiertypes.h
@@ -81,6 +81,8 @@ extern ModifierTypeInfo modifierType_UVWarp;
extern ModifierTypeInfo modifierType_MeshCache;
extern ModifierTypeInfo modifierType_LaplacianDeform;
extern ModifierTypeInfo modifierType_Wireframe;
+extern ModifierTypeInfo modifierType_DataTransfer;
+extern ModifierTypeInfo modifierType_NormalEdit;
/* MOD_util.c */
void modifier_type_init(ModifierTypeInfo *types[]);
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index a4248df5ea1..52a47c3e041 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -100,6 +100,7 @@ static void foreachObjectLink(
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 40db49afef2..409d862addb 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -102,7 +102,9 @@ static void foreachObjectLink(
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Scene *UNUSED(scene), Object *UNUSED(ob), DagNode *obNode)
+ struct Main *UNUSED(bmain),
+ struct Scene *UNUSED(scene),
+ Object *UNUSED(ob), DagNode *obNode)
{
ArrayModifierData *amd = (ArrayModifierData *) md;
@@ -167,8 +169,8 @@ typedef struct SortVertsElem {
static int svert_sum_cmp(const void *e1, const void *e2)
{
- const SortVertsElem *sv1 = (SortVertsElem *)e1;
- const SortVertsElem *sv2 = (SortVertsElem *)e2;
+ const SortVertsElem *sv1 = e1;
+ const SortVertsElem *sv2 = e2;
if (sv1->sum_co > sv2->sum_co) return 1;
else if (sv1->sum_co < sv2->sum_co) return -1;
@@ -201,7 +203,7 @@ static void dm_mvert_map_doubles(
const float dist,
const bool with_follow)
{
- const float dist3 = (M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */
+ const float dist3 = ((float)M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */
int i_source, i_target, i_target_low_bound, target_end, source_end;
SortVertsElem *sorted_verts_target, *sorted_verts_source;
SortVertsElem *sve_source, *sve_target, *sve_target_low_bound;
@@ -323,8 +325,8 @@ static void dm_merge_transform(
/* needed for subsurf so arrays are allocated */
cap_dm->getVertArray(cap_dm);
cap_dm->getEdgeArray(cap_dm);
- cap_dm->getNumLoops(cap_dm);
- cap_dm->getNumPolys(cap_dm);
+ cap_dm->getLoopArray(cap_dm);
+ cap_dm->getPolyArray(cap_dm);
DM_copy_vert_data(cap_dm, result, 0, cap_verts_index, cap_nverts);
DM_copy_edge_data(cap_dm, result, 0, cap_edges_index, cap_nedges);
@@ -404,7 +406,7 @@ static DerivedMesh *arrayModifier_doArray(
int *full_doubles_map = NULL;
int tot_doubles;
- const bool use_merge = amd->flags & MOD_ARR_MERGE;
+ const bool use_merge = (amd->flags & MOD_ARR_MERGE) != 0;
const bool use_recalc_normals = (dm->dirty & DM_DIRTY_NORMALS) || use_merge;
const bool use_offset_ob = ((amd->offset_type & MOD_ARR_OFF_OBJ) && amd->offset_ob);
/* allow pole vertices to be used by many faces */
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 49c0c091dee..ee3bc7140a8 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -39,8 +39,6 @@
#include "BLI_utildefines.h"
-#include "BLF_translation.h"
-
#include "BKE_cdderivedmesh.h"
#include "BKE_modifier.h"
@@ -49,8 +47,6 @@
#include "MOD_boolean_util.h"
#include "MOD_util.h"
-#include "PIL_time.h"
-
static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
@@ -78,6 +74,7 @@ static void foreachObjectLink(
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c
index 6e62a21ec4c..061b1198f7e 100644
--- a/source/blender/modifiers/intern/MOD_boolean_util.c
+++ b/source/blender/modifiers/intern/MOD_boolean_util.c
@@ -365,14 +365,6 @@ BLI_INLINE MPoly *which_mpoly(ExportMeshData *export_data, int which_mesh)
return mpoly;
}
-static void allocate_custom_layers(CustomData *data, int type, int num_elements, int num_layers)
-{
- int i;
- for (i = 0; i < num_layers; i++) {
- CustomData_add_layer(data, type, CD_DEFAULT, NULL, num_elements);
- }
-}
-
/* Create new external mesh */
static void exporter_InitGeomArrays(ExportMeshData *export_data,
int num_verts, int num_edges,
@@ -392,24 +384,15 @@ static void exporter_InitGeomArrays(ExportMeshData *export_data,
export_data->mloop = dm->getLoopArray(dm);
export_data->mpoly = dm->getPolyArray(dm);
- /* Allocate layers for UV layers and vertex colors.
- * Without this interpolation of those data will not happen.
- */
- allocate_custom_layers(&dm->loopData, CD_MLOOPCOL, num_loops,
- CustomData_number_of_layers(&dm_left->loopData, CD_MLOOPCOL));
- allocate_custom_layers(&dm->loopData, CD_MLOOPUV, num_loops,
- CustomData_number_of_layers(&dm_left->loopData, CD_MLOOPUV));
-
- allocate_custom_layers(&dm->loopData, CD_MLOOPCOL, num_loops,
- CustomData_number_of_layers(&dm_right->loopData, CD_MLOOPCOL));
- allocate_custom_layers(&dm->loopData, CD_MLOOPUV, num_loops,
- CustomData_number_of_layers(&dm_right->loopData, CD_MLOOPUV));
-
/* Merge custom data layers from operands.
*
* Will only create custom data layers for all the layers which appears in
* the operand. Data for those layers will not be allocated or initialized.
*/
+
+ CustomData_merge(&dm_left->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops);
+ CustomData_merge(&dm_right->loopData, &dm->loopData, merge_mask, CD_DEFAULT, num_loops);
+
CustomData_merge(&dm_left->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys);
CustomData_merge(&dm_right->polyData, &dm->polyData, merge_mask, CD_DEFAULT, num_polys);
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index f6ade2bf303..1dc1a1f8d64 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -40,16 +40,16 @@
#include "BLI_math_vector.h"
#include "BLI_ghash.h"
-#include "DNA_scene_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
-#include "MOD_util.h"
+#ifdef _OPENMP
+# include "BKE_mesh.h" /* BKE_MESH_OMP_LIMIT */
+#endif
static void initData(ModifierData *md)
{
@@ -86,7 +86,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
float frac;
MPoly *mpoly_dst;
MLoop *ml_dst, *ml_src /*, *mloop_dst */;
- GHashIterator *hashIter;
+ GHashIterator gh_iter;
/* maps vert indices in old mesh to indices in new mesh */
GHash *vertHash = BLI_ghash_int_new("build ve apply gh");
/* maps edge indices in new mesh to indices in old mesh */
@@ -230,15 +230,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
BLI_ghash_size(edgeHash), 0, numLoops_dst, numFaces_dst);
/* copy the vertices across */
- for (hashIter = BLI_ghashIterator_new(vertHash);
- BLI_ghashIterator_done(hashIter) == false;
- BLI_ghashIterator_step(hashIter)
- )
- {
+ GHASH_ITER (gh_iter, vertHash) {
MVert source;
MVert *dest;
- int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
- int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
+ int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter));
+ int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter));
source = mvert_src[oldIndex];
dest = CDDM_get_vert(result, newIndex);
@@ -246,7 +242,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
*dest = source;
}
- BLI_ghashIterator_free(hashIter);
/* copy the edges across, remapping indices */
for (i = 0; i < BLI_ghash_size(edgeHash); i++) {
diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c
index c4654287cfc..3bdc62e124c 100644
--- a/source/blender/modifiers/intern/MOD_cast.c
+++ b/source/blender/modifiers/intern/MOD_cast.c
@@ -106,6 +106,7 @@ static void foreachObjectLink(
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 1561fd1a981..d76427cd6ee 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -46,6 +46,7 @@
#include "BKE_cloth.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_modifier.h"
@@ -117,7 +118,9 @@ static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData,
dm->release(dm);
}
-static void updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
+static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
+ Scene *scene, Object *ob, DagNode *obNode)
{
ClothModifierData *clmd = (ClothModifierData *) md;
@@ -175,6 +178,8 @@ static void copyData(ModifierData *md, ModifierData *target)
tclmd->point_cache = BKE_ptcache_add(&tclmd->ptcaches);
tclmd->point_cache->step = 1;
tclmd->clothObject = NULL;
+ tclmd->hairdata = NULL;
+ tclmd->solver_result = NULL;
}
static bool dependsOnTime(ModifierData *UNUSED(md))
@@ -202,6 +207,12 @@ static void freeData(ModifierData *md)
BKE_ptcache_free_list(&clmd->ptcaches);
clmd->point_cache = NULL;
+
+ if (clmd->hairdata)
+ MEM_freeN(clmd->hairdata);
+
+ if (clmd->solver_result)
+ MEM_freeN(clmd->solver_result);
}
}
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index 8f6c533ae4c..130e332ef69 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -32,7 +32,6 @@
* \ingroup modifiers
*/
-
#include "DNA_object_types.h"
#include "DNA_meshdata_types.h"
@@ -49,8 +48,6 @@
#include "BKE_pointcache.h"
#include "BKE_scene.h"
-#include "MOD_util.h"
-
static void initData(ModifierData *md)
{
CollisionModifierData *collmd = (CollisionModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index fbc72cef0e8..d53bac390a6 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -32,7 +32,6 @@
* \ingroup modifiers
*/
-
#include <string.h>
#include "DNA_scene_types.h"
@@ -47,7 +46,6 @@
#include "depsgraph_private.h"
-#include "MOD_util.h"
static void initData(ModifierData *md)
{
@@ -94,6 +92,7 @@ static void foreachObjectLink(
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
new file mode 100644
index 00000000000..d13ca6e5bb7
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_datatransfer.c
@@ -0,0 +1,243 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): None yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_datatransfer.c
+ * \ingroup modifiers
+ */
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_customdata.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_data_transfer.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_library.h"
+#include "BKE_mesh_mapping.h"
+#include "BKE_mesh_remap.h"
+#include "BKE_modifier.h"
+#include "BKE_report.h"
+
+#include "MEM_guardedalloc.h"
+#include "MOD_util.h"
+
+#include "depsgraph_private.h"
+
+/**************************************
+ * Modifiers functions. *
+ **************************************/
+static void initData(ModifierData *md)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ int i;
+
+ dtmd->ob_source = NULL;
+ dtmd->data_types = 0;
+
+ dtmd->vmap_mode = MREMAP_MODE_VERT_NEAREST;
+ dtmd->emap_mode = MREMAP_MODE_EDGE_NEAREST;
+ dtmd->lmap_mode = MREMAP_MODE_LOOP_NEAREST_POLYNOR;
+ dtmd->pmap_mode = MREMAP_MODE_POLY_NEAREST;
+
+ dtmd->map_max_distance = 1.0f;
+ dtmd->map_ray_radius = 0.0f;
+
+ for (i = 0; i < DT_MULTILAYER_INDEX_MAX; i++) {
+ dtmd->layers_select_src[i] = DT_LAYERS_ALL_SRC;
+ dtmd->layers_select_dst[i] = DT_LAYERS_NAME_DST;
+ }
+
+ dtmd->mix_mode = CDT_MIX_TRANSFER;
+ dtmd->mix_factor = 1.0f;
+ dtmd->defgrp_name[0] = '\0';
+
+ dtmd->flags = MOD_DATATRANSFER_OBSRC_TRANSFORM;
+}
+
+static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ CustomDataMask dataMask = 0;
+
+ if (dtmd->defgrp_name[0]) {
+ /* We need vertex groups! */
+ dataMask |= CD_MASK_MDEFORMVERT;
+ }
+
+ dataMask |= BKE_object_data_transfer_dttypes_to_cdmask(dtmd->data_types);
+
+ return dataMask;
+}
+
+static bool dependsOnNormals(ModifierData *md)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ int item_types = BKE_object_data_transfer_get_dttypes_item_types(dtmd->data_types);
+
+ if ((item_types & ME_VERT) && (dtmd->vmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+ if ((item_types & ME_EDGE) && (dtmd->emap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+ if ((item_types & ME_LOOP) && (dtmd->lmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+ if ((item_types & ME_POLY) && (dtmd->pmap_mode & (MREMAP_USE_NORPROJ | MREMAP_USE_NORMAL))) {
+ return true;
+ }
+
+ return false;
+}
+
+static void foreachObjectLink(ModifierData *md, Object *ob,
+ void (*walk)(void *userData, Object *ob, Object **obpoin),
+ void *userData)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ walk(userData, ob, &dtmd->ob_source);
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
+}
+
+static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
+ struct Scene *UNUSED(scene),
+ Object *UNUSED(ob), DagNode *obNode)
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ DagNode *curNode;
+
+ if (dtmd->ob_source) {
+ curNode = dag_get_node(forest, dtmd->ob_source);
+
+ dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
+ "DataTransfer Modifier");
+ }
+}
+
+static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ /* If no source object, bypass. */
+ return (dtmd->ob_source == NULL);
+}
+
+#define HIGH_POLY_WARNING 10000
+#define DT_TYPES_AFFECT_MESH ( \
+ DT_TYPE_BWEIGHT_VERT | \
+ DT_TYPE_BWEIGHT_EDGE | DT_TYPE_CREASE | DT_TYPE_SHARP_EDGE | \
+ DT_TYPE_LNOR | \
+ DT_TYPE_SHARP_FACE \
+)
+
+static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ ModifierApplyFlag UNUSED(flag))
+{
+ DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
+ DerivedMesh *dm = derivedData;
+ ReportList reports;
+
+ /* Only used to check wehther we are operating on org data or not... */
+ Mesh *me = ob->data;
+ MVert *mvert;
+
+ const bool invert_vgroup = (dtmd->flags & MOD_DATATRANSFER_INVERT_VGROUP) != 0;
+
+ const float max_dist = (dtmd->flags & MOD_DATATRANSFER_MAP_MAXDIST) ? dtmd->map_max_distance : FLT_MAX;
+
+ SpaceTransform space_transform_data;
+ SpaceTransform *space_transform = (dtmd->flags & MOD_DATATRANSFER_OBSRC_TRANSFORM) ? &space_transform_data : NULL;
+
+ if (space_transform) {
+ BLI_SPACE_TRANSFORM_SETUP(space_transform, ob, dtmd->ob_source);
+ }
+
+ mvert = dm->getVertArray(dm);
+ if ((me->mvert == mvert) && (dtmd->data_types & DT_TYPES_AFFECT_MESH)) {
+ /* We need to duplicate data here, otherwise setting custom normals, edges' shaprness, etc., could
+ * modify org mesh, see T43671. */
+ dm = CDDM_copy(dm);
+ }
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ /* Note: no islands precision for now here. */
+ BKE_object_data_transfer_dm(md->scene, dtmd->ob_source, ob, dm, dtmd->data_types, false,
+ dtmd->vmap_mode, dtmd->emap_mode, dtmd->lmap_mode, dtmd->pmap_mode,
+ space_transform, max_dist, dtmd->map_ray_radius, 0.0f,
+ dtmd->layers_select_src, dtmd->layers_select_dst,
+ dtmd->mix_mode, dtmd->mix_factor, dtmd->defgrp_name, invert_vgroup, &reports);
+
+ if (BKE_reports_contain(&reports, RPT_ERROR)) {
+ modifier_setError(md, "%s", BKE_reports_string(&reports, RPT_ERROR));
+ }
+ else if (dm->getNumVerts(dm) > HIGH_POLY_WARNING || ((Mesh *)(dtmd->ob_source->data))->totvert > HIGH_POLY_WARNING) {
+ modifier_setError(md, "You are using a rather high poly as source or destination, computation might be slow");
+ }
+
+ return dm;
+}
+
+#undef HIGH_POLY_WARNING
+#undef DT_TYPES_AFFECT_MESH
+
+ModifierTypeInfo modifierType_DataTransfer = {
+ /* name */ "DataTransfer",
+ /* structName */ "DataTransferModifierData",
+ /* structSize */ sizeof(DataTransferModifierData),
+ /* type */ eModifierTypeType_NonGeometrical,
+ /* flags */ eModifierTypeFlag_AcceptsMesh |
+ eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_UsesPreview,
+
+ /* copyData */ NULL,
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+ /* applyModifierEM */ NULL,
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepgraph */ updateDepgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index b844b9e3bde..8a92deec8eb 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -35,17 +35,12 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BLI_utildefines.h"
-#include "BLF_translation.h"
-
#include "MEM_guardedalloc.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_deform.h"
-#include "BKE_particle.h"
#include "BKE_cdderivedmesh.h"
#include "bmesh.h"
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index a23873fcd8a..e377445fed8 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -150,6 +150,7 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index 838ceb5cfe0..c6999468dc3 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -28,7 +28,6 @@
#include <stddef.h>
#include "DNA_dynamicpaint_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -40,8 +39,6 @@
#include "depsgraph_private.h"
-#include "MOD_util.h"
-
static void initData(ModifierData *md)
{
@@ -115,6 +112,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *scene,
Object *ob,
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index d3c7e7d4779..32a6303d19d 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -54,7 +54,6 @@
#include "MEM_guardedalloc.h"
-#include "MOD_util.h"
static void initData(ModifierData *md)
{
@@ -892,7 +891,7 @@ static DerivedMesh *explodeMesh(ExplodeModifierData *emd,
/* get particle */
pa = pars + ed_v2;
- psys_get_birth_coordinates(&sim, pa, &birth, 0, 0);
+ psys_get_birth_coords(&sim, pa, &birth, 0, 0);
state.time = cfra;
psys_get_particle_state(&sim, ed_v2, &state, 1);
diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c
index d3c56b8d7f7..6344ec83a31 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim.c
@@ -45,7 +45,6 @@
#include "depsgraph_private.h"
-#include "MOD_util.h"
#include "MOD_fluidsim_util.h"
#include "MEM_guardedalloc.h"
@@ -98,7 +97,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
static void updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene,
+ ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain), Scene *scene,
Object *ob, DagNode *obNode)
{
FluidsimModifierData *fluidmd = (FluidsimModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c
index f6d7c03df32..10223d3880e 100644
--- a/source/blender/modifiers/intern/MOD_hook.c
+++ b/source/blender/modifiers/intern/MOD_hook.c
@@ -43,6 +43,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_modifier.h"
#include "BKE_deform.h"
+#include "BKE_colortools.h"
#include "depsgraph_private.h"
@@ -55,6 +56,9 @@ static void initData(ModifierData *md)
HookModifierData *hmd = (HookModifierData *) md;
hmd->force = 1.0;
+ hmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+ hmd->falloff_type = eHook_Falloff_Smooth;
+ hmd->flag = 0;
}
static void copyData(ModifierData *md, ModifierData *target)
@@ -64,6 +68,8 @@ static void copyData(ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
+ thmd->curfalloff = curvemapping_copy(hmd->curfalloff);
+
thmd->indexar = MEM_dupallocN(hmd->indexar);
}
@@ -83,6 +89,8 @@ static void freeData(ModifierData *md)
{
HookModifierData *hmd = (HookModifierData *) md;
+ curvemapping_free(hmd->curfalloff);
+
if (hmd->indexar) MEM_freeN(hmd->indexar);
}
@@ -104,6 +112,7 @@ static void foreachObjectLink(
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
@@ -120,32 +129,172 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
}
}
-static float hook_falloff(const float co_1[3], const float co_2[3], const float falloff_squared, float fac)
+struct HookData_cb {
+ float (*vertexCos)[3];
+
+ MDeformVert *dvert;
+ int defgrp_index;
+
+ struct CurveMapping *curfalloff;
+
+ char falloff_type;
+ float falloff;
+ float falloff_sq;
+ float fac_orig;
+
+ unsigned int use_falloff : 1;
+ unsigned int use_uniform : 1;
+
+ float cent[3];
+
+ float mat_uniform[3][3];
+ float mat[4][4];
+};
+
+static float hook_falloff(
+ const struct HookData_cb *hd,
+ const float len_sq)
+{
+ BLI_assert(hd->falloff_sq);
+ if (len_sq > hd->falloff_sq) {
+ return 0.0f;
+ }
+ else if (len_sq > 0.0f) {
+ float fac;
+
+ if (hd->falloff_type == eHook_Falloff_Const) {
+ fac = 1.0f;
+ goto finally;
+ }
+ else if (hd->falloff_type == eHook_Falloff_InvSquare) {
+ /* avoid sqrt below */
+ fac = 1.0f - (len_sq / hd->falloff_sq);
+ goto finally;
+ }
+
+ fac = 1.0f - (sqrtf(len_sq) / hd->falloff);
+
+ /* closely match PROP_SMOOTH and similar */
+ switch (hd->falloff_type) {
+#if 0
+ case eHook_Falloff_None:
+ fac = 1.0f;
+ break;
+#endif
+ case eHook_Falloff_Curve:
+ fac = curvemapping_evaluateF(hd->curfalloff, 0, fac);
+ break;
+ case eHook_Falloff_Sharp:
+ fac = fac * fac;
+ break;
+ case eHook_Falloff_Smooth:
+ fac = 3.0f * fac * fac - 2.0f * fac * fac * fac;
+ break;
+ case eHook_Falloff_Root:
+ fac = sqrtf(fac);
+ break;
+ case eHook_Falloff_Linear:
+ /* pass */
+ break;
+#if 0
+ case eHook_Falloff_Const:
+ fac = 1.0f;
+ break;
+#endif
+ case eHook_Falloff_Sphere:
+ fac = sqrtf(2 * fac - fac * fac);
+ break;
+#if 0
+ case eHook_Falloff_InvSquare:
+ fac = fac * (2.0f - fac);
+ break;
+#endif
+ }
+
+finally:
+ return fac * hd->fac_orig;
+ }
+ else {
+ return hd->fac_orig;
+ }
+}
+
+static void hook_co_apply(struct HookData_cb *hd, const int j)
{
- if (falloff_squared) {
- float len_squared = len_squared_v3v3(co_1, co_2);
- if (len_squared > falloff_squared) {
- return 0.0f;
+ float *co = hd->vertexCos[j];
+ float fac;
+
+ if (hd->use_falloff) {
+ float len_sq;
+
+ if (hd->use_uniform) {
+ float co_uniform[3];
+ mul_v3_m3v3(co_uniform, hd->mat_uniform, co);
+ len_sq = len_squared_v3v3(hd->cent, co_uniform);
}
- else if (len_squared > 0.0f) {
- return fac * (1.0f - (len_squared / falloff_squared));
+ else {
+ len_sq = len_squared_v3v3(hd->cent, co);
}
+
+ fac = hook_falloff(hd, len_sq);
}
+ else {
+ fac = hd->fac_orig;
+ }
+
+ if (fac) {
+ if (hd->dvert) {
+ fac *= defvert_find_weight(&hd->dvert[j], hd->defgrp_index);
+ }
- return fac;
+ if (fac) {
+ float co_tmp[3];
+ mul_v3_m4v3(co_tmp, hd->mat, co);
+ interp_v3_v3v3(co, co, co_tmp, fac);
+ }
+ }
}
static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm,
float (*vertexCos)[3], int numVerts)
{
bPoseChannel *pchan = BKE_pose_channel_find_name(hmd->object->pose, hmd->subtarget);
- float vec[3], mat[4][4], dmat[4][4];
+ float dmat[4][4];
int i, *index_pt;
- const float falloff_squared = hmd->falloff * hmd->falloff; /* for faster comparisons */
-
- MDeformVert *dvert;
- int defgrp_index, max_dvert;
+ struct HookData_cb hd;
+ if (hmd->curfalloff == NULL) {
+ /* should never happen, but bad lib linking could cause it */
+ hmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
+ }
+
+ if (hmd->curfalloff) {
+ curvemapping_initialize(hmd->curfalloff);
+ }
+
+ /* Generic data needed for applying per-vertex calculations (initialize all members) */
+ hd.vertexCos = vertexCos;
+ modifier_get_vgroup(ob, dm, hmd->name, &hd.dvert, &hd.defgrp_index);
+
+ hd.curfalloff = hmd->curfalloff;
+
+ hd.falloff_type = hmd->falloff_type;
+ hd.falloff = (hmd->falloff_type == eHook_Falloff_None) ? 0.0f : hmd->falloff;
+ hd.falloff_sq = SQUARE(hd.falloff);
+ hd.fac_orig = hmd->force;
+
+ hd.use_falloff = (hd.falloff_sq != 0.0f);
+ hd.use_uniform = (hmd->flag & MOD_HOOK_UNIFORM_SPACE) != 0;
+
+ if (hd.use_uniform) {
+ copy_m3_m4(hd.mat_uniform, hmd->parentinv);
+ mul_v3_m3v3(hd.cent, hd.mat_uniform, hmd->cent);
+ }
+ else {
+ unit_m3(hd.mat_uniform); /* unused */
+ copy_v3_v3(hd.cent, hmd->cent);
+ }
+
/* get world-space matrix of target, corrected for the space the verts are in */
if (hmd->subtarget[0] && pchan) {
/* bone target if there's a matching pose-channel */
@@ -156,10 +305,9 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm,
copy_m4_m4(dmat, hmd->object->obmat);
}
invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_series(mat, ob->imat, dmat, hmd->parentinv);
+ mul_m4_series(hd.mat, ob->imat, dmat, hmd->parentinv);
+ /* --- done with 'hd' init --- */
- modifier_get_vgroup(ob, dm, hmd->name, &dvert, &defgrp_index);
- max_dvert = (dvert) ? numVerts : 0;
/* Regarding index range checking below.
*
@@ -168,13 +316,11 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm,
* indices that are out of range because old blender did
* not correct them on exit editmode. - zr
*/
-
+
if (hmd->force == 0.0f) {
/* do nothing, avoid annoying checks in the loop */
}
else if (hmd->indexar) { /* vertex indices? */
- const float fac_orig = hmd->force;
- float fac;
const int *origindex_ar;
/* if DerivedMesh is present and has original index data, use it */
@@ -185,16 +331,7 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm,
for (j = 0; j < numVerts; j++) {
if (origindex_ar[j] == *index_pt) {
- float *co = vertexCos[j];
- if ((fac = hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
- if (dvert)
- fac *= defvert_find_weight(dvert + j, defgrp_index);
-
- if (fac) {
- mul_v3_m4v3(vec, mat, co);
- interp_v3_v3v3(co, co, vec, fac);
- }
- }
+ hook_co_apply(&hd, j);
}
}
}
@@ -203,34 +340,14 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm,
else { /* missing dm or ORIGINDEX */
for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
if (*index_pt < numVerts) {
- float *co = vertexCos[*index_pt];
- if ((fac = hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
- if (dvert)
- fac *= defvert_find_weight(dvert + (*index_pt), defgrp_index);
-
- if (fac) {
- mul_v3_m4v3(vec, mat, co);
- interp_v3_v3v3(co, co, vec, fac);
- }
- }
+ hook_co_apply(&hd, *index_pt);
}
}
}
}
- else if (dvert) { /* vertex group hook */
- const float fac_orig = hmd->force;
-
- for (i = 0; i < max_dvert; i++, dvert++) {
- float fac;
- float *co = vertexCos[i];
-
- if ((fac = hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
- fac *= defvert_find_weight(dvert, defgrp_index);
- if (fac) {
- mul_v3_m4v3(vec, mat, co);
- interp_v3_v3v3(co, co, vec, fac);
- }
- }
+ else if (hd.dvert) { /* vertex group hook */
+ for (i = 0; i < numVerts; i++) {
+ hook_co_apply(&hd, i);
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index ffadcda3e8c..a4f6d005d94 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -767,7 +767,7 @@ static void LaplacianDeformModifier_do(
LaplacianDeformModifierData *lmd, Object *ob, DerivedMesh *dm,
float (*vertexCos)[3], int numVerts)
{
- (void)lmd, (void)ob, (void)dm, (void)vertexCos, (void)numVerts;
+ UNUSED_VARS(lmd, ob, dm, vertexCos, numVerts);
}
#endif /* WITH_OPENNL */
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 9ba0bfc7ce9..93cd92196b2 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -41,7 +41,6 @@
#include "BKE_deform.h"
#include "BKE_modifier.h"
-#include "MOD_modifiertypes.h"
#include "MOD_util.h"
#ifdef WITH_OPENNL
@@ -467,13 +466,13 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl
if (sys->zerola[i] == 0) {
lam = sys->numNeEd[i] == sys->numNeFa[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) : (lambda_border >= 0.0f ? 1.0f : -1.0f);
if (flag & MOD_LAPLACIANSMOOTH_X) {
- sys->vertexCos[i][0] += lam * (nlGetVariable(0, i) - sys->vertexCos[i][0]);
+ sys->vertexCos[i][0] += lam * ((float)nlGetVariable(0, i) - sys->vertexCos[i][0]);
}
if (flag & MOD_LAPLACIANSMOOTH_Y) {
- sys->vertexCos[i][1] += lam * (nlGetVariable(1, i) - sys->vertexCos[i][1]);
+ sys->vertexCos[i][1] += lam * ((float)nlGetVariable(1, i) - sys->vertexCos[i][1]);
}
if (flag & MOD_LAPLACIANSMOOTH_Z) {
- sys->vertexCos[i][2] += lam * (nlGetVariable(2, i) - sys->vertexCos[i][2]);
+ sys->vertexCos[i][2] += lam * ((float)nlGetVariable(2, i) - sys->vertexCos[i][2]);
}
}
}
@@ -613,7 +612,7 @@ static void laplaciansmoothModifier_do(
LaplacianSmoothModifierData *smd, Object *ob, DerivedMesh *dm,
float (*vertexCos)[3], int numVerts)
{
- (void)smd, (void)ob, (void)dm, (void)vertexCos, (void)numVerts;
+ UNUSED_VARS(smd, ob, dm, vertexCos, numVerts);
}
#endif /* WITH_OPENNL */
diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c
index e4a359a93e2..60caf523a97 100644
--- a/source/blender/modifiers/intern/MOD_lattice.c
+++ b/source/blender/modifiers/intern/MOD_lattice.c
@@ -38,7 +38,6 @@
#include "DNA_object_types.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_lattice.h"
@@ -93,6 +92,7 @@ static void foreachObjectLink(
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c
index 838336a8f8a..e77225f3617 100644
--- a/source/blender/modifiers/intern/MOD_mask.c
+++ b/source/blender/modifiers/intern/MOD_mask.c
@@ -51,7 +51,7 @@
#include "depsgraph_private.h"
-#include "MOD_util.h"
+#include "BLI_strict_flags.h"
static void copyData(ModifierData *md, ModifierData *target)
{
@@ -77,6 +77,7 @@ static void foreachObjectLink(
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
@@ -101,20 +102,21 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
const bool found_test = (mmd->flag & MOD_MASK_INV) == 0;
DerivedMesh *result = NULL;
GHash *vertHash = NULL, *edgeHash, *polyHash;
- GHashIterator *hashIter;
+ GHashIterator gh_iter;
MDeformVert *dvert, *dv;
int numPolys = 0, numLoops = 0, numEdges = 0, numVerts = 0;
int maxVerts, maxEdges, maxPolys;
int i;
- MPoly *mpoly;
- MLoop *mloop;
-
- MPoly *mpoly_new;
- MLoop *mloop_new;
- MEdge *medge_new;
- MVert *mvert_new;
+ const MVert *mvert_src;
+ const MEdge *medge_src;
+ const MPoly *mpoly_src;
+ const MLoop *mloop_src;
+ MPoly *mpoly_dst;
+ MLoop *mloop_dst;
+ MEdge *medge_dst;
+ MVert *mvert_dst;
int *loop_mapping;
@@ -150,7 +152,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
bDeformGroup *def;
bool *bone_select_array;
int bone_select_tot = 0;
- const int defbase_tot = BLI_countlist(&ob->defbase);
+ const int defbase_tot = BLI_listbase_count(&ob->defbase);
/* check that there is armature object with bones to use, otherwise return original mesh */
if (ELEM(NULL, oba, oba->pose, ob->defbase.first))
@@ -160,7 +162,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
* - each cell is a boolean saying whether bone corresponding to the ith group is selected
* - groups that don't match a bone are treated as not existing (along with the corresponding ungrouped verts)
*/
- bone_select_array = MEM_mallocN(defbase_tot * sizeof(char), "mask array");
+ bone_select_array = MEM_mallocN((size_t)defbase_tot * sizeof(char), "mask array");
for (i = 0, def = ob->defbase.first; def; def = def->next, i++) {
pchan = BKE_pose_channel_find_name(oba->pose, def->name);
@@ -176,7 +178,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* verthash gives mapping from original vertex indices to the new indices (including selected matches only)
* key = oldindex, value = newindex
*/
- vertHash = BLI_ghash_int_new("mask vert gh");
+ vertHash = BLI_ghash_int_new_ex("mask vert gh", (unsigned int)maxVerts);
/* add vertices which exist in vertexgroups into vertHash for filtering
* - dv = for each vertex, what vertexgroups does it belong to
@@ -219,7 +221,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
return dm;
/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
- vertHash = BLI_ghash_int_new("mask vert2 bh");
+ vertHash = BLI_ghash_int_new_ex("mask vert2 bh", (unsigned int)maxVerts);
/* add vertices which exist in vertexgroup into ghash for filtering */
for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
@@ -235,37 +237,39 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
- edgeHash = BLI_ghash_int_new("mask ed2 gh");
- polyHash = BLI_ghash_int_new("mask fa2 gh");
-
- mpoly = dm->getPolyArray(dm);
- mloop = dm->getLoopArray(dm);
+ edgeHash = BLI_ghash_int_new_ex("mask ed2 gh", (unsigned int)maxEdges);
+ polyHash = BLI_ghash_int_new_ex("mask fa2 gh", (unsigned int)maxPolys);
- loop_mapping = MEM_callocN(sizeof(int) * maxPolys, "mask loopmap"); /* overalloc, assume all polys are seen */
+ mvert_src = dm->getVertArray(dm);
+ medge_src = dm->getEdgeArray(dm);
+ mpoly_src = dm->getPolyArray(dm);
+ mloop_src = dm->getLoopArray(dm);
+
+ /* overalloc, assume all polys are seen */
+ loop_mapping = MEM_mallocN(sizeof(int) * (size_t)maxPolys, "mask loopmap");
/* loop over edges and faces, and do the same thing to
* ensure that they only reference existing verts
*/
for (i = 0; i < maxEdges; i++) {
- MEdge me;
- dm->getEdge(dm, i, &me);
+ const MEdge *me = &medge_src[i];
/* only add if both verts will be in new mesh */
- if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) &&
- BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
+ if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1)) &&
+ BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2)))
{
BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges));
numEdges++;
}
}
for (i = 0; i < maxPolys; i++) {
- MPoly *mp = &mpoly[i];
- MLoop *ml = mloop + mp->loopstart;
+ const MPoly *mp_src = &mpoly_src[i];
+ const MLoop *ml_src = &mloop_src[mp_src->loopstart];
bool ok = true;
int j;
- for (j = 0; j < mp->totloop; j++, ml++) {
- if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) {
+ for (j = 0; j < mp_src->totloop; j++, ml_src++) {
+ if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml_src->v))) {
ok = false;
break;
}
@@ -276,7 +280,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
BLI_ghash_insert(polyHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numPolys));
loop_mapping[numPolys] = numLoops;
numPolys++;
- numLoops += mp->totloop;
+ numLoops += mp_src->totloop;
}
}
@@ -286,78 +290,64 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
*/
result = CDDM_from_template(dm, numVerts, numEdges, 0, numLoops, numPolys);
- mpoly_new = CDDM_get_polys(result);
- mloop_new = CDDM_get_loops(result);
- medge_new = CDDM_get_edges(result);
- mvert_new = CDDM_get_verts(result);
-
+ mpoly_dst = CDDM_get_polys(result);
+ mloop_dst = CDDM_get_loops(result);
+ medge_dst = CDDM_get_edges(result);
+ mvert_dst = CDDM_get_verts(result);
+
/* using ghash-iterators, map data into new mesh */
/* vertices */
- for (hashIter = BLI_ghashIterator_new(vertHash);
- BLI_ghashIterator_done(hashIter) == false;
- BLI_ghashIterator_step(hashIter))
- {
- MVert source;
- MVert *dest;
- int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
- int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
-
- dm->getVert(dm, oldIndex, &source);
- dest = &mvert_new[newIndex];
+ GHASH_ITER (gh_iter, vertHash) {
+ const MVert *v_src;
+ MVert *v_dst;
+ const int i_src = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter));
+ const int i_dst = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter));
- DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
- *dest = source;
+ v_src = &mvert_src[i_src];
+ v_dst = &mvert_dst[i_dst];
+
+ *v_dst = *v_src;
+ DM_copy_vert_data(dm, result, i_src, i_dst, 1);
}
- BLI_ghashIterator_free(hashIter);
/* edges */
- for (hashIter = BLI_ghashIterator_new(edgeHash);
- BLI_ghashIterator_done(hashIter) == false;
- BLI_ghashIterator_step(hashIter))
- {
- MEdge source;
- MEdge *dest;
- int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
- int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
-
- dm->getEdge(dm, oldIndex, &source);
- dest = &medge_new[newIndex];
-
- source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
- source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
+ GHASH_ITER (gh_iter, edgeHash) {
+ const MEdge *e_src;
+ MEdge *e_dst;
+ const int i_src = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter));
+ const int i_dst = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter));
- DM_copy_edge_data(dm, result, oldIndex, newIndex, 1);
- *dest = source;
+ e_src = &medge_src[i_src];
+ e_dst = &medge_dst[i_dst];
+
+ DM_copy_edge_data(dm, result, i_src, i_dst, 1);
+ *e_dst = *e_src;
+ e_dst->v1 = GET_UINT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_UINT_IN_POINTER(e_src->v1)));
+ e_dst->v2 = GET_UINT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_UINT_IN_POINTER(e_src->v2)));
}
- BLI_ghashIterator_free(hashIter);
/* faces */
- for (hashIter = BLI_ghashIterator_new(polyHash);
- BLI_ghashIterator_done(hashIter) == false;
- BLI_ghashIterator_step(hashIter))
- {
- int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
- int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
- MPoly *source = &mpoly[oldIndex];
- MPoly *dest = &mpoly_new[newIndex];
- int oldLoopIndex = source->loopstart;
- int newLoopIndex = loop_mapping[newIndex];
- MLoop *source_loop = &mloop[oldLoopIndex];
- MLoop *dest_loop = &mloop_new[newLoopIndex];
+ GHASH_ITER (gh_iter, polyHash) {
+ const int i_src = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter));
+ const int i_dst = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter));
+ const MPoly *mp_src = &mpoly_src[i_src];
+ MPoly *mp_dst = &mpoly_dst[i_dst];
+ const int i_ml_src = mp_src->loopstart;
+ const int i_ml_dst = loop_mapping[i_dst];
+ const MLoop *ml_src = &mloop_src[i_ml_src];
+ MLoop *ml_dst = &mloop_dst[i_ml_dst];
- DM_copy_poly_data(dm, result, oldIndex, newIndex, 1);
- DM_copy_loop_data(dm, result, oldLoopIndex, newLoopIndex, source->totloop);
-
- *dest = *source;
- dest->loopstart = newLoopIndex;
- for (i = 0; i < source->totloop; i++) {
- dest_loop[i].v = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source_loop[i].v)));
- dest_loop[i].e = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(source_loop[i].e)));
+ DM_copy_poly_data(dm, result, i_src, i_dst, 1);
+ DM_copy_loop_data(dm, result, i_ml_src, i_ml_dst, mp_src->totloop);
+
+ *mp_dst = *mp_src;
+ mp_dst->loopstart = i_ml_dst;
+ for (i = 0; i < mp_src->totloop; i++) {
+ ml_dst[i].v = GET_UINT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_UINT_IN_POINTER(ml_src[i].v)));
+ ml_dst[i].e = GET_UINT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_UINT_IN_POINTER(ml_src[i].e)));
}
}
- BLI_ghashIterator_free(hashIter);
-
MEM_freeN(loop_mapping);
/* why is this needed? - campbell */
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index 925d9691892..db50d49f790 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -48,8 +48,6 @@
#include "MOD_modifiertypes.h"
-#include "MOD_util.h"
-
static void initData(ModifierData *md)
{
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
index 3ef0ee54886..219eae4ecca 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -31,7 +31,6 @@
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
#include "BLI_fileops.h"
-#include "BLI_math.h"
#ifdef __BIG_ENDIAN__
# include "BLI_endian_switch.h"
#endif
@@ -58,7 +57,7 @@ static bool meshcache_read_pc2_head(FILE *fp, const int verts_tot,
return false;
}
- if (strcmp(pc2_head->header, "POINTCACHE2") != 0) {
+ if (!STREQ(pc2_head->header, "POINTCACHE2")) {
*err_str = "Invalid header";
return false;
}
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index c509bf44fc8..3ceed4a970d 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -40,8 +40,6 @@
#include "BLI_task.h"
#include "BLI_utildefines.h"
-#include "BLF_translation.h"
-
#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
#include "BKE_modifier.h"
@@ -84,9 +82,16 @@ static void copyData(ModifierData *md, ModifierData *target)
MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
MeshDeformModifierData *tmmd = (MeshDeformModifierData *) target;
- tmmd->gridsize = mmd->gridsize;
- tmmd->flag = mmd->flag;
- tmmd->object = mmd->object;
+ *tmmd = *mmd;
+
+ if (mmd->bindinfluences) tmmd->bindinfluences = MEM_dupallocN(mmd->bindinfluences);
+ if (mmd->bindoffsets) tmmd->bindoffsets = MEM_dupallocN(mmd->bindoffsets);
+ if (mmd->bindcagecos) tmmd->bindcagecos = MEM_dupallocN(mmd->bindcagecos);
+ if (mmd->dyngrid) tmmd->dyngrid = MEM_dupallocN(mmd->dyngrid);
+ if (mmd->dyninfluences) tmmd->dyninfluences = MEM_dupallocN(mmd->dyninfluences);
+ if (mmd->dynverts) tmmd->dynverts = MEM_dupallocN(mmd->dynverts);
+ if (mmd->bindweights) tmmd->dynverts = MEM_dupallocN(mmd->bindweights); /* deprecated */
+ if (mmd->bindcos) tmmd->dynverts = MEM_dupallocN(mmd->bindcos); /* deprecated */
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
@@ -118,6 +123,7 @@ static void foreachObjectLink(
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
@@ -213,17 +219,16 @@ typedef struct MeshdeformUserdata {
float (*vertexCos)[3];
float (*cagemat)[4];
float (*icagemat)[3];
- SpinLock lock;
} MeshdeformUserdata;
-static void meshdeform_vert_task(void *userdata, int iter)
+static void meshdeform_vert_task(void * userdata, int iter)
{
MeshdeformUserdata *data = userdata;
/*const*/ MeshDeformModifierData *mmd = data->mmd;
const MDeformVert *dvert = data->dvert;
const int defgrp_index = data->defgrp_index;
const int *offsets = mmd->bindoffsets;
- const MDefInfluence *influences = influences = mmd->bindinfluences;
+ const MDefInfluence *influences = mmd->bindinfluences;
/*const*/ float (*dco)[3] = data->dco;
float (*vertexCos)[3] = data->vertexCos;
float co[3];
@@ -265,12 +270,10 @@ static void meshdeform_vert_task(void *userdata, int iter)
if (totweight > 0.0f) {
mul_v3_fl(co, fac / totweight);
mul_m3_v3(data->icagemat, co);
- BLI_spin_lock(&data->lock);
if (G.debug_value != 527)
add_v3_v3(vertexCos[iter], co);
else
copy_v3_v3(vertexCos[iter], co);
- BLI_spin_unlock(&data->lock);
}
}
@@ -395,14 +398,10 @@ static void meshdeformModifier_do(
data.vertexCos = vertexCos;
data.cagemat = cagemat;
data.icagemat = icagemat;
- BLI_spin_init(&data.lock);
/* Do deformation. */
BLI_task_parallel_range(0, totvert, &data, meshdeform_vert_task);
- /* Uninitialize user dtaa used by the task system. */
- BLI_spin_end(&data.lock);
-
/* release cage derivedmesh */
MEM_freeN(dco);
MEM_freeN(cagecos);
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c
index 5de4a76dcbe..5285bc4124d 100644
--- a/source/blender/modifiers/intern/MOD_mirror.c
+++ b/source/blender/modifiers/intern/MOD_mirror.c
@@ -42,8 +42,6 @@
#include "BKE_modifier.h"
#include "BKE_deform.h"
-#include "bmesh.h"
-
#include "MEM_guardedalloc.h"
#include "depsgraph_private.h"
@@ -75,6 +73,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob,
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index deae10b5bcb..4754813a744 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -44,11 +44,8 @@
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_modifier.h"
-#include "BKE_paint.h"
#include "BKE_subsurf.h"
-#include "MOD_util.h"
-
static void initData(ModifierData *md)
{
MultiresModifierData *mmd = (MultiresModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
new file mode 100644
index 00000000000..edb7278789b
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -0,0 +1,514 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Bastien Montagne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_normal_edit.c
+ * \ingroup modifiers
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_bitmap.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_mesh.h"
+#include "BKE_deform.h"
+
+#include "depsgraph_private.h"
+
+#include "MOD_util.h"
+
+
+static void generate_vert_coordinates(
+ DerivedMesh *dm, Object *ob, Object *ob_center, const float offset[3],
+ const int num_verts, float (*r_cos)[3], float r_size[3])
+{
+ float min_co[3], max_co[3];
+ float diff[3];
+ bool do_diff = false;
+
+ INIT_MINMAX(min_co, max_co);
+
+ dm->getVertCos(dm, r_cos);
+
+ /* Get size (i.e. deformation of the spheroid generating normals), either from target object, or own geometry. */
+ if (ob_center) {
+ copy_v3_v3(r_size, ob_center->size);
+ }
+ else {
+ minmax_v3v3_v3_array(min_co, max_co, r_cos, num_verts);
+ /* Set size. */
+ sub_v3_v3v3(r_size, max_co, min_co);
+ }
+
+ /* Error checks - we do not want one or more of our sizes to be null! */
+ if (is_zero_v3(r_size)) {
+ r_size[0] = r_size[1] = r_size[2] = 1.0f;
+ }
+ else {
+ CLAMP_MIN(r_size[0], FLT_EPSILON);
+ CLAMP_MIN(r_size[1], FLT_EPSILON);
+ CLAMP_MIN(r_size[2], FLT_EPSILON);
+ }
+
+ if (ob_center) {
+ /* Translate our coordinates so that center of ob_center is at (0, 0, 0). */
+ float mat[4][4];
+
+ /* Get ob_center coordinates in ob local coordinates. */
+ invert_m4_m4(mat, ob_center->obmat);
+ mul_m4_m4m4(mat, mat, ob->obmat);
+ copy_v3_v3(diff, mat[3]);
+
+ do_diff = true;
+ }
+ else if (!is_zero_v3(offset)) {
+ negate_v3_v3(diff, offset);
+
+ do_diff = true;
+ }
+ /* Else, no need to change coordinates! */
+
+ if (do_diff) {
+ int i = num_verts;
+ while (i--) {
+ add_v3_v3(r_cos[i], diff);
+ }
+ }
+}
+
+/* Note this modifies nos_new in-place. */
+static void mix_normals(
+ const float mix_factor, MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup,
+ const short mix_mode,
+ const int num_verts, MLoop *mloop, float (*nos_old)[3], float (*nos_new)[3], const int num_loops)
+{
+ /* Mix with org normals... */
+ float *facs = NULL, *wfac;
+ float (*no_new)[3], (*no_old)[3];
+ int i;
+
+ if (dvert) {
+ facs = MEM_mallocN(sizeof(*facs) * (size_t)num_loops, __func__);
+ BKE_defvert_extract_vgroup_to_loopweights(
+ dvert, defgrp_index, num_verts, mloop, num_loops, facs, use_invert_vgroup);
+ }
+
+ for (i = num_loops, no_new = nos_new, no_old = nos_old, wfac = facs; i--; no_new++, no_old++, wfac++) {
+ const float fac = facs ? *wfac * mix_factor : mix_factor;
+
+ switch (mix_mode) {
+ case MOD_NORMALEDIT_MIX_ADD:
+ add_v3_v3(*no_new, *no_old);
+ normalize_v3(*no_new);
+ break;
+ case MOD_NORMALEDIT_MIX_SUB:
+ sub_v3_v3(*no_new, *no_old);
+ normalize_v3(*no_new);
+ break;
+ case MOD_NORMALEDIT_MIX_MUL:
+ mul_v3_v3(*no_new, *no_old);
+ normalize_v3(*no_new);
+ break;
+ case MOD_NORMALEDIT_MIX_COPY:
+ break;
+ }
+ interp_v3_v3v3_slerp_safe(*no_new, *no_old, *no_new, fac);
+ }
+
+ MEM_SAFE_FREE(facs);
+}
+
+static void normalEditModifier_do_radial(
+ NormalEditModifierData *smd, Object *ob, DerivedMesh *dm,
+ short (*clnors)[2], float (*loopnors)[3], float (*polynors)[3],
+ const short mix_mode, const float mix_factor,
+ MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup,
+ MVert *mvert, const int num_verts, MEdge *medge, const int num_edges,
+ MLoop *mloop, const int num_loops, MPoly *mpoly, const int num_polys)
+{
+ int i;
+
+ float (*cos)[3] = MEM_mallocN(sizeof(*cos) * num_verts, __func__);
+ float (*nos)[3] = MEM_mallocN(sizeof(*nos) * num_loops, __func__);
+ float size[3];
+
+ BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__);
+
+ generate_vert_coordinates(dm, ob, smd->target, smd->offset, num_verts, cos, size);
+
+ /**
+ * size gives us our spheroid coefficients ``(A, B, C)``.
+ * Then, we want to find out for each vert its (a, b, c) triple (proportional to (A, B, C) one).
+ *
+ * Ellipsoid basic equation: ``(x^2/a^2) + (y^2/b^2) + (z^2/c^2) = 1.``
+ * Since we want to find (a, b, c) matching this equation and proportional to (A, B, C), we can do:
+ * <pre>
+ * m = B / A
+ * n = C / A
+ * </pre>
+ *
+ * hence:
+ * <pre>
+ * (x^2/a^2) + (y^2/b^2) + (z^2/c^2) = 1
+ * -> b^2*c^2*x^2 + a^2*c^2*y^2 + a^2*b^2*z^2 = a^2*b^2*c^2
+ * b = ma
+ * c = na
+ * -> m^2*a^2*n^2*a^2*x^2 + a^2*n^2*a^2*y^2 + a^2*m^2*a^2*z^2 = a^2*m^2*a^2*n^2*a^2
+ * -> m^2*n^2*a^4*x^2 + n^2*a^4*y^2 + m^2*a^4*z^2 = m^2*n^2*a^6
+ * -> a^2 = (m^2*n^2*x^2 + n^2y^2 + m^2z^2) / (m^2*n^2) = x^2 + (y^2 / m^2) + (z^2 / n^2)
+ * -> b^2 = (m^2*n^2*x^2 + n^2y^2 + m^2z^2) / (n^2) = (m^2 * x^2) + y^2 + (m^2 * z^2 / n^2)
+ * -> c^2 = (m^2*n^2*x^2 + n^2y^2 + m^2z^2) / (m^2) = (n^2 * x^2) + (n^2 * y^2 / m^2) + z^2
+ * </pre>
+ *
+ * All we have to do now is compute normal of the spheroid at that point:
+ * <pre>
+ * n = (x / a^2, y / b^2, z / c^2)
+ * </pre>
+ * And we are done!
+ */
+ {
+ const float a = size[0], b = size[1], c = size[2];
+ const float m2 = (b * b) / (a * a);
+ const float n2 = (c * c) / (a * a);
+
+ MLoop *ml;
+ float (*no)[3];
+
+ /* We reuse cos to now store the ellipsoid-normal of the verts! */
+ for (i = num_loops, ml = mloop, no = nos; i-- ; ml++, no++) {
+ const int vidx = ml->v;
+ float *co = cos[vidx];
+
+ if (!BLI_BITMAP_TEST(done_verts, vidx)) {
+ const float x2 = co[0] * co[0];
+ const float y2 = co[1] * co[1];
+ const float z2 = co[2] * co[2];
+ const float a2 = x2 + (y2 / m2) + (z2 / n2);
+ const float b2 = (m2 * x2) + y2 + (m2 * z2 / n2);
+ const float c2 = (n2 * x2) + (n2 * y2 / m2) + z2;
+
+ co[0] /= a2;
+ co[1] /= b2;
+ co[2] /= c2;
+ normalize_v3(co);
+
+ BLI_BITMAP_ENABLE(done_verts, vidx);
+ }
+ copy_v3_v3(*no, co);
+ }
+ }
+
+ if (loopnors) {
+ mix_normals(mix_factor, dvert, defgrp_index, use_invert_vgroup,
+ mix_mode, num_verts, mloop, loopnors, nos, num_loops);
+ }
+
+ BKE_mesh_normals_loop_custom_set(mvert, num_verts, medge, num_edges, mloop, nos, num_loops,
+ mpoly, (const float(*)[3])polynors, num_polys, clnors);
+
+ MEM_freeN(cos);
+ MEM_freeN(nos);
+ MEM_freeN(done_verts);
+}
+
+static void normalEditModifier_do_directional(
+ NormalEditModifierData *smd, Object *ob, DerivedMesh *dm,
+ short (*clnors)[2], float (*loopnors)[3], float (*polynors)[3],
+ const short mix_mode, const float mix_factor,
+ MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup,
+ MVert *mvert, const int num_verts, MEdge *medge, const int num_edges,
+ MLoop *mloop, const int num_loops, MPoly *mpoly, const int num_polys)
+{
+ const bool use_parallel_normals = (smd->flag & MOD_NORMALEDIT_USE_DIRECTION_PARALLEL) != 0;
+
+ float (*cos)[3] = MEM_mallocN(sizeof(*cos) * num_verts, __func__);
+ float (*nos)[3] = MEM_mallocN(sizeof(*nos) * num_loops, __func__);
+
+ float target_co[3];
+ int i;
+
+ dm->getVertCos(dm, cos);
+
+ /* Get target's center coordinates in ob local coordinates. */
+ {
+ float mat[4][4];
+
+ invert_m4_m4(mat, ob->obmat);
+ mul_m4_m4m4(mat, mat, smd->target->obmat);
+ copy_v3_v3(target_co, mat[3]);
+ }
+
+ if (use_parallel_normals) {
+ float no[3];
+
+ sub_v3_v3v3(no, target_co, smd->offset);
+ normalize_v3(no);
+
+ for (i = num_loops; i--; ) {
+ copy_v3_v3(nos[i], no);
+ }
+ }
+ else {
+ BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__);
+ MLoop *ml;
+ float (*no)[3];
+
+ /* We reuse cos to now store the 'to target' normal of the verts! */
+ for (i = num_loops, no = nos, ml = mloop; i--; no++, ml++) {
+ const int vidx = ml->v;
+ float *co = cos[vidx];
+
+ if (!BLI_BITMAP_TEST(done_verts, vidx)) {
+ sub_v3_v3v3(co, target_co, co);
+ normalize_v3(co);
+
+ BLI_BITMAP_ENABLE(done_verts, vidx);
+ }
+
+ copy_v3_v3(*no, co);
+ }
+
+ MEM_freeN(done_verts);
+ }
+
+ if (loopnors) {
+ mix_normals(mix_factor, dvert, defgrp_index, use_invert_vgroup,
+ mix_mode, num_verts, mloop, loopnors, nos, num_loops);
+ }
+
+ BKE_mesh_normals_loop_custom_set(mvert, num_verts, medge, num_edges, mloop, nos, num_loops,
+ mpoly, (const float(*)[3])polynors, num_polys, clnors);
+
+ MEM_freeN(cos);
+ MEM_freeN(nos);
+}
+
+static bool is_valid_target(NormalEditModifierData *smd)
+{
+ if (smd->mode == MOD_NORMALEDIT_MODE_RADIAL) {
+ return true;
+ }
+ else if ((smd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && smd->target) {
+ return true;
+ }
+ modifier_setError((ModifierData *)smd, "Invalid target settings");
+ return false;
+}
+
+static DerivedMesh *normalEditModifier_do(NormalEditModifierData *smd, Object *ob, DerivedMesh *dm)
+{
+ Mesh *me = ob->data;
+
+ const int num_verts = dm->getNumVerts(dm);
+ const int num_edges = dm->getNumEdges(dm);
+ const int num_loops = dm->getNumLoops(dm);
+ const int num_polys = dm->getNumPolys(dm);
+ MVert *mvert;
+ MEdge *medge;
+ MLoop *mloop;
+ MPoly *mpoly;
+
+ const bool use_invert_vgroup = ((smd->flag & MOD_NORMALEDIT_INVERT_VGROUP) != 0);
+ const bool use_current_clnors = !((smd->mix_mode == MOD_NORMALEDIT_MIX_COPY) &&
+ (smd->mix_factor == 1.0f) &&
+ (smd->defgrp_name[0] == '\0'));
+
+ int defgrp_index;
+ MDeformVert *dvert;
+
+ float (*loopnors)[3] = NULL;
+ short (*clnors)[2];
+
+ float (*polynors)[3];
+ bool free_polynors = false;
+
+ /* Do not run that modifier at all if autosmooth is disabled! */
+ if (!is_valid_target(smd) || !num_loops) {
+ return dm;
+ }
+
+ if (!(me->flag & ME_AUTOSMOOTH)) {
+ modifier_setError((ModifierData *)smd, "Enable 'Auto Smooth' option in mesh settings");
+ return dm;
+ }
+
+ medge = dm->getEdgeArray(dm);
+ if (me->medge == medge) {
+ /* We need to duplicate data here, otherwise setting custom normals (which may also affect sharp edges) could
+ * modify org mesh, see T43671. */
+ dm = CDDM_copy(dm);
+ medge = dm->getEdgeArray(dm);
+ }
+ mvert = dm->getVertArray(dm);
+ mloop = dm->getLoopArray(dm);
+ mpoly = dm->getPolyArray(dm);
+
+ if (use_current_clnors) {
+ dm->calcLoopNormals(dm, true, me->smoothresh);
+ loopnors = dm->getLoopDataArray(dm, CD_NORMAL);
+ }
+
+ clnors = CustomData_duplicate_referenced_layer(&dm->loopData, CD_CUSTOMLOOPNORMAL, num_loops);
+ if (!clnors) {
+ DM_add_loop_layer(dm, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL);
+ clnors = dm->getLoopDataArray(dm, CD_CUSTOMLOOPNORMAL);
+ }
+
+ polynors = dm->getPolyDataArray(dm, CD_NORMAL);
+ if (!polynors) {
+ polynors = MEM_mallocN(sizeof(*polynors) * num_polys, __func__);
+ BKE_mesh_calc_normals_poly(mvert, num_verts, mloop, mpoly, num_loops, num_polys, polynors, false);
+ free_polynors = true;
+ }
+
+ modifier_get_vgroup(ob, dm, smd->defgrp_name, &dvert, &defgrp_index);
+
+ if (smd->mode == MOD_NORMALEDIT_MODE_RADIAL) {
+ normalEditModifier_do_radial(
+ smd, ob, dm, clnors, loopnors, polynors,
+ smd->mix_mode, smd->mix_factor, dvert, defgrp_index, use_invert_vgroup,
+ mvert, num_verts, medge, num_edges, mloop, num_loops, mpoly, num_polys);
+ }
+ else if (smd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) {
+ normalEditModifier_do_directional(
+ smd, ob, dm, clnors, loopnors, polynors,
+ smd->mix_mode, smd->mix_factor, dvert, defgrp_index, use_invert_vgroup,
+ mvert, num_verts, medge, num_edges, mloop, num_loops, mpoly, num_polys);
+ }
+
+ if (free_polynors) {
+ MEM_freeN(polynors);
+ }
+
+ return dm;
+}
+
+static void initData(ModifierData *md)
+{
+ NormalEditModifierData *smd = (NormalEditModifierData *)md;
+
+ smd->mode = MOD_NORMALEDIT_MODE_RADIAL;
+
+ smd->mix_mode = MOD_NORMALEDIT_MIX_COPY;
+ smd->mix_factor = 1.0f;
+}
+
+static void copyData(ModifierData *md, ModifierData *target)
+{
+ modifier_copyData_generic(md, target);
+}
+
+static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
+{
+ NormalEditModifierData *smd = (NormalEditModifierData *)md;
+ CustomDataMask dataMask = CD_CUSTOMLOOPNORMAL;
+
+ /* Ask for vertexgroups if we need them. */
+ if (smd->defgrp_name[0]) {
+ dataMask |= (CD_MASK_MDEFORMVERT);
+ }
+
+ return dataMask;
+}
+
+static bool dependsOnNormals(ModifierData *UNUSED(md))
+{
+ return true;
+}
+
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+{
+ NormalEditModifierData *smd = (NormalEditModifierData *) md;
+
+ walk(userData, ob, &smd->target);
+}
+
+static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ NormalEditModifierData *smd = (NormalEditModifierData *) md;
+
+ walk(userData, ob, (ID **)&smd->target);
+}
+
+static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
+{
+ NormalEditModifierData *smd = (NormalEditModifierData *)md;
+
+ return !is_valid_target(smd);
+}
+
+static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
+ struct Scene *UNUSED(scene),
+ Object *UNUSED(ob), DagNode *obNode)
+{
+ NormalEditModifierData *smd = (NormalEditModifierData *) md;
+
+ if (smd->target) {
+ DagNode *Node = dag_get_node(forest, smd->target);
+
+ dag_add_relation(forest, Node, obNode, DAG_RL_OB_DATA, "NormalEdit Modifier");
+ }
+}
+
+static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, ModifierApplyFlag UNUSED(flag))
+{
+ return normalEditModifier_do((NormalEditModifierData *)md, ob, dm);
+}
+
+ModifierTypeInfo modifierType_NormalEdit = {
+ /* name */ "Set Split Normals",
+ /* structName */ "NormalEditModifierData",
+ /* structSize */ sizeof(NormalEditModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh |
+ eModifierTypeFlag_AcceptsCVs |
+ eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode |
+ eModifierTypeFlag_EnableInEditmode,
+ /* copyData */ copyData,
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+ /* applyModifierEM */ NULL,
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepgraph */ updateDepgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index a324702a6ae..1c8dcdff46d 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -43,8 +43,6 @@
#include "BKE_modifier.h"
#include "BKE_ocean.h"
-#include "MOD_util.h"
-
#ifdef WITH_OCEANSIM
static void init_cache_data(Object *ob, struct OceanModifierData *omd)
{
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index 7aa81d6a003..29ba7dda5db 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -43,13 +43,13 @@
#include "BLI_utildefines.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_effect.h"
+#include "BKE_global.h"
#include "BKE_lattice.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
-#include "MOD_util.h"
-
#include "depsgraph_private.h"
@@ -111,6 +111,7 @@ static bool isDisabled(ModifierData *md, int useRenderParams)
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
@@ -185,7 +186,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
int maxvert, maxpoly, maxloop, totpart = 0, first_particle = 0;
int k, p, p_skip;
short track = ob->trackflag % 3, trackneg, axis = pimd->axis;
- float max_co = 0.0, min_co = 0.0, temp_co[3], cross[3];
+ float max_co = 0.0, min_co = 0.0, temp_co[3];
float *size = NULL;
trackneg = ((ob->trackflag > 2) ? 1 : 0);
@@ -278,6 +279,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
orig_mloop = dm->getLoopArray(dm);
for (p = 0, p_skip = 0; p < totpart; p++) {
+ float prev_dir[3];
+ float frame[4]; /* frame orientation quaternion */
+
/* skip particle? */
if (particle_skip(pimd, psys, p))
continue;
@@ -323,19 +327,55 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
normalize_v3(state.vel);
- /* TODO: incremental rotations somehow */
+ /* Incrementally Rotating Frame (Bishop Frame) */
+ if (k == 0) {
+ float hairmat[4][4];
+ float mat[3][3];
+
+ if (first_particle + p < psys->totpart)
+ pa = psys->particles + first_particle + p;
+ else {
+ ChildParticle *cpa = psys->child + (p - psys->totpart);
+ pa = psys->particles + cpa->parent;
+ }
+ psys_mat_hair_to_global(sim.ob, sim.psmd->dm, sim.psys->part->from, pa, hairmat);
+ copy_m3_m4(mat, hairmat);
+ /* to quaternion */
+ mat3_to_quat(frame, mat);
+
+ /* note: direction is same as normal vector currently,
+ * but best to keep this separate so the frame can be
+ * rotated later if necessary
+ */
+ copy_v3_v3(prev_dir, state.vel);
+ }
+ else {
+ float rot[4];
+
+ /* incrementally rotate along bend direction */
+ rotation_between_vecs_to_quat(rot, prev_dir, state.vel);
+ mul_qt_qtqt(frame, rot, frame);
+
+ copy_v3_v3(prev_dir, state.vel);
+ }
+
+ copy_qt_qt(state.rot, frame);
+#if 0
+ /* Absolute Frame (Frenet Frame) */
if (state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) {
unit_qt(state.rot);
}
else {
+ float cross[3];
float temp[3] = {0.0f, 0.0f, 0.0f};
temp[axis] = 1.0f;
-
+
cross_v3_v3v3(cross, temp, state.vel);
-
+
/* state.vel[axis] is the only component surviving from a dot product with the axis */
axis_angle_to_quat(state.rot, cross, saacos(state.vel[axis]));
}
+#endif
}
else {
state.time = -1.0;
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index a41fbb03462..9860daeda4c 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -85,37 +85,7 @@ static void copyData(ModifierData *md, ModifierData *target)
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
{
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
- CustomDataMask dataMask = 0;
- MTex *mtex;
- int i;
-
- if (!psmd->psys->part)
- return 0;
-
- for (i = 0; i < MAX_MTEX; i++) {
- mtex = psmd->psys->part->mtex[i];
- if (mtex && mtex->mapto && (mtex->texco & TEXCO_UV))
- dataMask |= CD_MASK_MTFACE;
- }
-
- if (psmd->psys->part->tanfac != 0.0f)
- dataMask |= CD_MASK_MTFACE;
-
- /* ask for vertexgroups if we need them */
- for (i = 0; i < PSYS_TOT_VG; i++) {
- if (psmd->psys->vgroup[i]) {
- dataMask |= CD_MASK_MDEFORMVERT;
- break;
- }
- }
-
- /* particles only need this if they are after a non deform modifier, and
- * the modifier stack will only create them in that case. */
- dataMask |= CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORIGINDEX;
-
- dataMask |= CD_MASK_ORCO;
-
- return dataMask;
+ return psys_emitter_customdata_mask(psmd->psys);
}
/* saves the current emitter state for a particle system and calculates particles */
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index 5900baaf537..2c9f5e32440 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -1058,6 +1058,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c
index 45725d1c453..f3327a03f2c 100644
--- a/source/blender/modifiers/intern/MOD_shapekey.c
+++ b/source/blender/modifiers/intern/MOD_shapekey.c
@@ -44,7 +44,7 @@
#include "MOD_modifiertypes.h"
-static void deformVerts(ModifierData *md, Object *ob,
+static void deformVerts(ModifierData *UNUSED(md), Object *ob,
DerivedMesh *UNUSED(derivedData),
float (*vertexCos)[3],
int numVerts,
@@ -54,8 +54,9 @@ static void deformVerts(ModifierData *md, Object *ob,
if (key && key->block.first) {
int deformedVerts_tot;
- BKE_key_evaluate_object_ex(md->scene, ob, &deformedVerts_tot,
- (float *)vertexCos, sizeof(*vertexCos) * numVerts);
+ BKE_key_evaluate_object_ex(
+ ob, &deformedVerts_tot,
+ (float *)vertexCos, sizeof(*vertexCos) * numVerts);
}
}
diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c
index 229f4911ab4..fd583c43d6e 100644
--- a/source/blender/modifiers/intern/MOD_shrinkwrap.c
+++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c
@@ -38,7 +38,6 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
-#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_cdderivedmesh.h"
@@ -144,6 +143,7 @@ static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editD
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index 3314196b776..0e1cb125a47 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -244,8 +244,6 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object
}
-
-
/* SimpleDeform */
static void initData(ModifierData *md)
{
@@ -289,6 +287,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob,
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 1e422806d80..bd16fd07044 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -79,8 +79,6 @@
#include "bmesh.h"
-#include "MOD_util.h"
-
typedef struct {
float mat[3][3];
/* Vert that edge is pointing away from, no relation to
@@ -328,8 +326,7 @@ static bool build_hull(SkinOutput *so, Frame **frames, int totframe)
return true;
#else
- (void)so, (void)frames, (void)totframe;
- (void)skin_frame_find_contained_faces;
+ UNUSED_VARS(so, frames, totframe, skin_frame_find_contained_faces);
return false;
#endif
}
@@ -968,23 +965,51 @@ static void add_poly(SkinOutput *so,
f->mat_nr = so->mat_nr;
}
-static void connect_frames(SkinOutput *so,
- BMVert *frame1[4],
-BMVert *frame2[4])
+static void connect_frames(
+ SkinOutput *so,
+ BMVert *frame1[4],
+ BMVert *frame2[4])
{
BMVert *q[4][4] = {{frame2[0], frame2[1], frame1[1], frame1[0]},
{frame2[1], frame2[2], frame1[2], frame1[1]},
{frame2[2], frame2[3], frame1[3], frame1[2]},
{frame2[3], frame2[0], frame1[0], frame1[3]}};
- float p[3], no[3];
- int i, swap;
+ int i;
+ bool swap;
/* Check if frame normals need swap */
- sub_v3_v3v3(p, q[3][0]->co, q[0][0]->co);
- normal_quad_v3(no,
- q[0][0]->co, q[0][1]->co,
- q[0][2]->co, q[0][3]->co);
- swap = dot_v3v3(no, p) > 0;
+#if 0
+ {
+ /* simple method, works mostly */
+ float p[3], no[3];
+ sub_v3_v3v3(p, q[3][0]->co, q[0][0]->co);
+ normal_quad_v3(no,
+ q[0][0]->co, q[0][1]->co,
+ q[0][2]->co, q[0][3]->co);
+ swap = dot_v3v3(no, p) > 0;
+ }
+#else
+ {
+ /* comprehensive method, accumulate flipping of all faces */
+ float cent_sides[4][3];
+ float cent[3];
+ float dot = 0.0f;
+
+ for (i = 0; i < 4; i++) {
+ mid_v3_v3v3v3v3(cent_sides[i], UNPACK4_EX(, q[i], ->co));
+ }
+ mid_v3_v3v3v3v3(cent, UNPACK4(cent_sides));
+
+ for (i = 0; i < 4; i++) {
+ float p[3], no[3];
+ normal_quad_v3(no, UNPACK4_EX(, q[i], ->co));
+ sub_v3_v3v3(p, cent, cent_sides[i]);
+ dot += dot_v3v3(no, p);
+ }
+
+ swap = dot > 0;
+ }
+#endif
for (i = 0; i < 4; i++) {
if (swap)
@@ -1117,7 +1142,7 @@ static BMFace *collapse_face_corners(BMesh *bm, BMFace *f, int n,
orig_verts[i] = NULL;
}
else if (orig_verts[i] &&
- !BM_vert_in_face(vf, orig_verts[i]))
+ !BM_vert_in_face(orig_verts[i], vf))
{
wrong_face = true;
break;
@@ -1263,7 +1288,7 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f
BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
"subdivide_edges edges=%he cuts=%i quad_corner_type=%i",
- BM_ELEM_TAG, 1, SUBD_STRAIGHT_CUT);
+ BM_ELEM_TAG, 1, SUBD_CORNER_STRAIGHT_CUT);
}
else if (split_face->len > 4) {
/* Maintain a dynamic vert array containing the split_face's
diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c
index fcd4cc96410..74409498ca3 100644
--- a/source/blender/modifiers/intern/MOD_smoke.c
+++ b/source/blender/modifiers/intern/MOD_smoke.c
@@ -47,14 +47,13 @@
#include "BKE_cdderivedmesh.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_smoke.h"
#include "depsgraph_private.h"
-#include "MOD_util.h"
-
-
static void initData(ModifierData *md)
{
SmokeModifierData *smd = (SmokeModifierData *) md;
@@ -117,7 +116,65 @@ static bool dependsOnTime(ModifierData *UNUSED(md))
return true;
}
+static void update_depsgraph_flow_coll_object(DagForest *forest,
+ DagNode *obNode,
+ Object *object2)
+{
+ SmokeModifierData *smd;
+ if ((object2->id.flag & LIB_DOIT) == 0) {
+ return;
+ }
+ object2->id.flag &= ~LIB_DOIT;
+ smd = (SmokeModifierData *)modifiers_findByType(object2, eModifierType_Smoke);
+ if (smd && (((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) ||
+ ((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll)))
+ {
+ DagNode *curNode = dag_get_node(forest, object2);
+ dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Smoke Flow/Coll");
+ }
+ if ((object2->transflag & OB_DUPLIGROUP) && object2->dup_group) {
+ GroupObject *go;
+ for (go = object2->dup_group->gobject.first;
+ go != NULL;
+ go = go->next)
+ {
+ if (go->ob == NULL) {
+ continue;
+ }
+ update_depsgraph_flow_coll_object(forest, obNode, go->ob);
+ }
+ }
+}
+
+static void update_depsgraph_field_source_object(DagForest *forest,
+ DagNode *obNode,
+ Object *object,
+ Object *object2)
+{
+ if ((object2->id.flag & LIB_DOIT) == 0) {
+ return;
+ }
+ object2->id.flag &= ~LIB_DOIT;
+ if (object2->pd && object2->pd->forcefield == PFIELD_SMOKEFLOW && object2->pd->f_source == object) {
+ DagNode *node2 = dag_get_node(forest, object2);
+ dag_add_relation(forest, obNode, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Source Object");
+ }
+ if ((object2->transflag & OB_DUPLIGROUP) && object2->dup_group) {
+ GroupObject *go;
+ for (go = object2->dup_group->gobject.first;
+ go != NULL;
+ go = go->next)
+ {
+ if (go->ob == NULL) {
+ continue;
+ }
+ update_depsgraph_field_source_object(forest, obNode, object, go->ob);
+ }
+ }
+}
+
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *bmain,
struct Scene *scene, struct Object *ob,
DagNode *obNode)
{
@@ -155,23 +212,17 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
}
}
else {
+ BKE_main_id_tag_listbase(&bmain->object, true);
base = scene->base.first;
for (; base; base = base->next) {
- SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(base->object, eModifierType_Smoke);
-
- if (smd2 && (((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) || ((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll))) {
- DagNode *curNode = dag_get_node(forest, base->object);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Smoke Flow/Coll");
- }
+ update_depsgraph_flow_coll_object(forest, obNode, base->object);
}
}
/* add relation to all "smoke flow" force fields */
base = scene->base.first;
+ BKE_main_id_tag_listbase(&bmain->object, true);
for (; base; base = base->next) {
- if (base->object->pd && base->object->pd->forcefield == PFIELD_SMOKEFLOW && base->object->pd->f_source == ob) {
- DagNode *node2 = dag_get_node(forest, base->object);
- dag_add_relation(forest, obNode, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Source Object");
- }
+ update_depsgraph_field_source_object(forest, obNode, ob, base->object);
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 813ef285058..08b8854c728 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -220,7 +220,7 @@ static DerivedMesh *applyModifier(
const unsigned int numEdges = (unsigned int)dm->getNumEdges(dm);
const unsigned int numFaces = (unsigned int)dm->getNumPolys(dm);
const unsigned int numLoops = (unsigned int)dm->getNumLoops(dm);
- unsigned int newLoops = 0, newFaces = 0, newEdges = 0, newVerts = 0;
+ unsigned int newLoops = 0, newFaces = 0, newEdges = 0, newVerts = 0, rimVerts = 0;
/* only use material offsets if we have 2 or more materials */
const short mat_nr_max = ob->totcol > 1 ? ob->totcol - 1 : 0;
@@ -343,7 +343,7 @@ static DerivedMesh *applyModifier(
if (BLI_BITMAP_TEST(orig_mvert_tag, i)) {
old_vert_arr[i] = STACK_SIZE(new_vert_arr);
STACK_PUSH(new_vert_arr, i);
- newEdges++;
+ rimVerts++;
}
else {
old_vert_arr[i] = INVALID_UNUSED;
@@ -353,16 +353,26 @@ static DerivedMesh *applyModifier(
MEM_freeN(orig_mvert_tag);
}
+ if (do_shell == false) {
+ /* only add rim vertices */
+ newVerts = rimVerts;
+ /* each extruded face needs an opposite edge */
+ newEdges = newFaces;
+ }
+ else {
+ /* (stride == 2) in this case, so no need to add newVerts/newEdges */
+ BLI_assert(newVerts == 0);
+ BLI_assert(newEdges == 0);
+ }
+
if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) {
vert_nors = MEM_callocN(sizeof(float) * (size_t)numVerts * 3, "mod_solid_vno_hq");
dm_calc_normal(dm, face_nors, vert_nors);
}
- newVerts = do_shell ? 0 : newEdges;
-
result = CDDM_from_template(dm,
(int)((numVerts * stride) + newVerts),
- (int)((numEdges * stride) + newEdges + newVerts), 0,
+ (int)((numEdges * stride) + newEdges + rimVerts), 0,
(int)((numLoops * stride) + newLoops),
(int)((numFaces * stride) + newFaces));
@@ -659,7 +669,7 @@ static DerivedMesh *applyModifier(
}
if (do_clamp) {
- float *vert_lens_sq = MEM_callocN(sizeof(float) * numVerts, "vert_lens");
+ float *vert_lens_sq = MEM_mallocN(sizeof(float) * numVerts, "vert_lens");
const float offset = fabsf(smd->offset) * smd->offset_clamp;
const float offset_sq = offset * offset;
fill_vn_fl(vert_lens_sq, (int)numVerts, FLT_MAX);
@@ -759,9 +769,9 @@ static DerivedMesh *applyModifier(
/* add faces & edges */
origindex_edge = result->getEdgeDataArray(result, CD_ORIGINDEX);
- ed = &medge[(numEdges * stride) + newVerts]; /* start after copied edges */
- orig_ed = &origindex_edge[(numEdges * stride) + newVerts];
- for (i = 0; i < newEdges; i++, ed++, orig_ed++) {
+ ed = &medge[(numEdges * stride) + newEdges]; /* start after copied edges */
+ orig_ed = &origindex_edge[(numEdges * stride) + newEdges];
+ for (i = 0; i < rimVerts; i++, ed++, orig_ed++) {
ed->v1 = new_vert_arr[i];
ed->v2 = (do_shell ? new_vert_arr[i] : i) + numVerts;
ed->flag |= ME_EDGEDRAW;
@@ -816,26 +826,26 @@ static DerivedMesh *applyModifier(
ml[j++].e = eidx;
ml[j].v = ed->v2;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newVerts;
+ ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges;
ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts;
ml[j++].e = (do_shell ? eidx : i) + numEdges;
ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newVerts;
+ ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges;
}
else {
ml[j].v = ed->v2;
ml[j++].e = eidx;
ml[j].v = ed->v1;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newVerts;
+ ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges;
ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts;
ml[j++].e = (do_shell ? eidx : i) + numEdges;
ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newVerts;
+ ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges;
}
origindex_edge[ml[j - 3].e] = ORIGINDEX_NONE;
@@ -877,7 +887,7 @@ static DerivedMesh *applyModifier(
#ifdef SOLIDIFY_SIDE_NORMALS
if (do_side_normals) {
ed = medge + (numEdges * stride);
- for (i = 0; i < newEdges; i++, ed++) {
+ for (i = 0; i < rimVerts; i++, ed++) {
float nor_cpy[3];
short *nor_short;
int k;
diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c
index 4cae3d662db..592ab4194ec 100644
--- a/source/blender/modifiers/intern/MOD_triangulate.c
+++ b/source/blender/modifiers/intern/MOD_triangulate.c
@@ -31,7 +31,6 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_modifier.h"
-#include "BKE_editmesh.h"
#include "bmesh.h"
#include "bmesh_tools.h"
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index 829c2b88995..c23c22b5fec 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -32,7 +32,6 @@
#include <string.h>
-#include "DNA_curve_types.h"
#include "DNA_image_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -48,8 +47,6 @@
#include "BKE_image.h"
#include "BKE_lattice.h"
#include "BKE_mesh.h"
-#include "BKE_displist.h"
-#include "BKE_scene.h"
#include "BKE_modifier.h"
@@ -58,8 +55,6 @@
#include "MEM_guardedalloc.h"
-#include "RE_shader_ext.h"
-
#ifdef OPENNL_THREADING_HACK
#include "BLI_threads.h"
#endif
@@ -164,8 +159,8 @@ DerivedMesh *get_cddm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float
if (dm) {
if (dm->type != DM_TYPE_CDDM) {
dm = CDDM_copy(dm);
- CDDM_apply_vert_coords(dm, vertexCos);
}
+ CDDM_apply_vert_coords(dm, vertexCos);
if (use_normals) {
DM_ensure_normals(dm);
@@ -309,5 +304,7 @@ void modifier_type_init(ModifierTypeInfo *types[])
INIT_TYPE(MeshCache);
INIT_TYPE(LaplacianDeform);
INIT_TYPE(Wireframe);
+ INIT_TYPE(DataTransfer);
+ INIT_TYPE(NormalEdit);
#undef INIT_TYPE
}
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 2ff93efdb86..a10386a6f41 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -49,7 +49,6 @@
#include "BKE_DerivedMesh.h"
#include "MOD_modifiertypes.h"
-#include "MOD_util.h"
#include "MEM_guardedalloc.h"
#include "depsgraph_private.h"
@@ -105,6 +104,7 @@ static void foreachIDLink(ModifierData *md, Object *ob,
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
index f5ff30e35d9..f41705d1aac 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.c
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -218,6 +218,7 @@ static void uv_warp_deps_object_bone(DagForest *forest, DagNode *obNode,
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
struct Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index f6714e79401..9d496724ba1 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -136,7 +136,9 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "texture");
}
-static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene),
+static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
+ struct Scene *UNUSED(scene),
Object *UNUSED(ob), DagNode *obNode)
{
WarpModifierData *wmd = (WarpModifierData *) md;
@@ -167,6 +169,7 @@ static void warpModifier_do(WarpModifierData *wmd, Object *ob,
float tmat[4][4];
+ const float falloff_radius_sq = SQUARE(wmd->falloff_radius);
float strength = wmd->strength;
float fac = 1.0f, weight;
int i;
@@ -179,6 +182,9 @@ static void warpModifier_do(WarpModifierData *wmd, Object *ob,
return;
modifier_get_vgroup(ob, dm, wmd->defgrp_name, &dvert, &defgrp_index);
+ if (dvert == NULL) {
+ defgrp_index = -1;
+ }
if (wmd->curfalloff == NULL) /* should never happen, but bad lib linking could cause it */
wmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
@@ -222,17 +228,15 @@ static void warpModifier_do(WarpModifierData *wmd, Object *ob,
float *co = vertexCos[i];
if (wmd->falloff_type == eWarp_Falloff_None ||
- ((fac = len_v3v3(co, mat_from[3])) < wmd->falloff_radius &&
- (fac = (wmd->falloff_radius - fac) / wmd->falloff_radius)))
+ ((fac = len_squared_v3v3(co, mat_from[3])) < falloff_radius_sq &&
+ (fac = (wmd->falloff_radius - sqrtf(fac)) / wmd->falloff_radius)))
{
/* skip if no vert group found */
- if (dvert && defgrp_index != -1) {
+ if (defgrp_index != -1) {
dv = &dvert[i];
-
- if (dv) {
- weight = defvert_find_weight(dv, defgrp_index) * strength;
- if (weight <= 0.0f) /* Should never occure... */
- continue;
+ weight = defvert_find_weight(dv, defgrp_index) * strength;
+ if (weight <= 0.0f) {
+ continue;
}
}
@@ -263,6 +267,9 @@ static void warpModifier_do(WarpModifierData *wmd, Object *ob,
case eWarp_Falloff_Sphere:
fac = sqrtf(2 * fac - fac * fac);
break;
+ case eWarp_Falloff_InvSquare:
+ fac = fac * (2.0f - fac);
+ break;
}
fac *= weight;
@@ -274,27 +281,29 @@ static void warpModifier_do(WarpModifierData *wmd, Object *ob,
fac *= texres.tin;
}
- /* into the 'from' objects space */
- mul_m4_v3(mat_from_inv, co);
+ if (fac != 0.0f) {
+ /* into the 'from' objects space */
+ mul_m4_v3(mat_from_inv, co);
- if (fac >= 1.0f) {
- mul_m4_v3(mat_final, co);
- }
- else if (fac > 0.0f) {
- if (wmd->flag & MOD_WARP_VOLUME_PRESERVE) {
- /* interpolate the matrix for nicer locations */
- blend_m4_m4m4(tmat, mat_unit, mat_final, fac);
- mul_m4_v3(tmat, co);
+ if (fac == 1.0f) {
+ mul_m4_v3(mat_final, co);
}
else {
- float tvec[3];
- mul_v3_m4v3(tvec, mat_final, co);
- interp_v3_v3v3(co, co, tvec, fac);
+ if (wmd->flag & MOD_WARP_VOLUME_PRESERVE) {
+ /* interpolate the matrix for nicer locations */
+ blend_m4_m4m4(tmat, mat_unit, mat_final, fac);
+ mul_m4_v3(tmat, co);
+ }
+ else {
+ float tvec[3];
+ mul_v3_m4v3(tvec, mat_final, co);
+ interp_v3_v3v3(co, co, tvec, fac);
+ }
}
- }
- /* out of the 'from' objects space */
- mul_m4_v3(mat_from, co);
+ /* out of the 'from' objects space */
+ mul_m4_v3(mat_from, co);
+ }
}
}
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c
index 47e4c502a90..7fd830dabd4 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.c
@@ -131,6 +131,7 @@ static void foreachTexLink(ModifierData *md, Object *ob,
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
Scene *UNUSED(scene),
Object *UNUSED(ob),
DagNode *obNode)
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c
index 744b6b62c2a..c9de1dc083d 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.c
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.c
@@ -34,7 +34,6 @@
#include "BLI_utildefines.h"
#include "DNA_color_types.h" /* CurveMapping. */
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
@@ -43,11 +42,9 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_colortools.h" /* CurveMapping. */
#include "BKE_deform.h"
-#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_texture.h" /* Texture masking. */
-#include "depsgraph_private.h"
#include "MEM_guardedalloc.h"
#include "MOD_util.h"
#include "MOD_weightvg_util.h"
@@ -235,8 +232,6 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne
}
-
-
/* Applies weights to given vgroup (defgroup), and optionally add/remove vertices from the group.
* If dws is not NULL, it must be an array of MDeformWeight pointers of same length as weights (and
* defgrp_idx can then have any value).
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index f36abcceae0..c4734ccd7a8 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -34,7 +34,6 @@
#include "BLI_rand.h"
#include "DNA_color_types.h" /* CurveMapping. */
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
@@ -48,7 +47,6 @@
#include "depsgraph_private.h"
#include "MEM_guardedalloc.h"
-#include "MOD_util.h"
#include "MOD_weightvg_util.h"
/**************************************
@@ -144,7 +142,9 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "mask_texture");
}
-static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene),
+static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
+ struct Scene *UNUSED(scene),
Object *UNUSED(ob), DagNode *obNode)
{
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index bdc1099d682..4433922f9bb 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -44,7 +44,6 @@
#include "depsgraph_private.h"
#include "MEM_guardedalloc.h"
-#include "MOD_util.h"
#include "MOD_weightvg_util.h"
@@ -192,7 +191,9 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "mask_texture");
}
-static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene),
+static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
+ struct Scene *UNUSED(scene),
Object *UNUSED(ob), DagNode *obNode)
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 71d4742980e..057674f1144 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -47,7 +47,6 @@
#include "depsgraph_private.h"
#include "MEM_guardedalloc.h"
-#include "MOD_util.h"
#include "MOD_weightvg_util.h"
// #define USE_TIMEIT
@@ -313,7 +312,9 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void
walk(userData, ob, md, "mask_texture");
}
-static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene),
+static void updateDepgraph(ModifierData *md, DagForest *forest,
+ struct Main *UNUSED(bmain),
+ struct Scene *UNUSED(scene),
Object *UNUSED(ob), DagNode *obNode)
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c
index 7349ca9f9ef..aa5e6116516 100644
--- a/source/blender/modifiers/intern/MOD_wireframe.c
+++ b/source/blender/modifiers/intern/MOD_wireframe.c
@@ -23,20 +23,14 @@
* \ingroup modifiers
*/
-#include "MEM_guardedalloc.h"
-
#include "DNA_object_types.h"
-#include "DNA_meshdata_types.h"
-#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_string.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_deform.h"
#include "MOD_modifiertypes.h"
-#include "MOD_util.h"
#include "bmesh.h"
#include "tools/bmesh_wireframe.h"
@@ -80,7 +74,7 @@ static bool dependsOnNormals(ModifierData *UNUSED(md))
return true;
}
-static DerivedMesh *WireframeModifier_do( WireframeModifierData *wmd, Object *ob, DerivedMesh *dm)
+static DerivedMesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, DerivedMesh *dm)
{
DerivedMesh *result;
BMesh *bm;
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c
index 6d5b85da569..e616680647e 100644
--- a/source/blender/nodes/composite/node_composite_tree.c
+++ b/source/blender/nodes/composite/node_composite_tree.c
@@ -36,11 +36,8 @@
#include "DNA_scene_types.h"
#include "DNA_node_types.h"
-#include "BLI_listbase.h"
-
#include "BLF_translation.h"
-#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
@@ -50,8 +47,6 @@
#include "node_common.h"
#include "node_util.h"
-#include "PIL_time.h"
-
#include "RNA_access.h"
#include "NOD_composite.h"
@@ -236,11 +231,10 @@ void ntreeCompositExecTree(Scene *scene, bNodeTree *ntree, RenderData *rd, int r
#ifdef WITH_COMPOSITOR
COM_execute(rd, scene, ntree, rendering, view_settings, display_settings);
#else
- (void)scene, (void)ntree, (void)rd, (void)rendering, (void)do_preview;
- (void)view_settings, (void)display_settings;
+ UNUSED_VARS(scene, ntree, rd, rendering, view_settings, display_settings);
#endif
- (void)do_preview;
+ UNUSED_VARS(do_preview);
}
/* *********************************************** */
diff --git a/source/blender/nodes/composite/nodes/node_composite_boxmask.c b/source/blender/nodes/composite/nodes/node_composite_boxmask.c
index 9cb0f1c75c7..0390eb43da0 100644
--- a/source/blender/nodes/composite/nodes/node_composite_boxmask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_boxmask.c
@@ -66,7 +66,3 @@ void register_node_type_cmp_boxmask(void)
nodeRegisterType(&ntype);
}
-
-
-
-
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
index 65f2391983e..70e52d432cd 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
+++ b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c
@@ -29,11 +29,8 @@
* \ingroup cmpnodes
*/
-
-
#include "node_composite_util.h"
-
/* ******************* Color Balance ********************************* */
static bNodeSocketTemplate cmp_node_colorbalance_in[] = {
{SOCK_FLOAT, 1, N_("Fac"), 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR},
diff --git a/source/blender/nodes/composite/nodes/node_composite_common.c b/source/blender/nodes/composite/nodes/node_composite_common.c
index 36c12693bdf..75e7fa8fbac 100644
--- a/source/blender/nodes/composite/nodes/node_composite_common.c
+++ b/source/blender/nodes/composite/nodes/node_composite_common.c
@@ -35,7 +35,6 @@
#include "node_composite_util.h"
#include "NOD_common.h"
#include "node_common.h"
-#include "node_exec.h"
#include "BKE_node.h"
diff --git a/source/blender/nodes/composite/nodes/node_composite_composite.c b/source/blender/nodes/composite/nodes/node_composite_composite.c
index 41d417c2cb4..be9ed457150 100644
--- a/source/blender/nodes/composite/nodes/node_composite_composite.c
+++ b/source/blender/nodes/composite/nodes/node_composite_composite.c
@@ -31,10 +31,6 @@
#include "node_composite_util.h"
-#include "BKE_context.h"
-
-#include "RNA_access.h"
-
/* **************** COMPOSITE ******************** */
static bNodeSocketTemplate cmp_node_composite_in[] = {
{ SOCK_RGBA, 1, N_("Image"), 0.0f, 0.0f, 0.0f, 1.0f},
diff --git a/source/blender/nodes/composite/nodes/node_composite_defocus.c b/source/blender/nodes/composite/nodes/node_composite_defocus.c
index ef670b760c2..a3311755717 100644
--- a/source/blender/nodes/composite/nodes/node_composite_defocus.c
+++ b/source/blender/nodes/composite/nodes/node_composite_defocus.c
@@ -33,10 +33,6 @@
#include <limits.h>
-#include "BKE_context.h"
-
-#include "RNA_access.h"
-
/* ************ qdn: Defocus node ****************** */
static bNodeSocketTemplate cmp_node_defocus_in[] = {
{ SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f},
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 659e582dc1d..34f3350c2ff 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -39,8 +39,6 @@
#include "BKE_global.h"
#include "BKE_main.h"
-#include "RNA_access.h"
-
/* **************** IMAGE (and RenderResult, multilayer image) ******************** */
static bNodeSocketTemplate cmp_node_rlayers_out[] = {
@@ -184,6 +182,14 @@ static void cmp_node_image_add_multilayer_outputs(bNodeTree *ntree, bNode *node,
sockdata->pass_index = index;
sockdata->pass_flag = rpass->passtype;
+
+ if (STREQ(rpass->chan_id, "RGBA")) {
+ sock = nodeAddStaticSocket(ntree, node, SOCK_OUT, SOCK_FLOAT, PROP_NONE, "Alpha", "Alpha");
+ sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
+ sock->storage = sockdata;
+ sockdata->pass_index = index;
+ sockdata->pass_flag = rpass->passtype;
+ }
}
}
@@ -441,7 +447,7 @@ static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr)
static int node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree)
{
- if (strcmp(ntree->idname, "CompositorNodeTree") == 0) {
+ if (STREQ(ntree->idname, "CompositorNodeTree")) {
Scene *scene;
/* XXX ugly: check if ntree is a local scene node tree.
diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.c b/source/blender/nodes/composite/nodes/node_composite_keying.c
index 6b5def1ea93..ba179bcbcd3 100644
--- a/source/blender/nodes/composite/nodes/node_composite_keying.c
+++ b/source/blender/nodes/composite/nodes/node_composite_keying.c
@@ -34,12 +34,8 @@
#include "DNA_movieclip_types.h"
-#include "BKE_movieclip.h"
-
-#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_math_color.h"
-#include "BLI_voronoi.h"
#include "node_composite_util.h"
diff --git a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c
index 9965b55e088..0cdf15c0412 100644
--- a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c
+++ b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.c
@@ -30,16 +30,10 @@
* \ingroup cmpnodes
*/
-#include "BLF_translation.h"
-
#include "DNA_movieclip_types.h"
-#include "BKE_movieclip.h"
-
-#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_math_color.h"
-#include "BLI_voronoi.h"
#include "node_composite_util.h"
diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.c b/source/blender/nodes/composite/nodes/node_composite_mask.c
index 83cea47db1b..dd05d5d83ad 100644
--- a/source/blender/nodes/composite/nodes/node_composite_mask.c
+++ b/source/blender/nodes/composite/nodes/node_composite_mask.c
@@ -30,12 +30,8 @@
* \ingroup cmpnodes
*/
-#include "BLF_translation.h"
-
#include "DNA_mask_types.h"
-#include "BKE_mask.h"
-
#include "node_composite_util.h"
/* **************** Translate ******************** */
diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.c b/source/blender/nodes/composite/nodes/node_composite_movieclip.c
index fc0d8060644..0fece9dd4f6 100644
--- a/source/blender/nodes/composite/nodes/node_composite_movieclip.c
+++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.c
@@ -30,13 +30,10 @@
* \ingroup cmpnodes
*/
-
#include "node_composite_util.h"
#include "BKE_context.h"
-#include "RNA_access.h"
-
static bNodeSocketTemplate cmp_node_movieclip_out[] = {
{ SOCK_RGBA, 0, N_("Image")},
{ SOCK_FLOAT, 0, N_("Alpha")},
diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
index 1d411aafe68..9c54009d2f1 100644
--- a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
+++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c
@@ -34,8 +34,6 @@
#include "BKE_context.h"
-#include "RNA_access.h"
-
/* **************** Translate ******************** */
static bNodeSocketTemplate cmp_node_moviedistortion_in[] = {
diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
index 76101409ba7..8e602c6179c 100644
--- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c
+++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
@@ -40,9 +40,6 @@
#include "node_composite_util.h"
-#include "IMB_imbuf.h"
-#include "IMB_imbuf_types.h"
-
#include "intern/openexr/openexr_multi.h"
@@ -140,7 +137,7 @@ int ntreeCompositOutputFileRemoveActiveSocket(bNodeTree *ntree, bNode *node)
{
NodeImageMultiFile *nimf = node->storage;
bNodeSocket *sock = BLI_findlink(&node->inputs, nimf->active_input);
- int totinputs = BLI_countlist(&node->inputs);
+ int totinputs = BLI_listbase_count(&node->inputs);
if (!sock)
return 0;
diff --git a/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c b/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c
index 7a15d6364dc..415427c360f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c
+++ b/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.c
@@ -47,7 +47,8 @@ static bNodeSocketTemplate cmp_node_planetrackdeform_out[] = {
static void init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodePlaneTrackDeformData *data = MEM_callocN(sizeof(NodePlaneTrackDeformData), "node plane track deform data");
-
+ data->motion_blur_samples = 16;
+ data->motion_blur_shutter = 0.5f;
node->storage = data;
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
index 28e2a2a205b..00791c278ae 100644
--- a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
+++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c
@@ -30,13 +30,10 @@
* \ingroup cmpnodes
*/
-
#include "node_composite_util.h"
#include "BKE_context.h"
-#include "RNA_access.h"
-
/* **************** Translate ******************** */
static bNodeSocketTemplate cmp_node_stabilize2d_in[] = {
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index c58c9c902ec..0e250dc3aa4 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -29,7 +29,6 @@
* \ingroup nodes
*/
-
#include <string.h>
#include <stddef.h>
@@ -43,15 +42,12 @@
#include "BKE_node.h"
-#include "RNA_access.h"
#include "RNA_types.h"
#include "MEM_guardedalloc.h"
#include "node_common.h"
#include "node_util.h"
-#include "node_exec.h"
-#include "NOD_socket.h"
#include "NOD_common.h"
diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c
index 2ac1a2c85f3..01c642b063d 100644
--- a/source/blender/nodes/intern/node_socket.c
+++ b/source/blender/nodes/intern/node_socket.c
@@ -41,7 +41,6 @@
#include "BKE_node.h"
#include "RNA_access.h"
-#include "RNA_define.h"
#include "RNA_types.h"
#include "MEM_guardedalloc.h"
@@ -109,7 +108,7 @@ static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in
bNodeSocket *sock;
for (sock = socklist->first; sock; sock = sock->next) {
- if (strncmp(sock->name, stemp->name, NODE_MAXSTR) == 0)
+ if (STREQLEN(sock->name, stemp->name, NODE_MAXSTR))
break;
}
if (sock) {
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 299172ae4cc..f18ee1d649f 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -41,16 +41,13 @@
#include "DNA_linestyle_types.h"
#include "BLI_listbase.h"
-#include "BLI_math.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
#include "BKE_context.h"
-#include "BKE_global.h"
#include "BKE_linestyle.h"
-#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_scene.h"
@@ -70,9 +67,9 @@ static int shader_tree_poll(const bContext *C, bNodeTreeType *UNUSED(treetype))
Scene *scene = CTX_data_scene(C);
/* allow empty engine string too, this is from older versions that didn't have registerable engines yet */
return (scene->r.engine[0] == '\0' ||
- STREQ(scene->r.engine, "BLENDER_RENDER") ||
- STREQ(scene->r.engine, "BLENDER_GAME") ||
- STREQ(scene->r.engine, "CYCLES"));
+ STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER) ||
+ STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME) ||
+ STREQ(scene->r.engine, RE_engine_id_CYCLES));
}
static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
diff --git a/source/blender/nodes/shader/nodes/node_shader_background.c b/source/blender/nodes/shader/nodes/node_shader_background.c
index 2478fb4d38c..b387529e456 100644
--- a/source/blender/nodes/shader/nodes/node_shader_background.c
+++ b/source/blender/nodes/shader/nodes/node_shader_background.c
@@ -40,6 +40,11 @@ static bNodeSocketTemplate sh_node_background_out[] = {
{ -1, 0, "" }
};
+static int node_shader_gpu_background(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ return GPU_stack_link(mat, "node_background", in, out, GPU_builtin(GPU_VIEW_NORMAL));
+}
+
/* node type definition */
void register_node_type_sh_background(void)
{
@@ -50,6 +55,7 @@ void register_node_type_sh_background(void)
node_type_socket_templates(&ntype, sh_node_background_in, sh_node_background_out);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
+ node_type_gpu(&ntype, node_shader_gpu_background);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c
index 3ce01ce03bf..de152ee45d1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bump.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bump.c
@@ -29,11 +29,8 @@
* \ingroup shdnodes
*/
-
-
#include "node_shader_util.h"
-
/* **************** BUMP ******************** */
static bNodeSocketTemplate sh_node_bump_in[] = {
{ SOCK_FLOAT, 1, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
diff --git a/source/blender/nodes/shader/nodes/node_shader_gamma.c b/source/blender/nodes/shader/nodes/node_shader_gamma.c
index 9956fd712c8..0264abe451f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_gamma.c
+++ b/source/blender/nodes/shader/nodes/node_shader_gamma.c
@@ -41,6 +41,18 @@ static bNodeSocketTemplate sh_node_gamma_out[] = {
{ -1, 0, "" }
};
+static void node_shader_exec_gamma(void *UNUSED(data), int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
+{
+ float col[3];
+ float gamma;
+ nodestack_get_vec(col, SOCK_VECTOR, in[0]);
+ nodestack_get_vec(&gamma, SOCK_FLOAT, in[1]);
+
+ out[0]->vec[0] = col[0] > 0.0f ? powf(col[0], gamma) : col[0];
+ out[0]->vec[1] = col[1] > 0.0f ? powf(col[1], gamma) : col[1];
+ out[0]->vec[2] = col[2] > 0.0f ? powf(col[2], gamma) : col[2];
+}
+
static int node_shader_gpu_gamma(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
return GPU_stack_link(mat, "node_gamma", in, out);
@@ -51,10 +63,11 @@ void register_node_type_sh_gamma(void)
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_GAMMA, "Gamma", NODE_CLASS_OP_COLOR, 0);
- node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_compatibility(&ntype, NODE_OLD_SHADING | NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_gamma_in, sh_node_gamma_out);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_gamma);
node_type_gpu(&ntype, node_shader_gpu_gamma);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/shader/nodes/node_shader_geom.c b/source/blender/nodes/shader/nodes/node_shader_geom.c
index 7c598f92bed..2fb03536bbe 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geom.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geom.c
@@ -63,7 +63,7 @@ static void node_shader_exec_geom(void *data, int UNUSED(thread), bNode *node, b
if (ngeo->uvname[0]) {
/* find uv map by name */
for (i = 0; i < shi->totuv; i++) {
- if (strcmp(shi->uv[i].name, ngeo->uvname) == 0) {
+ if (STREQ(shi->uv[i].name, ngeo->uvname)) {
suv = &shi->uv[i];
break;
}
@@ -84,7 +84,7 @@ static void node_shader_exec_geom(void *data, int UNUSED(thread), bNode *node, b
if (ngeo->colname[0]) {
for (i = 0; i < shi->totcol; i++) {
- if (strcmp(shi->col[i].name, ngeo->colname) == 0) {
+ if (STREQ(shi->col[i].name, ngeo->colname)) {
scol = &shi->col[i];
break;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c
index 01851b51c27..553ea65154f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c
@@ -37,6 +37,7 @@ static bNodeSocketTemplate sh_node_geometry_out[] = {
{ SOCK_VECTOR, 0, N_("Incoming"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_VECTOR, 0, N_("Parametric"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 0, N_("Backfacing"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_("Pointiness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
diff --git a/source/blender/nodes/shader/nodes/node_shader_lamp.c b/source/blender/nodes/shader/nodes/node_shader_lamp.c
index adf53ba9b52..3b000d49822 100644
--- a/source/blender/nodes/shader/nodes/node_shader_lamp.c
+++ b/source/blender/nodes/shader/nodes/node_shader_lamp.c
@@ -62,11 +62,11 @@ static int gpu_shader_lamp(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
{
if (node->id) {
GPULamp *lamp = GPU_lamp_from_blender(GPU_material_scene(mat), (Object *)node->id, NULL);
- GPUNodeLink *col, *lv, *dist, *visifac, *shadow;
+ GPUNodeLink *col, *lv, *dist, *visifac, *shadow, *energy;
- visifac = GPU_lamp_get_data(mat, lamp, &col, &lv, &dist, &shadow);
+ visifac = GPU_lamp_get_data(mat, lamp, &col, &lv, &dist, &shadow, &energy);
- return GPU_stack_link(mat, "lamp", in, out, col, lv, dist, shadow, visifac);
+ return GPU_stack_link(mat, "lamp", in, out, col, energy, lv, dist, shadow, visifac);
}
return 0;
diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c
index 79d66495ad7..41e44a64376 100644
--- a/source/blender/nodes/shader/nodes/node_shader_material.c
+++ b/source/blender/nodes/shader/nodes/node_shader_material.c
@@ -36,7 +36,7 @@
static bNodeSocketTemplate sh_node_material_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 1, N_("Spec"), 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 1, N_("Refl"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("DiffuseIntensity"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
{ SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION},
{ -1, 0, "" }
};
@@ -53,13 +53,13 @@ static bNodeSocketTemplate sh_node_material_out[] = {
static bNodeSocketTemplate sh_node_material_ext_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 1, N_("Spec"), 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 1, N_("Refl"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("DiffuseIntensity"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
{ SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_DIRECTION},
{ SOCK_RGBA, 1, N_("Mirror"), 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Ambient"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
{ SOCK_FLOAT, 1, N_("Emit"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
{ SOCK_FLOAT, 1, N_("SpecTra"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
- { SOCK_FLOAT, 1, N_("Ray Mirror"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE},
+ { SOCK_FLOAT, 1, N_("Reflectivity"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE},
{ SOCK_FLOAT, 1, N_("Alpha"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_UNSIGNED},
{ SOCK_FLOAT, 1, N_("Translucency"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE},
{ -1, 0, "" }
@@ -267,6 +267,8 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNU
shi.amb = gpu_get_input_link(&in[MAT_IN_AMB]);
if (hasinput[MAT_IN_EMIT])
shi.emit = gpu_get_input_link(&in[MAT_IN_EMIT]);
+ if (hasinput[MAT_IN_SPECTRA])
+ shi.spectra = gpu_get_input_link(&in[MAT_IN_SPECTRA]);
if (hasinput[MAT_IN_ALPHA])
shi.alpha = gpu_get_input_link(&in[MAT_IN_ALPHA]);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c
index dc5971909d2..be2e3dcd311 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.c
+++ b/source/blender/nodes/shader/nodes/node_shader_math.c
@@ -54,16 +54,16 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
switch (node->custom1) {
- case 0: /* Add */
+ case NODE_MATH_ADD:
r = a + b;
break;
- case 1: /* Subtract */
+ case NODE_MATH_SUB:
r = a - b;
break;
- case 2: /* Multiply */
+ case NODE_MATH_MUL:
r = a * b;
break;
- case 3: /* Divide */
+ case NODE_MATH_DIVIDE:
{
if (b == 0) /* We don't want to divide by zero. */
r = 0.0;
@@ -71,7 +71,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = a / b;
break;
}
- case 4: /* Sine */
+ case NODE_MATH_SIN:
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
r = sinf(a);
@@ -79,7 +79,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = sinf(b);
break;
}
- case 5: /* Cosine */
+ case NODE_MATH_COS:
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
r = cosf(a);
@@ -87,7 +87,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = cosf(b);
break;
}
- case 6: /* Tangent */
+ case NODE_MATH_TAN:
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
r = tanf(a);
@@ -95,7 +95,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = tanf(b);
break;
}
- case 7: /* Arc-Sine */
+ case NODE_MATH_ASIN:
{
if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
/* Can't do the impossible... */
@@ -113,7 +113,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
}
break;
}
- case 8: /* Arc-Cosine */
+ case NODE_MATH_ACOS:
{
if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
/* Can't do the impossible... */
@@ -131,7 +131,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
}
break;
}
- case 9: /* Arc-Tangent */
+ case NODE_MATH_ATAN:
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
r = atan(a);
@@ -139,7 +139,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = atan(b);
break;
}
- case 10: /* Power */
+ case NODE_MATH_POW:
{
/* Only raise negative numbers by full integers */
if (a >= 0) {
@@ -159,7 +159,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
break;
}
- case 11: /* Logarithm */
+ case NODE_MATH_LOG:
{
/* Don't want any imaginary numbers... */
if (a > 0 && b > 0)
@@ -168,7 +168,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = 0.0;
break;
}
- case 12: /* Minimum */
+ case NODE_MATH_MIN:
{
if (a < b)
r = a;
@@ -176,7 +176,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = b;
break;
}
- case 13: /* Maximum */
+ case NODE_MATH_MAX:
{
if (a > b)
r = a;
@@ -184,7 +184,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = b;
break;
}
- case 14: /* Round */
+ case NODE_MATH_ROUND:
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
r = (a < 0) ? (int)(a - 0.5f) : (int)(a + 0.5f);
@@ -192,7 +192,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = (b < 0) ? (int)(b - 0.5f) : (int)(b + 0.5f);
break;
}
- case 15: /* Less Than */
+ case NODE_MATH_LESS:
{
if (a < b)
r = 1.0f;
@@ -200,7 +200,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = 0.0f;
break;
}
- case 16: /* Greater Than */
+ case NODE_MATH_GREATER:
{
if (a > b)
r = 1.0f;
@@ -208,7 +208,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = 0.0f;
break;
}
- case 17: /* Modulo */
+ case NODE_MATH_MOD:
{
if (b == 0.0f)
r = 0.0f;
@@ -216,13 +216,15 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = fmod(a, b);
break;
}
- case 18: /* Absolute */
+ case NODE_MATH_ABS:
{
r = fabsf(a);
break;
}
}
-
+ if (node->custom2 & SHD_MATH_CLAMP) {
+ CLAMP(r, 0.0f, 1.0f);
+ }
out[0]->vec[0] = r;
}
@@ -231,29 +233,30 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
static const char *names[] = {"math_add", "math_subtract", "math_multiply",
"math_divide", "math_sine", "math_cosine", "math_tangent", "math_asin",
"math_acos", "math_atan", "math_pow", "math_log", "math_min", "math_max",
- "math_round", "math_less_than", "math_greater_than", "math_modulo", "math_absolute"};
+ "math_round", "math_less_than", "math_greater_than", "math_modulo", "math_abs"};
switch (node->custom1) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 10:
- case 11:
- case 12:
- case 13:
- case 15:
- case 16:
- case 17:
+ case NODE_MATH_ADD:
+ case NODE_MATH_SUB:
+ case NODE_MATH_MUL:
+ case NODE_MATH_DIVIDE:
+ case NODE_MATH_POW:
+ case NODE_MATH_LOG:
+ case NODE_MATH_MIN:
+ case NODE_MATH_MAX:
+ case NODE_MATH_LESS:
+ case NODE_MATH_GREATER:
+ case NODE_MATH_MOD:
GPU_stack_link(mat, names[node->custom1], in, out);
break;
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 14:
+ case NODE_MATH_SIN:
+ case NODE_MATH_COS:
+ case NODE_MATH_TAN:
+ case NODE_MATH_ASIN:
+ case NODE_MATH_ACOS:
+ case NODE_MATH_ATAN:
+ case NODE_MATH_ROUND:
+ case NODE_MATH_ABS:
if (in[0].hasinput || !in[1].hasinput) {
/* use only first item and terminator */
GPUNodeStack tmp_in[2];
@@ -272,7 +275,13 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
default:
return 0;
}
-
+
+ if (node->custom2 & SHD_MATH_CLAMP) {
+ float min[3] = {0.0f, 0.0f, 0.0f};
+ float max[3] = {1.0f, 1.0f, 1.0f};
+ GPU_link(mat, "clamp_val", out[0].link, GPU_uniform(min), GPU_uniform(max), &out[0].link);
+ }
+
return 1;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
index 2da51c19ef8..f911fa058dc 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
@@ -59,6 +59,9 @@ static void node_shader_exec_mix_rgb(void *UNUSED(data), int UNUSED(thread), bNo
nodestack_get_vec(vec, SOCK_VECTOR, in[2]);
ramp_blend(node->custom1, col, fac, vec);
+ if (node->custom2 & SHD_MIXRGB_CLAMP) {
+ CLAMP3(col, 0.0f, 1.0f);
+ }
copy_v3_v3(out[0]->vec, col);
}
@@ -68,8 +71,13 @@ static int gpu_shader_mix_rgb(GPUMaterial *mat, bNode *node, bNodeExecData *UNUS
"mix_screen", "mix_div", "mix_diff", "mix_dark", "mix_light",
"mix_overlay", "mix_dodge", "mix_burn", "mix_hue", "mix_sat",
"mix_val", "mix_color", "mix_soft", "mix_linear"};
-
- return GPU_stack_link(mat, names[node->custom1], in, out);
+ int ret = GPU_stack_link(mat, names[node->custom1], in, out);
+ if (ret && node->custom2 & SHD_MIXRGB_CLAMP) {
+ float min[3] = {0.0f, 0.0f, 0.0f};
+ float max[3] = {1.0f, 1.0f, 1.0f};
+ GPU_link(mat, "clamp_vec3", out[0].link, GPU_uniform(min), GPU_uniform(max), &out[0].link);
+ }
+ return ret;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal.c b/source/blender/nodes/shader/nodes/node_shader_normal.c
index fcd738f0b15..092fc201aa7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal.c
@@ -61,12 +61,12 @@ static void node_shader_exec_normal(void *UNUSED(data), int UNUSED(thread), bNod
static int gpu_shader_normal(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
GPUNodeLink *vec = GPU_uniform(out[0].vec);
- int ret = GPU_stack_link(mat, "normal", in, out, vec);
- if (ret && GPU_material_use_new_shading_nodes(mat)) {
- float fac[3] = {1.0f, 0.0f, 0.0f};
- GPU_link(mat, "invert", GPU_uniform(fac), out[1].link, &out[1].link);
+ if (GPU_material_use_new_shading_nodes(mat)) {
+ return GPU_stack_link(mat, "normal_new_shading", in, out, vec);
+ }
+ else {
+ return GPU_stack_link(mat, "normal", in, out, vec);
}
- return ret;
}
void register_node_type_sh_normal(void)
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_world.c b/source/blender/nodes/shader/nodes/node_shader_output_world.c
index c8e47c47c5f..ad7389fd56e 100644
--- a/source/blender/nodes/shader/nodes/node_shader_output_world.c
+++ b/source/blender/nodes/shader/nodes/node_shader_output_world.c
@@ -35,6 +35,16 @@ static bNodeSocketTemplate sh_node_output_world_in[] = {
{ -1, 0, "" }
};
+static int node_shader_gpu_output_world(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ GPUNodeLink *outlink;
+
+ GPU_stack_link(mat, "node_output_world", in, out, &outlink);
+ GPU_material_output_link(mat, outlink);
+
+ return 1;
+}
+
/* node type definition */
void register_node_type_sh_output_world(void)
{
@@ -45,7 +55,8 @@ void register_node_type_sh_output_world(void)
node_type_socket_templates(&ntype, sh_node_output_world_in, NULL);
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
-
+ node_type_gpu(&ntype, node_shader_gpu_output_world);
+
/* Do not allow muting output node. */
node_type_internal_links(&ntype, NULL);
diff --git a/source/blender/nodes/shader/nodes/node_shader_script.c b/source/blender/nodes/shader/nodes/node_shader_script.c
index d5ed38297da..f640dd5ea13 100644
--- a/source/blender/nodes/shader/nodes/node_shader_script.c
+++ b/source/blender/nodes/shader/nodes/node_shader_script.c
@@ -31,8 +31,6 @@
#include "node_shader_util.h"
-#include "BKE_idprop.h"
-
/* **************** Script ******************** */
static void init(bNodeTree *UNUSED(ntree), bNode *node)
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c b/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c
index 605a3b9faa3..6375dcc8782 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.c
@@ -65,9 +65,9 @@ void register_node_type_sh_sepxyz(void)
/* **************** COMBINE XYZ ******************** */
static bNodeSocketTemplate sh_node_combxyz_in[] = {
- { SOCK_FLOAT, 1, N_("X"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_UNSIGNED},
- { SOCK_FLOAT, 1, N_("Y"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_UNSIGNED},
- { SOCK_FLOAT, 1, N_("Z"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_UNSIGNED},
+ { SOCK_FLOAT, 1, N_("X"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f},
+ { SOCK_FLOAT, 1, N_("Y"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f},
+ { SOCK_FLOAT, 1, N_("Z"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f},
{ -1, 0, "" }
};
static bNodeSocketTemplate sh_node_combxyz_out[] = {
diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
index fd864f1c7c6..9fe56d4f01d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
+++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
@@ -51,7 +51,7 @@ static void node_shader_init_subsurface_scattering(bNodeTree *UNUSED(ntree), bNo
node->custom1 = SHD_SUBSURFACE_CUBIC;
/*for (sock = node->inputs.first; sock; sock = sock->next) {
- if (strcmp(sock->name, "Sharpness") == 0) {
+ if (STREQ(sock->name, "Sharpness")) {
bNodeSocketValueFloat *dval = sock->default_value;
dval->value = 0.0f;
}
@@ -72,7 +72,7 @@ static void node_shader_update_subsurface_scattering(bNodeTree *UNUSED(ntree), b
int falloff = node->custom1;
for (sock = node->inputs.first; sock; sock = sock->next) {
- if (strcmp(sock->name, "Sharpness") == 0) {
+ if (STREQ(sock->name, "Sharpness")) {
if (falloff == SHD_SUBSURFACE_CUBIC)
sock->flag &= ~SOCK_UNAVAIL;
else
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
index 781b1bb5a93..be393582a42 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c
@@ -46,10 +46,20 @@ static int node_shader_gpu_tex_coord(GPUMaterial *mat, bNode *UNUSED(node), bNod
{
GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
GPUNodeLink *mtface = GPU_attribute(CD_MTFACE, "");
-
- return GPU_stack_link(mat, "node_tex_coord", in, out,
- GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
- GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX), orco, mtface);
+ GPUMatType type = GPU_Material_get_type(mat);
+
+ if (type == GPU_MATERIAL_TYPE_MESH) {
+ return GPU_stack_link(mat, "node_tex_coord", in, out,
+ GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
+ GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);
+ }
+ else {
+ return GPU_stack_link(mat, "node_tex_coord_background", in, out,
+ GPU_builtin(GPU_VIEW_POSITION), GPU_builtin(GPU_VIEW_NORMAL),
+ GPU_builtin(GPU_INVERSE_VIEW_MATRIX), GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
+ GPU_builtin(GPU_CAMERA_TEXCO_FACTORS), orco, mtface);
+ }
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index dcb3ef3c8a0..8d6a77455bb 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -27,8 +27,6 @@
#include "../node_shader_util.h"
-#include "IMB_colormanagement.h"
-
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_tex_environment_in[] = {
@@ -67,13 +65,22 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, bNodeE
if (!ima)
return GPU_stack_link(mat, "node_tex_environment_empty", in, out);
- if (!in[0].link)
- in[0].link = GPU_builtin(GPU_VIEW_POSITION);
-
+ if (!in[0].link) {
+ GPUMatType type = GPU_Material_get_type(mat);
+
+ if (type == GPU_MATERIAL_TYPE_MESH)
+ in[0].link = GPU_builtin(GPU_VIEW_POSITION);
+ else
+ GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &in[0].link);
+ }
+
node_shader_gpu_tex_mapping(mat, node, in, out);
- ret = GPU_stack_link(mat, "node_tex_environment", in, out, GPU_image(ima, iuser, isdata));
-
+ if (tex->projection == SHD_PROJ_EQUIRECTANGULAR)
+ ret = GPU_stack_link(mat, "node_tex_environment_equirectangular", in, out, GPU_image(ima, iuser, isdata));
+ else
+ ret = GPU_stack_link(mat, "node_tex_environment_mirror_ball", in, out, GPU_image(ima, iuser, isdata));
+
if (ret) {
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index 0a11ee4a9b6..62db5b70891 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -27,8 +27,6 @@
#include "../node_shader_util.h"
-#include "IMB_colormanagement.h"
-
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_tex_image_in[] = {
diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c
index d02d72563ba..5cdbaf444f8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_texture.c
+++ b/source/blender/nodes/shader/nodes/node_shader_texture.c
@@ -29,11 +29,8 @@
* \ingroup shdnodes
*/
-
#include "DNA_texture_types.h"
-#include "IMB_colormanagement.h"
-
#include "node_shader_util.h"
/* **************** TEXTURE ******************** */
diff --git a/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c b/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c
index 48eb4cadba4..67342e1e836 100644
--- a/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c
+++ b/source/blender/nodes/shader/nodes/node_shader_uvAlongStroke.c
@@ -27,8 +27,6 @@
#include "../node_shader_util.h"
-#include "DNA_customdata_types.h"
-
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_uvalongstroke_out[] = {
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectMath.c b/source/blender/nodes/shader/nodes/node_shader_vectMath.c
index f2ea2faa5a7..45a11c5f799 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vectMath.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vectMath.c
@@ -29,11 +29,8 @@
* \ingroup shdnodes
*/
-
-
#include "node_shader_util.h"
-
/* **************** VECTOR MATH ******************** */
static bNodeSocketTemplate sh_node_vect_math_in[] = {
{ SOCK_VECTOR, 1, N_("Vector"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
@@ -59,14 +56,14 @@ static void node_shader_exec_vect_math(void *UNUSED(data), int UNUSED(thread), b
out[0]->vec[1] = vec1[1] + vec2[1];
out[0]->vec[2] = vec1[2] + vec2[2];
- out[1]->vec[0] = (fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[0])) / 3;
+ out[1]->vec[0] = (fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[1]) + fabsf(out[0]->vec[2])) / 3.0f;
}
else if (node->custom1 == 1) { /* Subtract */
out[0]->vec[0] = vec1[0] - vec2[0];
out[0]->vec[1] = vec1[1] - vec2[1];
out[0]->vec[2] = vec1[2] - vec2[2];
- out[1]->vec[0] = (fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[0])) / 3;
+ out[1]->vec[0] = (fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[1]) + fabsf(out[0]->vec[2])) / 3.0f;
}
else if (node->custom1 == 2) { /* Average */
out[0]->vec[0] = vec1[0] + vec2[0];
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 1b790f87faf..79923c5f7d5 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -43,9 +43,7 @@
#include "BLF_translation.h"
#include "BKE_context.h"
-#include "BKE_global.h"
#include "BKE_linestyle.h"
-#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_paint.h"
@@ -57,7 +55,6 @@
#include "RNA_access.h"
-#include "RE_pipeline.h"
#include "RE_shader_ext.h"
diff --git a/source/blender/nodes/texture/nodes/node_texture_math.c b/source/blender/nodes/texture/nodes/node_texture_math.c
index 94e778e10fb..19bc16fb82d 100644
--- a/source/blender/nodes/texture/nodes/node_texture_math.c
+++ b/source/blender/nodes/texture/nodes/node_texture_math.c
@@ -53,16 +53,16 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
switch (node->custom1) {
- case 0: /* Add */
+ case NODE_MATH_ADD:
*out = in0 + in1;
break;
- case 1: /* Subtract */
+ case NODE_MATH_SUB:
*out = in0 - in1;
break;
- case 2: /* Multiply */
+ case NODE_MATH_MUL:
*out = in0 * in1;
break;
- case 3: /* Divide */
+ case NODE_MATH_DIVIDE:
{
if (in1 == 0) /* We don't want to divide by zero. */
*out = 0.0;
@@ -70,22 +70,22 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
*out = in0 / in1;
break;
}
- case 4: /* Sine */
+ case NODE_MATH_SIN:
{
*out = sinf(in0);
break;
}
- case 5: /* Cosine */
+ case NODE_MATH_COS:
{
*out = cosf(in0);
break;
}
- case 6: /* Tangent */
+ case NODE_MATH_TAN:
{
*out = tanf(in0);
break;
}
- case 7: /* Arc-Sine */
+ case NODE_MATH_ASIN:
{
/* Can't do the impossible... */
if (in0 <= 1 && in0 >= -1)
@@ -94,7 +94,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
*out = 0.0;
break;
}
- case 8: /* Arc-Cosine */
+ case NODE_MATH_ACOS:
{
/* Can't do the impossible... */
if (in0 <= 1 && in0 >= -1)
@@ -103,12 +103,12 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
*out = 0.0;
break;
}
- case 9: /* Arc-Tangent */
+ case NODE_MATH_ATAN:
{
*out = atan(in0);
break;
}
- case 10: /* Power */
+ case NODE_MATH_POW:
{
/* Only raise negative numbers by full integers */
if (in0 >= 0) {
@@ -125,7 +125,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
}
break;
}
- case 11: /* Logarithm */
+ case NODE_MATH_LOG:
{
/* Don't want any imaginary numbers... */
if (in0 > 0 && in1 > 0)
@@ -134,7 +134,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
*out = 0.0;
break;
}
- case 12: /* Minimum */
+ case NODE_MATH_MIN:
{
if (in0 < in1)
*out = in0;
@@ -142,7 +142,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
*out = in1;
break;
}
- case 13: /* Maximum */
+ case NODE_MATH_MAX:
{
if (in0 > in1)
*out = in0;
@@ -150,13 +150,13 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
*out = in1;
break;
}
- case 14: /* Round */
+ case NODE_MATH_ROUND:
{
*out = (in0 < 0) ? (int)(in0 - 0.5f) : (int)(in0 + 0.5f);
break;
}
- case 15: /* Less Than */
+ case NODE_MATH_LESS:
{
if (in0 < in1)
*out = 1.0f;
@@ -165,7 +165,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
- case 16: /* Greater Than */
+ case NODE_MATH_GREATER:
{
if (in0 > in1)
*out = 1.0f;
@@ -174,7 +174,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
- case 17: /* Modulo */
+ case NODE_MATH_MOD:
{
if (in1 == 0.0f)
*out = 0.0f;
@@ -183,7 +183,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
- case 18: /* Absolute */
+ case NODE_MATH_ABS:
{
*out = fabsf(in0);
break;
@@ -195,6 +195,10 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
}
+
+ if (node->custom2 & SHD_MATH_CLAMP) {
+ CLAMP(*out, 0.0f, 1.0f);
+ }
}
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
diff --git a/source/blender/physics/BPH_mass_spring.h b/source/blender/physics/BPH_mass_spring.h
new file mode 100644
index 00000000000..c189dea28a4
--- /dev/null
+++ b/source/blender/physics/BPH_mass_spring.h
@@ -0,0 +1,62 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BPH_MASS_SPRING_H__
+#define __BPH_MASS_SPRING_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Implicit_Data;
+struct Object;
+struct ClothModifierData;
+struct ListBase;
+struct VoxelData;
+
+typedef enum eMassSpringSolverStatus {
+ BPH_SOLVER_SUCCESS = (1 << 0),
+ BPH_SOLVER_NUMERICAL_ISSUE = (1 << 1),
+ BPH_SOLVER_NO_CONVERGENCE = (1 << 2),
+ BPH_SOLVER_INVALID_INPUT = (1 << 3),
+} eMassSpringSolverStatus;
+
+struct Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings);
+void BPH_mass_spring_solver_free(struct Implicit_Data *id);
+
+int BPH_cloth_solver_init(struct Object *ob, struct ClothModifierData *clmd);
+void BPH_cloth_solver_free(struct ClothModifierData *clmd);
+int BPH_cloth_solve(struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors);
+void BKE_cloth_solver_set_positions(struct ClothModifierData *clmd);
+
+bool BPH_cloth_solver_get_texture_data(struct Object *ob, struct ClothModifierData *clmd, struct VoxelData *vd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/blender/physics/CMakeLists.txt b/source/blender/physics/CMakeLists.txt
new file mode 100644
index 00000000000..08ff1faca49
--- /dev/null
+++ b/source/blender/physics/CMakeLists.txt
@@ -0,0 +1,53 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2014, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Lukas Toenne
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+ intern
+ ../blenlib
+ ../blenkernel
+ ../imbuf
+ ../makesdna
+ ../../../intern/guardedalloc
+ ../../../extern/Eigen3
+)
+
+set(INC_SYS
+
+)
+
+set(SRC
+ intern/BPH_mass_spring.cpp
+ intern/ConstrainedConjugateGradient.h
+ intern/hair_volume.cpp
+ intern/implicit.h
+ intern/implicit_blender.c
+ intern/implicit_eigen.cpp
+ intern/eigen_utils.h
+
+ BPH_mass_spring.h
+)
+
+blender_add_lib(bf_physics "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/physics/SConscript b/source/blender/physics/SConscript
new file mode 100644
index 00000000000..c8165886cab
--- /dev/null
+++ b/source/blender/physics/SConscript
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2011, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Jeroen Bakker, Monique Dewanchand, Blender Developers Fund.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+Import ('env')
+defs = []
+
+sources = env.Glob('intern/*.cpp') + env.Glob('intern/*.c')
+
+incs = [
+ '.',
+ 'intern',
+ '../blenlib',
+ '../blenkernel',
+ '../imbuf',
+ '../makesdna',
+ '../../../intern/guardedalloc',
+ '../../../extern/Eigen3',
+ ]
+
+env.BlenderLib('bf_physics', sources, incs, defines=defs, libtype=['core', 'player'], priority=[180, 190])
diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp
new file mode 100644
index 00000000000..e0ca945eaf7
--- /dev/null
+++ b/source/blender/physics/intern/BPH_mass_spring.cpp
@@ -0,0 +1,1117 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/physics/intern/BPH_mass_spring.cpp
+ * \ingroup bph
+ */
+
+extern "C" {
+#include "MEM_guardedalloc.h"
+
+#include "DNA_cloth_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_force.h"
+#include "DNA_object_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+
+#include "BLI_math.h"
+#include "BLI_linklist.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_cloth.h"
+#include "BKE_collision.h"
+#include "BKE_effect.h"
+}
+
+#include "BPH_mass_spring.h"
+#include "implicit.h"
+
+static float I3[3][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}};
+
+/* Number of off-diagonal non-zero matrix blocks.
+ * Basically there is one of these for each vertex-vertex interaction.
+ */
+static int cloth_count_nondiag_blocks(Cloth *cloth)
+{
+ LinkNode *link;
+ int nondiag = 0;
+
+ for (link = cloth->springs; link; link = link->next) {
+ ClothSpring *spring = (ClothSpring *)link->link;
+ switch (spring->type) {
+ case CLOTH_SPRING_TYPE_BENDING_ANG:
+ /* angular bending combines 3 vertices */
+ nondiag += 3;
+ break;
+
+ default:
+ /* all other springs depend on 2 vertices only */
+ nondiag += 1;
+ break;
+ }
+ }
+
+ return nondiag;
+}
+
+int BPH_cloth_solver_init(Object *UNUSED(ob), ClothModifierData *clmd)
+{
+ Cloth *cloth = clmd->clothObject;
+ ClothVertex *verts = cloth->verts;
+ const float ZERO[3] = {0.0f, 0.0f, 0.0f};
+ Implicit_Data *id;
+ unsigned int i, nondiag;
+
+ nondiag = cloth_count_nondiag_blocks(cloth);
+ cloth->implicit = id = BPH_mass_spring_solver_create(cloth->numverts, nondiag);
+
+ for (i = 0; i < cloth->numverts; i++) {
+ BPH_mass_spring_set_vertex_mass(id, i, verts[i].mass);
+ }
+
+ for (i = 0; i < cloth->numverts; i++) {
+ BPH_mass_spring_set_motion_state(id, i, verts[i].x, ZERO);
+ }
+
+ return 1;
+}
+
+void BPH_cloth_solver_free(ClothModifierData *clmd)
+{
+ Cloth *cloth = clmd->clothObject;
+
+ if (cloth->implicit) {
+ BPH_mass_spring_solver_free(cloth->implicit);
+ cloth->implicit = NULL;
+ }
+}
+
+void BKE_cloth_solver_set_positions(ClothModifierData *clmd)
+{
+ Cloth *cloth = clmd->clothObject;
+ ClothVertex *verts = cloth->verts;
+ unsigned int numverts = cloth->numverts, i;
+ ClothHairData *cloth_hairdata = clmd->hairdata;
+ Implicit_Data *id = cloth->implicit;
+
+ for (i = 0; i < numverts; i++) {
+ if (cloth_hairdata) {
+ ClothHairData *root = &cloth_hairdata[i];
+ BPH_mass_spring_set_rest_transform(id, i, root->rot);
+ }
+ else
+ BPH_mass_spring_set_rest_transform(id, i, I3);
+
+ BPH_mass_spring_set_motion_state(id, i, verts[i].x, verts[i].v);
+ }
+}
+
+static bool collision_response(ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, float dt, float restitution, float r_impulse[3])
+{
+ Cloth *cloth = clmd->clothObject;
+ int index = collpair->ap1;
+ bool result = false;
+
+ float v1[3], v2_old[3], v2_new[3], v_rel_old[3], v_rel_new[3];
+ float epsilon2 = BLI_bvhtree_getepsilon(collmd->bvhtree);
+
+ float margin_distance = collpair->distance - epsilon2;
+ float mag_v_rel;
+
+ zero_v3(r_impulse);
+
+ if (margin_distance > 0.0f)
+ return false; /* XXX tested before already? */
+
+ /* only handle static collisions here */
+ if ( collpair->flag & COLLISION_IN_FUTURE )
+ return false;
+
+ /* velocity */
+ copy_v3_v3(v1, cloth->verts[index].v);
+ collision_get_collider_velocity(v2_old, v2_new, collmd, collpair);
+ /* relative velocity = velocity of the cloth point relative to the collider */
+ sub_v3_v3v3(v_rel_old, v1, v2_old);
+ sub_v3_v3v3(v_rel_new, v1, v2_new);
+ /* normal component of the relative velocity */
+ mag_v_rel = dot_v3v3(v_rel_old, collpair->normal);
+
+ /* only valid when moving toward the collider */
+ if (mag_v_rel < -ALMOST_ZERO) {
+ float v_nor_old, v_nor_new;
+ float v_tan_old[3], v_tan_new[3];
+ float bounce, repulse;
+
+ /* Collision response based on
+ * "Simulating Complex Hair with Robust Collision Handling" (Choe, Choi, Ko, ACM SIGGRAPH 2005)
+ * http://graphics.snu.ac.kr/publications/2005-choe-HairSim/Choe_2005_SCA.pdf
+ */
+
+ v_nor_old = mag_v_rel;
+ v_nor_new = dot_v3v3(v_rel_new, collpair->normal);
+
+ madd_v3_v3v3fl(v_tan_old, v_rel_old, collpair->normal, -v_nor_old);
+ madd_v3_v3v3fl(v_tan_new, v_rel_new, collpair->normal, -v_nor_new);
+
+ bounce = -v_nor_old * restitution;
+
+ repulse = -margin_distance / dt; /* base repulsion velocity in normal direction */
+ /* XXX this clamping factor is quite arbitrary ...
+ * not sure if there is a more scientific approach, but seems to give good results
+ */
+ CLAMP(repulse, 0.0f, 4.0f * bounce);
+
+ if (margin_distance < -epsilon2) {
+ mul_v3_v3fl(r_impulse, collpair->normal, max_ff(repulse, bounce) - v_nor_new);
+ }
+ else {
+ bounce = 0.0f;
+ mul_v3_v3fl(r_impulse, collpair->normal, repulse - v_nor_new);
+ }
+
+ result = true;
+ }
+
+ return result;
+}
+
+/* Init constraint matrix
+ * This is part of the modified CG method suggested by Baraff/Witkin in
+ * "Large Steps in Cloth Simulation" (Siggraph 1998)
+ */
+static void cloth_setup_constraints(ClothModifierData *clmd, ColliderContacts *contacts, int totcolliders, float dt)
+{
+ Cloth *cloth = clmd->clothObject;
+ Implicit_Data *data = cloth->implicit;
+ ClothVertex *verts = cloth->verts;
+ int numverts = cloth->numverts;
+ int i, j, v;
+
+ const float ZERO[3] = {0.0f, 0.0f, 0.0f};
+
+ BPH_mass_spring_clear_constraints(data);
+
+ for (v = 0; v < numverts; v++) {
+ if (verts[v].flags & CLOTH_VERT_FLAG_PINNED) {
+ /* pinned vertex constraints */
+ BPH_mass_spring_add_constraint_ndof0(data, v, ZERO); /* velocity is defined externally */
+ }
+
+ verts[v].impulse_count = 0;
+ }
+
+ for (i = 0; i < totcolliders; ++i) {
+ ColliderContacts *ct = &contacts[i];
+ for (j = 0; j < ct->totcollisions; ++j) {
+ CollPair *collpair = &ct->collisions[j];
+// float restitution = (1.0f - clmd->coll_parms->damping) * (1.0f - ct->ob->pd->pdef_sbdamp);
+ float restitution = 0.0f;
+ int v = collpair->face1;
+ float impulse[3];
+
+ /* pinned verts handled separately */
+ if (verts[v].flags & CLOTH_VERT_FLAG_PINNED)
+ continue;
+
+ /* XXX cheap way of avoiding instability from multiple collisions in the same step
+ * this should eventually be supported ...
+ */
+ if (verts[v].impulse_count > 0)
+ continue;
+
+ /* calculate collision response */
+ if (!collision_response(clmd, ct->collmd, collpair, dt, restitution, impulse))
+ continue;
+
+ BPH_mass_spring_add_constraint_ndof2(data, v, collpair->normal, impulse);
+ ++verts[v].impulse_count;
+ }
+ }
+}
+
+/* computes where the cloth would be if it were subject to perfectly stiff edges
+ * (edge distance constraints) in a lagrangian solver. then add forces to help
+ * guide the implicit solver to that state. this function is called after
+ * collisions*/
+static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothModifierData *clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
+{
+ Cloth *cloth= clmd->clothObject;
+ float (*cos)[3] = (float (*)[3])MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces");
+ float *masses = (float *)MEM_callocN(sizeof(float)*cloth->numverts, "cos cloth_calc_helper_forces");
+ LinkNode *node;
+ ClothSpring *spring;
+ ClothVertex *cv;
+ int i, steps;
+
+ cv = cloth->verts;
+ for (i=0; i<cloth->numverts; i++, cv++) {
+ copy_v3_v3(cos[i], cv->tx);
+
+ if (cv->goal == 1.0f || len_squared_v3v3(initial_cos[i], cv->tx) != 0.0f) {
+ masses[i] = 1e+10;
+ }
+ else {
+ masses[i] = cv->mass;
+ }
+ }
+
+ steps = 55;
+ for (i=0; i<steps; i++) {
+ for (node=cloth->springs; node; node=node->next) {
+ /* ClothVertex *cv1, *cv2; */ /* UNUSED */
+ int v1, v2;
+ float len, c, l, vec[3];
+
+ spring = (ClothSpring *)node->link;
+ if (spring->type != CLOTH_SPRING_TYPE_STRUCTURAL && spring->type != CLOTH_SPRING_TYPE_SHEAR)
+ continue;
+
+ v1 = spring->ij; v2 = spring->kl;
+ /* cv1 = cloth->verts + v1; */ /* UNUSED */
+ /* cv2 = cloth->verts + v2; */ /* UNUSED */
+ len = len_v3v3(cos[v1], cos[v2]);
+
+ sub_v3_v3v3(vec, cos[v1], cos[v2]);
+ normalize_v3(vec);
+
+ c = (len - spring->restlen);
+ if (c == 0.0f)
+ continue;
+
+ l = c / ((1.0f / masses[v1]) + (1.0f / masses[v2]));
+
+ mul_v3_fl(vec, -(1.0f / masses[v1]) * l);
+ add_v3_v3(cos[v1], vec);
+
+ sub_v3_v3v3(vec, cos[v2], cos[v1]);
+ normalize_v3(vec);
+
+ mul_v3_fl(vec, -(1.0f / masses[v2]) * l);
+ add_v3_v3(cos[v2], vec);
+ }
+ }
+
+ cv = cloth->verts;
+ for (i=0; i<cloth->numverts; i++, cv++) {
+ float vec[3];
+
+ /*compute forces*/
+ sub_v3_v3v3(vec, cos[i], cv->tx);
+ mul_v3_fl(vec, cv->mass*dt*20.0f);
+ add_v3_v3(cv->tv, vec);
+ //copy_v3_v3(cv->tx, cos[i]);
+ }
+
+ MEM_freeN(cos);
+ MEM_freeN(masses);
+
+ return 1;
+}
+
+BLI_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, float time)
+{
+ Cloth *cloth = clmd->clothObject;
+ ClothSimSettings *parms = clmd->sim_parms;
+ Implicit_Data *data = cloth->implicit;
+ ClothVertex *verts = cloth->verts;
+
+ bool no_compress = parms->flags & CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
+
+ zero_v3(s->f);
+ zero_m3(s->dfdx);
+ zero_m3(s->dfdv);
+
+ s->flags &= ~CLOTH_SPRING_FLAG_NEEDED;
+
+ // calculate force of structural + shear springs
+ if ((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR) || (s->type & CLOTH_SPRING_TYPE_SEWING) ) {
+#ifdef CLOTH_FORCE_SPRING_STRUCTURAL
+ float k, scaling;
+
+ s->flags |= CLOTH_SPRING_FLAG_NEEDED;
+
+ scaling = parms->structural + s->stiffness * fabsf(parms->max_struct - parms->structural);
+ k = scaling / (parms->avg_spring_len + FLT_EPSILON);
+
+ if (s->type & CLOTH_SPRING_TYPE_SEWING) {
+ // TODO: verify, half verified (couldn't see error)
+ // sewing springs usually have a large distance at first so clamp the force so we don't get tunnelling through colission objects
+ BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->restlen, k, parms->Cdis, no_compress, parms->max_sewing, s->f, s->dfdx, s->dfdv);
+ }
+ else {
+ BPH_mass_spring_force_spring_linear(data, s->ij, s->kl, s->restlen, k, parms->Cdis, no_compress, 0.0f, s->f, s->dfdx, s->dfdv);
+ }
+#endif
+ }
+ else if (s->type & CLOTH_SPRING_TYPE_GOAL) {
+#ifdef CLOTH_FORCE_SPRING_GOAL
+ float goal_x[3], goal_v[3];
+ float k, scaling;
+
+ s->flags |= CLOTH_SPRING_FLAG_NEEDED;
+
+ // current_position = xold + t * (newposition - xold)
+ interp_v3_v3v3(goal_x, verts[s->ij].xold, verts[s->ij].xconst, time);
+ sub_v3_v3v3(goal_v, verts[s->ij].xconst, verts[s->ij].xold); // distance covered over dt==1
+
+ scaling = parms->goalspring + s->stiffness * fabsf(parms->max_struct - parms->goalspring);
+ k = verts[s->ij].goal * scaling / (parms->avg_spring_len + FLT_EPSILON);
+
+ BPH_mass_spring_force_spring_goal(data, s->ij, goal_x, goal_v, k, parms->goalfrict * 0.01f, s->f, s->dfdx, s->dfdv);
+#endif
+ }
+ else if (s->type & CLOTH_SPRING_TYPE_BENDING) { /* calculate force of bending springs */
+#ifdef CLOTH_FORCE_SPRING_BEND
+ float kb, cb, scaling;
+
+ s->flags |= CLOTH_SPRING_FLAG_NEEDED;
+
+ scaling = parms->bending + s->stiffness * fabsf(parms->max_bend - parms->bending);
+ kb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON));
+
+ scaling = parms->bending_damping;
+ cb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON));
+
+ BPH_mass_spring_force_spring_bending(data, s->ij, s->kl, s->restlen, kb, cb, s->f, s->dfdx, s->dfdv);
+#endif
+ }
+ else if (s->type & CLOTH_SPRING_TYPE_BENDING_ANG) {
+#ifdef CLOTH_FORCE_SPRING_BEND
+ float kb, cb, scaling;
+
+ s->flags |= CLOTH_SPRING_FLAG_NEEDED;
+
+ /* XXX WARNING: angular bending springs for hair apply stiffness factor as an overall factor, unlike cloth springs!
+ * this is crap, but needed due to cloth/hair mixing ...
+ * max_bend factor is not even used for hair, so ...
+ */
+ scaling = s->stiffness * parms->bending;
+ kb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON));
+
+ scaling = parms->bending_damping;
+ cb = scaling / (20.0f * (parms->avg_spring_len + FLT_EPSILON));
+
+ /* XXX assuming same restlen for ij and jk segments here, this can be done correctly for hair later */
+ BPH_mass_spring_force_spring_bending_angular(data, s->ij, s->kl, s->mn, s->target, kb, cb);
+
+#if 0
+ {
+ float x_kl[3], x_mn[3], v[3], d[3];
+
+ BPH_mass_spring_get_motion_state(data, s->kl, x_kl, v);
+ BPH_mass_spring_get_motion_state(data, s->mn, x_mn, v);
+
+ BKE_sim_debug_data_add_dot(clmd->debug_data, x_kl, 0.9, 0.9, 0.9, "target", 7980, s->kl);
+ BKE_sim_debug_data_add_line(clmd->debug_data, x_kl, x_mn, 0.8, 0.8, 0.8, "target", 7981, s->kl);
+
+ copy_v3_v3(d, s->target);
+ BKE_sim_debug_data_add_vector(clmd->debug_data, x_kl, d, 0.8, 0.8, 0.2, "target", 7982, s->kl);
+
+// copy_v3_v3(d, s->target_ij);
+// BKE_sim_debug_data_add_vector(clmd->debug_data, x, d, 1, 0.4, 0.4, "target", 7983, s->kl);
+ }
+#endif
+#endif
+ }
+}
+
+static void hair_get_boundbox(ClothModifierData *clmd, float gmin[3], float gmax[3])
+{
+ Cloth *cloth = clmd->clothObject;
+ Implicit_Data *data = cloth->implicit;
+ unsigned int numverts = cloth->numverts;
+ int i;
+
+ INIT_MINMAX(gmin, gmax);
+ for (i = 0; i < numverts; i++) {
+ float x[3];
+ BPH_mass_spring_get_motion_state(data, i, x, NULL);
+ DO_MINMAX(x, gmin, gmax);
+ }
+}
+
+static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), ListBase *effectors, float time)
+{
+ /* Collect forces and derivatives: F, dFdX, dFdV */
+ Cloth *cloth = clmd->clothObject;
+ Implicit_Data *data = cloth->implicit;
+ unsigned int i = 0;
+ float drag = clmd->sim_parms->Cvi * 0.01f; /* viscosity of air scaled in percent */
+ float gravity[3] = {0.0f, 0.0f, 0.0f};
+ MFace *mfaces = cloth->mfaces;
+ unsigned int numverts = cloth->numverts;
+ ClothVertex *vert;
+
+#ifdef CLOTH_FORCE_GRAVITY
+ /* global acceleration (gravitation) */
+ if (clmd->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
+ /* scale gravity force */
+ mul_v3_v3fl(gravity, clmd->scene->physics_settings.gravity, 0.001f * clmd->sim_parms->effector_weights->global_gravity);
+ }
+ vert = cloth->verts;
+ for (i = 0; i < cloth->numverts; i++, vert++) {
+ BPH_mass_spring_force_gravity(data, i, vert->mass, gravity);
+ }
+#endif
+
+ /* cloth_calc_volume_force(clmd); */
+
+#ifdef CLOTH_FORCE_DRAG
+ BPH_mass_spring_force_drag(data, drag);
+#endif
+
+ /* handle external forces like wind */
+ if (effectors) {
+ /* cache per-vertex forces to avoid redundant calculation */
+ float (*winvec)[3] = (float (*)[3])MEM_callocN(sizeof(float) * 3 * numverts, "effector forces");
+ for (i = 0; i < cloth->numverts; i++) {
+ float x[3], v[3];
+ EffectedPoint epoint;
+
+ BPH_mass_spring_get_motion_state(data, i, x, v);
+ pd_point_from_loc(clmd->scene, x, v, i, &epoint);
+ pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL);
+ }
+
+ for (i = 0; i < cloth->numfaces; i++) {
+ MFace *mf = &mfaces[i];
+ BPH_mass_spring_force_face_wind(data, mf->v1, mf->v2, mf->v3, mf->v4, winvec);
+ }
+
+ /* Hair has only edges */
+ if (cloth->numfaces == 0) {
+#if 0
+ ClothHairData *hairdata = clmd->hairdata;
+ ClothHairData *hair_ij, *hair_kl;
+
+ for (LinkNode *link = cloth->springs; link; link = link->next) {
+ ClothSpring *spring = (ClothSpring *)link->link;
+ if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL) {
+ if (hairdata) {
+ hair_ij = &hairdata[spring->ij];
+ hair_kl = &hairdata[spring->kl];
+ BPH_mass_spring_force_edge_wind(data, spring->ij, spring->kl, hair_ij->radius, hair_kl->radius, winvec);
+ }
+ else
+ BPH_mass_spring_force_edge_wind(data, spring->ij, spring->kl, 1.0f, 1.0f, winvec);
+ }
+ }
+#else
+ ClothHairData *hairdata = clmd->hairdata;
+
+ vert = cloth->verts;
+ for (i = 0; i < cloth->numverts; i++, vert++) {
+ if (hairdata) {
+ ClothHairData *hair = &hairdata[i];
+ BPH_mass_spring_force_vertex_wind(data, i, hair->radius, winvec);
+ }
+ else
+ BPH_mass_spring_force_vertex_wind(data, i, 1.0f, winvec);
+ }
+ }
+#endif
+
+ MEM_freeN(winvec);
+ }
+
+ // calculate spring forces
+ for (LinkNode *link = cloth->springs; link; link = link->next) {
+ ClothSpring *spring = (ClothSpring *)link->link;
+ // only handle active springs
+ if (!(spring->flags & CLOTH_SPRING_FLAG_DEACTIVATE))
+ cloth_calc_spring_force(clmd, spring, time);
+ }
+}
+
+/* returns vertexes' motion state */
+BLI_INLINE void cloth_get_grid_location(Implicit_Data *data, float cell_scale, const float cell_offset[3],
+ int index, float x[3], float v[3])
+{
+ BPH_mass_spring_get_position(data, index, x);
+ BPH_mass_spring_get_new_velocity(data, index, v);
+
+ mul_v3_fl(x, cell_scale);
+ add_v3_v3(x, cell_offset);
+}
+
+/* returns next spring forming a continous hair sequence */
+BLI_INLINE LinkNode *hair_spring_next(LinkNode *spring_link)
+{
+ ClothSpring *spring = (ClothSpring *)spring_link->link;
+ LinkNode *next = spring_link->next;
+ if (next) {
+ ClothSpring *next_spring = (ClothSpring *)next->link;
+ if (next_spring->type == CLOTH_SPRING_TYPE_STRUCTURAL && next_spring->kl == spring->ij)
+ return next;
+ }
+ return NULL;
+}
+
+/* XXX this is nasty: cloth meshes do not explicitly store
+ * the order of hair segments!
+ * We have to rely on the spring build function for now,
+ * which adds structural springs in reverse order:
+ * (3,4), (2,3), (1,2)
+ * This is currently the only way to figure out hair geometry inside this code ...
+ */
+static LinkNode *cloth_continuum_add_hair_segments(HairGrid *grid, const float cell_scale, const float cell_offset[3], Cloth *cloth, LinkNode *spring_link)
+{
+ Implicit_Data *data = cloth->implicit;
+ LinkNode *next_spring_link = NULL; /* return value */
+ ClothSpring *spring1, *spring2, *spring3;
+ // ClothVertex *verts = cloth->verts;
+ // ClothVertex *vert3, *vert4;
+ float x1[3], v1[3], x2[3], v2[3], x3[3], v3[3], x4[3], v4[3];
+ float dir1[3], dir2[3], dir3[3];
+
+ spring1 = NULL;
+ spring2 = NULL;
+ spring3 = (ClothSpring *)spring_link->link;
+
+ zero_v3(x1); zero_v3(v1);
+ zero_v3(dir1);
+ zero_v3(x2); zero_v3(v2);
+ zero_v3(dir2);
+
+ // vert3 = &verts[spring3->kl];
+ cloth_get_grid_location(data, cell_scale, cell_offset, spring3->kl, x3, v3);
+ // vert4 = &verts[spring3->ij];
+ cloth_get_grid_location(data, cell_scale, cell_offset, spring3->ij, x4, v4);
+ sub_v3_v3v3(dir3, x4, x3);
+ normalize_v3(dir3);
+
+ while (spring_link) {
+ /* move on */
+ spring1 = spring2;
+ spring2 = spring3;
+
+ // vert3 = vert4;
+
+ copy_v3_v3(x1, x2); copy_v3_v3(v1, v2);
+ copy_v3_v3(x2, x3); copy_v3_v3(v2, v3);
+ copy_v3_v3(x3, x4); copy_v3_v3(v3, v4);
+
+ copy_v3_v3(dir1, dir2);
+ copy_v3_v3(dir2, dir3);
+
+ /* read next segment */
+ next_spring_link = spring_link->next;
+ spring_link = hair_spring_next(spring_link);
+
+ if (spring_link) {
+ spring3 = (ClothSpring *)spring_link->link;
+ // vert4 = &verts[spring3->ij];
+ cloth_get_grid_location(data, cell_scale, cell_offset, spring3->ij, x4, v4);
+ sub_v3_v3v3(dir3, x4, x3);
+ normalize_v3(dir3);
+ }
+ else {
+ spring3 = NULL;
+ // vert4 = NULL;
+ zero_v3(x4); zero_v3(v4);
+ zero_v3(dir3);
+ }
+
+ BPH_hair_volume_add_segment(grid, x1, v1, x2, v2, x3, v3, x4, v4,
+ spring1 ? dir1 : NULL,
+ dir2,
+ spring3 ? dir3 : NULL);
+ }
+
+ return next_spring_link;
+}
+
+static void cloth_continuum_fill_grid(HairGrid *grid, Cloth *cloth)
+{
+#if 0
+ Implicit_Data *data = cloth->implicit;
+ int numverts = cloth->numverts;
+ ClothVertex *vert;
+ int i;
+
+ for (i = 0, vert = cloth->verts; i < numverts; i++, vert++) {
+ float x[3], v[3];
+
+ cloth_get_vertex_motion_state(data, vert, x, v);
+ BPH_hair_volume_add_vertex(grid, x, v);
+ }
+#else
+ LinkNode *link;
+ float cellsize, gmin[3], cell_scale, cell_offset[3];
+
+ /* scale and offset for transforming vertex locations into grid space
+ * (cell size is 0..1, gmin becomes origin)
+ */
+ BPH_hair_volume_grid_geometry(grid, &cellsize, NULL, gmin, NULL);
+ cell_scale = cellsize > 0.0f ? 1.0f / cellsize : 0.0f;
+ mul_v3_v3fl(cell_offset, gmin, cell_scale);
+ negate_v3(cell_offset);
+
+ link = cloth->springs;
+ while (link) {
+ ClothSpring *spring = (ClothSpring *)link->link;
+ if (spring->type == CLOTH_SPRING_TYPE_STRUCTURAL)
+ link = cloth_continuum_add_hair_segments(grid, cell_scale, cell_offset, cloth, link);
+ else
+ link = link->next;
+ }
+#endif
+ BPH_hair_volume_normalize_vertex_grid(grid);
+}
+
+static void cloth_continuum_step(ClothModifierData *clmd, float dt)
+{
+ ClothSimSettings *parms = clmd->sim_parms;
+ Cloth *cloth = clmd->clothObject;
+ Implicit_Data *data = cloth->implicit;
+ int numverts = cloth->numverts;
+ ClothVertex *vert;
+
+ const float fluid_factor = 0.95f; /* blend between PIC and FLIP methods */
+ float smoothfac = parms->velocity_smooth;
+ /* XXX FIXME arbitrary factor!!! this should be based on some intuitive value instead,
+ * like number of hairs per cell and time decay instead of "strength"
+ */
+ float density_target = parms->density_target;
+ float density_strength = parms->density_strength;
+ float gmin[3], gmax[3];
+ int i;
+
+ /* clear grid info */
+ zero_v3_int(clmd->hair_grid_res);
+ zero_v3(clmd->hair_grid_min);
+ zero_v3(clmd->hair_grid_max);
+ clmd->hair_grid_cellsize = 0.0f;
+
+ hair_get_boundbox(clmd, gmin, gmax);
+
+ /* gather velocities & density */
+ if (smoothfac > 0.0f || density_strength > 0.0f) {
+ HairGrid *grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_cell_size, gmin, gmax);
+
+ cloth_continuum_fill_grid(grid, cloth);
+
+ /* main hair continuum solver */
+ BPH_hair_volume_solve_divergence(grid, dt, density_target, density_strength);
+
+ for (i = 0, vert = cloth->verts; i < numverts; i++, vert++) {
+ float x[3], v[3], nv[3];
+
+ /* calculate volumetric velocity influence */
+ BPH_mass_spring_get_position(data, i, x);
+ BPH_mass_spring_get_new_velocity(data, i, v);
+
+ BPH_hair_volume_grid_velocity(grid, x, v, fluid_factor, nv);
+
+ interp_v3_v3v3(nv, v, nv, smoothfac);
+
+ /* apply on hair data */
+ BPH_mass_spring_set_new_velocity(data, i, nv);
+ }
+
+ /* store basic grid info in the modifier data */
+ BPH_hair_volume_grid_geometry(grid, &clmd->hair_grid_cellsize, clmd->hair_grid_res, clmd->hair_grid_min, clmd->hair_grid_max);
+
+#if 0 /* DEBUG hair velocity vector field */
+ {
+ const int size = 64;
+ int i, j;
+ float offset[3], a[3], b[3];
+ const int axis = 0;
+ const float shift = 0.0f;
+
+ copy_v3_v3(offset, clmd->hair_grid_min);
+ zero_v3(a);
+ zero_v3(b);
+
+ offset[axis] = shift * clmd->hair_grid_cellsize;
+ a[(axis+1) % 3] = clmd->hair_grid_max[(axis+1) % 3] - clmd->hair_grid_min[(axis+1) % 3];
+ b[(axis+2) % 3] = clmd->hair_grid_max[(axis+2) % 3] - clmd->hair_grid_min[(axis+2) % 3];
+
+ BKE_sim_debug_data_clear_category(clmd->debug_data, "grid velocity");
+ for (j = 0; j < size; ++j) {
+ for (i = 0; i < size; ++i) {
+ float x[3], v[3], gvel[3], gvel_smooth[3], gdensity;
+
+ madd_v3_v3v3fl(x, offset, a, (float)i / (float)(size-1));
+ madd_v3_v3fl(x, b, (float)j / (float)(size-1));
+ zero_v3(v);
+
+ BPH_hair_volume_grid_interpolate(grid, x, &gdensity, gvel, gvel_smooth, NULL, NULL);
+
+// BKE_sim_debug_data_add_circle(clmd->debug_data, x, gdensity, 0.7, 0.3, 1, "grid density", i, j, 3111);
+ if (!is_zero_v3(gvel) || !is_zero_v3(gvel_smooth)) {
+ float dvel[3];
+ sub_v3_v3v3(dvel, gvel_smooth, gvel);
+// BKE_sim_debug_data_add_vector(clmd->debug_data, x, gvel, 0.4, 0, 1, "grid velocity", i, j, 3112);
+// BKE_sim_debug_data_add_vector(clmd->debug_data, x, gvel_smooth, 0.6, 1, 1, "grid velocity", i, j, 3113);
+ BKE_sim_debug_data_add_vector(clmd->debug_data, x, dvel, 0.4, 1, 0.7, "grid velocity", i, j, 3114);
+#if 0
+ if (gdensity > 0.0f) {
+ float col0[3] = {0.0, 0.0, 0.0};
+ float col1[3] = {0.0, 1.0, 0.0};
+ float col[3];
+
+ interp_v3_v3v3(col, col0, col1, CLAMPIS(gdensity * clmd->sim_parms->density_strength, 0.0, 1.0));
+// BKE_sim_debug_data_add_circle(clmd->debug_data, x, gdensity * clmd->sim_parms->density_strength, 0, 1, 0.4, "grid velocity", i, j, 3115);
+// BKE_sim_debug_data_add_dot(clmd->debug_data, x, col[0], col[1], col[2], "grid velocity", i, j, 3115);
+ BKE_sim_debug_data_add_circle(clmd->debug_data, x, 0.01f, col[0], col[1], col[2], "grid velocity", i, j, 3115);
+ }
+#endif
+ }
+ }
+ }
+ }
+#endif
+
+ BPH_hair_volume_free_vertex_grid(grid);
+ }
+}
+
+#if 0
+static void cloth_calc_volume_force(ClothModifierData *clmd)
+{
+ ClothSimSettings *parms = clmd->sim_parms;
+ Cloth *cloth = clmd->clothObject;
+ Implicit_Data *data = cloth->implicit;
+ int numverts = cloth->numverts;
+ ClothVertex *vert;
+
+ /* 2.0f is an experimental value that seems to give good results */
+ float smoothfac = 2.0f * parms->velocity_smooth;
+ float collfac = 2.0f * parms->collider_friction;
+ float pressfac = parms->pressure;
+ float minpress = parms->pressure_threshold;
+ float gmin[3], gmax[3];
+ int i;
+
+ hair_get_boundbox(clmd, gmin, gmax);
+
+ /* gather velocities & density */
+ if (smoothfac > 0.0f || pressfac > 0.0f) {
+ HairVertexGrid *vertex_grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_res, gmin, gmax);
+
+ vert = cloth->verts;
+ for (i = 0; i < numverts; i++, vert++) {
+ float x[3], v[3];
+
+ if (vert->solver_index < 0) {
+ copy_v3_v3(x, vert->x);
+ copy_v3_v3(v, vert->v);
+ }
+ else {
+ BPH_mass_spring_get_motion_state(data, vert->solver_index, x, v);
+ }
+ BPH_hair_volume_add_vertex(vertex_grid, x, v);
+ }
+ BPH_hair_volume_normalize_vertex_grid(vertex_grid);
+
+ vert = cloth->verts;
+ for (i = 0; i < numverts; i++, vert++) {
+ float x[3], v[3], f[3], dfdx[3][3], dfdv[3][3];
+
+ if (vert->solver_index < 0)
+ continue;
+
+ /* calculate volumetric forces */
+ BPH_mass_spring_get_motion_state(data, vert->solver_index, x, v);
+ BPH_hair_volume_vertex_grid_forces(vertex_grid, x, v, smoothfac, pressfac, minpress, f, dfdx, dfdv);
+ /* apply on hair data */
+ BPH_mass_spring_force_extern(data, vert->solver_index, f, dfdx, dfdv);
+ }
+
+ BPH_hair_volume_free_vertex_grid(vertex_grid);
+ }
+}
+#endif
+
+/* old collision stuff for cloth, use for continuity
+ * until a good replacement is ready
+ */
+static void cloth_collision_solve_extra(Object *ob, ClothModifierData *clmd, ListBase *effectors, float frame, float step, float dt)
+{
+ Cloth *cloth = clmd->clothObject;
+ Implicit_Data *id = cloth->implicit;
+ ClothVertex *verts = cloth->verts;
+ int numverts = cloth->numverts;
+ const float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;;
+
+ bool do_extra_solve;
+ int i;
+
+ if (!(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED))
+ return;
+ if (!clmd->clothObject->bvhtree)
+ return;
+
+ // update verts to current positions
+ for (i = 0; i < numverts; i++) {
+ BPH_mass_spring_get_new_position(id, i, verts[i].tx);
+
+ sub_v3_v3v3(verts[i].tv, verts[i].tx, verts[i].txold);
+ copy_v3_v3(verts[i].v, verts[i].tv);
+ }
+
+#if 0 /* unused */
+ for (i=0, cv=cloth->verts; i<cloth->numverts; i++, cv++) {
+ copy_v3_v3(initial_cos[i], cv->tx);
+ }
+#endif
+
+ // call collision function
+ // TODO: check if "step" or "step+dt" is correct - dg
+ do_extra_solve = cloth_bvh_objcollision(ob, clmd, step / clmd->sim_parms->timescale, dt / clmd->sim_parms->timescale);
+
+ // copy corrected positions back to simulation
+ for (i = 0; i < numverts; i++) {
+ float curx[3];
+ BPH_mass_spring_get_position(id, i, curx);
+ // correct velocity again, just to be sure we had to change it due to adaptive collisions
+ sub_v3_v3v3(verts[i].tv, verts[i].tx, curx);
+ }
+
+ if (do_extra_solve) {
+// cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
+
+ for (i = 0; i < numverts; i++) {
+
+ float newv[3];
+
+ if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
+ continue;
+
+ BPH_mass_spring_set_new_position(id, i, verts[i].tx);
+ mul_v3_v3fl(newv, verts[i].tv, spf);
+ BPH_mass_spring_set_new_velocity(id, i, newv);
+ }
+ }
+
+ // X = Xnew;
+ BPH_mass_spring_apply_result(id);
+
+ if (do_extra_solve) {
+ ImplicitSolverResult result;
+
+ /* initialize forces to zero */
+ BPH_mass_spring_clear_forces(id);
+
+ // calculate forces
+ cloth_calc_force(clmd, frame, effectors, step);
+
+ // calculate new velocity and position
+ BPH_mass_spring_solve_velocities(id, dt, &result);
+// cloth_record_result(clmd, &result, clmd->sim_parms->stepsPerFrame);
+
+ /* note: positions are advanced only once in the main solver step! */
+
+ BPH_mass_spring_apply_result(id);
+ }
+}
+
+static void cloth_clear_result(ClothModifierData *clmd)
+{
+ ClothSolverResult *sres = clmd->solver_result;
+
+ sres->status = 0;
+ sres->max_error = sres->min_error = sres->avg_error = 0.0f;
+ sres->max_iterations = sres->min_iterations = 0;
+ sres->avg_iterations = 0.0f;
+}
+
+static void cloth_record_result(ClothModifierData *clmd, ImplicitSolverResult *result, int steps)
+{
+ ClothSolverResult *sres = clmd->solver_result;
+
+ if (sres->status) { /* already initialized ? */
+ /* error only makes sense for successful iterations */
+ if (result->status == BPH_SOLVER_SUCCESS) {
+ sres->min_error = min_ff(sres->min_error, result->error);
+ sres->max_error = max_ff(sres->max_error, result->error);
+ sres->avg_error += result->error / (float)steps;
+ }
+
+ sres->min_iterations = min_ii(sres->min_iterations, result->iterations);
+ sres->max_iterations = max_ii(sres->max_iterations, result->iterations);
+ sres->avg_iterations += (float)result->iterations / (float)steps;
+ }
+ else {
+ /* error only makes sense for successful iterations */
+ if (result->status == BPH_SOLVER_SUCCESS) {
+ sres->min_error = sres->max_error = result->error;
+ sres->avg_error += result->error / (float)steps;
+ }
+
+ sres->min_iterations = sres->max_iterations = result->iterations;
+ sres->avg_iterations += (float)result->iterations / (float)steps;
+ }
+
+ sres->status |= result->status;
+}
+
+int BPH_cloth_solve(Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
+{
+ /* Hair currently is a cloth sim in disguise ...
+ * Collision detection and volumetrics work differently then.
+ * Bad design, TODO
+ */
+ const bool is_hair = (clmd->hairdata != NULL);
+
+ unsigned int i=0;
+ float step=0.0f, tf=clmd->sim_parms->timescale;
+ Cloth *cloth = clmd->clothObject;
+ ClothVertex *verts = cloth->verts/*, *cv*/;
+ unsigned int numverts = cloth->numverts;
+ float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
+ Implicit_Data *id = cloth->implicit;
+ ColliderContacts *contacts = NULL;
+ int totcolliders = 0;
+
+ BKE_sim_debug_data_clear_category("collision");
+
+ if (!clmd->solver_result)
+ clmd->solver_result = (ClothSolverResult *)MEM_callocN(sizeof(ClothSolverResult), "cloth solver result");
+ cloth_clear_result(clmd);
+
+ if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) { /* do goal stuff */
+ for (i = 0; i < numverts; i++) {
+ // update velocities with constrained velocities from pinned verts
+ if (verts [i].flags & CLOTH_VERT_FLAG_PINNED) {
+ float v[3];
+ sub_v3_v3v3(v, verts[i].xconst, verts[i].xold);
+ // mul_v3_fl(v, clmd->sim_parms->stepsPerFrame);
+ BPH_mass_spring_set_velocity(id, i, v);
+ }
+ }
+ }
+
+ while (step < tf) {
+ ImplicitSolverResult result;
+
+ /* copy velocities for collision */
+ for (i = 0; i < numverts; i++) {
+ BPH_mass_spring_get_motion_state(id, i, NULL, verts[i].tv);
+ copy_v3_v3(verts[i].v, verts[i].tv);
+ }
+
+ if (is_hair) {
+ /* determine contact points */
+ if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) {
+ cloth_find_point_contacts(ob, clmd, 0.0f, tf, &contacts, &totcolliders);
+ }
+
+ /* setup vertex constraints for pinned vertices and contacts */
+ cloth_setup_constraints(clmd, contacts, totcolliders, dt);
+ }
+ else {
+ /* setup vertex constraints for pinned vertices */
+ cloth_setup_constraints(clmd, NULL, 0, dt);
+ }
+
+ /* initialize forces to zero */
+ BPH_mass_spring_clear_forces(id);
+
+ // damping velocity for artistic reasons
+ // this is a bad way to do it, should be removed imo - lukas_t
+ if (clmd->sim_parms->vel_damping != 1.0f) {
+ for (i = 0; i < numverts; i++) {
+ float v[3];
+ BPH_mass_spring_get_motion_state(id, i, NULL, v);
+ mul_v3_fl(v, clmd->sim_parms->vel_damping);
+ BPH_mass_spring_set_velocity(id, i, v);
+ }
+ }
+
+ // calculate forces
+ cloth_calc_force(clmd, frame, effectors, step);
+
+ // calculate new velocity and position
+ BPH_mass_spring_solve_velocities(id, dt, &result);
+ cloth_record_result(clmd, &result, clmd->sim_parms->stepsPerFrame);
+
+ if (is_hair) {
+ cloth_continuum_step(clmd, dt);
+ }
+
+ BPH_mass_spring_solve_positions(id, dt);
+
+ if (!is_hair) {
+ cloth_collision_solve_extra(ob, clmd, effectors, frame, step, dt);
+ }
+
+ BPH_mass_spring_apply_result(id);
+
+ /* move pinned verts to correct position */
+ for (i = 0; i < numverts; i++) {
+ if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) {
+ if (verts[i].flags & CLOTH_VERT_FLAG_PINNED) {
+ float x[3];
+ interp_v3_v3v3(x, verts[i].xold, verts[i].xconst, step + dt);
+ BPH_mass_spring_set_position(id, i, x);
+ }
+ }
+
+ BPH_mass_spring_get_motion_state(id, i, verts[i].txold, NULL);
+ }
+
+ /* free contact points */
+ if (contacts) {
+ cloth_free_contacts(contacts, totcolliders);
+ }
+
+ step += dt;
+ }
+
+ /* copy results back to cloth data */
+ for (i = 0; i < numverts; i++) {
+ BPH_mass_spring_get_motion_state(id, i, verts[i].x, verts[i].v);
+ copy_v3_v3(verts[i].txold, verts[i].x);
+ }
+
+ return 1;
+}
+
+bool BPH_cloth_solver_get_texture_data(Object *UNUSED(ob), ClothModifierData *clmd, VoxelData *vd)
+{
+ Cloth *cloth = clmd->clothObject;
+ HairGrid *grid;
+ float gmin[3], gmax[3];
+
+ if (!clmd->clothObject || !clmd->clothObject->implicit)
+ return false;
+
+ hair_get_boundbox(clmd, gmin, gmax);
+
+ grid = BPH_hair_volume_create_vertex_grid(clmd->sim_parms->voxel_cell_size, gmin, gmax);
+ cloth_continuum_fill_grid(grid, cloth);
+
+ BPH_hair_volume_get_texture_data(grid, vd);
+
+ BPH_hair_volume_free_vertex_grid(grid);
+
+ return true;
+}
diff --git a/source/blender/physics/intern/ConstrainedConjugateGradient.h b/source/blender/physics/intern/ConstrainedConjugateGradient.h
new file mode 100644
index 00000000000..2d4389f6766
--- /dev/null
+++ b/source/blender/physics/intern/ConstrainedConjugateGradient.h
@@ -0,0 +1,294 @@
+
+#ifndef EIGEN_CONSTRAINEDCG_H
+#define EIGEN_CONSTRAINEDCG_H
+
+#include <Eigen/Core>
+
+namespace Eigen {
+
+namespace internal {
+
+/** \internal Low-level conjugate gradient algorithm
+ * \param mat The matrix A
+ * \param rhs The right hand side vector b
+ * \param x On input and initial solution, on output the computed solution.
+ * \param precond A preconditioner being able to efficiently solve for an
+ * approximation of Ax=b (regardless of b)
+ * \param iters On input the max number of iteration, on output the number of performed iterations.
+ * \param tol_error On input the tolerance error, on output an estimation of the relative error.
+ */
+template<typename MatrixType, typename Rhs, typename Dest, typename FilterMatrixType, typename Preconditioner>
+EIGEN_DONT_INLINE
+void constrained_conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x,
+ const FilterMatrixType &filter,
+ const Preconditioner& precond, int& iters,
+ typename Dest::RealScalar& tol_error)
+{
+ using std::sqrt;
+ using std::abs;
+ typedef typename Dest::RealScalar RealScalar;
+ typedef typename Dest::Scalar Scalar;
+ typedef Matrix<Scalar,Dynamic,1> VectorType;
+
+ RealScalar tol = tol_error;
+ int maxIters = iters;
+
+ int n = mat.cols();
+
+ VectorType residual = filter * (rhs - mat * x); //initial residual
+
+ RealScalar rhsNorm2 = (filter * rhs).squaredNorm();
+ if(rhsNorm2 == 0)
+ {
+ /* XXX TODO set constrained result here */
+ x.setZero();
+ iters = 0;
+ tol_error = 0;
+ return;
+ }
+ RealScalar threshold = tol*tol*rhsNorm2;
+ RealScalar residualNorm2 = residual.squaredNorm();
+ if (residualNorm2 < threshold)
+ {
+ iters = 0;
+ tol_error = sqrt(residualNorm2 / rhsNorm2);
+ return;
+ }
+
+ VectorType p(n);
+ p = filter * precond.solve(residual); //initial search direction
+
+ VectorType z(n), tmp(n);
+ RealScalar absNew = numext::real(residual.dot(p)); // the square of the absolute value of r scaled by invM
+ int i = 0;
+ while(i < maxIters)
+ {
+ tmp.noalias() = filter * (mat * p); // the bottleneck of the algorithm
+
+ Scalar alpha = absNew / p.dot(tmp); // the amount we travel on dir
+ x += alpha * p; // update solution
+ residual -= alpha * tmp; // update residue
+
+ residualNorm2 = residual.squaredNorm();
+ if(residualNorm2 < threshold)
+ break;
+
+ z = precond.solve(residual); // approximately solve for "A z = residual"
+
+ RealScalar absOld = absNew;
+ absNew = numext::real(residual.dot(z)); // update the absolute value of r
+ RealScalar beta = absNew / absOld; // calculate the Gram-Schmidt value used to create the new search direction
+ p = filter * (z + beta * p); // update search direction
+ i++;
+ }
+ tol_error = sqrt(residualNorm2 / rhsNorm2);
+ iters = i;
+}
+
+}
+
+#if 0 /* unused */
+template<typename MatrixType>
+struct MatrixFilter
+{
+ MatrixFilter() :
+ m_cmat(NULL)
+ {
+ }
+
+ MatrixFilter(const MatrixType &cmat) :
+ m_cmat(&cmat)
+ {
+ }
+
+ void setMatrix(const MatrixType &cmat) { m_cmat = &cmat; }
+
+ template <typename VectorType>
+ void apply(VectorType v) const
+ {
+ v = (*m_cmat) * v;
+ }
+
+protected:
+ const MatrixType *m_cmat;
+};
+#endif
+
+template< typename _MatrixType, int _UpLo=Lower,
+ typename _FilterMatrixType = _MatrixType,
+ typename _Preconditioner = DiagonalPreconditioner<typename _MatrixType::Scalar> >
+class ConstrainedConjugateGradient;
+
+namespace internal {
+
+template< typename _MatrixType, int _UpLo, typename _FilterMatrixType, typename _Preconditioner>
+struct traits<ConstrainedConjugateGradient<_MatrixType,_UpLo,_FilterMatrixType,_Preconditioner> >
+{
+ typedef _MatrixType MatrixType;
+ typedef _FilterMatrixType FilterMatrixType;
+ typedef _Preconditioner Preconditioner;
+};
+
+}
+
+/** \ingroup IterativeLinearSolvers_Module
+ * \brief A conjugate gradient solver for sparse self-adjoint problems with additional constraints
+ *
+ * This class allows to solve for A.x = b sparse linear problems using a conjugate gradient algorithm.
+ * The sparse matrix A must be selfadjoint. The vectors x and b can be either dense or sparse.
+ *
+ * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix.
+ * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower
+ * or Upper. Default is Lower.
+ * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner
+ *
+ * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()
+ * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations
+ * and NumTraits<Scalar>::epsilon() for the tolerance.
+ *
+ * This class can be used as the direct solver classes. Here is a typical usage example:
+ * \code
+ * int n = 10000;
+ * VectorXd x(n), b(n);
+ * SparseMatrix<double> A(n,n);
+ * // fill A and b
+ * ConjugateGradient<SparseMatrix<double> > cg;
+ * cg.compute(A);
+ * x = cg.solve(b);
+ * std::cout << "#iterations: " << cg.iterations() << std::endl;
+ * std::cout << "estimated error: " << cg.error() << std::endl;
+ * // update b, and solve again
+ * x = cg.solve(b);
+ * \endcode
+ *
+ * By default the iterations start with x=0 as an initial guess of the solution.
+ * One can control the start using the solveWithGuess() method. Here is a step by
+ * step execution example starting with a random guess and printing the evolution
+ * of the estimated error:
+ * * \code
+ * x = VectorXd::Random(n);
+ * cg.setMaxIterations(1);
+ * int i = 0;
+ * do {
+ * x = cg.solveWithGuess(b,x);
+ * std::cout << i << " : " << cg.error() << std::endl;
+ * ++i;
+ * } while (cg.info()!=Success && i<100);
+ * \endcode
+ * Note that such a step by step excution is slightly slower.
+ *
+ * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner
+ */
+template< typename _MatrixType, int _UpLo, typename _FilterMatrixType, typename _Preconditioner>
+class ConstrainedConjugateGradient : public IterativeSolverBase<ConstrainedConjugateGradient<_MatrixType,_UpLo,_FilterMatrixType,_Preconditioner> >
+{
+ typedef IterativeSolverBase<ConstrainedConjugateGradient> Base;
+ using Base::mp_matrix;
+ using Base::m_error;
+ using Base::m_iterations;
+ using Base::m_info;
+ using Base::m_isInitialized;
+public:
+ typedef _MatrixType MatrixType;
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::Index Index;
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef _FilterMatrixType FilterMatrixType;
+ typedef _Preconditioner Preconditioner;
+
+ enum {
+ UpLo = _UpLo
+ };
+
+public:
+
+ /** Default constructor. */
+ ConstrainedConjugateGradient() : Base() {}
+
+ /** Initialize the solver with matrix \a A for further \c Ax=b solving.
+ *
+ * This constructor is a shortcut for the default constructor followed
+ * by a call to compute().
+ *
+ * \warning this class stores a reference to the matrix A as well as some
+ * precomputed values that depend on it. Therefore, if \a A is changed
+ * this class becomes invalid. Call compute() to update it with the new
+ * matrix A, or modify a copy of A.
+ */
+ ConstrainedConjugateGradient(const MatrixType& A) : Base(A) {}
+
+ ~ConstrainedConjugateGradient() {}
+
+ FilterMatrixType &filter() { return m_filter; }
+ const FilterMatrixType &filter() const { return m_filter; }
+
+ /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A
+ * \a x0 as an initial solution.
+ *
+ * \sa compute()
+ */
+ template<typename Rhs,typename Guess>
+ inline const internal::solve_retval_with_guess<ConstrainedConjugateGradient, Rhs, Guess>
+ solveWithGuess(const MatrixBase<Rhs>& b, const Guess& x0) const
+ {
+ eigen_assert(m_isInitialized && "ConjugateGradient is not initialized.");
+ eigen_assert(Base::rows()==b.rows()
+ && "ConjugateGradient::solve(): invalid number of rows of the right hand side matrix b");
+ return internal::solve_retval_with_guess
+ <ConstrainedConjugateGradient, Rhs, Guess>(*this, b.derived(), x0);
+ }
+
+ /** \internal */
+ template<typename Rhs,typename Dest>
+ void _solveWithGuess(const Rhs& b, Dest& x) const
+ {
+ m_iterations = Base::maxIterations();
+ m_error = Base::m_tolerance;
+
+ for(int j=0; j<b.cols(); ++j)
+ {
+ m_iterations = Base::maxIterations();
+ m_error = Base::m_tolerance;
+
+ typename Dest::ColXpr xj(x,j);
+ internal::constrained_conjugate_gradient(mp_matrix->template selfadjointView<UpLo>(), b.col(j), xj, m_filter,
+ Base::m_preconditioner, m_iterations, m_error);
+ }
+
+ m_isInitialized = true;
+ m_info = m_error <= Base::m_tolerance ? Success : NoConvergence;
+ }
+
+ /** \internal */
+ template<typename Rhs,typename Dest>
+ void _solve(const Rhs& b, Dest& x) const
+ {
+ x.setOnes();
+ _solveWithGuess(b,x);
+ }
+
+protected:
+ FilterMatrixType m_filter;
+};
+
+
+namespace internal {
+
+template<typename _MatrixType, int _UpLo, typename _Filter, typename _Preconditioner, typename Rhs>
+struct solve_retval<ConstrainedConjugateGradient<_MatrixType,_UpLo,_Filter,_Preconditioner>, Rhs>
+ : solve_retval_base<ConstrainedConjugateGradient<_MatrixType,_UpLo,_Filter,_Preconditioner>, Rhs>
+{
+ typedef ConstrainedConjugateGradient<_MatrixType,_UpLo,_Filter,_Preconditioner> Dec;
+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
+
+ template<typename Dest> void evalTo(Dest& dst) const
+ {
+ dec()._solve(rhs(),dst);
+ }
+};
+
+} // end namespace internal
+
+} // end namespace Eigen
+
+#endif // EIGEN_CONSTRAINEDCG_H
diff --git a/source/blender/physics/intern/eigen_utils.h b/source/blender/physics/intern/eigen_utils.h
new file mode 100644
index 00000000000..cd3bd5ee45d
--- /dev/null
+++ b/source/blender/physics/intern/eigen_utils.h
@@ -0,0 +1,230 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __EIGEN_UTILS_H__
+#define __EIGEN_UTILS_H__
+
+/** \file eigen_utils.h
+ * \ingroup bph
+ */
+
+#ifdef __GNUC__
+# pragma GCC diagnostic push
+/* XXX suppress verbose warnings in eigen */
+# pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+
+#include <Eigen/Sparse>
+#include <Eigen/src/Core/util/DisableStupidWarnings.h>
+
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
+#include "BLI_utildefines.h"
+
+
+typedef float Scalar;
+
+/* slightly extended Eigen vector class
+ * with conversion to/from plain C float array
+ */
+class Vector3 : public Eigen::Vector3f {
+public:
+ typedef float *ctype;
+
+ Vector3()
+ {
+ }
+
+ Vector3(const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ coeffRef(k) = v[k];
+ }
+
+ Vector3& operator = (const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ coeffRef(k) = v[k];
+ return *this;
+ }
+
+ operator ctype()
+ {
+ return data();
+ }
+};
+
+/* slightly extended Eigen matrix class
+ * with conversion to/from plain C float array
+ */
+class Matrix3 : public Eigen::Matrix3f {
+public:
+ typedef float (*ctype)[3];
+
+ Matrix3()
+ {
+ }
+
+ Matrix3(const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ coeffRef(l, k) = v[k][l];
+ }
+
+ Matrix3& operator = (const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ coeffRef(l, k) = v[k][l];
+ return *this;
+ }
+
+ operator ctype()
+ {
+ return (ctype)data();
+ }
+};
+
+typedef Eigen::VectorXf lVector;
+
+/* Extension of dense Eigen vectors,
+ * providing 3-float block access for blenlib math functions
+ */
+class lVector3f : public Eigen::VectorXf {
+public:
+ typedef Eigen::VectorXf base_t;
+
+ lVector3f()
+ {
+ }
+
+ template <typename T>
+ lVector3f& operator = (T rhs)
+ {
+ base_t::operator=(rhs);
+ return *this;
+ }
+
+ float* v3(int vertex)
+ {
+ return &coeffRef(3 * vertex);
+ }
+
+ const float* v3(int vertex) const
+ {
+ return &coeffRef(3 * vertex);
+ }
+};
+
+typedef Eigen::Triplet<Scalar> Triplet;
+typedef std::vector<Triplet> TripletList;
+
+typedef Eigen::SparseMatrix<Scalar> lMatrix;
+
+/* Constructor type that provides more convenient handling of Eigen triplets
+ * for efficient construction of sparse 3x3 block matrices.
+ * This should be used for building lMatrix instead of writing to such lMatrix directly (which is very inefficient).
+ * After all elements have been defined using the set() method, the actual matrix can be filled using construct().
+ */
+struct lMatrix3fCtor {
+ lMatrix3fCtor()
+ {
+ }
+
+ void reset()
+ {
+ m_trips.clear();
+ }
+
+ void reserve(int numverts)
+ {
+ /* reserve for diagonal entries */
+ m_trips.reserve(numverts * 9);
+ }
+
+ void add(int i, int j, const Matrix3 &m)
+ {
+ i *= 3;
+ j *= 3;
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ m_trips.push_back(Triplet(i + k, j + l, m.coeff(l, k)));
+ }
+
+ void sub(int i, int j, const Matrix3 &m)
+ {
+ i *= 3;
+ j *= 3;
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ m_trips.push_back(Triplet(i + k, j + l, -m.coeff(l, k)));
+ }
+
+ inline void construct(lMatrix &m)
+ {
+ m.setFromTriplets(m_trips.begin(), m_trips.end());
+ m_trips.clear();
+ }
+
+private:
+ TripletList m_trips;
+};
+
+typedef Eigen::ConjugateGradient<lMatrix, Eigen::Lower, Eigen::DiagonalPreconditioner<Scalar> > ConjugateGradient;
+
+using Eigen::ComputationInfo;
+
+BLI_INLINE void print_lvector(const lVector3f &v)
+{
+ for (int i = 0; i < v.rows(); ++i) {
+ if (i > 0 && i % 3 == 0)
+ printf("\n");
+
+ printf("%f,\n", v[i]);
+ }
+}
+
+BLI_INLINE void print_lmatrix(const lMatrix &m)
+{
+ for (int j = 0; j < m.rows(); ++j) {
+ if (j > 0 && j % 3 == 0)
+ printf("\n");
+
+ for (int i = 0; i < m.cols(); ++i) {
+ if (i > 0 && i % 3 == 0)
+ printf(" ");
+
+ implicit_print_matrix_elem(m.coeff(j, i));
+ }
+ printf("\n");
+ }
+}
+
+#endif
diff --git a/source/blender/physics/intern/hair_volume.cpp b/source/blender/physics/intern/hair_volume.cpp
new file mode 100644
index 00000000000..b07af1d201c
--- /dev/null
+++ b/source/blender/physics/intern/hair_volume.cpp
@@ -0,0 +1,1154 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Janne Karhu, Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/physics/intern/hair_volume.cpp
+ * \ingroup bph
+ */
+
+#include "MEM_guardedalloc.h"
+
+extern "C" {
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_texture_types.h"
+
+#include "BKE_effect.h"
+}
+
+#include "implicit.h"
+#include "eigen_utils.h"
+
+/* ================ Volumetric Hair Interaction ================
+ * adapted from
+ *
+ * Volumetric Methods for Simulation and Rendering of Hair
+ * (Petrovic, Henne, Anderson, Pixar Technical Memo #06-08, Pixar Animation Studios)
+ *
+ * as well as
+ *
+ * "Detail Preserving Continuum Simulation of Straight Hair"
+ * (McAdams, Selle 2009)
+ */
+
+/* Note about array indexing:
+ * Generally the arrays here are one-dimensional.
+ * The relation between 3D indices and the array offset is
+ * offset = x + res_x * y + res_x * res_y * z
+ */
+
+static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
+
+BLI_INLINE int floor_int(float value)
+{
+ return value > 0.0f ? (int)value : ((int)value) - 1;
+}
+
+BLI_INLINE float floor_mod(float value)
+{
+ return value - floorf(value);
+}
+
+BLI_INLINE int hair_grid_size(const int res[3])
+{
+ return res[0] * res[1] * res[2];
+}
+
+typedef struct HairGridVert {
+ int samples;
+ float velocity[3];
+ float density;
+
+ float velocity_smooth[3];
+} HairGridVert;
+
+typedef struct HairGrid {
+ HairGridVert *verts;
+ int res[3];
+ float gmin[3], gmax[3];
+ float cellsize, inv_cellsize;
+} HairGrid;
+
+#define HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, axis) ( min_ii( max_ii( (int)((vec[axis] - gmin[axis]) * scale), 0), res[axis]-2 ) )
+
+BLI_INLINE int hair_grid_offset(const float vec[3], const int res[3], const float gmin[3], float scale)
+{
+ int i, j, k;
+ i = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 0);
+ j = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 1);
+ k = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 2);
+ return i + (j + k*res[1])*res[0];
+}
+
+BLI_INLINE int hair_grid_interp_weights(const int res[3], const float gmin[3], float scale, const float vec[3], float uvw[3])
+{
+ int i, j, k, offset;
+
+ i = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 0);
+ j = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 1);
+ k = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 2);
+ offset = i + (j + k*res[1])*res[0];
+
+ uvw[0] = (vec[0] - gmin[0]) * scale - (float)i;
+ uvw[1] = (vec[1] - gmin[1]) * scale - (float)j;
+ uvw[2] = (vec[2] - gmin[2]) * scale - (float)k;
+
+// BLI_assert(0.0f <= uvw[0] && uvw[0] <= 1.0001f);
+// BLI_assert(0.0f <= uvw[1] && uvw[1] <= 1.0001f);
+// BLI_assert(0.0f <= uvw[2] && uvw[2] <= 1.0001f);
+
+ return offset;
+}
+
+BLI_INLINE void hair_grid_interpolate(const HairGridVert *grid, const int res[3], const float gmin[3], float scale, const float vec[3],
+ float *density, float velocity[3], float vel_smooth[3], float density_gradient[3], float velocity_gradient[3][3])
+{
+ HairGridVert data[8];
+ float uvw[3], muvw[3];
+ int res2 = res[1] * res[0];
+ int offset;
+
+ offset = hair_grid_interp_weights(res, gmin, scale, vec, uvw);
+ muvw[0] = 1.0f - uvw[0];
+ muvw[1] = 1.0f - uvw[1];
+ muvw[2] = 1.0f - uvw[2];
+
+ data[0] = grid[offset ];
+ data[1] = grid[offset +1];
+ data[2] = grid[offset +res[0] ];
+ data[3] = grid[offset +res[0]+1];
+ data[4] = grid[offset+res2 ];
+ data[5] = grid[offset+res2 +1];
+ data[6] = grid[offset+res2+res[0] ];
+ data[7] = grid[offset+res2+res[0]+1];
+
+ if (density) {
+ *density = muvw[2]*( muvw[1]*( muvw[0]*data[0].density + uvw[0]*data[1].density ) +
+ uvw[1]*( muvw[0]*data[2].density + uvw[0]*data[3].density ) ) +
+ uvw[2]*( muvw[1]*( muvw[0]*data[4].density + uvw[0]*data[5].density ) +
+ uvw[1]*( muvw[0]*data[6].density + uvw[0]*data[7].density ) );
+ }
+
+ if (velocity) {
+ int k;
+ for (k = 0; k < 3; ++k) {
+ velocity[k] = muvw[2]*( muvw[1]*( muvw[0]*data[0].velocity[k] + uvw[0]*data[1].velocity[k] ) +
+ uvw[1]*( muvw[0]*data[2].velocity[k] + uvw[0]*data[3].velocity[k] ) ) +
+ uvw[2]*( muvw[1]*( muvw[0]*data[4].velocity[k] + uvw[0]*data[5].velocity[k] ) +
+ uvw[1]*( muvw[0]*data[6].velocity[k] + uvw[0]*data[7].velocity[k] ) );
+ }
+ }
+
+ if (vel_smooth) {
+ int k;
+ for (k = 0; k < 3; ++k) {
+ vel_smooth[k] = muvw[2]*( muvw[1]*( muvw[0]*data[0].velocity_smooth[k] + uvw[0]*data[1].velocity_smooth[k] ) +
+ uvw[1]*( muvw[0]*data[2].velocity_smooth[k] + uvw[0]*data[3].velocity_smooth[k] ) ) +
+ uvw[2]*( muvw[1]*( muvw[0]*data[4].velocity_smooth[k] + uvw[0]*data[5].velocity_smooth[k] ) +
+ uvw[1]*( muvw[0]*data[6].velocity_smooth[k] + uvw[0]*data[7].velocity_smooth[k] ) );
+ }
+ }
+
+ if (density_gradient) {
+ density_gradient[0] = muvw[1] * muvw[2] * ( data[0].density - data[1].density ) +
+ uvw[1] * muvw[2] * ( data[2].density - data[3].density ) +
+ muvw[1] * uvw[2] * ( data[4].density - data[5].density ) +
+ uvw[1] * uvw[2] * ( data[6].density - data[7].density );
+
+ density_gradient[1] = muvw[2] * muvw[0] * ( data[0].density - data[2].density ) +
+ uvw[2] * muvw[0] * ( data[4].density - data[6].density ) +
+ muvw[2] * uvw[0] * ( data[1].density - data[3].density ) +
+ uvw[2] * uvw[0] * ( data[5].density - data[7].density );
+
+ density_gradient[2] = muvw[2] * muvw[0] * ( data[0].density - data[4].density ) +
+ uvw[2] * muvw[0] * ( data[1].density - data[5].density ) +
+ muvw[2] * uvw[0] * ( data[2].density - data[6].density ) +
+ uvw[2] * uvw[0] * ( data[3].density - data[7].density );
+ }
+
+ if (velocity_gradient) {
+ /* XXX TODO */
+ zero_m3(velocity_gradient);
+ }
+}
+
+void BPH_hair_volume_vertex_grid_forces(HairGrid *grid, const float x[3], const float v[3],
+ float smoothfac, float pressurefac, float minpressure,
+ float f[3], float dfdx[3][3], float dfdv[3][3])
+{
+ float gdensity, gvelocity[3], ggrad[3], gvelgrad[3][3], gradlen;
+
+ hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->inv_cellsize, x, &gdensity, gvelocity, NULL, ggrad, gvelgrad);
+
+ zero_v3(f);
+ sub_v3_v3(gvelocity, v);
+ mul_v3_v3fl(f, gvelocity, smoothfac);
+
+ gradlen = normalize_v3(ggrad) - minpressure;
+ if (gradlen > 0.0f) {
+ mul_v3_fl(ggrad, gradlen);
+ madd_v3_v3fl(f, ggrad, pressurefac);
+ }
+
+ zero_m3(dfdx);
+
+ sub_m3_m3m3(dfdv, gvelgrad, I);
+ mul_m3_fl(dfdv, smoothfac);
+}
+
+void BPH_hair_volume_grid_interpolate(HairGrid *grid, const float x[3],
+ float *density, float velocity[3], float velocity_smooth[3], float density_gradient[3], float velocity_gradient[3][3])
+{
+ hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->inv_cellsize, x, density, velocity, velocity_smooth, density_gradient, velocity_gradient);
+}
+
+void BPH_hair_volume_grid_velocity(HairGrid *grid, const float x[3], const float v[3],
+ float fluid_factor,
+ float r_v[3])
+{
+ float gdensity, gvelocity[3], gvel_smooth[3], ggrad[3], gvelgrad[3][3];
+ float v_pic[3], v_flip[3];
+
+ hair_grid_interpolate(grid->verts, grid->res, grid->gmin, grid->inv_cellsize, x, &gdensity, gvelocity, gvel_smooth, ggrad, gvelgrad);
+
+ /* velocity according to PIC method (Particle-in-Cell) */
+ copy_v3_v3(v_pic, gvel_smooth);
+
+ /* velocity according to FLIP method (Fluid-Implicit-Particle) */
+ sub_v3_v3v3(v_flip, gvel_smooth, gvelocity);
+ add_v3_v3(v_flip, v);
+
+ interp_v3_v3v3(r_v, v_pic, v_flip, fluid_factor);
+}
+
+void BPH_hair_volume_grid_clear(HairGrid *grid)
+{
+ const int size = hair_grid_size(grid->res);
+ int i;
+ for (i = 0; i < size; ++i) {
+ zero_v3(grid->verts[i].velocity);
+ zero_v3(grid->verts[i].velocity_smooth);
+ grid->verts[i].density = 0.0f;
+ grid->verts[i].samples = 0;
+ }
+}
+
+BLI_INLINE bool hair_grid_point_valid(const float vec[3], float gmin[3], float gmax[3])
+{
+ return !(vec[0] < gmin[0] || vec[1] < gmin[1] || vec[2] < gmin[2] ||
+ vec[0] > gmax[0] || vec[1] > gmax[1] || vec[2] > gmax[2]);
+}
+
+BLI_INLINE float dist_tent_v3f3(const float a[3], float x, float y, float z)
+{
+ float w = (1.0f - fabsf(a[0] - x)) * (1.0f - fabsf(a[1] - y)) * (1.0f - fabsf(a[2] - z));
+ return w;
+}
+
+BLI_INLINE float weights_sum(const float weights[8])
+{
+ float totweight = 0.0f;
+ int i;
+ for (i = 0; i < 8; ++i)
+ totweight += weights[i];
+ return totweight;
+}
+
+/* returns the grid array offset as well to avoid redundant calculation */
+BLI_INLINE int hair_grid_weights(const int res[3], const float gmin[3], float scale, const float vec[3], float weights[8])
+{
+ int i, j, k, offset;
+ float uvw[3];
+
+ i = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 0);
+ j = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 1);
+ k = HAIR_GRID_INDEX_AXIS(vec, res, gmin, scale, 2);
+ offset = i + (j + k*res[1])*res[0];
+
+ uvw[0] = (vec[0] - gmin[0]) * scale;
+ uvw[1] = (vec[1] - gmin[1]) * scale;
+ uvw[2] = (vec[2] - gmin[2]) * scale;
+
+ weights[0] = dist_tent_v3f3(uvw, (float)i , (float)j , (float)k );
+ weights[1] = dist_tent_v3f3(uvw, (float)(i+1), (float)j , (float)k );
+ weights[2] = dist_tent_v3f3(uvw, (float)i , (float)(j+1), (float)k );
+ weights[3] = dist_tent_v3f3(uvw, (float)(i+1), (float)(j+1), (float)k );
+ weights[4] = dist_tent_v3f3(uvw, (float)i , (float)j , (float)(k+1));
+ weights[5] = dist_tent_v3f3(uvw, (float)(i+1), (float)j , (float)(k+1));
+ weights[6] = dist_tent_v3f3(uvw, (float)i , (float)(j+1), (float)(k+1));
+ weights[7] = dist_tent_v3f3(uvw, (float)(i+1), (float)(j+1), (float)(k+1));
+
+// BLI_assert(fabsf(weights_sum(weights) - 1.0f) < 0.0001f);
+
+ return offset;
+}
+
+BLI_INLINE void grid_to_world(HairGrid *grid, float vecw[3], const float vec[3])
+{
+ copy_v3_v3(vecw, vec);
+ mul_v3_fl(vecw, grid->cellsize);
+ add_v3_v3(vecw, grid->gmin);
+}
+
+void BPH_hair_volume_add_vertex(HairGrid *grid, const float x[3], const float v[3])
+{
+ const int res[3] = { grid->res[0], grid->res[1], grid->res[2] };
+ float weights[8];
+ int di, dj, dk;
+ int offset;
+
+ if (!hair_grid_point_valid(x, grid->gmin, grid->gmax))
+ return;
+
+ offset = hair_grid_weights(res, grid->gmin, grid->inv_cellsize, x, weights);
+
+ for (di = 0; di < 2; ++di) {
+ for (dj = 0; dj < 2; ++dj) {
+ for (dk = 0; dk < 2; ++dk) {
+ int voffset = offset + di + (dj + dk*res[1])*res[0];
+ int iw = di + dj*2 + dk*4;
+
+ grid->verts[voffset].density += weights[iw];
+ madd_v3_v3fl(grid->verts[voffset].velocity, v, weights[iw]);
+ }
+ }
+ }
+}
+
+#if 0
+BLI_INLINE void hair_volume_eval_grid_vertex(HairGridVert *vert, const float loc[3], float radius, float dist_scale,
+ const float x2[3], const float v2[3], const float x3[3], const float v3[3])
+{
+ float closest[3], lambda, dist, weight;
+
+ lambda = closest_to_line_v3(closest, loc, x2, x3);
+ dist = len_v3v3(closest, loc);
+
+ weight = (radius - dist) * dist_scale;
+
+ if (weight > 0.0f) {
+ float vel[3];
+
+ interp_v3_v3v3(vel, v2, v3, lambda);
+ madd_v3_v3fl(vert->velocity, vel, weight);
+ vert->density += weight;
+ vert->samples += 1;
+ }
+}
+
+BLI_INLINE int major_axis_v3(const float v[3])
+{
+ const float a = fabsf(v[0]);
+ const float b = fabsf(v[1]);
+ const float c = fabsf(v[2]);
+ return a > b ? (a > c ? 0 : 2) : (b > c ? 1 : 2);
+}
+
+BLI_INLINE void hair_volume_add_segment_2D(HairGrid *grid,
+ const float UNUSED(x1[3]), const float UNUSED(v1[3]), const float x2[3], const float v2[3],
+ const float x3[3], const float v3[3], const float UNUSED(x4[3]), const float UNUSED(v4[3]),
+ const float UNUSED(dir1[3]), const float dir2[3], const float UNUSED(dir3[3]),
+ int resj, int resk, int jmin, int jmax, int kmin, int kmax,
+ HairGridVert *vert, int stride_j, int stride_k, const float loc[3], int axis_j, int axis_k,
+ int debug_i)
+{
+ const float radius = 1.5f;
+ const float dist_scale = grid->inv_cellsize;
+
+ int j, k;
+
+ /* boundary checks to be safe */
+ CLAMP_MIN(jmin, 0);
+ CLAMP_MAX(jmax, resj-1);
+ CLAMP_MIN(kmin, 0);
+ CLAMP_MAX(kmax, resk-1);
+
+ HairGridVert *vert_j = vert + jmin * stride_j;
+ float loc_j[3] = { loc[0], loc[1], loc[2] };
+ loc_j[axis_j] += (float)jmin;
+ for (j = jmin; j <= jmax; ++j, vert_j += stride_j, loc_j[axis_j] += 1.0f) {
+
+ HairGridVert *vert_k = vert_j + kmin * stride_k;
+ float loc_k[3] = { loc_j[0], loc_j[1], loc_j[2] };
+ loc_k[axis_k] += (float)kmin;
+ for (k = kmin; k <= kmax; ++k, vert_k += stride_k, loc_k[axis_k] += 1.0f) {
+
+ hair_volume_eval_grid_vertex(vert_k, loc_k, radius, dist_scale, x2, v2, x3, v3);
+
+#if 0
+ {
+ float wloc[3], x2w[3], x3w[3];
+ grid_to_world(grid, wloc, loc_k);
+ grid_to_world(grid, x2w, x2);
+ grid_to_world(grid, x3w, x3);
+
+ if (vert_k->samples > 0)
+ BKE_sim_debug_data_add_circle(wloc, 0.01f, 1.0, 1.0, 0.3, "grid", 2525, debug_i, j, k);
+
+ if (grid->debug_value) {
+ BKE_sim_debug_data_add_dot(wloc, 1, 0, 0, "grid", 93, debug_i, j, k);
+ BKE_sim_debug_data_add_dot(x2w, 0.1, 0.1, 0.7, "grid", 649, debug_i, j, k);
+ BKE_sim_debug_data_add_line(wloc, x2w, 0.3, 0.8, 0.3, "grid", 253, debug_i, j, k);
+ BKE_sim_debug_data_add_line(wloc, x3w, 0.8, 0.3, 0.3, "grid", 254, debug_i, j, k);
+// BKE_sim_debug_data_add_circle(x2w, len_v3v3(wloc, x2w), 0.2, 0.7, 0.2, "grid", 255, i, j, k);
+ }
+ }
+#endif
+ }
+ }
+}
+
+/* Uses a variation of Bresenham's algorithm for rasterizing a 3D grid with a line segment.
+ *
+ * The radius of influence around a segment is assumed to be at most 2*cellsize,
+ * i.e. only cells containing the segment and their direct neighbors are examined.
+ *
+ *
+ */
+void BPH_hair_volume_add_segment(HairGrid *grid,
+ const float x1[3], const float v1[3], const float x2[3], const float v2[3],
+ const float x3[3], const float v3[3], const float x4[3], const float v4[3],
+ const float dir1[3], const float dir2[3], const float dir3[3])
+{
+ const int res[3] = { grid->res[0], grid->res[1], grid->res[2] };
+
+ /* find the primary direction from the major axis of the direction vector */
+ const int axis0 = major_axis_v3(dir2);
+ const int axis1 = (axis0 + 1) % 3;
+ const int axis2 = (axis0 + 2) % 3;
+
+ /* vertex buffer offset factors along cardinal axes */
+ const int strides[3] = { 1, res[0], res[0] * res[1] };
+ const int stride0 = strides[axis0];
+ const int stride1 = strides[axis1];
+ const int stride2 = strides[axis2];
+
+ /* increment of secondary directions per step in the primary direction
+ * note: we always go in the positive direction along axis0, so the sign can be inverted
+ */
+ const float inc1 = dir2[axis1] / dir2[axis0];
+ const float inc2 = dir2[axis2] / dir2[axis0];
+
+ /* start/end points, so increment along axis0 is always positive */
+ const float *start = x2[axis0] < x3[axis0] ? x2 : x3;
+ const float *end = x2[axis0] < x3[axis0] ? x3 : x2;
+ const float start0 = start[axis0], start1 = start[axis1], start2 = start[axis2];
+ const float end0 = end[axis0];
+
+ /* range along primary direction */
+ const int imin = max_ii(floor_int(start[axis0]) - 1, 0);
+ const int imax = min_ii(floor_int(end[axis0]) + 2, res[axis0]-1);
+
+ float h = 0.0f;
+ HairGridVert *vert0;
+ float loc0[3];
+ int j0, k0, j0_prev, k0_prev;
+ int i;
+
+ for (i = imin; i <= imax; ++i) {
+ float shift1, shift2; /* fraction of a full cell shift [0.0, 1.0) */
+ int jmin, jmax, kmin, kmax;
+
+ h = CLAMPIS((float)i, start0, end0);
+
+ shift1 = start1 + (h - start0) * inc1;
+ shift2 = start2 + (h - start0) * inc2;
+
+ j0_prev = j0;
+ j0 = floor_int(shift1);
+
+ k0_prev = k0;
+ k0 = floor_int(shift2);
+
+ if (i > imin) {
+ jmin = min_ii(j0, j0_prev);
+ jmax = max_ii(j0, j0_prev);
+ kmin = min_ii(k0, k0_prev);
+ kmax = max_ii(k0, k0_prev);
+ }
+ else {
+ jmin = jmax = j0;
+ kmin = kmax = k0;
+ }
+
+ vert0 = grid->verts + i * stride0;
+ loc0[axis0] = (float)i;
+ loc0[axis1] = 0.0f;
+ loc0[axis2] = 0.0f;
+
+ hair_volume_add_segment_2D(grid, x1, v1, x2, v2, x3, v3, x4, v4, dir1, dir2, dir3,
+ res[axis1], res[axis2], jmin-1, jmax+2, kmin-1, kmax+2,
+ vert0, stride1, stride2, loc0, axis1, axis2,
+ i);
+ }
+}
+#else
+BLI_INLINE void hair_volume_eval_grid_vertex_sample(HairGridVert *vert, const float loc[3], float radius, float dist_scale,
+ const float x[3], const float v[3])
+{
+ float dist, weight;
+
+ dist = len_v3v3(x, loc);
+
+ weight = (radius - dist) * dist_scale;
+
+ if (weight > 0.0f) {
+ madd_v3_v3fl(vert->velocity, v, weight);
+ vert->density += weight;
+ vert->samples += 1;
+ }
+}
+
+/* XXX simplified test implementation using a series of discrete sample along the segment,
+ * instead of finding the closest point for all affected grid vertices.
+ */
+void BPH_hair_volume_add_segment(HairGrid *grid,
+ const float UNUSED(x1[3]), const float UNUSED(v1[3]), const float x2[3], const float v2[3],
+ const float x3[3], const float v3[3], const float UNUSED(x4[3]), const float UNUSED(v4[3]),
+ const float UNUSED(dir1[3]), const float UNUSED(dir2[3]), const float UNUSED(dir3[3]))
+{
+ const float radius = 1.5f;
+ const float dist_scale = grid->inv_cellsize;
+
+ const int res[3] = { grid->res[0], grid->res[1], grid->res[2] };
+ const int stride[3] = { 1, res[0], res[0] * res[1] };
+ const int num_samples = 10;
+
+ int s;
+
+ for (s = 0; s < num_samples; ++s) {
+ float x[3], v[3];
+ int i, j, k;
+
+ float f = (float)s / (float)(num_samples-1);
+ interp_v3_v3v3(x, x2, x3, f);
+ interp_v3_v3v3(v, v2, v3, f);
+
+ int imin = max_ii(floor_int(x[0]) - 2, 0);
+ int imax = min_ii(floor_int(x[0]) + 2, res[0]-1);
+ int jmin = max_ii(floor_int(x[1]) - 2, 0);
+ int jmax = min_ii(floor_int(x[1]) + 2, res[1]-1);
+ int kmin = max_ii(floor_int(x[2]) - 2, 0);
+ int kmax = min_ii(floor_int(x[2]) + 2, res[2]-1);
+
+ for (k = kmin; k <= kmax; ++k) {
+ for (j = jmin; j <= jmax; ++j) {
+ for (i = imin; i <= imax; ++i) {
+ float loc[3] = { (float)i, (float)j, (float)k };
+ HairGridVert *vert = grid->verts + i * stride[0] + j * stride[1] + k * stride[2];
+
+ hair_volume_eval_grid_vertex_sample(vert, loc, radius, dist_scale, x, v);
+ }
+ }
+ }
+ }
+}
+#endif
+
+void BPH_hair_volume_normalize_vertex_grid(HairGrid *grid)
+{
+ int i, size = hair_grid_size(grid->res);
+ /* divide velocity with density */
+ for (i = 0; i < size; i++) {
+ float density = grid->verts[i].density;
+ if (density > 0.0f)
+ mul_v3_fl(grid->verts[i].velocity, 1.0f/density);
+ }
+}
+
+static const float density_threshold = 0.001f; /* cells with density below this are considered empty */
+
+/* Contribution of target density pressure to the laplacian in the pressure poisson equation.
+ * This is based on the model found in
+ * "Two-way Coupled SPH and Particle Level Set Fluid Simulation" (Losasso et al., 2008)
+ */
+BLI_INLINE float hair_volume_density_divergence(float density, float target_density, float strength)
+{
+ if (density > density_threshold && density > target_density)
+ return strength * logf(target_density / density);
+ else
+ return 0.0f;
+}
+
+bool BPH_hair_volume_solve_divergence(HairGrid *grid, float dt, float target_density, float target_strength)
+{
+ const float flowfac = grid->cellsize;
+ const float inv_flowfac = 1.0f / grid->cellsize;
+
+ /*const int num_cells = hair_grid_size(grid->res);*/
+ const int res[3] = { grid->res[0], grid->res[1], grid->res[2] };
+ const int resA[3] = { grid->res[0] + 2, grid->res[1] + 2, grid->res[2] + 2 };
+
+ const int stride0 = 1;
+ const int stride1 = grid->res[0];
+ const int stride2 = grid->res[1] * grid->res[0];
+ const int strideA0 = 1;
+ const int strideA1 = grid->res[0] + 2;
+ const int strideA2 = (grid->res[1] + 2) * (grid->res[0] + 2);
+
+ const int num_cells = res[0] * res[1] * res[2];
+ const int num_cellsA = (res[0] + 2) * (res[1] + 2) * (res[2] + 2);
+
+ HairGridVert *vert_start = grid->verts - (stride0 + stride1 + stride2);
+ HairGridVert *vert;
+ int i, j, k;
+
+#define MARGIN_i0 (i < 1)
+#define MARGIN_j0 (j < 1)
+#define MARGIN_k0 (k < 1)
+#define MARGIN_i1 (i >= resA[0]-1)
+#define MARGIN_j1 (j >= resA[1]-1)
+#define MARGIN_k1 (k >= resA[2]-1)
+
+#define NEIGHBOR_MARGIN_i0 (i < 2)
+#define NEIGHBOR_MARGIN_j0 (j < 2)
+#define NEIGHBOR_MARGIN_k0 (k < 2)
+#define NEIGHBOR_MARGIN_i1 (i >= resA[0]-2)
+#define NEIGHBOR_MARGIN_j1 (j >= resA[1]-2)
+#define NEIGHBOR_MARGIN_k1 (k >= resA[2]-2)
+
+ BLI_assert(num_cells >= 1);
+
+ /* Calculate divergence */
+ lVector B(num_cellsA);
+ for (k = 0; k < resA[2]; ++k) {
+ for (j = 0; j < resA[1]; ++j) {
+ for (i = 0; i < resA[0]; ++i) {
+ int u = i * strideA0 + j * strideA1 + k * strideA2;
+ bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1;
+
+ if (is_margin) {
+ B[u] = 0.0f;
+ continue;
+ }
+
+ vert = vert_start + i * stride0 + j * stride1 + k * stride2;
+
+ const float *v0 = vert->velocity;
+ float dx = 0.0f, dy = 0.0f, dz = 0.0f;
+ if (!NEIGHBOR_MARGIN_i0)
+ dx += v0[0] - (vert - stride0)->velocity[0];
+ if (!NEIGHBOR_MARGIN_i1)
+ dx += (vert + stride0)->velocity[0] - v0[0];
+ if (!NEIGHBOR_MARGIN_j0)
+ dy += v0[1] - (vert - stride1)->velocity[1];
+ if (!NEIGHBOR_MARGIN_j1)
+ dy += (vert + stride1)->velocity[1] - v0[1];
+ if (!NEIGHBOR_MARGIN_k0)
+ dz += v0[2] - (vert - stride2)->velocity[2];
+ if (!NEIGHBOR_MARGIN_k1)
+ dz += (vert + stride2)->velocity[2] - v0[2];
+
+ float divergence = -0.5f * flowfac * (dx + dy + dz);
+
+ /* adjustment term for target density */
+ float target = hair_volume_density_divergence(vert->density, target_density, target_strength);
+
+ /* B vector contains the finite difference approximation of the velocity divergence.
+ * Note: according to the discretized Navier-Stokes equation the rhs vector
+ * and resulting pressure gradient should be multiplied by the (inverse) density;
+ * however, this is already included in the weighting of hair velocities on the grid!
+ */
+ B[u] = divergence - target;
+
+#if 0
+ {
+ float wloc[3], loc[3];
+ float col0[3] = {0.0, 0.0, 0.0};
+ float colp[3] = {0.0, 1.0, 1.0};
+ float coln[3] = {1.0, 0.0, 1.0};
+ float col[3];
+ float fac;
+
+ loc[0] = (float)(i - 1);
+ loc[1] = (float)(j - 1);
+ loc[2] = (float)(k - 1);
+ grid_to_world(grid, wloc, loc);
+
+ if (divergence > 0.0f) {
+ fac = CLAMPIS(divergence * target_strength, 0.0, 1.0);
+ interp_v3_v3v3(col, col0, colp, fac);
+ }
+ else {
+ fac = CLAMPIS(-divergence * target_strength, 0.0, 1.0);
+ interp_v3_v3v3(col, col0, coln, fac);
+ }
+ if (fac > 0.05f)
+ BKE_sim_debug_data_add_circle(grid->debug_data, wloc, 0.01f, col[0], col[1], col[2], "grid", 5522, i, j, k);
+ }
+#endif
+ }
+ }
+ }
+
+ /* Main Poisson equation system:
+ * This is derived from the discretezation of the Poisson equation
+ * div(grad(p)) = div(v)
+ *
+ * The finite difference approximation yields the linear equation system described here:
+ * http://en.wikipedia.org/wiki/Discrete_Poisson_equation
+ */
+ lMatrix A(num_cellsA, num_cellsA);
+ /* Reserve space for the base equation system (without boundary conditions).
+ * Each column contains a factor 6 on the diagonal
+ * and up to 6 factors -1 on other places.
+ */
+ A.reserve(Eigen::VectorXi::Constant(num_cellsA, 7));
+
+ for (k = 0; k < resA[2]; ++k) {
+ for (j = 0; j < resA[1]; ++j) {
+ for (i = 0; i < resA[0]; ++i) {
+ int u = i * strideA0 + j * strideA1 + k * strideA2;
+ bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1;
+
+ vert = vert_start + i * stride0 + j * stride1 + k * stride2;
+ if (!is_margin && vert->density > density_threshold) {
+ int neighbors_lo = 0;
+ int neighbors_hi = 0;
+ int non_solid_neighbors = 0;
+ int neighbor_lo_index[3];
+ int neighbor_hi_index[3];
+ int n;
+
+ /* check for upper bounds in advance
+ * to get the correct number of neighbors,
+ * needed for the diagonal element
+ */
+ if (!NEIGHBOR_MARGIN_k0 && (vert - stride2)->density > density_threshold)
+ neighbor_lo_index[neighbors_lo++] = u - strideA2;
+ if (!NEIGHBOR_MARGIN_j0 && (vert - stride1)->density > density_threshold)
+ neighbor_lo_index[neighbors_lo++] = u - strideA1;
+ if (!NEIGHBOR_MARGIN_i0 && (vert - stride0)->density > density_threshold)
+ neighbor_lo_index[neighbors_lo++] = u - strideA0;
+ if (!NEIGHBOR_MARGIN_i1 && (vert + stride0)->density > density_threshold)
+ neighbor_hi_index[neighbors_hi++] = u + strideA0;
+ if (!NEIGHBOR_MARGIN_j1 && (vert + stride1)->density > density_threshold)
+ neighbor_hi_index[neighbors_hi++] = u + strideA1;
+ if (!NEIGHBOR_MARGIN_k1 && (vert + stride2)->density > density_threshold)
+ neighbor_hi_index[neighbors_hi++] = u + strideA2;
+
+ /*int liquid_neighbors = neighbors_lo + neighbors_hi;*/
+ non_solid_neighbors = 6;
+
+ for (n = 0; n < neighbors_lo; ++n)
+ A.insert(neighbor_lo_index[n], u) = -1.0f;
+ A.insert(u, u) = (float)non_solid_neighbors;
+ for (n = 0; n < neighbors_hi; ++n)
+ A.insert(neighbor_hi_index[n], u) = -1.0f;
+ }
+ else {
+ A.insert(u, u) = 1.0f;
+ }
+ }
+ }
+ }
+
+ ConjugateGradient cg;
+ cg.setMaxIterations(100);
+ cg.setTolerance(0.01f);
+
+ cg.compute(A);
+
+ lVector p = cg.solve(B);
+
+ if (cg.info() == Eigen::Success) {
+ /* Calculate velocity = grad(p) */
+ for (k = 0; k < resA[2]; ++k) {
+ for (j = 0; j < resA[1]; ++j) {
+ for (i = 0; i < resA[0]; ++i) {
+ int u = i * strideA0 + j * strideA1 + k * strideA2;
+ bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1;
+ if (is_margin)
+ continue;
+
+ vert = vert_start + i * stride0 + j * stride1 + k * stride2;
+ if (vert->density > density_threshold) {
+ float p_left = p[u - strideA0];
+ float p_right = p[u + strideA0];
+ float p_down = p[u - strideA1];
+ float p_up = p[u + strideA1];
+ float p_bottom = p[u - strideA2];
+ float p_top = p[u + strideA2];
+
+ /* finite difference estimate of pressure gradient */
+ float dvel[3];
+ dvel[0] = p_right - p_left;
+ dvel[1] = p_up - p_down;
+ dvel[2] = p_top - p_bottom;
+ mul_v3_fl(dvel, -0.5f * inv_flowfac);
+
+ /* pressure gradient describes velocity delta */
+ add_v3_v3v3(vert->velocity_smooth, vert->velocity, dvel);
+ }
+ else {
+ zero_v3(vert->velocity_smooth);
+ }
+ }
+ }
+ }
+
+#if 0
+ {
+ int axis = 0;
+ float offset = 0.0f;
+
+ int slice = (offset - grid->gmin[axis]) / grid->cellsize;
+
+ for (k = 0; k < resA[2]; ++k) {
+ for (j = 0; j < resA[1]; ++j) {
+ for (i = 0; i < resA[0]; ++i) {
+ int u = i * strideA0 + j * strideA1 + k * strideA2;
+ bool is_margin = MARGIN_i0 || MARGIN_i1 || MARGIN_j0 || MARGIN_j1 || MARGIN_k0 || MARGIN_k1;
+ if (i != slice)
+ continue;
+
+ vert = vert_start + i * stride0 + j * stride1 + k * stride2;
+
+ float wloc[3], loc[3];
+ float col0[3] = {0.0, 0.0, 0.0};
+ float colp[3] = {0.0, 1.0, 1.0};
+ float coln[3] = {1.0, 0.0, 1.0};
+ float col[3];
+ float fac;
+
+ loc[0] = (float)(i - 1);
+ loc[1] = (float)(j - 1);
+ loc[2] = (float)(k - 1);
+ grid_to_world(grid, wloc, loc);
+
+ float pressure = p[u];
+ if (pressure > 0.0f) {
+ fac = CLAMPIS(pressure * grid->debug1, 0.0, 1.0);
+ interp_v3_v3v3(col, col0, colp, fac);
+ }
+ else {
+ fac = CLAMPIS(-pressure * grid->debug1, 0.0, 1.0);
+ interp_v3_v3v3(col, col0, coln, fac);
+ }
+ if (fac > 0.05f)
+ BKE_sim_debug_data_add_circle(grid->debug_data, wloc, 0.01f, col[0], col[1], col[2], "grid", 5533, i, j, k);
+
+ if (!is_margin) {
+ float dvel[3];
+ sub_v3_v3v3(dvel, vert->velocity_smooth, vert->velocity);
+// BKE_sim_debug_data_add_vector(grid->debug_data, wloc, dvel, 1, 1, 1, "grid", 5566, i, j, k);
+ }
+
+ if (!is_margin) {
+ float d = CLAMPIS(vert->density * grid->debug2, 0.0f, 1.0f);
+ float col0[3] = {0.3, 0.3, 0.3};
+ float colp[3] = {0.0, 0.0, 1.0};
+ float col[3];
+
+ interp_v3_v3v3(col, col0, colp, d);
+// if (d > 0.05f)
+// BKE_sim_debug_data_add_dot(grid->debug_data, wloc, col[0], col[1], col[2], "grid", 5544, i, j, k);
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ return true;
+ }
+ else {
+ /* Clear result in case of error */
+ for (i = 0, vert = grid->verts; i < num_cells; ++i, ++vert) {
+ zero_v3(vert->velocity_smooth);
+ }
+
+ return false;
+ }
+}
+
+#if 0 /* XXX weighting is incorrect, disabled for now */
+/* Velocity filter kernel
+ * See http://en.wikipedia.org/wiki/Filter_%28large_eddy_simulation%29
+ */
+
+BLI_INLINE void hair_volume_filter_box_convolute(HairVertexGrid *grid, float invD, const int kernel_size[3], int i, int j, int k)
+{
+ int res = grid->res;
+ int p, q, r;
+ int minp = max_ii(i - kernel_size[0], 0), maxp = min_ii(i + kernel_size[0], res-1);
+ int minq = max_ii(j - kernel_size[1], 0), maxq = min_ii(j + kernel_size[1], res-1);
+ int minr = max_ii(k - kernel_size[2], 0), maxr = min_ii(k + kernel_size[2], res-1);
+ int offset, kernel_offset, kernel_dq, kernel_dr;
+ HairGridVert *verts;
+ float *vel_smooth;
+
+ offset = i + (j + k*res)*res;
+ verts = grid->verts;
+ vel_smooth = verts[offset].velocity_smooth;
+
+ kernel_offset = minp + (minq + minr*res)*res;
+ kernel_dq = res;
+ kernel_dr = res * res;
+ for (r = minr; r <= maxr; ++r) {
+ for (q = minq; q <= maxq; ++q) {
+ for (p = minp; p <= maxp; ++p) {
+
+ madd_v3_v3fl(vel_smooth, verts[kernel_offset].velocity, invD);
+
+ kernel_offset += 1;
+ }
+ kernel_offset += kernel_dq;
+ }
+ kernel_offset += kernel_dr;
+ }
+}
+
+void BPH_hair_volume_vertex_grid_filter_box(HairVertexGrid *grid, int kernel_size)
+{
+ int size = hair_grid_size(grid->res);
+ int kernel_sizev[3] = {kernel_size, kernel_size, kernel_size};
+ int tot;
+ float invD;
+ int i, j, k;
+
+ if (kernel_size <= 0)
+ return;
+
+ tot = kernel_size * 2 + 1;
+ invD = 1.0f / (float)(tot*tot*tot);
+
+ /* clear values for convolution */
+ for (i = 0; i < size; ++i) {
+ zero_v3(grid->verts[i].velocity_smooth);
+ }
+
+ for (i = 0; i < grid->res; ++i) {
+ for (j = 0; j < grid->res; ++j) {
+ for (k = 0; k < grid->res; ++k) {
+ hair_volume_filter_box_convolute(grid, invD, kernel_sizev, i, j, k);
+ }
+ }
+ }
+
+ /* apply as new velocity */
+ for (i = 0; i < size; ++i) {
+ copy_v3_v3(grid->verts[i].velocity, grid->verts[i].velocity_smooth);
+ }
+}
+#endif
+
+HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize, const float gmin[3], const float gmax[3])
+{
+ float scale;
+ float extent[3];
+ int resmin[3], resmax[3], res[3];
+ float gmin_margin[3], gmax_margin[3];
+ int size;
+ HairGrid *grid;
+ int i;
+
+ /* sanity check */
+ if (cellsize <= 0.0f)
+ cellsize = 1.0f;
+ scale = 1.0f / cellsize;
+
+ sub_v3_v3v3(extent, gmax, gmin);
+ for (i = 0; i < 3; ++i) {
+ resmin[i] = floor_int(gmin[i] * scale);
+ resmax[i] = floor_int(gmax[i] * scale) + 1;
+
+ /* add margin of 1 cell */
+ resmin[i] -= 1;
+ resmax[i] += 1;
+
+ res[i] = resmax[i] - resmin[i] + 1;
+ /* sanity check: avoid null-sized grid */
+ if (res[i] < 4) {
+ res[i] = 4;
+ resmax[i] = resmin[i] + 4;
+ }
+ /* sanity check: avoid too large grid size */
+ if (res[i] > MAX_HAIR_GRID_RES) {
+ res[i] = MAX_HAIR_GRID_RES;
+ resmax[i] = resmin[i] + MAX_HAIR_GRID_RES;
+ }
+
+ gmin_margin[i] = (float)resmin[i] * cellsize;
+ gmax_margin[i] = (float)resmax[i] * cellsize;
+ }
+ size = hair_grid_size(res);
+
+ grid = (HairGrid *)MEM_callocN(sizeof(HairGrid), "hair grid");
+ grid->res[0] = res[0];
+ grid->res[1] = res[1];
+ grid->res[2] = res[2];
+ copy_v3_v3(grid->gmin, gmin_margin);
+ copy_v3_v3(grid->gmax, gmax_margin);
+ grid->cellsize = cellsize;
+ grid->inv_cellsize = scale;
+ grid->verts = (HairGridVert *)MEM_callocN(sizeof(HairGridVert) * size, "hair voxel data");
+
+ return grid;
+}
+
+void BPH_hair_volume_free_vertex_grid(HairGrid *grid)
+{
+ if (grid) {
+ if (grid->verts)
+ MEM_freeN(grid->verts);
+ MEM_freeN(grid);
+ }
+}
+
+void BPH_hair_volume_grid_geometry(HairGrid *grid, float *cellsize, int res[3], float gmin[3], float gmax[3])
+{
+ if (cellsize) *cellsize = grid->cellsize;
+ if (res) copy_v3_v3_int(res, grid->res);
+ if (gmin) copy_v3_v3(gmin, grid->gmin);
+ if (gmax) copy_v3_v3(gmax, grid->gmax);
+}
+
+#if 0
+static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd, lfVector *lX, unsigned int numverts)
+{
+ int res = hair_grid_res;
+ int size = hair_grid_size(res);
+ HairGridVert *collgrid;
+ ListBase *colliders;
+ ColliderCache *col = NULL;
+ float gmin[3], gmax[3], scale[3];
+ /* 2.0f is an experimental value that seems to give good results */
+ float collfac = 2.0f * clmd->sim_parms->collider_friction;
+ unsigned int v = 0;
+ int i = 0;
+
+ hair_volume_get_boundbox(lX, numverts, gmin, gmax);
+ hair_grid_get_scale(res, gmin, gmax, scale);
+
+ collgrid = MEM_mallocN(sizeof(HairGridVert) * size, "hair collider voxel data");
+
+ /* initialize grid */
+ for (i = 0; i < size; ++i) {
+ zero_v3(collgrid[i].velocity);
+ collgrid[i].density = 0.0f;
+ }
+
+ /* gather colliders */
+ colliders = get_collider_cache(clmd->scene, NULL, NULL);
+ if (colliders && collfac > 0.0f) {
+ for (col = colliders->first; col; col = col->next) {
+ MVert *loc0 = col->collmd->x;
+ MVert *loc1 = col->collmd->xnew;
+ float vel[3];
+ float weights[8];
+ int di, dj, dk;
+
+ for (v=0; v < col->collmd->numverts; v++, loc0++, loc1++) {
+ int offset;
+
+ if (!hair_grid_point_valid(loc1->co, gmin, gmax))
+ continue;
+
+ offset = hair_grid_weights(res, gmin, scale, lX[v], weights);
+
+ sub_v3_v3v3(vel, loc1->co, loc0->co);
+
+ for (di = 0; di < 2; ++di) {
+ for (dj = 0; dj < 2; ++dj) {
+ for (dk = 0; dk < 2; ++dk) {
+ int voffset = offset + di + (dj + dk*res)*res;
+ int iw = di + dj*2 + dk*4;
+
+ collgrid[voffset].density += weights[iw];
+ madd_v3_v3fl(collgrid[voffset].velocity, vel, weights[iw]);
+ }
+ }
+ }
+ }
+ }
+ }
+ free_collider_cache(&colliders);
+
+ /* divide velocity with density */
+ for (i = 0; i < size; i++) {
+ float density = collgrid[i].density;
+ if (density > 0.0f)
+ mul_v3_fl(collgrid[i].velocity, 1.0f/density);
+ }
+
+ return collgrid;
+}
+#endif
+
+bool BPH_hair_volume_get_texture_data(HairGrid *grid, VoxelData *vd)
+{
+ int totres, i;
+ int depth;
+
+ vd->resol[0] = grid->res[0];
+ vd->resol[1] = grid->res[1];
+ vd->resol[2] = grid->res[2];
+
+ totres = hair_grid_size(grid->res);
+
+ if (vd->hair_type == TEX_VD_HAIRVELOCITY) {
+ depth = 4;
+ vd->data_type = TEX_VD_RGBA_PREMUL;
+ }
+ else {
+ depth = 1;
+ vd->data_type = TEX_VD_INTENSITY;
+ }
+
+ if (totres > 0) {
+ vd->dataset = (float *)MEM_mapallocN(sizeof(float) * depth * (totres), "hair volume texture data");
+
+ for (i = 0; i < totres; ++i) {
+ switch (vd->hair_type) {
+ case TEX_VD_HAIRDENSITY:
+ vd->dataset[i] = grid->verts[i].density;
+ break;
+
+ case TEX_VD_HAIRRESTDENSITY:
+ vd->dataset[i] = 0.0f; // TODO
+ break;
+
+ case TEX_VD_HAIRVELOCITY: {
+ vd->dataset[i + 0*totres] = grid->verts[i].velocity[0];
+ vd->dataset[i + 1*totres] = grid->verts[i].velocity[1];
+ vd->dataset[i + 2*totres] = grid->verts[i].velocity[2];
+ vd->dataset[i + 3*totres] = len_v3(grid->verts[i].velocity);
+ break;
+ }
+ case TEX_VD_HAIRENERGY:
+ vd->dataset[i] = 0.0f; // TODO
+ break;
+ }
+ }
+ }
+ else {
+ vd->dataset = NULL;
+ }
+
+ return true;
+}
diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h
new file mode 100644
index 00000000000..d286d3df1a5
--- /dev/null
+++ b/source/blender/physics/intern/implicit.h
@@ -0,0 +1,186 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __IMPLICIT_H__
+#define __IMPLICIT_H__
+
+/** \file implicit.h
+ * \ingroup bph
+ */
+
+#include "stdio.h"
+
+#include "BLI_utildefines.h"
+
+#include "BKE_collision.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define IMPLICIT_SOLVER_EIGEN
+#define IMPLICIT_SOLVER_BLENDER
+
+#define CLOTH_ROOT_FRAME /* enable use of root frame coordinate transform */
+
+#define CLOTH_FORCE_GRAVITY
+#define CLOTH_FORCE_DRAG
+#define CLOTH_FORCE_SPRING_STRUCTURAL
+#define CLOTH_FORCE_SPRING_BEND
+#define CLOTH_FORCE_SPRING_GOAL
+#define CLOTH_FORCE_EFFECTORS
+
+//#define IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
+
+//#define IMPLICIT_ENABLE_EIGEN_DEBUG
+
+struct Implicit_Data;
+struct ImplicitSolverInput;
+
+typedef struct ImplicitSolverResult {
+ int status;
+
+ int iterations;
+ float error;
+} ImplicitSolverResult;
+
+BLI_INLINE void implicit_print_matrix_elem(float v)
+{
+ printf("%-8.3f", v);
+}
+
+void BPH_mass_spring_set_vertex_mass(struct Implicit_Data *data, int index, float mass);
+void BPH_mass_spring_set_rest_transform(struct Implicit_Data *data, int index, float rot[3][3]);
+
+void BPH_mass_spring_set_motion_state(struct Implicit_Data *data, int index, const float x[3], const float v[3]);
+void BPH_mass_spring_set_position(struct Implicit_Data *data, int index, const float x[3]);
+void BPH_mass_spring_set_velocity(struct Implicit_Data *data, int index, const float v[3]);
+void BPH_mass_spring_get_motion_state(struct Implicit_Data *data, int index, float x[3], float v[3]);
+void BPH_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3]);
+
+/* access to modified motion state during solver step */
+void BPH_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3]);
+void BPH_mass_spring_set_new_position(struct Implicit_Data *data, int index, const float x[3]);
+void BPH_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3]);
+void BPH_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3]);
+
+void BPH_mass_spring_clear_constraints(struct Implicit_Data *data);
+void BPH_mass_spring_add_constraint_ndof0(struct Implicit_Data *data, int index, const float dV[3]);
+void BPH_mass_spring_add_constraint_ndof1(struct Implicit_Data *data, int index, const float c1[3], const float c2[3], const float dV[3]);
+void BPH_mass_spring_add_constraint_ndof2(struct Implicit_Data *data, int index, const float c1[3], const float dV[3]);
+
+bool BPH_mass_spring_solve_velocities(struct Implicit_Data *data, float dt, struct ImplicitSolverResult *result);
+bool BPH_mass_spring_solve_positions(struct Implicit_Data *data, float dt);
+void BPH_mass_spring_apply_result(struct Implicit_Data *data);
+
+/* Clear the force vector at the beginning of the time step */
+void BPH_mass_spring_clear_forces(struct Implicit_Data *data);
+/* Fictitious forces introduced by moving coordinate systems */
+void BPH_mass_spring_force_reference_frame(struct Implicit_Data *data, int index, const float acceleration[3], const float omega[3], const float domega_dt[3], float mass);
+/* Simple uniform gravity force */
+void BPH_mass_spring_force_gravity(struct Implicit_Data *data, int index, float mass, const float g[3]);
+/* Global drag force (velocity damping) */
+void BPH_mass_spring_force_drag(struct Implicit_Data *data, float drag);
+/* Custom external force */
+void BPH_mass_spring_force_extern(struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3]);
+/* Wind force, acting on a face */
+void BPH_mass_spring_force_face_wind(struct Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3]);
+/* Wind force, acting on an edge */
+void BPH_mass_spring_force_edge_wind(struct Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float (*winvec)[3]);
+/* Wind force, acting on a vertex */
+void BPH_mass_spring_force_vertex_wind(struct Implicit_Data *data, int v, float radius, const float (*winvec)[3]);
+/* Linear spring force between two points */
+bool BPH_mass_spring_force_spring_linear(struct Implicit_Data *data, int i, int j, float restlen,
+ float stiffness, float damping, bool no_compress, float clamp_force,
+ float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3]);
+/* Bending force, forming a triangle at the base of two structural springs */
+bool BPH_mass_spring_force_spring_bending(struct Implicit_Data *data, int i, int j, float restlen,
+ float kb, float cb,
+ float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3]);
+/* Angular bending force based on local target vectors */
+bool BPH_mass_spring_force_spring_bending_angular(struct Implicit_Data *data, int i, int j, int k,
+ const float target[3], float stiffness, float damping);
+/* Global goal spring */
+bool BPH_mass_spring_force_spring_goal(struct Implicit_Data *data, int i, const float goal_x[3], const float goal_v[3],
+ float stiffness, float damping,
+ float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3]);
+
+/* ======== Hair Volumetric Forces ======== */
+
+struct HairGrid;
+
+struct Object;
+struct VoxelData;
+
+#define MAX_HAIR_GRID_RES 256
+
+struct HairGrid *BPH_hair_volume_create_vertex_grid(float cellsize, const float gmin[3], const float gmax[3]);
+void BPH_hair_volume_free_vertex_grid(struct HairGrid *grid);
+void BPH_hair_volume_grid_geometry(struct HairGrid *grid, float *cellsize, int res[3], float gmin[3], float gmax[3]);
+
+void BPH_hair_volume_grid_clear(struct HairGrid *grid);
+void BPH_hair_volume_add_vertex(struct HairGrid *grid, const float x[3], const float v[3]);
+void BPH_hair_volume_add_segment(struct HairGrid *grid,
+ const float x1[3], const float v1[3], const float x2[3], const float v2[3],
+ const float x3[3], const float v3[3], const float x4[3], const float v4[3],
+ const float dir1[3], const float dir2[3], const float dir3[3]);
+
+void BPH_hair_volume_normalize_vertex_grid(struct HairGrid *grid);
+
+bool BPH_hair_volume_solve_divergence(struct HairGrid *grid, float dt, float target_density, float target_strength);
+#if 0 /* XXX weighting is incorrect, disabled for now */
+void BPH_hair_volume_vertex_grid_filter_box(struct HairVertexGrid *grid, int kernel_size);
+#endif
+
+void BPH_hair_volume_grid_interpolate(struct HairGrid *grid, const float x[3],
+ float *density, float velocity[3], float velocity_smooth[3],
+ float density_gradient[3], float velocity_gradient[3][3]);
+
+/* Effect of fluid simulation grid on velocities.
+ * fluid_factor controls blending between PIC (Particle-in-Cell)
+ * and FLIP (Fluid-Implicit-Particle) methods (0 = only PIC, 1 = only FLIP)
+ */
+void BPH_hair_volume_grid_velocity(struct HairGrid *grid, const float x[3], const float v[3],
+ float fluid_factor,
+ float r_v[3]);
+/* XXX Warning: expressing grid effects on velocity as a force is not very stable,
+ * due to discontinuities in interpolated values!
+ * Better use hybrid approaches such as described in
+ * "Detail Preserving Continuum Simulation of Straight Hair"
+ * (McAdams, Selle 2009)
+ */
+void BPH_hair_volume_vertex_grid_forces(struct HairGrid *grid, const float x[3], const float v[3],
+ float smoothfac, float pressurefac, float minpressure,
+ float f[3], float dfdx[3][3], float dfdv[3][3]);
+
+bool BPH_hair_volume_get_texture_data(struct HairGrid *grid, struct VoxelData *vd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c
new file mode 100644
index 00000000000..5b1d83a3eef
--- /dev/null
+++ b/source/blender/physics/intern/implicit_blender.c
@@ -0,0 +1,2041 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/physics/intern/implicit_blender.c
+ * \ingroup bph
+ */
+
+#include "implicit.h"
+
+#ifdef IMPLICIT_SOLVER_BLENDER
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_texture_types.h"
+
+#include "BLI_math.h"
+#include "BLI_linklist.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_cloth.h"
+#include "BKE_collision.h"
+#include "BKE_effect.h"
+#include "BKE_global.h"
+
+#include "BPH_mass_spring.h"
+
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wtype-limits"
+#endif
+
+#ifdef _OPENMP
+# define CLOTH_OPENMP_LIMIT 512
+#endif
+
+#if 0 /* debug timing */
+#ifdef _WIN32
+#include <windows.h>
+static LARGE_INTEGER _itstart, _itend;
+static LARGE_INTEGER ifreq;
+static void itstart(void)
+{
+ static int first = 1;
+ if (first) {
+ QueryPerformanceFrequency(&ifreq);
+ first = 0;
+ }
+ QueryPerformanceCounter(&_itstart);
+}
+static void itend(void)
+{
+ QueryPerformanceCounter(&_itend);
+}
+double itval(void)
+{
+ return ((double)_itend.QuadPart -
+ (double)_itstart.QuadPart)/((double)ifreq.QuadPart);
+}
+#else
+#include <sys/time.h>
+// intrinsics need better compile flag checking
+// #include <xmmintrin.h>
+// #include <pmmintrin.h>
+// #include <pthread.h>
+
+static struct timeval _itstart, _itend;
+static struct timezone itz;
+static void itstart(void)
+{
+ gettimeofday(&_itstart, &itz);
+}
+static void itend(void)
+{
+ gettimeofday(&_itend, &itz);
+}
+static double itval(void)
+{
+ double t1, t2;
+ t1 = (double)_itstart.tv_sec + (double)_itstart.tv_usec/(1000*1000);
+ t2 = (double)_itend.tv_sec + (double)_itend.tv_usec/(1000*1000);
+ return t2-t1;
+}
+#endif
+#endif /* debug timing */
+
+static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
+static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
+
+/*
+#define C99
+#ifdef C99
+#defineDO_INLINE inline
+#else
+#defineDO_INLINE static
+#endif
+*/
+struct Cloth;
+
+//////////////////////////////////////////
+/* fast vector / matrix library, enhancements are welcome :) -dg */
+/////////////////////////////////////////
+
+/* DEFINITIONS */
+typedef float lfVector[3];
+typedef struct fmatrix3x3 {
+ float m[3][3]; /* 3x3 matrix */
+ unsigned int c, r; /* column and row number */
+ /* int pinned; // is this vertex allowed to move? */
+ float n1, n2, n3; /* three normal vectors for collision constrains */
+ unsigned int vcount; /* vertex count */
+ unsigned int scount; /* spring count */
+} fmatrix3x3;
+
+///////////////////////////
+// float[3] vector
+///////////////////////////
+/* simple vector code */
+/* STATUS: verified */
+DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar)
+{
+ to[0] = from[0] * scalar;
+ to[1] = from[1] * scalar;
+ to[2] = from[2] * scalar;
+}
+/* simple v^T * v product ("outer product") */
+/* STATUS: HAS TO BE verified (*should* work) */
+DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3])
+{
+ mul_fvector_S(to[0], vectorB, vectorA[0]);
+ mul_fvector_S(to[1], vectorB, vectorA[1]);
+ mul_fvector_S(to[2], vectorB, vectorA[2]);
+}
+/* simple v^T * v product with scalar ("outer product") */
+/* STATUS: HAS TO BE verified (*should* work) */
+DO_INLINE void mul_fvectorT_fvectorS(float to[3][3], float vectorA[3], float vectorB[3], float aS)
+{
+ mul_fvectorT_fvector(to, vectorA, vectorB);
+
+ mul_fvector_S(to[0], to[0], aS);
+ mul_fvector_S(to[1], to[1], aS);
+ mul_fvector_S(to[2], to[2], aS);
+}
+
+#if 0
+/* printf vector[3] on console: for debug output */
+static void print_fvector(float m3[3])
+{
+ printf("%f\n%f\n%f\n\n", m3[0], m3[1], m3[2]);
+}
+
+///////////////////////////
+// long float vector float (*)[3]
+///////////////////////////
+/* print long vector on console: for debug output */
+DO_INLINE void print_lfvector(float (*fLongVector)[3], unsigned int verts)
+{
+ unsigned int i = 0;
+ for (i = 0; i < verts; i++) {
+ print_fvector(fLongVector[i]);
+ }
+}
+#endif
+
+/* create long vector */
+DO_INLINE lfVector *create_lfvector(unsigned int verts)
+{
+ /* TODO: check if memory allocation was successful */
+ return (lfVector *)MEM_callocN(verts * sizeof(lfVector), "cloth_implicit_alloc_vector");
+ // return (lfVector *)cloth_aligned_malloc(&MEMORY_BASE, verts * sizeof(lfVector));
+}
+/* delete long vector */
+DO_INLINE void del_lfvector(float (*fLongVector)[3])
+{
+ if (fLongVector != NULL) {
+ MEM_freeN(fLongVector);
+ // cloth_aligned_free(&MEMORY_BASE, fLongVector);
+ }
+}
+/* copy long vector */
+DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts)
+{
+ memcpy(to, from, verts * sizeof(lfVector));
+}
+/* init long vector with float[3] */
+DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts)
+{
+ unsigned int i = 0;
+ for (i = 0; i < verts; i++) {
+ copy_v3_v3(fLongVector[i], vector);
+ }
+}
+/* zero long vector with float[3] */
+DO_INLINE void zero_lfvector(float (*to)[3], unsigned int verts)
+{
+ memset(to, 0.0f, verts * sizeof(lfVector));
+}
+/* multiply long vector with scalar*/
+DO_INLINE void mul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < verts; i++) {
+ mul_fvector_S(to[i], fLongVector[i], scalar);
+ }
+}
+/* multiply long vector with scalar*/
+/* A -= B * float */
+DO_INLINE void submul_lfvectorS(float (*to)[3], float (*fLongVector)[3], float scalar, unsigned int verts)
+{
+ unsigned int i = 0;
+ for (i = 0; i < verts; i++) {
+ VECSUBMUL(to[i], fLongVector[i], scalar);
+ }
+}
+/* dot product for big vector */
+DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
+{
+ long i = 0;
+ float temp = 0.0;
+// XXX brecht, disabled this for now (first schedule line was already disabled),
+// due to non-commutative nature of floating point ops this makes the sim give
+// different results each time you run it!
+// schedule(guided, 2)
+//#pragma omp parallel for reduction(+: temp) if (verts > CLOTH_OPENMP_LIMIT)
+ for (i = 0; i < (long)verts; i++) {
+ temp += dot_v3v3(fLongVectorA[i], fLongVectorB[i]);
+ }
+ return temp;
+}
+/* A = B + C --> for big vector */
+DO_INLINE void add_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < verts; i++) {
+ VECADD(to[i], fLongVectorA[i], fLongVectorB[i]);
+ }
+
+}
+/* A = B + C * float --> for big vector */
+DO_INLINE void add_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < verts; i++) {
+ VECADDS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
+
+ }
+}
+/* A = B * float + C * float --> for big vector */
+DO_INLINE void add_lfvectorS_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float aS, float (*fLongVectorB)[3], float bS, unsigned int verts)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < verts; i++) {
+ VECADDSS(to[i], fLongVectorA[i], aS, fLongVectorB[i], bS);
+ }
+}
+/* A = B - C * float --> for big vector */
+DO_INLINE void sub_lfvector_lfvectorS(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], float bS, unsigned int verts)
+{
+ unsigned int i = 0;
+ for (i = 0; i < verts; i++) {
+ VECSUBS(to[i], fLongVectorA[i], fLongVectorB[i], bS);
+ }
+
+}
+/* A = B - C --> for big vector */
+DO_INLINE void sub_lfvector_lfvector(float (*to)[3], float (*fLongVectorA)[3], float (*fLongVectorB)[3], unsigned int verts)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < verts; i++) {
+ sub_v3_v3v3(to[i], fLongVectorA[i], fLongVectorB[i]);
+ }
+
+}
+///////////////////////////
+// 3x3 matrix
+///////////////////////////
+#if 0
+/* printf 3x3 matrix on console: for debug output */
+static void print_fmatrix(float m3[3][3])
+{
+ printf("%f\t%f\t%f\n", m3[0][0], m3[0][1], m3[0][2]);
+ printf("%f\t%f\t%f\n", m3[1][0], m3[1][1], m3[1][2]);
+ printf("%f\t%f\t%f\n\n", m3[2][0], m3[2][1], m3[2][2]);
+}
+
+static void print_sparse_matrix(fmatrix3x3 *m)
+{
+ if (m) {
+ unsigned int i;
+ for (i = 0; i < m[0].vcount + m[0].scount; i++) {
+ printf("%d:\n", i);
+ print_fmatrix(m[i].m);
+ }
+ }
+}
+#endif
+
+#if 0
+static void print_lvector(lfVector *v, int numverts)
+{
+ int i;
+ for (i = 0; i < numverts; ++i) {
+ if (i > 0)
+ printf("\n");
+
+ printf("%f,\n", v[i][0]);
+ printf("%f,\n", v[i][1]);
+ printf("%f,\n", v[i][2]);
+ }
+}
+#endif
+
+#if 0
+static void print_bfmatrix(fmatrix3x3 *m)
+{
+ int tot = m[0].vcount + m[0].scount;
+ int size = m[0].vcount * 3;
+ float *t = MEM_callocN(sizeof(float) * size*size, "bfmatrix");
+ int q, i, j;
+
+ for (q = 0; q < tot; ++q) {
+ int k = 3 * m[q].r;
+ int l = 3 * m[q].c;
+
+ for (j = 0; j < 3; ++j) {
+ for (i = 0; i < 3; ++i) {
+// if (t[k + i + (l + j) * size] != 0.0f) {
+// printf("warning: overwriting value at %d, %d\n", m[q].r, m[q].c);
+// }
+ if (k == l) {
+ t[k + i + (k + j) * size] += m[q].m[i][j];
+ }
+ else {
+ t[k + i + (l + j) * size] += m[q].m[i][j];
+ t[l + j + (k + i) * size] += m[q].m[j][i];
+ }
+ }
+ }
+ }
+
+ for (j = 0; j < size; ++j) {
+ if (j > 0 && j % 3 == 0)
+ printf("\n");
+
+ for (i = 0; i < size; ++i) {
+ if (i > 0 && i % 3 == 0)
+ printf(" ");
+
+ implicit_print_matrix_elem(t[i + j * size]);
+ }
+ printf("\n");
+ }
+
+ MEM_freeN(t);
+}
+#endif
+
+/* copy 3x3 matrix */
+DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3])
+{
+ // memcpy(to, from, sizeof (float) * 9);
+ copy_v3_v3(to[0], from[0]);
+ copy_v3_v3(to[1], from[1]);
+ copy_v3_v3(to[2], from[2]);
+}
+
+/* copy 3x3 matrix */
+DO_INLINE void initdiag_fmatrixS(float to[3][3], float aS)
+{
+ cp_fmatrix(to, ZERO);
+
+ to[0][0] = aS;
+ to[1][1] = aS;
+ to[2][2] = aS;
+}
+
+#if 0
+/* calculate determinant of 3x3 matrix */
+DO_INLINE float det_fmatrix(float m[3][3])
+{
+ return m[0][0]*m[1][1]*m[2][2] + m[1][0]*m[2][1]*m[0][2] + m[0][1]*m[1][2]*m[2][0] -
+ m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] - m[2][0]*m[1][1]*m[0][2];
+}
+
+DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
+{
+ unsigned int i, j;
+ float d;
+
+ if ((d=det_fmatrix(from)) == 0) {
+ printf("can't build inverse");
+ exit(0);
+ }
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++) {
+ int i1=(i+1)%3;
+ int i2=(i+2)%3;
+ int j1=(j+1)%3;
+ int j2=(j+2)%3;
+ // reverse indexs i&j to take transpose
+ to[j][i] = (from[i1][j1]*from[i2][j2]-from[i1][j2]*from[i2][j1])/d;
+ /*
+ if (i==j)
+ to[i][j] = 1.0f / from[i][j];
+ else
+ to[i][j] = 0;
+ */
+ }
+ }
+
+}
+#endif
+
+/* 3x3 matrix multiplied by a scalar */
+/* STATUS: verified */
+DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar)
+{
+ mul_fvector_S(matrix[0], matrix[0], scalar);
+ mul_fvector_S(matrix[1], matrix[1], scalar);
+ mul_fvector_S(matrix[2], matrix[2], scalar);
+}
+
+/* a vector multiplied by a 3x3 matrix */
+/* STATUS: verified */
+DO_INLINE void mul_fvector_fmatrix(float *to, float *from, float matrix[3][3])
+{
+ to[0] = matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
+ to[1] = matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
+ to[2] = matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
+}
+
+/* 3x3 matrix multiplied by a vector */
+/* STATUS: verified */
+DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float from[3])
+{
+ to[0] = dot_v3v3(matrix[0], from);
+ to[1] = dot_v3v3(matrix[1], from);
+ to[2] = dot_v3v3(matrix[2], from);
+}
+/* 3x3 matrix addition with 3x3 matrix */
+DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+{
+ VECADD(to[0], matrixA[0], matrixB[0]);
+ VECADD(to[1], matrixA[1], matrixB[1]);
+ VECADD(to[2], matrixA[2], matrixB[2]);
+}
+/* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */
+DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS)
+{
+ VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS);
+ VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS);
+ VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS);
+}
+/* A = B - C (3x3 matrix subtraction with 3x3 matrix) */
+DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+{
+ sub_v3_v3v3(to[0], matrixA[0], matrixB[0]);
+ sub_v3_v3v3(to[1], matrixA[1], matrixB[1]);
+ sub_v3_v3v3(to[2], matrixA[2], matrixB[2]);
+}
+/////////////////////////////////////////////////////////////////
+// special functions
+/////////////////////////////////////////////////////////////////
+/* 3x3 matrix multiplied+added by a vector */
+/* STATUS: verified */
+DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3])
+{
+ to[0] += dot_v3v3(matrix[0], from);
+ to[1] += dot_v3v3(matrix[1], from);
+ to[2] += dot_v3v3(matrix[2], from);
+}
+
+BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3])
+{
+ mul_v3_v3fl(r[0], a, b[0]);
+ mul_v3_v3fl(r[1], a, b[1]);
+ mul_v3_v3fl(r[2], a, b[2]);
+}
+
+BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], float m[3][3])
+{
+ cross_v3_v3v3(r[0], v, m[0]);
+ cross_v3_v3v3(r[1], v, m[1]);
+ cross_v3_v3v3(r[2], v, m[2]);
+}
+
+BLI_INLINE void cross_v3_identity(float r[3][3], const float v[3])
+{
+ r[0][0] = 0.0f; r[1][0] = v[2]; r[2][0] = -v[1];
+ r[0][1] = -v[2]; r[1][1] = 0.0f; r[2][1] = v[0];
+ r[0][2] = v[1]; r[1][2] = -v[0]; r[2][2] = 0.0f;
+}
+
+BLI_INLINE void madd_m3_m3fl(float r[3][3], float m[3][3], float f)
+{
+ r[0][0] += m[0][0] * f;
+ r[0][1] += m[0][1] * f;
+ r[0][2] += m[0][2] * f;
+ r[1][0] += m[1][0] * f;
+ r[1][1] += m[1][1] * f;
+ r[1][2] += m[1][2] * f;
+ r[2][0] += m[2][0] * f;
+ r[2][1] += m[2][1] * f;
+ r[2][2] += m[2][2] * f;
+}
+
+BLI_INLINE void madd_m3_m3m3fl(float r[3][3], float a[3][3], float b[3][3], float f)
+{
+ r[0][0] = a[0][0] + b[0][0] * f;
+ r[0][1] = a[0][1] + b[0][1] * f;
+ r[0][2] = a[0][2] + b[0][2] * f;
+ r[1][0] = a[1][0] + b[1][0] * f;
+ r[1][1] = a[1][1] + b[1][1] * f;
+ r[1][2] = a[1][2] + b[1][2] * f;
+ r[2][0] = a[2][0] + b[2][0] * f;
+ r[2][1] = a[2][1] + b[2][1] * f;
+ r[2][2] = a[2][2] + b[2][2] * f;
+}
+/////////////////////////////////////////////////////////////////
+
+///////////////////////////
+// SPARSE SYMMETRIC big matrix with 3x3 matrix entries
+///////////////////////////
+/* printf a big matrix on console: for debug output */
+#if 0
+static void print_bfmatrix(fmatrix3x3 *m3)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < m3[0].vcount + m3[0].scount; i++)
+ {
+ print_fmatrix(m3[i].m);
+ }
+}
+#endif
+
+BLI_INLINE void init_fmatrix(fmatrix3x3 *matrix, int r, int c)
+{
+ matrix->r = r;
+ matrix->c = c;
+}
+
+/* create big matrix */
+DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
+{
+ // TODO: check if memory allocation was successful */
+ fmatrix3x3 *temp = (fmatrix3x3 *)MEM_callocN(sizeof(fmatrix3x3) * (verts + springs), "cloth_implicit_alloc_matrix");
+ int i;
+
+ temp[0].vcount = verts;
+ temp[0].scount = springs;
+
+ /* vertex part of the matrix is diagonal blocks */
+ for (i = 0; i < verts; ++i) {
+ init_fmatrix(temp + i, i, i);
+ }
+
+ return temp;
+}
+/* delete big matrix */
+DO_INLINE void del_bfmatrix(fmatrix3x3 *matrix)
+{
+ if (matrix != NULL) {
+ MEM_freeN(matrix);
+ }
+}
+
+/* copy big matrix */
+DO_INLINE void cp_bfmatrix(fmatrix3x3 *to, fmatrix3x3 *from)
+{
+ // TODO bounds checking
+ memcpy(to, from, sizeof(fmatrix3x3) * (from[0].vcount+from[0].scount));
+}
+
+/* init big matrix */
+// slow in parallel
+DO_INLINE void init_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
+{
+ unsigned int i;
+
+ for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
+ cp_fmatrix(matrix[i].m, m3);
+ }
+}
+
+/* init the diagonal of big matrix */
+// slow in parallel
+DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
+{
+ unsigned int i, j;
+ float tmatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
+
+ for (i = 0; i < matrix[0].vcount; i++) {
+ cp_fmatrix(matrix[i].m, m3);
+ }
+ for (j = matrix[0].vcount; j < matrix[0].vcount+matrix[0].scount; j++) {
+ cp_fmatrix(matrix[j].m, tmatrix);
+ }
+}
+
+/* SPARSE SYMMETRIC multiply big matrix with long vector*/
+/* STATUS: verified */
+DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
+{
+ unsigned int i = 0;
+ unsigned int vcount = from[0].vcount;
+ lfVector *temp = create_lfvector(vcount);
+
+ zero_lfvector(to, vcount);
+
+#pragma omp parallel sections private(i) if (vcount > CLOTH_OPENMP_LIMIT)
+ {
+#pragma omp section
+ {
+ for (i = from[0].vcount; i < from[0].vcount+from[0].scount; i++) {
+ muladd_fmatrix_fvector(to[from[i].c], from[i].m, fLongVector[from[i].r]);
+ }
+ }
+#pragma omp section
+ {
+ for (i = 0; i < from[0].vcount+from[0].scount; i++) {
+ muladd_fmatrix_fvector(temp[from[i].r], from[i].m, fLongVector[from[i].c]);
+ }
+ }
+ }
+ add_lfvector_lfvector(to, to, temp, from[0].vcount);
+
+ del_lfvector(temp);
+
+
+}
+
+/* SPARSE SYMMETRIC sub big matrix with big matrix*/
+/* A -= B * float + C * float --> for big matrix */
+/* VERIFIED */
+DO_INLINE void subadd_bfmatrixS_bfmatrixS( fmatrix3x3 *to, fmatrix3x3 *from, float aS, fmatrix3x3 *matrix, float bS)
+{
+ unsigned int i = 0;
+
+ /* process diagonal elements */
+ for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
+ subadd_fmatrixS_fmatrixS(to[i].m, from[i].m, aS, matrix[i].m, bS);
+ }
+
+}
+
+///////////////////////////////////////////////////////////////////
+// simulator start
+///////////////////////////////////////////////////////////////////
+
+typedef struct Implicit_Data {
+ /* inputs */
+ fmatrix3x3 *bigI; /* identity (constant) */
+ fmatrix3x3 *tfm; /* local coordinate transform */
+ fmatrix3x3 *M; /* masses */
+ lfVector *F; /* forces */
+ fmatrix3x3 *dFdV, *dFdX; /* force jacobians */
+ int num_blocks; /* number of off-diagonal blocks (springs) */
+
+ /* motion state data */
+ lfVector *X, *Xnew; /* positions */
+ lfVector *V, *Vnew; /* velocities */
+
+ /* internal solver data */
+ lfVector *B; /* B for A*dV = B */
+ fmatrix3x3 *A; /* A for A*dV = B */
+
+ lfVector *dV; /* velocity change (solution of A*dV = B) */
+ lfVector *z; /* target velocity in constrained directions */
+ fmatrix3x3 *S; /* filtering matrix for constraints */
+ fmatrix3x3 *P, *Pinv; /* pre-conditioning matrix */
+} Implicit_Data;
+
+Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings)
+{
+ Implicit_Data *id = (Implicit_Data *)MEM_callocN(sizeof(Implicit_Data), "implicit vecmat");
+
+ /* process diagonal elements */
+ id->tfm = create_bfmatrix(numverts, 0);
+ id->A = create_bfmatrix(numverts, numsprings);
+ id->dFdV = create_bfmatrix(numverts, numsprings);
+ id->dFdX = create_bfmatrix(numverts, numsprings);
+ id->S = create_bfmatrix(numverts, 0);
+ id->Pinv = create_bfmatrix(numverts, numsprings);
+ id->P = create_bfmatrix(numverts, numsprings);
+ id->bigI = create_bfmatrix(numverts, numsprings); // TODO 0 springs
+ id->M = create_bfmatrix(numverts, numsprings);
+ id->X = create_lfvector(numverts);
+ id->Xnew = create_lfvector(numverts);
+ id->V = create_lfvector(numverts);
+ id->Vnew = create_lfvector(numverts);
+ id->F = create_lfvector(numverts);
+ id->B = create_lfvector(numverts);
+ id->dV = create_lfvector(numverts);
+ id->z = create_lfvector(numverts);
+
+ initdiag_bfmatrix(id->bigI, I);
+
+ return id;
+}
+
+void BPH_mass_spring_solver_free(Implicit_Data *id)
+{
+ del_bfmatrix(id->tfm);
+ del_bfmatrix(id->A);
+ del_bfmatrix(id->dFdV);
+ del_bfmatrix(id->dFdX);
+ del_bfmatrix(id->S);
+ del_bfmatrix(id->P);
+ del_bfmatrix(id->Pinv);
+ del_bfmatrix(id->bigI);
+ del_bfmatrix(id->M);
+
+ del_lfvector(id->X);
+ del_lfvector(id->Xnew);
+ del_lfvector(id->V);
+ del_lfvector(id->Vnew);
+ del_lfvector(id->F);
+ del_lfvector(id->B);
+ del_lfvector(id->dV);
+ del_lfvector(id->z);
+
+ MEM_freeN(id);
+}
+
+/* ==== Transformation from/to root reference frames ==== */
+
+BLI_INLINE void world_to_root_v3(Implicit_Data *data, int index, float r[3], const float v[3])
+{
+ copy_v3_v3(r, v);
+ mul_transposed_m3_v3(data->tfm[index].m, r);
+}
+
+BLI_INLINE void root_to_world_v3(Implicit_Data *data, int index, float r[3], const float v[3])
+{
+ mul_v3_m3v3(r, data->tfm[index].m, v);
+}
+
+BLI_INLINE void world_to_root_m3(Implicit_Data *data, int index, float r[3][3], float m[3][3])
+{
+ float trot[3][3];
+ copy_m3_m3(trot, data->tfm[index].m);
+ transpose_m3(trot);
+ mul_m3_m3m3(r, trot, m);
+}
+
+BLI_INLINE void root_to_world_m3(Implicit_Data *data, int index, float r[3][3], float m[3][3])
+{
+ mul_m3_m3m3(r, data->tfm[index].m, m);
+}
+
+/* ================================ */
+
+DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
+{
+ unsigned int i=0;
+
+ for (i = 0; i < S[0].vcount; i++) {
+ mul_m3_v3(S[i].m, V[S[i].r]);
+ }
+}
+
+#if 0 /* this version of the CG algorithm does not work very well with partial constraints (where S has non-zero elements) */
+static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S)
+{
+ // Solves for unknown X in equation AX=B
+ unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100;
+ float conjgrad_epsilon=0.0001f /* , conjgrad_lasterror=0 */ /* UNUSED */;
+ lfVector *q, *d, *tmp, *r;
+ float s, starget, a, s_prev;
+ unsigned int numverts = lA[0].vcount;
+ q = create_lfvector(numverts);
+ d = create_lfvector(numverts);
+ tmp = create_lfvector(numverts);
+ r = create_lfvector(numverts);
+
+ // zero_lfvector(ldV, CLOTHPARTICLES);
+ filter(ldV, S);
+
+ add_lfvector_lfvector(ldV, ldV, z, numverts);
+
+ // r = B - Mul(tmp, A, X); // just use B if X known to be zero
+ cp_lfvector(r, lB, numverts);
+ mul_bfmatrix_lfvector(tmp, lA, ldV);
+ sub_lfvector_lfvector(r, r, tmp, numverts);
+
+ filter(r, S);
+
+ cp_lfvector(d, r, numverts);
+
+ s = dot_lfvector(r, r, numverts);
+ starget = s * sqrtf(conjgrad_epsilon);
+
+ while (s>starget && conjgrad_loopcount < conjgrad_looplimit) {
+ // Mul(q, A, d); // q = A*d;
+ mul_bfmatrix_lfvector(q, lA, d);
+
+ filter(q, S);
+
+ a = s/dot_lfvector(d, q, numverts);
+
+ // X = X + d*a;
+ add_lfvector_lfvectorS(ldV, ldV, d, a, numverts);
+
+ // r = r - q*a;
+ sub_lfvector_lfvectorS(r, r, q, a, numverts);
+
+ s_prev = s;
+ s = dot_lfvector(r, r, numverts);
+
+ //d = r+d*(s/s_prev);
+ add_lfvector_lfvectorS(d, r, d, (s/s_prev), numverts);
+
+ filter(d, S);
+
+ conjgrad_loopcount++;
+ }
+ /* conjgrad_lasterror = s; */ /* UNUSED */
+
+ del_lfvector(q);
+ del_lfvector(d);
+ del_lfvector(tmp);
+ del_lfvector(r);
+ // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount);
+
+ return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
+}
+#endif
+
+static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, ImplicitSolverResult *result)
+{
+ // Solves for unknown X in equation AX=B
+ unsigned int conjgrad_loopcount=0, conjgrad_looplimit=100;
+ float conjgrad_epsilon=0.01f;
+
+ unsigned int numverts = lA[0].vcount;
+ lfVector *fB = create_lfvector(numverts);
+ lfVector *AdV = create_lfvector(numverts);
+ lfVector *r = create_lfvector(numverts);
+ lfVector *c = create_lfvector(numverts);
+ lfVector *q = create_lfvector(numverts);
+ lfVector *s = create_lfvector(numverts);
+ float bnorm2, delta_new, delta_old, delta_target, alpha;
+
+ cp_lfvector(ldV, z, numverts);
+
+ /* d0 = filter(B)^T * P * filter(B) */
+ cp_lfvector(fB, lB, numverts);
+ filter(fB, S);
+ bnorm2 = dot_lfvector(fB, fB, numverts);
+ delta_target = conjgrad_epsilon*conjgrad_epsilon * bnorm2;
+
+ /* r = filter(B - A * dV) */
+ mul_bfmatrix_lfvector(AdV, lA, ldV);
+ sub_lfvector_lfvector(r, lB, AdV, numverts);
+ filter(r, S);
+
+ /* c = filter(P^-1 * r) */
+ cp_lfvector(c, r, numverts);
+ filter(c, S);
+
+ /* delta = r^T * c */
+ delta_new = dot_lfvector(r, c, numverts);
+
+#ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
+ printf("==== A ====\n");
+ print_bfmatrix(lA);
+ printf("==== z ====\n");
+ print_lvector(z, numverts);
+ printf("==== B ====\n");
+ print_lvector(lB, numverts);
+ printf("==== S ====\n");
+ print_bfmatrix(S);
+#endif
+
+ while (delta_new > delta_target && conjgrad_loopcount < conjgrad_looplimit) {
+ mul_bfmatrix_lfvector(q, lA, c);
+ filter(q, S);
+
+ alpha = delta_new / dot_lfvector(c, q, numverts);
+
+ add_lfvector_lfvectorS(ldV, ldV, c, alpha, numverts);
+
+ add_lfvector_lfvectorS(r, r, q, -alpha, numverts);
+
+ /* s = P^-1 * r */
+ cp_lfvector(s, r, numverts);
+ delta_old = delta_new;
+ delta_new = dot_lfvector(r, s, numverts);
+
+ add_lfvector_lfvectorS(c, s, c, delta_new / delta_old, numverts);
+ filter(c, S);
+
+ conjgrad_loopcount++;
+ }
+
+#ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
+ printf("==== dV ====\n");
+ print_lvector(ldV, numverts);
+ printf("========\n");
+#endif
+
+ del_lfvector(fB);
+ del_lfvector(AdV);
+ del_lfvector(r);
+ del_lfvector(c);
+ del_lfvector(q);
+ del_lfvector(s);
+ // printf("W/O conjgrad_loopcount: %d\n", conjgrad_loopcount);
+
+ result->status = conjgrad_loopcount < conjgrad_looplimit ? BPH_SOLVER_SUCCESS : BPH_SOLVER_NO_CONVERGENCE;
+ result->iterations = conjgrad_loopcount;
+ result->error = bnorm2 > 0.0f ? sqrtf(delta_new / bnorm2) : 0.0f;
+
+ return conjgrad_loopcount < conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
+}
+
+#if 0
+// block diagonalizer
+DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
+{
+ unsigned int i = 0;
+
+ // Take only the diagonal blocks of A
+// #pragma omp parallel for private(i) if (lA[0].vcount > CLOTH_OPENMP_LIMIT)
+ for (i = 0; i<lA[0].vcount; i++) {
+ // block diagonalizer
+ cp_fmatrix(P[i].m, lA[i].m);
+ inverse_fmatrix(Pinv[i].m, P[i].m);
+
+ }
+}
+/*
+// version 1.3
+static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv)
+{
+ unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100;
+ float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0;
+ float conjgrad_epsilon=0.0001; // 0.2 is dt for steps=5
+ lfVector *r = create_lfvector(numverts);
+ lfVector *p = create_lfvector(numverts);
+ lfVector *s = create_lfvector(numverts);
+ lfVector *h = create_lfvector(numverts);
+
+ BuildPPinv(lA, P, Pinv);
+
+ filter(dv, S);
+ add_lfvector_lfvector(dv, dv, z, numverts);
+
+ mul_bfmatrix_lfvector(r, lA, dv);
+ sub_lfvector_lfvector(r, lB, r, numverts);
+ filter(r, S);
+
+ mul_prevfmatrix_lfvector(p, Pinv, r);
+ filter(p, S);
+
+ deltaNew = dot_lfvector(r, p, numverts);
+
+ delta0 = deltaNew * sqrt(conjgrad_epsilon);
+
+ // itstart();
+
+ while ((deltaNew > delta0) && (iterations < conjgrad_looplimit))
+ {
+ iterations++;
+
+ mul_bfmatrix_lfvector(s, lA, p);
+ filter(s, S);
+
+ alpha = deltaNew / dot_lfvector(p, s, numverts);
+
+ add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
+
+ add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
+
+ mul_prevfmatrix_lfvector(h, Pinv, r);
+ filter(h, S);
+
+ deltaOld = deltaNew;
+
+ deltaNew = dot_lfvector(r, h, numverts);
+
+ add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
+
+ filter(p, S);
+
+ }
+
+ // itend();
+ // printf("cg_filtered_pre time: %f\n", (float)itval());
+
+ del_lfvector(h);
+ del_lfvector(s);
+ del_lfvector(p);
+ del_lfvector(r);
+
+ printf("iterations: %d\n", iterations);
+
+ return iterations<conjgrad_looplimit;
+}
+*/
+// version 1.4
+static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv, fmatrix3x3 *bigI)
+{
+ unsigned int numverts = lA[0].vcount, iterations = 0, conjgrad_looplimit=100;
+ float delta0 = 0, deltaNew = 0, deltaOld = 0, alpha = 0, tol = 0;
+ lfVector *r = create_lfvector(numverts);
+ lfVector *p = create_lfvector(numverts);
+ lfVector *s = create_lfvector(numverts);
+ lfVector *h = create_lfvector(numverts);
+ lfVector *bhat = create_lfvector(numverts);
+ lfVector *btemp = create_lfvector(numverts);
+
+ BuildPPinv(lA, P, Pinv);
+
+ initdiag_bfmatrix(bigI, I);
+ sub_bfmatrix_Smatrix(bigI, bigI, S);
+
+ // x = Sx_0+(I-S)z
+ filter(dv, S);
+ add_lfvector_lfvector(dv, dv, z, numverts);
+
+ // b_hat = S(b-A(I-S)z)
+ mul_bfmatrix_lfvector(r, lA, z);
+ mul_bfmatrix_lfvector(bhat, bigI, r);
+ sub_lfvector_lfvector(bhat, lB, bhat, numverts);
+
+ // r = S(b-Ax)
+ mul_bfmatrix_lfvector(r, lA, dv);
+ sub_lfvector_lfvector(r, lB, r, numverts);
+ filter(r, S);
+
+ // p = SP^-1r
+ mul_prevfmatrix_lfvector(p, Pinv, r);
+ filter(p, S);
+
+ // delta0 = bhat^TP^-1bhat
+ mul_prevfmatrix_lfvector(btemp, Pinv, bhat);
+ delta0 = dot_lfvector(bhat, btemp, numverts);
+
+ // deltaNew = r^TP
+ deltaNew = dot_lfvector(r, p, numverts);
+
+ /*
+ filter(dv, S);
+ add_lfvector_lfvector(dv, dv, z, numverts);
+
+ mul_bfmatrix_lfvector(r, lA, dv);
+ sub_lfvector_lfvector(r, lB, r, numverts);
+ filter(r, S);
+
+ mul_prevfmatrix_lfvector(p, Pinv, r);
+ filter(p, S);
+
+ deltaNew = dot_lfvector(r, p, numverts);
+
+ delta0 = deltaNew * sqrt(conjgrad_epsilon);
+ */
+
+ // itstart();
+
+ tol = (0.01*0.2);
+
+ while ((deltaNew > delta0*tol*tol) && (iterations < conjgrad_looplimit))
+ {
+ iterations++;
+
+ mul_bfmatrix_lfvector(s, lA, p);
+ filter(s, S);
+
+ alpha = deltaNew / dot_lfvector(p, s, numverts);
+
+ add_lfvector_lfvectorS(dv, dv, p, alpha, numverts);
+
+ add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
+
+ mul_prevfmatrix_lfvector(h, Pinv, r);
+ filter(h, S);
+
+ deltaOld = deltaNew;
+
+ deltaNew = dot_lfvector(r, h, numverts);
+
+ add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
+
+ filter(p, S);
+
+ }
+
+ // itend();
+ // printf("cg_filtered_pre time: %f\n", (float)itval());
+
+ del_lfvector(btemp);
+ del_lfvector(bhat);
+ del_lfvector(h);
+ del_lfvector(s);
+ del_lfvector(p);
+ del_lfvector(r);
+
+ // printf("iterations: %d\n", iterations);
+
+ return iterations<conjgrad_looplimit;
+}
+#endif
+
+bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSolverResult *result)
+{
+ unsigned int numverts = data->dFdV[0].vcount;
+
+ lfVector *dFdXmV = create_lfvector(numverts);
+ zero_lfvector(data->dV, numverts);
+
+ cp_bfmatrix(data->A, data->M);
+
+ subadd_bfmatrixS_bfmatrixS(data->A, data->dFdV, dt, data->dFdX, (dt*dt));
+
+ mul_bfmatrix_lfvector(dFdXmV, data->dFdX, data->V);
+
+ add_lfvectorS_lfvectorS(data->B, data->F, dt, dFdXmV, (dt*dt), numverts);
+
+ // itstart();
+
+ cg_filtered(data->dV, data->A, data->B, data->z, data->S, result); /* conjugate gradient algorithm to solve Ax=b */
+ // cg_filtered_pre(id->dV, id->A, id->B, id->z, id->S, id->P, id->Pinv, id->bigI);
+
+ // itend();
+ // printf("cg_filtered calc time: %f\n", (float)itval());
+
+ // advance velocities
+ add_lfvector_lfvector(data->Vnew, data->V, data->dV, numverts);
+
+ del_lfvector(dFdXmV);
+
+ return result->status == BPH_SOLVER_SUCCESS;
+}
+
+bool BPH_mass_spring_solve_positions(Implicit_Data *data, float dt)
+{
+ int numverts = data->M[0].vcount;
+
+ // advance positions
+ add_lfvector_lfvectorS(data->Xnew, data->X, data->Vnew, dt, numverts);
+
+ return true;
+}
+
+void BPH_mass_spring_apply_result(Implicit_Data *data)
+{
+ int numverts = data->M[0].vcount;
+ cp_lfvector(data->X, data->Xnew, numverts);
+ cp_lfvector(data->V, data->Vnew, numverts);
+}
+
+void BPH_mass_spring_set_vertex_mass(Implicit_Data *data, int index, float mass)
+{
+ unit_m3(data->M[index].m);
+ mul_m3_fl(data->M[index].m, mass);
+}
+
+void BPH_mass_spring_set_rest_transform(Implicit_Data *data, int index, float tfm[3][3])
+{
+#ifdef CLOTH_ROOT_FRAME
+ copy_m3_m3(data->tfm[index].m, tfm);
+#else
+ unit_m3(data->tfm[index].m);
+ (void)tfm;
+#endif
+}
+
+void BPH_mass_spring_set_motion_state(Implicit_Data *data, int index, const float x[3], const float v[3])
+{
+ world_to_root_v3(data, index, data->X[index], x);
+ world_to_root_v3(data, index, data->V[index], v);
+}
+
+void BPH_mass_spring_set_position(Implicit_Data *data, int index, const float x[3])
+{
+ world_to_root_v3(data, index, data->X[index], x);
+}
+
+void BPH_mass_spring_set_velocity(Implicit_Data *data, int index, const float v[3])
+{
+ world_to_root_v3(data, index, data->V[index], v);
+}
+
+void BPH_mass_spring_get_motion_state(struct Implicit_Data *data, int index, float x[3], float v[3])
+{
+ if (x) root_to_world_v3(data, index, x, data->X[index]);
+ if (v) root_to_world_v3(data, index, v, data->V[index]);
+}
+
+void BPH_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3])
+{
+ root_to_world_v3(data, index, x, data->X[index]);
+}
+
+void BPH_mass_spring_get_new_position(struct Implicit_Data *data, int index, float x[3])
+{
+ root_to_world_v3(data, index, x, data->Xnew[index]);
+}
+
+void BPH_mass_spring_set_new_position(struct Implicit_Data *data, int index, const float x[3])
+{
+ world_to_root_v3(data, index, data->Xnew[index], x);
+}
+
+void BPH_mass_spring_get_new_velocity(struct Implicit_Data *data, int index, float v[3])
+{
+ root_to_world_v3(data, index, v, data->Vnew[index]);
+}
+
+void BPH_mass_spring_set_new_velocity(struct Implicit_Data *data, int index, const float v[3])
+{
+ world_to_root_v3(data, index, data->Vnew[index], v);
+}
+
+/* -------------------------------- */
+
+static int BPH_mass_spring_add_block(Implicit_Data *data, int v1, int v2)
+{
+ int s = data->M[0].vcount + data->num_blocks; /* index from array start */
+ BLI_assert(s < data->M[0].vcount + data->M[0].scount);
+ ++data->num_blocks;
+
+ /* tfm and S don't have spring entries (diagonal blocks only) */
+ init_fmatrix(data->bigI + s, v1, v2);
+ init_fmatrix(data->M + s, v1, v2);
+ init_fmatrix(data->dFdX + s, v1, v2);
+ init_fmatrix(data->dFdV + s, v1, v2);
+ init_fmatrix(data->A + s, v1, v2);
+ init_fmatrix(data->P + s, v1, v2);
+ init_fmatrix(data->Pinv + s, v1, v2);
+
+ return s;
+}
+
+void BPH_mass_spring_clear_constraints(Implicit_Data *data)
+{
+ int i, numverts = data->S[0].vcount;
+ for (i = 0; i < numverts; ++i) {
+ unit_m3(data->S[i].m);
+ zero_v3(data->z[i]);
+ }
+}
+
+void BPH_mass_spring_add_constraint_ndof0(Implicit_Data *data, int index, const float dV[3])
+{
+ zero_m3(data->S[index].m);
+
+ world_to_root_v3(data, index, data->z[index], dV);
+}
+
+void BPH_mass_spring_add_constraint_ndof1(Implicit_Data *data, int index, const float c1[3], const float c2[3], const float dV[3])
+{
+ float m[3][3], p[3], q[3], u[3], cmat[3][3];
+
+ world_to_root_v3(data, index, p, c1);
+ mul_fvectorT_fvector(cmat, p, p);
+ sub_m3_m3m3(m, I, cmat);
+
+ world_to_root_v3(data, index, q, c2);
+ mul_fvectorT_fvector(cmat, q, q);
+ sub_m3_m3m3(m, m, cmat);
+
+ /* XXX not sure but multiplication should work here */
+ copy_m3_m3(data->S[index].m, m);
+// mul_m3_m3m3(data->S[index].m, data->S[index].m, m);
+
+ world_to_root_v3(data, index, u, dV);
+ add_v3_v3(data->z[index], u);
+}
+
+void BPH_mass_spring_add_constraint_ndof2(Implicit_Data *data, int index, const float c1[3], const float dV[3])
+{
+ float m[3][3], p[3], u[3], cmat[3][3];
+
+ world_to_root_v3(data, index, p, c1);
+ mul_fvectorT_fvector(cmat, p, p);
+ sub_m3_m3m3(m, I, cmat);
+
+ copy_m3_m3(data->S[index].m, m);
+// mul_m3_m3m3(data->S[index].m, data->S[index].m, m);
+
+ world_to_root_v3(data, index, u, dV);
+ add_v3_v3(data->z[index], u);
+}
+
+void BPH_mass_spring_clear_forces(Implicit_Data *data)
+{
+ int numverts = data->M[0].vcount;
+ zero_lfvector(data->F, numverts);
+ init_bfmatrix(data->dFdX, ZERO);
+ init_bfmatrix(data->dFdV, ZERO);
+
+ data->num_blocks = 0;
+}
+
+void BPH_mass_spring_force_reference_frame(Implicit_Data *data, int index, const float acceleration[3], const float omega[3], const float domega_dt[3], float mass)
+{
+#ifdef CLOTH_ROOT_FRAME
+ float acc[3], w[3], dwdt[3];
+ float f[3], dfdx[3][3], dfdv[3][3];
+ float euler[3], coriolis[3], centrifugal[3], rotvel[3];
+ float deuler[3][3], dcoriolis[3][3], dcentrifugal[3][3], drotvel[3][3];
+
+ world_to_root_v3(data, index, acc, acceleration);
+ world_to_root_v3(data, index, w, omega);
+ world_to_root_v3(data, index, dwdt, domega_dt);
+
+ cross_v3_v3v3(euler, dwdt, data->X[index]);
+ cross_v3_v3v3(coriolis, w, data->V[index]);
+ mul_v3_fl(coriolis, 2.0f);
+ cross_v3_v3v3(rotvel, w, data->X[index]);
+ cross_v3_v3v3(centrifugal, w, rotvel);
+
+ sub_v3_v3v3(f, acc, euler);
+ sub_v3_v3(f, coriolis);
+ sub_v3_v3(f, centrifugal);
+
+ mul_v3_fl(f, mass); /* F = m * a */
+
+ cross_v3_identity(deuler, dwdt);
+ cross_v3_identity(dcoriolis, w);
+ mul_m3_fl(dcoriolis, 2.0f);
+ cross_v3_identity(drotvel, w);
+ cross_m3_v3m3(dcentrifugal, w, drotvel);
+
+ add_m3_m3m3(dfdx, deuler, dcentrifugal);
+ negate_m3(dfdx);
+ mul_m3_fl(dfdx, mass);
+
+ copy_m3_m3(dfdv, dcoriolis);
+ negate_m3(dfdv);
+ mul_m3_fl(dfdv, mass);
+
+ add_v3_v3(data->F[index], f);
+ add_m3_m3m3(data->dFdX[index].m, data->dFdX[index].m, dfdx);
+ add_m3_m3m3(data->dFdV[index].m, data->dFdV[index].m, dfdv);
+#else
+ (void)data;
+ (void)index;
+ (void)acceleration;
+ (void)omega;
+ (void)domega_dt;
+#endif
+}
+
+void BPH_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, const float g[3])
+{
+ /* force = mass * acceleration (in this case: gravity) */
+ float f[3];
+ world_to_root_v3(data, index, f, g);
+ mul_v3_fl(f, mass);
+
+ add_v3_v3(data->F[index], f);
+}
+
+void BPH_mass_spring_force_drag(Implicit_Data *data, float drag)
+{
+ int i, numverts = data->M[0].vcount;
+ for (i = 0; i < numverts; i++) {
+ float tmp[3][3];
+
+ /* NB: uses root space velocity, no need to transform */
+ madd_v3_v3fl(data->F[i], data->V[i], -drag);
+
+ copy_m3_m3(tmp, I);
+ mul_m3_fl(tmp, -drag);
+ add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, tmp);
+ }
+}
+
+void BPH_mass_spring_force_extern(struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3])
+{
+ float tf[3], tdfdx[3][3], tdfdv[3][3];
+ world_to_root_v3(data, i, tf, f);
+ world_to_root_m3(data, i, tdfdx, dfdx);
+ world_to_root_m3(data, i, tdfdv, dfdv);
+
+ add_v3_v3(data->F[i], tf);
+ add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, tdfdx);
+ add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, tdfdv);
+}
+
+static float calc_nor_area_tri(float nor[3], const float v1[3], const float v2[3], const float v3[3])
+{
+ float n1[3], n2[3];
+
+ sub_v3_v3v3(n1, v1, v2);
+ sub_v3_v3v3(n2, v2, v3);
+
+ cross_v3_v3v3(nor, n1, n2);
+ return normalize_v3(nor);
+}
+
+static float calc_nor_area_quad(float nor[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+{
+ float n1[3], n2[3];
+
+ sub_v3_v3v3(n1, v1, v3);
+ sub_v3_v3v3(n2, v2, v4);
+
+ cross_v3_v3v3(nor, n1, n2);
+ return normalize_v3(nor);
+}
+
+/* XXX does not support force jacobians yet, since the effector system does not provide them either */
+void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3])
+{
+ const float effector_scale = 0.02f;
+ float win[3], nor[3], area;
+ float factor;
+
+ // calculate face normal and area
+ if (v4) {
+ area = calc_nor_area_quad(nor, data->X[v1], data->X[v2], data->X[v3], data->X[v4]);
+ factor = effector_scale * area * 0.25f;
+ }
+ else {
+ area = calc_nor_area_tri(nor, data->X[v1], data->X[v2], data->X[v3]);
+ factor = effector_scale * area / 3.0f;
+ }
+
+ world_to_root_v3(data, v1, win, winvec[v1]);
+ madd_v3_v3fl(data->F[v1], nor, factor * dot_v3v3(win, nor));
+
+ world_to_root_v3(data, v2, win, winvec[v2]);
+ madd_v3_v3fl(data->F[v2], nor, factor * dot_v3v3(win, nor));
+
+ world_to_root_v3(data, v3, win, winvec[v3]);
+ madd_v3_v3fl(data->F[v3], nor, factor * dot_v3v3(win, nor));
+
+ if (v4) {
+ world_to_root_v3(data, v4, win, winvec[v4]);
+ madd_v3_v3fl(data->F[v4], nor, factor * dot_v3v3(win, nor));
+ }
+}
+
+static void edge_wind_vertex(const float dir[3], float length, float radius, const float wind[3], float f[3], float UNUSED(dfdx[3][3]), float UNUSED(dfdv[3][3]))
+{
+ const float density = 0.01f; /* XXX arbitrary value, corresponds to effect of air density */
+ float cos_alpha, sin_alpha, cross_section;
+ float windlen = len_v3(wind);
+
+ if (windlen == 0.0f) {
+ zero_v3(f);
+ return;
+ }
+
+ /* angle of wind direction to edge */
+ cos_alpha = dot_v3v3(wind, dir) / windlen;
+ sin_alpha = sqrtf(1.0f - cos_alpha * cos_alpha);
+ cross_section = radius * ((float)M_PI * radius * sin_alpha + length * cos_alpha);
+
+ mul_v3_v3fl(f, wind, density * cross_section);
+}
+
+void BPH_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, float radius1, float radius2, const float (*winvec)[3])
+{
+ float win[3], dir[3], length;
+ float f[3], dfdx[3][3], dfdv[3][3];
+
+ sub_v3_v3v3(dir, data->X[v1], data->X[v2]);
+ length = normalize_v3(dir);
+
+ world_to_root_v3(data, v1, win, winvec[v1]);
+ edge_wind_vertex(dir, length, radius1, win, f, dfdx, dfdv);
+ add_v3_v3(data->F[v1], f);
+
+ world_to_root_v3(data, v2, win, winvec[v2]);
+ edge_wind_vertex(dir, length, radius2, win, f, dfdx, dfdv);
+ add_v3_v3(data->F[v2], f);
+}
+
+void BPH_mass_spring_force_vertex_wind(Implicit_Data *data, int v, float UNUSED(radius), const float (*winvec)[3])
+{
+ const float density = 0.01f; /* XXX arbitrary value, corresponds to effect of air density */
+
+ float wind[3];
+ float f[3];
+
+ world_to_root_v3(data, v, wind, winvec[v]);
+ mul_v3_v3fl(f, wind, density);
+ add_v3_v3(data->F[v], f);
+}
+
+BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, float L, float k)
+{
+ // dir is unit length direction, rest is spring's restlength, k is spring constant.
+ //return ( (I-outerprod(dir, dir))*Min(1.0f, rest/length) - I) * -k;
+ outerproduct(to, dir, dir);
+ sub_m3_m3m3(to, I, to);
+
+ mul_m3_fl(to, (L/length));
+ sub_m3_m3m3(to, to, I);
+ mul_m3_fl(to, k);
+}
+
+/* unused */
+#if 0
+BLI_INLINE void dfdx_damp(float to[3][3], const float dir[3], float length, const float vel[3], float rest, float damping)
+{
+ // inner spring damping vel is the relative velocity of the endpoints.
+ // return (I-outerprod(dir, dir)) * (-damping * -(dot(dir, vel)/Max(length, rest)));
+ mul_fvectorT_fvector(to, dir, dir);
+ sub_fmatrix_fmatrix(to, I, to);
+ mul_fmatrix_S(to, (-damping * -(dot_v3v3(dir, vel)/MAX2(length, rest))));
+}
+#endif
+
+BLI_INLINE void dfdv_damp(float to[3][3], const float dir[3], float damping)
+{
+ // derivative of force wrt velocity
+ outerproduct(to, dir, dir);
+ mul_m3_fl(to, -damping);
+}
+
+BLI_INLINE float fb(float length, float L)
+{
+ float x = length / L;
+ float xx = x * x;
+ float xxx = xx * x;
+ float xxxx = xxx * x;
+ return (-11.541f * xxxx + 34.193f * xxx - 39.083f * xx + 23.116f * x - 9.713f);
+}
+
+BLI_INLINE float fbderiv(float length, float L)
+{
+ float x = length/L;
+ float xx = x * x;
+ float xxx = xx * x;
+ return (-46.164f * xxx + 102.579f * xx - 78.166f * x + 23.116f);
+}
+
+BLI_INLINE float fbstar(float length, float L, float kb, float cb)
+{
+ float tempfb_fl = kb * fb(length, L);
+ float fbstar_fl = cb * (length - L);
+
+ if (tempfb_fl < fbstar_fl)
+ return fbstar_fl;
+ else
+ return tempfb_fl;
+}
+
+// function to calculae bending spring force (taken from Choi & Co)
+BLI_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
+{
+ float tempfb_fl = kb * fb(length, L);
+ float fbstar_fl = cb * (length - L);
+
+ if (tempfb_fl < fbstar_fl) {
+ return -cb;
+ }
+ else {
+ return -kb * fbderiv(length, L);
+ }
+}
+
+/* calculate elonglation */
+BLI_INLINE bool spring_length(Implicit_Data *data, int i, int j, float r_extent[3], float r_dir[3], float *r_length, float r_vel[3])
+{
+ sub_v3_v3v3(r_extent, data->X[j], data->X[i]);
+ sub_v3_v3v3(r_vel, data->V[j], data->V[i]);
+ *r_length = len_v3(r_extent);
+
+ if (*r_length > ALMOST_ZERO) {
+ /*
+ if (length>L) {
+ if ((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) &&
+ ( ((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen )) {
+ // cut spring!
+ s->flags |= CSPRING_FLAG_DEACTIVATE;
+ return false;
+ }
+ }
+ */
+ mul_v3_v3fl(r_dir, r_extent, 1.0f/(*r_length));
+ }
+ else {
+ zero_v3(r_dir);
+ }
+
+ return true;
+}
+
+BLI_INLINE void apply_spring(Implicit_Data *data, int i, int j, const float f[3], float dfdx[3][3], float dfdv[3][3])
+{
+ int block_ij = BPH_mass_spring_add_block(data, i, j);
+
+ add_v3_v3(data->F[i], f);
+ sub_v3_v3(data->F[j], f);
+
+ add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfdx);
+ add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfdx);
+ sub_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfdx);
+
+ add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, dfdv);
+ add_m3_m3m3(data->dFdV[j].m, data->dFdV[j].m, dfdv);
+ sub_m3_m3m3(data->dFdV[block_ij].m, data->dFdV[block_ij].m, dfdv);
+}
+
+bool BPH_mass_spring_force_spring_linear(Implicit_Data *data, int i, int j, float restlen,
+ float stiffness, float damping, bool no_compress, float clamp_force,
+ float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3])
+{
+ float extent[3], length, dir[3], vel[3];
+
+ // calculate elonglation
+ spring_length(data, i, j, extent, dir, &length, vel);
+
+ if (length > restlen || no_compress) {
+ float stretch_force, f[3], dfdx[3][3], dfdv[3][3];
+
+ stretch_force = stiffness * (length - restlen);
+ if (clamp_force > 0.0f && stretch_force > clamp_force) {
+ stretch_force = clamp_force;
+ }
+ mul_v3_v3fl(f, dir, stretch_force);
+
+ // Ascher & Boxman, p.21: Damping only during elonglation
+ // something wrong with it...
+ madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir));
+
+ dfdx_spring(dfdx, dir, length, restlen, stiffness);
+ dfdv_damp(dfdv, dir, damping);
+
+ apply_spring(data, i, j, f, dfdx, dfdv);
+
+ if (r_f) copy_v3_v3(r_f, f);
+ if (r_dfdx) copy_m3_m3(r_dfdx, dfdx);
+ if (r_dfdv) copy_m3_m3(r_dfdv, dfdv);
+
+ return true;
+ }
+ else {
+ if (r_f) zero_v3(r_f);
+ if (r_dfdx) zero_m3(r_dfdx);
+ if (r_dfdv) zero_m3(r_dfdv);
+
+ return false;
+ }
+}
+
+/* See "Stable but Responsive Cloth" (Choi, Ko 2005) */
+bool BPH_mass_spring_force_spring_bending(Implicit_Data *data, int i, int j, float restlen,
+ float kb, float cb,
+ float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3])
+{
+ float extent[3], length, dir[3], vel[3];
+
+ // calculate elonglation
+ spring_length(data, i, j, extent, dir, &length, vel);
+
+ if (length < restlen) {
+ float f[3], dfdx[3][3], dfdv[3][3];
+
+ mul_v3_v3fl(f, dir, fbstar(length, restlen, kb, cb));
+
+ outerproduct(dfdx, dir, dir);
+ mul_m3_fl(dfdx, fbstar_jacobi(length, restlen, kb, cb));
+
+ /* XXX damping not supported */
+ zero_m3(dfdv);
+
+ apply_spring(data, i, j, f, dfdx, dfdv);
+
+ if (r_f) copy_v3_v3(r_f, f);
+ if (r_dfdx) copy_m3_m3(r_dfdx, dfdx);
+ if (r_dfdv) copy_m3_m3(r_dfdv, dfdv);
+
+ return true;
+ }
+ else {
+ if (r_f) zero_v3(r_f);
+ if (r_dfdx) zero_m3(r_dfdx);
+ if (r_dfdv) zero_m3(r_dfdv);
+
+ return false;
+ }
+}
+
+/* Jacobian of a direction vector.
+ * Basically the part of the differential orthogonal to the direction,
+ * inversely proportional to the length of the edge.
+ *
+ * dD_ij/dx_i = -dD_ij/dx_j = (D_ij * D_ij^T - I) / len_ij
+ */
+BLI_INLINE void spring_grad_dir(Implicit_Data *data, int i, int j, float edge[3], float dir[3], float grad_dir[3][3])
+{
+ float length;
+
+ sub_v3_v3v3(edge, data->X[j], data->X[i]);
+ length = normalize_v3_v3(dir, edge);
+
+ if (length > ALMOST_ZERO) {
+ outerproduct(grad_dir, dir, dir);
+ sub_m3_m3m3(grad_dir, I, grad_dir);
+ mul_m3_fl(grad_dir, 1.0f / length);
+ }
+ else {
+ zero_m3(grad_dir);
+ }
+}
+
+BLI_INLINE void spring_angbend_forces(Implicit_Data *data, int i, int j, int k,
+ const float goal[3],
+ float stiffness, float damping,
+ int q, const float dx[3], const float dv[3],
+ float r_f[3])
+{
+ float edge_ij[3], dir_ij[3];
+ float edge_jk[3], dir_jk[3];
+ float vel_ij[3], vel_jk[3], vel_ortho[3];
+ float f_bend[3], f_damp[3];
+ float fk[3];
+ float dist[3];
+
+ zero_v3(fk);
+
+ sub_v3_v3v3(edge_ij, data->X[j], data->X[i]);
+ if (q == i) sub_v3_v3(edge_ij, dx);
+ if (q == j) add_v3_v3(edge_ij, dx);
+ normalize_v3_v3(dir_ij, edge_ij);
+
+ sub_v3_v3v3(edge_jk, data->X[k], data->X[j]);
+ if (q == j) sub_v3_v3(edge_jk, dx);
+ if (q == k) add_v3_v3(edge_jk, dx);
+ normalize_v3_v3(dir_jk, edge_jk);
+
+ sub_v3_v3v3(vel_ij, data->V[j], data->V[i]);
+ if (q == i) sub_v3_v3(vel_ij, dv);
+ if (q == j) add_v3_v3(vel_ij, dv);
+
+ sub_v3_v3v3(vel_jk, data->V[k], data->V[j]);
+ if (q == j) sub_v3_v3(vel_jk, dv);
+ if (q == k) add_v3_v3(vel_jk, dv);
+
+ /* bending force */
+ sub_v3_v3v3(dist, goal, edge_jk);
+ mul_v3_v3fl(f_bend, dist, stiffness);
+
+ add_v3_v3(fk, f_bend);
+
+ /* damping force */
+ madd_v3_v3v3fl(vel_ortho, vel_jk, dir_jk, -dot_v3v3(vel_jk, dir_jk));
+ mul_v3_v3fl(f_damp, vel_ortho, damping);
+
+ sub_v3_v3(fk, f_damp);
+
+ copy_v3_v3(r_f, fk);
+}
+
+/* Finite Differences method for estimating the jacobian of the force */
+BLI_INLINE void spring_angbend_estimate_dfdx(Implicit_Data *data, int i, int j, int k,
+ const float goal[3],
+ float stiffness, float damping,
+ int q, float dfdx[3][3])
+{
+ const float delta = 0.00001f; // TODO find a good heuristic for this
+ float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
+ float f[3];
+ int a, b;
+
+ zero_m3(dvec_null);
+ unit_m3(dvec_pos);
+ mul_m3_fl(dvec_pos, delta * 0.5f);
+ copy_m3_m3(dvec_neg, dvec_pos);
+ negate_m3(dvec_neg);
+
+ /* XXX TODO offset targets to account for position dependency */
+
+ for (a = 0; a < 3; ++a) {
+ spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
+ q, dvec_pos[a], dvec_null[a], f);
+ copy_v3_v3(dfdx[a], f);
+
+ spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
+ q, dvec_neg[a], dvec_null[a], f);
+ sub_v3_v3(dfdx[a], f);
+
+ for (b = 0; b < 3; ++b) {
+ dfdx[a][b] /= delta;
+ }
+ }
+}
+
+/* Finite Differences method for estimating the jacobian of the force */
+BLI_INLINE void spring_angbend_estimate_dfdv(Implicit_Data *data, int i, int j, int k,
+ const float goal[3],
+ float stiffness, float damping,
+ int q, float dfdv[3][3])
+{
+ const float delta = 0.00001f; // TODO find a good heuristic for this
+ float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
+ float f[3];
+ int a, b;
+
+ zero_m3(dvec_null);
+ unit_m3(dvec_pos);
+ mul_m3_fl(dvec_pos, delta * 0.5f);
+ copy_m3_m3(dvec_neg, dvec_pos);
+ negate_m3(dvec_neg);
+
+ /* XXX TODO offset targets to account for position dependency */
+
+ for (a = 0; a < 3; ++a) {
+ spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
+ q, dvec_null[a], dvec_pos[a], f);
+ copy_v3_v3(dfdv[a], f);
+
+ spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
+ q, dvec_null[a], dvec_neg[a], f);
+ sub_v3_v3(dfdv[a], f);
+
+ for (b = 0; b < 3; ++b) {
+ dfdv[a][b] /= delta;
+ }
+ }
+}
+
+/* Angular spring that pulls the vertex toward the local target
+ * See "Artistic Simulation of Curly Hair" (Pixar technical memo #12-03a)
+ */
+bool BPH_mass_spring_force_spring_bending_angular(Implicit_Data *data, int i, int j, int k,
+ const float target[3], float stiffness, float damping)
+{
+ float goal[3];
+ float fj[3], fk[3];
+ float dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
+ float dfj_dvi[3][3], dfj_dvj[3][3], dfk_dvi[3][3], dfk_dvj[3][3], dfk_dvk[3][3];
+
+ const float vecnull[3] = {0.0f, 0.0f, 0.0f};
+
+ int block_ij = BPH_mass_spring_add_block(data, i, j);
+ int block_jk = BPH_mass_spring_add_block(data, j, k);
+ int block_ik = BPH_mass_spring_add_block(data, i, k);
+
+ world_to_root_v3(data, j, goal, target);
+
+ spring_angbend_forces(data, i, j, k, goal, stiffness, damping, k, vecnull, vecnull, fk);
+ negate_v3_v3(fj, fk); /* counterforce */
+
+ spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, i, dfk_dxi);
+ spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, j, dfk_dxj);
+ spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, k, dfk_dxk);
+ copy_m3_m3(dfj_dxi, dfk_dxi); negate_m3(dfj_dxi);
+ copy_m3_m3(dfj_dxj, dfk_dxj); negate_m3(dfj_dxj);
+
+ spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, i, dfk_dvi);
+ spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, j, dfk_dvj);
+ spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, k, dfk_dvk);
+ copy_m3_m3(dfj_dvi, dfk_dvi); negate_m3(dfj_dvi);
+ copy_m3_m3(dfj_dvj, dfk_dvj); negate_m3(dfj_dvj);
+
+ /* add forces and jacobians to the solver data */
+
+ add_v3_v3(data->F[j], fj);
+ add_v3_v3(data->F[k], fk);
+
+ add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfj_dxj);
+ add_m3_m3m3(data->dFdX[k].m, data->dFdX[k].m, dfk_dxk);
+
+ add_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfj_dxi);
+ add_m3_m3m3(data->dFdX[block_jk].m, data->dFdX[block_jk].m, dfk_dxj);
+ add_m3_m3m3(data->dFdX[block_ik].m, data->dFdX[block_ik].m, dfk_dxi);
+
+ add_m3_m3m3(data->dFdV[j].m, data->dFdV[j].m, dfj_dvj);
+ add_m3_m3m3(data->dFdV[k].m, data->dFdV[k].m, dfk_dvk);
+
+ add_m3_m3m3(data->dFdV[block_ij].m, data->dFdV[block_ij].m, dfj_dvi);
+ add_m3_m3m3(data->dFdV[block_jk].m, data->dFdV[block_jk].m, dfk_dvj);
+ add_m3_m3m3(data->dFdV[block_ik].m, data->dFdV[block_ik].m, dfk_dvi);
+
+
+ /* XXX analytical calculation of derivatives below is incorrect.
+ * This proved to be difficult, but for now just using the finite difference method for
+ * estimating the jacobians should be sufficient.
+ */
+#if 0
+ float edge_ij[3], dir_ij[3], grad_dir_ij[3][3];
+ float edge_jk[3], dir_jk[3], grad_dir_jk[3][3];
+ float dist[3], vel_jk[3], vel_jk_ortho[3], projvel[3];
+ float target[3];
+ float tmp[3][3];
+ float fi[3], fj[3], fk[3];
+ float dfi_dxi[3][3], dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
+ float dfdvi[3][3];
+
+ // TESTING
+ damping = 0.0f;
+
+ zero_v3(fi);
+ zero_v3(fj);
+ zero_v3(fk);
+ zero_m3(dfi_dxi);
+ zero_m3(dfj_dxi);
+ zero_m3(dfk_dxi);
+ zero_m3(dfk_dxj);
+ zero_m3(dfk_dxk);
+
+ /* jacobian of direction vectors */
+ spring_grad_dir(data, i, j, edge_ij, dir_ij, grad_dir_ij);
+ spring_grad_dir(data, j, k, edge_jk, dir_jk, grad_dir_jk);
+
+ sub_v3_v3v3(vel_jk, data->V[k], data->V[j]);
+
+ /* bending force */
+ mul_v3_v3fl(target, dir_ij, restlen);
+ sub_v3_v3v3(dist, target, edge_jk);
+ mul_v3_v3fl(fk, dist, stiffness);
+
+ /* damping force */
+ madd_v3_v3v3fl(vel_jk_ortho, vel_jk, dir_jk, -dot_v3v3(vel_jk, dir_jk));
+ madd_v3_v3fl(fk, vel_jk_ortho, damping);
+
+ /* XXX this only holds true as long as we assume straight rest shape!
+ * eventually will become a bit more involved since the opposite segment
+ * gets its own target, under condition of having equal torque on both sides.
+ */
+ copy_v3_v3(fi, fk);
+
+ /* counterforce on the middle point */
+ sub_v3_v3(fj, fi);
+ sub_v3_v3(fj, fk);
+
+ /* === derivatives === */
+
+ madd_m3_m3fl(dfk_dxi, grad_dir_ij, stiffness * restlen);
+
+ madd_m3_m3fl(dfk_dxj, grad_dir_ij, -stiffness * restlen);
+ madd_m3_m3fl(dfk_dxj, I, stiffness);
+
+ madd_m3_m3fl(dfk_dxk, I, -stiffness);
+
+ copy_m3_m3(dfi_dxi, dfk_dxk);
+ negate_m3(dfi_dxi);
+
+ /* dfj_dfi == dfi_dfj due to symmetry,
+ * dfi_dfj == dfk_dfj due to fi == fk
+ * XXX see comment above on future bent rest shapes
+ */
+ copy_m3_m3(dfj_dxi, dfk_dxj);
+
+ /* dfj_dxj == -(dfi_dxj + dfk_dxj) due to fj == -(fi + fk) */
+ sub_m3_m3m3(dfj_dxj, dfj_dxj, dfj_dxi);
+ sub_m3_m3m3(dfj_dxj, dfj_dxj, dfk_dxj);
+
+ /* add forces and jacobians to the solver data */
+ add_v3_v3(data->F[i], fi);
+ add_v3_v3(data->F[j], fj);
+ add_v3_v3(data->F[k], fk);
+
+ add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfi_dxi);
+ add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfj_dxj);
+ add_m3_m3m3(data->dFdX[k].m, data->dFdX[k].m, dfk_dxk);
+
+ add_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfj_dxi);
+ add_m3_m3m3(data->dFdX[block_jk].m, data->dFdX[block_jk].m, dfk_dxj);
+ add_m3_m3m3(data->dFdX[block_ik].m, data->dFdX[block_ik].m, dfk_dxi);
+#endif
+
+ return true;
+}
+
+bool BPH_mass_spring_force_spring_goal(Implicit_Data *data, int i, const float goal_x[3], const float goal_v[3],
+ float stiffness, float damping,
+ float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3])
+{
+ float root_goal_x[3], root_goal_v[3], extent[3], length, dir[3], vel[3];
+ float f[3], dfdx[3][3], dfdv[3][3];
+
+ /* goal is in world space */
+ world_to_root_v3(data, i, root_goal_x, goal_x);
+ world_to_root_v3(data, i, root_goal_v, goal_v);
+
+ sub_v3_v3v3(extent, root_goal_x, data->X[i]);
+ sub_v3_v3v3(vel, root_goal_v, data->V[i]);
+ length = normalize_v3_v3(dir, extent);
+
+ if (length > ALMOST_ZERO) {
+ mul_v3_v3fl(f, dir, stiffness * length);
+
+ // Ascher & Boxman, p.21: Damping only during elonglation
+ // something wrong with it...
+ madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir));
+
+ dfdx_spring(dfdx, dir, length, 0.0f, stiffness);
+ dfdv_damp(dfdv, dir, damping);
+
+ add_v3_v3(data->F[i], f);
+ add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfdx);
+ add_m3_m3m3(data->dFdV[i].m, data->dFdV[i].m, dfdv);
+
+ if (r_f) copy_v3_v3(r_f, f);
+ if (r_dfdx) copy_m3_m3(r_dfdx, dfdx);
+ if (r_dfdv) copy_m3_m3(r_dfdv, dfdv);
+
+ return true;
+ }
+ else {
+ if (r_f) zero_v3(r_f);
+ if (r_dfdx) zero_m3(r_dfdx);
+ if (r_dfdv) zero_m3(r_dfdv);
+
+ return false;
+ }
+}
+
+#endif /* IMPLICIT_SOLVER_BLENDER */
diff --git a/source/blender/physics/intern/implicit_eigen.cpp b/source/blender/physics/intern/implicit_eigen.cpp
new file mode 100644
index 00000000000..0ea8ccb0a49
--- /dev/null
+++ b/source/blender/physics/intern/implicit_eigen.cpp
@@ -0,0 +1,1369 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/physics/intern/implicit_eigen.cpp
+ * \ingroup bph
+ */
+
+#include "implicit.h"
+
+#ifdef IMPLICIT_SOLVER_EIGEN
+
+//#define USE_EIGEN_CORE
+#define USE_EIGEN_CONSTRAINED_CG
+
+#ifdef __GNUC__
+# pragma GCC diagnostic push
+/* XXX suppress verbose warnings in eigen */
+# pragma GCC diagnostic ignored "-Wlogical-op"
+#endif
+
+#ifndef IMPLICIT_ENABLE_EIGEN_DEBUG
+#ifdef NDEBUG
+#define IMPLICIT_NDEBUG
+#endif
+#define NDEBUG
+#endif
+
+#include <Eigen/Sparse>
+#include <Eigen/src/Core/util/DisableStupidWarnings.h>
+
+#ifdef USE_EIGEN_CONSTRAINED_CG
+#include <intern/ConstrainedConjugateGradient.h>
+#endif
+
+#ifndef IMPLICIT_ENABLE_EIGEN_DEBUG
+#ifndef IMPLICIT_NDEBUG
+#undef NDEBUG
+#else
+#undef IMPLICIT_NDEBUG
+#endif
+#endif
+
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
+#include "MEM_guardedalloc.h"
+
+extern "C" {
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_texture_types.h"
+
+#include "BLI_math.h"
+#include "BLI_linklist.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_cloth.h"
+#include "BKE_collision.h"
+#include "BKE_effect.h"
+#include "BKE_global.h"
+
+#include "BPH_mass_spring.h"
+}
+
+typedef float Scalar;
+
+static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
+static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
+
+/* slightly extended Eigen vector class
+ * with conversion to/from plain C float array
+ */
+class fVector : public Eigen::Vector3f {
+public:
+ typedef float *ctype;
+
+ fVector()
+ {
+ }
+
+ fVector(const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ coeffRef(k) = v[k];
+ }
+
+ fVector& operator = (const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ coeffRef(k) = v[k];
+ return *this;
+ }
+
+ operator ctype()
+ {
+ return data();
+ }
+};
+
+/* slightly extended Eigen matrix class
+ * with conversion to/from plain C float array
+ */
+class fMatrix : public Eigen::Matrix3f {
+public:
+ typedef float (*ctype)[3];
+
+ fMatrix()
+ {
+ }
+
+ fMatrix(const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ coeffRef(l, k) = v[k][l];
+ }
+
+ fMatrix& operator = (const ctype &v)
+ {
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ coeffRef(l, k) = v[k][l];
+ return *this;
+ }
+
+ operator ctype()
+ {
+ return (ctype)data();
+ }
+};
+
+/* Extension of dense Eigen vectors,
+ * providing 3-float block access for blenlib math functions
+ */
+class lVector : public Eigen::VectorXf {
+public:
+ typedef Eigen::VectorXf base_t;
+
+ lVector()
+ {
+ }
+
+ template <typename T>
+ lVector& operator = (T rhs)
+ {
+ base_t::operator=(rhs);
+ return *this;
+ }
+
+ float* v3(int vertex)
+ {
+ return &coeffRef(3 * vertex);
+ }
+
+ const float* v3(int vertex) const
+ {
+ return &coeffRef(3 * vertex);
+ }
+};
+
+typedef Eigen::Triplet<Scalar> Triplet;
+typedef std::vector<Triplet> TripletList;
+
+typedef Eigen::SparseMatrix<Scalar> lMatrix;
+
+/* Constructor type that provides more convenient handling of Eigen triplets
+ * for efficient construction of sparse 3x3 block matrices.
+ * This should be used for building lMatrix instead of writing to such lMatrix directly (which is very inefficient).
+ * After all elements have been defined using the set() method, the actual matrix can be filled using construct().
+ */
+struct lMatrixCtor {
+ lMatrixCtor()
+ {
+ }
+
+ void reset()
+ {
+ m_trips.clear();
+ }
+
+ void reserve(int numverts)
+ {
+ /* reserve for diagonal entries */
+ m_trips.reserve(numverts * 9);
+ }
+
+ void add(int i, int j, const fMatrix &m)
+ {
+ i *= 3;
+ j *= 3;
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ m_trips.push_back(Triplet(i + k, j + l, m.coeff(l, k)));
+ }
+
+ void sub(int i, int j, const fMatrix &m)
+ {
+ i *= 3;
+ j *= 3;
+ for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
+ m_trips.push_back(Triplet(i + k, j + l, -m.coeff(l, k)));
+ }
+
+ inline void construct(lMatrix &m)
+ {
+ m.setFromTriplets(m_trips.begin(), m_trips.end());
+ m_trips.clear();
+ }
+
+private:
+ TripletList m_trips;
+};
+
+#ifdef USE_EIGEN_CORE
+typedef Eigen::ConjugateGradient<lMatrix, Eigen::Lower, Eigen::DiagonalPreconditioner<Scalar> > ConjugateGradient;
+#endif
+#ifdef USE_EIGEN_CONSTRAINED_CG
+typedef Eigen::ConstrainedConjugateGradient<lMatrix, Eigen::Lower, lMatrix,
+ Eigen::DiagonalPreconditioner<Scalar> >
+ ConstraintConjGrad;
+#endif
+using Eigen::ComputationInfo;
+
+static void print_lvector(const lVector &v)
+{
+ for (int i = 0; i < v.rows(); ++i) {
+ if (i > 0 && i % 3 == 0)
+ printf("\n");
+
+ printf("%f,\n", v[i]);
+ }
+}
+
+static void print_lmatrix(const lMatrix &m)
+{
+ for (int j = 0; j < m.rows(); ++j) {
+ if (j > 0 && j % 3 == 0)
+ printf("\n");
+
+ for (int i = 0; i < m.cols(); ++i) {
+ if (i > 0 && i % 3 == 0)
+ printf(" ");
+
+ implicit_print_matrix_elem(m.coeff(j, i));
+ }
+ printf("\n");
+ }
+}
+
+BLI_INLINE void lMatrix_reserve_elems(lMatrix &m, int num)
+{
+ m.reserve(Eigen::VectorXi::Constant(m.cols(), num));
+}
+
+BLI_INLINE float *lVector_v3(lVector &v, int vertex)
+{
+ return v.data() + 3 * vertex;
+}
+
+BLI_INLINE const float *lVector_v3(const lVector &v, int vertex)
+{
+ return v.data() + 3 * vertex;
+}
+
+#if 0
+BLI_INLINE void triplets_m3(TripletList &tlist, float m[3][3], int i, int j)
+{
+ i *= 3;
+ j *= 3;
+ for (int l = 0; l < 3; ++l) {
+ for (int k = 0; k < 3; ++k) {
+ tlist.push_back(Triplet(i + k, j + l, m[k][l]));
+ }
+ }
+}
+
+BLI_INLINE void triplets_m3fl(TripletList &tlist, float m[3][3], int i, int j, float factor)
+{
+ i *= 3;
+ j *= 3;
+ for (int l = 0; l < 3; ++l) {
+ for (int k = 0; k < 3; ++k) {
+ tlist.push_back(Triplet(i + k, j + l, m[k][l] * factor));
+ }
+ }
+}
+
+BLI_INLINE void lMatrix_add_triplets(lMatrix &r, const TripletList &tlist)
+{
+ lMatrix t(r.rows(), r.cols());
+ t.setFromTriplets(tlist.begin(), tlist.end());
+ r += t;
+}
+
+BLI_INLINE void lMatrix_madd_triplets(lMatrix &r, const TripletList &tlist, float f)
+{
+ lMatrix t(r.rows(), r.cols());
+ t.setFromTriplets(tlist.begin(), tlist.end());
+ r += f * t;
+}
+
+BLI_INLINE void lMatrix_sub_triplets(lMatrix &r, const TripletList &tlist)
+{
+ lMatrix t(r.rows(), r.cols());
+ t.setFromTriplets(tlist.begin(), tlist.end());
+ r -= t;
+}
+#endif
+
+BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3])
+{
+ mul_v3_v3fl(r[0], a, b[0]);
+ mul_v3_v3fl(r[1], a, b[1]);
+ mul_v3_v3fl(r[2], a, b[2]);
+}
+
+BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], float m[3][3])
+{
+ cross_v3_v3v3(r[0], v, m[0]);
+ cross_v3_v3v3(r[1], v, m[1]);
+ cross_v3_v3v3(r[2], v, m[2]);
+}
+
+BLI_INLINE void cross_v3_identity(float r[3][3], const float v[3])
+{
+ r[0][0] = 0.0f; r[1][0] = v[2]; r[2][0] = -v[1];
+ r[0][1] = -v[2]; r[1][1] = 0.0f; r[2][1] = v[0];
+ r[0][2] = v[1]; r[1][2] = -v[0]; r[2][2] = 0.0f;
+}
+
+BLI_INLINE void madd_m3_m3fl(float r[3][3], float m[3][3], float f)
+{
+ r[0][0] += m[0][0] * f;
+ r[0][1] += m[0][1] * f;
+ r[0][2] += m[0][2] * f;
+ r[1][0] += m[1][0] * f;
+ r[1][1] += m[1][1] * f;
+ r[1][2] += m[1][2] * f;
+ r[2][0] += m[2][0] * f;
+ r[2][1] += m[2][1] * f;
+ r[2][2] += m[2][2] * f;
+}
+
+BLI_INLINE void madd_m3_m3m3fl(float r[3][3], float a[3][3], float b[3][3], float f)
+{
+ r[0][0] = a[0][0] + b[0][0] * f;
+ r[0][1] = a[0][1] + b[0][1] * f;
+ r[0][2] = a[0][2] + b[0][2] * f;
+ r[1][0] = a[1][0] + b[1][0] * f;
+ r[1][1] = a[1][1] + b[1][1] * f;
+ r[1][2] = a[1][2] + b[1][2] * f;
+ r[2][0] = a[2][0] + b[2][0] * f;
+ r[2][1] = a[2][1] + b[2][1] * f;
+ r[2][2] = a[2][2] + b[2][2] * f;
+}
+
+struct Implicit_Data {
+ typedef std::vector<fMatrix> fMatrixVector;
+
+ Implicit_Data(int numverts)
+ {
+ resize(numverts);
+ }
+
+ void resize(int numverts)
+ {
+ this->numverts = numverts;
+ int tot = 3 * numverts;
+
+ M.resize(tot, tot);
+ F.resize(tot);
+ dFdX.resize(tot, tot);
+ dFdV.resize(tot, tot);
+
+ tfm.resize(numverts, I);
+
+ X.resize(tot);
+ Xnew.resize(tot);
+ V.resize(tot);
+ Vnew.resize(tot);
+
+ A.resize(tot, tot);
+ B.resize(tot);
+
+ dV.resize(tot);
+ z.resize(tot);
+ S.resize(tot, tot);
+
+ iM.reserve(numverts);
+ idFdX.reserve(numverts);
+ idFdV.reserve(numverts);
+ iS.reserve(numverts);
+ }
+
+ int numverts;
+
+ /* inputs */
+ lMatrix M; /* masses */
+ lVector F; /* forces */
+ lMatrix dFdX, dFdV; /* force jacobians */
+
+ fMatrixVector tfm; /* local coordinate transform */
+
+ /* motion state data */
+ lVector X, Xnew; /* positions */
+ lVector V, Vnew; /* velocities */
+
+ /* internal solver data */
+ lVector B; /* B for A*dV = B */
+ lMatrix A; /* A for A*dV = B */
+
+ lVector dV; /* velocity change (solution of A*dV = B) */
+ lVector z; /* target velocity in constrained directions */
+ lMatrix S; /* filtering matrix for constraints */
+
+ /* temporary constructors */
+ lMatrixCtor iM; /* masses */
+ lMatrixCtor idFdX, idFdV; /* force jacobians */
+ lMatrixCtor iS; /* filtering matrix for constraints */
+};
+
+Implicit_Data *BPH_mass_spring_solver_create(int numverts, int numsprings)
+{
+ Implicit_Data *id = new Implicit_Data(numverts);
+ return id;
+}
+
+void BPH_mass_spring_solver_free(Implicit_Data *id)
+{
+ if (id)
+ delete id;
+}
+
+int BPH_mass_spring_solver_numvert(Implicit_Data *id)
+{
+ if (id)
+ return id->numverts;
+ else
+ return 0;
+}
+
+/* ==== Transformation from/to root reference frames ==== */
+
+BLI_INLINE void world_to_root_v3(Implicit_Data *data, int index, float r[3], const float v[3])
+{
+ copy_v3_v3(r, v);
+ mul_transposed_m3_v3(data->tfm[index], r);
+}
+
+BLI_INLINE void root_to_world_v3(Implicit_Data *data, int index, float r[3], const float v[3])
+{
+ mul_v3_m3v3(r, data->tfm[index], v);
+}
+
+BLI_INLINE void world_to_root_m3(Implicit_Data *data, int index, float r[3][3], float m[3][3])
+{
+ float trot[3][3];
+ copy_m3_m3(trot, data->tfm[index]);
+ transpose_m3(trot);
+ mul_m3_m3m3(r, trot, m);
+}
+
+BLI_INLINE void root_to_world_m3(Implicit_Data *data, int index, float r[3][3], float m[3][3])
+{
+ mul_m3_m3m3(r, data->tfm[index], m);
+}
+
+/* ================================ */
+
+bool BPH_mass_spring_solve_velocities(Implicit_Data *data, float dt, ImplicitSolverResult *result)
+{
+#ifdef USE_EIGEN_CORE
+ typedef ConjugateGradient solver_t;
+#endif
+#ifdef USE_EIGEN_CONSTRAINED_CG
+ typedef ConstraintConjGrad solver_t;
+#endif
+
+ data->iM.construct(data->M);
+ data->idFdX.construct(data->dFdX);
+ data->idFdV.construct(data->dFdV);
+ data->iS.construct(data->S);
+
+ solver_t cg;
+ cg.setMaxIterations(100);
+ cg.setTolerance(0.01f);
+
+#ifdef USE_EIGEN_CONSTRAINED_CG
+ cg.filter() = data->S;
+#endif
+
+ data->A = data->M - dt * data->dFdV - dt*dt * data->dFdX;
+ cg.compute(data->A);
+
+ data->B = dt * data->F + dt*dt * data->dFdX * data->V;
+
+#ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
+ printf("==== A ====\n");
+ print_lmatrix(id->A);
+ printf("==== z ====\n");
+ print_lvector(id->z);
+ printf("==== B ====\n");
+ print_lvector(id->B);
+ printf("==== S ====\n");
+ print_lmatrix(id->S);
+#endif
+
+#ifdef USE_EIGEN_CORE
+ data->dV = cg.solve(data->B);
+#endif
+#ifdef USE_EIGEN_CONSTRAINED_CG
+ data->dV = cg.solveWithGuess(data->B, data->z);
+#endif
+
+#ifdef IMPLICIT_PRINT_SOLVER_INPUT_OUTPUT
+ printf("==== dV ====\n");
+ print_lvector(id->dV);
+ printf("========\n");
+#endif
+
+ data->Vnew = data->V + data->dV;
+
+ switch (cg.info()) {
+ case Eigen::Success: result->status = BPH_SOLVER_SUCCESS; break;
+ case Eigen::NoConvergence: result->status = BPH_SOLVER_NO_CONVERGENCE; break;
+ case Eigen::InvalidInput: result->status = BPH_SOLVER_INVALID_INPUT; break;
+ case Eigen::NumericalIssue: result->status = BPH_SOLVER_NUMERICAL_ISSUE; break;
+ }
+
+ result->iterations = cg.iterations();
+ result->error = cg.error();
+
+ return cg.info() == Eigen::Success;
+}
+
+bool BPH_mass_spring_solve_positions(Implicit_Data *data, float dt)
+{
+ data->Xnew = data->X + data->Vnew * dt;
+ return true;
+}
+
+/* ================================ */
+
+void BPH_mass_spring_apply_result(Implicit_Data *data)
+{
+ data->X = data->Xnew;
+ data->V = data->Vnew;
+}
+
+void BPH_mass_spring_set_vertex_mass(Implicit_Data *data, int index, float mass)
+{
+ float m[3][3];
+ copy_m3_m3(m, I);
+ mul_m3_fl(m, mass);
+ data->iM.add(index, index, m);
+}
+
+void BPH_mass_spring_set_rest_transform(Implicit_Data *data, int index, float tfm[3][3])
+{
+#ifdef CLOTH_ROOT_FRAME
+ copy_m3_m3(data->tfm[index], tfm);
+#else
+ unit_m3(data->tfm[index]);
+ (void)tfm;
+#endif
+}
+
+void BPH_mass_spring_set_motion_state(Implicit_Data *data, int index, const float x[3], const float v[3])
+{
+ world_to_root_v3(data, index, data->X.v3(index), x);
+ world_to_root_v3(data, index, data->V.v3(index), v);
+}
+
+void BPH_mass_spring_set_position(Implicit_Data *data, int index, const float x[3])
+{
+ world_to_root_v3(data, index, data->X.v3(index), x);
+}
+
+void BPH_mass_spring_set_velocity(Implicit_Data *data, int index, const float v[3])
+{
+ world_to_root_v3(data, index, data->V.v3(index), v);
+}
+
+void BPH_mass_spring_get_motion_state(struct Implicit_Data *data, int index, float x[3], float v[3])
+{
+ if (x) root_to_world_v3(data, index, x, data->X.v3(index));
+ if (v) root_to_world_v3(data, index, v, data->V.v3(index));
+}
+
+void BPH_mass_spring_get_position(struct Implicit_Data *data, int index, float x[3])
+{
+ root_to_world_v3(data, index, x, data->X.v3(index));
+}
+
+void BPH_mass_spring_get_new_velocity(Implicit_Data *data, int index, float v[3])
+{
+ root_to_world_v3(data, index, v, data->V.v3(index));
+}
+
+void BPH_mass_spring_set_new_velocity(Implicit_Data *data, int index, const float v[3])
+{
+ world_to_root_v3(data, index, data->V.v3(index), v);
+}
+
+void BPH_mass_spring_clear_constraints(Implicit_Data *data)
+{
+ int numverts = data->numverts;
+ for (int i = 0; i < numverts; ++i) {
+ data->iS.add(i, i, I);
+ zero_v3(data->z.v3(i));
+ }
+}
+
+void BPH_mass_spring_add_constraint_ndof0(Implicit_Data *data, int index, const float dV[3])
+{
+ data->iS.sub(index, index, I);
+
+ world_to_root_v3(data, index, data->z.v3(index), dV);
+}
+
+void BPH_mass_spring_add_constraint_ndof1(Implicit_Data *data, int index, const float c1[3], const float c2[3], const float dV[3])
+{
+ float m[3][3], p[3], q[3], u[3], cmat[3][3];
+
+ world_to_root_v3(data, index, p, c1);
+ outerproduct(cmat, p, p);
+ copy_m3_m3(m, cmat);
+
+ world_to_root_v3(data, index, q, c2);
+ outerproduct(cmat, q, q);
+ add_m3_m3m3(m, m, cmat);
+
+ /* XXX not sure but multiplication should work here */
+ data->iS.sub(index, index, m);
+// mul_m3_m3m3(data->S[index].m, data->S[index].m, m);
+
+ world_to_root_v3(data, index, u, dV);
+ add_v3_v3(data->z.v3(index), u);
+}
+
+void BPH_mass_spring_add_constraint_ndof2(Implicit_Data *data, int index, const float c1[3], const float dV[3])
+{
+ float m[3][3], p[3], u[3], cmat[3][3];
+
+ world_to_root_v3(data, index, p, c1);
+ outerproduct(cmat, p, p);
+ copy_m3_m3(m, cmat);
+
+ data->iS.sub(index, index, m);
+// mul_m3_m3m3(data->S[index].m, data->S[index].m, m);
+
+ world_to_root_v3(data, index, u, dV);
+ add_v3_v3(data->z.v3(index), u);
+}
+
+void BPH_mass_spring_clear_forces(Implicit_Data *data)
+{
+ data->F.setZero();
+ data->dFdX.setZero();
+ data->dFdV.setZero();
+}
+
+void BPH_mass_spring_force_reference_frame(Implicit_Data *data, int index, const float acceleration[3], const float omega[3], const float domega_dt[3], float mass)
+{
+#ifdef CLOTH_ROOT_FRAME
+ float acc[3], w[3], dwdt[3];
+ float f[3], dfdx[3][3], dfdv[3][3];
+ float euler[3], coriolis[3], centrifugal[3], rotvel[3];
+ float deuler[3][3], dcoriolis[3][3], dcentrifugal[3][3], drotvel[3][3];
+
+ world_to_root_v3(data, index, acc, acceleration);
+ world_to_root_v3(data, index, w, omega);
+ world_to_root_v3(data, index, dwdt, domega_dt);
+
+ cross_v3_v3v3(euler, dwdt, data->X.v3(index));
+ cross_v3_v3v3(coriolis, w, data->V.v3(index));
+ mul_v3_fl(coriolis, 2.0f);
+ cross_v3_v3v3(rotvel, w, data->X.v3(index));
+ cross_v3_v3v3(centrifugal, w, rotvel);
+
+ sub_v3_v3v3(f, acc, euler);
+ sub_v3_v3(f, coriolis);
+ sub_v3_v3(f, centrifugal);
+
+ mul_v3_fl(f, mass); /* F = m * a */
+
+ cross_v3_identity(deuler, dwdt);
+ cross_v3_identity(dcoriolis, w);
+ mul_m3_fl(dcoriolis, 2.0f);
+ cross_v3_identity(drotvel, w);
+ cross_m3_v3m3(dcentrifugal, w, drotvel);
+
+ add_m3_m3m3(dfdx, deuler, dcentrifugal);
+ negate_m3(dfdx);
+ mul_m3_fl(dfdx, mass);
+
+ copy_m3_m3(dfdv, dcoriolis);
+ negate_m3(dfdv);
+ mul_m3_fl(dfdv, mass);
+
+ add_v3_v3(data->F.v3(index), f);
+ data->idFdX.add(index, index, dfdx);
+ data->idFdV.add(index, index, dfdv);
+#else
+ (void)data;
+ (void)index;
+ (void)acceleration;
+ (void)omega;
+ (void)domega_dt;
+#endif
+}
+
+void BPH_mass_spring_force_gravity(Implicit_Data *data, int index, float mass, const float g[3])
+{
+ /* force = mass * acceleration (in this case: gravity) */
+ float f[3];
+ world_to_root_v3(data, index, f, g);
+ mul_v3_fl(f, mass);
+
+ add_v3_v3(data->F.v3(index), f);
+}
+
+void BPH_mass_spring_force_drag(Implicit_Data *data, float drag)
+{
+ int numverts = data->numverts;
+ for (int i = 0; i < numverts; i++) {
+ float tmp[3][3];
+
+ /* NB: uses root space velocity, no need to transform */
+ madd_v3_v3fl(data->F.v3(i), data->V.v3(i), -drag);
+
+ copy_m3_m3(tmp, I);
+ mul_m3_fl(tmp, -drag);
+ data->idFdV.add(i, i, tmp);
+ }
+}
+
+void BPH_mass_spring_force_extern(struct Implicit_Data *data, int i, const float f[3], float dfdx[3][3], float dfdv[3][3])
+{
+ float tf[3], tdfdx[3][3], tdfdv[3][3];
+ world_to_root_v3(data, i, tf, f);
+ world_to_root_m3(data, i, tdfdx, dfdx);
+ world_to_root_m3(data, i, tdfdv, dfdv);
+
+ add_v3_v3(data->F.v3(i), tf);
+ data->idFdX.add(i, i, tdfdx);
+ data->idFdV.add(i, i, tdfdv);
+}
+
+static float calc_nor_area_tri(float nor[3], const float v1[3], const float v2[3], const float v3[3])
+{
+ float n1[3], n2[3];
+
+ sub_v3_v3v3(n1, v1, v2);
+ sub_v3_v3v3(n2, v2, v3);
+
+ cross_v3_v3v3(nor, n1, n2);
+ return normalize_v3(nor);
+}
+
+static float calc_nor_area_quad(float nor[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+{
+ float n1[3], n2[3];
+
+ sub_v3_v3v3(n1, v1, v3);
+ sub_v3_v3v3(n2, v2, v4);
+
+ cross_v3_v3v3(nor, n1, n2);
+ return normalize_v3(nor);
+}
+
+/* XXX does not support force jacobians yet, since the effector system does not provide them either */
+void BPH_mass_spring_force_face_wind(Implicit_Data *data, int v1, int v2, int v3, int v4, const float (*winvec)[3])
+{
+ const float effector_scale = 0.02f;
+ float win[3], nor[3], area;
+ float factor;
+
+ // calculate face normal and area
+ if (v4) {
+ area = calc_nor_area_quad(nor, data->X.v3(v1), data->X.v3(v2), data->X.v3(v3), data->X.v3(v4));
+ factor = effector_scale * area * 0.25f;
+ }
+ else {
+ area = calc_nor_area_tri(nor, data->X.v3(v1), data->X.v3(v2), data->X.v3(v3));
+ factor = effector_scale * area / 3.0f;
+ }
+
+ world_to_root_v3(data, v1, win, winvec[v1]);
+ madd_v3_v3fl(data->F.v3(v1), nor, factor * dot_v3v3(win, nor));
+
+ world_to_root_v3(data, v2, win, winvec[v2]);
+ madd_v3_v3fl(data->F.v3(v2), nor, factor * dot_v3v3(win, nor));
+
+ world_to_root_v3(data, v3, win, winvec[v3]);
+ madd_v3_v3fl(data->F.v3(v3), nor, factor * dot_v3v3(win, nor));
+
+ if (v4) {
+ world_to_root_v3(data, v4, win, winvec[v4]);
+ madd_v3_v3fl(data->F.v3(v4), nor, factor * dot_v3v3(win, nor));
+ }
+}
+
+void BPH_mass_spring_force_edge_wind(Implicit_Data *data, int v1, int v2, const float (*winvec)[3])
+{
+ const float effector_scale = 0.01;
+ float win[3], dir[3], nor[3], length;
+
+ sub_v3_v3v3(dir, data->X.v3(v1), data->X.v3(v2));
+ length = normalize_v3(dir);
+
+ world_to_root_v3(data, v1, win, winvec[v1]);
+ madd_v3_v3v3fl(nor, win, dir, -dot_v3v3(win, dir));
+ madd_v3_v3fl(data->F.v3(v1), nor, effector_scale * length);
+
+ world_to_root_v3(data, v2, win, winvec[v2]);
+ madd_v3_v3v3fl(nor, win, dir, -dot_v3v3(win, dir));
+ madd_v3_v3fl(data->F.v3(v2), nor, effector_scale * length);
+}
+
+BLI_INLINE void dfdx_spring(float to[3][3], const float dir[3], float length, float L, float k)
+{
+ // dir is unit length direction, rest is spring's restlength, k is spring constant.
+ //return ( (I-outerprod(dir, dir))*Min(1.0f, rest/length) - I) * -k;
+ outerproduct(to, dir, dir);
+ sub_m3_m3m3(to, I, to);
+
+ mul_m3_fl(to, (L/length));
+ sub_m3_m3m3(to, to, I);
+ mul_m3_fl(to, k);
+}
+
+/* unused */
+#if 0
+BLI_INLINE void dfdx_damp(float to[3][3], const float dir[3], float length, const float vel[3], float rest, float damping)
+{
+ // inner spring damping vel is the relative velocity of the endpoints.
+ // return (I-outerprod(dir, dir)) * (-damping * -(dot(dir, vel)/Max(length, rest)));
+ mul_fvectorT_fvector(to, dir, dir);
+ sub_fmatrix_fmatrix(to, I, to);
+ mul_fmatrix_S(to, (-damping * -(dot_v3v3(dir, vel)/MAX2(length, rest))));
+}
+#endif
+
+BLI_INLINE void dfdv_damp(float to[3][3], const float dir[3], float damping)
+{
+ // derivative of force wrt velocity
+ outerproduct(to, dir, dir);
+ mul_m3_fl(to, -damping);
+}
+
+BLI_INLINE float fb(float length, float L)
+{
+ float x = length / L;
+ return (-11.541f * powf(x, 4) + 34.193f * powf(x, 3) - 39.083f * powf(x, 2) + 23.116f * x - 9.713f);
+}
+
+BLI_INLINE float fbderiv(float length, float L)
+{
+ float x = length/L;
+
+ return (-46.164f * powf(x, 3) + 102.579f * powf(x, 2) - 78.166f * x + 23.116f);
+}
+
+BLI_INLINE float fbstar(float length, float L, float kb, float cb)
+{
+ float tempfb_fl = kb * fb(length, L);
+ float fbstar_fl = cb * (length - L);
+
+ if (tempfb_fl < fbstar_fl)
+ return fbstar_fl;
+ else
+ return tempfb_fl;
+}
+
+// function to calculae bending spring force (taken from Choi & Co)
+BLI_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
+{
+ float tempfb_fl = kb * fb(length, L);
+ float fbstar_fl = cb * (length - L);
+
+ if (tempfb_fl < fbstar_fl) {
+ return -cb;
+ }
+ else {
+ return -kb * fbderiv(length, L);
+ }
+}
+
+/* calculate elonglation */
+BLI_INLINE bool spring_length(Implicit_Data *data, int i, int j, float r_extent[3], float r_dir[3], float *r_length, float r_vel[3])
+{
+ sub_v3_v3v3(r_extent, data->X.v3(j), data->X.v3(i));
+ sub_v3_v3v3(r_vel, data->V.v3(j), data->V.v3(i));
+ *r_length = len_v3(r_extent);
+
+ if (*r_length > ALMOST_ZERO) {
+ /*
+ if (length>L) {
+ if ((clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED) &&
+ ( ((length-L)*100.0f/L) > clmd->sim_parms->maxspringlen )) {
+ // cut spring!
+ s->flags |= CSPRING_FLAG_DEACTIVATE;
+ return false;
+ }
+ }
+ */
+ mul_v3_v3fl(r_dir, r_extent, 1.0f/(*r_length));
+ }
+ else {
+ zero_v3(r_dir);
+ }
+
+ return true;
+}
+
+BLI_INLINE void apply_spring(Implicit_Data *data, int i, int j, const float f[3], float dfdx[3][3], float dfdv[3][3])
+{
+ add_v3_v3(data->F.v3(i), f);
+ sub_v3_v3(data->F.v3(j), f);
+
+ data->idFdX.add(i, i, dfdx);
+ data->idFdX.add(j, j, dfdx);
+ data->idFdX.sub(i, j, dfdx);
+ data->idFdX.sub(j, i, dfdx);
+
+ data->idFdV.add(i, i, dfdv);
+ data->idFdV.add(j, j, dfdv);
+ data->idFdV.sub(i, j, dfdv);
+ data->idFdV.sub(j, i, dfdv);
+}
+
+bool BPH_mass_spring_force_spring_linear(Implicit_Data *data, int i, int j, float restlen,
+ float stiffness, float damping, bool no_compress, float clamp_force,
+ float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3])
+{
+ float extent[3], length, dir[3], vel[3];
+
+ // calculate elonglation
+ spring_length(data, i, j, extent, dir, &length, vel);
+
+ if (length > restlen || no_compress) {
+ float stretch_force, f[3], dfdx[3][3], dfdv[3][3];
+
+ stretch_force = stiffness * (length - restlen);
+ if (clamp_force > 0.0f && stretch_force > clamp_force) {
+ stretch_force = clamp_force;
+ }
+ mul_v3_v3fl(f, dir, stretch_force);
+
+ // Ascher & Boxman, p.21: Damping only during elonglation
+ // something wrong with it...
+ madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir));
+
+ dfdx_spring(dfdx, dir, length, restlen, stiffness);
+ dfdv_damp(dfdv, dir, damping);
+
+ apply_spring(data, i, j, f, dfdx, dfdv);
+
+ if (r_f) copy_v3_v3(r_f, f);
+ if (r_dfdx) copy_m3_m3(r_dfdx, dfdx);
+ if (r_dfdv) copy_m3_m3(r_dfdv, dfdv);
+
+ return true;
+ }
+ else {
+ if (r_f) zero_v3(r_f);
+ if (r_dfdx) zero_m3(r_dfdx);
+ if (r_dfdv) zero_m3(r_dfdv);
+
+ return false;
+ }
+}
+
+/* See "Stable but Responsive Cloth" (Choi, Ko 2005) */
+bool BPH_mass_spring_force_spring_bending(Implicit_Data *data, int i, int j, float restlen,
+ float kb, float cb,
+ float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3])
+{
+ float extent[3], length, dir[3], vel[3];
+
+ // calculate elonglation
+ spring_length(data, i, j, extent, dir, &length, vel);
+
+ if (length < restlen) {
+ float f[3], dfdx[3][3], dfdv[3][3];
+
+ mul_v3_v3fl(f, dir, fbstar(length, restlen, kb, cb));
+
+ outerproduct(dfdx, dir, dir);
+ mul_m3_fl(dfdx, fbstar_jacobi(length, restlen, kb, cb));
+
+ /* XXX damping not supported */
+ zero_m3(dfdv);
+
+ apply_spring(data, i, j, f, dfdx, dfdv);
+
+ if (r_f) copy_v3_v3(r_f, f);
+ if (r_dfdx) copy_m3_m3(r_dfdx, dfdx);
+ if (r_dfdv) copy_m3_m3(r_dfdv, dfdv);
+
+ return true;
+ }
+ else {
+ if (r_f) zero_v3(r_f);
+ if (r_dfdx) zero_m3(r_dfdx);
+ if (r_dfdv) zero_m3(r_dfdv);
+
+ return false;
+ }
+}
+
+/* Jacobian of a direction vector.
+ * Basically the part of the differential orthogonal to the direction,
+ * inversely proportional to the length of the edge.
+ *
+ * dD_ij/dx_i = -dD_ij/dx_j = (D_ij * D_ij^T - I) / len_ij
+ */
+BLI_INLINE void spring_grad_dir(Implicit_Data *data, int i, int j, float edge[3], float dir[3], float grad_dir[3][3])
+{
+ float length;
+
+ sub_v3_v3v3(edge, data->X.v3(j), data->X.v3(i));
+ length = normalize_v3_v3(dir, edge);
+
+ if (length > ALMOST_ZERO) {
+ outerproduct(grad_dir, dir, dir);
+ sub_m3_m3m3(grad_dir, I, grad_dir);
+ mul_m3_fl(grad_dir, 1.0f / length);
+ }
+ else {
+ zero_m3(grad_dir);
+ }
+}
+
+BLI_INLINE void spring_angbend_forces(Implicit_Data *data, int i, int j, int k,
+ const float goal[3],
+ float stiffness, float damping,
+ int q, const float dx[3], const float dv[3],
+ float r_f[3])
+{
+ float edge_ij[3], dir_ij[3];
+ float edge_jk[3], dir_jk[3];
+ float vel_ij[3], vel_jk[3], vel_ortho[3];
+ float f_bend[3], f_damp[3];
+ float fk[3];
+ float dist[3];
+
+ zero_v3(fk);
+
+ sub_v3_v3v3(edge_ij, data->X.v3(j), data->X.v3(i));
+ if (q == i) sub_v3_v3(edge_ij, dx);
+ if (q == j) add_v3_v3(edge_ij, dx);
+ normalize_v3_v3(dir_ij, edge_ij);
+
+ sub_v3_v3v3(edge_jk, data->X.v3(k), data->X.v3(j));
+ if (q == j) sub_v3_v3(edge_jk, dx);
+ if (q == k) add_v3_v3(edge_jk, dx);
+ normalize_v3_v3(dir_jk, edge_jk);
+
+ sub_v3_v3v3(vel_ij, data->V.v3(j), data->V.v3(i));
+ if (q == i) sub_v3_v3(vel_ij, dv);
+ if (q == j) add_v3_v3(vel_ij, dv);
+
+ sub_v3_v3v3(vel_jk, data->V.v3(k), data->V.v3(j));
+ if (q == j) sub_v3_v3(vel_jk, dv);
+ if (q == k) add_v3_v3(vel_jk, dv);
+
+ /* bending force */
+ sub_v3_v3v3(dist, goal, edge_jk);
+ mul_v3_v3fl(f_bend, dist, stiffness);
+
+ add_v3_v3(fk, f_bend);
+
+ /* damping force */
+ madd_v3_v3v3fl(vel_ortho, vel_jk, dir_jk, -dot_v3v3(vel_jk, dir_jk));
+ mul_v3_v3fl(f_damp, vel_ortho, damping);
+
+ sub_v3_v3(fk, f_damp);
+
+ copy_v3_v3(r_f, fk);
+}
+
+/* Finite Differences method for estimating the jacobian of the force */
+BLI_INLINE void spring_angbend_estimate_dfdx(Implicit_Data *data, int i, int j, int k,
+ const float goal[3],
+ float stiffness, float damping,
+ int q, float dfdx[3][3])
+{
+ const float delta = 0.00001f; // TODO find a good heuristic for this
+ float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
+ float f[3];
+ int a, b;
+
+ zero_m3(dvec_null);
+ unit_m3(dvec_pos);
+ mul_m3_fl(dvec_pos, delta * 0.5f);
+ copy_m3_m3(dvec_neg, dvec_pos);
+ negate_m3(dvec_neg);
+
+ /* XXX TODO offset targets to account for position dependency */
+
+ for (a = 0; a < 3; ++a) {
+ spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
+ q, dvec_pos[a], dvec_null[a], f);
+ copy_v3_v3(dfdx[a], f);
+
+ spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
+ q, dvec_neg[a], dvec_null[a], f);
+ sub_v3_v3(dfdx[a], f);
+
+ for (b = 0; b < 3; ++b) {
+ dfdx[a][b] /= delta;
+ }
+ }
+}
+
+/* Finite Differences method for estimating the jacobian of the force */
+BLI_INLINE void spring_angbend_estimate_dfdv(Implicit_Data *data, int i, int j, int k,
+ const float goal[3],
+ float stiffness, float damping,
+ int q, float dfdv[3][3])
+{
+ const float delta = 0.00001f; // TODO find a good heuristic for this
+ float dvec_null[3][3], dvec_pos[3][3], dvec_neg[3][3];
+ float f[3];
+ int a, b;
+
+ zero_m3(dvec_null);
+ unit_m3(dvec_pos);
+ mul_m3_fl(dvec_pos, delta * 0.5f);
+ copy_m3_m3(dvec_neg, dvec_pos);
+ negate_m3(dvec_neg);
+
+ /* XXX TODO offset targets to account for position dependency */
+
+ for (a = 0; a < 3; ++a) {
+ spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
+ q, dvec_null[a], dvec_pos[a], f);
+ copy_v3_v3(dfdv[a], f);
+
+ spring_angbend_forces(data, i, j, k, goal, stiffness, damping,
+ q, dvec_null[a], dvec_neg[a], f);
+ sub_v3_v3(dfdv[a], f);
+
+ for (b = 0; b < 3; ++b) {
+ dfdv[a][b] /= delta;
+ }
+ }
+}
+
+/* Angular spring that pulls the vertex toward the local target
+ * See "Artistic Simulation of Curly Hair" (Pixar technical memo #12-03a)
+ */
+bool BPH_mass_spring_force_spring_bending_angular(Implicit_Data *data, int i, int j, int k,
+ const float target[3], float stiffness, float damping)
+{
+ float goal[3];
+ float fj[3], fk[3];
+ float dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
+ float dfj_dvi[3][3], dfj_dvj[3][3], dfk_dvi[3][3], dfk_dvj[3][3], dfk_dvk[3][3];
+
+ const float vecnull[3] = {0.0f, 0.0f, 0.0f};
+
+ world_to_root_v3(data, j, goal, target);
+
+ spring_angbend_forces(data, i, j, k, goal, stiffness, damping, k, vecnull, vecnull, fk);
+ negate_v3_v3(fj, fk); /* counterforce */
+
+ spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, i, dfk_dxi);
+ spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, j, dfk_dxj);
+ spring_angbend_estimate_dfdx(data, i, j, k, goal, stiffness, damping, k, dfk_dxk);
+ copy_m3_m3(dfj_dxi, dfk_dxi); negate_m3(dfj_dxi);
+ copy_m3_m3(dfj_dxj, dfk_dxj); negate_m3(dfj_dxj);
+
+ spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, i, dfk_dvi);
+ spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, j, dfk_dvj);
+ spring_angbend_estimate_dfdv(data, i, j, k, goal, stiffness, damping, k, dfk_dvk);
+ copy_m3_m3(dfj_dvi, dfk_dvi); negate_m3(dfj_dvi);
+ copy_m3_m3(dfj_dvj, dfk_dvj); negate_m3(dfj_dvj);
+
+ /* add forces and jacobians to the solver data */
+
+ add_v3_v3(data->F.v3(j), fj);
+ add_v3_v3(data->F.v3(k), fk);
+
+ data->idFdX.add(j, j, dfj_dxj);
+ data->idFdX.add(k, k, dfk_dxk);
+
+ data->idFdX.add(i, j, dfj_dxi);
+ data->idFdX.add(j, i, dfj_dxi);
+ data->idFdX.add(j, k, dfk_dxj);
+ data->idFdX.add(k, j, dfk_dxj);
+ data->idFdX.add(i, k, dfk_dxi);
+ data->idFdX.add(k, i, dfk_dxi);
+
+ data->idFdV.add(j, j, dfj_dvj);
+ data->idFdV.add(k, k, dfk_dvk);
+
+ data->idFdV.add(i, j, dfj_dvi);
+ data->idFdV.add(j, i, dfj_dvi);
+ data->idFdV.add(j, k, dfk_dvj);
+ data->idFdV.add(k, j, dfk_dvj);
+ data->idFdV.add(i, k, dfk_dvi);
+ data->idFdV.add(k, i, dfk_dvi);
+
+ /* XXX analytical calculation of derivatives below is incorrect.
+ * This proved to be difficult, but for now just using the finite difference method for
+ * estimating the jacobians should be sufficient.
+ */
+#if 0
+ float edge_ij[3], dir_ij[3], grad_dir_ij[3][3];
+ float edge_jk[3], dir_jk[3], grad_dir_jk[3][3];
+ float dist[3], vel_jk[3], vel_jk_ortho[3], projvel[3];
+ float target[3];
+ float tmp[3][3];
+ float fi[3], fj[3], fk[3];
+ float dfi_dxi[3][3], dfj_dxi[3][3], dfj_dxj[3][3], dfk_dxi[3][3], dfk_dxj[3][3], dfk_dxk[3][3];
+ float dfdvi[3][3];
+
+ // TESTING
+ damping = 0.0f;
+
+ zero_v3(fi);
+ zero_v3(fj);
+ zero_v3(fk);
+ zero_m3(dfi_dxi);
+ zero_m3(dfj_dxi);
+ zero_m3(dfk_dxi);
+ zero_m3(dfk_dxj);
+ zero_m3(dfk_dxk);
+
+ /* jacobian of direction vectors */
+ spring_grad_dir(data, i, j, edge_ij, dir_ij, grad_dir_ij);
+ spring_grad_dir(data, j, k, edge_jk, dir_jk, grad_dir_jk);
+
+ sub_v3_v3v3(vel_jk, data->V[k], data->V[j]);
+
+ /* bending force */
+ mul_v3_v3fl(target, dir_ij, restlen);
+ sub_v3_v3v3(dist, target, edge_jk);
+ mul_v3_v3fl(fk, dist, stiffness);
+
+ /* damping force */
+ madd_v3_v3v3fl(vel_jk_ortho, vel_jk, dir_jk, -dot_v3v3(vel_jk, dir_jk));
+ madd_v3_v3fl(fk, vel_jk_ortho, damping);
+
+ /* XXX this only holds true as long as we assume straight rest shape!
+ * eventually will become a bit more involved since the opposite segment
+ * gets its own target, under condition of having equal torque on both sides.
+ */
+ copy_v3_v3(fi, fk);
+
+ /* counterforce on the middle point */
+ sub_v3_v3(fj, fi);
+ sub_v3_v3(fj, fk);
+
+ /* === derivatives === */
+
+ madd_m3_m3fl(dfk_dxi, grad_dir_ij, stiffness * restlen);
+
+ madd_m3_m3fl(dfk_dxj, grad_dir_ij, -stiffness * restlen);
+ madd_m3_m3fl(dfk_dxj, I, stiffness);
+
+ madd_m3_m3fl(dfk_dxk, I, -stiffness);
+
+ copy_m3_m3(dfi_dxi, dfk_dxk);
+ negate_m3(dfi_dxi);
+
+ /* dfj_dfi == dfi_dfj due to symmetry,
+ * dfi_dfj == dfk_dfj due to fi == fk
+ * XXX see comment above on future bent rest shapes
+ */
+ copy_m3_m3(dfj_dxi, dfk_dxj);
+
+ /* dfj_dxj == -(dfi_dxj + dfk_dxj) due to fj == -(fi + fk) */
+ sub_m3_m3m3(dfj_dxj, dfj_dxj, dfj_dxi);
+ sub_m3_m3m3(dfj_dxj, dfj_dxj, dfk_dxj);
+
+ /* add forces and jacobians to the solver data */
+ add_v3_v3(data->F[i], fi);
+ add_v3_v3(data->F[j], fj);
+ add_v3_v3(data->F[k], fk);
+
+ add_m3_m3m3(data->dFdX[i].m, data->dFdX[i].m, dfi_dxi);
+ add_m3_m3m3(data->dFdX[j].m, data->dFdX[j].m, dfj_dxj);
+ add_m3_m3m3(data->dFdX[k].m, data->dFdX[k].m, dfk_dxk);
+
+ add_m3_m3m3(data->dFdX[block_ij].m, data->dFdX[block_ij].m, dfj_dxi);
+ add_m3_m3m3(data->dFdX[block_jk].m, data->dFdX[block_jk].m, dfk_dxj);
+ add_m3_m3m3(data->dFdX[block_ik].m, data->dFdX[block_ik].m, dfk_dxi);
+#endif
+
+ return true;
+}
+
+bool BPH_mass_spring_force_spring_goal(Implicit_Data *data, int i, const float goal_x[3], const float goal_v[3],
+ float stiffness, float damping,
+ float r_f[3], float r_dfdx[3][3], float r_dfdv[3][3])
+{
+ float root_goal_x[3], root_goal_v[3], extent[3], length, dir[3], vel[3];
+ float f[3], dfdx[3][3], dfdv[3][3];
+
+ /* goal is in world space */
+ world_to_root_v3(data, i, root_goal_x, goal_x);
+ world_to_root_v3(data, i, root_goal_v, goal_v);
+
+ sub_v3_v3v3(extent, root_goal_x, data->X.v3(i));
+ sub_v3_v3v3(vel, root_goal_v, data->V.v3(i));
+ length = normalize_v3_v3(dir, extent);
+
+ if (length > ALMOST_ZERO) {
+ mul_v3_v3fl(f, dir, stiffness * length);
+
+ // Ascher & Boxman, p.21: Damping only during elonglation
+ // something wrong with it...
+ madd_v3_v3fl(f, dir, damping * dot_v3v3(vel, dir));
+
+ dfdx_spring(dfdx, dir, length, 0.0f, stiffness);
+ dfdv_damp(dfdv, dir, damping);
+
+ add_v3_v3(data->F.v3(i), f);
+ data->idFdX.add(i, i, dfdx);
+ data->idFdV.add(i, i, dfdv);
+
+ if (r_f) copy_v3_v3(r_f, f);
+ if (r_dfdx) copy_m3_m3(r_dfdx, dfdx);
+ if (r_dfdv) copy_m3_m3(r_dfdv, dfdv);
+
+ return true;
+ }
+ else {
+ if (r_f) zero_v3(r_f);
+ if (r_dfdx) zero_m3(r_dfdx);
+ if (r_dfdv) zero_m3(r_dfdv);
+
+ return false;
+ }
+}
+
+#endif /* IMPLICIT_SOLVER_EIGEN */
diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript
index d7c47d11ca3..3b46b3ff917 100644
--- a/source/blender/python/SConscript
+++ b/source/blender/python/SConscript
@@ -165,6 +165,11 @@ if env['WITH_BF_OPENAL']:
if env['WITH_BF_SDL']:
defs.append('WITH_SDL')
+ incs += ' ' + env['BF_SDL_INC']
+
+ if env['WITH_BF_SDL_DYNLOAD']:
+ defs.append('WITH_SDL_DYNLOAD')
+ incs += ' #extern/sdlew/include'
if env['WITH_BF_JACK']:
defs.append('WITH_JACK')
diff --git a/source/blender/python/bmesh/bmesh_py_geometry.c b/source/blender/python/bmesh/bmesh_py_geometry.c
index 4cd0a3951b3..f67bf29c94d 100644
--- a/source/blender/python/bmesh/bmesh_py_geometry.c
+++ b/source/blender/python/bmesh/bmesh_py_geometry.c
@@ -43,13 +43,13 @@
PyDoc_STRVAR(bpy_bm_geometry_intersect_face_point_doc,
".. method:: intersect_face_point(face, point)\n"
"\n"
-" Tests if a point is inside a face (using the faces normal).\n"
+" Tests if the projection of a point is inside a face (using the face's normal).\n"
"\n"
" :arg face: The face to test.\n"
" :type face: :class:`bmesh.types.BMFace`\n"
" :arg point: The point to test.\n"
" :type point: float triplet\n"
-" :return: True when the the point is in the face.\n"
+" :return: True when the projection of the point is in the face.\n"
" :rtype: bool\n"
);
static PyObject *bpy_bm_geometry_intersect_face_point(BPy_BMFace *UNUSED(self), PyObject *args)
diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c
index 4fc0160bbd6..ee96c859858 100644
--- a/source/blender/python/bmesh/bmesh_py_ops.c
+++ b/source/blender/python/bmesh/bmesh_py_ops.c
@@ -37,17 +37,12 @@
#include "MEM_guardedalloc.h"
-#include "../generic/py_capi_utils.h"
#include "bmesh.h"
#include "bmesh_py_ops_call.h"
#include "bmesh_py_ops.h" /* own include */
-#include "bmesh_py_types.h"
-
-#include "bmesh_py_utils.h"
-
/* bmesh operator 'bmesh.ops.*' callable types
* ******************************************* */
static PyTypeObject bmesh_op_Type;
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index 2c07df98973..84c1031a24a 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -39,11 +39,11 @@
#include "bmesh.h"
-#include "bmesh_py_ops.h"
#include "bmesh_py_ops_call.h" /* own include */
#include "bmesh_py_types.h"
-#include "bmesh_py_utils.h"
+
+#include "../generic/python_utildefines.h"
static int bpy_bm_op_as_py_error(BMesh *bm)
{
@@ -542,20 +542,20 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
item = PyFloat_FromDouble((double)BMO_SLOT_AS_FLOAT(slot));
break;
case BMO_OP_SLOT_MAT:
- item = Matrix_CreatePyObject((float *)BMO_SLOT_AS_MATRIX(slot), 4, 4, Py_NEW, NULL);
+ item = Matrix_CreatePyObject((float *)BMO_SLOT_AS_MATRIX(slot), 4, 4, NULL);
break;
case BMO_OP_SLOT_VEC:
- item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, Py_NEW, NULL);
+ item = Vector_CreatePyObject(BMO_SLOT_AS_VECTOR(slot), slot->len, NULL);
break;
case BMO_OP_SLOT_PTR:
BLI_assert(0); /* currently we don't have any pointer return values in use */
- item = (Py_INCREF(Py_None), Py_None);
+ item = Py_INCREF_RET(Py_None);
break;
case BMO_OP_SLOT_ELEMENT_BUF:
{
if (slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) {
BMHeader *ele = BMO_slot_buffer_get_single(slot);
- item = ele ? BPy_BMElem_CreatePyObject(bm, ele) : (Py_INCREF(Py_None), Py_None);
+ item = ele ? BPy_BMElem_CreatePyObject(bm, ele) : Py_INCREF_RET(Py_None);
}
else {
const int size = slot->len;
@@ -666,7 +666,7 @@ static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot)
}
case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL:
/* can't convert from these */
- item = (Py_INCREF(Py_None), Py_None);
+ item = Py_INCREF_RET(Py_None);
break;
}
break;
@@ -745,7 +745,7 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
ret = NULL; /* exception raised above */
}
else if (bmop.slots_out[0].slot_name == NULL) {
- ret = (Py_INCREF(Py_None), Py_None);
+ ret = Py_INCREF_RET(Py_None);
}
else {
/* build return value */
@@ -761,7 +761,7 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
/* this function doesn't throw exceptions */
item = bpy_slot_to_py(bm, slot);
if (item == NULL) {
- item = (Py_INCREF(Py_None), Py_None);
+ item = Py_INCREF_RET(Py_None);
}
#if 1
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index a31345cd7f5..20ee872b3be 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -44,6 +44,7 @@
#include "../mathutils/mathutils.h"
#include "../generic/py_capi_utils.h"
+#include "../generic/python_utildefines.h"
#include "bmesh_py_types.h" /* own include */
#include "bmesh_py_types_select.h"
@@ -342,7 +343,7 @@ PyDoc_STRVAR(bpy_bmvert_co_doc,
static PyObject *bpy_bmvert_co_get(BPy_BMVert *self)
{
BPY_BM_CHECK_OBJ(self);
- return Vector_CreatePyObject(self->v->co, 3, Py_WRAP, NULL);
+ return Vector_CreatePyObject_wrap(self->v->co, 3, NULL);
}
static int bpy_bmvert_co_set(BPy_BMVert *self, PyObject *value)
@@ -364,7 +365,7 @@ PyDoc_STRVAR(bpy_bmvert_normal_doc,
static PyObject *bpy_bmvert_normal_get(BPy_BMVert *self)
{
BPY_BM_CHECK_OBJ(self);
- return Vector_CreatePyObject(self->v->no, 3, Py_WRAP, NULL);
+ return Vector_CreatePyObject_wrap(self->v->no, 3, NULL);
}
static int bpy_bmvert_normal_set(BPy_BMVert *self, PyObject *value)
@@ -468,7 +469,7 @@ PyDoc_STRVAR(bpy_bmface_normal_doc,
static PyObject *bpy_bmface_normal_get(BPy_BMFace *self)
{
BPY_BM_CHECK_OBJ(self);
- return Vector_CreatePyObject(self->f->no, 3, Py_WRAP, NULL);
+ return Vector_CreatePyObject_wrap(self->f->no, 3, NULL);
}
static int bpy_bmface_normal_set(BPy_BMFace *self, PyObject *value)
@@ -1421,17 +1422,44 @@ static PyObject *bpy_bmvert_copy_from_face_interp(BPy_BMVert *self, PyObject *ar
PyDoc_STRVAR(bpy_bmvert_calc_edge_angle_doc,
-".. method:: calc_vert_angle()\n"
+".. method:: calc_edge_angle(fallback=None)\n"
"\n"
" Return the angle between this vert's two connected edges.\n"
"\n"
+" :arg fallback: return this when the vert doesn't have 2 edges\n"
+" (instead of raising a :exc:`ValueError`).\n"
+" :type fallback: any\n"
" :return: Angle between edges in radians.\n"
" :rtype: float\n"
);
-static PyObject *bpy_bmvert_calc_edge_angle(BPy_BMVert *self)
+static PyObject *bpy_bmvert_calc_edge_angle(BPy_BMVert *self, PyObject *args)
{
+ const float angle_invalid = -1.0f;
+ float angle;
+ PyObject *fallback = NULL;
+
BPY_BM_CHECK_OBJ(self);
- return PyFloat_FromDouble(BM_vert_calc_edge_angle(self->v));
+
+ if (!PyArg_ParseTuple(args, "|O:calc_edge_angle", &fallback))
+ return NULL;
+
+ angle = BM_vert_calc_edge_angle_ex(self->v, angle_invalid);
+
+ if (angle == angle_invalid) {
+ /* avoid exception */
+ if (fallback) {
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "BMVert.calc_edge_angle(): "
+ "vert doesn't use 2 edges");
+ return NULL;
+ }
+ }
+
+ return PyFloat_FromDouble(angle);
}
PyDoc_STRVAR(bpy_bmvert_calc_shell_factor_doc,
@@ -1481,27 +1509,81 @@ static PyObject *bpy_bmedge_calc_length(BPy_BMEdge *self)
}
PyDoc_STRVAR(bpy_bmedge_calc_face_angle_doc,
-".. method:: calc_face_angle()\n"
+".. method:: calc_face_angle(fallback=None)\n"
"\n"
+" :arg fallback: return this when the edge doesn't have 2 faces\n"
+" (instead of raising a :exc:`ValueError`).\n"
+" :type fallback: any\n"
" :return: The angle between 2 connected faces in radians.\n"
" :rtype: float\n"
);
-static PyObject *bpy_bmedge_calc_face_angle(BPy_BMEdge *self)
+static PyObject *bpy_bmedge_calc_face_angle(BPy_BMEdge *self, PyObject *args)
{
+ const float angle_invalid = -1.0f;
+ float angle;
+ PyObject *fallback = NULL;
+
BPY_BM_CHECK_OBJ(self);
- return PyFloat_FromDouble(BM_edge_calc_face_angle(self->e));
+
+ if (!PyArg_ParseTuple(args, "|O:calc_face_angle", &fallback))
+ return NULL;
+
+ angle = BM_edge_calc_face_angle_ex(self->e, angle_invalid);
+
+ if (angle == angle_invalid) {
+ /* avoid exception */
+ if (fallback) {
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "BMEdge.calc_face_angle(): "
+ "edge doesn't use 2 faces");
+ return NULL;
+ }
+ }
+
+ return PyFloat_FromDouble(angle);
}
PyDoc_STRVAR(bpy_bmedge_calc_face_angle_signed_doc,
-".. method:: calc_face_angle_signed()\n"
+".. method:: calc_face_angle_signed(fallback=None)\n"
"\n"
+" :arg fallback: return this when the edge doesn't have 2 faces\n"
+" (instead of raising a :exc:`ValueError`).\n"
+" :type fallback: any\n"
" :return: The angle between 2 connected faces in radians (negative for concave join).\n"
" :rtype: float\n"
);
-static PyObject *bpy_bmedge_calc_face_angle_signed(BPy_BMEdge *self)
+static PyObject *bpy_bmedge_calc_face_angle_signed(BPy_BMEdge *self, PyObject *args)
{
+ const float angle_invalid = -FLT_MAX;
+ float angle;
+ PyObject *fallback = NULL;
+
BPY_BM_CHECK_OBJ(self);
- return PyFloat_FromDouble(BM_edge_calc_face_angle_signed(self->e));
+
+ if (!PyArg_ParseTuple(args, "|O:calc_face_angle_signed", &fallback))
+ return NULL;
+
+ angle = BM_edge_calc_face_angle_signed_ex(self->e, angle_invalid);
+
+ if (angle == angle_invalid) {
+ /* avoid exception */
+ if (fallback) {
+ Py_INCREF(fallback);
+ return fallback;
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "BMEdge.calc_face_angle_signed(): "
+ "edge doesn't use 2 faces");
+ return NULL;
+ }
+ }
+
+ return PyFloat_FromDouble(angle);
}
PyDoc_STRVAR(bpy_bmedge_calc_tangent_doc,
@@ -1530,7 +1612,7 @@ static PyObject *bpy_bmedge_calc_tangent(BPy_BMEdge *self, PyObject *args)
BPY_BM_CHECK_OBJ(py_loop);
/* no need to check if they are from the same mesh or even connected */
BM_edge_calc_face_tangent(self->e, py_loop->l, vec);
- return Vector_CreatePyObject(vec, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(vec, 3, NULL);
}
}
@@ -1711,7 +1793,7 @@ static PyObject *bpy_bmface_calc_center_mean(BPy_BMFace *self)
BPY_BM_CHECK_OBJ(self);
BM_face_calc_center_mean(self->f, cent);
- return Vector_CreatePyObject(cent, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(cent, 3, NULL);
}
PyDoc_STRVAR(bpy_bmface_calc_center_mean_weighted_doc,
@@ -1728,7 +1810,7 @@ static PyObject *bpy_bmface_calc_center_mean_weighted(BPy_BMFace *self)
BPY_BM_CHECK_OBJ(self);
BM_face_calc_center_mean_weighted(self->f, cent);
- return Vector_CreatePyObject(cent, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(cent, 3, NULL);
}
PyDoc_STRVAR(bpy_bmface_calc_center_bounds_doc,
@@ -1745,7 +1827,7 @@ static PyObject *bpy_bmface_calc_center_bounds(BPy_BMFace *self)
BPY_BM_CHECK_OBJ(self);
BM_face_calc_center_bounds(self->f, cent);
- return Vector_CreatePyObject(cent, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(cent, 3, NULL);
}
@@ -1849,7 +1931,7 @@ static PyObject *bpy_bmloop_calc_normal(BPy_BMLoop *self)
float vec[3];
BPY_BM_CHECK_OBJ(self);
BM_loop_calc_face_normal(self->l, vec);
- return Vector_CreatePyObject(vec, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(vec, 3, NULL);
}
PyDoc_STRVAR(bpy_bmloop_calc_tangent_doc,
@@ -1866,7 +1948,7 @@ static PyObject *bpy_bmloop_calc_tangent(BPy_BMLoop *self)
float vec[3];
BPY_BM_CHECK_OBJ(self);
BM_loop_calc_face_tangent(self->l, vec);
- return Vector_CreatePyObject(vec, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(vec, 3, NULL);
}
/* Vert Seq
@@ -2311,6 +2393,22 @@ static PyObject *bpy_bmelemseq_index_update(BPy_BMElemSeq *self)
Py_RETURN_NONE;
}
+PyDoc_STRVAR(bpy_bmelemseq_ensure_lookup_table_doc,
+".. method:: ensure_lookup_table()\n"
+"\n"
+" Ensure internal data needed for int subscription is initialized with verts/edges/faces, eg ``bm.verts[index]``.\n"
+"\n"
+" This needs to be called again after adding/removing data in this sequence."
+);
+static PyObject *bpy_bmelemseq_ensure_lookup_table(BPy_BMElemSeq *self)
+{
+ BPY_BM_CHECK_OBJ(self);
+
+ BM_mesh_elem_table_ensure(self->bm, bm_iter_itype_htype_map[self->itype]);
+
+ Py_RETURN_NONE;
+}
+
PyDoc_STRVAR(bpy_bmelemseq_sort_doc,
".. method:: sort(key=None, reverse=False)\n"
"\n"
@@ -2537,7 +2635,7 @@ static struct PyMethodDef bpy_bmvert_methods[] = {
{"copy_from_face_interp", (PyCFunction)bpy_bmvert_copy_from_face_interp, METH_VARARGS, bpy_bmvert_copy_from_face_interp_doc},
{"copy_from_vert_interp", (PyCFunction)bpy_bmvert_copy_from_vert_interp, METH_VARARGS, bpy_bmvert_copy_from_vert_interp_doc},
- {"calc_vert_angle", (PyCFunction)bpy_bmvert_calc_edge_angle, METH_NOARGS, bpy_bmvert_calc_edge_angle_doc},
+ {"calc_edge_angle", (PyCFunction)bpy_bmvert_calc_edge_angle, METH_VARARGS, bpy_bmvert_calc_edge_angle_doc},
{"calc_shell_factor", (PyCFunction)bpy_bmvert_calc_shell_factor, METH_NOARGS, bpy_bmvert_calc_shell_factor_doc},
{"normal_update", (PyCFunction)bpy_bmvert_normal_update, METH_NOARGS, bpy_bmvert_normal_update_doc},
@@ -2553,8 +2651,8 @@ static struct PyMethodDef bpy_bmedge_methods[] = {
{"other_vert", (PyCFunction)bpy_bmedge_other_vert, METH_O, bpy_bmedge_other_vert_doc},
{"calc_length", (PyCFunction)bpy_bmedge_calc_length, METH_NOARGS, bpy_bmedge_calc_length_doc},
- {"calc_face_angle", (PyCFunction)bpy_bmedge_calc_face_angle, METH_NOARGS, bpy_bmedge_calc_face_angle_doc},
- {"calc_face_angle_signed", (PyCFunction)bpy_bmedge_calc_face_angle_signed, METH_NOARGS, bpy_bmedge_calc_face_angle_signed_doc},
+ {"calc_face_angle", (PyCFunction)bpy_bmedge_calc_face_angle, METH_VARARGS, bpy_bmedge_calc_face_angle_doc},
+ {"calc_face_angle_signed", (PyCFunction)bpy_bmedge_calc_face_angle_signed, METH_VARARGS, bpy_bmedge_calc_face_angle_signed_doc},
{"calc_tangent", (PyCFunction)bpy_bmedge_calc_tangent, METH_VARARGS, bpy_bmedge_calc_tangent_doc},
{"normal_update", (PyCFunction)bpy_bmedge_normal_update, METH_NOARGS, bpy_bmedge_normal_update_doc},
@@ -2605,6 +2703,7 @@ static struct PyMethodDef bpy_bmvertseq_methods[] = {
/* odd function, initializes index values */
{"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
+ {"ensure_lookup_table", (PyCFunction)bpy_bmelemseq_ensure_lookup_table, METH_NOARGS, bpy_bmelemseq_ensure_lookup_table_doc},
{"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc},
{NULL, NULL, 0, NULL}
};
@@ -2617,6 +2716,7 @@ static struct PyMethodDef bpy_bmedgeseq_methods[] = {
/* odd function, initializes index values */
{"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
+ {"ensure_lookup_table", (PyCFunction)bpy_bmelemseq_ensure_lookup_table, METH_NOARGS, bpy_bmelemseq_ensure_lookup_table_doc},
{"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc},
{NULL, NULL, 0, NULL}
};
@@ -2629,6 +2729,7 @@ static struct PyMethodDef bpy_bmfaceseq_methods[] = {
/* odd function, initializes index values */
{"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
+ {"ensure_lookup_table", (PyCFunction)bpy_bmelemseq_ensure_lookup_table, METH_NOARGS, bpy_bmelemseq_ensure_lookup_table_doc},
{"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc},
{NULL, NULL, 0, NULL}
};
@@ -2725,9 +2826,43 @@ static PyObject *bpy_bmelemseq_subscript_int(BPy_BMElemSeq *self, int keynum)
if (keynum < 0) keynum += bpy_bmelemseq_length(self); /* only get length on negative value, may loop entire seq */
if (keynum >= 0) {
- BMHeader *ele = BM_iter_at_index(self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL, keynum);
- if (ele) {
- return BPy_BMElem_CreatePyObject(self->bm, ele);
+ if (self->itype <= BM_FACES_OF_MESH) {
+ if ((self->bm->elem_table_dirty & bm_iter_itype_htype_map[self->itype]) == 0) {
+ BMHeader *ele = NULL;
+ switch (self->itype) {
+ case BM_VERTS_OF_MESH:
+ if (keynum < self->bm->totvert) {
+ ele = (BMHeader *)self->bm->vtable[keynum];
+ }
+ break;
+ case BM_EDGES_OF_MESH:
+ if (keynum < self->bm->totedge) {
+ ele = (BMHeader *)self->bm->etable[keynum];
+ }
+ break;
+ case BM_FACES_OF_MESH:
+ if (keynum < self->bm->totface) {
+ ele = (BMHeader *)self->bm->ftable[keynum];
+ }
+ break;
+ }
+ if (ele) {
+ return BPy_BMElem_CreatePyObject(self->bm, ele);
+ }
+ /* fall through to index error below */
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError,
+ "BMElemSeq[index]: outdated internal index table, "
+ "run ensure_lookup_table() first");
+ return NULL;
+ }
+ }
+ else {
+ BMHeader *ele = BM_iter_at_index(self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL, keynum);
+ if (ele) {
+ return BPy_BMElem_CreatePyObject(self->bm, ele);
+ }
}
}
@@ -2743,7 +2878,6 @@ static PyObject *bpy_bmelemseq_subscript_slice(BPy_BMElemSeq *self, Py_ssize_t s
bool ok;
PyObject *list;
- PyObject *item;
BMHeader *ele;
BPY_BM_CHECK_OBJ(self);
@@ -2768,9 +2902,7 @@ static PyObject *bpy_bmelemseq_subscript_slice(BPy_BMElemSeq *self, Py_ssize_t s
/* add items until stop */
while ((ele = BM_iter_step(&iter))) {
- item = BPy_BMElem_CreatePyObject(self->bm, ele);
- PyList_Append(list, item);
- Py_DECREF(item);
+ PyList_APPEND(list, BPy_BMElem_CreatePyObject(self->bm, ele));
count++;
if (count == stop) {
diff --git a/source/blender/python/bmesh/bmesh_py_types.h b/source/blender/python/bmesh/bmesh_py_types.h
index a2c2c312e71..66059a642d1 100644
--- a/source/blender/python/bmesh/bmesh_py_types.h
+++ b/source/blender/python/bmesh/bmesh_py_types.h
@@ -198,16 +198,17 @@ int bpy_bm_generic_valid_check_source(BMesh *bm_source, const char *error_prefi
#define BPY_BM_IS_VALID(obj) (LIKELY((obj)->bm != NULL))
-#define BM_ITER_BPY_BM_SEQ(ele, iter, bpy_bmelemseq) \
- for (ele = BM_iter_new(iter, \
- (bpy_bmelemseq)->bm, \
- (bpy_bmelemseq)->itype, \
- (bpy_bmelemseq)->py_ele ? \
- ((BPy_BMElem *)(bpy_bmelemseq)->py_ele)->ele : \
- NULL \
- ); \
- ele; \
- ele = BM_iter_step(iter))
+#define BM_ITER_BPY_BM_SEQ(ele, iter, bpy_bmelemseq) \
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new( \
+ iter, \
+ (bpy_bmelemseq)->bm, \
+ (bpy_bmelemseq)->itype, \
+ (bpy_bmelemseq)->py_ele ? \
+ ((BPy_BMElem *)(bpy_bmelemseq)->py_ele)->ele : \
+ NULL \
+ ); \
+ ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
#ifdef __PY_CAPI_UTILS_H__
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 6ecb01a8528..bfcd91ac72d 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -42,6 +42,7 @@
#include "bmesh_py_types_meshdata.h"
#include "../mathutils/mathutils.h"
+#include "../generic/python_utildefines.h"
#include "BKE_customdata.h"
@@ -483,8 +484,9 @@ static PyObject *bpy_bmlayercollection_items(BPy_BMLayerCollection *self)
for (i = 0; tot-- > 0; index++) {
item = PyTuple_New(2);
- PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(data->layers[index].name));
- PyTuple_SET_ITEM(item, 1, BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index));
+ PyTuple_SET_ITEMS(item,
+ PyUnicode_FromString(data->layers[index].name),
+ BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index));
PyList_SET_ITEM(ret, i++, item);
}
@@ -559,7 +561,7 @@ static PyObject *bpy_bmlayercollection_get(BPy_BMLayerCollection *self, PyObject
}
}
- return Py_INCREF(def), def;
+ return Py_INCREF_RET(def);
}
static struct PyMethodDef bpy_bmlayeritem_methods[] = {
@@ -1014,7 +1016,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
}
case CD_SHAPEKEY:
{
- ret = Vector_CreatePyObject((float *)value, 3, Py_WRAP, NULL);
+ ret = Vector_CreatePyObject_wrap((float *)value, 3, NULL);
break;
}
case CD_BWEIGHT:
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index 3512dc76cef..94f38ffdec7 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -45,6 +45,8 @@
#include "bmesh_py_types_meshdata.h"
+#include "../generic/python_utildefines.h"
+
/* Mesh BMTexPoly
* ************** */
@@ -150,7 +152,7 @@ PyDoc_STRVAR(bpy_bmloopuv_uv_doc,
);
static PyObject *bpy_bmloopuv_uv_get(BPy_BMLoopUV *self, void *UNUSED(closure))
{
- return Vector_CreatePyObject(self->data->uv, 2, Py_WRAP, NULL);
+ return Vector_CreatePyObject_wrap(self->data->uv, 2, NULL);
}
static int bpy_bmloopuv_uv_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED(closure))
@@ -263,7 +265,7 @@ PyDoc_STRVAR(bpy_bmvertskin_radius_doc,
);
static PyObject *bpy_bmvertskin_radius_get(BPy_BMVertSkin *self, void *UNUSED(closure))
{
- return Vector_CreatePyObject(self->data->radius, 2, Py_WRAP, NULL);
+ return Vector_CreatePyObject_wrap(self->data->radius, 2, NULL);
}
static int bpy_bmvertskin_radius_set(BPy_BMVertSkin *self, PyObject *value, void *UNUSED(closure))
@@ -369,7 +371,7 @@ PyObject *BPy_BMVertSkin_CreatePyObject(struct MVertSkin *mvertskin)
static void mloopcol_to_float(const MLoopCol *mloopcol, float r_col[3])
{
- rgb_uchar_to_float(r_col, (unsigned char *)&mloopcol->r);
+ rgb_uchar_to_float(r_col, (const unsigned char *)&mloopcol->r);
}
static void mloopcol_from_float(MLoopCol *mloopcol, const float col[3])
@@ -684,10 +686,9 @@ static PyObject *bpy_bmdeformvert_items(BPy_BMDeformVert *self)
ret = PyList_New(self->data->totweight);
for (i = 0; i < self->data->totweight; i++, dw++) {
item = PyTuple_New(2);
-
- PyTuple_SET_ITEM(item, 0, PyLong_FromLong(dw->def_nr));
- PyTuple_SET_ITEM(item, 1, PyFloat_FromDouble(dw->weight));
-
+ PyTuple_SET_ITEMS(item,
+ PyLong_FromLong(dw->def_nr),
+ PyFloat_FromDouble(dw->weight));
PyList_SET_ITEM(ret, i, item);
}
@@ -721,7 +722,7 @@ static PyObject *bpy_bmdeformvert_get(BPy_BMDeformVert *self, PyObject *args)
return PyFloat_FromDouble(dw->weight);
}
else {
- return Py_INCREF(def), def;
+ return Py_INCREF_RET(def);
}
}
}
diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c
index 3c72112e7ce..7b792e9f08e 100644
--- a/source/blender/python/bmesh/bmesh_py_types_select.c
+++ b/source/blender/python/bmesh/bmesh_py_types_select.c
@@ -43,11 +43,8 @@
#include "bmesh_py_types.h"
#include "bmesh_py_types_select.h"
-
-
#include "../generic/py_capi_utils.h"
-
-#include "bmesh_py_api.h" /* own include */
+#include "../generic/python_utildefines.h"
PyDoc_STRVAR(bpy_bmeditselseq_active_doc,
"The last selected element or None (read-only).\n\n:type: :class:`BMVert`, :class:`BMEdge` or :class:`BMFace`"
@@ -165,7 +162,7 @@ static Py_ssize_t bpy_bmeditselseq_length(BPy_BMEditSelSeq *self)
{
BPY_BM_CHECK_INT(self);
- return BLI_countlist(&self->bm->selected);
+ return BLI_listbase_count(&self->bm->selected);
}
static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keynum)
@@ -197,7 +194,6 @@ static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, Py_ssi
bool ok;
PyObject *list;
- PyObject *item;
BMEditSelection *ese;
BPY_BM_CHECK_OBJ(self);
@@ -222,9 +218,7 @@ static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, Py_ssi
/* add items until stop */
while ((ese = ese->next)) {
- item = BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
- PyList_Append(list, item);
- Py_DECREF(item);
+ PyList_APPEND(list, BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head));
count++;
if (count == stop) {
diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c
index 7088036245a..2e32a571e3c 100644
--- a/source/blender/python/bmesh/bmesh_py_utils.c
+++ b/source/blender/python/bmesh/bmesh_py_utils.c
@@ -42,6 +42,8 @@
#include "bmesh_py_types.h"
#include "bmesh_py_utils.h" /* own include */
+#include "../generic/python_utildefines.h"
+
PyDoc_STRVAR(bpy_bm_utils_vert_collapse_edge_doc,
".. method:: vert_collapse_edge(vert, edge)\n"
@@ -253,6 +255,7 @@ static PyObject *bpy_bm_utils_vert_splice(PyObject *UNUSED(self), PyObject *args
/* should always succeed */
ok = BM_vert_splice(bm, py_vert->v, py_vert_target->v);
BLI_assert(ok == true);
+ UNUSED_VARS_NDEBUG(ok);
Py_RETURN_NONE;
}
@@ -365,8 +368,9 @@ static PyObject *bpy_bm_utils_edge_split(PyObject *UNUSED(self), PyObject *args)
if (v_new && e_new) {
PyObject *ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, BPy_BMEdge_CreatePyObject(bm, e_new));
- PyTuple_SET_ITEM(ret, 1, BPy_BMVert_CreatePyObject(bm, v_new));
+ PyTuple_SET_ITEMS(ret,
+ BPy_BMEdge_CreatePyObject(bm, e_new),
+ BPy_BMVert_CreatePyObject(bm, v_new));
return ret;
}
else {
@@ -524,8 +528,9 @@ static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args,
if (f_new && l_new) {
PyObject *ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, BPy_BMFace_CreatePyObject(bm, f_new));
- PyTuple_SET_ITEM(ret, 1, BPy_BMLoop_CreatePyObject(bm, l_new));
+ PyTuple_SET_ITEMS(ret,
+ BPy_BMFace_CreatePyObject(bm, f_new),
+ BPy_BMLoop_CreatePyObject(bm, l_new));
return ret;
}
else {
diff --git a/source/blender/python/generic/CMakeLists.txt b/source/blender/python/generic/CMakeLists.txt
index 155247a4249..df611e00d00 100644
--- a/source/blender/python/generic/CMakeLists.txt
+++ b/source/blender/python/generic/CMakeLists.txt
@@ -46,6 +46,9 @@ set(SRC
bpy_internal_import.h
idprop_py_api.h
py_capi_utils.h
+
+ # header-only
+ python_utildefines.h
)
add_definitions(${GL_DEFINITIONS})
diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c
index 655542e320a..ed1ac7ceed9 100644
--- a/source/blender/python/generic/blf_py_api.c
+++ b/source/blender/python/generic/blf_py_api.c
@@ -33,6 +33,9 @@
#include "BLI_utildefines.h"
+#include "../generic/python_utildefines.h"
+
+
PyDoc_STRVAR(py_blf_position_doc,
".. function:: position(fontid, x, y, z)\n"
"\n"
@@ -183,8 +186,9 @@ static PyObject *py_blf_dimensions(PyObject *UNUSED(self), PyObject *args)
BLF_width_and_height(fontid, text, INT_MAX, &r_width, &r_height);
ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(r_width));
- PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(r_height));
+ PyTuple_SET_ITEMS(ret,
+ PyFloat_FromDouble(r_width),
+ PyFloat_FromDouble(r_height));
return ret;
}
diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c
index 2d19fdb87b3..ed2752d8372 100644
--- a/source/blender/python/generic/bpy_internal_import.c
+++ b/source/blender/python/generic/bpy_internal_import.c
@@ -81,7 +81,7 @@ void bpy_import_init(PyObject *builtins)
/* move reload here
* XXX, use import hooks */
- mod = PyImport_ImportModuleLevel("imp", NULL, NULL, NULL, 0);
+ mod = PyImport_ImportModuleLevel("importlib", NULL, NULL, NULL, 0);
if (mod) {
PyObject *mod_dict = PyModule_GetDict(mod);
@@ -93,7 +93,7 @@ void bpy_import_init(PyObject *builtins)
Py_DECREF(mod);
}
else {
- BLI_assert(!"unable to load 'imp' module.");
+ BLI_assert(!"unable to load 'importlib' module.");
}
}
@@ -265,7 +265,7 @@ PyObject *bpy_text_reimport(PyObject *module, int *found)
}
/* make into a module */
- return PyImport_ExecCodeModule((char *)name, text->compiled);
+ return PyImport_ExecCodeModule(name, text->compiled);
}
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 8c9e84af8ed..1f35572a483 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -33,16 +33,17 @@
#include "idprop_py_api.h"
-
#include "BKE_idprop.h"
-
#define USE_STRING_COERCE
#ifdef USE_STRING_COERCE
#include "py_capi_utils.h"
#endif
+#include "../generic/python_utildefines.h"
+
+
/*********************** ID Property Main Wrapper Stuff ***************/
/* ----------------------------------------------------------------------------
@@ -296,10 +297,10 @@ static PyObject *BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item)
}
/* returns NULL on success, error string on failure */
-static int idp_sequence_type(PyObject *seq_fast)
+static char idp_sequence_type(PyObject *seq_fast)
{
PyObject *item;
- int type = IDP_INT;
+ char type = IDP_INT;
Py_ssize_t i, len = PySequence_Fast_GET_SIZE(seq_fast);
for (i = 0; i < len; i++) {
@@ -376,7 +377,7 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group,
else if (PyUnicode_Check(ob)) {
#ifdef USE_STRING_COERCE
PyObject *value_coerce = NULL;
- val.string.str = (char *)PyC_UnicodeAsByte(ob, &value_coerce);
+ val.string.str = PyC_UnicodeAsByte(ob, &value_coerce);
val.string.subtype = IDP_STRING_SUB_UTF8;
prop = IDP_New(IDP_STRING, &val, name);
Py_XDECREF(value_coerce);
@@ -403,7 +404,7 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group,
return false;
}
- if ((val.array.type = idp_sequence_type(ob_seq_fast)) == -1) {
+ if ((val.array.type = idp_sequence_type(ob_seq_fast)) == (char)-1) {
Py_DECREF(ob_seq_fast);
PyErr_SetString(PyExc_TypeError, "only floats, ints and dicts are allowed in ID property arrays");
return false;
@@ -510,7 +511,26 @@ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group,
MEM_freeN(prop);
}
else {
- IDP_ReplaceInGroup(group, prop);
+ IDProperty *prop_exist;
+
+ /* avoid freeing when types match in case they are referenced by the UI, see: T37073
+ * obviously this isn't a complete solution, but helps for common cases. */
+ prop_exist = IDP_GetPropertyFromGroup(group, prop->name);
+ if ((prop_exist != NULL) &&
+ (prop_exist->type == prop->type) &&
+ (prop_exist->subtype == prop->subtype))
+ {
+ /* Preserve prev/next links!!! See T42593. */
+ prop->prev = prop_exist->prev;
+ prop->next = prop_exist->next;
+
+ IDP_FreeProperty(prop_exist);
+ *prop_exist = *prop;
+ MEM_freeN(prop);
+ }
+ else {
+ IDP_ReplaceInGroup_ex(group, prop, prop_exist);
+ }
}
return true;
@@ -727,10 +747,9 @@ static void BPy_IDGroup_CorrectListLen(IDProperty *prop, PyObject *seq, int len,
printf("%s: ID Property Error found and corrected!\n", func);
- /*fill rest of list with valid references to None*/
+ /* fill rest of list with valid references to None */
for (j = len; j < prop->len; j++) {
- Py_INCREF(Py_None);
- PyList_SET_ITEM(seq, j, Py_None);
+ PyList_SET_ITEM(seq, j, Py_INCREF_RET(Py_None));
}
/*set correct group length*/
@@ -789,8 +808,9 @@ PyObject *BPy_Wrap_GetItems(ID *id, IDProperty *prop)
for (i = 0, loop = prop->data.group.first; loop; loop = loop->next, i++) {
PyObject *item = PyTuple_New(2);
- PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(loop->name));
- PyTuple_SET_ITEM(item, 1, BPy_IDGroup_WrapData(id, loop, prop));
+ PyTuple_SET_ITEMS(item,
+ PyUnicode_FromString(loop->name),
+ BPy_IDGroup_WrapData(id, loop, prop));
PyList_SET_ITEM(seq, i, item);
}
@@ -1387,8 +1407,9 @@ static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self)
if (self->mode == IDPROP_ITER_ITEMS) {
ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, PyUnicode_FromString(cur->name));
- PyTuple_SET_ITEM(ret, 1, BPy_IDGroup_WrapData(self->group->id, cur, self->group->prop));
+ PyTuple_SET_ITEMS(ret,
+ PyUnicode_FromString(cur->name),
+ BPy_IDGroup_WrapData(self->group->id, cur, self->group->prop));
return ret;
}
else {
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 36ae30ada22..92ac82508e5 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -37,6 +37,8 @@
#include "py_capi_utils.h"
+#include "../generic/python_utildefines.h"
+
/* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */
#include "BLI_string_utf8.h"
@@ -178,6 +180,17 @@ void PyC_Tuple_Fill(PyObject *tuple, PyObject *value)
}
}
+void PyC_List_Fill(PyObject *list, PyObject *value)
+{
+ unsigned int tot = PyList_GET_SIZE(list);
+ unsigned int i;
+
+ for (i = 0; i < tot; i++) {
+ PyList_SET_ITEM(list, i, value);
+ Py_INCREF(value);
+ }
+}
+
/* for debugging */
void PyC_ObSpit(const char *name, PyObject *var)
{
@@ -568,7 +581,7 @@ void PyC_MainModule_Restore(PyObject *main_mod)
Py_XDECREF(main_mod);
}
-/* must be called before Py_Initialize, expects output of BLI_get_folder(BLENDER_PYTHON, NULL) */
+/* must be called before Py_Initialize, expects output of BKE_appdir_folder_id(BLENDER_PYTHON, NULL) */
void PyC_SetHomePath(const char *py_path_bundle)
{
if (py_path_bundle == NULL) {
@@ -664,8 +677,7 @@ void PyC_RunQuicky(const char *filepath, int n, ...)
PyErr_Print();
PyErr_Clear();
- PyList_SET_ITEM(values, i, Py_None); /* hold user */
- Py_INCREF(Py_None);
+ PyList_SET_ITEM(values, i, Py_INCREF_RET(Py_None)); /* hold user */
sizes[i] = 0;
}
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index 559a8e15678..398d7da9179 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -42,6 +42,7 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
PyObject * PyC_FromArray(const void *array, int length, const PyTypeObject *type,
const bool is_double, const char *error_prefix);
void PyC_Tuple_Fill(PyObject *tuple, PyObject *value);
+void PyC_List_Fill(PyObject *list, PyObject *value);
/* follow http://www.python.org/dev/peps/pep-0383/ */
PyObject * PyC_UnicodeFromByte(const char *str);
diff --git a/source/blender/python/generic/python_utildefines.h b/source/blender/python/generic/python_utildefines.h
new file mode 100644
index 00000000000..f7d3e7a8b4a
--- /dev/null
+++ b/source/blender/python/generic/python_utildefines.h
@@ -0,0 +1,60 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/generic/python_utildefines.h
+ * \ingroup pygen
+ * \brief header-only utilities
+ * \note light addition to Python.h, use py_capi_utils.h for larger features.
+ */
+
+#ifndef __PYTHON_UTILDEFINES_H__
+#define __PYTHON_UTILDEFINES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PyTuple_SET_ITEMS(op_arg, ...) \
+{ \
+ PyTupleObject *op = (PyTupleObject *)op_arg; \
+ PyObject **ob_items = op->ob_item; \
+ CHECK_TYPE_ANY(op_arg, PyObject *, PyTupleObject *); \
+ BLI_assert(_VA_NARGS_COUNT(__VA_ARGS__) == PyTuple_GET_SIZE(op)); \
+ ARRAY_SET_ITEMS(ob_items, __VA_ARGS__); \
+} (void)0
+
+/* wrap Py_INCREF & return the result,
+ * use sparingly to avoid comma operator or temp var assignment */
+BLI_INLINE PyObject *Py_INCREF_RET(PyObject *op) { Py_INCREF(op); return op; }
+
+/* append & transfer ownership to the list, avoids inline Py_DECREF all over (which is quite a large macro) */
+BLI_INLINE int PyList_APPEND(PyObject *op, PyObject *v)
+{
+ int ret = PyList_Append(op, v);
+ Py_DecRef(v);
+ return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PYTHON_UTILDEFINES_H__ */
+
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index d77bfbedd43..42112d41ea6 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -47,11 +47,12 @@ set(SRC
gpu.c
bpy.c
bpy_app.c
- bpy_app_ffmpeg.c
bpy_app_build_options.c
+ bpy_app_ffmpeg.c
bpy_app_handlers.c
bpy_app_ocio.c
bpy_app_oiio.c
+ bpy_app_sdl.c
bpy_app_translations.c
bpy_driver.c
bpy_interface.c
@@ -74,11 +75,12 @@ set(SRC
gpu.h
bpy.h
bpy_app.h
- bpy_app_ffmpeg.h
bpy_app_build_options.h
+ bpy_app_ffmpeg.h
bpy_app_handlers.h
bpy_app_ocio.h
bpy_app_oiio.h
+ bpy_app_sdl.h
bpy_app_translations.h
bpy_driver.h
bpy_intern_string.h
@@ -210,9 +212,19 @@ if(WITH_OPENAL)
endif()
if(WITH_SDL)
+ list(APPEND INC_SYS
+ ${SDL_INCLUDE_DIR}
+ )
add_definitions(-DWITH_SDL)
endif()
+if(WITH_SDL_DYNLOAD)
+ list(APPEND INC
+ ../../../../extern/sdlew/include
+ )
+ add_definitions(-DWITH_SDL_DYNLOAD)
+endif()
+
if(WITH_JACK)
add_definitions(-DWITH_JACK)
endif()
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 134e718bce5..ec3c017a7ed 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -31,10 +31,9 @@
#include <Python.h>
#include "BLI_utildefines.h"
-#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BKE_main.h"
+#include "BKE_appdir.h"
#include "BKE_global.h" /* XXX, G.main only */
#include "BKE_blender.h"
#include "BKE_bpath.h"
@@ -52,15 +51,10 @@
#include "bpy_utils_units.h"
#include "../generic/py_capi_utils.h"
-
-#include "MEM_guardedalloc.h"
+#include "../generic/python_utildefines.h"
/* external util modules */
#include "../generic/idprop_py_api.h"
-#include "../generic/bgl.h"
-#include "../generic/blf_py_api.h"
-#include "../generic/blf_py_api.h"
-#include "../mathutils/mathutils.h"
#ifdef WITH_FREESTYLE
# include "BPy_Freestyle.h"
@@ -82,11 +76,11 @@ static PyObject *bpy_script_paths(PyObject *UNUSED(self))
PyObject *item;
const char *path;
- path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL);
+ path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, NULL);
item = PyC_UnicodeFromByte(path ? path : "");
BLI_assert(item != NULL);
PyTuple_SET_ITEM(ret, 0, item);
- path = BLI_get_folder(BLENDER_USER_SCRIPTS, NULL);
+ path = BKE_appdir_folder_id(BLENDER_USER_SCRIPTS, NULL);
item = PyC_UnicodeFromByte(path ? path : "");
BLI_assert(item != NULL);
PyTuple_SET_ITEM(ret, 1, item);
@@ -96,10 +90,7 @@ static PyObject *bpy_script_paths(PyObject *UNUSED(self))
static bool bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
{
- PyObject *list = (PyObject *)userdata;
- PyObject *item = PyC_UnicodeFromByte(path_src);
- PyList_Append(list, item);
- Py_DECREF(item);
+ PyList_APPEND((PyObject *)userdata, PyC_UnicodeFromByte(path_src));
return false; /* never edits the path */
}
@@ -168,11 +159,11 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj
return NULL;
}
- /* same logic as BLI_get_folder_create(), but best leave it up to the script author to create */
- path = BLI_get_folder(folder_id, subdir);
+ /* same logic as BKE_appdir_folder_id_create(), but best leave it up to the script author to create */
+ path = BKE_appdir_folder_id(folder_id, subdir);
if (!path)
- path = BLI_get_user_folder_notest(folder_id, subdir);
+ path = BKE_appdir_folder_id_user_notest(folder_id, subdir);
return PyC_UnicodeFromByte(path ? path : "");
}
@@ -211,7 +202,7 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
return NULL;
}
- path = BLI_get_folder_version(folder_id, (major * 100) + minor, false);
+ path = BKE_appdir_folder_id_version(folder_id, (major * 100) + minor, false);
return PyC_UnicodeFromByte(path ? path : "");
}
@@ -296,7 +287,7 @@ void BPy_init_modules(void)
PyObject *mod;
/* Needs to be first since this dir is needed for future modules */
- const char * const modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules");
+ const char * const modpath = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "modules");
if (modpath) {
// printf("bpy: found module path '%s'.\n", modpath);
PyObject *sys_path = PySys_GetObject("path"); /* borrow */
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index 16cdd44ce38..c8a4971847b 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -36,6 +36,7 @@
#include "bpy_app_ffmpeg.h"
#include "bpy_app_ocio.h"
#include "bpy_app_oiio.h"
+#include "bpy_app_sdl.h"
#include "bpy_app_build_options.h"
#include "bpy_app_translations.h"
@@ -44,13 +45,13 @@
#include "bpy_driver.h"
#include "BLI_utildefines.h"
-#include "BLI_path_util.h"
+#include "BKE_appdir.h"
#include "BKE_blender.h"
#include "BKE_global.h"
-#include "structseq.h"
#include "../generic/py_capi_utils.h"
+#include "../generic/python_utildefines.h"
#ifdef BUILD_DATE
extern char build_date[];
@@ -97,6 +98,7 @@ static PyStructSequence_Field app_info_fields[] = {
{(char *)"ffmpeg", (char *)"FFmpeg library information backend"},
{(char *)"ocio", (char *)"OpenColorIO library information backend"},
{(char *)"oiio", (char *)"OpenImageIO library information backend"},
+ {(char *)"sdl", (char *)"SDL library information backend"},
{(char *)"build_options", (char *)"A set containing most important enabled optional build features"},
{(char *)"handlers", (char *)"Application handler callbacks"},
{(char *)"translations", (char *)"Application and addons internationalization API"},
@@ -135,7 +137,7 @@ static PyObject *make_app_info(void)
SetStrItem(STRINGIFY(BLENDER_VERSION_CHAR));
SetStrItem(STRINGIFY(BLENDER_VERSION_CYCLE));
- SetStrItem(BLI_program_path());
+ SetStrItem(BKE_appdir_program_path());
SetObjItem(PyBool_FromLong(G.background));
/* build info, use bytes since we can't assume _any_ encoding:
@@ -173,6 +175,7 @@ static PyObject *make_app_info(void)
SetObjItem(BPY_app_ffmpeg_struct());
SetObjItem(BPY_app_ocio_struct());
SetObjItem(BPY_app_oiio_struct());
+ SetObjItem(BPY_app_sdl_struct());
SetObjItem(BPY_app_build_options_struct());
SetObjItem(BPY_app_handlers_struct());
SetObjItem(BPY_app_translations_struct());
@@ -250,7 +253,7 @@ PyDoc_STRVAR(bpy_app_tempdir_doc,
);
static PyObject *bpy_app_tempdir_get(PyObject *UNUSED(self), void *UNUSED(closure))
{
- return PyC_UnicodeFromByte(BLI_temp_dir_session());
+ return PyC_UnicodeFromByte(BKE_tempdir_session());
}
PyDoc_STRVAR(bpy_app_driver_dict_doc,
@@ -265,8 +268,7 @@ static PyObject *bpy_app_driver_dict_get(PyObject *UNUSED(self), void *UNUSED(cl
}
}
- Py_INCREF(bpy_pydriver_Dict);
- return bpy_pydriver_Dict;
+ return Py_INCREF_RET(bpy_pydriver_Dict);
}
static PyObject *bpy_app_autoexec_fail_message_get(PyObject *UNUSED(self), void *UNUSED(closure))
@@ -284,6 +286,7 @@ static PyGetSetDef bpy_app_getsets[] = {
{(char *)"debug_handlers", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_HANDLERS},
{(char *)"debug_wm", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_WM},
{(char *)"debug_depsgraph", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_DEPSGRAPH},
+ {(char *)"debug_simdata", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_SIMDATA},
{(char *)"debug_value", bpy_app_debug_value_get, bpy_app_debug_value_set, (char *)bpy_app_debug_value_doc, NULL},
{(char *)"tempdir", bpy_app_tempdir_get, NULL, (char *)bpy_app_tempdir_doc, NULL},
diff --git a/source/blender/python/intern/bpy_app_build_options.c b/source/blender/python/intern/bpy_app_build_options.c
index 022713558d7..975d76ca42d 100644
--- a/source/blender/python/intern/bpy_app_build_options.c
+++ b/source/blender/python/intern/bpy_app_build_options.c
@@ -57,6 +57,7 @@ static PyStructSequence_Field app_builtopts_info_fields[] = {
{(char *)"international", NULL},
{(char *)"openal", NULL},
{(char *)"sdl", NULL},
+ {(char *)"sdl_dynload", NULL},
{(char *)"jack", NULL},
{(char *)"libmv", NULL},
{(char *)"mod_boolean", NULL},
@@ -230,6 +231,12 @@ static PyObject *make_builtopts_info(void)
SetObjIncref(Py_False);
#endif
+#ifdef WITH_SDL_DYNLOAD
+ SetObjIncref(Py_True);
+#else
+ SetObjIncref(Py_False);
+#endif
+
#ifdef WITH_JACK
SetObjIncref(Py_True);
#else
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index 44da322efc0..6a8b0b065c2 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -37,6 +37,8 @@
#include "bpy_rna.h"
#include "bpy_app_handlers.h"
+#include "../generic/python_utildefines.h"
+
#include "BPY_extern.h"
void bpy_app_generic_callback(struct Main *main, struct ID *id, void *arg);
@@ -44,23 +46,24 @@ void bpy_app_generic_callback(struct Main *main, struct ID *id, void *arg);
static PyTypeObject BlenderAppCbType;
static PyStructSequence_Field app_cb_info_fields[] = {
- {(char *)"frame_change_pre", (char *)"Callback list - on frame change for playback and rendering (before)"},
- {(char *)"frame_change_post", (char *)"Callback list - on frame change for playback and rendering (after)"},
- {(char *)"render_pre", (char *)"Callback list - on render (before)"},
- {(char *)"render_post", (char *)"Callback list - on render (after)"},
- {(char *)"render_stats", (char *)"Callback list - on printing render statistics"},
- {(char *)"render_init", (char *)"Callback list - on initialization of a render job"},
- {(char *)"render_complete", (char *)"Callback list - on completion of render job"},
- {(char *)"render_cancel", (char *)"Callback list - on canceling a render job"},
- {(char *)"load_pre", (char *)"Callback list - on loading a new blend file (before)"},
- {(char *)"load_post", (char *)"Callback list - on loading a new blend file (after)"},
- {(char *)"save_pre", (char *)"Callback list - on saving a blend file (before)"},
- {(char *)"save_post", (char *)"Callback list - on saving a blend file (after)"},
- {(char *)"scene_update_pre", (char *)"Callback list - on updating the scenes data (before)"},
- {(char *)"scene_update_post", (char *)"Callback list - on updating the scenes data (after)"},
- {(char *)"game_pre", (char *)"Callback list - on starting the game engine"},
- {(char *)"game_post", (char *)"Callback list - on ending the game engine"},
- {(char *)"version_update", (char *)"Callback list - on ending the versioning code"},
+ {(char *)"frame_change_pre", (char *)"on frame change for playback and rendering (before)"},
+ {(char *)"frame_change_post", (char *)"on frame change for playback and rendering (after)"},
+ {(char *)"render_pre", (char *)"on render (before)"},
+ {(char *)"render_post", (char *)"on render (after)"},
+ {(char *)"render_write", (char *)"on writing a render frame (directly after the frame is written)"},
+ {(char *)"render_stats", (char *)"on printing render statistics"},
+ {(char *)"render_init", (char *)"on initialization of a render job"},
+ {(char *)"render_complete", (char *)"on completion of render job"},
+ {(char *)"render_cancel", (char *)"on canceling a render job"},
+ {(char *)"load_pre", (char *)"on loading a new blend file (before)"},
+ {(char *)"load_post", (char *)"on loading a new blend file (after)"},
+ {(char *)"save_pre", (char *)"on saving a blend file (before)"},
+ {(char *)"save_post", (char *)"on saving a blend file (after)"},
+ {(char *)"scene_update_pre", (char *)"on updating the scenes data (before)"},
+ {(char *)"scene_update_post", (char *)"on updating the scenes data (after)"},
+ {(char *)"game_pre", (char *)"on starting the game engine"},
+ {(char *)"game_post", (char *)"on ending the game engine"},
+ {(char *)"version_update", (char *)"on ending the versioning code"},
/* sets the permanent tag */
# define APP_CB_OTHER_FIELDS 1
@@ -71,7 +74,7 @@ static PyStructSequence_Field app_cb_info_fields[] = {
static PyStructSequence_Desc app_cb_info_desc = {
(char *)"bpy.app.handlers", /* name */
- (char *)"This module contains callbacks", /* doc */
+ (char *)"This module contains callback lists", /* doc */
app_cb_info_fields, /* fields */
ARRAY_SIZE(app_cb_info_fields) - 1
};
@@ -305,8 +308,7 @@ void bpy_app_generic_callback(struct Main *UNUSED(main), struct ID *id, void *ar
PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&id_ptr));
}
else {
- PyTuple_SET_ITEM(args, 0, Py_None);
- Py_INCREF(Py_None);
+ PyTuple_SET_ITEM(args, 0, Py_INCREF_RET(Py_None));
}
/* Iterate the list and run the callbacks
diff --git a/source/blender/python/intern/bpy_app_sdl.c b/source/blender/python/intern/bpy_app_sdl.c
new file mode 100644
index 00000000000..c91595b5900
--- /dev/null
+++ b/source/blender/python/intern/bpy_app_sdl.c
@@ -0,0 +1,136 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Sergey Sharybin, Sybren A. Stuvel
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_app_sdl.c
+ * \ingroup pythonintern
+ */
+
+#include <Python.h>
+#include "BLI_utildefines.h"
+
+#include "bpy_app_sdl.h"
+
+#ifdef WITH_SDL
+# include "SDL.h"
+# ifdef WITH_SDL_DYNLOAD
+# include "sdlew.h"
+# endif
+#endif
+
+static PyTypeObject BlenderAppSDLType;
+
+static PyStructSequence_Field app_sdl_info_fields[] = {
+ {(char *)"supported", (char *)("Boolean, True when Blender is built with SDL support")},
+ {(char *)"version", (char *)("The SDL version as a tuple of 3 numbers")},
+ {(char *)"version_string", (char *)("The SDL version formatted as a string")},
+ {(char *)"available", (char *)("Boolean, True when SDL is available. This is False when "
+ "either *supported* is False, or *dynload* is True and "
+ "Blender cannot find the correct library.")},
+ {NULL}
+};
+
+static PyStructSequence_Desc app_sdl_info_desc = {
+ (char *)"bpy.app.sdl", /* name */
+ (char *)"This module contains information about SDL blender is linked against", /* doc */
+ app_sdl_info_fields, /* fields */
+ ARRAY_SIZE(app_sdl_info_fields) - 1
+};
+
+static PyObject *make_sdl_info(void)
+{
+ PyObject *sdl_info;
+ int pos = 0;
+#ifdef WITH_SDL
+ bool sdl_available = false;
+ SDL_version version = {0, 0, 0};
+#endif
+
+ sdl_info = PyStructSequence_New(&BlenderAppSDLType);
+ if (sdl_info == NULL) {
+ return NULL;
+ }
+
+#define SetStrItem(str) \
+ PyStructSequence_SET_ITEM(sdl_info, pos++, PyUnicode_FromString(str))
+
+#define SetObjItem(obj) \
+ PyStructSequence_SET_ITEM(sdl_info, pos++, obj)
+
+#ifdef WITH_SDL
+ SetObjItem(PyBool_FromLong(1));
+
+# ifdef WITH_SDL_DYNLOAD
+ if (sdlewInit() == SDLEW_SUCCESS) {
+ SDL_GetVersion(&version);
+ sdl_available = true;
+ }
+# else // WITH_SDL_DYNLOAD=OFF
+ sdl_available = true;
+# if SDL_MAJOR_VERSION >= 2
+ SDL_GetVersion(&version);
+# else
+ SDL_VERSION(&version);
+# endif
+# endif
+
+ SetObjItem(Py_BuildValue("(iii)", version.major, version.minor, version.patch));
+ if (sdl_available) {
+ SetObjItem(PyUnicode_FromFormat("%d.%d.%d", version.major, version.minor, version.patch));
+ }
+ else {
+ SetStrItem("Unknown");
+ }
+ SetObjItem(PyBool_FromLong(sdl_available));
+
+#else // WITH_SDL=OFF
+ SetObjItem(PyBool_FromLong(0));
+ SetObjItem(Py_BuildValue("(iii)", 0, 0, 0));
+ SetStrItem("Unknown");
+ SetObjItem(PyBool_FromLong(0));
+#endif
+
+ if (PyErr_Occurred()) {
+ Py_CLEAR(sdl_info);
+ return NULL;
+ }
+
+#undef SetStrItem
+#undef SetObjItem
+
+ return sdl_info;
+}
+
+PyObject *BPY_app_sdl_struct(void)
+{
+ PyObject *ret;
+
+ PyStructSequence_InitType(&BlenderAppSDLType, &app_sdl_info_desc);
+
+ ret = make_sdl_info();
+
+ /* prevent user from creating new instances */
+ BlenderAppSDLType.tp_init = NULL;
+ BlenderAppSDLType.tp_new = NULL;
+ BlenderAppSDLType.tp_hash = (hashfunc)_Py_HashPointer; /* without this we can't do set(sys.modules) [#29635] */
+
+ return ret;
+}
diff --git a/source/blender/gpu/intern/gpu_extensions_private.h b/source/blender/python/intern/bpy_app_sdl.h
index a4124b8fa3d..e826a59de70 100644
--- a/source/blender/gpu/intern/gpu_extensions_private.h
+++ b/source/blender/python/intern/bpy_app_sdl.h
@@ -15,18 +15,18 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
+ * Contributor(s): Sergey Sharybin, Sybren A. Stuvel
+ *
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file gpu_extensions_private.h
- * \ingroup gpu
+/** \file blender/python/intern/bpy_app_sdl.h
+ * \ingroup pythonintern
*/
-#ifndef __GPU_EXTENSIONS_PRIVATE_H__
-#define __GPU_EXTENSIONS_PRIVATE_H__
+#ifndef __BPY_APP_SDL_H__
+#define __BPY_APP_SDL_H__
-/* call this before running any of the functions below */
-void gpu_extensions_init(void);
-void gpu_extensions_exit(void);
+PyObject *BPY_app_sdl_struct(void);
-#endif /* __GPU_EXTENSIONS_PRIVATE_H__ */
+#endif /* __BPY_APP_SDL_H__ */
diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c
index 0114e8e65e4..123b111f3cb 100644
--- a/source/blender/python/intern/bpy_app_translations.c
+++ b/source/blender/python/intern/bpy_app_translations.c
@@ -44,8 +44,8 @@
#include "BLF_translation.h"
#include "RNA_types.h"
-#include "RNA_access.h"
+#include "../generic/python_utildefines.h"
typedef struct
{
@@ -242,12 +242,9 @@ static void _build_translations_cache(PyObject *py_messages, const char *locale)
}
/* Clean up! */
- if (language)
- MEM_freeN(language);
- if (language_country)
- MEM_freeN(language_country);
- if (language_variant)
- MEM_freeN(language_variant);
+ MEM_SAFE_FREE(language);
+ MEM_SAFE_FREE(language_country);
+ MEM_SAFE_FREE(language_variant);
}
const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *msgid)
@@ -263,7 +260,7 @@ const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *ms
return msgid;
tmp = BLF_lang_get();
- if (strcmp(tmp, locale) || !_translations_cache) {
+ if (!STREQ(tmp, locale) || !_translations_cache) {
PyGILState_STATE _py_state;
BLI_strncpy(locale, tmp, STATIC_LOCALE_SIZE);
@@ -410,7 +407,7 @@ static PyObject *app_translations_contexts_make(void)
}
#define SetObjString(item) PyStructSequence_SET_ITEM(translations_contexts, pos++, PyUnicode_FromString((item)))
-#define SetObjNone() Py_INCREF(Py_None); PyStructSequence_SET_ITEM(translations_contexts, pos++, Py_None)
+#define SetObjNone() PyStructSequence_SET_ITEM(translations_contexts, pos++, Py_INCREF_RET(Py_None))
for (ctxt = _contexts; ctxt->c_id; ctxt++) {
if (ctxt->value) {
@@ -430,11 +427,11 @@ static PyObject *app_translations_contexts_make(void)
/***** Main BlenderAppTranslations Py object definition *****/
PyDoc_STRVAR(app_translations_contexts_doc,
- "A named tuple containing all pre-defined translation contexts.\n"
- "\n"
- ".. warning::\n"
- " Never use a (new) context starting with \"" BLF_I18NCONTEXT_DEFAULT_BPYRNA "\", it would be internally \n"
- " assimilated as the default one!\n"
+"A named tuple containing all pre-defined translation contexts.\n"
+"\n"
+".. warning::\n"
+" Never use a (new) context starting with \"" BLF_I18NCONTEXT_DEFAULT_BPYRNA "\", it would be internally \n"
+" assimilated as the default one!\n"
);
PyDoc_STRVAR(app_translations_contexts_C_to_py_doc,
@@ -450,8 +447,8 @@ static PyMemberDef app_translations_members[] = {
};
PyDoc_STRVAR(app_translations_locale_doc,
- "The actual locale currently in use (will always return a void string when Blender is built without "
- "internationalization support)."
+"The actual locale currently in use (will always return a void string when Blender is built without "
+"internationalization support)."
);
static PyObject *app_translations_locale_get(PyObject *UNUSED(self), void *UNUSED(userdata))
{
@@ -520,9 +517,7 @@ static PyObject *_py_pgettext(PyObject *args, PyObject *kw, const char *(*_pgett
return NULL;
}
- Py_INCREF(msgid);
-
- return msgid;
+ return Py_INCREF_RET(msgid);
#endif
}
@@ -632,6 +627,7 @@ PyDoc_STRVAR(app_translations_locale_explode_doc,
);
static PyObject *app_translations_locale_explode(BlenderAppTranslations *UNUSED(self), PyObject *args, PyObject *kw)
{
+ PyObject *ret_tuple;
static const char *kwlist[] = {"locale", NULL};
const char *locale;
char *language, *country, *variant, *language_country, *language_variant;
@@ -642,7 +638,15 @@ static PyObject *app_translations_locale_explode(BlenderAppTranslations *UNUSED(
BLF_locale_explode(locale, &language, &country, &variant, &language_country, &language_variant);
- return Py_BuildValue("sssss", language, country, variant, language_country, language_variant);
+ ret_tuple = Py_BuildValue("sssss", language, country, variant, language_country, language_variant);
+
+ MEM_SAFE_FREE(language);
+ MEM_SAFE_FREE(country);
+ MEM_SAFE_FREE(variant);
+ MEM_SAFE_FREE(language_country);
+ MEM_SAFE_FREE(language_variant);
+
+ return ret_tuple;
}
static PyMethodDef app_translations_methods[] = {
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index b51de01103c..df848f6b60c 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -245,7 +245,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime)
expr_vars = PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
Py_XDECREF(expr_vars);
- expr_vars = PyTuple_New(BLI_countlist(&driver->variables));
+ expr_vars = PyTuple_New(BLI_listbase_count(&driver->variables));
PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars);
for (dvar = driver->variables.first, i = 0; dvar; dvar = dvar->next) {
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 971616f5c1a..f0c0e2c5fe8 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -63,6 +63,7 @@
#include "DNA_text_types.h"
+#include "BKE_appdir.h"
#include "BKE_context.h"
#include "BKE_text.h"
#include "BKE_main.h"
@@ -246,11 +247,11 @@ void BPY_python_start(int argc, const char **argv)
{
#ifndef WITH_PYTHON_MODULE
PyThreadState *py_tstate = NULL;
- const char *py_path_bundle = BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL);
+ const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL);
/* not essential but nice to set our name */
static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */
- BLI_strncpy_wchar_from_utf8(program_path_wchar, BLI_program_path(), ARRAY_SIZE(program_path_wchar));
+ BLI_strncpy_wchar_from_utf8(program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar));
Py_SetProgramName(program_path_wchar);
/* must run before python initializes */
diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c
index 3d7d08024c7..3b95b99a0a1 100644
--- a/source/blender/python/intern/bpy_library.c
+++ b/source/blender/python/intern/bpy_library.c
@@ -53,6 +53,8 @@
#include "bpy_util.h"
#include "bpy_library.h"
+#include "../generic/python_utildefines.h"
+
/* nifty feature. swap out strings for RNA data */
#define USE_RNA_DATABLOCKS
@@ -274,10 +276,9 @@ static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args))
/* return pair */
ret = PyTuple_New(2);
-
- PyTuple_SET_ITEM(ret, 0, (PyObject *)self_from);
-
- PyTuple_SET_ITEM(ret, 1, (PyObject *)self);
+ PyTuple_SET_ITEMS(ret,
+ (PyObject *)self_from,
+ (PyObject *)self);
Py_INCREF(self);
BKE_reports_clear(&reports);
@@ -362,8 +363,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
/* just warn for now */
/* err = -1; */
#ifdef USE_RNA_DATABLOCKS
- item = Py_None;
- Py_INCREF(item);
+ item = Py_INCREF_RET(Py_None);
#endif
}
@@ -375,8 +375,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
PyErr_Clear();
#ifdef USE_RNA_DATABLOCKS
- item = Py_None;
- Py_INCREF(item);
+ item = Py_INCREF_RET(Py_None);
#endif
}
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 1e97d7aeada..aad47d14b7c 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -44,6 +44,7 @@
#include "bpy_rna.h" /* for setting arg props only - pyrna_py_to_prop() */
#include "bpy_util.h"
#include "../generic/bpy_internal_import.h"
+#include "../generic/python_utildefines.h"
#include "RNA_access.h"
#include "RNA_enum_types.h"
@@ -127,9 +128,8 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
/* restore with original context dict, probably NULL but need this for nested operator calls */
Py_XDECREF(context_dict);
CTX_py_dict_set(C, (void *)context_dict_back);
-
- Py_INCREF(ret);
- return ret;
+
+ return Py_INCREF_RET(ret);
}
static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
@@ -367,17 +367,17 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
static PyObject *pyop_dir(PyObject *UNUSED(self))
{
- GHashIterator *iter = WM_operatortype_iter();
- PyObject *list = PyList_New(0), *name;
+ GHashIterator iter;
+ PyObject *list;
+ int i;
- for ( ; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) {
- wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
+ WM_operatortype_iter(&iter);
+ list = PyList_New(BLI_ghash_size(iter.gh));
- name = PyUnicode_FromString(ot->idname);
- PyList_Append(list, name);
- Py_DECREF(name);
+ for (i = 0; !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter), i++) {
+ wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
+ PyList_SET_ITEM(list, i, PyUnicode_FromString(ot->idname));
}
- BLI_ghashIterator_free(iter);
return list;
}
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 9a8c3d89e8d..8370aea4c99 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -64,6 +64,7 @@ static EnumPropertyItem property_flag_items[] = {
{PROP_ANIMATABLE, "ANIMATABLE", 0, "Animatable", ""},
{PROP_LIB_EXCEPTION, "LIBRARY_EDITABLE", 0, "Library Editable", ""},
{PROP_PROPORTIONAL, "PROPORTIONAL", 0, "Adjust values proportionally to eachother", ""},
+ {PROP_TEXTEDIT_UPDATE, "TEXTEDIT_UPDATE", 0, "Update on every keystroke in textedit 'mode'", ""},
{0, NULL, 0, NULL, NULL}};
#define BPY_PROPDEF_OPTIONS_DOC \
@@ -192,6 +193,19 @@ static void printf_func_error(PyObject *py_func)
);
}
+static void bpy_prop_assign_flag(PropertyRNA *prop, const int flag)
+{
+ const int flag_mask = ((PROP_ANIMATABLE) & ~flag);
+
+ if (flag) {
+ RNA_def_property_flag(prop, flag);
+ }
+
+ if (flag_mask) {
+ RNA_def_property_clear_flag(prop, flag_mask);
+ }
+}
+
/* operators and classes use this so it can store the args given but defer
* running it until the operator runs where these values are used to setup
* the default args for that operator instance */
@@ -1361,7 +1375,8 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
(tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
/* TODO, number isn't ensured to be unique from the script author */
(item_size != 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1) &&
- (item_size != 5 || ((tmp_icon = _PyUnicode_AsString(PyTuple_GET_ITEM(item, 3))) &&
+ (item_size != 5 || ((py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.icon) != -1 ||
+ (tmp_icon = _PyUnicode_AsString(PyTuple_GET_ITEM(item, 3)))) &&
py_long_as_int(PyTuple_GET_ITEM(item, 4), &tmp.value) != -1)))
{
if (is_enum_flag) {
@@ -1955,10 +1970,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
RNA_def_property_ui_text(prop, name ? name : id, description);
if (pyopts) {
- if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
- if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ bpy_prop_assign_flag(prop, opts);
}
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_boolean(prop, get_cb, set_cb);
@@ -2054,10 +2066,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
RNA_def_property_ui_text(prop, name ? name : id, description);
if (pyopts) {
- if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
- if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ bpy_prop_assign_flag(prop, opts);
}
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb);
@@ -2151,10 +2160,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
if (pyopts) {
- if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
- if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ bpy_prop_assign_flag(prop, opts);
}
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_int(prop, get_cb, set_cb);
@@ -2266,10 +2272,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
if (pyopts) {
- if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
- if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ bpy_prop_assign_flag(prop, opts);
}
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_int_array(prop, get_cb, set_cb);
@@ -2377,10 +2380,7 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
if (pyopts) {
- if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
- if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ bpy_prop_assign_flag(prop, opts);
}
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_float(prop, get_cb, set_cb);
@@ -2504,10 +2504,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
if (pyopts) {
- if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
- if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ bpy_prop_assign_flag(prop, opts);
}
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_float_array(prop, get_cb, set_cb);
@@ -2590,10 +2587,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
RNA_def_property_ui_text(prop, name ? name : id, description);
if (pyopts) {
- if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
- if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ bpy_prop_assign_flag(prop, opts);
}
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_string(prop, get_cb, set_cb);
@@ -2606,7 +2600,7 @@ PyDoc_STRVAR(BPy_EnumProperty_doc,
".. function:: EnumProperty(items, "
"name=\"\", "
"description=\"\", "
- "default=\"\", "
+ "default=None, "
"options={'ANIMATABLE'}, "
"update=None, "
"get=None, "
@@ -2618,8 +2612,8 @@ PyDoc_STRVAR(BPy_EnumProperty_doc,
" [(identifier, name, description, icon, number), ...] where the identifier is used\n"
" for python access and other values are used for the interface.\n"
" The three first elements of the tuples are mandatory.\n"
-" The forth one is either the (unique!) number id of the item or, if followed by a fith element \n"
-" (which must be the numid), an icon string identifier.\n"
+" The forth one is either the (unique!) number id of the item or, if followed by a fith element\n"
+" (which must be the numid), an icon string identifier or integer icon value (e.g. returned by icon()...).\n"
" Note the item is optional.\n"
" For dynamic values a callback can be passed which returns a list in\n"
" the same format as the static list.\n"
@@ -2631,6 +2625,8 @@ BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
" :arg default: The default value for this enum, a string from the identifiers used in *items*.\n"
" If the *ENUM_FLAG* option is used this must be a set of such string identifiers instead.\n"
+" WARNING: It shall not be specified (or specified to its default *None* value) for dynamic enums\n"
+" (i.e. if a callback function is given as *items* parameter).\n"
" :type default: string or set\n"
BPY_PROPDEF_OPTIONS_ENUM_DOC
BPY_PROPDEF_UPDATE_DOC
@@ -2682,6 +2678,12 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
+ if (def == Py_None) {
+ /* This allows to get same behavior when explicitely passing None as default value,
+ * and not defining a default value at all! */
+ def = NULL;
+ }
+
/* items can be a list or a callable */
if (PyFunction_Check(items)) { /* don't use PyCallable_Check because we need the function code for errors */
PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(items);
@@ -2722,10 +2724,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description);
if (pyopts) {
- if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
- if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ bpy_prop_assign_flag(prop, opts);
}
bpy_prop_callback_assign_update(prop, update_cb);
bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL));
@@ -2828,10 +2827,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
prop = RNA_def_pointer_runtime(srna, id, ptype, name ? name : id, description);
if (pyopts) {
- if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
- if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ bpy_prop_assign_flag(prop, opts);
}
bpy_prop_callback_assign_update(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
@@ -2885,10 +2881,7 @@ static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject
prop = RNA_def_collection_runtime(srna, id, ptype, name ? name : id, description);
if (pyopts) {
- if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
- if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+ bpy_prop_assign_flag(prop, opts);
}
RNA_def_property_duplicate_pointers(srna, prop);
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index f6e97d6a2d8..fadc50e3317 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -76,10 +76,7 @@
#include "../generic/idprop_py_api.h" /* for IDprop lookups */
#include "../generic/py_capi_utils.h"
-
-#ifdef WITH_INTERNATIONAL
-# include "BLF_translation.h"
-#endif
+#include "../generic/python_utildefines.h"
#define USE_PEDANTIC_WRITE
#define USE_MATHUTILS
@@ -641,7 +638,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
case PROP_ALL_VECTOR_SUBTYPES:
if (len >= 2 && len <= 4) {
if (is_thick) {
- ret = Vector_CreatePyObject(NULL, len, Py_NEW, NULL);
+ ret = Vector_CreatePyObject(NULL, len, NULL);
RNA_property_float_get_array(ptr, prop, ((VectorObject *)ret)->vec);
}
else {
@@ -654,7 +651,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
case PROP_MATRIX:
if (len == 16) {
if (is_thick) {
- ret = Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, NULL);
+ ret = Matrix_CreatePyObject(NULL, 4, 4, NULL);
RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
@@ -665,7 +662,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
}
else if (len == 9) {
if (is_thick) {
- ret = Matrix_CreatePyObject(NULL, 3, 3, Py_NEW, NULL);
+ ret = Matrix_CreatePyObject(NULL, 3, 3, NULL);
RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
@@ -683,7 +680,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
PropertyRNA *prop_eul_order = NULL;
short order = pyrna_rotation_euler_order_get(ptr, &prop_eul_order, EULER_ORDER_XYZ);
- ret = Euler_CreatePyObject(NULL, order, Py_NEW, NULL); /* TODO, get order from RNA */
+ ret = Euler_CreatePyObject(NULL, order, NULL); /* TODO, get order from RNA */
RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
}
else {
@@ -695,7 +692,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
}
else if (len == 4) {
if (is_thick) {
- ret = Quaternion_CreatePyObject(NULL, Py_NEW, NULL);
+ ret = Quaternion_CreatePyObject(NULL, NULL);
RNA_property_float_get_array(ptr, prop, ((QuaternionObject *)ret)->quat);
}
else {
@@ -709,7 +706,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
case PROP_COLOR_GAMMA:
if (len == 3) { /* color */
if (is_thick) {
- ret = Color_CreatePyObject(NULL, Py_NEW, NULL);
+ ret = Color_CreatePyObject(NULL, NULL);
RNA_property_float_get_array(ptr, prop, ((ColorObject *)ret)->col);
}
else {
@@ -809,7 +806,7 @@ static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
return NULL;
}
- return Py_INCREF(res), res;
+ return Py_INCREF_RET(res);
}
static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
@@ -839,7 +836,7 @@ static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
return NULL;
}
- return Py_INCREF(res), res;
+ return Py_INCREF_RET(res);
}
/*----------------------repr--------------------------------------------*/
@@ -2305,8 +2302,7 @@ static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self, Py
RNA_property_collection_next(&rna_macro_iter))
{
item = pyrna_struct_CreatePyObject(&rna_macro_iter.ptr);
- PyList_Append(list, item);
- Py_DECREF(item);
+ PyList_APPEND(list, item);
count++;
if (count == stop) {
@@ -3188,6 +3184,34 @@ static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *
return PyBool_FromLong(RNA_property_flag(prop) & PROP_HIDDEN);
}
+PyDoc_STRVAR(pyrna_struct_is_property_readonly_doc,
+".. method:: is_property_readonly(property)\n"
+"\n"
+" Check if a property is readonly.\n"
+"\n"
+" :return: True when the property is readonly (not writable).\n"
+" :rtype: boolean\n"
+);
+static PyObject *pyrna_struct_is_property_readonly(BPy_StructRNA *self, PyObject *args)
+{
+ PropertyRNA *prop;
+ const char *name;
+
+ PYRNA_STRUCT_CHECK_OBJ(self);
+
+ if (!PyArg_ParseTuple(args, "s:is_property_readonly", &name))
+ return NULL;
+
+ if ((prop = RNA_struct_find_property(&self->ptr, name)) == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.is_property_readonly(\"%.200s\") not found",
+ RNA_struct_identifier(self->ptr.type), name);
+ return NULL;
+ }
+
+ return PyBool_FromLong(!RNA_property_editable(&self->ptr, prop));
+}
+
PyDoc_STRVAR(pyrna_struct_path_resolve_doc,
".. method:: path_resolve(path, coerce=True)\n"
"\n"
@@ -3430,7 +3454,6 @@ static void pyrna_dir_members_py(PyObject *list, PyObject *self)
static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
{
- PyObject *pystring;
const char *idname;
/* for looping over attrs and funcs */
@@ -3446,10 +3469,7 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
FunctionRNA *func = itemptr.data;
if (RNA_function_defined(func)) {
idname = RNA_function_identifier(itemptr.data);
-
- pystring = PyUnicode_FromString(idname);
- PyList_Append(list, pystring);
- Py_DECREF(pystring);
+ PyList_APPEND(list, PyUnicode_FromString(idname));
}
}
RNA_PROP_END;
@@ -3469,9 +3489,7 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
if (nameptr) {
- pystring = PyUnicode_FromStringAndSize(nameptr, namelen);
- PyList_Append(list, pystring);
- Py_DECREF(pystring);
+ PyList_APPEND(list, PyUnicode_FromStringAndSize(nameptr, namelen));
if (name != nameptr) {
MEM_freeN(nameptr);
@@ -3486,7 +3504,6 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
{
PyObject *ret;
- PyObject *pystring;
PYRNA_STRUCT_CHECK_OBJ(self);
@@ -3505,9 +3522,7 @@ static PyObject *pyrna_struct_dir(BPy_StructRNA *self)
LinkData *link;
for (link = lb.first; link; link = link->next) {
- pystring = PyUnicode_FromString(link->data);
- PyList_Append(ret, pystring);
- Py_DECREF(pystring);
+ PyList_APPEND(ret, PyUnicode_FromString(link->data));
}
BLI_freelistN(&lb);
@@ -3587,14 +3602,11 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
case CTX_DATA_TYPE_COLLECTION:
{
CollectionPointerLink *link;
- PyObject *linkptr;
ret = PyList_New(0);
for (link = newlb.first; link; link = link->next) {
- linkptr = pyrna_struct_CreatePyObject(&link->ptr);
- PyList_Append(ret, linkptr);
- Py_DECREF(linkptr);
+ PyList_APPEND(ret, pyrna_struct_CreatePyObject(&link->ptr));
}
break;
}
@@ -4101,7 +4113,6 @@ PyDoc_STRVAR(pyrna_prop_collection_keys_doc,
static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self)
{
PyObject *ret = PyList_New(0);
- PyObject *item;
char name[256], *nameptr;
int namelen;
@@ -4110,11 +4121,7 @@ static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self)
nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
if (nameptr) {
- /* add to python list */
- item = PyUnicode_FromStringAndSize(nameptr, namelen);
- PyList_Append(ret, item);
- Py_DECREF(item);
- /* done */
+ PyList_APPEND(ret, PyUnicode_FromStringAndSize(nameptr, namelen));
if (name != nameptr) {
MEM_freeN(nameptr);
@@ -4160,8 +4167,7 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
}
PyTuple_SET_ITEM(item, 1, pyrna_struct_CreatePyObject(&itemptr));
- PyList_Append(ret, item);
- Py_DECREF(item);
+ PyList_APPEND(ret, item);
i++;
}
@@ -4227,7 +4233,7 @@ static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
}
}
- return Py_INCREF(def), def;
+ return Py_INCREF_RET(def);
}
PyDoc_STRVAR(pyrna_struct_as_pointer_doc,
@@ -4289,7 +4295,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
Py_TYPE(key_ob)->tp_name);
}
- return Py_INCREF(def), def;
+ return Py_INCREF_RET(def);
}
PyDoc_STRVAR(pyrna_prop_collection_find_doc,
@@ -4698,6 +4704,7 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, pyrna_struct_is_property_set_doc},
{"property_unset", (PyCFunction)pyrna_struct_property_unset, METH_VARARGS, pyrna_struct_property_unset_doc},
{"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, pyrna_struct_is_property_hidden_doc},
+ {"is_property_readonly", (PyCFunction)pyrna_struct_is_property_readonly, METH_VARARGS, pyrna_struct_is_property_readonly_doc},
{"path_resolve", (PyCFunction)pyrna_struct_path_resolve, METH_VARARGS, pyrna_struct_path_resolve_doc},
{"path_from_id", (PyCFunction)pyrna_struct_path_from_id, METH_VARARGS, pyrna_struct_path_from_id_doc},
{"type_recast", (PyCFunction)pyrna_struct_type_recast, METH_NOARGS, pyrna_struct_type_recast_doc},
@@ -4802,8 +4809,7 @@ static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UN
return NULL;
if (type == Py_TYPE(base)) {
- Py_INCREF(base);
- return (PyObject *)base;
+ return Py_INCREF_RET((PyObject *)base);
}
else if (PyType_IsSubtype(type, &pyrna_prop_Type)) {
BPy_PropertyRNA *ret = (BPy_PropertyRNA *) type->tp_alloc(type, 0);
@@ -4855,15 +4861,15 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
switch (RNA_property_subtype(prop)) {
#ifdef USE_MATHUTILS
case PROP_ALL_VECTOR_SUBTYPES:
- ret = Vector_CreatePyObject(data, len, Py_NEW, NULL);
+ ret = Vector_CreatePyObject(data, len, NULL);
break;
case PROP_MATRIX:
if (len == 16) {
- ret = Matrix_CreatePyObject(data, 4, 4, Py_NEW, NULL);
+ ret = Matrix_CreatePyObject(data, 4, 4, NULL);
break;
}
else if (len == 9) {
- ret = Matrix_CreatePyObject(data, 3, 3, Py_NEW, NULL);
+ ret = Matrix_CreatePyObject(data, 3, 3, NULL);
break;
}
/* fall-through */
@@ -4971,14 +4977,11 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
{
ListBase *lb = (ListBase *)data;
CollectionPointerLink *link;
- PyObject *linkptr;
ret = PyList_New(0);
for (link = lb->first; link; link = link->next) {
- linkptr = pyrna_struct_CreatePyObject(&link->ptr);
- PyList_Append(ret, linkptr);
- Py_DECREF(linkptr);
+ PyList_APPEND(ret, pyrna_struct_CreatePyObject(&link->ptr));
}
break;
@@ -5142,9 +5145,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
#ifdef DEBUG_STRING_FREE
if (item) {
if (PyUnicode_Check(item)) {
- item = PyUnicode_FromString(_PyUnicode_AsString(item));
- PyList_Append(string_free_ls, item);
- Py_DECREF(item);
+ PyList_APPEND(string_free_ls, PyUnicode_FromString(_PyUnicode_AsString(item)));
}
}
#endif
@@ -6287,7 +6288,7 @@ static PyObject *pyrna_srna_Subtype(StructRNA *srna)
/* arg[1] (bases=...) */
PyTuple_SET_ITEM(args, 1, item = PyTuple_New(1));
- PyTuple_SET_ITEM(item, 0, py_base); Py_INCREF(py_base);
+ PyTuple_SET_ITEM(item, 0, Py_INCREF_RET(py_base));
/* arg[2] (dict=...) */
@@ -6601,7 +6602,6 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
{
PyObject *list;
#if 0
- PyObject *name;
PyMethodDef *meth;
#endif
@@ -6609,9 +6609,7 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
#if 0 /* for now only contains __dir__ */
for (meth = pyrna_basetype_methods; meth->ml_name; meth++) {
- name = PyUnicode_FromString(meth->ml_name);
- PyList_Append(list, name);
- Py_DECREF(name);
+ PyList_APPEND(list, PyUnicode_FromString(meth->ml_name));
}
#endif
return list;
@@ -6622,7 +6620,6 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
{
PyObject *ret = PyList_New(0);
- PyObject *item;
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop)
{
@@ -6634,9 +6631,7 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
}
else {
/* add to python list */
- item = PyUnicode_FromString(RNA_struct_identifier(srna));
- PyList_Append(ret, item);
- Py_DECREF(item);
+ PyList_APPEND(ret, PyUnicode_FromString(RNA_struct_identifier(srna)));
}
}
RNA_PROP_END;
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index ed51ba5bd1f..ced7d6a5c1c 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -53,6 +53,8 @@
#include "bpy_util.h"
#include "bpy_rna_anim.h"
+#include "../generic/python_utildefines.h"
+
/* for keyframes and drivers */
static int pyrna_struct_anim_args_parse(
PointerRNA *ptr, const char *error_prefix, const char *path,
@@ -329,16 +331,13 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
FCurve *fcu;
PointerRNA tptr;
- PyObject *item;
if (index == -1) { /* all, use a list */
int i = 0;
ret = PyList_New(0);
while ((fcu = list_find_fcurve(&adt->drivers, path_full, i++))) {
RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
- item = pyrna_struct_CreatePyObject(&tptr);
- PyList_Append(ret, item);
- Py_DECREF(item);
+ PyList_APPEND(ret, pyrna_struct_CreatePyObject(&tptr));
}
}
else {
diff --git a/source/blender/python/intern/bpy_utils_units.c b/source/blender/python/intern/bpy_utils_units.c
index cdbd57bcebe..a6df8f54cc3 100644
--- a/source/blender/python/intern/bpy_utils_units.c
+++ b/source/blender/python/intern/bpy_utils_units.c
@@ -35,9 +35,7 @@
#include "BLI_utildefines.h"
#include "BLI_string.h"
-#include "BLI_ghash.h"
-#include "BPY_extern.h"
#include "bpy_utils_units.h"
#include "../generic/py_capi_utils.h"
diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c
index 26e3bde57a3..e4580e8035b 100644
--- a/source/blender/python/intern/gpu.c
+++ b/source/blender/python/intern/gpu.c
@@ -40,7 +40,6 @@
#include <Python.h>
#include "DNA_scene_types.h"
-#include "DNA_image_types.h"
#include "DNA_material_types.h"
#include "DNA_ID.h"
#include "DNA_customdata_types.h"
@@ -200,7 +199,7 @@ static PyObject *GPU_export_shader(PyObject *UNUSED(self), PyObject *args, PyObj
if (shader->vertex) {
PY_DICT_ADD_STRING(result, shader, vertex);
}
- seq = PyList_New(BLI_countlist(&shader->uniforms));
+ seq = PyList_New(BLI_listbase_count(&shader->uniforms));
for (i = 0, uniform = shader->uniforms.first; uniform; uniform = uniform->next, i++) {
dict = PyDict_New();
PY_DICT_ADD_STRING(dict, uniform, varname);
@@ -229,7 +228,7 @@ static PyObject *GPU_export_shader(PyObject *UNUSED(self), PyObject *args, PyObj
PyDict_SetItemString(result, "uniforms", seq);
Py_DECREF(seq);
- seq = PyList_New(BLI_countlist(&shader->attributes));
+ seq = PyList_New(BLI_listbase_count(&shader->attributes));
for (i = 0, attribute = shader->attributes.first; attribute; attribute = attribute->next, i++) {
dict = PyDict_New();
PY_DICT_ADD_STRING(dict, attribute, varname);
diff --git a/source/blender/python/mathutils/CMakeLists.txt b/source/blender/python/mathutils/CMakeLists.txt
index 133b8d3895c..ef6b090140b 100644
--- a/source/blender/python/mathutils/CMakeLists.txt
+++ b/source/blender/python/mathutils/CMakeLists.txt
@@ -38,6 +38,7 @@ set(SRC
mathutils_Quaternion.c
mathutils_Vector.c
mathutils_geometry.c
+ mathutils_interpolate.c
mathutils_kdtree.c
mathutils_noise.c
@@ -48,6 +49,7 @@ set(SRC
mathutils_Quaternion.h
mathutils_Vector.h
mathutils_geometry.h
+ mathutils_interpolate.h
mathutils_kdtree.h
mathutils_noise.h
)
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index 349f8483fb0..7b51b08451b 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -31,12 +31,25 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "../generic/python_utildefines.h"
+
#ifndef MATH_STANDALONE
# include "BLI_dynstr.h"
#endif
PyDoc_STRVAR(M_Mathutils_doc,
-"This module provides access to matrices, eulers, quaternions and vectors."
+"This module provides access to the math classes:\n"
+"\n"
+"- :class:`Color`,\n"
+"- :class:`Euler`,\n"
+"- :class:`Matrix`,\n"
+"- :class:`Quaternion`,\n"
+"- :class:`Vector`,\n"
+"\n"
+".. note::\n"
+"\n"
+" Classes, methods and attributes that accept vectors also accept other numeric sequences,\n"
+" such as tuples, lists."
);
static int mathutils_array_parse_fast(float *array,
int size,
@@ -66,11 +79,45 @@ static int mathutils_array_parse_fast(float *array,
return size;
}
+/**
+ * helper function that returns a Python ``__hash__``.
+ *
+ * \note consistent with the equivalent tuple of floats (CPython's 'tuplehash')
+ */
+Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
+{
+ int i;
+ Py_uhash_t x; /* Unsigned for defined overflow behavior. */
+ Py_hash_t y;
+ Py_uhash_t mult;
+ Py_ssize_t len;
+
+ mult = _PyHASH_MULTIPLIER;
+ len = array_len;
+ x = 0x345678UL;
+ i = 0;
+ while (--len >= 0) {
+ y = _Py_HashDouble((double)(array[i++]));
+ if (y == -1)
+ return -1;
+ x = (x ^ y) * mult;
+ /* the cast might truncate len; that doesn't change hash stability */
+ mult += (Py_hash_t)(82520UL + len + len);
+ }
+ x += 97531UL;
+ if (x == (Py_uhash_t)-1)
+ x = -2;
+ return x;
+}
+
/* helper functionm returns length of the 'value', -1 on error */
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
{
+ const int flag = array_max;
int size;
+ array_max &= ~MU_ARRAY_FLAGS;
+
#if 1 /* approx 6x speedup for mathutils types */
if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
@@ -82,6 +129,10 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
return -1;
}
+ if (flag & MU_ARRAY_SPILL) {
+ CLAMP_MAX(size, array_max);
+ }
+
if (size > array_max || size < array_min) {
if (array_max == array_min) {
PyErr_Format(PyExc_ValueError,
@@ -97,7 +148,6 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
}
memcpy(array, ((BaseMathObject *)value)->data, size * sizeof(float));
- return size;
}
else
#endif
@@ -112,6 +162,10 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
size = PySequence_Fast_GET_SIZE(value_fast);
+ if (flag & MU_ARRAY_SPILL) {
+ CLAMP_MAX(size, array_max);
+ }
+
if (size > array_max || size < array_min) {
if (array_max == array_min) {
PyErr_Format(PyExc_ValueError,
@@ -127,8 +181,19 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
return -1;
}
- return mathutils_array_parse_fast(array, size, value_fast, error_prefix);
+ size = mathutils_array_parse_fast(array, size, value_fast, error_prefix);
}
+
+ if (size != -1) {
+ if (flag & MU_ARRAY_ZERO) {
+ int size_left = array_max - size;
+ if (size_left) {
+ memset(&array[size], 0, sizeof(float) * size_left);
+ }
+ }
+ }
+
+ return size;
}
/* on error, -1 is returned and no allocation is made */
@@ -196,6 +261,7 @@ int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, c
int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value, const char *error_prefix)
{
PyObject *value_fast = NULL;
+ const int array_dim_flag = array_dim;
int i, size;
/* non list/tuple cases */
@@ -209,12 +275,14 @@ int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value,
if (size != 0) {
float *fp;
+ array_dim &= ~MU_ARRAY_FLAGS;
+
fp = *array = PyMem_Malloc(size * array_dim * sizeof(float));
for (i = 0; i < size; i++, fp += array_dim) {
PyObject *item = PySequence_Fast_GET_ITEM(value, i);
- if (mathutils_array_parse(fp, array_dim, array_dim, item, error_prefix) == -1) {
+ if (mathutils_array_parse(fp, array_dim, array_dim_flag, item, error_prefix) == -1) {
PyMem_Free(*array);
*array = NULL;
size = -1;
@@ -415,19 +483,59 @@ int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index)
return -1;
}
+void _BaseMathObject_RaiseFrozenExc(const BaseMathObject *self)
+{
+ PyErr_Format(PyExc_TypeError,
+ "%s is frozen (immutable)",
+ Py_TYPE(self)->tp_name);
+}
+
+void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self)
+{
+ PyErr_Format(PyExc_TypeError,
+ "%s is not frozen (mutable), call freeze first",
+ Py_TYPE(self)->tp_name);
+}
+
/* BaseMathObject generic functions for all mathutils types */
char BaseMathObject_owner_doc[] = "The item this is wrapping or None (read-only).";
PyObject *BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure))
{
PyObject *ret = self->cb_user ? self->cb_user : Py_None;
- Py_INCREF(ret);
- return ret;
+ return Py_INCREF_RET(ret);
}
char BaseMathObject_is_wrapped_doc[] = "True when this object wraps external data (read-only).\n\n:type: boolean";
PyObject *BaseMathObject_is_wrapped_get(BaseMathObject *self, void *UNUSED(closure))
{
- return PyBool_FromLong((self->wrapped == Py_WRAP) ? 1 : 0);
+ return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_WRAP) != 0);
+}
+
+char BaseMathObject_is_frozen_doc[] = "True when this object has been frozen (read-only).\n\n:type: boolean";
+PyObject *BaseMathObject_is_frozen_get(BaseMathObject *self, void *UNUSED(closure))
+{
+ return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_FROZEN) != 0);
+}
+
+char BaseMathObject_freeze_doc[] =
+".. function:: freeze()\n"
+"\n"
+" Make this object immutable.\n"
+"\n"
+" After this the object can be hashed, used in dictionaries & sets.\n"
+"\n"
+" :return: An instance of this object.\n"
+;
+PyObject *BaseMathObject_freeze(BaseMathObject *self)
+{
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
+ PyErr_SetString(PyExc_TypeError, "Cannot freeze wrapped data");
+ return NULL;
+ }
+
+ self->flag |= BASE_MATH_FLAG_IS_FROZEN;
+
+ return Py_INCREF_RET((PyObject *)self);;
}
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
@@ -445,7 +553,7 @@ int BaseMathObject_clear(BaseMathObject *self)
void BaseMathObject_dealloc(BaseMathObject *self)
{
/* only free non wrapped */
- if (self->wrapped != Py_WRAP) {
+ if ((self->flag & BASE_MATH_FLAG_IS_WRAP) == 0) {
PyMem_Free(self->data);
}
@@ -477,6 +585,7 @@ static struct PyModuleDef M_Mathutils_module_def = {
/* submodules only */
#include "mathutils_geometry.h"
+#include "mathutils_interpolate.h"
#ifndef MATH_STANDALONE
# include "mathutils_kdtree.h"
# include "mathutils_noise.h"
@@ -518,6 +627,13 @@ PyMODINIT_FUNC PyInit_mathutils(void)
PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
Py_INCREF(submodule);
+ PyModule_AddObject(mod, "interpolate", (submodule = PyInit_mathutils_interpolate()));
+ /* XXX, python doesnt do imports with this usefully yet
+ * 'from mathutils.geometry import PolyFill'
+ * ...fails without this. */
+ PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
+ Py_INCREF(submodule);
+
#ifndef MATH_STANDALONE
/* Noise submodule */
PyModule_AddObject(mod, "noise", (submodule = PyInit_mathutils_noise()));
diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h
index eb25d9bff07..e653b45389b 100644
--- a/source/blender/python/mathutils/mathutils.h
+++ b/source/blender/python/mathutils/mathutils.h
@@ -29,11 +29,25 @@
/* Can cast different mathutils types to this, use for generic funcs */
+#include "BLI_compiler_attrs.h"
+
struct DynStr;
extern char BaseMathObject_is_wrapped_doc[];
+extern char BaseMathObject_is_frozen_doc[];
extern char BaseMathObject_owner_doc[];
+#define BASE_MATH_NEW(struct_name, root_type, base_type) \
+ (struct_name *)((base_type ? (base_type)->tp_alloc(base_type, 0) : _PyObject_GC_New(&(root_type))));
+
+
+/* BaseMathObject.flag */
+enum {
+ BASE_MATH_FLAG_IS_WRAP = (1 << 0),
+ BASE_MATH_FLAG_IS_FROZEN = (1 << 1),
+};
+#define BASE_MATH_FLAG_DEFAULT 0
+
#define BASE_MATH_MEMBERS(_data) \
PyObject_VAR_HEAD \
float *_data; /* array of data (alias), wrapped status depends on wrapped status */ \
@@ -42,7 +56,7 @@ extern char BaseMathObject_owner_doc[];
unsigned char cb_type; /* which user funcs do we adhere to, RNA, GameObject, etc */ \
unsigned char cb_subtype; /* subtype: location, rotation... \
* to avoid defining many new functions for every attribute of the same type */ \
- unsigned char wrapped /* wrapped data type? */ \
+ unsigned char flag /* wrapped data type? */ \
typedef struct {
BASE_MATH_MEMBERS(data);
@@ -57,6 +71,10 @@ typedef struct {
PyObject *BaseMathObject_owner_get(BaseMathObject *self, void *);
PyObject *BaseMathObject_is_wrapped_get(BaseMathObject *self, void *);
+PyObject *BaseMathObject_is_frozen_get(BaseMathObject *self, void *);
+
+extern char BaseMathObject_freeze_doc[];
+PyObject *BaseMathObject_freeze(BaseMathObject *self);
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg);
int BaseMathObject_clear(BaseMathObject *self);
@@ -67,9 +85,6 @@ PyMODINIT_FUNC PyInit_mathutils(void);
int EXPP_FloatsAreEqual(float A, float B, int floatSteps);
int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps);
-#define Py_NEW 1
-#define Py_WRAP 2
-
typedef struct Mathutils_Callback Mathutils_Callback;
typedef int (*BaseMathCheckFunc)(BaseMathObject *); /* checks the user is still valid */
@@ -93,6 +108,9 @@ int _BaseMathObject_WriteCallback(BaseMathObject *self);
int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index);
int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
+void _BaseMathObject_RaiseFrozenExc(const BaseMathObject *self);
+void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self);
+
/* since this is called so often avoid where possible */
#define BaseMath_ReadCallback(_self) \
(((_self)->cb_user ? _BaseMathObject_ReadCallback((BaseMathObject *)_self):0))
@@ -103,12 +121,39 @@ int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
#define BaseMath_WriteIndexCallback(_self, _index) \
(((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):0))
+/* support BASE_MATH_FLAG_IS_FROZEN */
+#define BaseMath_ReadCallback_ForWrite(_self) \
+ (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \
+ (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : (BaseMath_ReadCallback(_self)))
+
+#define BaseMath_ReadIndexCallback_ForWrite(_self, _index) \
+ (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \
+ (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : (BaseMath_ReadIndexCallback(_self, _index)))
+
+#define BaseMath_Prepare_ForWrite(_self) \
+ (UNLIKELY((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) ? \
+ (_BaseMathObject_RaiseFrozenExc((BaseMathObject *)_self), -1) : 0)
+
+#define BaseMathObject_Prepare_ForHash(_self) \
+ (UNLIKELY(((_self)->flag & BASE_MATH_FLAG_IS_FROZEN) == 0) ? \
+ (_BaseMathObject_RaiseNotFrozenExc((BaseMathObject *)_self), -1) : 0)
+
/* utility func */
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, const char *error_prefix);
int mathutils_array_parse_alloc_v(float **array, int array_dim, PyObject *value, const char *error_prefix);
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
+Py_hash_t mathutils_array_hash(const float *float_array, size_t array_len);
+
+/* zero remaining unused elements of the array */
+#define MU_ARRAY_ZERO (1 << 30)
+/* ignore larger py sequences than requested (just use first elements),
+ * handy when using 3d vectors as 2d */
+#define MU_ARRAY_SPILL (1 << 31)
+
+#define MU_ARRAY_FLAGS (MU_ARRAY_ZERO | MU_ARRAY_SPILL)
+
int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat);
#ifndef MATH_STANDALONE
diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c
index aee2b9e9711..add8c2451ff 100644
--- a/source/blender/python/mathutils/mathutils_Color.c
+++ b/source/blender/python/mathutils/mathutils_Color.c
@@ -32,6 +32,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "../generic/python_utildefines.h"
+
#ifndef MATH_STANDALONE
# include "BLI_dynstr.h"
#endif
@@ -64,7 +66,7 @@ static PyObject *Color_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
"more than a single arg given");
return NULL;
}
- return Color_CreatePyObject(col, Py_NEW, type);
+ return Color_CreatePyObject(col, type);
}
/* -----------------------------METHODS---------------------------- */
@@ -107,7 +109,7 @@ static PyObject *Color_copy(ColorObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- return Color_CreatePyObject(self->col, Py_NEW, Py_TYPE(self));
+ return Color_CreatePyObject(self->col, Py_TYPE(self));
}
static PyObject *Color_deepcopy(ColorObject *self, PyObject *args)
{
@@ -187,7 +189,18 @@ static PyObject *Color_richcmpr(PyObject *a, PyObject *b, int op)
return NULL;
}
- return Py_INCREF(res), res;
+ return Py_INCREF_RET(res);
+}
+
+static Py_hash_t Color_hash(ColorObject *self)
+{
+ if (BaseMath_ReadCallback(self) == -1)
+ return -1;
+
+ if (BaseMathObject_Prepare_ForHash(self) == -1)
+ return -1;
+
+ return mathutils_array_hash(self->col, COLOR_SIZE);
}
/* ---------------------SEQUENCE PROTOCOLS------------------------ */
@@ -220,8 +233,12 @@ static PyObject *Color_item(ColorObject *self, int i)
/* sequence accessor (set) */
static int Color_ass_item(ColorObject *self, int i, PyObject *value)
{
- float f = PyFloat_AsDouble(value);
+ float f;
+
+ if (BaseMath_Prepare_ForWrite(self) == -1)
+ return -1;
+ f = PyFloat_AsDouble(value);
if (f == -1 && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError,
"color[item] = x: "
@@ -273,7 +290,7 @@ static int Color_ass_slice(ColorObject *self, int begin, int end, PyObject *seq)
int i, size;
float col[COLOR_SIZE];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
CLAMP(begin, 0, COLOR_SIZE);
@@ -411,7 +428,7 @@ static PyObject *Color_add(PyObject *v1, PyObject *v2)
add_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE);
- return Color_CreatePyObject(col, Py_NEW, Py_TYPE(v1));
+ return Color_CreatePyObject(col, Py_TYPE(v1));
}
/* addition in-place: obj += obj */
@@ -429,7 +446,7 @@ static PyObject *Color_iadd(PyObject *v1, PyObject *v2)
color1 = (ColorObject *)v1;
color2 = (ColorObject *)v2;
- if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1)
+ if (BaseMath_ReadCallback_ForWrite(color1) == -1 || BaseMath_ReadCallback(color2) == -1)
return NULL;
add_vn_vn(color1->col, color2->col, COLOR_SIZE);
@@ -460,7 +477,7 @@ static PyObject *Color_sub(PyObject *v1, PyObject *v2)
sub_vn_vnvn(col, color1->col, color2->col, COLOR_SIZE);
- return Color_CreatePyObject(col, Py_NEW, Py_TYPE(v1));
+ return Color_CreatePyObject(col, Py_TYPE(v1));
}
/* subtraction in-place: obj -= obj */
@@ -478,7 +495,7 @@ static PyObject *Color_isub(PyObject *v1, PyObject *v2)
color1 = (ColorObject *)v1;
color2 = (ColorObject *)v2;
- if (BaseMath_ReadCallback(color1) == -1 || BaseMath_ReadCallback(color2) == -1)
+ if (BaseMath_ReadCallback_ForWrite(color1) == -1 || BaseMath_ReadCallback(color2) == -1)
return NULL;
sub_vn_vn(color1->col, color2->col, COLOR_SIZE);
@@ -492,7 +509,7 @@ static PyObject *color_mul_float(ColorObject *color, const float scalar)
{
float tcol[COLOR_SIZE];
mul_vn_vn_fl(tcol, color->col, COLOR_SIZE, scalar);
- return Color_CreatePyObject(tcol, Py_NEW, Py_TYPE(color));
+ return Color_CreatePyObject(tcol, Py_TYPE(color));
}
@@ -577,7 +594,7 @@ static PyObject *Color_imul(PyObject *v1, PyObject *v2)
ColorObject *color = (ColorObject *)v1;
float scalar;
- if (BaseMath_ReadCallback(color) == -1)
+ if (BaseMath_ReadCallback_ForWrite(color) == -1)
return NULL;
/* only support color *= float */
@@ -603,7 +620,7 @@ static PyObject *Color_idiv(PyObject *v1, PyObject *v2)
ColorObject *color = (ColorObject *)v1;
float scalar;
- if (BaseMath_ReadCallback(color) == -1)
+ if (BaseMath_ReadCallback_ForWrite(color) == -1)
return NULL;
/* only support color /= float */
@@ -639,7 +656,7 @@ static PyObject *Color_neg(ColorObject *self)
return NULL;
negate_vn_vn(tcol, self->col, COLOR_SIZE);
- return Color_CreatePyObject(tcol, Py_NEW, Py_TYPE(self));
+ return Color_CreatePyObject(tcol, Py_TYPE(self));
}
@@ -726,7 +743,7 @@ static int Color_channel_hsv_set(ColorObject *self, PyObject *value, void *type)
return -1;
}
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
rgb_to_hsv_v(self->col, hsv);
@@ -753,9 +770,10 @@ static PyObject *Color_hsv_get(ColorObject *self, void *UNUSED(closure))
rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
ret = PyTuple_New(3);
- PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(hsv[0]));
- PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(hsv[1]));
- PyTuple_SET_ITEM(ret, 2, PyFloat_FromDouble(hsv[2]));
+ PyTuple_SET_ITEMS(ret,
+ PyFloat_FromDouble(hsv[0]),
+ PyFloat_FromDouble(hsv[1]),
+ PyFloat_FromDouble(hsv[2]));
return ret;
}
@@ -766,6 +784,9 @@ static int Color_hsv_set(ColorObject *self, PyObject *value, void *UNUSED(closur
if (mathutils_array_parse(hsv, 3, 3, value, "mathutils.Color.hsv = value") == -1)
return -1;
+ if (BaseMath_Prepare_ForWrite(self) == -1)
+ return -1;
+
CLAMP(hsv[0], 0.0f, 1.0f);
CLAMP(hsv[1], 0.0f, 1.0f);
CLAMP(hsv[2], 0.0f, 1.0f);
@@ -793,6 +814,7 @@ static PyGetSetDef Color_getseters[] = {
{(char *)"hsv", (getter)Color_hsv_get, (setter)Color_hsv_set, (char *)Color_hsv_doc, (void *)0},
{(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
+ {(char *)"is_frozen", (getter)BaseMathObject_is_frozen_get, (setter)NULL, BaseMathObject_is_frozen_doc, NULL},
{(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -803,12 +825,20 @@ static struct PyMethodDef Color_methods[] = {
{"copy", (PyCFunction) Color_copy, METH_NOARGS, Color_copy_doc},
{"__copy__", (PyCFunction) Color_copy, METH_NOARGS, Color_copy_doc},
{"__deepcopy__", (PyCFunction) Color_deepcopy, METH_VARARGS, Color_copy_doc},
+
+ /* base-math methods */
+ {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
{NULL, NULL, 0, NULL}
};
/* ------------------PY_OBECT DEFINITION-------------------------- */
PyDoc_STRVAR(color_doc,
-"This object gives access to Colors in Blender."
+".. class:: Color(rgb)\n"
+"\n"
+" This object gives access to Colors in Blender.\n"
+"\n"
+" :param rgb: (r, g, b) color values\n"
+" :type rgb: 3d vector\n"
);
PyTypeObject color_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -824,7 +854,7 @@ PyTypeObject color_Type = {
&Color_NumMethods, /* tp_as_number */
&Color_SeqMethods, /* tp_as_sequence */
&Color_AsMapping, /* tp_as_mapping */
- NULL, /* tp_hash */
+ (hashfunc)Color_hash, /* tp_hash */
NULL, /* tp_call */
#ifndef MATH_STANDALONE
(reprfunc) Color_str, /* tp_str */
@@ -862,40 +892,60 @@ PyTypeObject color_Type = {
NULL, /* tp_weaklist */
NULL /* tp_del */
};
-/* ------------------------Color_CreatePyObject (internal)------------- */
-/* creates a new color object */
-/* pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
- * (i.e. it was allocated elsewhere by MEM_mallocN())
- * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
- * (i.e. it must be created here with PyMEM_malloc())*/
-PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type)
+
+PyObject *Color_CreatePyObject(
+ const float col[3],
+ PyTypeObject *base_type)
{
ColorObject *self;
+ float *col_alloc;
- self = base_type ? (ColorObject *)base_type->tp_alloc(base_type, 0) :
- (ColorObject *)PyObject_GC_New(ColorObject, &color_Type);
+ col_alloc = PyMem_Malloc(COLOR_SIZE * sizeof(float));
+ if (UNLIKELY(col_alloc == NULL)) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Color(): "
+ "problem allocating data");
+ return NULL;
+ }
+ self = BASE_MATH_NEW(ColorObject, color_Type, base_type);
if (self) {
+ self->col = col_alloc;
+
/* init callbacks as NULL */
self->cb_user = NULL;
self->cb_type = self->cb_subtype = 0;
- if (type == Py_WRAP) {
- self->col = col;
- self->wrapped = Py_WRAP;
- }
- else if (type == Py_NEW) {
- self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float));
- if (col)
- copy_v3_v3(self->col, col);
- else
- zero_v3(self->col);
-
- self->wrapped = Py_NEW;
- }
- else {
- Py_FatalError("Color(): invalid type!");
- }
+ /* NEW */
+ if (col)
+ copy_v3_v3(self->col, col);
+ else
+ zero_v3(self->col);
+
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ }
+ else {
+ PyMem_Free(col_alloc);
+ }
+
+ return (PyObject *)self;
+}
+
+PyObject *Color_CreatePyObject_wrap(
+ float col[3],
+ PyTypeObject *base_type)
+{
+ ColorObject *self;
+
+ self = BASE_MATH_NEW(ColorObject, color_Type, base_type);
+ if (self) {
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ /* WRAP */
+ self->col = col;
+ self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
}
return (PyObject *)self;
@@ -904,7 +954,7 @@ PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type)
PyObject *Color_CreatePyObject_cb(PyObject *cb_user,
unsigned char cb_type, unsigned char cb_subtype)
{
- ColorObject *self = (ColorObject *)Color_CreatePyObject(NULL, Py_NEW, NULL);
+ ColorObject *self = (ColorObject *)Color_CreatePyObject(NULL, NULL);
if (self) {
Py_INCREF(cb_user);
self->cb_user = cb_user;
diff --git a/source/blender/python/mathutils/mathutils_Color.h b/source/blender/python/mathutils/mathutils_Color.h
index 193d30a2b6f..1290f73da62 100644
--- a/source/blender/python/mathutils/mathutils_Color.h
+++ b/source/blender/python/mathutils/mathutils_Color.h
@@ -42,8 +42,17 @@ typedef struct {
* blender (stored in blend_data). This is an either/or struct not both*/
/* prototypes */
-PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type);
-PyObject *Color_CreatePyObject_cb(PyObject *cb_user,
- unsigned char cb_type, unsigned char cb_subtype);
+PyObject *Color_CreatePyObject(
+ const float col[3],
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT;
+PyObject *Color_CreatePyObject_wrap(
+ float col[3],
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+PyObject *Color_CreatePyObject_cb(
+ PyObject *cb_user,
+ unsigned char cb_type, unsigned char cb_subtype
+ ) ATTR_WARN_UNUSED_RESULT;
#endif /* __MATHUTILS_COLOR_H__ */
diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c
index f6d124938a4..54adc826af7 100644
--- a/source/blender/python/mathutils/mathutils_Euler.c
+++ b/source/blender/python/mathutils/mathutils_Euler.c
@@ -31,6 +31,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "../generic/python_utildefines.h"
#ifndef MATH_STANDALONE
# include "BLI_dynstr.h"
@@ -70,7 +71,7 @@ static PyObject *Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
break;
}
- return Euler_CreatePyObject(eul, order, Py_NEW, type);
+ return Euler_CreatePyObject(eul, order, type);
}
/* internal use, assume read callback is done */
@@ -150,7 +151,7 @@ static PyObject *Euler_to_quaternion(EulerObject *self)
eulO_to_quat(quat, self->eul, self->order);
- return Quaternion_CreatePyObject(quat, Py_NEW, NULL);
+ return Quaternion_CreatePyObject(quat, NULL);
}
/* return a matrix representation of the euler */
@@ -171,7 +172,7 @@ static PyObject *Euler_to_matrix(EulerObject *self)
eulO_to_mat3((float (*)[3])mat, self->eul, self->order);
- return Matrix_CreatePyObject(mat, 3, 3, Py_NEW, NULL);
+ return Matrix_CreatePyObject(mat, 3, 3, NULL);
}
PyDoc_STRVAR(Euler_zero_doc,
@@ -181,6 +182,9 @@ PyDoc_STRVAR(Euler_zero_doc,
);
static PyObject *Euler_zero(EulerObject *self)
{
+ if (BaseMath_Prepare_ForWrite(self) == -1)
+ return NULL;
+
zero_v3(self->eul);
if (BaseMath_WriteCallback(self) == -1)
@@ -219,7 +223,7 @@ static PyObject *Euler_rotate_axis(EulerObject *self, PyObject *args)
return NULL;
}
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
@@ -233,7 +237,7 @@ static PyObject *Euler_rotate_axis(EulerObject *self, PyObject *args)
PyDoc_STRVAR(Euler_rotate_doc,
".. method:: rotate(other)\n"
"\n"
-" Rotates the euler a by another mathutils value.\n"
+" Rotates the euler by another mathutils value.\n"
"\n"
" :arg other: rotation component of mathutils value\n"
" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
@@ -242,7 +246,7 @@ static PyObject *Euler_rotate(EulerObject *self, PyObject *value)
{
float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (mathutils_any_to_rotmat(other_rmat, value, "euler.rotate(value)") == -1)
@@ -269,7 +273,7 @@ static PyObject *Euler_make_compatible(EulerObject *self, PyObject *value)
{
float teul[EULER_SIZE];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (mathutils_array_parse(teul, EULER_SIZE, EULER_SIZE, value,
@@ -304,7 +308,7 @@ static PyObject *Euler_copy(EulerObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- return Euler_CreatePyObject(self->eul, self->order, Py_NEW, Py_TYPE(self));
+ return Euler_CreatePyObject(self->eul, self->order, Py_TYPE(self));
}
static PyObject *Euler_deepcopy(EulerObject *self, PyObject *args)
{
@@ -382,7 +386,18 @@ static PyObject *Euler_richcmpr(PyObject *a, PyObject *b, int op)
return NULL;
}
- return Py_INCREF(res), res;
+ return Py_INCREF_RET(res);
+}
+
+static Py_hash_t Euler_hash(EulerObject *self)
+{
+ if (BaseMath_ReadCallback(self) == -1)
+ return -1;
+
+ if (BaseMathObject_Prepare_ForHash(self) == -1)
+ return -1;
+
+ return mathutils_array_hash(self->eul, EULER_SIZE);
}
/* ---------------------SEQUENCE PROTOCOLS------------------------ */
@@ -415,8 +430,12 @@ static PyObject *Euler_item(EulerObject *self, int i)
/* sequence accessor (set) */
static int Euler_ass_item(EulerObject *self, int i, PyObject *value)
{
- float f = PyFloat_AsDouble(value);
+ float f;
+
+ if (BaseMath_Prepare_ForWrite(self) == -1)
+ return -1;
+ f = PyFloat_AsDouble(value);
if (f == -1 && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError,
"euler[attribute] = x: "
@@ -469,7 +488,7 @@ static int Euler_ass_slice(EulerObject *self, int begin, int end, PyObject *seq)
int i, size;
float eul[EULER_SIZE];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
CLAMP(begin, 0, EULER_SIZE);
@@ -614,12 +633,18 @@ static PyObject *Euler_order_get(EulerObject *self, void *UNUSED(closure))
static int Euler_order_set(EulerObject *self, PyObject *value, void *UNUSED(closure))
{
- const char *order_str = _PyUnicode_AsString(value);
- short order = euler_order_from_string(order_str, "euler.order");
+ const char *order_str;
+ short order;
- if (order == -1)
+ if (BaseMath_Prepare_ForWrite(self) == -1)
return -1;
+ if (((order_str = _PyUnicode_AsString(value)) == NULL) ||
+ ((order = euler_order_from_string(order_str, "euler.order")) == -1))
+ {
+ return -1;
+ }
+
self->order = order;
(void)BaseMath_WriteCallback(self); /* order can be written back */
return 0;
@@ -635,6 +660,7 @@ static PyGetSetDef Euler_getseters[] = {
{(char *)"order", (getter)Euler_order_get, (setter)Euler_order_set, Euler_order_doc, (void *)NULL},
{(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
+ {(char *)"is_frozen", (getter)BaseMathObject_is_frozen_get, (setter)NULL, BaseMathObject_is_frozen_doc, NULL},
{(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -651,12 +677,22 @@ static struct PyMethodDef Euler_methods[] = {
{"copy", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc},
{"__copy__", (PyCFunction) Euler_copy, METH_NOARGS, Euler_copy_doc},
{"__deepcopy__", (PyCFunction) Euler_deepcopy, METH_VARARGS, Euler_copy_doc},
+
+ /* base-math methods */
+ {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
{NULL, NULL, 0, NULL}
};
/* ------------------PY_OBECT DEFINITION-------------------------- */
PyDoc_STRVAR(euler_doc,
-"This object gives access to Eulers in Blender."
+".. class:: Euler(angles, order='XYZ')\n"
+"\n"
+" This object gives access to Eulers in Blender.\n"
+"\n"
+" :param angles: Three angles, in radians.\n"
+" :type angles: 3d vector\n"
+" :param order: Optional order of the angles, a permutation of ``XYZ``.\n"
+" :type order: str\n"
);
PyTypeObject euler_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -672,7 +708,7 @@ PyTypeObject euler_Type = {
NULL, /* tp_as_number */
&Euler_SeqMethods, /* tp_as_sequence */
&Euler_AsMapping, /* tp_as_mapping */
- NULL, /* tp_hash */
+ (hashfunc)Euler_hash, /* tp_hash */
NULL, /* tp_call */
#ifndef MATH_STANDALONE
(reprfunc) Euler_str, /* tp_str */
@@ -710,53 +746,74 @@ PyTypeObject euler_Type = {
NULL, /* tp_weaklist */
NULL /* tp_del */
};
-/* ------------------------Euler_CreatePyObject (internal)------------- */
-/* creates a new euler object */
-/* pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
- * (i.e. it was allocated elsewhere by MEM_mallocN())
- * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
- * (i.e. it must be created here with PyMEM_malloc())*/
-PyObject *Euler_CreatePyObject(float eul[3], const short order, int type, PyTypeObject *base_type)
+
+
+PyObject *Euler_CreatePyObject(
+ const float eul[3], const short order,
+ PyTypeObject *base_type)
{
EulerObject *self;
+ float *eul_alloc;
- self = base_type ? (EulerObject *)base_type->tp_alloc(base_type, 0) :
- (EulerObject *)PyObject_GC_New(EulerObject, &euler_Type);
+ eul_alloc = PyMem_Malloc(EULER_SIZE * sizeof(float));
+ if (UNLIKELY(eul_alloc == NULL)) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Euler(): "
+ "problem allocating data");
+ return NULL;
+ }
+ self = BASE_MATH_NEW(EulerObject, euler_Type, base_type);
if (self) {
+ self->eul = eul_alloc;
+
/* init callbacks as NULL */
self->cb_user = NULL;
self->cb_type = self->cb_subtype = 0;
- if (type == Py_WRAP) {
- self->eul = eul;
- self->wrapped = Py_WRAP;
- }
- else if (type == Py_NEW) {
- self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float));
- if (eul) {
- copy_v3_v3(self->eul, eul);
- }
- else {
- zero_v3(self->eul);
- }
-
- self->wrapped = Py_NEW;
+ if (eul) {
+ copy_v3_v3(self->eul, eul);
}
else {
- Py_FatalError("Euler(): invalid type!");
+ zero_v3(self->eul);
}
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ self->order = order;
+ }
+ else {
+ PyMem_Free(eul_alloc);
+ }
+
+ return (PyObject *)self;
+}
+
+PyObject *Euler_CreatePyObject_wrap(
+ float eul[3], const short order,
+ PyTypeObject *base_type)
+{
+ EulerObject *self;
+
+ self = BASE_MATH_NEW(EulerObject, euler_Type, base_type);
+ if (self) {
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ self->eul = eul;
+ self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
+
self->order = order;
}
return (PyObject *)self;
}
-PyObject *Euler_CreatePyObject_cb(PyObject *cb_user, const short order,
- unsigned char cb_type, unsigned char cb_subtype)
+PyObject *Euler_CreatePyObject_cb(
+ PyObject *cb_user, const short order,
+ unsigned char cb_type, unsigned char cb_subtype)
{
- EulerObject *self = (EulerObject *)Euler_CreatePyObject(NULL, order, Py_NEW, NULL);
+ EulerObject *self = (EulerObject *)Euler_CreatePyObject(NULL, order, NULL);
if (self) {
Py_INCREF(cb_user);
self->cb_user = cb_user;
diff --git a/source/blender/python/mathutils/mathutils_Euler.h b/source/blender/python/mathutils/mathutils_Euler.h
index 62fb83ef234..744f39faed1 100644
--- a/source/blender/python/mathutils/mathutils_Euler.h
+++ b/source/blender/python/mathutils/mathutils_Euler.h
@@ -43,9 +43,18 @@ typedef struct {
* blender (stored in blend_data). This is an either/or struct not both */
/* prototypes */
-PyObject *Euler_CreatePyObject(float eul[3], const short order, int type, PyTypeObject *base_type);
-PyObject *Euler_CreatePyObject_cb(PyObject *cb_user, const short order,
- unsigned char cb_type, unsigned char cb_subtype);
+PyObject *Euler_CreatePyObject(
+ const float eul[3], const short order,
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT;
+PyObject *Euler_CreatePyObject_wrap(
+ float eul[3], const short order,
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+PyObject *Euler_CreatePyObject_cb(
+ PyObject *cb_user, const short order,
+ unsigned char cb_type, unsigned char cb_subtype
+ ) ATTR_WARN_UNUSED_RESULT;
short euler_order_from_string(const char *str, const char *error_prefix);
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 282f29b4934..67905f8e340 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -32,6 +32,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "../generic/python_utildefines.h"
+
#ifndef MATH_STANDALONE
# include "BLI_string.h"
# include "BLI_dynstr.h"
@@ -109,7 +111,7 @@ static int mathutils_matrix_row_set(BaseMathObject *bmo, int row)
MatrixObject *self = (MatrixObject *)bmo->cb_user;
int col;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
if (!matrix_row_vector_check(self, (VectorObject *)bmo, row))
return -1;
@@ -139,7 +141,7 @@ static int mathutils_matrix_row_set_index(BaseMathObject *bmo, int row, int col)
{
MatrixObject *self = (MatrixObject *)bmo->cb_user;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
if (!matrix_row_vector_check(self, (VectorObject *)bmo, row))
return -1;
@@ -198,7 +200,7 @@ static int mathutils_matrix_col_set(BaseMathObject *bmo, int col)
int num_row;
int row;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
if (!matrix_col_vector_check(self, (VectorObject *)bmo, col))
return -1;
@@ -231,7 +233,7 @@ static int mathutils_matrix_col_set_index(BaseMathObject *bmo, int col, int row)
{
MatrixObject *self = (MatrixObject *)bmo->cb_user;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
if (!matrix_col_vector_check(self, (VectorObject *)bmo, col))
return -1;
@@ -284,7 +286,7 @@ static int mathutils_matrix_translation_set(BaseMathObject *bmo, int col)
MatrixObject *self = (MatrixObject *)bmo->cb_user;
int row;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
for (row = 0; row < 3; row++) {
@@ -310,7 +312,7 @@ static int mathutils_matrix_translation_set_index(BaseMathObject *bmo, int col,
{
MatrixObject *self = (MatrixObject *)bmo->cb_user;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
MATRIX_ITEM(self, row, col) = bmo->data[row];
@@ -344,7 +346,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
switch (PyTuple_GET_SIZE(args)) {
case 0:
- return Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, type);
+ return Matrix_CreatePyObject(NULL, 4, 4, type);
case 1:
{
PyObject *arg = PyTuple_GET_ITEM(args, 0);
@@ -363,7 +365,7 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (num_col >= 2 && num_col <= 4) {
/* sane row & col size, new matrix and assign as slice */
- PyObject *matrix = Matrix_CreatePyObject(NULL, num_col, num_row, Py_NEW, type);
+ PyObject *matrix = Matrix_CreatePyObject(NULL, num_col, num_row, type);
if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) {
return matrix;
}
@@ -444,7 +446,7 @@ static PyObject *C_Matrix_Identity(PyObject *cls, PyObject *args)
return NULL;
}
- return Matrix_CreatePyObject(NULL, matSize, matSize, Py_NEW, (PyTypeObject *)cls);
+ return Matrix_CreatePyObject(NULL, matSize, matSize, (PyTypeObject *)cls);
}
PyDoc_STRVAR(C_Matrix_Rotation_doc,
@@ -535,7 +537,7 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
matrix_3x3_as_4x4(mat);
}
/* pass to matrix creation */
- return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls);
+ return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
}
@@ -558,7 +560,7 @@ static PyObject *C_Matrix_Translation(PyObject *cls, PyObject *value)
if (mathutils_array_parse(mat[3], 3, 4, value, "mathutils.Matrix.Translation(vector), invalid vector arg") == -1)
return NULL;
- return Matrix_CreatePyObject(&mat[0][0], 4, 4, Py_NEW, (PyTypeObject *)cls);
+ return Matrix_CreatePyObject(&mat[0][0], 4, 4, (PyTypeObject *)cls);
}
/* ----------------------------------mathutils.Matrix.Scale() ------------- */
/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */
@@ -650,7 +652,7 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
matrix_3x3_as_4x4(mat);
}
/* pass to matrix creation */
- return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls);
+ return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
}
/* ----------------------------------mathutils.Matrix.OrthoProjection() --- */
/* mat is a 1D array of floats - row[0][0], row[0][1], row[1][0], etc. */
@@ -771,7 +773,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
matrix_3x3_as_4x4(mat);
}
/* pass to matrix creation */
- return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls);
+ return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
}
PyDoc_STRVAR(C_Matrix_Shear_doc,
@@ -874,7 +876,7 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
matrix_3x3_as_4x4(mat);
}
/* pass to matrix creation */
- return Matrix_CreatePyObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls);
+ return Matrix_CreatePyObject(mat, matSize, matSize, (PyTypeObject *)cls);
}
void matrix_as_3x3(float mat[3][3], MatrixObject *self)
@@ -893,6 +895,19 @@ static void matrix_copy(MatrixObject *mat_dst, const MatrixObject *mat_src)
memcpy(mat_dst->matrix, mat_src->matrix, sizeof(float) * (mat_dst->num_col * mat_dst->num_row));
}
+/* transposes memory layout, rol/col's don't have to match */
+static void matrix_transpose_internal(float mat_dst_fl[], const MatrixObject *mat_src)
+{
+ unsigned short col, row;
+ unsigned int i = 0;
+
+ for (row = 0; row < mat_src->num_row; row++) {
+ for (col = 0; col < mat_src->num_col; col++) {
+ mat_dst_fl[i++] = MATRIX_ITEM(mat_src, row, col);
+ }
+ }
+}
+
/* assumes rowsize == colsize is checked and the read callback has run */
static float matrix_determinant_internal(const MatrixObject *self)
{
@@ -1078,7 +1093,7 @@ static PyObject *Matrix_to_quaternion(MatrixObject *self)
mat4_to_quat(quat, (float (*)[4])self->matrix);
}
- return Quaternion_CreatePyObject(quat, Py_NEW, NULL);
+ return Quaternion_CreatePyObject(quat, NULL);
}
/*---------------------------matrix.toEuler() --------------------*/
@@ -1152,7 +1167,7 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args)
else mat3_to_eulO(eul, order, mat);
}
- return Euler_CreatePyObject(eul, order, Py_NEW, NULL);
+ return Euler_CreatePyObject(eul, order, NULL);
}
PyDoc_STRVAR(Matrix_resize_4x4_doc,
@@ -1165,7 +1180,7 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
float mat[4][4];
int col;
- if (self->wrapped == Py_WRAP) {
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
PyErr_SetString(PyExc_ValueError,
"Matrix.resize_4x4(): "
"cannot resize wrapped data - make a copy and resize that");
@@ -1214,12 +1229,12 @@ static PyObject *Matrix_to_4x4(MatrixObject *self)
return NULL;
if (self->num_row == 4 && self->num_col == 4) {
- return Matrix_CreatePyObject(self->matrix, 4, 4, Py_NEW, Py_TYPE(self));
+ return Matrix_CreatePyObject(self->matrix, 4, 4, Py_TYPE(self));
}
else if (self->num_row == 3 && self->num_col == 3) {
float mat[4][4];
copy_m4_m3(mat, (float (*)[3])self->matrix);
- return Matrix_CreatePyObject((float *)mat, 4, 4, Py_NEW, Py_TYPE(self));
+ return Matrix_CreatePyObject((float *)mat, 4, 4, Py_TYPE(self));
}
/* TODO, 2x2 matrix */
@@ -1252,15 +1267,15 @@ static PyObject *Matrix_to_3x3(MatrixObject *self)
matrix_as_3x3(mat, self);
- return Matrix_CreatePyObject((float *)mat, 3, 3, Py_NEW, Py_TYPE(self));
+ return Matrix_CreatePyObject((float *)mat, 3, 3, Py_TYPE(self));
}
PyDoc_STRVAR(Matrix_to_translation_doc,
".. method:: to_translation()\n"
"\n"
-" Return a the translation part of a 4 row matrix.\n"
+" Return the translation part of a 4 row matrix.\n"
"\n"
-" :return: Return a the translation of a matrix.\n"
+" :return: Return the translation of a matrix.\n"
" :rtype: :class:`Vector`\n"
);
static PyObject *Matrix_to_translation(MatrixObject *self)
@@ -1275,15 +1290,15 @@ static PyObject *Matrix_to_translation(MatrixObject *self)
return NULL;
}
- return Vector_CreatePyObject(MATRIX_COL_PTR(self, 3), 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(MATRIX_COL_PTR(self, 3), 3, NULL);
}
PyDoc_STRVAR(Matrix_to_scale_doc,
".. method:: to_scale()\n"
"\n"
-" Return a the scale part of a 3x3 or 4x4 matrix.\n"
+" Return the scale part of a 3x3 or 4x4 matrix.\n"
"\n"
-" :return: Return a the scale of a matrix.\n"
+" :return: Return the scale of a matrix.\n"
" :rtype: :class:`Vector`\n"
"\n"
" .. note:: This method does not return negative a scale on any axis because it is not possible to obtain this data from the matrix alone.\n"
@@ -1310,7 +1325,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
/* compatible mat4_to_loc_rot_size */
mat3_to_rot_size(rot, size, mat);
- return Vector_CreatePyObject(size, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(size, 3, NULL);
}
/*---------------------------matrix.invert() ---------------------*/
@@ -1383,7 +1398,7 @@ PyDoc_STRVAR(Matrix_invert_doc,
);
static PyObject *Matrix_invert(MatrixObject *self, PyObject *args)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (matrix_invert_is_compat(self) == false) {
@@ -1423,8 +1438,8 @@ PyDoc_STRVAR(Matrix_inverted_doc,
"\n"
" Return an inverted copy of the matrix.\n"
"\n"
-" :arg fallback: return this value when the inverse can't be calculated\n"
-" (instead of raising a :exc:`ValueError` exception).\n"
+" :arg fallback: return this when the inverse can't be calculated\n"
+" (instead of raising a :exc:`ValueError`).\n"
" :type fallback: any\n"
" :return: the inverted matrix or fallback when given.\n"
" :rtype: :class:`Matrix`\n"
@@ -1464,7 +1479,7 @@ static PyObject *Matrix_inverted(MatrixObject *self, PyObject *args)
static PyObject *Matrix_inverted_noargs(MatrixObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (matrix_invert_is_compat(self) == false) {
@@ -1494,7 +1509,7 @@ PyDoc_STRVAR(Matrix_invert_safe_doc,
);
static PyObject *Matrix_invert_safe(MatrixObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (matrix_invert_is_compat(self) == false) {
@@ -1545,7 +1560,7 @@ PyDoc_STRVAR(Matrix_adjugate_doc,
);
static PyObject *Matrix_adjugate(MatrixObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (self->num_col != self->num_row) {
@@ -1589,7 +1604,7 @@ static PyObject *Matrix_adjugated(MatrixObject *self)
PyDoc_STRVAR(Matrix_rotate_doc,
".. method:: rotate(other)\n"
"\n"
-" Rotates the matrix a by another mathutils value.\n"
+" Rotates the matrix by another mathutils value.\n"
"\n"
" :arg other: rotation component of mathutils value\n"
" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
@@ -1600,7 +1615,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
{
float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (mathutils_any_to_rotmat(other_rmat, value, "matrix.rotate(value)") == -1)
@@ -1653,10 +1668,10 @@ static PyObject *Matrix_decompose(MatrixObject *self)
mat3_to_quat(quat, rot);
ret = PyTuple_New(3);
- PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(loc, 3, Py_NEW, NULL));
- PyTuple_SET_ITEM(ret, 1, Quaternion_CreatePyObject(quat, Py_NEW, NULL));
- PyTuple_SET_ITEM(ret, 2, Vector_CreatePyObject(size, 3, Py_NEW, NULL));
-
+ PyTuple_SET_ITEMS(ret,
+ Vector_CreatePyObject(loc, 3, NULL),
+ Quaternion_CreatePyObject(quat, NULL),
+ Vector_CreatePyObject(size, 3, NULL));
return ret;
}
@@ -1706,7 +1721,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
return NULL;
}
- return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_NEW, Py_TYPE(self));
+ return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_TYPE(self));
}
/*---------------------------matrix.determinant() ----------------*/
@@ -1715,7 +1730,7 @@ PyDoc_STRVAR(Matrix_determinant_doc,
"\n"
" Return the determinant of a matrix.\n"
"\n"
-" :return: Return a the determinant of a matrix.\n"
+" :return: Return the determinant of a matrix.\n"
" :rtype: float\n"
"\n"
" .. seealso:: <http://en.wikipedia.org/wiki/Determinant>\n"
@@ -1744,7 +1759,7 @@ PyDoc_STRVAR(Matrix_transpose_doc,
);
static PyObject *Matrix_transpose(MatrixObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (self->num_col != self->num_row) {
@@ -1791,7 +1806,7 @@ PyDoc_STRVAR(Matrix_normalize_doc,
);
static PyObject *Matrix_normalize(MatrixObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (self->num_col != self->num_row) {
@@ -1836,19 +1851,37 @@ PyDoc_STRVAR(Matrix_zero_doc,
"\n"
" Set all the matrix values to zero.\n"
"\n"
-" :return: an instance of itself\n"
" :rtype: :class:`Matrix`\n"
);
static PyObject *Matrix_zero(MatrixObject *self)
{
+ if (BaseMath_Prepare_ForWrite(self) == -1)
+ return NULL;
+
fill_vn_fl(self->matrix, self->num_col * self->num_row, 0.0f);
if (BaseMath_WriteCallback(self) == -1)
return NULL;
Py_RETURN_NONE;
+
}
/*---------------------------matrix.identity(() ------------------*/
+static void matrix_identity_internal(MatrixObject *self)
+{
+ BLI_assert((self->num_col == self->num_row) && (self->num_row <= 4));
+
+ if (self->num_col == 2) {
+ unit_m2((float (*)[2])self->matrix);
+ }
+ else if (self->num_col == 3) {
+ unit_m3((float (*)[3])self->matrix);
+ }
+ else {
+ unit_m4((float (*)[4])self->matrix);
+ }
+}
+
PyDoc_STRVAR(Matrix_identity_doc,
".. method:: identity()\n"
"\n"
@@ -1861,7 +1894,7 @@ PyDoc_STRVAR(Matrix_identity_doc,
);
static PyObject *Matrix_identity(MatrixObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (self->num_col != self->num_row) {
@@ -1871,15 +1904,7 @@ static PyObject *Matrix_identity(MatrixObject *self)
return NULL;
}
- if (self->num_col == 2) {
- unit_m2((float (*)[2])self->matrix);
- }
- else if (self->num_col == 3) {
- unit_m3((float (*)[3])self->matrix);
- }
- else {
- unit_m4((float (*)[4])self->matrix);
- }
+ matrix_identity_internal(self);
if (BaseMath_WriteCallback(self) == -1)
return NULL;
@@ -1891,7 +1916,7 @@ static PyObject *Matrix_identity(MatrixObject *self)
static PyObject *Matrix_copy_notest(MatrixObject *self, const float *matrix)
{
- return Matrix_CreatePyObject((float *)matrix, self->num_col, self->num_row, Py_NEW, Py_TYPE(self));
+ return Matrix_CreatePyObject((float *)matrix, self->num_col, self->num_row, Py_TYPE(self));
}
PyDoc_STRVAR(Matrix_copy_doc,
@@ -2025,7 +2050,22 @@ static PyObject *Matrix_richcmpr(PyObject *a, PyObject *b, int op)
return NULL;
}
- return Py_INCREF(res), res;
+ return Py_INCREF_RET(res);
+}
+
+static Py_hash_t Matrix_hash(MatrixObject *self)
+{
+ float mat[SQUARE(MATRIX_MAX_DIM)];
+
+ if (BaseMath_ReadCallback(self) == -1)
+ return -1;
+
+ if (BaseMathObject_Prepare_ForHash(self) == -1)
+ return -1;
+
+ matrix_transpose_internal(mat, self);
+
+ return mathutils_array_hash(mat, self->num_row * self->num_col);
}
/*---------------------SEQUENCE PROTOCOLS------------------------
@@ -2040,7 +2080,7 @@ static int Matrix_len(MatrixObject *self)
* the wrapped vector gives direct access to the matrix data */
static PyObject *Matrix_item_row(MatrixObject *self, int row)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (row < 0 || row >= self->num_row) {
@@ -2054,7 +2094,7 @@ static PyObject *Matrix_item_row(MatrixObject *self, int row)
/* same but column access */
static PyObject *Matrix_item_col(MatrixObject *self, int col)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (col < 0 || col >= self->num_col) {
@@ -2073,7 +2113,7 @@ static int Matrix_ass_item_row(MatrixObject *self, int row, PyObject *value)
{
int col;
float vec[MATRIX_MAX_DIM];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
if (row >= self->num_row || row < 0) {
@@ -2098,7 +2138,7 @@ static int Matrix_ass_item_col(MatrixObject *self, int col, PyObject *value)
{
int row;
float vec[MATRIX_MAX_DIM];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
if (col >= self->num_col || col < 0) {
@@ -2150,7 +2190,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
{
PyObject *value_fast = NULL;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
CLAMP(begin, 0, self->num_row);
@@ -2233,7 +2273,7 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
- return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1));
}
/*------------------------obj - obj------------------------------
* subtraction */
@@ -2265,7 +2305,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
- return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1));
}
/*------------------------obj * obj------------------------------
* multiplication */
@@ -2273,7 +2313,7 @@ static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar)
{
float tmat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
mul_vn_vn_fl(tmat, mat->matrix, mat->num_col * mat->num_row, scalar);
- return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_NEW, Py_TYPE(mat));
+ return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_TYPE(mat));
}
static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
@@ -2317,7 +2357,7 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
}
}
- return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1));
}
else if (mat2) {
/*FLOAT/INT * MATRIX */
@@ -2343,7 +2383,7 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
vec_size = mat1->num_row;
}
- return Vector_CreatePyObject(tvec, vec_size, Py_NEW, Py_TYPE(m2));
+ return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(m2));
}
/*FLOAT/INT * MATRIX */
else if (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0) {
@@ -2516,7 +2556,7 @@ static int Matrix_translation_set(MatrixObject *self, PyObject *value, void *UNU
{
float tvec[3];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
/*must be 4x4 square matrix*/
@@ -2652,6 +2692,7 @@ static PyGetSetDef Matrix_getseters[] = {
{(char *)"is_orthogonal", (getter)Matrix_is_orthogonal_get, (setter)NULL, Matrix_is_orthogonal_doc, NULL},
{(char *)"is_orthogonal_axis_vectors", (getter)Matrix_is_orthogonal_axis_vectors_get, (setter)NULL, Matrix_is_orthogonal_axis_vectors_doc, NULL},
{(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
+ {(char *)"is_frozen", (getter)BaseMathObject_is_frozen_get, (setter)NULL, BaseMathObject_is_frozen_doc, NULL},
{(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -2695,6 +2736,9 @@ static struct PyMethodDef Matrix_methods[] = {
{"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
{"__deepcopy__", (PyCFunction) Matrix_deepcopy, METH_VARARGS, Matrix_copy_doc},
+ /* base-math methods */
+ {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
+
/* class methods */
{"Identity", (PyCFunction) C_Matrix_Identity, METH_VARARGS | METH_CLASS, C_Matrix_Identity_doc},
{"Rotation", (PyCFunction) C_Matrix_Rotation, METH_VARARGS | METH_CLASS, C_Matrix_Rotation_doc},
@@ -2707,7 +2751,14 @@ static struct PyMethodDef Matrix_methods[] = {
/*------------------PY_OBECT DEFINITION--------------------------*/
PyDoc_STRVAR(matrix_doc,
-"This object gives access to Matrices in Blender."
+".. class:: Matrix([rows])\n"
+"\n"
+" This object gives access to Matrices in Blender, supporting square and rectangular\n"
+" matrices from 2x2 up to 4x4.\n"
+"\n"
+" :param rows: Sequence of rows.\n"
+" When ommitted, a 4x4 identity matrix is constructed.\n"
+" :type rows: 2d number sequence\n"
);
PyTypeObject matrix_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -2723,7 +2774,7 @@ PyTypeObject matrix_Type = {
&Matrix_NumMethods, /*tp_as_number*/
&Matrix_SeqMethods, /*tp_as_sequence*/
&Matrix_AsMapping, /*tp_as_mapping*/
- NULL, /*tp_hash*/
+ (hashfunc)Matrix_hash, /*tp_hash*/
NULL, /*tp_call*/
#ifndef MATH_STANDALONE
(reprfunc) Matrix_str, /*tp_str*/
@@ -2762,15 +2813,13 @@ PyTypeObject matrix_Type = {
NULL /*tp_del*/
};
-/* pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
- * (i.e. it was allocated elsewhere by MEM_mallocN())
- * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
- * (i.e. it must be created here with PyMEM_malloc()) */
-PyObject *Matrix_CreatePyObject(float *mat,
- const unsigned short num_col, const unsigned short num_row,
- int type, PyTypeObject *base_type)
+PyObject *Matrix_CreatePyObject(
+ const float *mat,
+ const unsigned short num_col, const unsigned short num_row,
+ PyTypeObject *base_type)
{
MatrixObject *self;
+ float *mat_alloc;
/* matrix objects can be any 2-4row x 2-4col matrix */
if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) {
@@ -2780,10 +2829,17 @@ PyObject *Matrix_CreatePyObject(float *mat,
return NULL;
}
- self = base_type ? (MatrixObject *)base_type->tp_alloc(base_type, 0) :
- (MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type);
+ mat_alloc = PyMem_Malloc(num_col * num_row * sizeof(float));
+ if (UNLIKELY(mat_alloc == NULL)) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Matrix(): "
+ "problem allocating data");
+ return NULL;
+ }
+ self = BASE_MATH_NEW(MatrixObject, matrix_Type, base_type);
if (self) {
+ self->matrix = mat_alloc;
self->num_col = num_col;
self->num_row = num_row;
@@ -2791,37 +2847,52 @@ PyObject *Matrix_CreatePyObject(float *mat,
self->cb_user = NULL;
self->cb_type = self->cb_subtype = 0;
- if (type == Py_WRAP) {
- self->matrix = mat;
- self->wrapped = Py_WRAP;
+ if (mat) { /*if a float array passed*/
+ memcpy(self->matrix, mat, num_col * num_row * sizeof(float));
}
- else if (type == Py_NEW) {
- self->matrix = PyMem_Malloc(num_col * num_row * sizeof(float));
- if (self->matrix == NULL) { /*allocation failure*/
- PyErr_SetString(PyExc_MemoryError,
- "Matrix(): "
- "problem allocating pointer space");
- return NULL;
- }
-
- if (mat) { /*if a float array passed*/
- memcpy(self->matrix, mat, num_col * num_row * sizeof(float));
- }
- else if (num_col == num_row) {
- /* or if no arguments are passed return identity matrix for square matrices */
- PyObject *ret_dummy = Matrix_identity(self);
- Py_DECREF(ret_dummy);
- }
- else {
- /* otherwise zero everything */
- memset(self->matrix, 0, num_col * num_row * sizeof(float));
- }
- self->wrapped = Py_NEW;
+ else if (num_col == num_row) {
+ /* or if no arguments are passed return identity matrix for square matrices */
+ matrix_identity_internal(self);
}
else {
- Py_FatalError("Matrix(): invalid type!");
- return NULL;
+ /* otherwise zero everything */
+ memset(self->matrix, 0, num_col * num_row * sizeof(float));
}
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ }
+ else {
+ PyMem_Free(mat_alloc);
+ }
+
+ return (PyObject *)self;
+}
+
+PyObject *Matrix_CreatePyObject_wrap(
+ float *mat,
+ const unsigned short num_col, const unsigned short num_row,
+ PyTypeObject *base_type)
+{
+ MatrixObject *self;
+
+ /* matrix objects can be any 2-4row x 2-4col matrix */
+ if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Matrix(): "
+ "row and column sizes must be between 2 and 4");
+ return NULL;
+ }
+
+ self = BASE_MATH_NEW(MatrixObject, matrix_Type, base_type);
+ if (self) {
+ self->num_col = num_col;
+ self->num_row = num_row;
+
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ self->matrix = mat;
+ self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
}
return (PyObject *) self;
}
@@ -2830,7 +2901,7 @@ PyObject *Matrix_CreatePyObject_cb(PyObject *cb_user,
const unsigned short num_col, const unsigned short num_row,
unsigned char cb_type, unsigned char cb_subtype)
{
- MatrixObject *self = (MatrixObject *)Matrix_CreatePyObject(NULL, num_col, num_row, Py_NEW, NULL);
+ MatrixObject *self = (MatrixObject *)Matrix_CreatePyObject(NULL, num_col, num_row, NULL);
if (self) {
Py_INCREF(cb_user);
self->cb_user = cb_user;
diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h
index f94af9e540e..9ae5a4bd61d 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.h
+++ b/source/blender/python/mathutils/mathutils_Matrix.h
@@ -61,12 +61,21 @@ typedef struct {
* blender (stored in blend_data). This is an either/or struct not both */
/* prototypes */
-PyObject *Matrix_CreatePyObject(float *mat,
- const unsigned short num_col, const unsigned short num_row,
- int type, PyTypeObject *base_type);
-PyObject *Matrix_CreatePyObject_cb(PyObject *user,
- const unsigned short num_col, const unsigned short num_row,
- unsigned char cb_type, unsigned char cb_subtype);
+PyObject *Matrix_CreatePyObject(
+ const float *mat,
+ const unsigned short num_col, const unsigned short num_row,
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT;
+PyObject *Matrix_CreatePyObject_wrap(
+ float *mat,
+ const unsigned short num_col, const unsigned short num_row,
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+PyObject *Matrix_CreatePyObject_cb(
+ PyObject *user,
+ const unsigned short num_col, const unsigned short num_row,
+ unsigned char cb_type, unsigned char cb_subtype
+ ) ATTR_WARN_UNUSED_RESULT;
extern unsigned char mathutils_matrix_row_cb_index; /* default */
extern unsigned char mathutils_matrix_col_cb_index;
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index ae3476f5802..1752be6e306 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -32,6 +32,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "../generic/python_utildefines.h"
+
#ifndef MATH_STANDALONE
# include "BLI_dynstr.h"
#endif
@@ -121,7 +123,7 @@ static PyObject *Quaternion_to_euler(QuaternionObject *self, PyObject *args)
else quat_to_eulO(eul, order, tquat);
}
- return Euler_CreatePyObject(eul, order, Py_NEW, NULL);
+ return Euler_CreatePyObject(eul, order, NULL);
}
PyDoc_STRVAR(Quaternion_to_matrix_doc,
@@ -140,7 +142,7 @@ static PyObject *Quaternion_to_matrix(QuaternionObject *self)
return NULL;
quat_to_mat3((float (*)[3])mat, self->quat);
- return Matrix_CreatePyObject(mat, 3, 3, Py_NEW, NULL);
+ return Matrix_CreatePyObject(mat, 3, 3, NULL);
}
PyDoc_STRVAR(Quaternion_to_axis_angle_doc,
@@ -169,11 +171,36 @@ static PyObject *Quaternion_to_axis_angle(QuaternionObject *self)
quat__axis_angle_sanitize(axis, &angle);
ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(axis, 3, Py_NEW, NULL));
- PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(angle));
+ PyTuple_SET_ITEMS(ret,
+ Vector_CreatePyObject(axis, 3, NULL),
+ PyFloat_FromDouble(angle));
return ret;
}
+PyDoc_STRVAR(Quaternion_to_exponential_map_doc,
+".. method:: to_exponential_map()\n"
+"\n"
+" Return the exponential map representation of the quaternion.\n"
+"\n"
+" This representation consist of the rotation axis multiplied by the rotation angle."
+" Such a representation is useful for interpolation between multiple orientations.\n"
+"\n"
+" :return: exponential map.\n"
+" :rtype: :class:`Vector` of size 3\n"
+"\n"
+" To convert back to a quaternion, pass it to the :class:`Quaternion` constructor.\n"
+);
+static PyObject *Quaternion_to_exponential_map(QuaternionObject *self)
+{
+ float expmap[3];
+
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ quat_to_expmap(expmap, self->quat);
+ return Vector_CreatePyObject(expmap, 3, NULL);
+}
+
PyDoc_STRVAR(Quaternion_cross_doc,
".. method:: cross(other)\n"
"\n"
@@ -198,7 +225,7 @@ static PyObject *Quaternion_cross(QuaternionObject *self, PyObject *value)
}
mul_qt_qtqt(quat, self->quat, tquat);
- return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self));
+ return Quaternion_CreatePyObject(quat, Py_TYPE(self));
}
PyDoc_STRVAR(Quaternion_dot_doc,
@@ -252,7 +279,7 @@ static PyObject *Quaternion_rotation_difference(QuaternionObject *self, PyObject
rotation_between_quats_to_quat(quat, self->quat, tquat);
- return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self));
+ return Quaternion_CreatePyObject(quat, Py_TYPE(self));
}
PyDoc_STRVAR(Quaternion_slerp_doc,
@@ -297,13 +324,13 @@ static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args)
interp_qt_qtqt(quat, self->quat, tquat, fac);
- return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self));
+ return Quaternion_CreatePyObject(quat, Py_TYPE(self));
}
PyDoc_STRVAR(Quaternion_rotate_doc,
".. method:: rotate(other)\n"
"\n"
-" Rotates the quaternion a by another mathutils value.\n"
+" Rotates the quaternion by another mathutils value.\n"
"\n"
" :arg other: rotation component of mathutils value\n"
" :type other: :class:`Euler`, :class:`Quaternion` or :class:`Matrix`\n"
@@ -313,7 +340,7 @@ static PyObject *Quaternion_rotate(QuaternionObject *self, PyObject *value)
float self_rmat[3][3], other_rmat[3][3], rmat[3][3];
float tquat[4], length;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (mathutils_any_to_rotmat(other_rmat, value, "Quaternion.rotate(value)") == -1)
@@ -331,7 +358,8 @@ static PyObject *Quaternion_rotate(QuaternionObject *self, PyObject *value)
}
/* ----------------------------Quaternion.normalize()---------------- */
-/* normalize the axis of rotation of [theta, vector] */
+/* Normalize the quaternion. This may change the angle as well as the
+ * rotation axis, as all of (w, x, y, z) are scaled. */
PyDoc_STRVAR(Quaternion_normalize_doc,
".. function:: normalize()\n"
"\n"
@@ -339,7 +367,7 @@ PyDoc_STRVAR(Quaternion_normalize_doc,
);
static PyObject *Quaternion_normalize(QuaternionObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
normalize_qt(self->quat);
@@ -367,7 +395,7 @@ PyDoc_STRVAR(Quaternion_invert_doc,
);
static PyObject *Quaternion_invert(QuaternionObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
invert_qt(self->quat);
@@ -393,12 +421,11 @@ PyDoc_STRVAR(Quaternion_identity_doc,
"\n"
" Set the quaternion to an identity quaternion.\n"
"\n"
-" :return: an instance of itself.\n"
" :rtype: :class:`Quaternion`\n"
);
static PyObject *Quaternion_identity(QuaternionObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
unit_qt(self->quat);
@@ -412,12 +439,11 @@ PyDoc_STRVAR(Quaternion_negate_doc,
"\n"
" Set the quaternion to its negative.\n"
"\n"
-" :return: an instance of itself.\n"
" :rtype: :class:`Quaternion`\n"
);
static PyObject *Quaternion_negate(QuaternionObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
mul_qt_fl(self->quat, -1.0f);
@@ -433,7 +459,7 @@ PyDoc_STRVAR(Quaternion_conjugate_doc,
);
static PyObject *Quaternion_conjugate(QuaternionObject *self)
{
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
conjugate_qt(self->quat);
@@ -470,7 +496,7 @@ static PyObject *Quaternion_copy(QuaternionObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- return Quaternion_CreatePyObject(self->quat, Py_NEW, Py_TYPE(self));
+ return Quaternion_CreatePyObject(self->quat, Py_TYPE(self));
}
static PyObject *Quaternion_deepcopy(QuaternionObject *self, PyObject *args)
{
@@ -546,7 +572,18 @@ static PyObject *Quaternion_richcmpr(PyObject *a, PyObject *b, int op)
return NULL;
}
- return Py_INCREF(res), res;
+ return Py_INCREF_RET(res);
+}
+
+static Py_hash_t Quaternion_hash(QuaternionObject *self)
+{
+ if (BaseMath_ReadCallback(self) == -1)
+ return -1;
+
+ if (BaseMathObject_Prepare_ForHash(self) == -1)
+ return -1;
+
+ return mathutils_array_hash(self->quat, QUAT_SIZE);
}
/* ---------------------SEQUENCE PROTOCOLS------------------------ */
@@ -579,8 +616,14 @@ static PyObject *Quaternion_item(QuaternionObject *self, int i)
/* sequence accessor (set) */
static int Quaternion_ass_item(QuaternionObject *self, int i, PyObject *ob)
{
- float scalar = (float)PyFloat_AsDouble(ob);
- if (scalar == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
+ float f;
+
+ if (BaseMath_Prepare_ForWrite(self) == -1)
+ return -1;
+
+ f = (float)PyFloat_AsDouble(ob);
+
+ if (f == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError,
"quaternion[index] = x: "
"assigned value not a number");
@@ -595,7 +638,7 @@ static int Quaternion_ass_item(QuaternionObject *self, int i, PyObject *ob)
"array assignment index out of range");
return -1;
}
- self->quat[i] = scalar;
+ self->quat[i] = f;
if (BaseMath_WriteIndexCallback(self, i) == -1)
return -1;
@@ -631,7 +674,7 @@ static int Quaternion_ass_slice(QuaternionObject *self, int begin, int end, PyOb
int i, size;
float quat[QUAT_SIZE];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
CLAMP(begin, 0, QUAT_SIZE);
@@ -750,7 +793,7 @@ static PyObject *Quaternion_add(PyObject *q1, PyObject *q2)
return NULL;
add_qt_qtqt(quat, quat1->quat, quat2->quat, 1.0f);
- return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1));
+ return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
}
/* ------------------------obj - obj------------------------------ */
/* subtraction */
@@ -778,7 +821,7 @@ static PyObject *Quaternion_sub(PyObject *q1, PyObject *q2)
quat[x] = quat1->quat[x] - quat2->quat[x];
}
- return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1));
+ return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
}
static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar)
@@ -786,7 +829,7 @@ static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar)
float tquat[4];
copy_qt_qt(tquat, quat->quat);
mul_qt_fl(tquat, scalar);
- return Quaternion_CreatePyObject(tquat, Py_NEW, Py_TYPE(quat));
+ return Quaternion_CreatePyObject(tquat, Py_TYPE(quat));
}
/*------------------------obj * obj------------------------------
@@ -809,7 +852,7 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
if (quat1 && quat2) { /* QUAT * QUAT (cross product) */
mul_qt_qtqt(quat, quat1->quat, quat2->quat);
- return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1));
+ return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
}
/* the only case this can happen (for a supported type is "FLOAT * QUAT") */
else if (quat2) { /* FLOAT * QUAT */
@@ -837,7 +880,7 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
copy_v3_v3(tvec, vec2->vec);
mul_qt_v3(quat1->quat, tvec);
- return Vector_CreatePyObject(tvec, 3, Py_NEW, Py_TYPE(vec2));
+ return Vector_CreatePyObject(tvec, 3, Py_TYPE(vec2));
}
/* QUAT * FLOAT */
else if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
@@ -865,7 +908,7 @@ static PyObject *Quaternion_neg(QuaternionObject *self)
return NULL;
negate_v4_v4(tquat, self->quat);
- return Quaternion_CreatePyObject(tquat, Py_NEW, Py_TYPE(self));
+ return Quaternion_CreatePyObject(tquat, Py_TYPE(self));
}
@@ -978,7 +1021,7 @@ static int Quaternion_angle_set(QuaternionObject *self, PyObject *value, void *U
float axis[3], angle_dummy;
float angle;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
len = normalize_qt_qt(tquat, self->quat);
@@ -1023,7 +1066,7 @@ static PyObject *Quaternion_axis_vector_get(QuaternionObject *self, void *UNUSED
quat__axis_angle_sanitize(axis, NULL);
- return Vector_CreatePyObject(axis, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(axis, 3, NULL);
}
static int Quaternion_axis_vector_set(QuaternionObject *self, PyObject *value, void *UNUSED(closure))
@@ -1034,7 +1077,7 @@ static int Quaternion_axis_vector_set(QuaternionObject *self, PyObject *value, v
float axis[3];
float angle;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
len = normalize_qt_qt(tquat, self->quat);
@@ -1075,9 +1118,24 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
case 0:
break;
case 1:
- if (mathutils_array_parse(quat, QUAT_SIZE, QUAT_SIZE, seq, "mathutils.Quaternion()") == -1)
+ {
+ int size;
+
+ if ((size = mathutils_array_parse(quat, 3, QUAT_SIZE, seq, "mathutils.Quaternion()")) == -1) {
return NULL;
+ }
+
+ if (size == 4) {
+ /* 4d: Quaternion (common case) */
+ }
+ else {
+ /* 3d: Interpret as exponential map */
+ BLI_assert(size == 3);
+ expmap_to_quat(quat, quat);
+ }
+
break;
+ }
case 2:
{
float axis[3];
@@ -1089,7 +1147,7 @@ static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kw
/* PyArg_ParseTuple assures no more than 2 */
}
}
- return Quaternion_CreatePyObject(quat, Py_NEW, type);
+ return Quaternion_CreatePyObject(quat, type);
}
static PyObject *quat__apply_to_copy(PyNoArgsFunction quat_func, QuaternionObject *self)
@@ -1154,6 +1212,7 @@ static struct PyMethodDef Quaternion_methods[] = {
{"to_euler", (PyCFunction) Quaternion_to_euler, METH_VARARGS, Quaternion_to_euler_doc},
{"to_matrix", (PyCFunction) Quaternion_to_matrix, METH_NOARGS, Quaternion_to_matrix_doc},
{"to_axis_angle", (PyCFunction) Quaternion_to_axis_angle, METH_NOARGS, Quaternion_to_axis_angle_doc},
+ {"to_exponential_map", (PyCFunction) Quaternion_to_exponential_map, METH_NOARGS, Quaternion_to_exponential_map_doc},
/* operation between 2 or more types */
{"cross", (PyCFunction) Quaternion_cross, METH_O, Quaternion_cross_doc},
@@ -1162,6 +1221,9 @@ static struct PyMethodDef Quaternion_methods[] = {
{"slerp", (PyCFunction) Quaternion_slerp, METH_VARARGS, Quaternion_slerp_doc},
{"rotate", (PyCFunction) Quaternion_rotate, METH_O, Quaternion_rotate_doc},
+ /* base-math methods */
+ {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
+
{"copy", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
{"__copy__", (PyCFunction) Quaternion_copy, METH_NOARGS, Quaternion_copy_doc},
{"__deepcopy__", (PyCFunction) Quaternion_deepcopy, METH_VARARGS, Quaternion_copy_doc},
@@ -1180,13 +1242,36 @@ static PyGetSetDef Quaternion_getseters[] = {
{(char *)"angle", (getter)Quaternion_angle_get, (setter)Quaternion_angle_set, Quaternion_angle_doc, NULL},
{(char *)"axis", (getter)Quaternion_axis_vector_get, (setter)Quaternion_axis_vector_set, Quaternion_axis_vector_doc, NULL},
{(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
+ {(char *)"is_frozen", (getter)BaseMathObject_is_frozen_get, (setter)NULL, BaseMathObject_is_frozen_doc, NULL},
{(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
/* ------------------PY_OBECT DEFINITION-------------------------- */
PyDoc_STRVAR(quaternion_doc,
-"This object gives access to Quaternions in Blender."
+".. class:: Quaternion([seq, [angle]])\n"
+"\n"
+" This object gives access to Quaternions in Blender.\n"
+"\n"
+" :param seq: size 3 or 4\n"
+" :type seq: :class:`Vector`\n"
+" :param angle: rotation angle, in radians\n"
+" :type angle: float\n"
+"\n"
+" The constructor takes arguments in various forms:\n"
+"\n"
+" (), *no args*\n"
+" Create an identity quaternion\n"
+" (*wxyz*)\n"
+" Create a quaternion from a ``(w, x, y, z)`` vector.\n"
+" (*exponential_map*)\n"
+" Create a quaternion from a 3d exponential map vector.\n"
+"\n"
+" .. seealso:: :meth:`to_exponential_map`\n"
+" (*axis, angle*)\n"
+" Create a quaternion representing a rotation of *angle* radians over *axis*.\n"
+"\n"
+" .. seealso:: :meth:`to_axis_angle`\n"
);
PyTypeObject quaternion_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -1202,7 +1287,7 @@ PyTypeObject quaternion_Type = {
&Quaternion_NumMethods, /* tp_as_number */
&Quaternion_SeqMethods, /* tp_as_sequence */
&Quaternion_AsMapping, /* tp_as_mapping */
- NULL, /* tp_hash */
+ (hashfunc)Quaternion_hash, /* tp_hash */
NULL, /* tp_call */
#ifndef MATH_STANDALONE
(reprfunc) Quaternion_str, /* tp_str */
@@ -1240,41 +1325,60 @@ PyTypeObject quaternion_Type = {
NULL, /* tp_weaklist */
NULL, /* tp_del */
};
-/* ------------------------Quaternion_CreatePyObject (internal)------------- */
-/* creates a new quaternion object */
-/*pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
- * (i.e. it was allocated elsewhere by MEM_mallocN())
- * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
- * (i.e. it must be created here with PyMEM_malloc())*/
-PyObject *Quaternion_CreatePyObject(float quat[4], int type, PyTypeObject *base_type)
+
+PyObject *Quaternion_CreatePyObject(
+ const float quat[4],
+ PyTypeObject *base_type)
{
QuaternionObject *self;
+ float *quat_alloc;
- self = base_type ? (QuaternionObject *)base_type->tp_alloc(base_type, 0) :
- (QuaternionObject *)PyObject_GC_New(QuaternionObject, &quaternion_Type);
+ quat_alloc = PyMem_Malloc(QUAT_SIZE * sizeof(float));
+ if (UNLIKELY(quat_alloc == NULL)) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Quaternion(): "
+ "problem allocating data");
+ return NULL;
+ }
+ self = BASE_MATH_NEW(QuaternionObject, quaternion_Type, base_type);
if (self) {
+ self->quat = quat_alloc;
/* init callbacks as NULL */
self->cb_user = NULL;
self->cb_type = self->cb_subtype = 0;
- if (type == Py_WRAP) {
- self->quat = quat;
- self->wrapped = Py_WRAP;
- }
- else if (type == Py_NEW) {
- self->quat = PyMem_Malloc(QUAT_SIZE * sizeof(float));
- if (!quat) { /* new empty */
- unit_qt(self->quat);
- }
- else {
- copy_qt_qt(self->quat, quat);
- }
- self->wrapped = Py_NEW;
+ /* NEW */
+ if (!quat) { /* new empty */
+ unit_qt(self->quat);
}
else {
- Py_FatalError("Quaternion(): invalid type!");
+ copy_qt_qt(self->quat, quat);
}
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ }
+ else {
+ PyMem_Free(quat_alloc);
+ }
+
+ return (PyObject *)self;
+}
+
+PyObject *Quaternion_CreatePyObject_wrap(
+ float quat[4],
+ PyTypeObject *base_type)
+{
+ QuaternionObject *self;
+
+ self = BASE_MATH_NEW(QuaternionObject, quaternion_Type, base_type);
+ if (self) {
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ /* WRAP */
+ self->quat = quat;
+ self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
}
return (PyObject *) self;
}
@@ -1282,7 +1386,7 @@ PyObject *Quaternion_CreatePyObject(float quat[4], int type, PyTypeObject *base_
PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user,
unsigned char cb_type, unsigned char cb_subtype)
{
- QuaternionObject *self = (QuaternionObject *)Quaternion_CreatePyObject(NULL, Py_NEW, NULL);
+ QuaternionObject *self = (QuaternionObject *)Quaternion_CreatePyObject(NULL, NULL);
if (self) {
Py_INCREF(cb_user);
self->cb_user = cb_user;
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.h b/source/blender/python/mathutils/mathutils_Quaternion.h
index 36036c6d3fa..66ee3362906 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.h
+++ b/source/blender/python/mathutils/mathutils_Quaternion.h
@@ -40,8 +40,17 @@ typedef struct {
* blender (stored in blend_data). This is an either/or struct not both */
/* prototypes */
-PyObject *Quaternion_CreatePyObject(float quat[4], int type, PyTypeObject *base_type);
-PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user,
- unsigned char cb_type, unsigned char cb_subtype);
+PyObject *Quaternion_CreatePyObject(
+ const float quat[4],
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT;
+PyObject *Quaternion_CreatePyObject_wrap(
+ float quat[4],
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+PyObject *Quaternion_CreatePyObject_cb(
+ PyObject *cb_user,
+ unsigned char cb_type, unsigned char cb_subtype
+ ) ATTR_WARN_UNUSED_RESULT;
#endif /* __MATHUTILS_QUATERNION_H__ */
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 15a9860be0a..a33b55c35dc 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -336,6 +336,9 @@ PyDoc_STRVAR(Vector_zero_doc,
);
static PyObject *Vector_zero(VectorObject *self)
{
+ if (BaseMath_Prepare_ForWrite(self) == -1)
+ return NULL;
+
fill_vn_fl(self->vec, self->size, 0.0f);
if (BaseMath_WriteCallback(self) == -1)
@@ -357,7 +360,7 @@ PyDoc_STRVAR(Vector_normalize_doc,
static PyObject *Vector_normalize(VectorObject *self)
{
int size = (self->size == 4 ? 3 : self->size);
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
normalize_vn(self->vec, size);
@@ -387,7 +390,7 @@ static PyObject *Vector_resize(VectorObject *self, PyObject *value)
{
int size;
- if (self->wrapped == Py_WRAP) {
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
PyErr_SetString(PyExc_TypeError,
"Vector.resize(): "
"cannot resize wrapped data - only python vectors");
@@ -475,7 +478,7 @@ PyDoc_STRVAR(Vector_resize_2d_doc,
);
static PyObject *Vector_resize_2d(VectorObject *self)
{
- if (self->wrapped == Py_WRAP) {
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
PyErr_SetString(PyExc_TypeError,
"Vector.resize_2d(): "
"cannot resize wrapped data - only python vectors");
@@ -507,7 +510,7 @@ PyDoc_STRVAR(Vector_resize_3d_doc,
);
static PyObject *Vector_resize_3d(VectorObject *self)
{
- if (self->wrapped == Py_WRAP) {
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
PyErr_SetString(PyExc_TypeError,
"Vector.resize_3d(): "
"cannot resize wrapped data - only python vectors");
@@ -542,7 +545,7 @@ PyDoc_STRVAR(Vector_resize_4d_doc,
);
static PyObject *Vector_resize_4d(VectorObject *self)
{
- if (self->wrapped == Py_WRAP) {
+ if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
PyErr_SetString(PyExc_TypeError,
"Vector.resize_4d(): "
"cannot resize wrapped data - only python vectors");
@@ -586,7 +589,7 @@ static PyObject *Vector_to_2d(VectorObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- return Vector_CreatePyObject(self->vec, 2, Py_NEW, Py_TYPE(self));
+ return Vector_CreatePyObject(self->vec, 2, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_to_3d_doc,
".. method:: to_3d()\n"
@@ -604,7 +607,7 @@ static PyObject *Vector_to_3d(VectorObject *self)
return NULL;
memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 3));
- return Vector_CreatePyObject(tvec, 3, Py_NEW, Py_TYPE(self));
+ return Vector_CreatePyObject(tvec, 3, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_to_4d_doc,
".. method:: to_4d()\n"
@@ -622,7 +625,7 @@ static PyObject *Vector_to_4d(VectorObject *self)
return NULL;
memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 4));
- return Vector_CreatePyObject(tvec, 4, Py_NEW, Py_TYPE(self));
+ return Vector_CreatePyObject(tvec, 4, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_to_tuple_doc,
@@ -797,7 +800,7 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
vec_to_quat(quat, vec, track, up);
- return Quaternion_CreatePyObject(quat, Py_NEW, NULL);
+ return Quaternion_CreatePyObject(quat, NULL);
}
PyDoc_STRVAR(Vector_orthogonal_doc,
@@ -829,7 +832,7 @@ static PyObject *Vector_orthogonal(VectorObject *self)
else
ortho_v2_v2(vec, self->vec);
- return Vector_CreatePyObject(vec, self->size, Py_NEW, Py_TYPE(self));
+ return Vector_CreatePyObject(vec, self->size, Py_TYPE(self));
}
@@ -877,7 +880,7 @@ static PyObject *Vector_reflect(VectorObject *self, PyObject *value)
normalize_v3(mirror);
reflect_v3_v3v3(reflect, vec, mirror);
- return Vector_CreatePyObject(reflect, self->size, Py_NEW, Py_TYPE(self));
+ return Vector_CreatePyObject(reflect, self->size, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_cross_doc,
@@ -910,7 +913,7 @@ static PyObject *Vector_cross(VectorObject *self, PyObject *value)
return NULL;
if (self->size == 3) {
- ret = Vector_CreatePyObject(NULL, 3, Py_NEW, Py_TYPE(self));
+ ret = Vector_CreatePyObject(NULL, 3, Py_TYPE(self));
cross_v3_v3v3(((VectorObject *)ret)->vec, self->vec, tvec);
}
else {
@@ -954,13 +957,11 @@ PyDoc_STRVAR(Vector_angle_doc,
"\n"
" :arg other: another vector to compare the angle with\n"
" :type other: :class:`Vector`\n"
-" :arg fallback: return this value when the angle can't be calculated\n"
-" (zero length vector)\n"
+" :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
+" (instead of raising a :exc:`ValueError`).\n"
" :type fallback: any\n"
" :return: angle in radians or fallback when given\n"
" :rtype: float\n"
-"\n"
-" .. note:: Zero length vectors raise an :exc:`ValueError`.\n"
);
static PyObject *Vector_angle(VectorObject *self, PyObject *args)
{
@@ -1018,13 +1019,11 @@ PyDoc_STRVAR(Vector_angle_signed_doc,
"\n"
" :arg other: another vector to compare the angle with\n"
" :type other: :class:`Vector`\n"
-" :arg fallback: return this value when the angle can't be calculated\n"
-" (zero length vector)\n"
+" :arg fallback: return this when the angle can't be calculated (zero length vector),\n"
+" (instead of raising a :exc:`ValueError`).\n"
" :type fallback: any\n"
" :return: angle in radians or fallback when given\n"
" :rtype: float\n"
-"\n"
-" .. note:: Zero length vectors raise an :exc:`ValueError`.\n"
);
static PyObject *Vector_angle_signed(VectorObject *self, PyObject *args)
{
@@ -1102,7 +1101,7 @@ static PyObject *Vector_rotation_difference(VectorObject *self, PyObject *value)
rotation_between_vecs_to_quat(quat, vec_a, vec_b);
- return Quaternion_CreatePyObject(quat, Py_NEW, NULL);
+ return Quaternion_CreatePyObject(quat, NULL);
}
PyDoc_STRVAR(Vector_project_doc,
@@ -1123,9 +1122,6 @@ static PyObject *Vector_project(VectorObject *self, PyObject *value)
double dot = 0.0f, dot2 = 0.0f;
int x;
- if (BaseMath_ReadCallback(self) == -1)
- return NULL;
-
if (mathutils_array_parse(tvec, size, size, value, "Vector.project(other), invalid 'other' arg") == -1)
return NULL;
@@ -1148,7 +1144,7 @@ static PyObject *Vector_project(VectorObject *self, PyObject *value)
for (x = 0; x < size; x++) {
vec[x] = (float)dot * tvec[x];
}
- return Vector_CreatePyObject(vec, size, Py_NEW, Py_TYPE(self));
+ return Vector_CreatePyObject(vec, size, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_lerp_doc,
@@ -1167,9 +1163,8 @@ static PyObject *Vector_lerp(VectorObject *self, PyObject *args)
{
const int size = self->size;
PyObject *value = NULL;
- float fac, ifac;
- float *tvec, *vec;
- int x;
+ float fac;
+ float *tvec;
if (!PyArg_ParseTuple(args, "Of:lerp", &value, &fac))
return NULL;
@@ -1182,23 +1177,9 @@ static PyObject *Vector_lerp(VectorObject *self, PyObject *args)
return NULL;
}
- vec = PyMem_Malloc(size * sizeof(float));
- if (vec == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Vector.lerp(): "
- "problem allocating pointer space");
- return NULL;
- }
-
- ifac = 1.0f - fac;
-
- for (x = 0; x < size; x++) {
- vec[x] = (ifac * self->vec[x]) + (fac * tvec[x]);
- }
-
- PyMem_Free(tvec);
+ interp_vn_vn(tvec, self->vec, 1.0f - fac, size);
- return Vector_CreatePyObject_alloc(vec, size, Py_TYPE(self));
+ return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_slerp_doc,
@@ -1210,8 +1191,8 @@ PyDoc_STRVAR(Vector_slerp_doc,
" :type other: :class:`Vector`\n"
" :arg factor: The interpolation value typically in [0.0, 1.0].\n"
" :type factor: float\n"
-" :arg fallback: return this value when the vector can't be calculated\n"
-" (zero length vector or direct opposites)\n"
+" :arg fallback: return this when the vector can't be calculated (zero length vector or direct opposites),\n"
+" (instead of raising a :exc:`ValueError`).\n"
" :type fallback: any\n"
" :return: The interpolated vector.\n"
" :rtype: :class:`Vector`\n"
@@ -1287,7 +1268,7 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args)
ret_vec[x] = (w[0] * self_vec[x]) + (w[1] * other_vec[x]);
}
- return Vector_CreatePyObject(ret_vec, size, Py_NEW, Py_TYPE(self));
+ return Vector_CreatePyObject(ret_vec, size, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_rotate_doc,
@@ -1302,7 +1283,7 @@ static PyObject *Vector_rotate(VectorObject *self, PyObject *value)
{
float other_rmat[3][3];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return NULL;
if (mathutils_any_to_rotmat(other_rmat, value, "Vector.rotate(value)") == -1)
@@ -1336,7 +1317,7 @@ static PyObject *Vector_copy(VectorObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- return Vector_CreatePyObject(self->vec, self->size, Py_NEW, Py_TYPE(self));
+ return Vector_CreatePyObject(self->vec, self->size, Py_TYPE(self));
}
static PyObject *Vector_deepcopy(VectorObject *self, PyObject *args)
{
@@ -1420,6 +1401,10 @@ static PyObject *Vector_item(VectorObject *self, int i)
static int vector_ass_item_internal(VectorObject *self, int i, PyObject *value, const bool is_attr)
{
float scalar;
+
+ if (BaseMath_Prepare_ForWrite(self) == -1)
+ return -1;
+
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
PyErr_SetString(PyExc_TypeError,
"vector[index] = x: "
@@ -1481,7 +1466,7 @@ static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *se
int size = 0;
float *vec = NULL;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
CLAMP(begin, 0, self->size);
@@ -1540,8 +1525,7 @@ static PyObject *Vector_add(PyObject *v1, PyObject *v2)
}
vec = PyMem_Malloc(vec1->size * sizeof(float));
-
- if (vec == NULL) { /*allocation failure*/
+ if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
"Vector(): "
"problem allocating pointer space");
@@ -1575,7 +1559,7 @@ static PyObject *Vector_iadd(PyObject *v1, PyObject *v2)
return NULL;
}
- if (BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1)
+ if (BaseMath_ReadCallback_ForWrite(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1)
return NULL;
add_vn_vn(vec1->vec, vec2->vec, vec1->size);
@@ -1612,8 +1596,7 @@ static PyObject *Vector_sub(PyObject *v1, PyObject *v2)
}
vec = PyMem_Malloc(vec1->size * sizeof(float));
-
- if (vec == NULL) { /*allocation failure*/
+ if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
"Vector(): "
"problem allocating pointer space");
@@ -1647,7 +1630,7 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
return NULL;
}
- if (BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1)
+ if (BaseMath_ReadCallback_ForWrite(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1)
return NULL;
sub_vn_vn(vec1->vec, vec2->vec, vec1->size);
@@ -1705,8 +1688,7 @@ int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec,
static PyObject *vector_mul_float(VectorObject *vec, const float scalar)
{
float *tvec = PyMem_Malloc(vec->size * sizeof(float));
-
- if (tvec == NULL) { /*allocation failure*/
+ if (tvec == NULL) {
PyErr_SetString(PyExc_MemoryError,
"vec * float: "
"problem allocating pointer space");
@@ -1765,7 +1747,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
vec_size = ((MatrixObject *)v2)->num_col;
}
- return Vector_CreatePyObject(tvec, vec_size, Py_NEW, Py_TYPE(vec1));
+ return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(vec1));
}
else if (QuaternionObject_Check(v2)) {
/* VEC * QUAT */
@@ -1791,7 +1773,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
copy_v3_v3(tvec, vec1->vec);
mul_qt_v3(quat2->quat, tvec);
- return Vector_CreatePyObject(tvec, 3, Py_NEW, Py_TYPE(vec1));
+ return Vector_CreatePyObject(tvec, 3, Py_TYPE(vec1));
#endif
/* ------ to be removed ------*/
}
@@ -1821,7 +1803,7 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
VectorObject *vec = (VectorObject *)v1;
float scalar;
- if (BaseMath_ReadCallback(vec) == -1)
+ if (BaseMath_ReadCallback_ForWrite(vec) == -1)
return NULL;
/* only support vec*=float and vec*=mat
@@ -1923,7 +1905,7 @@ static PyObject *Vector_div(PyObject *v1, PyObject *v2)
vec = PyMem_Malloc(vec1->size * sizeof(float));
- if (vec == NULL) { /*allocation failure*/
+ if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
"vec / value: "
"problem allocating pointer space");
@@ -1941,7 +1923,7 @@ static PyObject *Vector_idiv(PyObject *v1, PyObject *v2)
float scalar;
VectorObject *vec1 = (VectorObject *)v1;
- if (BaseMath_ReadCallback(vec1) == -1)
+ if (BaseMath_ReadCallback_ForWrite(vec1) == -1)
return NULL;
if ((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) { /* parsed item not a number */
@@ -2065,6 +2047,17 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
}
}
+static Py_hash_t Vector_hash(VectorObject *self)
+{
+ if (BaseMath_ReadCallback(self) == -1)
+ return -1;
+
+ if (BaseMathObject_Prepare_ForHash(self) == -1)
+ return -1;
+
+ return mathutils_array_hash(self->vec, self->size);
+}
+
/*-----------------PROTCOL DECLARATIONS--------------------------*/
static PySequenceMethods Vector_SeqMethods = {
(lenfunc) Vector_len, /* sq_length */
@@ -2228,7 +2221,7 @@ static int Vector_length_set(VectorObject *self, PyObject *value)
{
double dot = 0.0f, param;
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
if ((param = PyFloat_AsDouble(value)) == -1.0 && PyErr_Occurred()) {
@@ -2308,7 +2301,7 @@ static PyObject *Vector_swizzle_get(VectorObject *self, void *closure)
axis_to++;
}
- return Vector_CreatePyObject(vec, axis_to, Py_NEW, Py_TYPE(self));
+ return Vector_CreatePyObject(vec, axis_to, Py_TYPE(self));
}
/* Set the items of this vector using a swizzle.
@@ -2334,7 +2327,7 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure
float tvec[MAX_DIMENSIONS];
float vec_assign[MAX_DIMENSIONS];
- if (BaseMath_ReadCallback(self) == -1)
+ if (BaseMath_ReadCallback_ForWrite(self) == -1)
return -1;
/* Check that the closure can be used with this vector: even 2D vectors have
@@ -2415,6 +2408,7 @@ static PyGetSetDef Vector_getseters[] = {
{(char *)"length_squared", (getter)Vector_length_squared_get, (setter)NULL, Vector_length_squared_doc, NULL},
{(char *)"magnitude", (getter)Vector_length_get, (setter)Vector_length_set, Vector_length_doc, NULL},
{(char *)"is_wrapped", (getter)BaseMathObject_is_wrapped_get, (setter)NULL, BaseMathObject_is_wrapped_doc, NULL},
+ {(char *)"is_frozen", (getter)BaseMathObject_is_frozen_get, (setter)NULL, BaseMathObject_is_frozen_doc, NULL},
{(char *)"owner", (getter)BaseMathObject_owner_get, (setter)NULL, BaseMathObject_owner_doc, NULL},
/* autogenerated swizzle attrs, see python script below */
@@ -2893,6 +2887,9 @@ static struct PyMethodDef Vector_methods[] = {
{"slerp", (PyCFunction) Vector_slerp, METH_VARARGS, Vector_slerp_doc},
{"rotate", (PyCFunction) Vector_rotate, METH_O, Vector_rotate_doc},
+ /* base-math methods */
+ {"freeze", (PyCFunction)BaseMathObject_freeze, METH_NOARGS, BaseMathObject_freeze_doc},
+
{"copy", (PyCFunction) Vector_copy, METH_NOARGS, Vector_copy_doc},
{"__copy__", (PyCFunction) Vector_copy, METH_NOARGS, NULL},
{"__deepcopy__", (PyCFunction) Vector_deepcopy, METH_VARARGS, NULL},
@@ -2907,7 +2904,12 @@ static struct PyMethodDef Vector_methods[] = {
*/
PyDoc_STRVAR(vector_doc,
-"This object gives access to Vectors in Blender."
+".. class:: Vector(seq)\n"
+"\n"
+" This object gives access to Vectors in Blender.\n"
+"\n"
+" :param seq: Components of the vector, must be a sequence of at least two\n"
+" :type seq: sequence of numbers\n"
);
PyTypeObject vector_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
@@ -2933,7 +2935,7 @@ PyTypeObject vector_Type = {
/* More standard operations (here for binary compatibility) */
- NULL, /* hashfunc tp_hash; */
+ (hashfunc)Vector_hash, /* hashfunc tp_hash; */
NULL, /* ternaryfunc tp_call; */
#ifndef MATH_STANDALONE
(reprfunc)Vector_str, /* reprfunc tp_str; */
@@ -2994,15 +2996,12 @@ PyTypeObject vector_Type = {
NULL
};
-/*------------------------Vector_CreatePyObject (internal)-------------
- * creates a new vector object
- * pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
- * (i.e. it was allocated elsewhere by MEM_mallocN())
- * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
- * (i.e. it must be created here with PyMEM_malloc())*/
-PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTypeObject *base_type)
+PyObject *Vector_CreatePyObject(
+ const float *vec, const int size,
+ PyTypeObject *base_type)
{
VectorObject *self;
+ float *vec_alloc;
if (size < 2) {
PyErr_SetString(PyExc_RuntimeError,
@@ -3010,44 +3009,72 @@ PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTy
return NULL;
}
- self = base_type ? (VectorObject *)base_type->tp_alloc(base_type, 0) :
- (VectorObject *)PyObject_GC_New(VectorObject, &vector_Type);
+ vec_alloc = PyMem_Malloc(size * sizeof(float));
+ if (UNLIKELY(vec_alloc == NULL)) {
+ PyErr_SetString(PyExc_MemoryError,
+ "Vector(): "
+ "problem allocating data");
+ return NULL;
+ }
+ self = BASE_MATH_NEW(VectorObject, vector_Type, base_type);
if (self) {
+ self->vec = vec_alloc;
self->size = size;
/* init callbacks as NULL */
self->cb_user = NULL;
self->cb_type = self->cb_subtype = 0;
- if (type == Py_WRAP) {
- self->vec = vec;
- self->wrapped = Py_WRAP;
+ if (vec) {
+ memcpy(self->vec, vec, size * sizeof(float));
}
- else if (type == Py_NEW) {
- self->vec = PyMem_Malloc(size * sizeof(float));
- if (vec) {
- memcpy(self->vec, vec, size * sizeof(float));
+ else { /* new empty */
+ fill_vn_fl(self->vec, size, 0.0f);
+ if (size == 4) { /* do the homogeneous thing */
+ self->vec[3] = 1.0f;
}
- else { /* new empty */
- fill_vn_fl(self->vec, size, 0.0f);
- if (size == 4) { /* do the homogeneous thing */
- self->vec[3] = 1.0f;
- }
- }
- self->wrapped = Py_NEW;
- }
- else {
- Py_FatalError("Vector(): invalid type!");
}
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ }
+ else {
+ PyMem_Free(vec_alloc);
+ }
+
+ return (PyObject *)self;
+}
+
+PyObject *Vector_CreatePyObject_wrap(
+ float *vec, const int size,
+ PyTypeObject *base_type)
+{
+ VectorObject *self;
+
+ if (size < 2) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Vector(): invalid size");
+ return NULL;
+ }
+
+ self = BASE_MATH_NEW(VectorObject, vector_Type, base_type);
+ if (self) {
+ self->size = size;
+
+ /* init callbacks as NULL */
+ self->cb_user = NULL;
+ self->cb_type = self->cb_subtype = 0;
+
+ self->vec = vec;
+ self->flag = BASE_MATH_FLAG_DEFAULT | BASE_MATH_FLAG_IS_WRAP;
}
return (PyObject *) self;
}
-PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, unsigned char cb_type, unsigned char cb_subtype)
+PyObject *Vector_CreatePyObject_cb(
+ PyObject *cb_user, int size,
+ unsigned char cb_type, unsigned char cb_subtype)
{
- float dummy[4] = {0.0, 0.0, 0.0, 0.0}; /* dummy init vector, callbacks will be used on access */
- VectorObject *self = (VectorObject *)Vector_CreatePyObject(dummy, size, Py_NEW, NULL);
+ VectorObject *self = (VectorObject *)Vector_CreatePyObject(NULL, size, NULL);
if (self) {
Py_INCREF(cb_user);
self->cb_user = cb_user;
@@ -3059,11 +3086,15 @@ PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, unsigned char cb
return (PyObject *)self;
}
-PyObject *Vector_CreatePyObject_alloc(const float *vec, const int size, PyTypeObject *base_type)
+PyObject *Vector_CreatePyObject_alloc(
+ float *vec, const int size,
+ PyTypeObject *base_type)
{
- VectorObject *vect_ob;
- vect_ob = (VectorObject *)Vector_CreatePyObject((float *)vec, size, Py_WRAP, base_type);
- vect_ob->wrapped = Py_NEW;
+ VectorObject *self;
+ self = (VectorObject *)Vector_CreatePyObject_wrap(vec, size, base_type);
+ if (self) {
+ self->flag = BASE_MATH_FLAG_DEFAULT;
+ }
- return (PyObject *)vect_ob;
+ return (PyObject *)self;
}
diff --git a/source/blender/python/mathutils/mathutils_Vector.h b/source/blender/python/mathutils/mathutils_Vector.h
index 2074270670a..74ca3336f4b 100644
--- a/source/blender/python/mathutils/mathutils_Vector.h
+++ b/source/blender/python/mathutils/mathutils_Vector.h
@@ -34,13 +34,25 @@ extern PyTypeObject vector_Type;
typedef struct {
BASE_MATH_MEMBERS(vec);
- int size; /* vec size 2,3 or 4 */
+ int size; /* vec size 2 or more */
} VectorObject;
/*prototypes*/
-PyObject *Vector_CreatePyObject(float *vec, const int size, const int type, PyTypeObject *base_type);
-PyObject *Vector_CreatePyObject_cb(PyObject *user, int size,
- unsigned char cb_type, unsigned char subtype);
-PyObject *Vector_CreatePyObject_alloc(const float *vec, const int size, PyTypeObject *base_type);
+PyObject *Vector_CreatePyObject(
+ const float *vec, const int size,
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT;
+PyObject *Vector_CreatePyObject_wrap(
+ float *vec, const int size,
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+PyObject *Vector_CreatePyObject_cb(
+ PyObject *user, int size,
+ unsigned char cb_type, unsigned char subtype
+ ) ATTR_WARN_UNUSED_RESULT;
+PyObject *Vector_CreatePyObject_alloc(
+ float *vec, const int size,
+ PyTypeObject *base_type
+ ) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
#endif /* __MATHUTILS_VECTOR_H__ */
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 0f0ffe9fec5..bb4080decef 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -42,6 +42,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "../generic/python_utildefines.h"
/*-------------------------DOC STRINGS ---------------------------*/
PyDoc_STRVAR(M_Geometry_doc,
@@ -72,48 +73,37 @@ PyDoc_STRVAR(M_Geometry_intersect_ray_tri_doc,
);
static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *ray, *ray_off, *vec1, *vec2, *vec3;
- float dir[3], orig[3], v1[3], v2[3], v3[3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
+ const char *error_prefix = "intersect_ray_tri";
+ PyObject *py_ray, *py_ray_off, *py_tri[3];
+ float dir[3], orig[3], tri[3][3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
float det, inv_det, u, v, t;
int clip = 1;
+ int i;
- if (!PyArg_ParseTuple(args,
- "O!O!O!O!O!|i:intersect_ray_tri",
- &vector_Type, &vec1,
- &vector_Type, &vec2,
- &vector_Type, &vec3,
- &vector_Type, &ray,
- &vector_Type, &ray_off, &clip))
+ if (!PyArg_ParseTuple(
+ args, "OOOOO|i:intersect_ray_tri",
+ UNPACK3_EX(&, py_tri, ), &py_ray, &py_ray_off, &clip))
{
return NULL;
}
- if (vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || ray->size != 3 || ray_off->size != 3) {
- PyErr_SetString(PyExc_ValueError,
- "only 3D vectors for all parameters");
- return NULL;
- }
- if (BaseMath_ReadCallback(vec1) == -1 ||
- BaseMath_ReadCallback(vec2) == -1 ||
- BaseMath_ReadCallback(vec3) == -1 ||
- BaseMath_ReadCallback(ray) == -1 ||
- BaseMath_ReadCallback(ray_off) == -1)
+ if (((mathutils_array_parse(dir, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_ray, error_prefix) != -1) &&
+ (mathutils_array_parse(orig, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_ray_off, error_prefix) != -1)) == 0)
{
return NULL;
}
- copy_v3_v3(v1, vec1->vec);
- copy_v3_v3(v2, vec2->vec);
- copy_v3_v3(v3, vec3->vec);
+ for (i = 0; i < ARRAY_SIZE(tri); i++) {
+ if (mathutils_array_parse(tri[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_tri[i], error_prefix) == -1) {
+ return NULL;
+ }
+ }
- copy_v3_v3(dir, ray->vec);
normalize_v3(dir);
- copy_v3_v3(orig, ray_off->vec);
-
/* find vectors for two edges sharing v1 */
- sub_v3_v3v3(e1, v2, v1);
- sub_v3_v3v3(e2, v3, v1);
+ sub_v3_v3v3(e1, tri[1], tri[0]);
+ sub_v3_v3v3(e2, tri[2], tri[0]);
/* begin calculating determinant - also used to calculated U parameter */
cross_v3_v3v3(pvec, dir, e2);
@@ -128,7 +118,7 @@ static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject *
inv_det = 1.0f / det;
/* calculate distance from v1 to ray origin */
- sub_v3_v3v3(tvec, orig, v1);
+ sub_v3_v3v3(tvec, orig, tri[0]);
/* calculate U parameter and test bounds */
u = dot_v3v3(tvec, pvec) * inv_det;
@@ -157,7 +147,7 @@ static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject *
mul_v3_fl(dir, t);
add_v3_v3v3(pvec, orig, dir);
- return Vector_CreatePyObject(pvec, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(pvec, 3, NULL);
}
/* Line-Line intersection using algorithm from mathworld.wolfram.com */
@@ -179,82 +169,45 @@ PyDoc_STRVAR(M_Geometry_intersect_line_line_doc,
);
static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject *args)
{
+ const char *error_prefix = "intersect_line_line";
PyObject *tuple;
- VectorObject *vec1, *vec2, *vec3, *vec4;
- float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3];
-
- if (!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line",
- &vector_Type, &vec1,
- &vector_Type, &vec2,
- &vector_Type, &vec3,
- &vector_Type, &vec4))
+ PyObject *py_lines[4];
+ float lines[4][3], i1[3], i2[3];
+ int len;
+ int result;
+
+ if (!PyArg_ParseTuple(
+ args, "OOOO:intersect_line_line",
+ UNPACK4_EX(&, py_lines, )))
{
return NULL;
}
- if (vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) {
- PyErr_SetString(PyExc_ValueError,
- "vectors must be of the same size");
- return NULL;
- }
-
- if (BaseMath_ReadCallback(vec1) == -1 ||
- BaseMath_ReadCallback(vec2) == -1 ||
- BaseMath_ReadCallback(vec3) == -1 ||
- BaseMath_ReadCallback(vec4) == -1)
+ if ((((len = mathutils_array_parse(lines[0], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[0], error_prefix)) != -1) &&
+ (mathutils_array_parse(lines[1], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[1], error_prefix) != -1) &&
+ (mathutils_array_parse(lines[2], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[2], error_prefix) != -1) &&
+ (mathutils_array_parse(lines[3], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[3], error_prefix) != -1)) == 0)
{
return NULL;
}
- if (vec1->size == 3 || vec1->size == 2) {
- int result;
-
- if (vec1->size == 3) {
- copy_v3_v3(v1, vec1->vec);
- copy_v3_v3(v2, vec2->vec);
- copy_v3_v3(v3, vec3->vec);
- copy_v3_v3(v4, vec4->vec);
- }
- else {
- v1[0] = vec1->vec[0];
- v1[1] = vec1->vec[1];
- v1[2] = 0.0f;
-
- v2[0] = vec2->vec[0];
- v2[1] = vec2->vec[1];
- v2[2] = 0.0f;
-
- v3[0] = vec3->vec[0];
- v3[1] = vec3->vec[1];
- v3[2] = 0.0f;
-
- v4[0] = vec4->vec[0];
- v4[1] = vec4->vec[1];
- v4[2] = 0.0f;
- }
-
- result = isect_line_line_v3(v1, v2, v3, v4, i1, i2);
- /* The return-code isnt exposed,
- * this way we can check know how close the lines are. */
- if (result == 1) {
- closest_to_line_v3(i2, i1, v3, v4);
- }
+ result = isect_line_line_v3(UNPACK4(lines), i1, i2);
+ /* The return-code isnt exposed,
+ * this way we can check know how close the lines are. */
+ if (result == 1) {
+ closest_to_line_v3(i2, i1, lines[2], lines[3]);
+ }
- if (result == 0) {
- /* colinear */
- Py_RETURN_NONE;
- }
- else {
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEM(tuple, 0, Vector_CreatePyObject(i1, vec1->size, Py_NEW, NULL));
- PyTuple_SET_ITEM(tuple, 1, Vector_CreatePyObject(i2, vec1->size, Py_NEW, NULL));
- return tuple;
- }
+ if (result == 0) {
+ /* colinear */
+ Py_RETURN_NONE;
}
else {
- PyErr_SetString(PyExc_ValueError,
- "2D/3D vectors only");
- return NULL;
+ tuple = PyTuple_New(2);
+ PyTuple_SET_ITEMS(tuple,
+ Vector_CreatePyObject(i1, len, NULL),
+ Vector_CreatePyObject(i2, len, NULL));
+ return tuple;
}
}
@@ -277,31 +230,30 @@ PyDoc_STRVAR(M_Geometry_intersect_sphere_sphere_2d_doc,
);
static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), PyObject *args)
{
+ const char *error_prefix = "intersect_sphere_sphere_2d";
PyObject *ret;
- VectorObject *vec_a, *vec_b;
- const float *v_a, *v_b;
+ PyObject *py_v_a, *py_v_b;
+ float v_a[2], v_b[2];
float rad_a, rad_b;
float v_ab[2];
float dist;
- if (!PyArg_ParseTuple(args, "O!fO!f:intersect_sphere_sphere_2d",
- &vector_Type, &vec_a, &rad_a,
- &vector_Type, &vec_b, &rad_b))
+ if (!PyArg_ParseTuple(
+ args, "OfOf:intersect_sphere_sphere_2d",
+ &py_v_a, &rad_a,
+ &py_v_b, &rad_b))
{
return NULL;
}
- if (BaseMath_ReadCallback(vec_a) == -1 ||
- BaseMath_ReadCallback(vec_b) == -1)
+ if (((mathutils_array_parse(v_a, 2, 2, py_v_a, error_prefix) != -1) &&
+ (mathutils_array_parse(v_b, 2, 2, py_v_b, error_prefix) != -1)) == 0)
{
return NULL;
}
ret = PyTuple_New(2);
- v_a = vec_a->vec;
- v_b = vec_b->vec;
-
sub_v2_v2v2(v_ab, v_b, v_a);
dist = len_v2(v_ab);
@@ -313,8 +265,9 @@ static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), P
(dist < FLT_EPSILON))
{
/* out of range */
- PyTuple_SET_ITEM(ret, 0, Py_None); Py_INCREF(Py_None);
- PyTuple_SET_ITEM(ret, 1, Py_None); Py_INCREF(Py_None);
+ PyTuple_SET_ITEMS(ret,
+ Py_INCREF_RET(Py_None),
+ Py_INCREF_RET(Py_None));
}
else {
const float dist_delta = ((rad_a * rad_a) - (rad_b * rad_b) + (dist * dist)) / (2.0f * dist);
@@ -331,94 +284,51 @@ static PyObject *M_Geometry_intersect_sphere_sphere_2d(PyObject *UNUSED(self), P
i2[0] = i_cent[0] - h * v_ab[1] / dist;
i2[1] = i_cent[1] + h * v_ab[0] / dist;
- PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(i1, 2, Py_NEW, NULL));
- PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(i2, 2, Py_NEW, NULL));
+ PyTuple_SET_ITEMS(ret,
+ Vector_CreatePyObject(i1, 2, NULL),
+ Vector_CreatePyObject(i2, 2, NULL));
}
return ret;
}
PyDoc_STRVAR(M_Geometry_normal_doc,
-".. function:: normal(v1, v2, v3, v4=None)\n"
+".. function:: normal(vectors)\n"
"\n"
-" Returns the normal of the 3D tri or quad.\n"
+" Returns the normal of a 3D polygon.\n"
"\n"
-" :arg v1: Point1\n"
-" :type v1: :class:`mathutils.Vector`\n"
-" :arg v2: Point2\n"
-" :type v2: :class:`mathutils.Vector`\n"
-" :arg v3: Point3\n"
-" :type v3: :class:`mathutils.Vector`\n"
-" :arg v4: Point4 (optional)\n"
-" :type v4: :class:`mathutils.Vector`\n"
+" :arg vectors: Vectors to calculate normals with\n"
+" :type vectors: sequence of 3 or more 3d vector\n"
" :rtype: :class:`mathutils.Vector`\n"
);
static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *vec1, *vec2, *vec3, *vec4;
+ float (*coords)[3];
+ int coords_len;
float n[3];
+ PyObject *ret = NULL;
- if (PyTuple_GET_SIZE(args) == 3) {
- if (!PyArg_ParseTuple(args, "O!O!O!:normal",
- &vector_Type, &vec1,
- &vector_Type, &vec2,
- &vector_Type, &vec3))
- {
- return NULL;
- }
-
- if (vec1->size != vec2->size || vec1->size != vec3->size) {
- PyErr_SetString(PyExc_ValueError,
- "vectors must be of the same size");
- return NULL;
- }
- if (vec1->size < 3) {
- PyErr_SetString(PyExc_ValueError,
- "2D vectors unsupported");
- return NULL;
- }
-
- if (BaseMath_ReadCallback(vec1) == -1 ||
- BaseMath_ReadCallback(vec2) == -1 ||
- BaseMath_ReadCallback(vec3) == -1)
- {
- return NULL;
- }
-
- normal_tri_v3(n, vec1->vec, vec2->vec, vec3->vec);
+ /* use */
+ if (PyTuple_GET_SIZE(args) == 1) {
+ args = PyTuple_GET_ITEM(args, 0);
}
- else {
- if (!PyArg_ParseTuple(args, "O!O!O!O!:normal",
- &vector_Type, &vec1,
- &vector_Type, &vec2,
- &vector_Type, &vec3,
- &vector_Type, &vec4))
- {
- return NULL;
- }
- if (vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) {
- PyErr_SetString(PyExc_ValueError,
- "vectors must be of the same size");
- return NULL;
- }
- if (vec1->size < 3) {
- PyErr_SetString(PyExc_ValueError,
- "2D vectors unsupported");
- return NULL;
- }
- if (BaseMath_ReadCallback(vec1) == -1 ||
- BaseMath_ReadCallback(vec2) == -1 ||
- BaseMath_ReadCallback(vec3) == -1 ||
- BaseMath_ReadCallback(vec4) == -1)
- {
- return NULL;
- }
+ if ((coords_len = mathutils_array_parse_alloc_v((float **)&coords, 3 | MU_ARRAY_SPILL, args, "normal")) == -1) {
+ return NULL;
+ }
- normal_quad_v3(n, vec1->vec, vec2->vec, vec3->vec, vec4->vec);
+ if (coords_len < 3) {
+ PyErr_SetString(PyExc_ValueError,
+ "Expected 3 or more vectors");
+ goto finally;
}
- return Vector_CreatePyObject(n, 3, Py_NEW, NULL);
+ normal_poly_v3(n, (const float (*)[3])coords, coords_len);
+ ret = Vector_CreatePyObject(n, 3, NULL);
+
+finally:
+ PyMem_Free(coords);
+ return ret;
}
/* --------------------------------- AREA FUNCTIONS-------------------- */
@@ -438,40 +348,26 @@ PyDoc_STRVAR(M_Geometry_area_tri_doc,
);
static PyObject *M_Geometry_area_tri(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *vec1, *vec2, *vec3;
-
- if (!PyArg_ParseTuple(args, "O!O!O!:area_tri",
- &vector_Type, &vec1,
- &vector_Type, &vec2,
- &vector_Type, &vec3))
+ const char *error_prefix = "area_tri";
+ PyObject *py_tri[3];
+ float tri[3][3];
+ int len;
+
+ if (!PyArg_ParseTuple(
+ args, "OOO:area_tri",
+ UNPACK3_EX(&, py_tri, )))
{
return NULL;
}
- if (vec1->size != vec2->size || vec1->size != vec3->size) {
- PyErr_SetString(PyExc_ValueError,
- "vectors must be of the same size");
- return NULL;
- }
-
- if (BaseMath_ReadCallback(vec1) == -1 ||
- BaseMath_ReadCallback(vec2) == -1 ||
- BaseMath_ReadCallback(vec3) == -1)
+ if ((((len = mathutils_array_parse(tri[0], 2, 3, py_tri[0], error_prefix)) != -1) &&
+ (mathutils_array_parse(tri[1], len, len, py_tri[1], error_prefix) != -1) &&
+ (mathutils_array_parse(tri[2], len, len, py_tri[2], error_prefix) != -1)) == 0)
{
return NULL;
}
- if (vec1->size == 3) {
- return PyFloat_FromDouble(area_tri_v3(vec1->vec, vec2->vec, vec3->vec));
- }
- else if (vec1->size == 2) {
- return PyFloat_FromDouble(area_tri_v2(vec1->vec, vec2->vec, vec3->vec));
- }
- else {
- PyErr_SetString(PyExc_ValueError,
- "only 2D,3D vectors are supported");
- return NULL;
- }
+ return PyFloat_FromDouble((len == 3 ? area_tri_v3 : area_tri_v2)(UNPACK3(tri)));
}
PyDoc_STRVAR(M_Geometry_volume_tetrahedron_doc,
@@ -491,33 +387,25 @@ PyDoc_STRVAR(M_Geometry_volume_tetrahedron_doc,
);
static PyObject *M_Geometry_volume_tetrahedron(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *vec1, *vec2, *vec3, *vec4;
+ const char *error_prefix = "volume_tetrahedron";
+ PyObject *py_tet[4];
+ float tet[4][3];
+ int i;
- if (!PyArg_ParseTuple(args, "O!O!O!O!:volume_tetrahedron",
- &vector_Type, &vec1,
- &vector_Type, &vec2,
- &vector_Type, &vec3,
- &vector_Type, &vec4))
+ if (!PyArg_ParseTuple(
+ args, "OOOO:volume_tetrahedron",
+ UNPACK4_EX(&, py_tet, )))
{
return NULL;
}
- if (vec1->size < 3 || vec2->size < 3 || vec3->size < 3 || vec4->size < 3) {
- PyErr_SetString(PyExc_ValueError,
- "geometry.volume_tetrahedron(...): "
- " can't use 2D Vectors");
- return NULL;
- }
-
- if (BaseMath_ReadCallback(vec1) == -1 ||
- BaseMath_ReadCallback(vec2) == -1 ||
- BaseMath_ReadCallback(vec3) == -1 ||
- BaseMath_ReadCallback(vec4) == -1)
- {
- return NULL;
+ for (i = 0; i < ARRAY_SIZE(tet); i++) {
+ if (mathutils_array_parse(tet[i], 3, 3 | MU_ARRAY_SPILL, py_tet[i], error_prefix) == -1) {
+ return NULL;
+ }
}
- return PyFloat_FromDouble(volume_tetrahedron_v3(vec1->vec, vec2->vec, vec3->vec, vec4->vec));
+ return PyFloat_FromDouble(volume_tetrahedron_v3(UNPACK4(tet)));
}
PyDoc_STRVAR(M_Geometry_intersect_line_line_2d_doc,
@@ -538,27 +426,27 @@ PyDoc_STRVAR(M_Geometry_intersect_line_line_2d_doc,
);
static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *line_a1, *line_a2, *line_b1, *line_b2;
+ const char *error_prefix = "intersect_line_line_2d";
+ PyObject *py_lines[4];
+ float lines[4][2];
float vi[2];
- if (!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line_2d",
- &vector_Type, &line_a1,
- &vector_Type, &line_a2,
- &vector_Type, &line_b1,
- &vector_Type, &line_b2))
+ int i;
+
+ if (!PyArg_ParseTuple(
+ args, "OOOO:intersect_line_line_2d",
+ UNPACK4_EX(&, py_lines, )))
{
return NULL;
}
-
- if (BaseMath_ReadCallback(line_a1) == -1 ||
- BaseMath_ReadCallback(line_a2) == -1 ||
- BaseMath_ReadCallback(line_b1) == -1 ||
- BaseMath_ReadCallback(line_b2) == -1)
- {
- return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(lines); i++) {
+ if (mathutils_array_parse(lines[i], 2, 2 | MU_ARRAY_SPILL, py_lines[i], error_prefix) == -1) {
+ return NULL;
+ }
}
- if (isect_seg_seg_v2_point(line_a1->vec, line_a2->vec, line_b1->vec, line_b2->vec, vi) == 1) {
- return Vector_CreatePyObject(vi, 2, Py_NEW, NULL);
+ if (isect_seg_seg_v2_point(UNPACK4(lines), vi) == 1) {
+ return Vector_CreatePyObject(vi, 2, NULL);
}
else {
Py_RETURN_NONE;
@@ -585,38 +473,31 @@ PyDoc_STRVAR(M_Geometry_intersect_line_plane_doc,
);
static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *line_a, *line_b, *plane_co, *plane_no;
+ const char *error_prefix = "intersect_line_plane";
+ PyObject *py_line_a, *py_line_b, *py_plane_co, *py_plane_no;
+ float line_a[3], line_b[3], plane_co[3], plane_no[3];
float isect[3];
int no_flip = false;
- if (!PyArg_ParseTuple(args, "O!O!O!O!|i:intersect_line_plane",
- &vector_Type, &line_a,
- &vector_Type, &line_b,
- &vector_Type, &plane_co,
- &vector_Type, &plane_no,
- &no_flip))
+ if (!PyArg_ParseTuple(
+ args, "OOOO|i:intersect_line_plane",
+ &py_line_a, &py_line_b, &py_plane_co, &py_plane_no,
+ &no_flip))
{
return NULL;
}
- if (BaseMath_ReadCallback(line_a) == -1 ||
- BaseMath_ReadCallback(line_b) == -1 ||
- BaseMath_ReadCallback(plane_co) == -1 ||
- BaseMath_ReadCallback(plane_no) == -1)
+ if (((mathutils_array_parse(line_a, 3, 3 | MU_ARRAY_SPILL, py_line_a, error_prefix) != -1) &&
+ (mathutils_array_parse(line_b, 3, 3 | MU_ARRAY_SPILL, py_line_b, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_co, 3, 3 | MU_ARRAY_SPILL, py_plane_co, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_no, 3, 3 | MU_ARRAY_SPILL, py_plane_no, error_prefix) != -1)) == 0)
{
return NULL;
}
- if (ELEM(2, line_a->size, line_b->size, plane_co->size, plane_no->size)) {
- PyErr_SetString(PyExc_ValueError,
- "geometry.intersect_line_plane(...): "
- " can't use 2D Vectors");
- return NULL;
- }
-
/* TODO: implements no_flip */
- if (isect_line_plane_v3(isect, line_a->vec, line_b->vec, plane_co->vec, plane_no->vec) == 1) {
- return Vector_CreatePyObject(isect, 3, Py_NEW, NULL);
+ if (isect_line_plane_v3(isect, line_a, line_b, plane_co, plane_no) == 1) {
+ return Vector_CreatePyObject(isect, 3, NULL);
}
else {
Py_RETURN_NONE;
@@ -641,68 +522,59 @@ PyDoc_STRVAR(M_Geometry_intersect_plane_plane_doc,
);
static PyObject *M_Geometry_intersect_plane_plane(PyObject *UNUSED(self), PyObject *args)
{
+ const char *error_prefix = "intersect_plane_plane";
PyObject *ret, *ret_co, *ret_no;
- VectorObject *plane_a_co, *plane_a_no, *plane_b_co, *plane_b_no;
+ PyObject *py_plane_a_co, *py_plane_a_no, *py_plane_b_co, *py_plane_b_no;
+ float plane_a_co[3], plane_a_no[3], plane_b_co[3], plane_b_no[3];
float isect_co[3];
float isect_no[3];
- if (!PyArg_ParseTuple(args, "O!O!O!O!:intersect_plane_plane",
- &vector_Type, &plane_a_co,
- &vector_Type, &plane_a_no,
- &vector_Type, &plane_b_co,
- &vector_Type, &plane_b_no))
+ if (!PyArg_ParseTuple(
+ args, "OOOO:intersect_plane_plane",
+ &py_plane_a_co, &py_plane_a_no, &py_plane_b_co, &py_plane_b_no))
{
return NULL;
}
- if (BaseMath_ReadCallback(plane_a_co) == -1 ||
- BaseMath_ReadCallback(plane_a_no) == -1 ||
- BaseMath_ReadCallback(plane_b_co) == -1 ||
- BaseMath_ReadCallback(plane_b_no) == -1)
+ if (((mathutils_array_parse(plane_a_co, 3, 3 | MU_ARRAY_SPILL, py_plane_a_co, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_a_no, 3, 3 | MU_ARRAY_SPILL, py_plane_a_no, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_b_co, 3, 3 | MU_ARRAY_SPILL, py_plane_b_co, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_b_no, 3, 3 | MU_ARRAY_SPILL, py_plane_b_no, error_prefix) != -1)) == 0)
{
return NULL;
}
- if (ELEM(2, plane_a_co->size, plane_a_no->size, plane_b_co->size, plane_b_no->size)) {
- PyErr_SetString(PyExc_ValueError,
- "geometry.intersect_plane_plane(...): "
- " can't use 2D Vectors");
- return NULL;
- }
-
if (isect_plane_plane_v3(isect_co, isect_no,
- plane_a_co->vec, plane_a_no->vec,
- plane_b_co->vec, plane_b_no->vec))
+ plane_a_co, plane_a_no,
+ plane_b_co, plane_b_no))
{
normalize_v3(isect_no);
- ret_co = Vector_CreatePyObject(isect_co, 3, Py_NEW, NULL);
- ret_no = Vector_CreatePyObject(isect_no, 3, Py_NEW, NULL);
+ ret_co = Vector_CreatePyObject(isect_co, 3, NULL);
+ ret_no = Vector_CreatePyObject(isect_no, 3, NULL);
}
else {
- ret_co = Py_None;
- ret_no = Py_None;
-
- Py_INCREF(ret_co);
- Py_INCREF(ret_no);
+ ret_co = Py_INCREF_RET(Py_None);
+ ret_no = Py_INCREF_RET(Py_None);
}
ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, ret_co);
- PyTuple_SET_ITEM(ret, 1, ret_no);
+ PyTuple_SET_ITEMS(ret,
+ ret_co,
+ ret_no);
return ret;
}
PyDoc_STRVAR(M_Geometry_intersect_line_sphere_doc,
".. function:: intersect_line_sphere(line_a, line_b, sphere_co, sphere_radius, clip=True)\n"
"\n"
-" Takes a lines (as 2 vectors), a sphere as a point and a radius and\n"
+" Takes a line (as 2 points) and a sphere (as a point and a radius) and\n"
" returns the intersection\n"
"\n"
-" :arg line_a: First point of the first line\n"
+" :arg line_a: First point of the line\n"
" :type line_a: :class:`mathutils.Vector`\n"
-" :arg line_b: Second point of the first line\n"
+" :arg line_b: Second point of the line\n"
" :type line_b: :class:`mathutils.Vector`\n"
" :arg sphere_co: The center of the sphere\n"
" :type sphere_co: :class:`mathutils.Vector`\n"
@@ -713,35 +585,28 @@ PyDoc_STRVAR(M_Geometry_intersect_line_sphere_doc,
);
static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *line_a, *line_b, *sphere_co;
+ const char *error_prefix = "intersect_line_sphere";
+ PyObject *py_line_a, *py_line_b, *py_sphere_co;
+ float line_a[3], line_b[3], sphere_co[3];
float sphere_radius;
int clip = true;
float isect_a[3];
float isect_b[3];
- if (!PyArg_ParseTuple(args, "O!O!O!f|i:intersect_line_sphere",
- &vector_Type, &line_a,
- &vector_Type, &line_b,
- &vector_Type, &sphere_co,
- &sphere_radius, &clip))
+ if (!PyArg_ParseTuple(
+ args, "OOOf|i:intersect_line_sphere",
+ &py_line_a, &py_line_b, &py_sphere_co, &sphere_radius, &clip))
{
return NULL;
}
- if (BaseMath_ReadCallback(line_a) == -1 ||
- BaseMath_ReadCallback(line_b) == -1 ||
- BaseMath_ReadCallback(sphere_co) == -1)
+ if (((mathutils_array_parse(line_a, 3, 3 | MU_ARRAY_SPILL, py_line_a, error_prefix) != -1) &&
+ (mathutils_array_parse(line_b, 3, 3 | MU_ARRAY_SPILL, py_line_b, error_prefix) != -1) &&
+ (mathutils_array_parse(sphere_co, 3, 3 | MU_ARRAY_SPILL, py_sphere_co, error_prefix) != -1)) == 0)
{
return NULL;
}
-
- if (ELEM(2, line_a->size, line_b->size, sphere_co->size)) {
- PyErr_SetString(PyExc_ValueError,
- "geometry.intersect_line_sphere(...): "
- " can't use 2D Vectors");
- return NULL;
- }
else {
bool use_a = true;
bool use_b = true;
@@ -749,14 +614,14 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje
PyObject *ret = PyTuple_New(2);
- switch (isect_line_sphere_v3(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) {
+ switch (isect_line_sphere_v3(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) {
case 1:
- if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a = false;
+ if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) use_a = false;
use_b = false;
break;
case 2:
- if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a = false;
- if (!(!clip || (((lambda = line_point_factor_v3(isect_b, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_b = false;
+ if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) use_a = false;
+ if (!(!clip || (((lambda = line_point_factor_v3(isect_b, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) use_b = false;
break;
default:
use_a = false;
@@ -764,11 +629,9 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje
break;
}
- if (use_a) { PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_a, 3, Py_NEW, NULL)); }
- else { PyTuple_SET_ITEM(ret, 0, Py_None); Py_INCREF(Py_None); }
-
- if (use_b) { PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(isect_b, 3, Py_NEW, NULL)); }
- else { PyTuple_SET_ITEM(ret, 1, Py_None); Py_INCREF(Py_None); }
+ PyTuple_SET_ITEMS(ret,
+ use_a ? Vector_CreatePyObject(isect_a, 3, NULL) : Py_INCREF_RET(Py_None),
+ use_b ? Vector_CreatePyObject(isect_b, 3, NULL) : Py_INCREF_RET(Py_None));
return ret;
}
@@ -778,12 +641,12 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje
PyDoc_STRVAR(M_Geometry_intersect_line_sphere_2d_doc,
".. function:: intersect_line_sphere_2d(line_a, line_b, sphere_co, sphere_radius, clip=True)\n"
"\n"
-" Takes a lines (as 2 vectors), a sphere as a point and a radius and\n"
+" Takes a line (as 2 points) and a sphere (as a point and a radius) and\n"
" returns the intersection\n"
"\n"
-" :arg line_a: First point of the first line\n"
+" :arg line_a: First point of the line\n"
" :type line_a: :class:`mathutils.Vector`\n"
-" :arg line_b: Second point of the first line\n"
+" :arg line_b: Second point of the line\n"
" :type line_b: :class:`mathutils.Vector`\n"
" :arg sphere_co: The center of the sphere\n"
" :type sphere_co: :class:`mathutils.Vector`\n"
@@ -794,25 +657,25 @@ PyDoc_STRVAR(M_Geometry_intersect_line_sphere_2d_doc,
);
static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *line_a, *line_b, *sphere_co;
+ const char *error_prefix = "intersect_line_sphere_2d";
+ PyObject *py_line_a, *py_line_b, *py_sphere_co;
+ float line_a[2], line_b[2], sphere_co[2];
float sphere_radius;
int clip = true;
float isect_a[2];
float isect_b[2];
- if (!PyArg_ParseTuple(args, "O!O!O!f|i:intersect_line_sphere_2d",
- &vector_Type, &line_a,
- &vector_Type, &line_b,
- &vector_Type, &sphere_co,
- &sphere_radius, &clip))
+ if (!PyArg_ParseTuple(
+ args, "OOOf|i:intersect_line_sphere_2d",
+ &py_line_a, &py_line_b, &py_sphere_co, &sphere_radius, &clip))
{
return NULL;
}
- if (BaseMath_ReadCallback(line_a) == -1 ||
- BaseMath_ReadCallback(line_b) == -1 ||
- BaseMath_ReadCallback(sphere_co) == -1)
+ if (((mathutils_array_parse(line_a, 2, 2 | MU_ARRAY_SPILL, py_line_a, error_prefix) != -1) &&
+ (mathutils_array_parse(line_b, 2, 2 | MU_ARRAY_SPILL, py_line_b, error_prefix) != -1) &&
+ (mathutils_array_parse(sphere_co, 2, 2 | MU_ARRAY_SPILL, py_sphere_co, error_prefix) != -1)) == 0)
{
return NULL;
}
@@ -823,14 +686,14 @@ static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyO
PyObject *ret = PyTuple_New(2);
- switch (isect_line_sphere_v2(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) {
+ switch (isect_line_sphere_v2(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) {
case 1:
- if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a = false;
+ if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) use_a = false;
use_b = false;
break;
case 2:
- if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a = false;
- if (!(!clip || (((lambda = line_point_factor_v2(isect_b, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_b = false;
+ if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) use_a = false;
+ if (!(!clip || (((lambda = line_point_factor_v2(isect_b, line_a, line_b)) >= 0.0f) && (lambda <= 1.0f)))) use_b = false;
break;
default:
use_a = false;
@@ -838,11 +701,9 @@ static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyO
break;
}
- if (use_a) { PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(isect_a, 2, Py_NEW, NULL)); }
- else { PyTuple_SET_ITEM(ret, 0, Py_None); Py_INCREF(Py_None); }
-
- if (use_b) { PyTuple_SET_ITEM(ret, 1, Vector_CreatePyObject(isect_b, 2, Py_NEW, NULL)); }
- else { PyTuple_SET_ITEM(ret, 1, Py_None); Py_INCREF(Py_None); }
+ PyTuple_SET_ITEMS(ret,
+ use_a ? Vector_CreatePyObject(isect_a, 2, NULL) : Py_INCREF_RET(Py_None),
+ use_b ? Vector_CreatePyObject(isect_b, 2, NULL) : Py_INCREF_RET(Py_None));
return ret;
}
@@ -863,43 +724,35 @@ PyDoc_STRVAR(M_Geometry_intersect_point_line_doc,
);
static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *pt, *line_1, *line_2;
- float pt_in[3], pt_out[3], l1[3], l2[3];
+ const char *error_prefix = "intersect_point_line";
+ PyObject *py_pt, *py_line_a, *py_line_b;
+ float pt[3], pt_out[3], line_a[3], line_b[3];
float lambda;
PyObject *ret;
int size = 2;
- if (!PyArg_ParseTuple(args, "O!O!O!:intersect_point_line",
- &vector_Type, &pt,
- &vector_Type, &line_1,
- &vector_Type, &line_2))
+ if (!PyArg_ParseTuple(
+ args, "OOO:intersect_point_line",
+ &py_pt, &py_line_a, &py_line_b))
{
return NULL;
}
- if (BaseMath_ReadCallback(pt) == -1 ||
- BaseMath_ReadCallback(line_1) == -1 ||
- BaseMath_ReadCallback(line_2) == -1)
+ /* accept 2d verts */
+ if ((((size = mathutils_array_parse(pt, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_pt, error_prefix)) != -1) &&
+ (mathutils_array_parse(line_a, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_a, error_prefix) != -1) &&
+ (mathutils_array_parse(line_b, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_b, error_prefix) != -1)) == 0)
{
return NULL;
}
- /* accept 2d verts */
- if (pt->size >= 3) { copy_v3_v3(pt_in, pt->vec); size = 3; }
- else { copy_v2_v2(pt_in, pt->vec); pt_in[2] = 0.0f; }
-
- if (line_1->size >= 3) { copy_v3_v3(l1, line_1->vec); size = 3; }
- else { copy_v2_v2(l1, line_1->vec); l1[2] = 0.0f; }
-
- if (line_2->size >= 3) { copy_v3_v3(l2, line_2->vec); size = 3; }
- else { copy_v2_v2(l2, line_2->vec); l2[2] = 0.0f; }
-
/* do the calculation */
- lambda = closest_to_line_v3(pt_out, pt_in, l1, l2);
+ lambda = closest_to_line_v3(pt_out, pt, line_a, line_b);
ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, Vector_CreatePyObject(pt_out, size, Py_NEW, NULL));
- PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(lambda));
+ PyTuple_SET_ITEMS(ret,
+ Vector_CreatePyObject(pt_out, size, NULL),
+ PyFloat_FromDouble(lambda));
return ret;
}
@@ -921,38 +774,30 @@ PyDoc_STRVAR(M_Geometry_intersect_point_tri_doc,
);
static PyObject *M_Geometry_intersect_point_tri(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *pt_vec, *tri_p1, *tri_p2, *tri_p3;
+ const char *error_prefix = "intersect_point_tri";
+ PyObject *py_pt, *py_tri[3];
+ float pt[3], tri[3][3];
float vi[3];
+ int i;
- if (!PyArg_ParseTuple(args, "O!O!O!O!:intersect_point_tri",
- &vector_Type, &pt_vec,
- &vector_Type, &tri_p1,
- &vector_Type, &tri_p2,
- &vector_Type, &tri_p3))
+ if (!PyArg_ParseTuple(
+ args, "OOOO:intersect_point_tri",
+ &py_pt, UNPACK3_EX(&, py_tri, )))
{
return NULL;
}
- if (BaseMath_ReadCallback(pt_vec) == -1 ||
- BaseMath_ReadCallback(tri_p1) == -1 ||
- BaseMath_ReadCallback(tri_p2) == -1 ||
- BaseMath_ReadCallback(tri_p3) == -1)
- {
+ if (mathutils_array_parse(pt, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_pt, error_prefix) == -1) {
return NULL;
}
-
- if (pt_vec->size < 3 ||
- tri_p1->size < 3 ||
- tri_p2->size < 3 ||
- tri_p3->size < 3)
- {
- PyErr_SetString(PyExc_ValueError,
- "One of more of the vector arguments wasn't a 3D vector");
- return NULL;
+ for (i = 0; i < ARRAY_SIZE(tri); i++) {
+ if (mathutils_array_parse(tri[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_tri[i], error_prefix) == -1) {
+ return NULL;
+ }
}
- if (isect_point_tri_v3(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec, vi)) {
- return Vector_CreatePyObject(vi, 3, Py_NEW, NULL);
+ if (isect_point_tri_v3(pt, UNPACK3(tri), vi)) {
+ return Vector_CreatePyObject(vi, 3, NULL);
}
else {
Py_RETURN_NONE;
@@ -976,26 +821,28 @@ PyDoc_STRVAR(M_Geometry_intersect_point_tri_2d_doc,
);
static PyObject *M_Geometry_intersect_point_tri_2d(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *pt_vec, *tri_p1, *tri_p2, *tri_p3;
-
- if (!PyArg_ParseTuple(args, "O!O!O!O!:intersect_point_tri_2d",
- &vector_Type, &pt_vec,
- &vector_Type, &tri_p1,
- &vector_Type, &tri_p2,
- &vector_Type, &tri_p3))
+ const char *error_prefix = "intersect_point_tri_2d";
+ PyObject *py_pt, *py_tri[3];
+ float pt[2], tri[3][2];
+ int i;
+
+ if (!PyArg_ParseTuple(
+ args, "OOOO:intersect_point_tri_2d",
+ &py_pt, UNPACK3_EX(&, py_tri, )))
{
return NULL;
}
-
- if (BaseMath_ReadCallback(pt_vec) == -1 ||
- BaseMath_ReadCallback(tri_p1) == -1 ||
- BaseMath_ReadCallback(tri_p2) == -1 ||
- BaseMath_ReadCallback(tri_p3) == -1)
- {
+
+ if (mathutils_array_parse(pt, 2, 2 | MU_ARRAY_SPILL, py_pt, error_prefix) == -1) {
return NULL;
}
+ for (i = 0; i < ARRAY_SIZE(tri); i++) {
+ if (mathutils_array_parse(tri[i], 2, 2 | MU_ARRAY_SPILL, py_tri[i], error_prefix) == -1) {
+ return NULL;
+ }
+ }
- return PyLong_FromLong(isect_point_tri_v2(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec));
+ return PyLong_FromLong(isect_point_tri_v2(pt, UNPACK3(tri)));
}
PyDoc_STRVAR(M_Geometry_intersect_point_quad_2d_doc,
@@ -1019,28 +866,28 @@ PyDoc_STRVAR(M_Geometry_intersect_point_quad_2d_doc,
);
static PyObject *M_Geometry_intersect_point_quad_2d(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *pt_vec, *quad_p1, *quad_p2, *quad_p3, *quad_p4;
+ const char *error_prefix = "intersect_point_quad_2d";
+ PyObject *py_pt, *py_quad[4];
+ float pt[2], quad[4][2];
+ int i;
- if (!PyArg_ParseTuple(args, "O!O!O!O!O!:intersect_point_quad_2d",
- &vector_Type, &pt_vec,
- &vector_Type, &quad_p1,
- &vector_Type, &quad_p2,
- &vector_Type, &quad_p3,
- &vector_Type, &quad_p4))
+ if (!PyArg_ParseTuple(
+ args, "OOOOO:intersect_point_quad_2d",
+ &py_pt, UNPACK4_EX(&, py_quad, )))
{
return NULL;
}
- if (BaseMath_ReadCallback(pt_vec) == -1 ||
- BaseMath_ReadCallback(quad_p1) == -1 ||
- BaseMath_ReadCallback(quad_p2) == -1 ||
- BaseMath_ReadCallback(quad_p3) == -1 ||
- BaseMath_ReadCallback(quad_p4) == -1)
- {
+ if (mathutils_array_parse(pt, 2, 2 | MU_ARRAY_SPILL, py_pt, error_prefix) == -1) {
return NULL;
}
+ for (i = 0; i < ARRAY_SIZE(quad); i++) {
+ if (mathutils_array_parse(quad[i], 2, 2 | MU_ARRAY_SPILL, py_quad[i], error_prefix) == -1) {
+ return NULL;
+ }
+ }
- return PyLong_FromLong(isect_point_quad_v2(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec));
+ return PyLong_FromLong(isect_point_quad_v2(pt, UNPACK4(quad)));
}
PyDoc_STRVAR(M_Geometry_distance_point_to_plane_doc,
@@ -1059,35 +906,27 @@ PyDoc_STRVAR(M_Geometry_distance_point_to_plane_doc,
);
static PyObject *M_Geometry_distance_point_to_plane(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *pt, *plane_co, *plane_no;
+ const char *error_prefix = "distance_point_to_plane";
+ PyObject *py_pt, *py_plane_co, *py_plane_no;
+ float pt[3], plane_co[3], plane_no[3];
float plane[4];
- if (!PyArg_ParseTuple(args, "O!O!O!:distance_point_to_plane",
- &vector_Type, &pt,
- &vector_Type, &plane_co,
- &vector_Type, &plane_no))
- {
- return NULL;
- }
-
- if (pt->size != 3 ||
- plane_co->size != 3 ||
- plane_no->size != 3)
+ if (!PyArg_ParseTuple(
+ args, "OOO:distance_point_to_plane",
+ &py_pt, &py_plane_co, &py_plane_no))
{
- PyErr_SetString(PyExc_ValueError,
- "One of more of the vector arguments wasn't a 3D vector");
return NULL;
}
- if (BaseMath_ReadCallback(pt) == -1 ||
- BaseMath_ReadCallback(plane_co) == -1 ||
- BaseMath_ReadCallback(plane_no) == -1)
+ if (((mathutils_array_parse(pt, 3, 3 | MU_ARRAY_SPILL, py_pt, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_co, 3, 3 | MU_ARRAY_SPILL, py_plane_co, error_prefix) != -1) &&
+ (mathutils_array_parse(plane_no, 3, 3 | MU_ARRAY_SPILL, py_plane_no, error_prefix) != -1)) == 0)
{
return NULL;
}
- plane_from_point_normal_v3(plane, plane_co->vec, plane_no->vec);
- return PyFloat_FromDouble(dist_signed_to_plane_v3(pt->vec, plane));
+ plane_from_point_normal_v3(plane, plane_co, plane_no);
+ return PyFloat_FromDouble(dist_signed_to_plane_v3(pt, plane));
}
PyDoc_STRVAR(M_Geometry_barycentric_transform_doc,
@@ -1114,53 +953,37 @@ PyDoc_STRVAR(M_Geometry_barycentric_transform_doc,
);
static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *vec_pt;
- VectorObject *vec_t1_tar, *vec_t2_tar, *vec_t3_tar;
- VectorObject *vec_t1_src, *vec_t2_src, *vec_t3_src;
- float vec[3];
-
- if (!PyArg_ParseTuple(args, "O!O!O!O!O!O!O!::barycentric_transform",
- &vector_Type, &vec_pt,
- &vector_Type, &vec_t1_src,
- &vector_Type, &vec_t2_src,
- &vector_Type, &vec_t3_src,
- &vector_Type, &vec_t1_tar,
- &vector_Type, &vec_t2_tar,
- &vector_Type, &vec_t3_tar))
- {
- return NULL;
- }
+ const char *error_prefix = "barycentric_transform";
+ PyObject *py_pt_src, *py_tri_src[3], *py_tri_dst[3];
+ float pt_src[3], pt_dst[3], tri_src[3][3], tri_dst[3][3];
+ int i;
- if (vec_pt->size != 3 ||
- vec_t1_src->size != 3 ||
- vec_t2_src->size != 3 ||
- vec_t3_src->size != 3 ||
- vec_t1_tar->size != 3 ||
- vec_t2_tar->size != 3 ||
- vec_t3_tar->size != 3)
+ if (!PyArg_ParseTuple(
+ args, "OOOOOOO:barycentric_transform",
+ &py_pt_src,
+ UNPACK3_EX(&, py_tri_src, ),
+ UNPACK3_EX(&, py_tri_dst, )))
{
- PyErr_SetString(PyExc_ValueError,
- "One of more of the vector arguments wasn't a 3D vector");
return NULL;
}
- if (BaseMath_ReadCallback(vec_pt) == -1 ||
- BaseMath_ReadCallback(vec_t1_src) == -1 ||
- BaseMath_ReadCallback(vec_t2_src) == -1 ||
- BaseMath_ReadCallback(vec_t3_src) == -1 ||
- BaseMath_ReadCallback(vec_t1_tar) == -1 ||
- BaseMath_ReadCallback(vec_t2_tar) == -1 ||
- BaseMath_ReadCallback(vec_t3_tar) == -1)
- {
+ if (mathutils_array_parse(pt_src, 3, 3 | MU_ARRAY_SPILL, py_pt_src, error_prefix) == -1) {
return NULL;
}
+ for (i = 0; i < ARRAY_SIZE(tri_src); i++) {
+ if (((mathutils_array_parse(tri_src[i], 3, 3 | MU_ARRAY_SPILL, py_tri_src[i], error_prefix) != -1) &&
+ (mathutils_array_parse(tri_dst[i], 3, 3 | MU_ARRAY_SPILL, py_tri_dst[i], error_prefix) != -1)) == 0)
+ {
+ return NULL;
+ }
+ }
transform_point_by_tri_v3(
- vec, vec_pt->vec,
- vec_t1_tar->vec, vec_t2_tar->vec, vec_t3_tar->vec,
- vec_t1_src->vec, vec_t2_src->vec, vec_t3_src->vec);
+ pt_dst, pt_src,
+ UNPACK3(tri_dst),
+ UNPACK3(tri_src));
- return Vector_CreatePyObject(vec, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(pt_dst, 3, NULL);
}
PyDoc_STRVAR(M_Geometry_points_in_planes_doc,
@@ -1180,8 +1003,9 @@ static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *a
float (*planes)[4];
unsigned int planes_len;
- if (!PyArg_ParseTuple(args, "O:points_in_planes",
- &py_planes))
+ if (!PyArg_ParseTuple(
+ args, "O:points_in_planes",
+ &py_planes))
{
return NULL;
}
@@ -1233,10 +1057,7 @@ static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *a
if (l == len) { /* ok */
/* python */
- PyObject *item = Vector_CreatePyObject(potentialVertex, 3, Py_NEW, NULL);
- PyList_Append(py_verts, item);
- Py_DECREF(item);
-
+ PyList_APPEND(py_verts, Vector_CreatePyObject(potentialVertex, 3, NULL));
planes_used[i] = planes_used[j] = planes_used[k] = true;
}
}
@@ -1252,17 +1073,16 @@ static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *a
/* now make a list of used planes */
for (i = 0; i < len; i++) {
if (planes_used[i]) {
- PyObject *item = PyLong_FromLong(i);
- PyList_Append(py_plane_index, item);
- Py_DECREF(item);
+ PyList_APPEND(py_plane_index, PyLong_FromLong(i));
}
}
PyMem_Free(planes_used);
{
PyObject *ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, py_verts);
- PyTuple_SET_ITEM(ret, 1, py_plane_index);
+ PyTuple_SET_ITEMS(ret,
+ py_verts,
+ py_plane_index);
return ret;
}
}
@@ -1290,58 +1110,45 @@ PyDoc_STRVAR(M_Geometry_interpolate_bezier_doc,
);
static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject *args)
{
- VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2;
+ const char *error_prefix = "interpolate_bezier";
+ PyObject *py_data[4];
+ float data[4][4] = {{0.0f}};
int resolu;
- int dims;
+ int dims = 0;
int i;
float *coord_array, *fp;
PyObject *list;
- float k1[4] = {0.0, 0.0, 0.0, 0.0};
- float h1[4] = {0.0, 0.0, 0.0, 0.0};
- float k2[4] = {0.0, 0.0, 0.0, 0.0};
- float h2[4] = {0.0, 0.0, 0.0, 0.0};
-
-
- if (!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier",
- &vector_Type, &vec_k1,
- &vector_Type, &vec_h1,
- &vector_Type, &vec_h2,
- &vector_Type, &vec_k2, &resolu))
+ if (!PyArg_ParseTuple(
+ args, "OOOOi:interpolate_bezier",
+ UNPACK4_EX(&, py_data, ), &resolu))
{
return NULL;
}
+ for (i = 0; i < 4; i++) {
+ int dims_tmp;
+ if ((dims_tmp = mathutils_array_parse(data[i], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_data[i], error_prefix)) == -1) {
+ return NULL;
+ }
+ dims = max_ii(dims, dims_tmp);
+ }
+
if (resolu <= 1) {
PyErr_SetString(PyExc_ValueError,
"resolution must be 2 or over");
return NULL;
}
- if (BaseMath_ReadCallback(vec_k1) == -1 ||
- BaseMath_ReadCallback(vec_h1) == -1 ||
- BaseMath_ReadCallback(vec_k2) == -1 ||
- BaseMath_ReadCallback(vec_h2) == -1)
- {
- return NULL;
- }
-
- dims = max_iiii(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
-
- for (i = 0; i < vec_k1->size; i++) k1[i] = vec_k1->vec[i];
- for (i = 0; i < vec_h1->size; i++) h1[i] = vec_h1->vec[i];
- for (i = 0; i < vec_k2->size; i++) k2[i] = vec_k2->vec[i];
- for (i = 0; i < vec_h2->size; i++) h2[i] = vec_h2->vec[i];
-
- coord_array = MEM_callocN(dims * (resolu) * sizeof(float), "interpolate_bezier");
+ coord_array = MEM_callocN(dims * (resolu) * sizeof(float), error_prefix);
for (i = 0; i < dims; i++) {
- BKE_curve_forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array + i, resolu - 1, sizeof(float) * dims);
+ BKE_curve_forward_diff_bezier(UNPACK4_EX(, data, [i]), coord_array + i, resolu - 1, sizeof(float) * dims);
}
list = PyList_New(resolu);
fp = coord_array;
for (i = 0; i < resolu; i++, fp = fp + dims) {
- PyList_SET_ITEM(list, i, Vector_CreatePyObject(fp, dims, Py_NEW, NULL));
+ PyList_SET_ITEM(list, i, Vector_CreatePyObject(fp, dims, NULL));
}
MEM_freeN(coord_array);
return list;
@@ -1581,8 +1388,9 @@ static PyObject *M_Geometry_box_pack_2d(PyObject *UNUSED(self), PyObject *boxlis
}
ret = PyTuple_New(2);
- PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(tot_width));
- PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(tot_height));
+ PyTuple_SET_ITEMS(ret,
+ PyFloat_FromDouble(tot_width),
+ PyFloat_FromDouble(tot_height));
return ret;
}
diff --git a/source/blender/python/mathutils/mathutils_interpolate.c b/source/blender/python/mathutils/mathutils_interpolate.c
new file mode 100644
index 00000000000..4d7841b906a
--- /dev/null
+++ b/source/blender/python/mathutils/mathutils_interpolate.c
@@ -0,0 +1,137 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/mathutils/mathutils_interpolate.c
+ * \ingroup pymathutils
+ */
+
+
+#include <Python.h>
+
+#include "mathutils.h"
+#include "mathutils_interpolate.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#ifndef MATH_STANDALONE /* define when building outside blender */
+# include "MEM_guardedalloc.h"
+#endif
+
+/*-------------------------DOC STRINGS ---------------------------*/
+PyDoc_STRVAR(M_Interpolate_doc,
+"The Blender interpolate module"
+);
+
+/* ---------------------------------WEIGHT CALCULATION ----------------------- */
+
+#ifndef MATH_STANDALONE
+
+PyDoc_STRVAR(M_Interpolate_poly_3d_calc_doc,
+".. function:: poly_3d_calc(veclist, pt)\n"
+"\n"
+" Calculate barycentric weights for a point on a polygon.\n"
+"\n"
+" :arg veclist: list of vectors\n"
+" :arg pt: point"
+" :rtype: list of per-vector weights\n"
+);
+static PyObject *M_Interpolate_poly_3d_calc(PyObject *UNUSED(self), PyObject *args)
+{
+ float fp[3];
+ float (*vecs)[3];
+ Py_ssize_t len;
+
+ PyObject *point, *veclist, *ret;
+ int i;
+
+ if (!PyArg_ParseTuple(args, "OO!:interpolation_weights",
+ &veclist,
+ &vector_Type, &point))
+ {
+ return NULL;
+ }
+
+ if (BaseMath_ReadCallback((VectorObject *)point) == -1)
+ return NULL;
+
+ fp[0] = ((VectorObject *)point)->vec[0];
+ fp[1] = ((VectorObject *)point)->vec[1];
+ if (((VectorObject *)point)->size > 2)
+ fp[2] = ((VectorObject *)point)->vec[2];
+ else
+ fp[2] = 0.0f; /* if its a 2d vector then set the z to be zero */
+
+ len = mathutils_array_parse_alloc_v(((float **)&vecs), 3, veclist, "interpolation_weights");
+ if (len == -1) {
+ return NULL;
+ }
+
+ if (len) {
+ float *weights = MEM_mallocN(sizeof(float) * len, "interpolation weights");
+
+ interp_weights_poly_v3(weights, vecs, len, fp);
+
+ ret = PyList_New(len);
+ for (i = 0; i < len; i++) {
+ PyList_SET_ITEM(ret, i, PyFloat_FromDouble(weights[i]));
+ }
+
+ MEM_freeN(weights);
+
+ PyMem_Free(vecs);
+ }
+ else {
+ ret = PyList_New(0);
+ }
+
+ return ret;
+}
+
+#endif /* MATH_STANDALONE */
+
+
+static PyMethodDef M_Interpolate_methods[] = {
+#ifndef MATH_STANDALONE
+ {"poly_3d_calc", (PyCFunction) M_Interpolate_poly_3d_calc, METH_VARARGS, M_Interpolate_poly_3d_calc_doc},
+#endif
+ {NULL, NULL, 0, NULL}
+};
+
+static struct PyModuleDef M_Interpolate_module_def = {
+ PyModuleDef_HEAD_INIT,
+ "mathutils.interpolate", /* m_name */
+ M_Interpolate_doc, /* m_doc */
+ 0, /* m_size */
+ M_Interpolate_methods, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+/*----------------------------MODULE INIT-------------------------*/
+PyMODINIT_FUNC PyInit_mathutils_interpolate(void)
+{
+ PyObject *submodule = PyModule_Create(&M_Interpolate_module_def);
+ return submodule;
+}
diff --git a/source/blender/compositor/intern/COM_ChannelInfo.cpp b/source/blender/python/mathutils/mathutils_interpolate.h
index 557075cdc80..1bbff6f3286 100644
--- a/source/blender/compositor/intern/COM_ChannelInfo.cpp
+++ b/source/blender/python/mathutils/mathutils_interpolate.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011, Blender Foundation.
+ * ***** 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
@@ -15,21 +15,18 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributor:
- * Jeroen Bakker
- * Monique Dewanchand
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
*/
-#include "COM_ChannelInfo.h"
-#include "COM_defines.h"
-#include <stdio.h>
+#ifndef __MATHUTILS_INTERPOLATE_H__
+#define __MATHUTILS_INTERPOLATE_H__
-/**
- * @brief create new ChannelInfo instance and sets the defaults.
+/** \file blender/python/mathutils/mathutils_interpolate.h
+ * \ingroup pymathutils
*/
-ChannelInfo::ChannelInfo()
-{
- this->m_number = 0;
- this->m_premultiplied = true;
- this->m_type = COM_CT_UNUSED;
-}
+
+PyMODINIT_FUNC PyInit_mathutils_interpolate(void);
+
+#endif /* __MATHUTILS_INTERPOLATE_H__ */
diff --git a/source/blender/python/mathutils/mathutils_kdtree.c b/source/blender/python/mathutils/mathutils_kdtree.c
index 519778aea7d..199c2e02da4 100644
--- a/source/blender/python/mathutils/mathutils_kdtree.c
+++ b/source/blender/python/mathutils/mathutils_kdtree.c
@@ -35,6 +35,7 @@
#include "BLI_kdtree.h"
#include "../generic/py_capi_utils.h"
+#include "../generic/python_utildefines.h"
#include "mathutils.h"
#include "mathutils_kdtree.h" /* own include */
@@ -58,9 +59,10 @@ static void kdtree_nearest_to_py_tuple(const KDTreeNearest *nearest, PyObject *p
BLI_assert(nearest->index >= 0);
BLI_assert(PyTuple_GET_SIZE(py_retval) == 3);
- PyTuple_SET_ITEM(py_retval, 0, Vector_CreatePyObject((float *)nearest->co, 3, Py_NEW, NULL));
- PyTuple_SET_ITEM(py_retval, 1, PyLong_FromLong(nearest->index));
- PyTuple_SET_ITEM(py_retval, 2, PyFloat_FromDouble(nearest->dist));
+ PyTuple_SET_ITEMS(py_retval,
+ Vector_CreatePyObject((float *)nearest->co, 3, NULL),
+ PyLong_FromLong(nearest->index),
+ PyFloat_FromDouble(nearest->dist));
}
static PyObject *kdtree_nearest_to_py(const KDTreeNearest *nearest)
@@ -126,7 +128,7 @@ static void PyKDTree__tp_dealloc(PyKDTree *self)
}
PyDoc_STRVAR(py_kdtree_insert_doc,
-".. method:: insert(index, co)\n"
+".. method:: insert(co, index)\n"
"\n"
" Insert a point into the KDTree.\n"
"\n"
@@ -171,6 +173,10 @@ PyDoc_STRVAR(py_kdtree_balance_doc,
".. method:: balance()\n"
"\n"
" Balance the tree.\n"
+"\n"
+".. note::\n"
+"\n"
+" This builds the entire tree, avoid calling after each insertion.\n"
);
static PyObject *py_kdtree_balance(PyKDTree *self)
{
diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c
index 8dfa7904300..f0449c23dcd 100644
--- a/source/blender/python/mathutils/mathutils_noise.c
+++ b/source/blender/python/mathutils/mathutils_noise.c
@@ -34,8 +34,6 @@
#include <Python.h>
-#include "structseq.h"
-
#include "BLI_math.h"
#include "BLI_noise.h"
#include "BLI_utildefines.h"
@@ -311,7 +309,7 @@ static PyObject *M_Noise_random_unit_vector(PyObject *UNUSED(self), PyObject *ar
norm = normalize_vn(vec, size);
}
- return Vector_CreatePyObject(vec, size, Py_NEW, NULL);
+ return Vector_CreatePyObject(vec, size, NULL);
}
/* This is dumb, most people will want a unit vector anyway, since this doesn't have uniform distribution over a sphere*/
#if 0
@@ -340,7 +338,7 @@ static PyObject *M_Noise_random_vector(PyObject *UNUSED(self), PyObject *args)
rand_vn(vec, size);
- return Vector_CreatePyObject(vec, size, Py_NEW, NULL);
+ return Vector_CreatePyObject(vec, size, NULL);
}
#endif
@@ -414,7 +412,7 @@ static PyObject *M_Noise_noise_vector(PyObject *UNUSED(self), PyObject *args)
noise_vector(vec[0], vec[1], vec[2], nb, r_vec);
- return Vector_CreatePyObject(r_vec, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(r_vec, 3, NULL);
}
PyDoc_STRVAR(M_Noise_turbulence_doc,
@@ -486,7 +484,7 @@ static PyObject *M_Noise_turbulence_vector(PyObject *UNUSED(self), PyObject *arg
return NULL;
vTurb(vec[0], vec[1], vec[2], oct, hd, nb, as, fs, r_vec);
- return Vector_CreatePyObject(r_vec, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(r_vec, 3, NULL);
}
/* F. Kenton Musgrave's fractal functions */
@@ -738,7 +736,7 @@ static PyObject *M_Noise_voronoi(PyObject *UNUSED(self), PyObject *args)
voronoi(vec[0], vec[1], vec[2], da, pa, me, dtype);
for (i = 0; i < 4; i++) {
- PyList_SET_ITEM(list, i, Vector_CreatePyObject(pa + 3 * i, 3, Py_NEW, NULL));
+ PyList_SET_ITEM(list, i, Vector_CreatePyObject(pa + 3 * i, 3, NULL));
}
return Py_BuildValue("[[ffff]O]", da[0], da[1], da[2], da[3], list);
@@ -790,7 +788,7 @@ static PyObject *M_Noise_cell_vector(PyObject *UNUSED(self), PyObject *args)
return NULL;
cellNoiseV(vec[0], vec[1], vec[2], r_vec);
- return Vector_CreatePyObject(r_vec, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(r_vec, 3, NULL);
}
static PyMethodDef M_Noise_methods[] = {
diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m
index 0c193df3861..cbc76e26aa9 100644
--- a/source/blender/quicktime/apple/qtkit_export.m
+++ b/source/blender/quicktime/apple/qtkit_export.m
@@ -814,22 +814,26 @@ void free_qtcomponentdata(void)
void quicktime_verify_image_type(RenderData *rd, ImageFormatData *imf)
{
if (imf->imtype == R_IMF_IMTYPE_QUICKTIME) {
- if ((rd->qtcodecsettings.codecType<= 0) ||
- (rd->qtcodecsettings.codecSpatialQuality <0) ||
- (rd->qtcodecsettings.codecSpatialQuality > 100)) {
-
+ if ((rd->qtcodecsettings.codecType <= 0) ||
+ (rd->qtcodecsettings.codecSpatialQuality < 0) ||
+ (rd->qtcodecsettings.codecSpatialQuality > 100))
+ {
rd->qtcodecsettings.codecType = kJPEGCodecType;
- rd->qtcodecsettings.codecSpatialQuality = (codecHighQuality*100)/codecLosslessQuality;
+ rd->qtcodecsettings.codecSpatialQuality = (codecHighQuality * 100) / codecLosslessQuality;
}
if ((rd->qtcodecsettings.audioSampleRate < 21000) ||
- (rd->qtcodecsettings.audioSampleRate > 193000))
+ (rd->qtcodecsettings.audioSampleRate > 193000))
+ {
rd->qtcodecsettings.audioSampleRate = 48000;
+ }
- if (rd->qtcodecsettings.audioBitDepth == 0)
+ if (rd->qtcodecsettings.audioBitDepth == 0) {
rd->qtcodecsettings.audioBitDepth = AUD_FORMAT_S16;
+ }
- if (rd->qtcodecsettings.audioBitRate == 0)
+ if (rd->qtcodecsettings.audioBitRate == 0) {
rd->qtcodecsettings.audioBitRate = 256000;
+ }
}
}
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index 8d64d701695..318b376d8c1 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -33,6 +33,7 @@ set(INC
../imbuf
../makesdna
../makesrna
+ ../physics
../../../intern/guardedalloc
../../../intern/mikktspace
../../../intern/smoke/extern
diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript
index 7f459444a39..0cbf188525b 100644
--- a/source/blender/render/SConscript
+++ b/source/blender/render/SConscript
@@ -38,9 +38,9 @@ incs = [
'../blenkernel',
'../blenlib',
'../imbuf',
- '../include',
'../makesdna',
'../makesrna',
+ '../physics',
'../../../intern/mikktspace',
'../../../intern/smoke/extern',
]
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 4b0473f7483..5edf970c129 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -144,6 +144,7 @@ void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char
void RE_engine_update_progress(RenderEngine *engine, float progress);
void RE_engine_update_memory_stats(RenderEngine *engine, float mem_used, float mem_peak);
void RE_engine_report(RenderEngine *engine, int type, const char *msg);
+void RE_engine_set_error_message(RenderEngine *engine, const char *msg);
int RE_engine_render(struct Render *re, int do_all);
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 61795c2c173..d1b6673c792 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -144,7 +144,7 @@ typedef struct RenderResult {
/* render info text */
char *text;
-
+ char *error;
} RenderResult;
diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h
index 6d083ec785d..d76d16a641e 100644
--- a/source/blender/render/extern/include/RE_render_ext.h
+++ b/source/blender/render/extern/include/RE_render_ext.h
@@ -45,7 +45,7 @@ struct Scene;
struct View3D;
/* particle.c, effect.c, editmesh_modes.c and brush.c, returns 1 if rgb, 0 otherwise */
-int externtex(struct MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread, struct ImagePool *pool);
+int externtex(struct MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread, struct ImagePool *pool, const bool skip_load_image);
/* particle.c */
void texture_rgb_blend(float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype);
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index da847d235f2..7c76f0362f4 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -198,9 +198,9 @@ struct ImagePool;
struct Object;
/* this one uses nodes */
-int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage);
+int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image);
/* nodes disabled */
-int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage);
+int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image);
/* only for internal node usage */
int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres,
const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex,
diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h
index c813e88c656..627e6c0e1e6 100644
--- a/source/blender/render/intern/include/envmap.h
+++ b/source/blender/render/intern/include/envmap.h
@@ -47,7 +47,7 @@ struct TexResult;
struct ImagePool;
void make_envmaps(struct Render *re);
-int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool);
+int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, const bool skip_image_load);
void env_rotate_scene(struct Render *re, float mat[4][4], int do_rotate);
#endif /* __ENVMAP_H__ */
diff --git a/source/blender/render/intern/include/rayintersection.h b/source/blender/render/intern/include/rayintersection.h
index 9c0835af56f..3607e66a237 100644
--- a/source/blender/render/intern/include/rayintersection.h
+++ b/source/blender/render/intern/include/rayintersection.h
@@ -121,7 +121,7 @@ typedef struct Isect {
/* arbitrary, but can't use e.g. FLT_MAX because of precision issues */
#define RE_RAYTRACE_MAXDIST 1e15f
-#define RE_RAYTRACE_EPSILON -FLT_EPSILON
+#define RE_RAYTRACE_EPSILON 0.0f
#ifdef __cplusplus
}
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index b87b1e6f367..8d92fb9eec9 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -424,6 +424,7 @@ typedef struct HaloRen {
unsigned int lay;
struct Material *mat;
struct ImagePool *pool;
+ bool skip_load_image;
} HaloRen;
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h
index ff5004fd7f0..ebc83984306 100644
--- a/source/blender/render/intern/include/texture.h
+++ b/source/blender/render/intern/include/texture.h
@@ -81,8 +81,8 @@ void render_realtime_texture(struct ShadeInput *shi, struct Image *ima);
/* imagetexture.h */
-int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], const float dxt[2], const float dyt[2], struct TexResult *texres, struct ImagePool *pool);
-int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], struct TexResult *texres, struct ImagePool *pool);
+int imagewraposa(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], const float dxt[2], const float dyt[2], struct TexResult *texres, struct ImagePool *pool, const bool skip_load_image);
+int imagewrap(struct Tex *tex, struct Image *ima, struct ImBuf *ibuf, const float texvec[3], struct TexResult *texres, struct ImagePool *pool, const bool skip_load_image);
void image_sample(struct Image *ima, float fx, float fy, float dx, float dy, float result[4], struct ImagePool *pool);
#endif /* __TEXTURE_H__ */
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
index 15634c93491..4aa2f4e919e 100644
--- a/source/blender/render/intern/source/bake.c
+++ b/source/blender/render/intern/source/bake.c
@@ -54,8 +54,6 @@
#include "IMB_imbuf.h"
#include "IMB_colormanagement.h"
-#include "RE_bake.h"
-
/* local include */
#include "rayintersection.h"
#include "rayobject.h"
@@ -374,8 +372,8 @@ static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist,
bs->vcol->b = col[2];
}
else {
- const char *imcol = (char *)(bs->rect + bs->rectx * y + x);
- copy_v4_v4_char((char *)imcol, (char *)col);
+ char *imcol = (char *)(bs->rect + bs->rectx * y + x);
+ copy_v4_v4_char(imcol, (char *)col);
}
}
if (bs->rect_mask) {
@@ -613,6 +611,10 @@ static int get_next_bake_face(BakeShade *bs)
for (; obi; obi = obi->next, v = 0) {
obr = obi->obr;
+ /* only allow non instances here */
+ if (obr->flag & R_INSTANCEABLE)
+ continue;
+
for (; v < obr->totvlak; v++) {
vlr = RE_findOrAddVlak(obr, v);
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
index 90deac2de32..ecfb86c8d17 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -45,14 +45,14 @@
*
* pixel_array is a Python object storing BakePixel elements:
*
- * <pre>
+ * \code{.c}
* struct BakePixel {
* int primitive_id;
* float uv[2];
* float du_dx, du_dy;
* float dv_dx, dv_dy;
* };
- * </pre>
+ * \endcode
*
* In python you have access to:
* - ``primitive_id``, ``uv``, ``du_dx``, ``du_dy``, ``next``
@@ -444,7 +444,7 @@ bool RE_bake_pixels_populate_from_objects(
size_t i;
int primitive_id;
float u, v;
- float imat_low [4][4];
+ float imat_low[4][4];
bool is_cage = me_cage != NULL;
bool result = true;
@@ -928,7 +928,6 @@ bool RE_bake_internal(
case SCE_PASS_UV:
{
return bake_uv(pixel_array, num_pixels, depth, result);
- break;
}
default:
break;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 69dd9607c3b..2ebcb76e3d1 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -82,9 +82,7 @@
#include "BKE_particle.h"
#include "BKE_scene.h"
-
#include "PIL_time.h"
-#include "IMB_imbuf_types.h"
#include "envmap.h"
#include "occlusion.h"
@@ -103,8 +101,6 @@
#include "zbuf.h"
#include "sunsky.h"
-#include "RE_render_ext.h"
-
/* 10 times larger than normal epsilon, test it on default nurbs sphere with ray_transp (for quad detection) */
/* or for checking vertex normal flips */
#define FLT_EPSILON10 1.19209290e-06F
@@ -1262,7 +1258,7 @@ static void get_particle_uvco_mcol(short from, DerivedMesh *dm, float *fuv, int
/* get mcol */
if (sd->mcol && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
for (i=0; i<sd->totcol; i++) {
- if (num != DMCACHE_NOTFOUND) {
+ if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) {
MFace *mface = dm->getTessFaceData(dm, num, CD_MFACE);
MCol *mc = (MCol*)CustomData_get_layer_n(&dm->faceData, CD_MCOL, i);
mc += num * 4;
@@ -1305,7 +1301,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
int totchild=0, step_nbr;
int seed, path_nbr=0, orco1=0, num;
int totface;
- const char **uv_name = NULL;
const int *index_mf_to_mpoly = NULL;
const int *index_mp_to_orig = NULL;
@@ -1326,6 +1321,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if ((re->r.scemode & R_VIEWPORT_PREVIEW) && (ob->mode & OB_MODE_PARTICLE_EDIT))
return 0;
+ if (part->ren_as == PART_DRAW_BB && part->bb_ob == NULL && RE_GetCamera(re) == NULL)
+ return 0;
+
/* 2. start initializing things */
/* last possibility to bail out! */
@@ -1349,11 +1347,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if (re->r.scemode & R_VIEWPORT_PREVIEW) { /* preview render */
totchild = (int)((float)totchild * (float)part->disp / 100.0f);
- step_nbr = part->draw_step;
+ step_nbr = 1 << part->draw_step;
}
else {
- step_nbr = part->ren_step;
+ step_nbr = 1 << part->ren_step;
}
+ if (ELEM(part->kink, PART_KINK_SPIRAL))
+ step_nbr += part->kink_extra_steps;
psys->flag |= PSYS_DRAWING;
@@ -1427,8 +1427,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
/* 2.5 setup matrices */
mul_m4_m4m4(mat, re->viewmat, ob->obmat);
invert_m4_m4(ob->imat, mat); /* need to be that way, for imat texture */
- copy_m3_m4(nmat, ob->imat);
- transpose_m3(nmat);
+ transpose_m3_m4(nmat, ob->imat);
if (psys->flag & PSYS_USE_IMAT) {
/* psys->imat is the original emitter's inverse matrix, ob->obmat is the duplicated object's matrix */
@@ -1438,7 +1437,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
/* 2.6 setup strand rendering */
if (part->ren_as == PART_DRAW_PATH && psys->pathcache) {
- path_nbr=(int)pow(2.0, (double) step_nbr);
+ path_nbr = step_nbr;
if (path_nbr) {
if (!ELEM(ma->material_type, MA_TYPE_HALO, MA_TYPE_WIRE)) {
@@ -1557,7 +1556,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if (path_nbr) {
cache = psys->pathcache[a];
- max_k = (int)cache->steps;
+ max_k = (int)cache->segments;
}
if (totchild && (part->draw&PART_DRAW_PARENT)==0) continue;
@@ -1568,10 +1567,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if (path_nbr) {
cache = psys->childcache[a-totpart];
- if (cache->steps < 0)
+ if (cache->segments < 0)
continue;
- max_k = (int)cache->steps;
+ max_k = (int)cache->segments;
}
pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
@@ -1855,9 +1854,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
if (sd.mcol)
MEM_freeN(sd.mcol);
- if (uv_name)
- MEM_freeN(uv_name);
-
if (states)
MEM_freeN(states);
@@ -2652,8 +2648,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
negative_scale = is_negative_m4(mat);
/* local object -> world space transform for normals */
- copy_m4_m4(nmat, mat);
- transpose_m4(nmat);
+ transpose_m4_m4(nmat, mat);
invert_m4(nmat);
/* material array */
@@ -2731,12 +2726,13 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
vlr->v4= NULL;
/* to prevent float accuracy issues, we calculate normal in local object space (not world) */
- if (area_tri_v3(co3, co2, co1)>FLT_EPSILON) {
- if (negative_scale)
- normal_tri_v3(tmp, co1, co2, co3);
- else
- normal_tri_v3(tmp, co3, co2, co1);
- add_v3_v3(n, tmp);
+ if (normal_tri_v3(tmp, co1, co2, co3) > FLT_EPSILON) {
+ if (negative_scale == false) {
+ add_v3_v3(n, tmp);
+ }
+ else {
+ sub_v3_v3(n, tmp);
+ }
}
vlr->mat= matar[ dl->col ];
@@ -3323,7 +3319,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
v2= mface->v2;
v3= reverse_verts==0 ? mface->v3 : mface->v1;
v4= mface->v4;
- flag= mface->flag & ME_SMOOTH;
+ flag = do_autosmooth ? ME_SMOOTH : mface->flag & ME_SMOOTH;
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->v1= RE_findOrAddVert(obr, vertofs+v1);
@@ -3917,7 +3913,15 @@ static bool is_object_hidden(Render *re, Object *ob)
if (re->r.scemode & R_VIEWPORT_PREVIEW) {
/* Mesh deform cages and so on mess up the preview. To avoid the problem,
* viewport doesn't show mesh object if its draw type is bounding box or wireframe.
+ * Unless it's an active smoke domain!
*/
+ ModifierData *md = NULL;
+
+ if ((md = modifiers_findByType(ob, eModifierType_Smoke)) &&
+ (modifier_isEnabled(re->scene, md, eModifierMode_Realtime)))
+ {
+ return false;
+ }
return ELEM(ob->dt, OB_BOUNDBOX, OB_WIRE);
}
else {
@@ -5136,8 +5140,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
re->lights.first= re->lights.last= NULL;
re->lampren.first= re->lampren.last= NULL;
-
- slurph_opt= 0;
+
re->i.partsdone = false; /* signal now in use for previewrender */
/* in localview, lamps are using normal layers, objects only local bits */
@@ -5199,8 +5202,6 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
re->i.totlamp= re->totlamp;
re->stats_draw(re->sdh, &re->i);
}
-
- slurph_opt= 1;
}
void RE_Database_Preprocess(Render *re)
@@ -5240,7 +5241,7 @@ void RE_Database_Preprocess(Render *re)
}
if (!re->test_break(re->tbh))
- project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
+ project_renderdata(re, projectverto, (re->r.mode & R_PANORAMA) != 0, 0, 1);
/* Occlusion */
if ((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && !re->test_break(re->tbh))
@@ -5318,8 +5319,6 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la
re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
re->i.totface=re->i.totvert=re->i.totstrand=re->i.totlamp=re->i.tothalo= 0;
re->lights.first= re->lights.last= NULL;
-
- slurph_opt= 0;
/* in localview, lamps are using normal layers, objects only local bits */
if (re->lay & 0xFF000000)
@@ -5340,7 +5339,7 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la
database_init_objects(re, lay, 0, 0, NULL, timeoffset);
if (!re->test_break(re->tbh))
- project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
+ project_renderdata(re, projectverto, (re->r.mode & R_PANORAMA) != 0, 0, 1);
/* do this in end, particles for example need cfra */
scene->r.cfra -= timeoffset;
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 06be00a5a5e..f0268836104 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -55,14 +55,10 @@
/* this module */
#include "render_types.h"
-#include "renderpipeline.h"
#include "envmap.h"
-#include "rendercore.h"
#include "renderdatabase.h"
#include "texture.h"
#include "zbuf.h"
-#include "initrender.h"
-
/* ------------------------------------------------------------------------- */
@@ -698,7 +694,7 @@ static void set_dxtdyt(float r_dxt[3], float r_dyt[3], const float dxt[3], const
/* ------------------------------------------------------------------------- */
-int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool)
+int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool, const bool skip_load_image)
{
extern Render R; /* only in this call */
/* texvec should be the already reflected normal */
@@ -754,7 +750,7 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o
mul_mat3_m4_v3(R.viewinv, dyt);
}
set_dxtdyt(dxts, dyts, dxt, dyt, face);
- imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres, pool);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, texres, pool, skip_load_image);
/* edges? */
@@ -771,7 +767,7 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o
if (face != face1) {
ibuf = env->cube[face1];
set_dxtdyt(dxts, dyts, dxt, dyt, face1);
- imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr1, pool);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr1, pool, skip_load_image);
}
else texr1.tr = texr1.tg = texr1.tb = texr1.ta = 0.0;
@@ -784,7 +780,7 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o
if (face != face1) {
ibuf = env->cube[face1];
set_dxtdyt(dxts, dyts, dxt, dyt, face1);
- imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr2, pool);
+ imagewraposa(tex, NULL, ibuf, sco, dxts, dyts, &texr2, pool, skip_load_image);
}
else texr2.tr = texr2.tg = texr2.tb = texr2.ta = 0.0;
@@ -800,7 +796,7 @@ int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int o
}
}
else {
- imagewrap(tex, NULL, ibuf, sco, texres, pool);
+ imagewrap(tex, NULL, ibuf, sco, texres, pool, skip_load_image);
}
return 1;
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 54f142184e1..4e63a9918e1 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -46,9 +46,6 @@
#include "BKE_report.h"
#include "BKE_scene.h"
-#include "IMB_imbuf.h"
-#include "IMB_imbuf_types.h"
-
#include "RNA_access.h"
#ifdef WITH_PYTHON
@@ -358,6 +355,19 @@ void RE_engine_report(RenderEngine *engine, int type, const char *msg)
BKE_report(engine->reports, type, msg);
}
+void RE_engine_set_error_message(RenderEngine *engine, const char *msg)
+{
+ Render *re = engine->re;
+ if (re != NULL) {
+ RenderResult *rr = RE_AcquireResultRead(re);
+ if (rr->error != NULL) {
+ MEM_freeN(rr->error);
+ }
+ rr->error = BLI_strdup(msg);
+ RE_ReleaseResult(re);
+ }
+}
+
void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r)
{
RenderPart *pa;
@@ -430,7 +440,7 @@ bool RE_bake_engine(
{
RenderEngineType *type = RE_engines_find(re->r.engine);
RenderEngine *engine;
- int persistent_data = re->r.mode & R_PERSISTENT_DATA;
+ bool persistent_data = (re->r.mode & R_PERSISTENT_DATA) != 0;
/* set render info */
re->i.cfra = re->scene->r.cfra;
@@ -522,7 +532,7 @@ int RE_engine_render(Render *re, int do_all)
{
RenderEngineType *type = RE_engines_find(re->r.engine);
RenderEngine *engine;
- int persistent_data = re->r.mode & R_PERSISTENT_DATA;
+ bool persistent_data = (re->r.mode & R_PERSISTENT_DATA) != 0;
/* verify if we can render */
if (!type->render)
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index 2787ce99b13..687e25a9410 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -50,12 +50,10 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
-#include "BKE_main.h"
#include "BKE_image.h"
#include "RE_render_ext.h"
-#include "renderpipeline.h"
#include "render_types.h"
#include "texture.h"
@@ -105,7 +103,7 @@ static void ibuf_get_color(float col[4], struct ImBuf *ibuf, int x, int y)
}
}
-int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResult *texres, struct ImagePool *pool)
+int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResult *texres, struct ImagePool *pool, const bool skip_load_image)
{
float fx, fy, val1, val2, val3;
int x, y, retval;
@@ -122,7 +120,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
if (ima) {
/* hack for icon render */
- if ((R.r.scemode & R_NO_IMAGE_LOAD) && !BKE_image_has_loaded_ibuf(ima))
+ if (skip_load_image && !BKE_image_has_loaded_ibuf(ima))
return retval;
ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
@@ -914,7 +912,7 @@ static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
}
-static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[2], float dyt[2], TexResult *texres, struct ImagePool *pool)
+static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[2], float dyt[2], TexResult *texres, struct ImagePool *pool, const bool skip_load_image)
{
TexResult texr;
float fx, fy, minx, maxx, miny, maxy;
@@ -944,7 +942,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
if (ibuf==NULL && ima==NULL) return retval;
if (ima) { /* hack for icon render */
- if ((R.r.scemode & R_NO_IMAGE_LOAD) && !BKE_image_has_loaded_ibuf(ima)) {
+ if (skip_load_image && !BKE_image_has_loaded_ibuf(ima)) {
return retval;
}
ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
@@ -1340,7 +1338,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
}
-int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[2], const float DYT[2], TexResult *texres, struct ImagePool *pool)
+int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[2], const float DYT[2], TexResult *texres, struct ImagePool *pool, const bool skip_load_image)
{
TexResult texr;
float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[2], dyt[2];
@@ -1354,7 +1352,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* anisotropic filtering */
if (tex->texfilter != TXF_BOX)
- return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres, pool);
+ return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres, pool, skip_load_image);
texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
@@ -1367,7 +1365,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (ima) {
/* hack for icon render */
- if ((R.r.scemode & R_NO_IMAGE_LOAD) && !BKE_image_has_loaded_ibuf(ima))
+ if (skip_load_image && !BKE_image_has_loaded_ibuf(ima))
return retval;
ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 353ba5d5caa..a0fcc7cdcd2 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -36,8 +36,6 @@
#include "MEM_guardedalloc.h"
-#include "PIL_time.h"
-
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_jitter.h"
@@ -48,12 +46,8 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-
#include "BKE_camera.h"
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-
#ifdef WITH_QUICKTIME
#include "quicktime_export.h"
#endif
@@ -62,10 +56,6 @@
#include "renderpipeline.h"
#include "render_types.h"
-#include "rendercore.h"
-#include "pixelshading.h"
-#include "zbuf.h"
-
/* Own includes */
#include "initrender.h"
@@ -164,8 +154,11 @@ float RE_filter_value(int type, float x)
return 1.0f - x;
case R_FILTER_GAUSS:
- x *= gaussfac;
- return (1.0f / expf(x * x) - 1.0f / expf(gaussfac * gaussfac * 2.25f));
+ {
+ const float two_gaussfac2 = 2.0f * gaussfac * gaussfac;
+ x *= 3.0f * gaussfac;
+ return 1.0f / sqrtf((float)M_PI * two_gaussfac2) * expf(-x*x / two_gaussfac2);
+ }
case R_FILTER_MITCH:
return filt_mitchell(x * gaussfac);
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index 0c6341fe9e5..f55dde588cb 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -56,9 +56,7 @@
#include "render_types.h"
#include "rendercore.h"
#include "renderdatabase.h"
-#include "pixelshading.h"
#include "shading.h"
-#include "zbuf.h"
/* ------------------------- Declarations --------------------------- */
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 7b43c77537f..21ca7924fa0 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -90,7 +90,6 @@
#include "renderdatabase.h"
#include "rendercore.h"
#include "initrender.h"
-#include "shadbuf.h"
#include "pixelblending.h"
#include "zbuf.h"
@@ -257,7 +256,7 @@ Render *RE_GetRender(const char *name)
/* search for existing renders */
for (re = RenderGlobal.renderlist.first; re; re = re->next)
- if (strncmp(re->name, name, RE_MAXNAME) == 0)
+ if (STREQLEN(re->name, name, RE_MAXNAME))
break;
return re;
@@ -492,6 +491,12 @@ static int check_mode_full_sample(RenderData *rd)
{
int scemode = rd->scemode;
+ if (!STREQ(rd->engine, RE_engine_id_BLENDER_RENDER) &&
+ !STREQ(rd->engine, RE_engine_id_BLENDER_GAME))
+ {
+ scemode &= ~R_FULL_SAMPLE;
+ }
+
if ((rd->mode & R_OSA) == 0)
scemode &= ~R_FULL_SAMPLE;
@@ -713,10 +718,10 @@ static void render_result_rescale(Render *re)
scale_y = (float) result->recty / re->result->recty;
for (x = 0; x < re->result->rectx; ++x) {
for (y = 0; y < re->result->recty; ++y) {
- int src_x = x * scale_x,
- src_y = y * scale_y;
- int dst_index = y * re->result->rectx + x,
- src_index = src_y * result->rectx + src_x;
+ int src_x = x * scale_x;
+ int src_y = y * scale_y;
+ int dst_index = y * re->result->rectx + x;
+ int src_index = src_y * result->rectx + src_x;
copy_v4_v4(dst_rectf + dst_index * 4,
src_rectf + src_index * 4);
}
@@ -2345,7 +2350,9 @@ static void renderresult_stampinfo(Render *re)
/* this is the basic trick to get the displayed float or char rect from render result */
RE_AcquireResultImage(re, &rres);
- BKE_stamp_buf(re->scene, RE_GetCamera(re), (unsigned char *)rres.rect32, rres.rectf, rres.rectx, rres.recty, 4);
+ BKE_image_stamp_buf(
+ re->scene, RE_GetCamera(re),
+ (unsigned char *)rres.rect32, rres.rectf, rres.rectx, rres.recty, 4);
RE_ReleaseResultImage(re);
}
@@ -2374,6 +2381,7 @@ static void do_render_seq(Render *re)
RenderResult *rr; /* don't assign re->result here as it might change during give_ibuf_seq */
int cfra = re->r.cfra;
SeqRenderData context;
+ int re_x, re_y;
re->i.cfra = cfra;
@@ -2387,14 +2395,19 @@ static void do_render_seq(Render *re)
if ((re->r.mode & R_BORDER) && (re->r.mode & R_CROP) == 0) {
/* if border rendering is used and cropping is disabled, final buffer should
* be as large as the whole frame */
- context = BKE_sequencer_new_render_data(re->eval_ctx, re->main, re->scene,
- re->winx, re->winy, 100);
+ re_x = re->winx;
+ re_y = re->winy;
}
else {
- context = BKE_sequencer_new_render_data(re->eval_ctx, re->main, re->scene,
- re->result->rectx, re->result->recty, 100);
+ re_x = re->result->rectx;
+ re_y = re->result->recty;
}
+ BKE_sequencer_new_render_data(
+ re->eval_ctx, re->main, re->scene,
+ re_x, re_y, 100,
+ &context);
+
out = BKE_sequencer_give_ibuf(&context, cfra, 0);
if (out) {
@@ -2820,8 +2833,9 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
}
else {
char name[FILE_MAX];
- BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra,
- &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false);
+ BKE_image_path_from_imformat(
+ name, scene->r.pic, bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, false);
/* reports only used for Movie */
do_write_image_or_movie(re, bmain, scene, NULL, name);
@@ -2829,6 +2843,9 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
}
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */
+ if (write_still) {
+ BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_WRITE);
+ }
}
BLI_callback_exec(re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE);
@@ -2903,8 +2920,9 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
if (name_override)
BLI_strncpy(name, name_override, sizeof(name));
else
- BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra,
- &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true);
+ BKE_image_path_from_imformat(
+ name, scene->r.pic, bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true);
if (re->r.im_format.imtype == R_IMF_IMTYPE_MULTILAYER) {
if (re->result) {
@@ -2932,7 +2950,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
if (BLI_testextensie(name, ".exr"))
name[strlen(name) - 4] = 0;
- BKE_add_image_extension(name, &imf);
+ BKE_image_path_ensure_ext_from_imformat(name, &imf);
ibuf->planes = 24;
IMB_colormanagement_imbuf_for_write(ibuf, true, false, &scene->view_settings,
@@ -3026,6 +3044,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
if (G.is_break == false) {
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */
+ BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_WRITE);
}
}
else {
@@ -3064,8 +3083,9 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
/* Touch/NoOverwrite options are only valid for image's */
if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) {
if (scene->r.mode & (R_NO_OVERWRITE | R_TOUCH))
- BKE_makepicstring(name, scene->r.pic, bmain->name, scene->r.cfra,
- &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true);
+ BKE_image_path_from_imformat(
+ name, scene->r.pic, bmain->name, scene->r.cfra,
+ &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true);
if (scene->r.mode & R_NO_OVERWRITE && BLI_exists(name)) {
printf("skipping existing frame \"%s\"\n", name);
@@ -3098,7 +3118,8 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
if (G.is_break == true) {
/* remove touched file */
if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) {
- if (scene->r.mode & R_TOUCH && BLI_exists(name) && BLI_file_size(name) == 0) {
+ if ((scene->r.mode & R_TOUCH) && (BLI_file_size(name) == 0)) {
+ /* BLI_exists(name) is implicit */
BLI_delete(name, false, false);
}
}
@@ -3108,6 +3129,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
if (G.is_break == false) {
BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_POST); /* keep after file save */
+ BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_WRITE);
}
}
}
diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c
index 460a6814f07..32fb196e1f3 100644
--- a/source/blender/render/intern/source/pixelblending.c
+++ b/source/blender/render/intern/source/pixelblending.c
@@ -38,7 +38,6 @@
/* own includes */
#include "render_types.h"
-#include "renderpipeline.h"
#include "pixelblending.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index 014df802a78..104cde0a0b5 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -36,8 +36,6 @@
#include "BLI_utildefines.h"
/* External modules: */
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
#include "DNA_group_types.h"
#include "DNA_material_types.h"
@@ -51,14 +49,11 @@
/* own module */
#include "render_types.h"
-#include "renderpipeline.h"
#include "renderdatabase.h"
#include "texture.h"
-#include "pixelblending.h"
#include "rendercore.h"
#include "shadbuf.h"
#include "pixelshading.h"
-#include "shading.h"
#include "sunsky.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -160,7 +155,7 @@ static void render_lighting_halo(HaloRen *har, float col_r[3])
x = max_ff(fabsf(lvrot[0]/lvrot[2]), fabsf(lvrot[1]/lvrot[2]));
/* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
- inpr = 1.0 / (sqrtf(1.0f + x * x));
+ inpr = 1.0f / (sqrtf(1.0f + x * x));
}
else inpr= 0.0;
}
@@ -206,7 +201,7 @@ static void render_lighting_halo(HaloRen *har, float col_r[3])
/* dot product and reflectivity*/
- inp = 1.0 - fabsf(dot_v3v3(vn, lv));
+ inp = 1.0f - fabsf(dot_v3v3(vn, lv));
/* inp= cos(0.5*M_PI-acos(inp)); */
@@ -366,7 +361,7 @@ int shadeHaloFloat(HaloRen *har, float col[4], int zz,
else dist= dist/har->radsq;
if (har->type & HA_FLARECIRC) {
- dist = 0.5 + fabsf(dist - 0.5f);
+ dist = 0.5f + fabsf(dist - 0.5f);
}
if (har->hard>=30) {
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index ac2e85a33b3..1f4726809de 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -55,7 +55,6 @@
#include "DNA_particle_types.h"
#include "render_types.h"
-#include "renderdatabase.h"
#include "texture.h"
#include "pointdensity.h"
@@ -161,7 +160,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
else
continue;
- cache += cache->steps; /* use endpoint */
+ cache += cache->segments; /* use endpoint */
copy_v3_v3(state.co, cache->co);
zero_v3(state.vel);
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index ff1f502cc1a..065cdeab61c 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -27,7 +27,6 @@
* \ingroup render
*/
-
#include <stdio.h>
#include <math.h>
#include <string.h>
@@ -50,25 +49,18 @@
#include "BKE_node.h"
-
-#include "PIL_time.h"
-
#include "render_result.h"
#include "render_types.h"
-#include "renderpipeline.h"
#include "rendercore.h"
#include "renderdatabase.h"
-#include "pixelblending.h"
#include "pixelshading.h"
#include "shading.h"
-#include "texture.h"
#include "volumetric.h"
#include "rayintersection.h"
#include "rayobject.h"
#include "raycounter.h"
-
#define RAY_TRA 1
#define RAY_INSIDE 2
@@ -1281,7 +1273,7 @@ static float get_avg_speed(ShadeInput *shi)
post_x = (shi->winspeed[2] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[2];
post_y = (shi->winspeed[3] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[3];
- speedavg = (sqrtf(pre_x * pre_x + pre_y * pre_y) + sqrtf(post_x * post_x + post_y * post_y)) / 2.0;
+ speedavg = (sqrtf(pre_x * pre_x + pre_y * pre_y) + sqrtf(post_x * post_x + post_y * post_y)) / 2.0f;
return speedavg;
}
@@ -1299,7 +1291,7 @@ static void trace_refract(float col[4], ShadeInput *shi, ShadeResult *shr)
float v_refract[3], v_refract_new[3];
float sampcol[4], colsq[4];
- float blur = powf(1.0f - shi->mat->gloss_tra, 3);
+ float blur = pow3f(1.0f - shi->mat->gloss_tra);
short max_samples = shi->mat->samp_gloss_tra;
float adapt_thresh = shi->mat->adapt_thresh_tra;
@@ -1400,7 +1392,7 @@ static void trace_reflect(float col[3], ShadeInput *shi, ShadeResult *shr, float
float v_nor_new[3], v_reflect[3];
float sampcol[4], colsq[4];
- float blur = powf(1.0f - shi->mat->gloss_mir, 3);
+ float blur = pow3f(1.0f - shi->mat->gloss_mir);
short max_samples = shi->mat->samp_gloss_mir;
float adapt_thresh = shi->mat->adapt_thresh_mir;
float aniso = 1.0f - shi->mat->aniso_gloss_mir;
@@ -1562,7 +1554,7 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
}
if (shi->combinedflag & SCE_PASS_REFLECT) {
- /* values in shr->spec can be greater then 1.0.
+ /* values in shr->spec can be greater than 1.0.
* In this case the mircol uses a zero blending factor, so ignoring it is ok.
* Fixes bug #18837 - when the spec is higher then 1.0,
* diff can become a negative color - Campbell */
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 24797521435..6486844bacf 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -35,13 +35,13 @@
#include "MEM_guardedalloc.h"
+#include "BKE_appdir.h"
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
-#include "BLI_md5.h"
+#include "BLI_hash_md5.h"
#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_string.h"
-#include "BLI_system.h"
#include "BLI_threads.h"
#include "BKE_image.h"
@@ -94,6 +94,8 @@ void render_result_free(RenderResult *res)
MEM_freeN(res->rectf);
if (res->text)
MEM_freeN(res->text);
+ if (res->error)
+ MEM_freeN(res->error);
MEM_freeN(res);
}
@@ -307,97 +309,97 @@ static const char *get_pass_name(int passtype, int channel)
static int passtype_from_name(const char *str)
{
- if (strcmp(str, "Combined") == 0)
+ if (STREQ(str, "Combined"))
return SCE_PASS_COMBINED;
- if (strcmp(str, "Depth") == 0)
+ if (STREQ(str, "Depth"))
return SCE_PASS_Z;
- if (strcmp(str, "Vector") == 0)
+ if (STREQ(str, "Vector"))
return SCE_PASS_VECTOR;
- if (strcmp(str, "Normal") == 0)
+ if (STREQ(str, "Normal"))
return SCE_PASS_NORMAL;
- if (strcmp(str, "UV") == 0)
+ if (STREQ(str, "UV"))
return SCE_PASS_UV;
- if (strcmp(str, "Color") == 0)
+ if (STREQ(str, "Color"))
return SCE_PASS_RGBA;
- if (strcmp(str, "Emit") == 0)
+ if (STREQ(str, "Emit"))
return SCE_PASS_EMIT;
- if (strcmp(str, "Diffuse") == 0)
+ if (STREQ(str, "Diffuse"))
return SCE_PASS_DIFFUSE;
- if (strcmp(str, "Spec") == 0)
+ if (STREQ(str, "Spec"))
return SCE_PASS_SPEC;
- if (strcmp(str, "Shadow") == 0)
+ if (STREQ(str, "Shadow"))
return SCE_PASS_SHADOW;
- if (strcmp(str, "AO") == 0)
+ if (STREQ(str, "AO"))
return SCE_PASS_AO;
- if (strcmp(str, "Env") == 0)
+ if (STREQ(str, "Env"))
return SCE_PASS_ENVIRONMENT;
- if (strcmp(str, "Indirect") == 0)
+ if (STREQ(str, "Indirect"))
return SCE_PASS_INDIRECT;
- if (strcmp(str, "Reflect") == 0)
+ if (STREQ(str, "Reflect"))
return SCE_PASS_REFLECT;
- if (strcmp(str, "Refract") == 0)
+ if (STREQ(str, "Refract"))
return SCE_PASS_REFRACT;
- if (strcmp(str, "IndexOB") == 0)
+ if (STREQ(str, "IndexOB"))
return SCE_PASS_INDEXOB;
- if (strcmp(str, "IndexMA") == 0)
+ if (STREQ(str, "IndexMA"))
return SCE_PASS_INDEXMA;
- if (strcmp(str, "Mist") == 0)
+ if (STREQ(str, "Mist"))
return SCE_PASS_MIST;
- if (strcmp(str, "RayHits") == 0)
+ if (STREQ(str, "RayHits"))
return SCE_PASS_RAYHITS;
- if (strcmp(str, "DiffDir") == 0)
+ if (STREQ(str, "DiffDir"))
return SCE_PASS_DIFFUSE_DIRECT;
- if (strcmp(str, "DiffInd") == 0)
+ if (STREQ(str, "DiffInd"))
return SCE_PASS_DIFFUSE_INDIRECT;
- if (strcmp(str, "DiffCol") == 0)
+ if (STREQ(str, "DiffCol"))
return SCE_PASS_DIFFUSE_COLOR;
- if (strcmp(str, "GlossDir") == 0)
+ if (STREQ(str, "GlossDir"))
return SCE_PASS_GLOSSY_DIRECT;
- if (strcmp(str, "GlossInd") == 0)
+ if (STREQ(str, "GlossInd"))
return SCE_PASS_GLOSSY_INDIRECT;
- if (strcmp(str, "GlossCol") == 0)
+ if (STREQ(str, "GlossCol"))
return SCE_PASS_GLOSSY_COLOR;
- if (strcmp(str, "TransDir") == 0)
+ if (STREQ(str, "TransDir"))
return SCE_PASS_TRANSM_DIRECT;
- if (strcmp(str, "TransInd") == 0)
+ if (STREQ(str, "TransInd"))
return SCE_PASS_TRANSM_INDIRECT;
- if (strcmp(str, "TransCol") == 0)
+ if (STREQ(str, "TransCol"))
return SCE_PASS_TRANSM_COLOR;
- if (strcmp(str, "SubsurfaceDir") == 0)
+ if (STREQ(str, "SubsurfaceDir"))
return SCE_PASS_SUBSURFACE_DIRECT;
- if (strcmp(str, "SubsurfaceInd") == 0)
+ if (STREQ(str, "SubsurfaceInd"))
return SCE_PASS_SUBSURFACE_INDIRECT;
- if (strcmp(str, "SubsurfaceCol") == 0)
+ if (STREQ(str, "SubsurfaceCol"))
return SCE_PASS_SUBSURFACE_COLOR;
return 0;
@@ -507,7 +509,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) {
if (layername && layername[0])
- if (strcmp(srl->name, layername) != 0)
+ if (!STREQ(srl->name, layername))
continue;
if (re->r.scemode & R_SINGLE_LAYER) {
@@ -609,7 +611,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR);
#ifdef WITH_CYCLES_DEBUG
- if(BKE_scene_use_new_shading_nodes(re->scene)) {
+ if (BKE_scene_use_new_shading_nodes(re->scene)) {
render_layer_add_debug_pass(rr, rl, 1, SCE_PASS_DEBUG,
RENDER_PASS_DEBUG_BVH_TRAVERSAL_STEPS);
}
@@ -1072,7 +1074,10 @@ void render_result_exr_file_path(Scene *scene, const char *layname, int sample,
BLI_snprintf(name, sizeof(name), "%s_%s_%s%d.exr", fi, scene->id.name + 2, layname, sample);
}
- BLI_make_file_string("/", filepath, BLI_temp_dir_session(), name);
+ /* Make name safe for paths, see T43275. */
+ BLI_filename_make_safe(name);
+
+ BLI_make_file_string("/", filepath, BKE_tempdir_session(), name);
}
/* only for temp buffer, makes exact copy of render result */
@@ -1160,17 +1165,17 @@ static void render_result_exr_file_cache_path(Scene *sce, const char *root, char
if (G.main->name[0]) {
BLI_split_dirfile(G.main->name, dirname, filename, sizeof(dirname), sizeof(filename));
BLI_replace_extension(filename, sizeof(filename), ""); /* strip '.blend' */
- md5_buffer(G.main->name, strlen(G.main->name), path_digest);
+ BLI_hash_md5_buffer(G.main->name, strlen(G.main->name), path_digest);
}
else {
- BLI_strncpy(dirname, BLI_temp_dir_base(), sizeof(dirname));
+ BLI_strncpy(dirname, BKE_tempdir_base(), sizeof(dirname));
BLI_strncpy(filename, "UNSAVED", sizeof(filename));
}
- md5_to_hexdigest(path_digest, path_hexdigest);
+ BLI_hash_md5_to_hexdigest(path_digest, path_hexdigest);
/* Default to *non-volatile* tmp dir. */
if (*root == '\0') {
- root = BLI_temp_dir_base();
+ root = BKE_tempdir_base();
}
BLI_snprintf(filename_full, sizeof(filename_full), "cached_RR_%s_%s_%s.exr",
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 1a8ab60d4d0..17039bca63a 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -48,7 +48,6 @@
#include "DNA_node_types.h"
#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
#include "IMB_colormanagement.h"
#include "BKE_image.h"
@@ -68,9 +67,7 @@
#include "envmap.h"
#include "pointdensity.h"
#include "voxeldata.h"
-#include "renderpipeline.h"
#include "render_types.h"
-#include "rendercore.h"
#include "shading.h"
#include "texture.h"
#include "texture_ocean.h"
@@ -223,10 +220,10 @@ static int blend(Tex *tex, const float texvec[3], TexResult *texres)
texres->tin= (2.0f+x+y)/4.0f;
}
else if (tex->stype==TEX_RAD) { /* radial */
- texres->tin = (atan2f(y, x) / (2 * M_PI) + 0.5f);
+ texres->tin = (atan2f(y, x) / (float)(2 * M_PI) + 0.5f);
}
else { /* sphere TEX_SPHERE */
- texres->tin = 1.0 - sqrtf(x * x + y * y + texvec[2] * texvec[2]);
+ texres->tin = 1.0f - sqrtf(x * x + y * y + texvec[2] * texvec[2]);
if (texres->tin<0.0f) texres->tin= 0.0f;
if (tex->stype==TEX_HALO) texres->tin*= texres->tin; /* halo */
}
@@ -277,7 +274,7 @@ static int clouds(Tex *tex, const float texvec[3], TexResult *texres)
/* creates a sine wave */
static float tex_sin(float a)
{
- a = 0.5 + 0.5 * sinf(a);
+ a = 0.5f + 0.5f * sinf(a);
return a;
}
@@ -1106,7 +1103,7 @@ static void do_2d_mapping(MTex *mtex, float texvec[3], VlakRen *vlr, const float
/* ************************************** */
-static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, short which_output, struct ImagePool *pool)
+static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, short which_output, struct ImagePool *pool, const bool skip_load_image)
{
float tmpvec[3];
int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */
@@ -1144,14 +1141,14 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o
retval = texnoise(tex, texres, thread);
break;
case TEX_IMAGE:
- if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres, pool);
- else retval = imagewrap(tex, tex->ima, NULL, texvec, texres, pool);
+ if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres, pool, skip_load_image);
+ else retval = imagewrap(tex, tex->ima, NULL, texvec, texres, pool, skip_load_image);
if (tex->ima) {
BKE_image_tag_time(tex->ima);
}
break;
case TEX_ENVMAP:
- retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres, pool);
+ retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres, pool, skip_load_image);
break;
case TEX_MUSGRAVE:
/* newnoise: musgrave types */
@@ -1223,7 +1220,7 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o
static int multitex_nodes_intern(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres,
const short thread, short which_output, ShadeInput *shi, MTex *mtex, struct ImagePool *pool,
- bool scene_color_manage)
+ bool scene_color_manage, const bool skip_load_image)
{
if (tex==NULL) {
memset(texres, 0, sizeof(TexResult));
@@ -1239,7 +1236,7 @@ static int multitex_nodes_intern(Tex *tex, float texvec[3], float dxt[3], float
if (mtex) {
/* we have mtex, use it for 2d mapping images only */
do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
- rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, pool);
+ rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, pool, skip_load_image);
if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
@@ -1272,7 +1269,7 @@ static int multitex_nodes_intern(Tex *tex, float texvec[3], float dxt[3], float
}
do_2d_mapping(&localmtex, texvec_l, NULL, NULL, dxt_l, dyt_l);
- rgbnor = multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output, pool);
+ rgbnor = multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output, pool, skip_load_image);
{
ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
@@ -1288,7 +1285,7 @@ static int multitex_nodes_intern(Tex *tex, float texvec[3], float dxt[3], float
return rgbnor;
}
else {
- return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, pool);
+ return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output, pool, skip_load_image);
}
}
@@ -1299,11 +1296,12 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os
const short thread, short which_output, ShadeInput *shi, MTex *mtex, struct ImagePool *pool)
{
return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres,
- thread, which_output, shi, mtex, pool, R.scene_color_manage);
+ thread, which_output, shi, mtex, pool, R.scene_color_manage,
+ (R.r.scemode & R_NO_IMAGE_LOAD) != 0);
}
/* this is called for surface shading */
-static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres, struct ImagePool *pool)
+static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres, struct ImagePool *pool, const bool skip_load_image)
{
Tex *tex = mtex->tex;
@@ -1314,7 +1312,7 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt
tex, mtex->which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, shi, mtex);
}
else {
- return multitex(mtex->tex, texvec, dxt, dyt, shi->osatex, texres, shi->thread, mtex->which_output, pool);
+ return multitex(mtex->tex, texvec, dxt, dyt, shi->osatex, texres, shi->thread, mtex->which_output, pool, skip_load_image);
}
}
@@ -1323,21 +1321,21 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt
*
* Use it for stuff which is out of render pipeline.
*/
-int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool, bool scene_color_manage)
+int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image)
{
- return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL, pool, scene_color_manage);
+ return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL, pool, scene_color_manage, skip_load_image);
}
/* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on)\
*
* Use it for stuff which is out of render pipeline.
*/
-int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct ImagePool *pool, bool scene_color_manage)
+int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image)
{
int use_nodes= tex->use_nodes, retval;
tex->use_nodes = false;
- retval= multitex_nodes_intern(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool, scene_color_manage);
+ retval= multitex_nodes_intern(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool, scene_color_manage, skip_load_image);
tex->use_nodes= use_nodes;
return retval;
@@ -1721,7 +1719,7 @@ static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *s
static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres,
float Tnor, const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3],
- struct ImagePool *pool)
+ struct ImagePool *pool, const bool skip_load_image)
{
TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */
float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv;
@@ -1774,7 +1772,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
/* center, main return value */
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool);
+ rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool, skip_load_image);
cd = fromrgb ? (texres->tr + texres->tg + texres->tb) / 3.0f : texres->tin;
if (mtex->texco == TEXCO_UV) {
@@ -1788,7 +1786,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
tco[1] = co[1] + compat_bump->dvdnu*du;
tco[2] = 0.f;
texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
- multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool);
+ multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image);
ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
/* +v val */
@@ -1796,7 +1794,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
tco[1] = co[1] + compat_bump->dvdnv*du;
tco[2] = 0.f;
texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
- multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool);
+ multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image);
vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
}
else {
@@ -1830,7 +1828,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
tco[1] = co[1] + tu[1]*du;
tco[2] = co[2] + tu[2]*du;
texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
- multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool);
+ multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image);
ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
/* +v val */
@@ -1838,7 +1836,7 @@ static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi,
tco[1] = co[1] + tv[1]*dv;
tco[2] = co[2] + tv[2]*dv;
texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
- multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool);
+ multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image);
vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
}
@@ -1880,7 +1878,8 @@ static void ntap_bump_init(NTapBump *ntap_bump)
static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres,
float Tnor, const float co[3], const float dx[3], const float dy[3],
- float texvec[3], float dxt[3], float dyt[3], struct ImagePool *pool)
+ float texvec[3], float dxt[3], float dyt[3], struct ImagePool *pool,
+ const bool skip_load_image)
{
TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */
@@ -1940,7 +1939,7 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
float dBdu, dBdv, auto_bump = 1.0f;
float s = 1; /* negate this if flipped texture coordinate */
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool);
+ rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool, skip_load_image);
if (shi->obr->ob->derivedFinal) {
auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale;
@@ -1982,14 +1981,14 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
}
/* use texres for the center sample, set rgbnor */
- rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, texres, pool);
+ rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, texres, pool, skip_load_image);
Hll = (fromrgb) ? rgb_to_grayscale(&texres->tr) : texres->tin;
/* use ttexr for the other 2 taps */
- multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr, pool);
+ multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr, pool, skip_load_image);
Hlr = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr, pool);
+ multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr, pool, skip_load_image);
Hul = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
dHdx = Hscale*(Hlr - Hll);
@@ -2020,17 +2019,17 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
}
/* use texres for the center sample, set rgbnor */
- rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres, pool);
+ rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres, pool, skip_load_image);
/* Hc = (fromrgb) ? rgb_to_grayscale(&texres->tr) : texres->tin; */ /* UNUSED */
/* use ttexr for the other taps */
- multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr, pool);
+ multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr, pool, skip_load_image);
Hl = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr, pool);
+ multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr, pool, skip_load_image);
Hr = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr, pool);
+ multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr, pool, skip_load_image);
Hd = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr, pool);
+ multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr, pool, skip_load_image);
Hu = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
dHdx = Hscale*(Hr - Hl);
@@ -2140,6 +2139,7 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
void do_material_tex(ShadeInput *shi, Render *re)
{
+ const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0;
CompatibleBump compat_bump;
NTapBump ntap_bump;
MTex *mtex;
@@ -2252,7 +2252,7 @@ void do_material_tex(ShadeInput *shi, Render *re)
if (mtex->uvname[0] != 0) {
for (i = 0; i < shi->totuv; i++) {
- if (strcmp(shi->uv[i].name, mtex->uvname)==0) {
+ if (STREQ(shi->uv[i].name, mtex->uvname)) {
suv= &shi->uv[i];
break;
}
@@ -2308,21 +2308,21 @@ void do_material_tex(ShadeInput *shi, Render *re)
if (use_compat_bump) {
rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex,
&texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt,
- re->pool);
+ re->pool, skip_load_image);
}
else if (use_ntap_bump) {
rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex,
&texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt,
- re->pool);
+ re->pool, skip_load_image);
}
else {
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool);
+ rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool, skip_load_image);
}
}
else {
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool);
+ rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool, skip_load_image);
}
/* texture output */
@@ -2674,6 +2674,7 @@ void do_material_tex(ShadeInput *shi, Render *re)
void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_r[3], float *val, Render *re)
{
+ const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
MTex *mtex;
Tex *tex;
TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
@@ -2761,7 +2762,7 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_
else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
}
- rgbnor = multitex(tex, texvec, NULL, NULL, 0, &texres, shi->thread, mtex->which_output, re->pool); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */
+ rgbnor = multitex(tex, texvec, NULL, NULL, 0, &texres, shi->thread, mtex->which_output, re->pool, skip_load_image); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */
/* texture output */
@@ -2872,6 +2873,7 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_
void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
{
+ const bool skip_load_image = har->skip_load_image;
MTex *mtex;
TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
float texvec[3], dxt[3], dyt[3], fact, facm, dx;
@@ -2928,7 +2930,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
if (mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
- rgb = multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output, har->pool);
+ rgb = multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output, har->pool, skip_load_image);
/* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@ -3017,6 +3019,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
/* hor and zen are RGB vectors, blend is 1 float, should all be initialized */
void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float hor[3], float zen[3], float *blend, int skyflag, short thread)
{
+ const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0;
MTex *mtex;
Tex *tex;
TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
@@ -3053,7 +3056,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h
switch (mtex->texco) {
case TEXCO_ANGMAP:
/* only works with texture being "real" */
- /* use saacos(), fixes bug [#22398], float precision caused lo[2] to be slightly less then -1.0 */
+ /* use saacos(), fixes bug [#22398], float precision caused lo[2] to be slightly less than -1.0 */
if (lo[0] || lo[1]) { /* check for zero case [#24807] */
fact= (1.0f/(float)M_PI)*saacos(lo[2])/(sqrtf(lo[0]*lo[0] + lo[1]*lo[1]));
tempvec[0]= lo[0]*fact;
@@ -3133,7 +3136,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h
/* texture */
if (tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
- rgb = multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output, R.pool);
+ rgb = multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output, R.pool, skip_load_image);
/* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@ -3225,6 +3228,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h
void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r[3], int effect)
{
+ const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0;
Object *ob;
MTex *mtex;
Tex *tex;
@@ -3348,7 +3352,7 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r
do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
}
- rgb = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output, R.pool);
+ rgb = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output, R.pool, skip_load_image);
/* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@@ -3422,7 +3426,7 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r
/* ------------------------------------------------------------------------- */
-int externtex(MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread, struct ImagePool *pool)
+int externtex(MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread, struct ImagePool *pool, const bool skip_load_image)
{
Tex *tex;
TexResult texr;
@@ -3448,7 +3452,7 @@ int externtex(MTex *mtex, const float vec[3], float *tin, float *tr, float *tg,
do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
}
- rgb = multitex(tex, texvec, dxt, dyt, 0, &texr, thread, mtex->which_output, pool);
+ rgb = multitex(tex, texvec, dxt, dyt, 0, &texr, thread, mtex->which_output, pool, skip_load_image);
if (rgb) {
texr.tin = rgb_to_bw(&texr.tr);
@@ -3473,6 +3477,7 @@ int externtex(MTex *mtex, const float vec[3], float *tin, float *tr, float *tg,
void render_realtime_texture(ShadeInput *shi, Image *ima)
{
+ const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0;
TexResult texr;
static Tex imatex[BLENDER_MAX_THREADS]; /* threadsafe */
static int firsttime= 1;
@@ -3513,8 +3518,8 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
texr.nor= NULL;
- if (shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr, R.pool);
- else imagewrap(tex, ima, NULL, texvec, &texr, R.pool);
+ if (shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr, R.pool, skip_load_image);
+ else imagewrap(tex, ima, NULL, texvec, &texr, R.pool, skip_load_image);
shi->vcol[0]*= texr.tr;
shi->vcol[1]*= texr.tg;
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index a67140c6334..5b054005bac 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -50,15 +50,7 @@
#include "DNA_material_types.h"
#include "DNA_group_types.h"
-#include "BKE_main.h"
-
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-#include "IMB_colormanagement.h"
-
/* local include */
-#include "rayintersection.h"
-#include "rayobject.h"
#include "renderpipeline.h"
#include "render_result.h"
#include "render_types.h"
@@ -71,8 +63,6 @@
#include "sss.h"
#include "zbuf.h"
-#include "PIL_time.h"
-
/* own include */
#include "rendercore.h"
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 46c504aaabf..42c654b2c43 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -78,11 +78,8 @@
#include "rayintersection.h"
#include "rayobject.h"
-#include "renderpipeline.h"
#include "render_types.h"
#include "renderdatabase.h"
-#include "texture.h"
-#include "strand.h"
#include "zbuf.h"
/* ------------------------------------------------------------------------- */
@@ -957,6 +954,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,
const float vec[3], const float vec1[3],
const float *orco, float hasize, float vectsize, int seed)
{
+ const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
HaloRen *har;
MTex *mtex;
float tin, tr, tg, tb, ta;
@@ -1048,7 +1046,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,
}
}
- externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool);
+ externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool, skip_load_image);
yn= tin*mtex->colfac;
//zn= tin*mtex->alphafac;
@@ -1068,6 +1066,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,
}
har->pool = re->pool;
+ har->skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
return har;
}
@@ -1076,6 +1075,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
const float vec[3], const float vec1[3],
const float *orco, const float *uvco, float hasize, float vectsize, int seed, const float pa_co[3])
{
+ const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
HaloRen *har;
MTex *mtex;
float tin, tr, tg, tb, ta;
@@ -1179,7 +1179,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
copy_v3_v3(texvec, orco);
}
- hasrgb = externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool);
+ hasrgb = externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool, skip_load_image);
//yn= tin*mtex->colfac;
//zn= tin*mtex->alphafac;
@@ -1223,6 +1223,7 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
}
har->pool = re->pool;
+ har->skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
return har;
}
@@ -1394,7 +1395,7 @@ void RE_makeRenderInstances(Render *re)
int tot;
/* convert list of object instances to an array for index based lookup */
- tot= BLI_countlist(&re->instancetable);
+ tot= BLI_listbase_count(&re->instancetable);
re->objectinstance= MEM_callocN(sizeof(ObjectInstanceRen)*tot, "ObjectInstance");
re->totinstance= tot;
newlist.first= newlist.last= NULL;
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index 9d83ff1d7e8..0bd4815fb73 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -50,7 +50,6 @@
#include "PIL_time.h"
-#include "renderpipeline.h"
#include "render_types.h"
#include "renderdatabase.h"
#include "rendercore.h"
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 7aca6b9ac87..01055d87a38 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -46,11 +46,9 @@
/* local include */
#include "raycounter.h"
-#include "renderpipeline.h"
#include "render_types.h"
#include "renderdatabase.h"
#include "rendercore.h"
-#include "shadbuf.h"
#include "shading.h"
#include "strand.h"
#include "texture.h"
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index f909c585561..63a97a04b39 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -47,9 +47,7 @@
/* local include */
#include "occlusion.h"
-#include "renderpipeline.h"
#include "render_types.h"
-#include "pixelblending.h"
#include "rendercore.h"
#include "shadbuf.h"
#include "sss.h"
@@ -2066,7 +2064,7 @@ float RE_lamp_get_data(ShadeInput *shi, Object *lamp_obj, float col[4], float lv
if (R.r.scemode & R_BUTS_PREVIEW) {
for (go = R.lights.first; go; go = go->next) {
/* "Lamp.002" is main key light of material preview */
- if (strcmp(go->ob->id.name + 2, "Lamp.002") == 0)
+ if (STREQ(go->ob->id.name + 2, "Lamp.002"))
return lamp_get_data_internal(shi, go, col, lv, dist, shadow);
}
return 0.0f;
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index 7e9003aaee7..890b0445ecc 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -57,7 +57,6 @@
#include "BLF_translation.h"
-#include "PIL_time.h"
#include "DNA_material_types.h"
@@ -68,11 +67,7 @@
/* this module */
#include "render_types.h"
-#include "rendercore.h"
-#include "renderdatabase.h"
-#include "shading.h"
#include "sss.h"
-#include "zbuf.h"
/* Generic Multiple Scattering API */
@@ -1036,14 +1031,12 @@ void make_sss_tree(Render *re)
void free_sss(Render *re)
{
if (re->sss_hash) {
- GHashIterator *it= BLI_ghashIterator_new(re->sss_hash);
+ GHashIterator gh_iter;
- while (!BLI_ghashIterator_done(it)) {
- sss_free_tree(BLI_ghashIterator_getValue(it));
- BLI_ghashIterator_step(it);
+ GHASH_ITER (gh_iter, re->sss_hash) {
+ sss_free_tree(BLI_ghashIterator_getValue(&gh_iter));
}
- BLI_ghashIterator_free(it);
BLI_ghash_free(re->sss_hash, NULL, NULL);
re->sss_hash= NULL;
}
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 485680da76f..6b52d4aa419 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -47,11 +47,8 @@
#include "render_types.h"
-#include "initrender.h"
#include "rendercore.h"
#include "renderdatabase.h"
-#include "renderpipeline.h"
-#include "pixelblending.h"
#include "shading.h"
#include "strand.h"
#include "zbuf.h"
diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c
index 1836b3f48a7..d4e53eb7305 100644
--- a/source/blender/render/intern/source/sunsky.c
+++ b/source/blender/render/intern/source/sunsky.c
@@ -254,14 +254,14 @@ void GetSkyXYZRadiance(struct SunSky *sunsky, float theta, float phi, float colo
float hfade = 1, nfade = 1;
- if (theta > (0.5f * (float)M_PI)) {
+ if (theta > (float)M_PI_2) {
hfade = 1.0f - (theta * (float)M_1_PI - 0.5f) * 2.0f;
hfade = hfade * hfade * (3.0f - 2.0f * hfade);
- theta = 0.5 * M_PI;
+ theta = M_PI_2;
}
- if (sunsky->theta > (0.5f * (float)M_PI)) {
- if (theta <= 0.5f * (float)M_PI) {
+ if (sunsky->theta > (float)M_PI_2) {
+ if (theta <= (float)M_PI_2) {
nfade = 1.0f - (0.5f - theta * (float)M_1_PI) * 2.0f;
nfade *= 1.0f - (sunsky->theta * (float)M_1_PI - 0.5f) * 2.0f;
nfade = nfade * nfade * (3.0f - 2.0f * nfade);
@@ -299,8 +299,7 @@ void GetSkyXYZRadiancef(struct SunSky *sunsky, const float varg[3], float color_
float theta, phi;
float v[3];
- copy_v3_v3(v, (float *)varg);
- normalize_v3(v);
+ normalize_v3_v3(v, varg);
if (v[2] < 0.001f) {
v[2] = 0.001f;
diff --git a/source/blender/render/intern/source/texture_ocean.c b/source/blender/render/intern/source/texture_ocean.c
index 55f4bf3794d..5261374b34d 100644
--- a/source/blender/render/intern/source/texture_ocean.c
+++ b/source/blender/render/intern/source/texture_ocean.c
@@ -56,8 +56,6 @@ extern struct Render R;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-
/* ***** actual texture sampling ***** */
int ocean_texture(Tex *tex, const float texvec[2], TexResult *texres)
{
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 50b5e392b3f..8bc5c7a1c8f 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -51,22 +51,24 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "BKE_cloth.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "smoke_API.h"
+#include "BPH_mass_spring.h"
#include "DNA_texture_types.h"
#include "DNA_object_force.h"
#include "DNA_object_types.h"
+#include "DNA_particle_types.h"
#include "DNA_modifier_types.h"
#include "DNA_smoke_types.h"
#include "render_types.h"
-#include "renderdatabase.h"
#include "texture.h"
#include "voxeldata.h"
@@ -365,6 +367,27 @@ static void init_frame_smoke(VoxelData *vd, int cfra)
#endif
}
+static void init_frame_hair(VoxelData *vd, int UNUSED(cfra))
+{
+ Object *ob;
+ ModifierData *md;
+ bool found = false;
+
+ vd->dataset = NULL;
+ if (vd->object == NULL) return;
+ ob = vd->object;
+
+ if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_ParticleSystem))) {
+ ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md;
+
+ if (pmd->psys && pmd->psys->clmd) {
+ found |= BPH_cloth_solver_get_texture_data(ob, pmd->psys->clmd, vd);
+ }
+ }
+
+ vd->ok = found;
+}
+
void cache_voxeldata(Tex *tex, int scene_frame)
{
VoxelData *vd = tex->vd;
@@ -398,6 +421,9 @@ void cache_voxeldata(Tex *tex, int scene_frame)
case TEX_VD_SMOKE:
init_frame_smoke(vd, scene_frame);
return;
+ case TEX_VD_HAIR:
+ init_frame_hair(vd, scene_frame);
+ return;
case TEX_VD_BLENDERVOXEL:
BLI_path_abs(path, G.main->name);
if (!BLI_exists(path)) return;
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 87e546ef24e..7e8f0e3e9fc 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -63,12 +63,10 @@
#include "pixelblending.h"
#include "render_result.h"
#include "render_types.h"
-#include "renderpipeline.h"
#include "renderdatabase.h"
#include "rendercore.h"
#include "shadbuf.h"
#include "shading.h"
-#include "sss.h"
#include "strand.h"
/* own includes */
@@ -2065,8 +2063,6 @@ static void zmask_rect(int *rectz, int *rectp, int xs, int ys, int neg)
}
-
-
/* ***************** ZBUFFER MAIN ROUTINES **************** */
void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart *, ZSpan *, int, void *), void *data)
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index 088bddc8a76..78b5d499644 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -130,10 +130,10 @@ if(WITH_BUILDINFO)
add_definitions(-DWITH_BUILDINFO)
endif()
-if(WIN322)
- list(APPEND INC
- ../../../intern/utfconv
- )
+if(WIN32)
+ if(WITH_INPUT_IME)
+ add_definitions(-DWITH_INPUT_IME)
+ endif()
endif()
if(WITH_COMPOSITOR)
diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript
index b93192d5067..a6f64f7cdae 100644
--- a/source/blender/windowmanager/SConscript
+++ b/source/blender/windowmanager/SConscript
@@ -65,11 +65,14 @@ if env['WITH_BF_COLLADA']:
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
- incs += ' ../../intern/utfconv'
if env['BF_BUILDINFO']:
defs.append('WITH_BUILDINFO')
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'win64-mingw'):
+ if env['WITH_BF_IME']:
+ defs.append('WITH_INPUT_IME')
+
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index e1cd334637a..d2abfd419d1 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -47,6 +47,7 @@ extern "C" {
#endif
struct bContext;
+struct GHashIterator;
struct IDProperty;
struct wmEvent;
struct wmEventHandler;
@@ -223,12 +224,13 @@ void WM_operator_stack_clear(struct wmWindowManager *wm);
void WM_operator_handlers_clear(wmWindowManager *wm, struct wmOperatorType *ot);
struct wmOperatorType *WM_operatortype_find(const char *idname, bool quiet);
-struct GHashIterator *WM_operatortype_iter(void);
+void WM_operatortype_iter(struct GHashIterator *ghi);
void WM_operatortype_append(void (*opfunc)(struct wmOperatorType *));
void WM_operatortype_append_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata);
void WM_operatortype_append_macro_ptr(void (*opfunc)(struct wmOperatorType *, void *), void *userdata);
void WM_operatortype_remove_ptr(struct wmOperatorType *ot);
bool WM_operatortype_remove(const char *idname);
+void WM_operatortype_last_properties_clear_all(void);
struct wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag);
struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *ot, const char *idname);
@@ -266,6 +268,7 @@ void WM_operator_properties_select_action_simple(struct wmOperatorType *ot, int
bool WM_operator_check_ui_enabled(const struct bContext *C, const char *idname);
wmOperator *WM_operator_last_redo(const struct bContext *C);
+ID *WM_operator_drop_load_path(struct bContext *C, struct wmOperator *op, const short idcode);
bool WM_operator_last_properties_init(struct wmOperator *op);
bool WM_operator_last_properties_store(struct wmOperator *op);
@@ -395,6 +398,7 @@ enum {
WM_JOB_TYPE_CLIP_SOLVE_CAMERA,
WM_JOB_TYPE_CLIP_PREFETCH,
WM_JOB_TYPE_SEQ_BUILD_PROXY,
+ WM_JOB_TYPE_SEQ_BUILD_PREVIEW,
/* add as needed, screencast, seq proxy build
* if having hard coded values is a problem */
};
@@ -458,6 +462,10 @@ void WM_event_ndof_to_quat(const struct wmNDOFMotionData *ndof, float q[4
float WM_event_tablet_data(const struct wmEvent *event, int *pen_flip, float tilt[2]);
bool WM_event_is_tablet(const struct wmEvent *event);
+#ifdef WITH_INPUT_IME
+bool WM_event_is_ime_switch(const struct wmEvent *event);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index ff252f0fc20..0e3e65d2e21 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -94,12 +94,12 @@
* </pre>
*
* A common way to get the space from the ScrArea:
- * <pre>
- * if (sa->spacetype == SPACE_VIEW3D) {
- * View3D *v3d = sa->spacedata.first;
- * ...
- * }
- * </pre>
+ * \code{.c}
+ * if (sa->spacetype == SPACE_VIEW3D) {
+ * View3D *v3d = sa->spacedata.first;
+ * ...
+ * }
+ * \endcode
*/
#ifdef __cplusplus
@@ -169,7 +169,7 @@ enum {
#define KM_OSKEY2 128
/* KM_MOD_ flags for wmKeyMapItem and wmEvent.alt/shift/oskey/ctrl */
-/* note that KM_ANY and false are used with these defines too */
+/* note that KM_ANY and KM_NOTHING are used with these defines too */
#define KM_MOD_FIRST 1
#define KM_MOD_SECOND 2
@@ -239,6 +239,7 @@ typedef struct wmNotifier {
#define NC_MASK (21<<24)
#define NC_GPENCIL (22<<24)
#define NC_LINESTYLE (23<<24)
+#define NC_CAMERA (24<<24)
/* data type, 256 entries is enough, it can overlap */
#define NOTE_DATA 0x00FF0000
@@ -297,6 +298,7 @@ typedef struct wmNotifier {
#define ND_POINTCACHE (28<<16)
#define ND_PARENT (29<<16)
#define ND_LOD (30<<16)
+#define ND_DRAW_RENDER_VIEWPORT (31<<16) /* for camera & sequencer viewport update, also /w NC_SCENE */
/* NC_MATERIAL Material */
#define ND_SHADING (30<<16)
@@ -324,6 +326,9 @@ typedef struct wmNotifier {
#define ND_NLA_ACTCHANGE (74<<16)
#define ND_FCURVES_ORDER (75<<16)
+ /* NC_GPENCIL */
+#define ND_GPENCIL_EDITMODE (85<<16)
+
/* NC_GEOM Geometry */
/* Mesh, Curve, MetaBall, Armature, .. */
#define ND_SELECT (90<<16)
@@ -554,9 +559,7 @@ typedef struct wmOperatorType {
/* pointer to modal keymap, do not free! */
struct wmKeyMap *modalkeymap;
- /* only used for operators defined with python
- * use to store pointers to python functions */
- void *pyop_data;
+ /* python needs the operator type as well */
int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot) ATTR_WARN_UNUSED_RESULT;
/* RNA integration */
@@ -567,6 +570,24 @@ typedef struct wmOperatorType {
} wmOperatorType;
+#ifdef WITH_INPUT_IME
+/* *********** Input Method Editor (IME) *********** */
+
+/* similar to GHOST_TEventImeData */
+typedef struct wmIMEData {
+ size_t result_len, composite_len;
+
+ char *str_result; /* utf8 encoding */
+ char *str_composite; /* utf8 encoding */
+
+ int cursor_pos; /* cursor position in the IME composition. */
+ int sel_start; /* beginning of the selection */
+ int sel_end; /* end of the selection */
+
+ bool is_ime_composing;
+} wmIMEData;
+#endif
+
/* **************** Paint Cursor ******************* */
typedef void (*wmPaintCursorDraw)(struct bContext *C, int, int, void *customdata);
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index d05cc572c45..34069e0b873 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -39,8 +39,6 @@
#include "DNA_windowmanager_types.h"
-#include "GHOST_C-api.h"
-
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
@@ -59,7 +57,6 @@
#include "WM_types.h"
#include "wm_window.h"
#include "wm_event_system.h"
-#include "wm_event_types.h"
#include "wm_draw.h"
#include "wm.h"
@@ -155,7 +152,7 @@ void wm_operator_register(bContext *C, wmOperator *op)
int tot;
BLI_addtail(&wm->operators, op);
- tot = BLI_countlist(&wm->operators);
+ tot = BLI_listbase_count(&wm->operators);
while (tot > MAX_OP_REGISTERED) {
wmOperator *opt = wm->operators.first;
@@ -253,15 +250,14 @@ void WM_uilisttype_init(void)
void WM_uilisttype_free(void)
{
- GHashIterator *iter = BLI_ghashIterator_new(uilisttypes_hash);
+ GHashIterator gh_iter;
- for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) {
- uiListType *ult = BLI_ghashIterator_getValue(iter);
+ GHASH_ITER (gh_iter, uilisttypes_hash) {
+ uiListType *ult = BLI_ghashIterator_getValue(&gh_iter);
if (ult->ext.free) {
ult->ext.free(ult->ext.data);
}
}
- BLI_ghashIterator_free(iter);
BLI_ghash_free(uilisttypes_hash, NULL, MEM_freeN);
uilisttypes_hash = NULL;
@@ -312,15 +308,14 @@ void WM_menutype_init(void)
void WM_menutype_free(void)
{
- GHashIterator *iter = BLI_ghashIterator_new(menutypes_hash);
+ GHashIterator gh_iter;
- for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) {
- MenuType *mt = BLI_ghashIterator_getValue(iter);
+ GHASH_ITER (gh_iter, menutypes_hash) {
+ MenuType *mt = BLI_ghashIterator_getValue(&gh_iter);
if (mt->ext.free) {
mt->ext.free(mt->ext.data);
}
}
- BLI_ghashIterator_free(iter);
BLI_ghash_free(menutypes_hash, NULL, MEM_freeN);
menutypes_hash = NULL;
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index e5bba9285b4..cdc3c9eaaff 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -45,10 +45,8 @@
#include "BIF_glutil.h"
#include "BKE_context.h"
-#include "BKE_screen.h"
#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
#include "UI_interface.h"
#include "UI_interface_icons.h"
@@ -58,8 +56,6 @@
#include "WM_api.h"
#include "WM_types.h"
#include "wm_event_system.h"
-#include "wm.h"
-
/* ****************************************************** */
@@ -85,7 +81,7 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
for (dm = dropboxes.first; dm; dm = dm->next)
if (dm->spaceid == spaceid && dm->regionid == regionid)
- if (0 == strncmp(idname, dm->idname, KMAP_MAX_NAME))
+ if (STREQLEN(idname, dm->idname, KMAP_MAX_NAME))
return &dm->dropboxes;
dm = MEM_callocN(sizeof(struct wmDropBoxMap), "dropmap list");
@@ -271,16 +267,11 @@ void wm_drags_check_ops(bContext *C, wmEvent *event)
static void wm_drop_operator_draw(const char *name, int x, int y)
{
- int width = UI_GetStringWidth(name);
- int padding = 4 * UI_DPI_FAC;
-
- glColor4ub(0, 0, 0, 50);
-
- uiSetRoundBox(UI_CNR_ALL | UI_RB_ALPHA);
- uiRoundBox(x, y, x + width + 2 * padding, y + 4 * padding, padding);
-
- glColor4ub(255, 255, 255, 255);
- UI_DrawString(x + padding, y + padding, name);
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ const unsigned char fg[4] = {255, 255, 255, 255};
+ const unsigned char bg[4] = {0, 0, 0, 50};
+
+ UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, fg, bg);
}
static const char *wm_drag_name(wmDrag *drag)
@@ -288,13 +279,12 @@ static const char *wm_drag_name(wmDrag *drag)
switch (drag->type) {
case WM_DRAG_ID:
{
- ID *id = (ID *)drag->poin;
+ ID *id = drag->poin;
return id->name + 2;
}
case WM_DRAG_PATH:
- return drag->path;
case WM_DRAG_NAME:
- return (char *)drag->path;
+ return drag->path;
}
return "";
}
@@ -315,6 +305,7 @@ static void drag_rect_minmax(rcti *rect, int x1, int y1, int x2, int y2)
/* if rect set, do not draw */
void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
{
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
wmWindowManager *wm = CTX_wm_manager(C);
wmDrag *drag;
const int winsize_y = WM_window_pixels_y(win);
@@ -330,7 +321,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
/* XXX todo, multiline drag draws... but maybe not, more types mixed wont work well */
glEnable(GL_BLEND);
for (drag = wm->drags.first; drag; drag = drag->next) {
- int iconsize = 16 * UI_DPI_FAC; /* assumed to be 16 pixels */
+ int iconsize = UI_DPI_ICON_SIZE;
int padding = 4 * UI_DPI_FAC;
/* image or icon */
@@ -366,12 +357,12 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
}
if (rect) {
- int w = UI_GetStringWidth(wm_drag_name(drag));
+ int w = UI_fontstyle_string_width(fstyle, wm_drag_name(drag));
drag_rect_minmax(rect, x, y, x + w, y + iconsize);
}
else {
glColor4ub(255, 255, 255, 255);
- UI_DrawString(x, y, wm_drag_name(drag));
+ UI_fontstyle_draw_simple(fstyle, x, y, wm_drag_name(drag));
}
/* operator name with roundbox */
@@ -387,14 +378,16 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
else {
x = cursorx - 2 * padding;
- if (cursory + iconsize + iconsize < winsize_y)
- y = cursory + iconsize;
- else
- y = cursory - iconsize - 2 * UI_DPI_FAC;
+ if (cursory + iconsize + iconsize < winsize_y) {
+ y = (cursory + iconsize) + padding;
+ }
+ else {
+ y = (cursory - iconsize) - padding;
+ }
}
if (rect) {
- int w = UI_GetStringWidth(wm_drag_name(drag));
+ int w = UI_fontstyle_string_width(fstyle, wm_drag_name(drag));
drag_rect_minmax(rect, x, y, x + w, y + iconsize);
}
else
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 793908ec44b..f1a46826435 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -71,6 +71,8 @@
#include "BIF_gl.h"
+#include "GPU_debug.h"
+
#include "UI_interface.h"
#include "PIL_time.h"
@@ -81,7 +83,6 @@
#include "wm_window.h"
#include "wm_event_system.h"
#include "wm_event_types.h"
-#include "wm_draw.h"
#ifndef NDEBUG
# include "RNA_enum_types.h"
@@ -269,7 +270,7 @@ void wm_event_do_notifiers(bContext *C)
if (note->category == NC_SCREEN) {
if (note->data == ND_SCREENBROWSE) {
/* free popup handlers only [#35434] */
- UI_remove_popup_handlers_all(C, &win->modalhandlers);
+ UI_popup_handlers_remove_all(C, &win->modalhandlers);
ED_screen_set(C, note->reference); // XXX hrms, think this over!
@@ -542,7 +543,7 @@ void WM_event_print(const wmEvent *event)
event->shift, event->ctrl, event->alt, event->oskey, event->keymodifier,
event->x, event->y, event->ascii,
BLI_str_utf8_size(event->utf8_buf), event->utf8_buf,
- event->keymap_idname, (void *)event);
+ event->keymap_idname, (const void *)event);
if (ISNDOF(event->type)) {
const wmNDOFMotionData *ndof = event->customdata;
@@ -621,7 +622,7 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, bool ca
{
if (caller_owns_reports == false) { /* popup */
if (op->reports->list.first) {
- /* FIXME, temp setting window, see other call to uiPupMenuReports for why */
+ /* FIXME, temp setting window, see other call to UI_popup_menu_reports for why */
wmWindow *win_prev = CTX_wm_window(C);
ScrArea *area_prev = CTX_wm_area(C);
ARegion *ar_prev = CTX_wm_region(C);
@@ -629,7 +630,7 @@ static void wm_operator_reports(bContext *C, wmOperator *op, int retval, bool ca
if (win_prev == NULL)
CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first);
- uiPupMenuReports(C, op->reports);
+ UI_popup_menu_reports(C, op->reports);
CTX_wm_window_set(C, win_prev);
CTX_wm_area_set(C, area_prev);
@@ -730,7 +731,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons
/* XXX Disabled the repeat check to address part 2 of #31840.
* Carefully checked all calls to wm_operator_exec and WM_operator_repeat, don't see any reason
* why this was needed, but worth to note it in case something turns bad. (mont29) */
- if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED)/* && repeat == 0 */)
+ if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED) /* && repeat == 0 */)
wm_operator_reports(C, op, retval, false);
if (retval & OPERATOR_FINISHED) {
@@ -871,7 +872,7 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot,
break;
/* skip invalid properties */
- if (strcmp(RNA_property_identifier(prop), otmacro->idname) == 0) {
+ if (STREQ(RNA_property_identifier(prop), otmacro->idname)) {
wmOperatorType *otm = WM_operatortype_find(otmacro->idname, 0);
PointerRNA someptr = RNA_property_pointer_get(properties, prop);
wmOperator *opm = wm_operator_create(wm, otm, &someptr, NULL);
@@ -1663,7 +1664,6 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
int action = WM_HANDLER_CONTINUE;
switch (val) {
- case EVT_FILESELECT_OPEN:
case EVT_FILESELECT_FULL_OPEN:
{
ScrArea *sa;
@@ -1677,9 +1677,16 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
else {
sa = handler->op_area;
}
-
- if (val == EVT_FILESELECT_OPEN) {
+
+ if (sa->full) {
+ /* ensure the first area becomes the file browser, because the second one is the small
+ * top (info-)area which might be too small (in fullscreens we have max two areas) */
+ if (sa->prev) {
+ sa = sa->prev;
+ }
ED_area_newspace(C, sa, SPACE_FILE); /* 'sa' is modified in-place */
+ /* we already had a fullscreen here -> mark new space as a stacked fullscreen */
+ sa->flag |= AREA_FLAG_STACKED_FULLSCREEN;
}
else {
sa = ED_screen_full_newspace(C, sa, SPACE_FILE); /* sets context */
@@ -1703,24 +1710,16 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
case EVT_FILESELECT_CANCEL:
case EVT_FILESELECT_EXTERNAL_CANCEL:
{
- /* XXX validate area and region? */
- bScreen *screen = CTX_wm_screen(C);
-
/* remlink now, for load file case before removing*/
BLI_remlink(handlers, handler);
-
+
if (val != EVT_FILESELECT_EXTERNAL_CANCEL) {
- if (screen != handler->filescreen) {
- ED_screen_full_prevspace(C, CTX_wm_area(C));
- }
- else {
- ED_area_prevspace(C, CTX_wm_area(C));
- }
+ ED_screen_full_prevspace(C, CTX_wm_area(C));
}
-
+
wm_handler_op_context(C, handler);
- /* needed for uiPupMenuReports */
+ /* needed for UI_popup_menu_reports */
if (val == EVT_FILESELECT_EXEC) {
int retval;
@@ -1752,7 +1751,7 @@ static int wm_handler_fileselect_do(bContext *C, ListBase *handlers, wmEventHand
CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first);
BKE_report_print_level_set(handler->op->reports, RPT_WARNING);
- uiPupMenuReports(C, handler->op->reports);
+ UI_popup_menu_reports(C, handler->op->reports);
/* XXX - copied from 'wm_operator_finished()' */
/* add reports to the global list, otherwise they are not seen */
@@ -1955,7 +1954,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
event->customdata = NULL;
event->custom = 0;
- WM_operator_name_call(C, drop->ot->idname, drop->opcontext, drop->ptr);
+ WM_operator_name_call_ptr(C, drop->ot, drop->opcontext, drop->ptr);
action |= WM_HANDLER_BREAK;
/* XXX fileread case */
@@ -2323,6 +2322,14 @@ void wm_event_do_handlers(bContext *C)
}
for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+ /* after restoring a screen from SCREENMAXIMIZED we have to wait
+ * with the screen handling till the region coordinates are updated */
+ if (win->screen->skip_handling == true) {
+ /* restore for the next iteration of wm_event_do_handlers */
+ win->screen->skip_handling = false;
+ break;
+ }
+
if (wm_event_inside_i(event, &sa->totrct)) {
CTX_wm_area_set(C, sa);
@@ -2417,12 +2424,7 @@ void wm_event_do_handlers(bContext *C)
/* update key configuration after handling events */
WM_keyconfig_update(wm);
- if (G.debug) {
- GLenum error = glGetError();
- if (error != GL_NO_ERROR) {
- printf("GL error: %s\n", gluErrorString(error));
- }
- }
+ GPU_ASSERT_NO_GL_ERRORS("wm_event_do_handlers");
}
/* ********** filesector handling ************ */
@@ -2456,7 +2458,6 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
wmEventHandler *handler, *handlernext;
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
- int full = 1; // XXX preset?
/* only allow 1 file selector open per window */
for (handler = win->modalhandlers.first; handler; handler = handlernext) {
@@ -2491,7 +2492,6 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
handler->op = op;
handler->op_area = CTX_wm_area(C);
handler->op_region = CTX_wm_region(C);
- handler->filescreen = CTX_wm_screen(C);
BLI_addhead(&win->modalhandlers, handler);
@@ -2501,7 +2501,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
op->type->check(C, op); /* ignore return value */
}
- WM_event_fileselect_event(wm, op, full ? EVT_FILESELECT_FULL_OPEN : EVT_FILESELECT_OPEN);
+ WM_event_fileselect_event(wm, op, EVT_FILESELECT_FULL_OPEN);
}
#if 0
@@ -3050,6 +3050,13 @@ static void wm_event_add_mousemove(wmWindow *win, const wmEvent *event)
void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int UNUSED(time), void *customdata)
{
wmWindow *owin;
+
+ /* Having both, event and evt, can be highly confusing to work with, but is necessary for
+ * our current event system, so let's clear things up a bit:
+ * - data added to event only will be handled immediately, but will not be copied to the next event
+ * - data added to evt only stays, but is handled with the next event -> execution delay
+ * - data added to event and evt stays and is handled immediately
+ */
wmEvent event, *evt = win->eventstate;
/* initialize and copy state (only mouse x y and modifiers) */
@@ -3190,6 +3197,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
case GHOST_kEventKeyUp:
{
GHOST_TEventKeyData *kd = customdata;
+ short keymodifier = KM_NOTHING;
event.type = convert_key(kd->key);
event.ascii = kd->ascii;
memcpy(event.utf8_buf, kd->utf8_buf, sizeof(event.utf8_buf)); /* might be not null terminated*/
@@ -3230,28 +3238,38 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
}
}
- /* modifiers assign to eventstate, so next event gets the modifer (makes modifier key events work) */
/* assigning both first and second is strange - campbell */
switch (event.type) {
- case LEFTSHIFTKEY: case RIGHTSHIFTKEY:
- evt->shift = (event.val == KM_PRESS) ?
- ((evt->ctrl || evt->alt || evt->oskey) ? (KM_MOD_FIRST | KM_MOD_SECOND) : KM_MOD_FIRST) :
- false;
+ case LEFTSHIFTKEY:
+ case RIGHTSHIFTKEY:
+ if (event.val == KM_PRESS) {
+ if (evt->ctrl || evt->alt || evt->oskey) keymodifier = (KM_MOD_FIRST | KM_MOD_SECOND);
+ else keymodifier = KM_MOD_FIRST;
+ }
+ event.shift = evt->shift = keymodifier;
break;
- case LEFTCTRLKEY: case RIGHTCTRLKEY:
- evt->ctrl = (event.val == KM_PRESS) ?
- ((evt->shift || evt->alt || evt->oskey) ? (KM_MOD_FIRST | KM_MOD_SECOND) : KM_MOD_FIRST) :
- false;
+ case LEFTCTRLKEY:
+ case RIGHTCTRLKEY:
+ if (event.val == KM_PRESS) {
+ if (evt->shift || evt->alt || evt->oskey) keymodifier = (KM_MOD_FIRST | KM_MOD_SECOND);
+ else keymodifier = KM_MOD_FIRST;
+ }
+ event.ctrl = evt->ctrl = keymodifier;
break;
- case LEFTALTKEY: case RIGHTALTKEY:
- evt->alt = (event.val == KM_PRESS) ?
- ((evt->ctrl || evt->shift || evt->oskey) ? (KM_MOD_FIRST | KM_MOD_SECOND) : KM_MOD_FIRST) :
- false;
+ case LEFTALTKEY:
+ case RIGHTALTKEY:
+ if (event.val == KM_PRESS) {
+ if (evt->ctrl || evt->shift || evt->oskey) keymodifier = (KM_MOD_FIRST | KM_MOD_SECOND);
+ else keymodifier = KM_MOD_FIRST;
+ }
+ event.alt = evt->alt = keymodifier;
break;
case OSKEY:
- evt->oskey = (event.val == KM_PRESS) ?
- ((evt->ctrl || evt->alt || evt->shift) ? (KM_MOD_FIRST | KM_MOD_SECOND) : KM_MOD_FIRST) :
- false;
+ if (event.val == KM_PRESS) {
+ if (evt->ctrl || evt->alt || evt->shift) keymodifier = (KM_MOD_FIRST | KM_MOD_SECOND);
+ else keymodifier = KM_MOD_FIRST;
+ }
+ event.oskey = evt->oskey = keymodifier;
break;
default:
if (event.val == KM_PRESS && event.keymodifier == 0)
@@ -3374,6 +3392,35 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
break;
}
+#ifdef WITH_INPUT_IME
+ case GHOST_kEventImeCompositionStart:
+ {
+ event.val = KM_PRESS;
+ win->ime_data = customdata;
+ win->ime_data->is_ime_composing = true;
+ event.type = WM_IME_COMPOSITE_START;
+ wm_event_add(win, &event);
+ break;
+ }
+ case GHOST_kEventImeComposition:
+ {
+ event.val = KM_PRESS;
+ event.type = WM_IME_COMPOSITE_EVENT;
+ wm_event_add(win, &event);
+ break;
+ }
+ case GHOST_kEventImeCompositionEnd:
+ {
+ event.val = KM_PRESS;
+ if (win->ime_data) {
+ win->ime_data->is_ime_composing = false;
+ }
+ event.type = WM_IME_COMPOSITE_END;
+ wm_event_add(win, &event);
+ break;
+ }
+#endif /* WITH_INPUT_IME */
+
}
#if 0
@@ -3480,5 +3527,13 @@ bool WM_event_is_tablet(const struct wmEvent *event)
return (event->tablet_data) ? true : false;
}
+#ifdef WITH_INPUT_IME
+/* most os using ctrl/oskey + space to switch ime, avoid added space */
+bool WM_event_is_ime_switch(const struct wmEvent *event)
+{
+ return event->val == KM_PRESS && event->type == SPACEKEY &&
+ (event->ctrl || event->oskey || event->shift || event->alt);
+}
+#endif
/** \} */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 7865e09cbe2..f5a7ad164d6 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -69,6 +69,7 @@
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
+#include "BKE_appdir.h"
#include "BKE_utildefines.h"
#include "BKE_autoexec.h"
#include "BKE_blender.h"
@@ -96,8 +97,6 @@
#include "ED_view3d.h"
#include "ED_util.h"
-#include "RE_pipeline.h" /* only to report missing engine */
-
#include "GHOST_C-api.h"
#include "GHOST_Path-api.h"
@@ -319,7 +318,7 @@ static void wm_init_userdef(bContext *C, const bool from_memory)
}
/* update tempdir from user preferences */
- BLI_temp_dir_init(U.tempdir);
+ BKE_tempdir_init(U.tempdir);
BKE_userdef_state();
}
@@ -356,7 +355,7 @@ static int wm_read_exotic(Scene *UNUSED(scene), const char *name)
else {
len = gzread(gzfile, header, sizeof(header));
gzclose(gzfile);
- if (len == sizeof(header) && strncmp(header, "BLENDER", 7) == 0) {
+ if (len == sizeof(header) && STREQLEN(header, "BLENDER", 7)) {
retval = BKE_READ_EXOTIC_OK_BLEND;
}
else {
@@ -476,6 +475,8 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
BPY_python_reset(C);
#endif
+ WM_operatortype_last_properties_clear_all();
+
/* important to do before NULL'ing the context */
BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_VERSION_UPDATE);
BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST);
@@ -534,11 +535,13 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
}
-/* called on startup, (context entirely filled with NULLs) */
-/* or called for 'New File' */
-/* both startup.blend and userpref.blend are checked */
-/* the optional paramater custom_file points to an alterntive startup page */
-/* custom_file can be NULL */
+/**
+ * called on startup, (context entirely filled with NULLs)
+ * or called for 'New File'
+ * both startup.blend and userpref.blend are checked
+ * the optional parameter custom_file points to an alternative startup page
+ * custom_file can be NULL
+ */
int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const char *custom_file)
{
ListBase wmbase;
@@ -560,13 +563,17 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c
/* options exclude eachother */
BLI_assert((from_memory && custom_file) == 0);
+ if ((G.f & G_SCRIPT_OVERRIDE_PREF) == 0) {
+ BKE_BIT_TEST_SET(G.f, (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0, G_SCRIPT_AUTOEXEC);
+ }
+
BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
UI_view2d_zoom_cache_reset();
G.relbase_valid = 0;
if (!from_memory) {
- const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
+ const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
if (custom_file) {
BLI_strncpy(startstr, custom_file, FILE_MAX);
@@ -612,7 +619,7 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c
if (BLI_listbase_is_empty(&wmbase)) {
wm_clear_default_size(C);
}
- BLI_temp_dir_init(U.tempdir);
+ BKE_tempdir_init(U.tempdir);
#ifdef WITH_PYTHON_SECURITY
/* use alternative setting for security nuts
@@ -668,6 +675,8 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c
}
#endif
+ WM_operatortype_last_properties_clear_all();
+
/* important to do before NULL'ing the context */
BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_VERSION_UPDATE);
BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST);
@@ -723,7 +732,7 @@ void wm_read_history(void)
struct RecentFile *recent;
const char *line;
int num;
- const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
+ const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
if (!cfgdir) return;
@@ -760,7 +769,7 @@ static void write_history(void)
return;
/* will be NULL in background mode */
- user_config_dir = BLI_get_folder_create(BLENDER_USER_CONFIG, NULL);
+ user_config_dir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL);
if (!user_config_dir)
return;
@@ -837,11 +846,11 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt)
if (scene->camera) {
ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera,
BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, OB_SOLID, false, false, R_ADDSKY, err_out);
+ IB_rect, OB_SOLID, false, false, false, R_ALPHAPREMUL, err_out);
}
else {
ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2,
- IB_rect, false, R_ADDSKY, err_out);
+ IB_rect, false, R_ALPHAPREMUL, err_out);
}
if (ibuf) {
@@ -1011,6 +1020,8 @@ int wm_homefile_write_exec(bContext *C, wmOperator *op)
char filepath[FILE_MAX];
int fileflags;
+ BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE);
+
/* check current window and close it if temp */
if (win && win->screen->temp)
wm_window_close(C, wm, win);
@@ -1018,7 +1029,7 @@ int wm_homefile_write_exec(bContext *C, wmOperator *op)
/* update keymaps in user preferences */
WM_keyconfig_update(wm);
- BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
+ BLI_make_file_string("/", filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
printf("trying to save homefile at %s ", filepath);
ED_editors_flush_edits(C, false);
@@ -1035,6 +1046,8 @@ int wm_homefile_write_exec(bContext *C, wmOperator *op)
G.save_over = 0;
+ BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_POST);
+
return OPERATOR_FINISHED;
}
@@ -1047,7 +1060,7 @@ int wm_userpref_write_exec(bContext *C, wmOperator *op)
/* update keymaps in user preferences */
WM_keyconfig_update(wm);
- BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_USERPREF_FILE);
+ BLI_make_file_string("/", filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_USERPREF_FILE);
printf("trying to save userpref at %s ", filepath);
if (BKE_write_file_userdef(filepath, op->reports) == 0) {
@@ -1064,12 +1077,20 @@ int wm_userpref_write_exec(bContext *C, wmOperator *op)
void wm_autosave_location(char *filepath)
{
- char pidstr[32];
+ const int pid = abs(getpid());
+ char path[1024];
#ifdef WIN32
const char *savedir;
#endif
- BLI_snprintf(pidstr, sizeof(pidstr), "%d.blend", abs(getpid()));
+ if (G.main && G.relbase_valid) {
+ const char *basename = BLI_path_basename(G.main->name);
+ int len = strlen(basename) - 6;
+ BLI_snprintf(path, sizeof(path), "%.*s-%d.blend", len, basename, pid);
+ }
+ else {
+ BLI_snprintf(path, sizeof(path), "%d.blend", pid);
+ }
#ifdef WIN32
/* XXX Need to investigate how to handle default location of '/tmp/'
@@ -1080,14 +1101,14 @@ void wm_autosave_location(char *filepath)
* BLI_make_file_string will create string that has it most likely on C:\
* through get_default_root().
* If there is no C:\tmp autosave fails. */
- if (!BLI_exists(BLI_temp_dir_base())) {
- savedir = BLI_get_folder_create(BLENDER_USER_AUTOSAVE, NULL);
- BLI_make_file_string("/", filepath, savedir, pidstr);
+ if (!BLI_exists(BKE_tempdir_base())) {
+ savedir = BKE_appdir_folder_id_create(BLENDER_USER_AUTOSAVE, NULL);
+ BLI_make_file_string("/", filepath, savedir, path);
return;
}
#endif
- BLI_make_file_string("/", filepath, BLI_temp_dir_base(), pidstr);
+ BLI_make_file_string("/", filepath, BKE_tempdir_base(), path);
}
void WM_autosave_init(wmWindowManager *wm)
@@ -1151,7 +1172,7 @@ void wm_autosave_delete(void)
if (BLI_exists(filename)) {
char str[FILE_MAX];
- BLI_make_file_string("/", str, BLI_temp_dir_base(), BLENDER_QUIT_FILE);
+ BLI_make_file_string("/", str, BKE_tempdir_base(), BLENDER_QUIT_FILE);
/* if global undo; remove tempsave, otherwise rename */
if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, false, false);
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 3e287a3907b..46c3909f7bf 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -49,7 +49,6 @@
#include "WM_types.h"
#include "wm.h"
-#include "wm_event_system.h"
#include "wm_subwindow.h"
#include "wm_draw.h"
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index f762e19c969..9778f1651de 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -40,9 +40,6 @@
#include "MEM_guardedalloc.h"
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
#include "DNA_windowmanager_types.h"
@@ -68,6 +65,7 @@
#include "BKE_report.h"
#include "BKE_addon.h"
+#include "BKE_appdir.h"
#include "BKE_sequencer.h" /* free seq clipboard */
#include "BKE_material.h" /* clear_matcopybuf */
#include "BKE_tracking.h" /* free tracking clipboard */
@@ -98,6 +96,7 @@
#include "wm_window.h"
#include "ED_armature.h"
+#include "ED_gpencil.h"
#include "ED_keyframing.h"
#include "ED_node.h"
#include "ED_render.h"
@@ -110,7 +109,6 @@
#include "BLF_translation.h"
#include "GPU_buffers.h"
-#include "GPU_extensions.h"
#include "GPU_draw.h"
#include "GPU_init_exit.h"
@@ -172,6 +170,8 @@ void WM_init(bContext *C, int argc, const char **argv)
BLF_lang_set(NULL);
+ ED_spacemacros_init();
+
/* note: there is a bug where python needs initializing before loading the
* startup.blend because it may contain PyDrivers. It also needs to be after
* initializing space types and other internal data.
@@ -190,8 +190,6 @@ void WM_init(bContext *C, int argc, const char **argv)
(void)argv; /* unused */
#endif
- ED_spacemacros_init();
-
if (!G.background && !wm_start_with_console)
GHOST_toggleConsole(3);
@@ -219,7 +217,7 @@ void WM_init(bContext *C, int argc, const char **argv)
/* allow a path of "", this is what happens when making a new file */
#if 0
if (G.main->name[0] == 0)
- BLI_make_file_string("/", G.main->name, BLI_getDefaultDocumentFolder(), "untitled.blend");
+ BLI_make_file_string("/", G.main->name, BKE_appdir_folder_default(), "untitled.blend");
#endif
BLI_strncpy(G.lib, G.main->name, FILE_MAX);
@@ -414,7 +412,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
bool has_edited;
int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY);
- BLI_make_file_string("/", filename, BLI_temp_dir_base(), BLENDER_QUIT_FILE);
+ BLI_make_file_string("/", filename, BKE_tempdir_base(), BLENDER_QUIT_FILE);
has_edited = ED_editors_flush_edits(C, false);
@@ -478,6 +476,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
free_anim_copybuf();
free_anim_drivers_copybuf();
free_fmodifiers_copybuf();
+ ED_gpencil_strokes_copybuf_free();
ED_clipboard_posebuf_free();
BKE_node_clipboard_clear();
@@ -538,12 +537,15 @@ void WM_exit_ext(bContext *C, const bool do_python)
BLI_threadapi_exit();
if (MEM_get_memory_blocks_in_use() != 0) {
- printf("Error: Not freed memory blocks: %d\n", MEM_get_memory_blocks_in_use());
+ size_t mem_in_use = MEM_get_memory_in_use() + MEM_get_memory_in_use();
+ printf("Error: Not freed memory blocks: %d, total unfreed memory %f MB\n",
+ MEM_get_memory_blocks_in_use(),
+ (double)mem_in_use / 1024 / 1024);
MEM_printmemlist();
}
wm_autosave_delete();
- BLI_temp_dir_session_purge();
+ BKE_tempdir_session_purge();
}
void WM_exit(bContext *C)
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 74c504050ae..6bc858e861a 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -45,8 +45,6 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "wm_window.h"
-#include "wm_event_system.h"
#include "wm_event_types.h"
#include "wm.h"
@@ -630,17 +628,22 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
}
}
- /* on file load 'winactive' can be NULL, possibly it should not happen but for now do a NULL check - campbell */
- if (wm->winactive) {
- /* if there are running jobs, set the global progress indicator */
- if (jobs_progress > 0) {
- float progress = total_progress / (float)jobs_progress;
- WM_progress_set(wm->winactive, progress);
- }
- else {
- WM_progress_clear(wm->winactive);
- }
+
+ /* if there are running jobs, set the global progress indicator */
+ if (jobs_progress > 0) {
+ wmWindow *win;
+ float progress = total_progress / (float)jobs_progress;
+
+ for (win = wm->windows.first; win; win = win->next)
+ WM_progress_set(win, progress);
}
+ else {
+ wmWindow *win;
+
+ for (win = wm->windows.first; win; win = win->next)
+ WM_progress_clear(win);
+ }
+
}
bool WM_jobs_has_running(wmWindowManager *wm)
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index ff90de4b3c6..82e46c1b333 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -56,7 +56,6 @@
#include "WM_api.h"
#include "WM_types.h"
-#include "wm_window.h"
#include "wm_event_system.h"
#include "wm_event_types.h"
@@ -146,21 +145,15 @@ static void wm_keyconfig_properties_update_ot(ListBase *km_lb)
}
}
-static int wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b)
+static bool wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b)
{
- if (strcmp(a->idname, b->idname) != 0)
- return 0;
-
- if (!RNA_struct_equals(a->ptr, b->ptr, RNA_EQ_UNSET_MATCH_NONE))
- return 0;
-
- if ((a->flag & KMI_INACTIVE) != (b->flag & KMI_INACTIVE))
- return 0;
-
- return (a->propvalue == b->propvalue);
+ return (STREQ(a->idname, b->idname) &&
+ RNA_struct_equals(a->ptr, b->ptr, RNA_EQ_UNSET_MATCH_NONE) &&
+ (a->flag & KMI_INACTIVE) == (b->flag & KMI_INACTIVE) &&
+ a->propvalue == b->propvalue);
}
-static int wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b)
+static bool wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b)
{
return (wm_keymap_item_equals_result(a, b) &&
a->type == b->type &&
@@ -267,7 +260,7 @@ wmKeyConfig *WM_keyconfig_new_user(wmWindowManager *wm, const char *idname)
bool WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
{
if (BLI_findindex(&wm->keyconfigs, keyconf) != -1) {
- if (strncmp(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr)) == 0) {
+ if (STREQLEN(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr))) {
BLI_strncpy(U.keyconfigstr, wm->defaultconf->idname, sizeof(U.keyconfigstr));
WM_keyconfig_update_tag(NULL, NULL);
}
@@ -422,7 +415,7 @@ wmKeyMapItem *WM_keymap_verify_item(wmKeyMap *keymap, const char *idname, int ty
wmKeyMapItem *kmi;
for (kmi = keymap->items.first; kmi; kmi = kmi->next)
- if (strncmp(kmi->idname, idname, OP_MAX_TYPENAME) == 0)
+ if (STREQLEN(kmi->idname, idname, OP_MAX_TYPENAME))
break;
if (kmi == NULL) {
kmi = MEM_callocN(sizeof(wmKeyMapItem), "keymap entry");
@@ -729,7 +722,7 @@ wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int
for (km = lb->first; km; km = km->next)
if (km->spaceid == spaceid && km->regionid == regionid)
- if (0 == strncmp(idname, km->idname, KMAP_MAX_NAME))
+ if (STREQLEN(idname, km->idname, KMAP_MAX_NAME))
return km;
return NULL;
@@ -788,7 +781,7 @@ wmKeyMap *WM_modalkeymap_get(wmKeyConfig *keyconf, const char *idname)
for (km = keyconf->keymaps.first; km; km = km->next)
if (km->flag & KEYMAP_MODAL)
- if (0 == strncmp(idname, km->idname, KMAP_MAX_NAME))
+ if (STREQLEN(idname, km->idname, KMAP_MAX_NAME))
break;
return km;
@@ -953,18 +946,17 @@ static wmKeyMapItem *wm_keymap_item_find_handlers(
if (kmi->flag & KMI_INACTIVE)
continue;
- if (strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0]) {
+ if (STREQ(kmi->idname, opname) && WM_key_event_string(kmi->type)[0]) {
if (is_hotkey) {
if (!ISHOTKEY(kmi->type))
continue;
}
if (properties) {
-
/* example of debugging keymaps */
#if 0
if (kmi->ptr) {
- if (strcmp("MESH_OT_rip_move", opname) == 0) {
+ if (STREQ("MESH_OT_rip_move", opname)) {
printf("OPERATOR\n");
IDP_spit(properties);
printf("KEYMAP\n");
@@ -977,6 +969,39 @@ static wmKeyMapItem *wm_keymap_item_find_handlers(
if (keymap_r) *keymap_r = keymap;
return kmi;
}
+ /* Debug only, helps spotting mismatches between menu entries and shortcuts! */
+ else if (G.debug & G_DEBUG_WM) {
+ if (is_strict && kmi->ptr) {
+ wmOperatorType *ot = WM_operatortype_find(opname, true);
+ if (ot) {
+ /* make a copy of the properties and set unset ones to their default values. */
+ PointerRNA opptr;
+ IDProperty *properties_default = IDP_CopyProperty(kmi->ptr->data);
+
+ RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
+ WM_operator_properties_default(&opptr, true);
+
+ if (IDP_EqualsProperties_ex(properties, properties_default, is_strict)) {
+ char kmi_str[128];
+ WM_keymap_item_to_string(kmi, kmi_str, sizeof(kmi_str));
+ /* Note gievn properties could come from other things than menu entry... */
+ printf("%s: Some set values in menu entry match default op values, "
+ "this might not be desired!\n", opname);
+ printf("\tkm: '%s', kmi: '%s'\n", keymap->idname, kmi_str);
+#ifndef NDEBUG
+ printf("OPERATOR\n");
+ IDP_spit(properties);
+ printf("KEYMAP\n");
+ IDP_spit(kmi->ptr->data);
+#endif
+ printf("\n");
+ }
+
+ IDP_FreeProperty(properties_default);
+ MEM_freeN(properties_default);
+ }
+ }
+ }
}
else {
if (keymap_r) *keymap_r = keymap;
@@ -1043,33 +1068,83 @@ static wmKeyMapItem *wm_keymap_item_find_props(
static wmKeyMapItem *wm_keymap_item_find(
const bContext *C, const char *opname, int opcontext,
- IDProperty *properties, const bool is_hotkey, const bool is_strict, wmKeyMap **keymap_r)
+ IDProperty *properties, const bool is_hotkey, bool is_strict, wmKeyMap **keymap_r)
{
- wmKeyMapItem *found = wm_keymap_item_find_props(C, opname, opcontext, properties, is_strict, is_hotkey, keymap_r);
+ wmKeyMapItem *found;
+ /* XXX Hack! Macro operators in menu entry have their whole props defined, which is not the case for
+ * relevant keymap entries. Could be good to check and harmonize this, but for now always
+ * compare non-strict in this case.
+ */
+ wmOperatorType *ot = WM_operatortype_find(opname, true);
+ if (ot) {
+ is_strict = is_strict && ((ot->flag & OPTYPE_MACRO) == 0);
+ }
+
+ found = wm_keymap_item_find_props(C, opname, opcontext, properties, is_strict, is_hotkey, keymap_r);
+
+ /* This block is *only* useful in one case: when op uses an enum menu in its prop member
+ * (then, we want to rerun a comparison with that 'prop' unset). Note this remains brittle,
+ * since now any enum prop may be used in UI (specified by name), ot->prop is not so much used...
+ * Otherwise:
+ * * If non-strict, unset properties always match set ones in IDP_EqualsProperties_ex.
+ * * If strict, unset properties never match set ones in IDP_EqualsProperties_ex,
+ * and we do not want that to change (else we get things like T41757)!
+ * ...so in either case, re-running a comparison with unset props set to default is useless.
+ */
if (!found && properties) {
- wmOperatorType *ot = WM_operatortype_find(opname, true);
- if (ot) {
- /* make a copy of the properties and set any unset props
- * to their default values, so the ID property compare function succeeds */
+ if (ot && ot->prop) { /* XXX Shall we also check ot->prop is actually an enum? */
+ /* make a copy of the properties and unset the 'ot->prop' one if set. */
PointerRNA opptr;
- IDProperty *properties_default = IDP_CopyProperty(properties);
+ IDProperty *properties_temp = IDP_CopyProperty(properties);
- RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
+ RNA_pointer_create(NULL, ot->srna, properties_temp, &opptr);
- if (WM_operator_properties_default(&opptr, true) ||
- (!is_strict && ot->prop && RNA_property_is_set(&opptr, ot->prop)))
- {
- /* for operator that has enum menu, unset it so it always matches */
- if (!is_strict && ot->prop) {
- RNA_property_unset(&opptr, ot->prop);
- }
+ if (RNA_property_is_set(&opptr, ot->prop)) {
+ /* for operator that has enum menu, unset it so its value does not affect comparison result */
+ RNA_property_unset(&opptr, ot->prop);
- found = wm_keymap_item_find_props(C, opname, opcontext, properties_default, false, is_hotkey, keymap_r);
+ found = wm_keymap_item_find_props(C, opname, opcontext, properties_temp,
+ is_strict, is_hotkey, keymap_r);
}
- IDP_FreeProperty(properties_default);
- MEM_freeN(properties_default);
+ IDP_FreeProperty(properties_temp);
+ MEM_freeN(properties_temp);
+ }
+ }
+
+ /* Debug only, helps spotting mismatches between menu entries and shortcuts! */
+ if (G.debug & G_DEBUG_WM) {
+ if (!found && is_strict && properties) {
+ wmKeyMap *km;
+ wmKeyMapItem *kmi;
+ if (ot) {
+ /* make a copy of the properties and set unset ones to their default values. */
+ PointerRNA opptr;
+ IDProperty *properties_default = IDP_CopyProperty(properties);
+
+ RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
+ WM_operator_properties_default(&opptr, true);
+
+ kmi = wm_keymap_item_find_props(C, opname, opcontext, properties_default, is_strict, is_hotkey, &km);
+ if (kmi) {
+ char kmi_str[128];
+ WM_keymap_item_to_string(kmi, kmi_str, sizeof(kmi_str));
+ printf("%s: Some set values in keymap entry match default op values, "
+ "this might not be desired!\n", opname);
+ printf("\tkm: '%s', kmi: '%s'\n", km->idname, kmi_str);
+#ifndef NDEBUG
+ printf("OPERATOR\n");
+ IDP_spit(properties);
+ printf("KEYMAP\n");
+ IDP_spit(kmi->ptr->data);
+#endif
+ printf("\n");
+ }
+
+ IDP_FreeProperty(properties_default);
+ MEM_freeN(properties_default);
+ }
}
}
@@ -1354,7 +1429,7 @@ void WM_keymap_restore_item_to_default(bContext *C, wmKeyMap *keymap, wmKeyMapIt
if (orig) {
/* restore to original */
- if (strcmp(orig->idname, kmi->idname) != 0) {
+ if (!STREQ(orig->idname, kmi->idname)) {
BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname));
WM_keymap_properties_reset(kmi, NULL);
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 68aad2dbda6..6f9646f35a1 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -38,8 +38,11 @@
#include <stdio.h>
#include <stddef.h>
#include <assert.h>
+#include <errno.h>
-#include "GHOST_C-api.h"
+#ifdef WIN32
+# include "GHOST_C-api.h"
+#endif
#include "MEM_guardedalloc.h"
@@ -58,12 +61,14 @@
#include "BLI_blenlib.h"
#include "BLI_dial.h"
#include "BLI_dynstr.h" /*for WM_operator_pystring */
+#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLO_readfile.h"
+#include "BKE_appdir.h"
#include "BKE_autoexec.h"
#include "BKE_blender.h"
#include "BKE_brush.h"
@@ -72,12 +77,14 @@
#include "BKE_idprop.h"
#include "BKE_image.h"
#include "BKE_library.h"
+#include "BKE_library_query.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h" /* BKE_ST_MAXNAME */
+#include "BKE_unit.h"
#include "BKE_utildefines.h"
#include "BKE_idcode.h"
@@ -90,15 +97,19 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "ED_numinput.h"
#include "ED_screen.h"
#include "ED_util.h"
#include "ED_view3d.h"
+#include "GPU_material.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "UI_interface.h"
+#include "UI_interface_icons.h"
#include "UI_resources.h"
#include "WM_api.h"
@@ -147,9 +158,9 @@ wmOperatorType *WM_operatortype_find(const char *idname, bool quiet)
}
/* caller must free */
-GHashIterator *WM_operatortype_iter(void)
+void WM_operatortype_iter(GHashIterator *ghi)
{
- return BLI_ghashIterator_new(global_ops_hash);
+ BLI_ghashIterator_init(ghi, global_ops_hash);
}
/* all ops in 1 list (for time being... needs evaluation later) */
@@ -494,6 +505,27 @@ bool WM_operatortype_remove(const char *idname)
return true;
}
+/**
+ * Remove memory of all previously executed tools.
+ */
+void WM_operatortype_last_properties_clear_all(void)
+{
+ GHashIterator iter;
+
+ for (WM_operatortype_iter(&iter);
+ (!BLI_ghashIterator_done(&iter));
+ (BLI_ghashIterator_step(&iter)))
+ {
+ wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
+
+ if (ot->last_properties) {
+ IDP_FreeProperty(ot->last_properties);
+ MEM_freeN(ot->last_properties);
+ ot->last_properties = NULL;
+ }
+ }
+}
+
/* SOME_OT_op -> some.op */
void WM_operator_py_idname(char *to, const char *from)
{
@@ -1052,12 +1084,13 @@ int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
return retval;
}
else {
- pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
/* set this so the default execution context is the same as submenus */
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
uiItemsFullEnumO(layout, op->type->idname, RNA_property_identifier(prop), op->ptr->data, WM_OP_EXEC_REGION_WIN, 0);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
+ return OPERATOR_INTERFACE;
}
return OPERATOR_CANCELLED;
@@ -1074,19 +1107,19 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
uiBut *but;
wmOperator *op = (wmOperator *)arg_op;
- block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
- uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
#if 0 /* ok, this isn't so easy... */
- uiDefBut(block, LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
#endif
but = uiDefSearchButO_ptr(block, op->type, op->ptr->data, search, 0, ICON_VIEWZOOM, sizeof(search),
- 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, 0, 0, "");
+ 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, 0, 0, "");
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
- uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
+ UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
@@ -1101,8 +1134,8 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- uiPupBlock(C, wm_enum_search_menu, op);
- return OPERATOR_CANCELLED;
+ UI_popup_block_invoke(C, wm_enum_search_menu, op);
+ return OPERATOR_INTERFACE;
}
/* Can't be used as an invoke directly, needs message arg (can be NULL) */
@@ -1119,12 +1152,12 @@ int WM_operator_confirm_message_ex(bContext *C, wmOperator *op,
else
properties = NULL;
- pup = uiPupMenuBegin(C, title, icon);
- layout = uiPupMenuLayout(pup);
+ pup = UI_popup_menu_begin(C, title, icon);
+ layout = UI_popup_menu_layout(pup);
uiItemFullO_ptr(layout, op->type, message, ICON_NONE, properties, WM_OP_EXEC_REGION_WIN, 0);
- uiPupMenuEnd(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
int WM_operator_confirm_message(bContext *C, wmOperator *op, const char *message)
@@ -1156,7 +1189,7 @@ bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFor
/* dont NULL check prop, this can only run on ops with a 'filepath' */
prop = RNA_struct_find_property(op->ptr, "filepath");
RNA_property_string_get(op->ptr, prop, filepath);
- if (BKE_add_image_extension(filepath, im_format)) {
+ if (BKE_image_path_ensure_ext_from_imformat(filepath, im_format)) {
RNA_property_string_set(op->ptr, prop, filepath);
/* note, we could check for and update 'filename' here,
* but so far nothing needs this. */
@@ -1194,31 +1227,32 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type,
if (action == FILE_SAVE) {
/* note, this is only used to check if we should highlight the filename area red when the
* filepath is an existing file. */
- prop = RNA_def_boolean(ot->srna, "check_existing", 1, "Check Existing", "Check and warn on overwriting existing files");
+ prop = RNA_def_boolean(ot->srna, "check_existing", true, "Check Existing",
+ "Check and warn on overwriting existing files");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
- prop = RNA_def_boolean(ot->srna, "filter_blender", (filter & BLENDERFILE), "Filter .blend files", "");
+ prop = RNA_def_boolean(ot->srna, "filter_blender", (filter & FILE_TYPE_BLENDER) != 0, "Filter .blend files", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "filter_backup", (filter & BLENDERFILE_BACKUP), "Filter .blend files", "");
+ prop = RNA_def_boolean(ot->srna, "filter_backup", (filter & FILE_TYPE_BLENDER_BACKUP) != 0, "Filter .blend files", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "filter_image", (filter & IMAGEFILE), "Filter image files", "");
+ prop = RNA_def_boolean(ot->srna, "filter_image", (filter & FILE_TYPE_IMAGE) != 0, "Filter image files", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "filter_movie", (filter & MOVIEFILE), "Filter movie files", "");
+ prop = RNA_def_boolean(ot->srna, "filter_movie", (filter & FILE_TYPE_MOVIE) != 0, "Filter movie files", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "filter_python", (filter & PYSCRIPTFILE), "Filter python files", "");
+ prop = RNA_def_boolean(ot->srna, "filter_python", (filter & FILE_TYPE_PYSCRIPT) != 0, "Filter python files", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "filter_font", (filter & FTFONTFILE), "Filter font files", "");
+ prop = RNA_def_boolean(ot->srna, "filter_font", (filter & FILE_TYPE_FTFONT) != 0, "Filter font files", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "filter_sound", (filter & SOUNDFILE), "Filter sound files", "");
+ prop = RNA_def_boolean(ot->srna, "filter_sound", (filter & FILE_TYPE_SOUND) != 0, "Filter sound files", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", "");
+ prop = RNA_def_boolean(ot->srna, "filter_text", (filter & FILE_TYPE_TEXT) != 0, "Filter text files", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "filter_btx", (filter & BTXFILE), "Filter btx files", "");
+ prop = RNA_def_boolean(ot->srna, "filter_btx", (filter & FILE_TYPE_BTX) != 0, "Filter btx files", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "filter_collada", (filter & COLLADAFILE), "Filter COLLADA files", "");
+ prop = RNA_def_boolean(ot->srna, "filter_collada", (filter & FILE_TYPE_COLLADA) != 0, "Filter COLLADA files", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", "");
+ prop = RNA_def_boolean(ot->srna, "filter_folder", (filter & FILE_TYPE_FOLDER) != 0, "Filter folders", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_int(ot->srna, "filemode", type, FILE_LOADLIB, FILE_SPECIAL,
@@ -1307,7 +1341,7 @@ void WM_operator_properties_gesture_border(wmOperatorType *ot, bool extend)
WM_operator_properties_border(ot);
if (extend) {
- RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection instead of deselecting everything first");
}
}
@@ -1315,11 +1349,12 @@ void WM_operator_properties_mouse_select(wmOperatorType *ot)
{
PropertyRNA *prop;
- prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first");
+ prop = RNA_def_boolean(ot->srna, "extend", false, "Extend",
+ "Extend selection instead of deselecting everything first");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Remove from selection");
+ prop = RNA_def_boolean(ot->srna, "deselect", false, "Deselect", "Remove from selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "toggle", 0, "Toggle Selection", "Toggle the selection");
+ prop = RNA_def_boolean(ot->srna, "toggle", false, "Toggle Selection", "Toggle the selection");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -1373,6 +1408,64 @@ wmOperator *WM_operator_last_redo(const bContext *C)
return op;
}
+/**
+ * Use for drag & drop a path or name with operators invoke() function.
+ */
+ID *WM_operator_drop_load_path(struct bContext *C, wmOperator *op, const short idcode)
+{
+ ID *id = NULL;
+ /* check input variables */
+ if (RNA_struct_property_is_set(op->ptr, "filepath")) {
+ const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
+ char path[FILE_MAX];
+ bool exists = false;
+
+ RNA_string_get(op->ptr, "filepath", path);
+
+ errno = 0;
+
+ if (idcode == ID_IM) {
+ id = (ID *)BKE_image_load_exists_ex(path, &exists);
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ if (!id) {
+ BKE_reportf(op->reports, RPT_ERROR, "Cannot read %s '%s': %s",
+ BKE_idcode_to_name(idcode), path,
+ errno ? strerror(errno) : TIP_("unsupported format"));
+ return NULL;
+ }
+
+ if (is_relative_path ) {
+ if (exists == false) {
+ Main *bmain = CTX_data_main(C);
+
+ if (idcode == ID_IM) {
+ BLI_path_rel(((Image *)id)->name, bmain->name);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ }
+ }
+ else if (RNA_struct_property_is_set(op->ptr, "name")) {
+ char name[MAX_ID_NAME - 2];
+ RNA_string_get(op->ptr, "name", name);
+ id = BKE_libblock_find_name(idcode, name);
+ if (!id) {
+ BKE_reportf(op->reports, RPT_ERROR, "%s '%s' not found",
+ BKE_idcode_to_name(idcode), name);
+ return NULL;
+ }
+ id_us_plus(id);
+ }
+
+ return id;
+}
+
static void wm_block_redo_cb(bContext *C, void *arg_op, int UNUSED(arg_event))
{
wmOperator *op = arg_op;
@@ -1404,19 +1497,19 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
wmOperator *op = arg_op;
uiBlock *block;
uiLayout *layout;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
int width = 15 * UI_UNIT_X;
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
- uiBlockClearFlag(block, UI_BLOCK_LOOP);
- uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ UI_block_flag_disable(block, UI_BLOCK_LOOP);
+ UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT);
/* if register is not enabled, the operator gets freed on OPERATOR_FINISHED
* ui_apply_but_funcs_after calls ED_undo_operator_repeate_cb and crashes */
assert(op->type->flag & OPTYPE_REGISTER);
- uiBlockSetHandleFunc(block, wm_block_redo_cb, arg_op);
- layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, UI_UNIT_Y, 0, style);
+ UI_block_func_handle_set(block, wm_block_redo_cb, arg_op);
+ layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, UI_UNIT_Y, 0, style);
if (op == WM_operator_last_redo(C))
if (!WM_operator_check_ui_enabled(C, op->type->name))
@@ -1431,7 +1524,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
}
- uiPopupBoundsBlock(block, 4, 0, 0);
+ UI_block_bounds_set_popup(block, 4, 0, 0);
return block;
}
@@ -1458,7 +1551,7 @@ static void dialog_exec_cb(bContext *C, void *arg1, void *arg2)
/* in this case, wm_operator_ui_popup_cancel wont run */
MEM_freeN(data);
- uiPupBlockClose(C, block);
+ UI_popup_block_close(C, block);
}
static void dialog_check_cb(bContext *C, void *op_ptr, void *UNUSED(arg))
@@ -1482,23 +1575,23 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
wmOperator *op = data->op;
uiBlock *block;
uiLayout *layout;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
- uiBlockClearFlag(block, UI_BLOCK_LOOP);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ UI_block_flag_disable(block, UI_BLOCK_LOOP);
/* intentionally don't use 'UI_BLOCK_MOVEMOUSE_QUIT', some dialogues have many items
* where quitting by accident is very annoying */
- uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN);
+ UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN);
- layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
+ layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
- uiBlockSetFunc(block, dialog_check_cb, op, NULL);
+ UI_block_func_set(block, dialog_check_cb, op, NULL);
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
/* clear so the OK button is left alone */
- uiBlockSetFunc(block, NULL, NULL, NULL);
+ UI_block_func_set(block, NULL, NULL, NULL);
/* new column so as not to interfere with custom layouts [#26436] */
{
@@ -1509,12 +1602,12 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
col = uiLayoutColumn(layout, false);
col_block = uiLayoutGetBlock(col);
/* Create OK button, the callback of which will execute op */
- btn = uiDefBut(col_block, BUT, 0, IFACE_("OK"), 0, -30, 0, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- uiButSetFunc(btn, dialog_exec_cb, data, col_block);
+ btn = uiDefBut(col_block, UI_BTYPE_BUT, 0, IFACE_("OK"), 0, -30, 0, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ UI_but_func_set(btn, dialog_exec_cb, data, col_block);
}
/* center around the mouse */
- uiPopupBoundsBlock(block, 4, data->width / -2, data->height / 2);
+ UI_block_bounds_set_popup(block, 4, data->width / -2, data->height / 2);
return block;
}
@@ -1525,18 +1618,18 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
wmOperator *op = data->op;
uiBlock *block;
uiLayout *layout;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
- block = uiBeginBlock(C, ar, __func__, UI_EMBOSS);
- uiBlockClearFlag(block, UI_BLOCK_LOOP);
- uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT);
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ UI_block_flag_disable(block, UI_BLOCK_LOOP);
+ UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT);
- layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
+ layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
/* since ui is defined the auto-layout args are not used */
uiLayoutOperatorButs(C, layout, op, NULL, 'V', 0);
- uiPopupBoundsBlock(block, 4, 0, 0);
+ UI_block_bounds_set_popup(block, 4, 0, 0);
return block;
}
@@ -1577,14 +1670,14 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
data->width = width;
data->height = height;
data->free_op = true; /* if this runs and gets registered we may want not to free it */
- uiPupBlockEx(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data);
+ UI_popup_block_ex(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data);
return OPERATOR_RUNNING_MODAL;
}
/**
* For use by #WM_operator_props_popup_call, #WM_operator_props_popup only.
*
- * \note operator menu needs undo flag enabled , for redo callback */
+ * \note operator menu needs undo flag enabled, for redo callback */
static int wm_operator_props_popup_ex(bContext *C, wmOperator *op,
const bool do_call, const bool do_redo)
{
@@ -1607,7 +1700,7 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op,
if (!do_redo || !(U.uiflag & USER_GLOBALUNDO))
return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y);
- uiPupBlockEx(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op);
+ UI_popup_block_ex(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op);
if (do_call)
wm_block_redo_cb(C, op, 0);
@@ -1647,7 +1740,7 @@ int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int h
data->free_op = true; /* if this runs and gets registered we may want not to free it */
/* op is not executed until popup OK but is clicked */
- uiPupBlockEx(C, wm_block_dialog_create, wm_operator_ui_popup_ok, wm_operator_ui_popup_cancel, data);
+ UI_popup_block_ex(C, wm_block_dialog_create, wm_operator_ui_popup_ok, wm_operator_ui_popup_cancel, data);
return OPERATOR_RUNNING_MODAL;
}
@@ -1665,7 +1758,7 @@ int WM_operator_redo_popup(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- uiPupBlock(C, wm_block_create_redo, op);
+ UI_popup_block_invoke(C, wm_block_create_redo, op);
return OPERATOR_CANCELLED;
}
@@ -1730,7 +1823,7 @@ static void WM_OT_operator_defaults(wmOperatorType *ot)
static void wm_block_splash_close(bContext *C, void *arg_block, void *UNUSED(arg))
{
- uiPupBlockClose(C, arg_block);
+ UI_popup_block_close(C, arg_block);
}
static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *arg_unused);
@@ -1742,22 +1835,22 @@ static void wm_block_splash_refreshmenu(bContext *UNUSED(C), void *UNUSED(arg_bl
/* ugh, causes crashes in other buttons, disabling for now until
* a better fix */
#if 0
- uiPupBlockClose(C, arg_block);
- uiPupBlock(C, wm_block_create_splash, NULL);
+ UI_popup_block_close(C, arg_block);
+ UI_popup_block_invoke(C, wm_block_create_splash, NULL);
#endif
}
static int wm_resource_check_prev(void)
{
- const char *res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, true);
+ const char *res = BKE_appdir_folder_id_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, true);
// if (res) printf("USER: %s\n", res);
#if 0 /* ignore the local folder */
if (res == NULL) {
/* with a local dir, copying old files isn't useful since local dir get priority for config */
- res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, true);
+ res = BKE_appdir_folder_id_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, true);
}
#endif
@@ -1766,7 +1859,7 @@ static int wm_resource_check_prev(void)
return false;
}
else {
- return (BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, true) != NULL);
+ return (BKE_appdir_folder_id_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, true) != NULL);
}
}
@@ -1775,7 +1868,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiBlock *block;
uiBut *but;
uiLayout *layout, *split, *col;
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
const struct RecentFile *recent;
int i;
MenuType *mt = WM_menutype_find("USERPREF_MT_splash", true);
@@ -1821,17 +1914,17 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
}
#endif
- block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
/* note on UI_BLOCK_NO_WIN_CLIP, the window size is not always synchronized
* with the OS when the splash shows, window clipping in this case gives
* ugly results and clipping the splash isn't useful anyway, just disable it [#32938] */
- uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP);
+ UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP);
/* XXX splash scales with pixelsize, should become widget-units */
- but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize * 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */
- uiButSetFunc(but, wm_block_splash_close, block, NULL);
- uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL);
+ but = uiDefBut(block, UI_BTYPE_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize * 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */
+ UI_but_func_set(but, wm_block_splash_close, block, NULL);
+ UI_block_func_set(block, wm_block_splash_refreshmenu, block, NULL);
/* label for 'a' bugfix releases, or 'Release Candidate 1'...
* avoids recreating splash for version updates */
@@ -1849,32 +1942,32 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
int w = 240;
/* hack to have text draw 'text_sel' */
- uiBlockSetEmboss(block, UI_EMBOSSN);
- but = uiDefBut(block, LABEL, 0, version_suffix, x * U.pixelsize, y * U.pixelsize, w * U.pixelsize, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, version_suffix, x * U.pixelsize, y * U.pixelsize, w * U.pixelsize, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
/* XXX, set internal flag - UI_SELECT */
- uiButSetFlag(but, 1);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_but_flag_enable(but, 1);
+ UI_block_emboss_set(block, UI_EMBOSS);
}
#ifdef WITH_BUILDINFO
if (build_commit_timestamp != 0) {
- uiDefBut(block, LABEL, 0, date_buf, U.pixelsize * 494 - date_width, U.pixelsize * 270, date_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, date_buf, U.pixelsize * 494 - date_width, U.pixelsize * 270, date_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
label_delta = 12;
}
- uiDefBut(block, LABEL, 0, hash_buf, U.pixelsize * 494 - hash_width, U.pixelsize * (270 - label_delta), hash_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, hash_buf, U.pixelsize * 494 - hash_width, U.pixelsize * (270 - label_delta), hash_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
if (!STREQ(build_branch, "master")) {
char branch_buf[128] = "\0";
int branch_width;
BLI_snprintf(branch_buf, sizeof(branch_buf), "Branch: %s", build_branch);
branch_width = (int)BLF_width(style->widgetlabel.uifont_id, branch_buf, sizeof(branch_buf)) + U.widget_unit;
- uiDefBut(block, LABEL, 0, branch_buf, U.pixelsize * 494 - branch_width, U.pixelsize * (258 - label_delta), branch_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, branch_buf, U.pixelsize * 494 - branch_width, U.pixelsize * (258 - label_delta), branch_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
}
#endif /* WITH_BUILDINFO */
- layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, 0, style);
+ layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, 0, style);
- uiBlockSetEmboss(block, UI_EMBOSS);
+ UI_block_emboss_set(block, UI_EMBOSS);
/* show the splash menu (containing interaction presets), using python */
if (mt) {
Menu menu = {NULL};
@@ -1886,7 +1979,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
// uiItemM(layout, C, "USERPREF_MT_keyconfigs", U.keyconfigstr, ICON_NONE);
}
- uiBlockSetEmboss(block, UI_EMBOSSP);
+ UI_block_emboss_set(block, UI_EMBOSS_PULLDOWN);
uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN);
split = uiLayoutSplit(layout, 0.0f, false);
@@ -1902,7 +1995,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
BLENDER_VERSION / 100, BLENDER_VERSION % 100);
uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url", url);
uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url",
- "http://wiki.blender.org/index.php/Doc:2.6/Manual");
+ "http://www.blender.org/manual");
uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org");
if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) {
BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d"
@@ -1935,14 +2028,22 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiItemO(col, NULL, ICON_RECOVER_LAST, "WM_OT_recover_last_session");
uiItemL(col, "", ICON_NONE);
- uiCenteredBoundsBlock(block, 0);
+ mt = WM_menutype_find("USERPREF_MT_splash_footer", false);
+ if (mt) {
+ Menu menu = {NULL};
+ menu.layout = uiLayoutColumn(layout, false);
+ menu.type = mt;
+ mt->draw(C, &menu);
+ }
+
+ UI_block_bounds_set_centered(block, 0);
return block;
}
static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
- uiPupBlock(C, wm_block_create_splash, NULL);
+ UI_popup_block_invoke(C, wm_block_create_splash, NULL);
return OPERATOR_FINISHED;
}
@@ -1967,16 +2068,16 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_
uiBlock *block;
uiBut *but;
- block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
- uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, 0, 0, "");
- uiOperatorSearch_But(but);
+ but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, 0, 0, "");
+ UI_but_func_operator_search(but);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
- uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
+ UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
wm_event_init_from_window(win, &event);
event.type = EVT_BUT_OPEN;
@@ -1995,9 +2096,9 @@ static int wm_search_menu_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
static int wm_search_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- uiPupBlock(C, wm_block_search_menu, op);
+ UI_popup_block_invoke(C, wm_block_search_menu, op);
- return OPERATOR_CANCELLED;
+ return OPERATOR_INTERFACE;
}
/* op->poll */
@@ -2036,9 +2137,7 @@ static int wm_call_menu_exec(bContext *C, wmOperator *op)
char idname[BKE_ST_MAXNAME];
RNA_string_get(op->ptr, "name", idname);
- uiPupMenuInvoke(C, idname, op->reports);
-
- return OPERATOR_CANCELLED;
+ return UI_popup_menu_invoke(C, idname, op->reports);
}
static void WM_OT_call_menu(wmOperatorType *ot)
@@ -2060,9 +2159,7 @@ static int wm_call_pie_menu_invoke(bContext *C, wmOperator *op, const wmEvent *e
char idname[BKE_ST_MAXNAME];
RNA_string_get(op->ptr, "name", idname);
- uiPieMenuInvoke(C, idname, event);
-
- return OPERATOR_CANCELLED;
+ return UI_pie_menu_invoke(C, idname, event);
}
static int wm_call_pie_menu_exec(bContext *C, wmOperator *op)
@@ -2070,9 +2167,7 @@ static int wm_call_pie_menu_exec(bContext *C, wmOperator *op)
char idname[BKE_ST_MAXNAME];
RNA_string_get(op->ptr, "name", idname);
- uiPieMenuInvoke(C, idname, CTX_wm_window(C)->eventstate);
-
- return OPERATOR_CANCELLED;
+ return UI_pie_menu_invoke(C, idname, CTX_wm_window(C)->eventstate);
}
static void WM_OT_call_menu_pie(wmOperatorType *ot)
@@ -2374,7 +2469,7 @@ static void WM_OT_open_mainfile(wmOperatorType *ot)
ot->ui = wm_open_mainfile_ui;
/* omit window poll so this can work in background mode */
- WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_BLENDER, FILE_OPENFILE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
RNA_def_boolean(ot->srna, "load_ui", true, "Load UI", "Load user interface setup in the .blend file");
@@ -2561,6 +2656,13 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
lib = mainl->curlib;
BLI_assert(lib);
+ if (mainl->versionfile < 250) {
+ BKE_reportf(op->reports, RPT_WARNING,
+ "Linking or appending from a very old .blend file format (%d.%d), no animation conversion will "
+ "be done! You may want to re-save your lib file with current Blender",
+ mainl->versionfile, mainl->subversionfile);
+ }
+
if (totfiles == 0) {
BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag);
}
@@ -2590,7 +2692,9 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* recreate dependency graph to include new objects */
DAG_scene_relations_rebuild(bmain, scene);
-
+
+ /* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */
+ GPU_materials_free();
BLO_blendhandle_close(bh);
/* XXX TODO: align G.lib with other directory storage (like last opened image etc...) */
@@ -2634,7 +2738,7 @@ static void WM_OT_link(wmOperatorType *ot)
ot->flag |= OPTYPE_UNDO;
WM_operator_properties_filesel(
- ot, FOLDERFILE | BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE,
+ ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_LOADLIB, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_RELPATH | WM_FILESEL_FILES,
FILE_DEFAULTDISPLAY);
@@ -2654,7 +2758,7 @@ static void WM_OT_append(wmOperatorType *ot)
ot->flag |= OPTYPE_UNDO;
WM_operator_properties_filesel(
- ot, FOLDERFILE | BLENDERFILE, FILE_LOADLIB, FILE_OPENFILE,
+ ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_LOADLIB, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_FILES,
FILE_DEFAULTDISPLAY);
@@ -2667,7 +2771,7 @@ void WM_recover_last_session(bContext *C, ReportList *reports)
{
char filepath[FILE_MAX];
- BLI_make_file_string("/", filepath, BLI_temp_dir_base(), BLENDER_QUIT_FILE);
+ BLI_make_file_string("/", filepath, BKE_tempdir_base(), BLENDER_QUIT_FILE);
/* if reports==NULL, it's called directly without operator, we add a quick check here */
if (reports || BLI_exists(filepath)) {
G.fileflags |= G_FILE_RECOVER;
@@ -2746,7 +2850,7 @@ static void WM_OT_recover_auto_save(wmOperatorType *ot)
ot->exec = wm_recover_auto_save_exec;
ot->invoke = wm_recover_auto_save_invoke;
- WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER, FILE_OPENFILE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_BLENDER, FILE_BLENDER, FILE_OPENFILE,
WM_FILESEL_FILEPATH, FILE_LONGDISPLAY);
}
@@ -2763,9 +2867,9 @@ static void save_set_compress(wmOperator *op)
{
if (!RNA_struct_property_is_set(op->ptr, "compress")) {
if (G.save_over) /* keep flag for existing file */
- RNA_boolean_set(op->ptr, "compress", G.fileflags & G_FILE_COMPRESS);
+ RNA_boolean_set(op->ptr, "compress", (G.fileflags & G_FILE_COMPRESS) != 0);
else /* use userdef for new file */
- RNA_boolean_set(op->ptr, "compress", U.flag & USER_FILECOMPRESS);
+ RNA_boolean_set(op->ptr, "compress", (U.flag & USER_FILECOMPRESS) != 0);
}
}
@@ -2824,6 +2928,8 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
(RNA_struct_find_property(op->ptr, "use_mesh_compat") &&
RNA_boolean_get(op->ptr, "use_mesh_compat")),
G_FILE_MESH_COMPAT);
+#else
+# error "don't remove by accident"
#endif
if (wm_file_write(C, path, fileflags, op->reports) != 0)
@@ -2862,16 +2968,16 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
ot->check = blend_save_check;
/* omit window poll so this can work in background mode */
- WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_BLENDER, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
- RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file");
- RNA_def_boolean(ot->srna, "relative_remap", 1, "Remap Relative",
+ RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file");
+ RNA_def_boolean(ot->srna, "relative_remap", true, "Remap Relative",
"Remap relative paths when saving in a different directory");
- prop = RNA_def_boolean(ot->srna, "copy", 0, "Save Copy",
+ prop = RNA_def_boolean(ot->srna, "copy", false, "Save Copy",
"Save a copy of the actual working state but does not make saved file active");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
#ifdef USE_BMESH_SAVE_AS_COMPAT
- RNA_def_boolean(ot->srna, "use_mesh_compat", 0, "Legacy Mesh Format",
+ RNA_def_boolean(ot->srna, "use_mesh_compat", false, "Legacy Mesh Format",
"Save using legacy mesh format (no ngons) - WARNING: only saves tris and quads, other ngons will "
"be lost (no implicit triangulation)");
#endif
@@ -2938,10 +3044,11 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
ot->check = blend_save_check;
/* omit window poll so this can work in background mode */
- WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE,
+ WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_BLENDER, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
- 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");
+ RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file");
+ RNA_def_boolean(ot->srna, "relative_remap", false, "Remap Relative",
+ "Remap relative paths when saving in a different directory");
}
static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
@@ -3064,14 +3171,16 @@ static int border_apply_rect(wmOperator *op)
static int border_apply(bContext *C, wmOperator *op, int gesture_mode)
{
+ PropertyRNA *prop;
+
int retval;
if (!border_apply_rect(op))
return 0;
/* XXX weak; border should be configured for this without reading event types */
- if (RNA_struct_find_property(op->ptr, "gesture_mode")) {
- RNA_int_set(op->ptr, "gesture_mode", gesture_mode);
+ if ((prop = RNA_struct_find_property(op->ptr, "gesture_mode"))) {
+ RNA_property_int_set(op->ptr, prop, gesture_mode);
}
retval = op->type->exec(C, op);
@@ -3391,6 +3500,8 @@ void wm_tweakevent_test(bContext *C, wmEvent *event, int action)
int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ PropertyRNA *prop;
+
op->customdata = WM_gesture_new(C, event, WM_GESTURE_LASSO);
/* add modal handler */
@@ -3398,8 +3509,8 @@ int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wm_gesture_tag_redraw(C);
- if (RNA_struct_find_property(op->ptr, "cursor")) {
- WM_cursor_modal_set(CTX_wm_window(C), RNA_int_get(op->ptr, "cursor"));
+ if ((prop = RNA_struct_find_property(op->ptr, "cursor"))) {
+ WM_cursor_modal_set(CTX_wm_window(C), RNA_property_int_get(op->ptr, prop));
}
return OPERATOR_RUNNING_MODAL;
@@ -3407,6 +3518,8 @@ int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_lines_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ PropertyRNA *prop;
+
op->customdata = WM_gesture_new(C, event, WM_GESTURE_LINES);
/* add modal handler */
@@ -3414,8 +3527,8 @@ int WM_gesture_lines_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wm_gesture_tag_redraw(C);
- if (RNA_struct_find_property(op->ptr, "cursor")) {
- WM_cursor_modal_set(CTX_wm_window(C), RNA_int_get(op->ptr, "cursor"));
+ if ((prop = RNA_struct_find_property(op->ptr, "cursor"))) {
+ WM_cursor_modal_set(CTX_wm_window(C), RNA_property_int_get(op->ptr, prop));
}
return OPERATOR_RUNNING_MODAL;
@@ -3621,6 +3734,8 @@ static int straightline_apply(bContext *C, wmOperator *op)
int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ PropertyRNA *prop;
+
op->customdata = WM_gesture_new(C, event, WM_GESTURE_STRAIGHTLINE);
/* add modal handler */
@@ -3628,8 +3743,8 @@ int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *e
wm_gesture_tag_redraw(C);
- if (RNA_struct_find_property(op->ptr, "cursor")) {
- WM_cursor_modal_set(CTX_wm_window(C), RNA_int_get(op->ptr, "cursor"));
+ if ((prop = RNA_struct_find_property(op->ptr, "cursor"))) {
+ WM_cursor_modal_set(CTX_wm_window(C), RNA_property_int_get(op->ptr, prop));
}
return OPERATOR_RUNNING_MODAL;
@@ -3709,9 +3824,10 @@ void WM_OT_straightline_gesture(wmOperatorType *ot)
/* *********************** radial control ****************** */
-#define WM_RADIAL_CONTROL_DISPLAY_SIZE 200
-#define WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE 35
+#define WM_RADIAL_CONTROL_DISPLAY_SIZE (200 * U.pixelsize)
+#define WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE (35 * U.pixelsize)
#define WM_RADIAL_CONTROL_DISPLAY_WIDTH (WM_RADIAL_CONTROL_DISPLAY_SIZE - WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE)
+#define WM_RADIAL_CONTROL_HEADER_LENGTH 180
#define WM_RADIAL_MAX_STR 6
typedef struct {
@@ -3729,8 +3845,24 @@ typedef struct {
ListBase orig_paintcursors;
bool use_secondary_tex;
void *cursor;
+ NumInput num_input;
} RadialControl;
+static void radial_control_update_header(wmOperator *op, bContext *C)
+{
+ RadialControl *rc = op->customdata;
+ char msg[WM_RADIAL_CONTROL_HEADER_LENGTH];
+ ScrArea *sa = CTX_wm_area(C);
+ Scene *scene = CTX_data_scene(C);
+
+ if (sa && hasNumInput(&rc->num_input)) {
+ char num_str[NUM_STR_REP_LEN];
+ outputNumInput(&rc->num_input, num_str, &scene->unit);
+ BLI_snprintf(msg, WM_RADIAL_CONTROL_HEADER_LENGTH, "%s: %s", RNA_property_ui_name(rc->prop), num_str);
+ ED_area_headerprint(sa, msg);
+ }
+}
+
static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *event)
{
float d[2] = {0, 0};
@@ -3742,8 +3874,9 @@ static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *e
switch (rc->subtype) {
case PROP_NONE:
case PROP_DISTANCE:
+ case PROP_PERCENTAGE:
case PROP_PIXEL:
- d[0] = rc->initial_value;
+ d[0] = rc->initial_value * U.pixelsize;
break;
case PROP_FACTOR:
d[0] = (1 - rc->initial_value) * WM_RADIAL_CONTROL_DISPLAY_WIDTH + WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE;
@@ -3837,7 +3970,7 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
{
RadialControl *rc = customdata;
ARegion *ar = CTX_wm_region(C);
- uiStyle *style = UI_GetStyle();
+ uiStyle *style = UI_style_get();
const uiFontStyle *fstyle = &style->widget;
const int fontid = fstyle->uifont_id;
short fstyle_points = fstyle->points;
@@ -3850,9 +3983,10 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
switch (rc->subtype) {
case PROP_NONE:
case PROP_DISTANCE:
+ case PROP_PERCENTAGE:
case PROP_PIXEL:
- r1 = rc->current_value;
- r2 = rc->initial_value;
+ r1 = rc->current_value * U.pixelsize;
+ r2 = rc->initial_value * U.pixelsize;
tex_radius = r1;
alpha = 0.75;
break;
@@ -3877,11 +4011,6 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
break;
}
- /* adjust for DPI, like BKE_brush_size_get */
- r1 *= U.pixelsize;
- r2 *= U.pixelsize;
- tex_radius *= U.pixelsize;
-
/* Keep cursor in the original place */
x = rc->initial_mouse[0] - ar->winrct.xmin;
y = rc->initial_mouse[1] - ar->winrct.ymin;
@@ -3989,7 +4118,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op,
PropertyType prop_type = RNA_property_type(*r_prop);
if (((flags & RC_PROP_REQUIRE_BOOL) && (prop_type != PROP_BOOLEAN)) ||
- ((flags & RC_PROP_REQUIRE_FLOAT) && prop_type != PROP_FLOAT))
+ ((flags & RC_PROP_REQUIRE_FLOAT) && (prop_type != PROP_FLOAT)))
{
MEM_freeN(str);
BKE_reportf(op->reports, RPT_ERROR, "Property from path '%s' is not a float", name);
@@ -4113,14 +4242,21 @@ static int radial_control_invoke(bContext *C, wmOperator *op, const wmEvent *eve
return OPERATOR_CANCELLED;
}
+ /* initialize numerical input */
+ initNumInput(&rc->num_input);
+ rc->num_input.idx_max = 0;
+ rc->num_input.val_flag[0] |= NUM_NO_NEGATIVE;
+ rc->num_input.unit_sys = USER_UNIT_NONE;
+ rc->num_input.unit_type[0] = B_UNIT_LENGTH;
+
/* get subtype of property */
rc->subtype = RNA_property_subtype(rc->prop);
- if (!ELEM(rc->subtype, PROP_NONE, PROP_DISTANCE, PROP_FACTOR, PROP_ANGLE, PROP_PIXEL)) {
- BKE_report(op->reports, RPT_ERROR, "Property must be a none, distance, a factor, or an angle");
+ if (!ELEM(rc->subtype, PROP_NONE, PROP_DISTANCE, PROP_FACTOR, PROP_PERCENTAGE, PROP_ANGLE, PROP_PIXEL)) {
+ BKE_report(op->reports, RPT_ERROR, "Property must be a none, distance, factor, percentage, angle, or pixel");
MEM_freeN(rc);
return OPERATOR_CANCELLED;
}
-
+
rc->current_value = rc->initial_value;
radial_control_set_initial_mouse(rc, event);
radial_control_set_tex(rc);
@@ -4157,11 +4293,16 @@ static void radial_control_cancel(bContext *C, wmOperator *op)
{
RadialControl *rc = op->customdata;
wmWindowManager *wm = CTX_wm_manager(C);
+ ScrArea *sa = CTX_wm_area(C);
if (rc->dial) {
MEM_freeN(rc->dial);
rc->dial = NULL;
}
+
+ if (sa) {
+ ED_area_headerprint(sa, NULL);
+ }
WM_paint_cursor_end(wm, rc->cursor);
@@ -4185,125 +4326,183 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even
float delta[2], ret = OPERATOR_RUNNING_MODAL;
bool snap;
float angle_precision = 0.0f;
+ const bool has_numInput = hasNumInput(&rc->num_input);
+ bool handled = false;
+ float numValue;
/* TODO: fix hardcoded events */
snap = event->ctrl != 0;
- switch (event->type) {
- case MOUSEMOVE:
- if (rc->slow_mode) {
- if (rc->subtype == PROP_ANGLE) {
- float position[2] = {event->x, event->y};
-
- /* calculate the initial angle here first */
- delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
- delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1];
-
- /* precision angle gets calculated from dial and gets added later */
- angle_precision = -0.1f * BLI_dial_angle(rc->dial, position);
- }
- else {
- delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
- delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1];
-
- if (rc->zoom_prop) {
- RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
- delta[0] /= zoom[0];
- delta[1] /= zoom[1];
+ /* Modal numinput active, try to handle numeric inputs first... */
+ if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &rc->num_input, event)) {
+ handled = true;
+ applyNumInput(&rc->num_input, &numValue);
+
+ if (rc->subtype == PROP_ANGLE) {
+ numValue = DEG2RADF(numValue);
+ numValue = fmod(numValue, 2.0f * (float)M_PI);
+ if (numValue < 0.0f)
+ numValue += 2.0f * (float)M_PI;
+ }
+
+ CLAMP(numValue, rc->min_value, rc->max_value);
+ new_value = numValue;
+
+ radial_control_set_value(rc, new_value);
+ rc->current_value = new_value;
+ radial_control_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ handled = false;
+ switch (event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ /* canceled; restore original value */
+ radial_control_set_value(rc, rc->initial_value);
+ ret = OPERATOR_CANCELLED;
+ break;
+
+ case LEFTMOUSE:
+ case PADENTER:
+ case RETKEY:
+ /* done; value already set */
+ RNA_property_update(C, &rc->ptr, rc->prop);
+ ret = OPERATOR_FINISHED;
+ break;
+
+ case MOUSEMOVE:
+ if (!has_numInput) {
+ if (rc->slow_mode) {
+ if (rc->subtype == PROP_ANGLE) {
+ float position[2] = {event->x, event->y};
+
+ /* calculate the initial angle here first */
+ delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
+ delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1];
+
+ /* precision angle gets calculated from dial and gets added later */
+ angle_precision = -0.1f * BLI_dial_angle(rc->dial, position);
+ }
+ else {
+ delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
+ delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1];
+
+ if (rc->zoom_prop) {
+ RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
+ delta[0] /= zoom[0];
+ delta[1] /= zoom[1];
+ }
+
+ dist = len_v2(delta);
+
+ delta[0] = event->x - rc->slow_mouse[0];
+ delta[1] = event->y - rc->slow_mouse[1];
+
+ if (rc->zoom_prop) {
+ delta[0] /= zoom[0];
+ delta[1] /= zoom[1];
+ }
+
+ dist = dist + 0.1f * (delta[0] + delta[1]);
+ }
}
-
- dist = len_v2(delta);
-
- delta[0] = event->x - rc->slow_mouse[0];
- delta[1] = event->y - rc->slow_mouse[1];
-
- if (rc->zoom_prop) {
- delta[0] /= zoom[0];
- delta[1] /= zoom[1];
+ else {
+ delta[0] = rc->initial_mouse[0] - event->x;
+ delta[1] = rc->initial_mouse[1] - event->y;
+
+ if (rc->zoom_prop) {
+ RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
+ delta[0] /= zoom[0];
+ delta[1] /= zoom[1];
+ }
+
+ dist = len_v2(delta);
}
-
- dist = dist + 0.1f * (delta[0] + delta[1]);
+
+ /* calculate new value and apply snapping */
+ switch (rc->subtype) {
+ case PROP_NONE:
+ case PROP_DISTANCE:
+ case PROP_PERCENTAGE:
+ case PROP_PIXEL:
+ new_value = dist;
+ if (snap) new_value = ((int)new_value + 5) / 10 * 10;
+ new_value /= U.pixelsize;
+ break;
+ case PROP_FACTOR:
+ new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) / WM_RADIAL_CONTROL_DISPLAY_WIDTH;
+ if (snap) new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f;
+ break;
+ case PROP_ANGLE:
+ new_value = atan2f(delta[1], delta[0]) + (float)M_PI + angle_precision;
+ new_value = fmod(new_value, 2.0f * (float)M_PI);
+ if (new_value < 0.0f)
+ new_value += 2.0f * (float)M_PI;
+ if (snap) new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10);
+ break;
+ default:
+ new_value = dist; /* dummy value, should this ever happen? - campbell */
+ break;
+ }
+
+ /* clamp and update */
+ CLAMP(new_value, rc->min_value, rc->max_value);
+ radial_control_set_value(rc, new_value);
+ rc->current_value = new_value;
+ handled = true;
+ break;
}
- }
- else {
- delta[0] = rc->initial_mouse[0] - event->x;
- delta[1] = rc->initial_mouse[1] - event->y;
+ break;
- if (rc->zoom_prop) {
- RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
- delta[0] /= zoom[0];
- delta[1] /= zoom[1];
+ case LEFTSHIFTKEY:
+ case RIGHTSHIFTKEY:
+ {
+ if (event->val == KM_PRESS) {
+ rc->slow_mouse[0] = event->x;
+ rc->slow_mouse[1] = event->y;
+ rc->slow_mode = true;
+ if (rc->subtype == PROP_ANGLE) {
+ float initial_position[2] = {UNPACK2(rc->initial_mouse)};
+ float current_position[2] = {UNPACK2(rc->slow_mouse)};
+ rc->dial = BLI_dial_initialize(initial_position, 0.0f);
+ /* immediately set the position to get a an initial direction */
+ BLI_dial_angle(rc->dial, current_position);
+ }
+ handled = true;
}
-
- dist = len_v2(delta);
+ if (event->val == KM_RELEASE) {
+ rc->slow_mode = false;
+ handled = true;
+ if (rc->dial) {
+ MEM_freeN(rc->dial);
+ rc->dial = NULL;
+ }
+ }
+ break;
}
+ }
- /* calculate new value and apply snapping */
- switch (rc->subtype) {
- case PROP_NONE:
- case PROP_DISTANCE:
- case PROP_PIXEL:
- new_value = dist;
- if (snap) new_value = ((int)new_value + 5) / 10 * 10;
- break;
- case PROP_FACTOR:
- new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) / WM_RADIAL_CONTROL_DISPLAY_WIDTH;
- if (snap) new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f;
- break;
- case PROP_ANGLE:
- new_value = atan2f(delta[1], delta[0]) + M_PI + angle_precision;
- new_value = fmod(new_value, 2.0f * (float)M_PI);
- if (new_value < 0.0f)
- new_value += 2.0f * (float)M_PI;
- if (snap) new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10);
- break;
- default:
- new_value = dist; /* dummy value, should this ever happen? - campbell */
- break;
+ /* Modal numinput inactive, try to handle numeric inputs last... */
+ if (!handled && event->val == KM_PRESS && handleNumInput(C, &rc->num_input, event)) {
+ applyNumInput(&rc->num_input, &numValue);
+
+ if (rc->subtype == PROP_ANGLE) {
+ numValue = DEG2RADF(numValue);
+ numValue = fmod(numValue, 2.0f * (float)M_PI);
+ if (numValue < 0.0f)
+ numValue += 2.0f * (float)M_PI;
}
- /* clamp and update */
- CLAMP(new_value, rc->min_value, rc->max_value);
+ CLAMP(numValue, rc->min_value, rc->max_value);
+ new_value = numValue;
+
radial_control_set_value(rc, new_value);
- rc->current_value = new_value;
- break;
-
- case ESCKEY:
- case RIGHTMOUSE:
- /* canceled; restore original value */
- radial_control_set_value(rc, rc->initial_value);
- ret = OPERATOR_CANCELLED;
- break;
-
- case LEFTMOUSE:
- case PADENTER:
- /* done; value already set */
- RNA_property_update(C, &rc->ptr, rc->prop);
- ret = OPERATOR_FINISHED;
- break;
- case LEFTSHIFTKEY:
- case RIGHTSHIFTKEY:
- if (event->val == KM_PRESS) {
- rc->slow_mouse[0] = event->x;
- rc->slow_mouse[1] = event->y;
- rc->slow_mode = true;
- if (rc->subtype == PROP_ANGLE) {
- float initial_position[2] = {UNPACK2(rc->initial_mouse)};
- float current_position[2] = {UNPACK2(rc->slow_mouse)};
- rc->dial = BLI_dial_initialize(initial_position, 0.0f);
- /* immediately set the position to get a an initial direction */
- BLI_dial_angle(rc->dial, current_position);
- }
- }
- if (event->val == KM_RELEASE) {
- rc->slow_mode = false;
- if (rc->dial) {
- MEM_freeN(rc->dial);
- rc->dial = NULL;
- }
- }
- break;
+ rc->current_value = new_value;
+ radial_control_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
+ }
}
ED_region_tag_redraw(CTX_wm_region(C));
@@ -4343,7 +4542,7 @@ static void WM_OT_radial_control(wmOperatorType *ot)
RNA_def_string(ot->srna, "image_id", NULL, 0, "Image ID", "Path of ID that is used to generate an image for the control");
- RNA_def_boolean(ot->srna, "secondary_tex", 0, "Secondary Texture", "Tweak brush secondary/mask texture");
+ RNA_def_boolean(ot->srna, "secondary_tex", false, "Secondary Texture", "Tweak brush secondary/mask texture");
}
/* ************************** timer for testing ***************** */
@@ -4525,6 +4724,90 @@ static void WM_OT_dependency_relations(wmOperatorType *ot)
ot->exec = dependency_relations_exec;
}
+/* *************************** Mat/tex/etc. previews generation ************* */
+
+typedef struct PreviewsIDEnsureStack {
+ Scene *scene;
+
+ BLI_LINKSTACK_DECLARE(id_stack, ID *);
+} PreviewsIDEnsureStack;
+
+static void previews_id_ensure(bContext *C, Scene *scene, ID *id)
+{
+ BLI_assert(ELEM(GS(id->name), ID_MA, ID_TE, ID_IM, ID_WO, ID_LA));
+
+ /* Only preview non-library datablocks, lib ones do not pertain to this .blend file!
+ * Same goes for ID with no user. */
+ if (!id->lib && (id->us != 0)) {
+ UI_id_icon_render(C, scene, id, false, false);
+ UI_id_icon_render(C, scene, id, true, false);
+ }
+}
+
+static bool previews_id_ensure_callback(void *todo_v, ID **idptr, int UNUSED(cd_flag))
+{
+ PreviewsIDEnsureStack *todo = todo_v;
+ ID *id = *idptr;
+
+ if (id && (id->flag & LIB_DOIT)) {
+ if (ELEM(GS(id->name), ID_MA, ID_TE, ID_IM, ID_WO, ID_LA)) {
+ previews_id_ensure(NULL, todo->scene, id);
+ }
+ id->flag &= ~LIB_DOIT; /* Tag the ID as done in any case. */
+ BLI_LINKSTACK_PUSH(todo->id_stack, id);
+ }
+
+ return true;
+}
+
+static int previews_ensure_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Main *bmain = CTX_data_main(C);
+ ListBase *lb[] = {&bmain->mat, &bmain->tex, &bmain->image, &bmain->world, &bmain->lamp, NULL};
+ PreviewsIDEnsureStack preview_id_stack;
+ Scene *scene;
+ ID *id;
+ int i;
+
+ /* We use LIB_DOIT to check whether we have already handled a given ID or not. */
+ BKE_main_id_flag_all(bmain, LIB_DOIT, true);
+
+ BLI_LINKSTACK_INIT(preview_id_stack.id_stack);
+
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
+ preview_id_stack.scene = scene;
+ id = (ID *)scene;
+
+ do {
+ /* This will loop over all IDs linked by current one, render icons for them if needed,
+ * and add them to 'todo' preview_id_stack. */
+ BKE_library_foreach_ID_link(id, previews_id_ensure_callback, &preview_id_stack, IDWALK_READONLY);
+ } while ((id = BLI_LINKSTACK_POP(preview_id_stack.id_stack)));
+ }
+
+ BLI_LINKSTACK_FREE(preview_id_stack.id_stack);
+
+ /* Check a last time for ID not used (fake users only, in theory), and
+ * do our best for those, using current scene... */
+ for (i = 0; lb[i]; i++) {
+ for (id = lb[i]->first; id; id = id->next) {
+ previews_id_ensure(C, NULL, id);
+ }
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void WM_OT_previews_ensure(wmOperatorType *ot)
+{
+ ot->name = "Refresh DataBlock Previews";
+ ot->idname = "WM_OT_previews_ensure";
+ ot->description = "Ensure datablock previews are available and up-to-date "
+ "(to be saved in .blend file, only for some types like materials, textures, etc.)";
+
+ ot->exec = previews_ensure_exec;
+}
+
/* ******************************************************* */
static void operatortype_ghash_free_cb(wmOperatorType *ot)
@@ -4588,6 +4871,7 @@ void wm_operatortype_init(void)
#if defined(WIN32)
WM_operatortype_append(WM_OT_console_toggle);
#endif
+ WM_operatortype_append(WM_OT_previews_ensure);
}
/* circleselect-like modal operators */
@@ -4645,6 +4929,8 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "CLIP_OT_select_circle");
WM_modalkeymap_assign(keymap, "MASK_OT_select_circle");
WM_modalkeymap_assign(keymap, "NODE_OT_select_circle");
+ WM_modalkeymap_assign(keymap, "GPENCIL_OT_select_circle");
+ WM_modalkeymap_assign(keymap, "GRAPH_OT_select_circle");
}
@@ -4741,6 +5027,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_border");
WM_modalkeymap_assign(keymap, "VIEW3D_OT_zoom_border"); /* XXX TODO: zoom border should perhaps map rightmouse to zoom out instead of in+cancel */
WM_modalkeymap_assign(keymap, "IMAGE_OT_render_border");
+ WM_modalkeymap_assign(keymap, "GPENCIL_OT_select_border");
}
/* zoom to border modal operators */
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 76add2f9aac..31883cf234c 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -69,8 +69,6 @@
#include "GHOST_C-api.h"
#include "BLF_api.h"
-#include "wm_event_types.h"
-
#include "WM_api.h" /* only for WM_main_playanim */
struct PlayState;
@@ -298,8 +296,8 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf
glRasterPos2f(offs_x + (ps->draw_flip[0] ? span_x : 0.0f),
offs_y + (ps->draw_flip[1] ? span_y : 0.0f));
- glPixelZoom(ps->zoom * ps->draw_flip[0] ? -1.0f : 1.0f,
- ps->zoom * ps->draw_flip[1] ? -1.0f : 1.0f);
+ glPixelZoom(ps->zoom * (ps->draw_flip[0] ? -1.0f : 1.0f),
+ ps->zoom * (ps->draw_flip[1] ? -1.0f : 1.0f));
glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
@@ -850,6 +848,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
static void playanim_window_open(const char *title, int posx, int posy, int sizex, int sizey)
{
+ GHOST_GLSettings glsettings = {0};
GHOST_TUns32 scr_w, scr_h;
GHOST_GetMainDisplayDimensions(g_WS.ghost_system, &scr_w, &scr_h);
@@ -862,7 +861,7 @@ static void playanim_window_open(const char *title, int posx, int posy, int size
/* could optionally start fullscreen */
GHOST_kWindowStateNormal,
GHOST_kDrawingContextTypeOpenGL,
- false /* no stereo */, false);
+ glsettings);
}
static void playanim_window_zoom(PlayState *ps, const float zoom_offset)
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index e26bcac9b1a..4ce2415e310 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -53,7 +53,6 @@
#include "WM_api.h"
#include "wm_subwindow.h"
-#include "wm_window.h"
/* wmSubWindow stored in wmWindow... but not exposed outside this C file */
/* it seems a bit redundant (area regions can store it too, but we keep it
@@ -368,7 +367,7 @@ static void wmOrtho2_offset(const float x, const float y, const float ofs)
*/
void wmOrtho2_region_pixelspace(const struct ARegion *ar)
{
- wmOrtho2_offset(ar->winx + 1, ar->winy + 1, -GLA_PIXEL_OFS);
+ wmOrtho2_offset(ar->winx, ar->winy, -0.01f);
}
void wmOrtho2_pixelspace(const float x, const float y)
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 46a20d3bf88..4f7e5ab75b3 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -356,6 +356,7 @@ float wm_window_pixelsize(wmWindow *win)
static void wm_window_add_ghostwindow(wmWindowManager *wm, const char *title, wmWindow *win)
{
GHOST_WindowHandle ghostwin;
+ GHOST_GLSettings glSettings = {0};
static int multisamples = -1;
int scr_w, scr_h, posy;
@@ -363,7 +364,12 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, const char *title, wm
* mix it, either all windows have it, or none (tested in OSX opengl) */
if (multisamples == -1)
multisamples = U.ogl_multisamples;
-
+
+ glSettings.numOfAASamples = multisamples;
+
+ if (!(U.uiflag2 & USER_OPENGL_NO_WARN_SUPPORT))
+ glSettings.flags |= GHOST_glWarnSupport;
+
wm_get_screensize(&scr_w, &scr_h);
posy = (scr_h - win->posy - win->sizey);
@@ -371,8 +377,7 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, const char *title, wm
win->posx, posy, win->sizex, win->sizey,
(GHOST_TWindowState)win->windowstate,
GHOST_kDrawingContextTypeOpenGL,
- 0 /* no stereo */,
- multisamples /* AA */);
+ glSettings);
if (ghostwin) {
GHOST_RectangleHandle bounds;
@@ -1524,3 +1529,21 @@ bool WM_window_is_fullscreen(wmWindow *win)
return win->windowstate == GHOST_kWindowStateFullScreen;
}
+
+#ifdef WITH_INPUT_IME
+/* note: keep in mind wm_window_IME_begin is also used to reposition the IME window */
+void wm_window_IME_begin(wmWindow *win, int x, int y, int w, int h, bool complete)
+{
+ BLI_assert(win);
+
+ GHOST_BeginIME(win->ghostwin, x, win->sizey - y, w, h, complete);
+}
+
+void wm_window_IME_end(wmWindow *win)
+{
+ BLI_assert(win && win->ime_data);
+
+ GHOST_EndIME(win->ghostwin);
+ win->ime_data = NULL;
+}
+#endif /* WITH_INPUT_IME */
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index d1a94194108..f89177a82ea 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -65,9 +65,6 @@ typedef struct wmEventHandler {
struct ARegion *ui_region; /* for derived/modal handlers */
struct ARegion *ui_menu; /* for derived/modal handlers */
- /* fileselect handler re-uses modal operator data */
- struct bScreen *filescreen; /* screen it started in, to validate exec */
-
/* drop box handler */
ListBase *dropboxes;
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index 7dfc2b52c33..ecc29de0e7d 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -86,10 +86,19 @@ enum {
* paint and drawing tools however will want to handle these. */
INBETWEEN_MOUSEMOVE = 0x0011,
+/* IME event, GHOST_kEventImeCompositionStart in ghost */
+ WM_IME_COMPOSITE_START = 0x0014,
+/* IME event, GHOST_kEventImeComposition in ghost */
+ WM_IME_COMPOSITE_EVENT = 0x0015,
+/* IME event, GHOST_kEventImeCompositionEnd in ghost */
+ WM_IME_COMPOSITE_END = 0x0016,
+
/* *** Start of keyboard codes. *** */
/* standard keyboard.
* XXX from 0x0020 to 0x00ff, and 0x012c to 0x013f for function keys! */
+
+ /* NOTE: these values are saved in keymap files, do not change them but just add new ones */
AKEY = 0x0061, /* 'a' */
BKEY = 0x0062, /* 'b' */
CKEY = 0x0063, /* 'c' */
@@ -299,16 +308,21 @@ enum {
/* Tweak, gestures: 0x500x, 0x501x */
EVT_ACTIONZONE_AREA = 0x5000,
EVT_ACTIONZONE_REGION = 0x5001,
- EVT_ACTIONZONE_FULLSCREEN = 0x5002,
+ EVT_ACTIONZONE_FULLSCREEN = 0x5011,
+
+ /* NOTE: these values are saved in keymap files, do not change them but just add new ones */
+
/* tweak events, for L M R mousebuttons */
- EVT_TWEAK_L = 0x5003,
- EVT_TWEAK_M = 0x5004,
- EVT_TWEAK_R = 0x5005,
+ EVT_TWEAK_L = 0x5002,
+ EVT_TWEAK_M = 0x5003,
+ EVT_TWEAK_R = 0x5004,
/* tweak events for action or select mousebutton */
- EVT_TWEAK_A = 0x5006,
- EVT_TWEAK_S = 0x5007,
+ EVT_TWEAK_A = 0x5005,
+ EVT_TWEAK_S = 0x5006,
EVT_GESTURE = 0x5010,
+ /* 0x5011 is taken, see EVT_ACTIONZONE_FULLSCREEN */
+
/* Misc Blender internals: 0x502x */
EVT_FILESELECT = 0x5020,
EVT_BUT_OPEN = 0x5021,
@@ -355,10 +369,23 @@ enum {
(event_type >= LEFTCTRLKEY && event_type <= LEFTSHIFTKEY) == false && \
(event_type >= UNKNOWNKEY && event_type <= GRLESSKEY) == false)
+/* internal helpers*/
+#define _VA_IS_EVENT_MOD2(v, a) (CHECK_TYPE_INLINE(v, wmEvent *), \
+ ((v)->a))
+#define _VA_IS_EVENT_MOD3(v, a, b) \
+ (_VA_IS_EVENT_MOD2(v, a) || ((v)->b))
+#define _VA_IS_EVENT_MOD4(v, a, b, c) \
+ (_VA_IS_EVENT_MOD3(v, a, b) || ((v)->c))
+#define _VA_IS_EVENT_MOD5(v, a, b, c, d) \
+ (_VA_IS_EVENT_MOD4(v, a, b, c) || ((v)->d))
+
+/* reusable IS_EVENT_MOD(event, shift, ctrl, alt, oskey), macro */
+#define IS_EVENT_MOD(...) VA_NARGS_CALL_OVERLOAD(_VA_IS_EVENT_MOD, __VA_ARGS__)
/* ********** wmEvent.val ********** */
/* Gestures */
+/* NOTE: these values are saved in keymap files, do not change them but just add new ones */
enum {
/* value of tweaks and line gestures, note, KM_ANY (-1) works for this case too */
EVT_GESTURE_N = 1,
@@ -382,11 +409,10 @@ enum {
/* File select */
enum {
- EVT_FILESELECT_OPEN = 1,
- EVT_FILESELECT_FULL_OPEN = 2,
- EVT_FILESELECT_EXEC = 3,
- EVT_FILESELECT_CANCEL = 4,
- EVT_FILESELECT_EXTERNAL_CANCEL = 5,
+ EVT_FILESELECT_FULL_OPEN = 1,
+ EVT_FILESELECT_EXEC = 2,
+ EVT_FILESELECT_CANCEL = 3,
+ EVT_FILESELECT_EXTERNAL_CANCEL = 4,
};
/* Gesture */
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 9c9c79d2f54..833234b0f13 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -69,6 +69,11 @@ wmWindow *wm_window_copy (bContext *C, wmWindow *winorig);
void wm_window_testbreak (void);
+#ifdef WITH_INPUT_IME
+void wm_window_IME_begin (wmWindow *win, int x, int y, int w, int h, bool complete);
+void wm_window_IME_end (wmWindow *win);
+#endif
+
/* *************** window operators ************** */
int wm_window_duplicate_exec(bContext *C, struct wmOperator *op);
int wm_window_fullscreen_toggle_exec(bContext *C, struct wmOperator *op);
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 9cd5763847a..4451264c02a 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -56,6 +56,10 @@ if(WIN32 AND NOT UNIX)
add_executable(blenderplayer ${EXETYPE} bad_level_call_stubs/stubs.c ../icons/winblender.rc)
+ install(TARGETS blenderplayer
+ COMPONENT Blenderplayer
+ DESTINATION ".")
+
elseif(APPLE)
add_executable(blenderplayer ${EXETYPE} bad_level_call_stubs/stubs.c)
# setup Info.plist
@@ -69,6 +73,13 @@ elseif(APPLE)
else()
add_executable(blenderplayer bad_level_call_stubs/stubs.c)
+
+ if(NOT WITH_INSTALL_PORTABLE)
+ install(
+ TARGETS blenderplayer
+ DESTINATION bin
+ )
+ endif()
endif()
add_dependencies(blenderplayer makesdna)
@@ -95,6 +106,7 @@ endif()
bf_intern_ghostndof3dconnexion
bf_rna
bf_blenkernel
+ bf_physics
bf_intern_rigidbody
bf_blenloader
ge_blen_routines
@@ -157,6 +169,7 @@ endif()
extern_wcwidth
extern_libmv
extern_glog
+ extern_sdlew
)
if(WITH_MOD_CLOTH_ELTOPO)
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 0846e37178d..0856b50c19b 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -163,7 +163,9 @@ struct wmWindowManager;
#include "../blender/editors/include/ED_render.h"
#include "../blender/editors/include/ED_screen.h"
#include "../blender/editors/include/ED_space_api.h"
+#include "../blender/editors/include/ED_text.h"
#include "../blender/editors/include/ED_transform.h"
+#include "../blender/editors/include/ED_uvedit.h"
#include "../blender/editors/include/ED_view3d.h"
#include "../blender/editors/include/UI_interface.h"
#include "../blender/editors/include/UI_interface_icons.h"
@@ -217,6 +219,7 @@ void EDBM_mesh_load(struct Object *ob) RET_NONE
void EDBM_mesh_make(struct ToolSettings *ts, struct Object *ob) RET_NONE
void EDBM_mesh_normals_update(struct BMEditMesh *em) RET_NONE
void *g_system;
+bool EDBM_mtexpoly_check(struct BMEditMesh *em) RET_ZERO
float *RE_RenderLayerGetPass(struct RenderLayer *rl, int passtype) RET_NULL
float RE_filter_value(int type, float x) RET_ZERO
@@ -236,8 +239,8 @@ bool ED_texture_context_check_linestyle(const struct bContext *C) RET_ZERO
void FRS_free_view_map_cache(void) RET_NONE
/* texture.c */
-int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage) RET_ZERO
-int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage) RET_ZERO
+int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image) RET_ZERO
+int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image) RET_ZERO
int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex, struct ImagePool *pool) RET_ZERO
struct Material *RE_init_sample_material(struct Material *orig_mat, struct Scene *scene) RET_NULL
@@ -260,7 +263,7 @@ struct Scene *RE_GetScene(struct Render *re) RET_NULL
void RE_Database_Free(struct Render *re) RET_NONE
void RE_FreeRender(struct Render *re) RET_NONE
void RE_DataBase_GetView(struct Render *re, float mat[4][4]) RET_NONE
-int externtex(struct MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread, struct ImagePool *poold) RET_ZERO
+int externtex(struct MTex *mtex, const float vec[3], float *tin, float *tr, float *tg, float *tb, float *ta, const int thread, struct ImagePool *pool, const bool skip_load_image) RET_ZERO
float texture_value_blend(float tex, float out, float fact, float facg, int blendtype) RET_ZERO
void texture_rgb_blend(float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype) RET_NONE
const unsigned char stipple_quarttone[128];
@@ -338,6 +341,9 @@ bool ED_space_image_show_paint(struct SpaceImage *sima) RET_ZERO
void ED_space_image_paint_update(struct wmWindowManager *wm, struct ToolSettings *settings) RET_NONE
void ED_space_image_set(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima) RET_NONE
void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSettings *settings) RET_NONE
+void ED_space_image_scopes_update(const struct bContext *C, struct SpaceImage *sima, struct ImBuf *ibuf, bool use_view_settings) RET_NONE
+
+void ED_uvedit_get_aspect(struct Scene *scene, struct Object *ob, struct BMesh *em, float *aspx, float *aspy) RET_NONE
void ED_screen_set_scene(struct bContext *C, struct bScreen *screen, struct Scene *scene) RET_NONE
struct MovieClip *ED_space_clip_get_clip(struct SpaceClip *sc) RET_NULL
@@ -349,6 +355,16 @@ void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype) RET_NONE
void ED_render_engine_changed(struct Main *bmain) RET_NONE
void ED_file_read_bookmarks(void) RET_NONE
+void ED_file_change_dir(struct bContext *C, const bool checkdir) RET_NONE
+void ED_preview_kill_jobs(struct wmWindowManager *wm, struct Main *bmain) RET_NONE
+struct FSMenu *ED_fsmenu_get(void) RET_NULL
+struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category) RET_NULL
+int ED_fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category) RET_ZERO
+struct FSMenuEntry *ED_fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index) RET_NULL
+char *ED_fsmenu_entry_get_path(struct FSMenuEntry *fsentry) RET_NULL
+void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *name) RET_NONE
+char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry) RET_NULL
+void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name) RET_NONE
struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob) RET_NULL
void PE_current_changed(struct Scene *scene, struct Object *ob) RET_NONE
@@ -461,13 +477,9 @@ bool ED_mesh_color_remove_named(struct Mesh *me, const char *name) RET_ZERO
bool ED_mesh_uv_texture_remove_named(struct Mesh *me, const char *name) RET_ZERO
void ED_object_constraint_dependency_update(struct Main *bmain, struct Object *ob) RET_NONE
void ED_object_constraint_update(struct Object *ob) RET_NONE
-struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, const char *name) RET_NULL
void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum, float weight, int assignmode) RET_NONE
void ED_vgroup_vert_remove(struct Object *ob, struct bDeformGroup *dg, int vertnum) RET_NONE
float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int vertnum) RET_ZERO
-void ED_vgroup_delete(struct Object *ob, struct bDeformGroup *defgroup) RET_NONE
-void ED_vgroup_clear(struct Object *ob) RET_NONE
-bool ED_vgroup_object_is_edit_mode(struct Object *ob) RET_ZERO
int ED_mesh_mirror_topo_table(struct Object *ob, char mode) RET_ZERO
int ED_mesh_mirror_spatial_table(struct Object *ob, struct BMEditMesh *em, const float co[3], char mode) RET_ZERO
@@ -481,6 +493,8 @@ bool ED_texture_context_check_lamp(const struct bContext *C) RET_ZERO
bool ED_texture_context_check_particles(const struct bContext *C) RET_ZERO
bool ED_texture_context_check_others(const struct bContext *C) RET_ZERO
+bool ED_text_region_location_from_cursor(SpaceText *st, ARegion *ar, const int cursor_co[2], int r_pixel_co[2]) RET_ZERO
+
bool snapObjectsRayEx(struct Scene *scene, struct Base *base_act, struct View3D *v3d, struct ARegion *ar, struct Object *obedit, short snap_mode,
struct Object **r_ob, float r_obmat[4][4],
const float ray_start[3], const float ray_normal[3], float *r_ray_dist,
@@ -505,6 +519,7 @@ struct uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align) RE
bool uiLayoutGetRedAlert(struct uiLayout *layout) RET_ZERO
void uiLayoutSetRedAlert(uiLayout *layout, bool redalert) RET_NONE
void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname) RET_NONE
+void uiItemMenuEnumR_prop(uiLayout *layout, struct PointerRNA *ptr, PropertyRNA *prop, const char *name, int icon) RET_NONE
void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon) RET_NONE
void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *value, const char *name, int icon) RET_NONE
void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, struct PointerRNA *searchptr, const char *searchpropname, const char *name, int icon) RET_NONE
@@ -541,7 +556,7 @@ void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, const char *prop
void uiTemplateImageLayers(struct uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser) RET_NONE
void uiTemplateList(struct uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id,
PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname,
- int rows, int maxrows, int layout_type, int columns) RET_NONE
+ const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns) RET_NONE
void uiTemplateRunningJobs(struct uiLayout *layout, struct bContext *C) RET_NONE
void uiTemplateOperatorSearch(struct uiLayout *layout) RET_NONE
void uiTemplateHeader3D(struct uiLayout *layout, struct bContext *C) RET_NONE
@@ -576,6 +591,7 @@ struct RenderStats *RE_GetStats(struct Render *re) RET_NULL
struct RenderData *RE_engine_get_render_data(struct Render *re) RET_NULL
void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result) RET_NONE
void RE_engine_update_progress(struct RenderEngine *engine, float progress) RET_NONE
+void RE_engine_set_error_message(RenderEngine *engine, const char *msg) RET_NONE
void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result, int cancel, int merge_results) RET_NONE
void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info) RET_NONE
void RE_layer_load_from_file(struct RenderLayer *layer, struct ReportList *reports, const char *filename, int x, int y) RET_NONE
@@ -597,7 +613,7 @@ void RE_FreePersistentData(void) RET_NONE
/* python */
struct wmOperatorType *WM_operatortype_find(const char *idname, bool quiet) RET_NULL
-struct GHashIterator *WM_operatortype_iter() RET_NULL
+void WM_operatortype_iter(struct GHashIterator *ghi) RET_NONE
struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *ot, const char *idname) RET_NULL
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, short context, struct PointerRNA *properties, struct ReportList *reports, const bool is_undo) RET_ZERO
void WM_operatortype_remove_ptr(struct wmOperatorType *ot) RET_NONE
@@ -617,21 +633,22 @@ int WM_operator_ui_popup(struct bContext *C, struct wmOperator *op, int width, i
void update_autoflags_fcurve(struct FCurve *fcu, struct bContext *C, struct ReportList *reports, struct PointerRNA *ptr) RET_NONE
short insert_keyframe(struct ReportList *reports, struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag) RET_ZERO
short delete_keyframe(struct ReportList *reports, struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag) RET_ZERO
+struct bAction *verify_adt_action(struct ID *id, short add) RET_NULL
char *WM_operator_pystring_ex(struct bContext *C, struct wmOperator *op, const bool all_args, const bool macro_args, struct wmOperatorType *ot, struct PointerRNA *opptr) RET_NULL
char *WM_operator_pystring(struct bContext *C, struct wmOperator *op, const bool all_args, const bool macro_args) RET_NULL
struct wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value) RET_NULL
struct wmKeyMapItem *WM_modalkeymap_add_item_str(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, const char *value) RET_NULL
struct wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, const char *idname, struct EnumPropertyItem *items) RET_NULL
-struct uiPopupMenu *uiPupMenuBegin(struct bContext *C, const char *title, int icon) RET_NULL
-void uiPupMenuEnd(struct bContext *C, struct uiPopupMenu *head) RET_NONE
-struct uiLayout *uiPupMenuLayout(struct uiPopupMenu *head) RET_NULL
-struct uiLayout *uiPieMenuLayout(struct uiPieMenu *pie) RET_NULL
-void uiPieMenuInvoke(struct bContext *C, const char *idname, const struct wmEvent *event) RET_NONE
-struct uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const struct wmEvent *event) RET_NULL
-void uiPieMenuEnd(struct bContext *C, uiPieMenu *pie) RET_NONE
+struct uiPopupMenu *UI_popup_menu_begin(struct bContext *C, const char *title, int icon) RET_NULL
+void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *head) RET_NONE
+struct uiLayout *UI_popup_menu_layout(struct uiPopupMenu *head) RET_NULL
+struct uiLayout *UI_pie_menu_layout(struct uiPieMenu *pie) RET_NULL
+int UI_pie_menu_invoke(struct bContext *C, const char *idname, const struct wmEvent *event) RET_ZERO
+struct uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, const struct wmEvent *event) RET_NULL
+void UI_pie_menu_end(struct bContext *C, uiPieMenu *pie) RET_NONE
struct uiLayout *uiLayoutRadial(struct uiLayout *layout) RET_NULL
-void uiPieOperatorEnumInvoke(struct bContext *C, const char *title, const char *opname,
- const char *propname, const struct wmEvent *event) RET_NONE
+int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title, const char *opname,
+ const char *propname, const struct wmEvent *event) RET_ZERO
/* RNA COLLADA dependency */
int collada_export(struct Scene *sce,
@@ -656,7 +673,7 @@ int collada_export(struct Scene *sce,
BC_export_transformation_type export_transformation_type,
int open_sim) RET_ZERO
-void ED_mesh_calc_tessface(struct Mesh *mesh) RET_NONE
+void ED_mesh_calc_tessface(struct Mesh *mesh, bool free_mpoly) RET_NONE
/* bpy/python internal api */
void operator_wrapper(struct wmOperatorType *ot, void *userdata) RET_NONE
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index de8abbd1088..9f3ee8b3935 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -81,6 +81,10 @@ if(WITH_GAMEENGINE)
endif()
if(WITH_SDL)
+ if(WITH_SDL_DYNLOAD)
+ add_definitions(-DWITH_SDL_DYNLOAD)
+ blender_include_dirs(../../extern/sdlew/include)
+ endif()
add_definitions(-DWITH_SDL)
endif()
@@ -211,6 +215,7 @@ if(WITH_PYTHON_MODULE)
set_target_properties(
blender
PROPERTIES
+ MACOSX_BUNDLE
LINK_FLAGS_RELEASE "${PLATFORM_LINKFLAGS}"
LINK_FLAGS_DEBUG "${PLATFORM_LINKFLAGS_DEBUG}"
)
@@ -236,15 +241,20 @@ endif()
# Post build steps for bundling/packaging.
-
-if(MSVC_IDE)
- # ${CMAKE_CFG_INTDIR} should replace \${BUILD_TYPE} when using add_command
- set(TARGETDIR ${EXECUTABLE_OUTPUT_PATH}/\${BUILD_TYPE})
-elseif(APPLE)
- set(TARGETDIR ${EXECUTABLE_OUTPUT_PATH}/\${BUILD_TYPE})
-else()
- set(TARGETDIR ${EXECUTABLE_OUTPUT_PATH})
-endif()
+function(install_text_files_patch path)
+ install(
+ CODE
+ "
+ set(DATA_FILE \"${path}/readme.html\")
+ file(READ \"\${DATA_FILE}\" DATA_SRC)
+ string(REGEX REPLACE \"BLENDER_VERSION\" \"${BLENDER_VERSION}\" DATA_DST \"\${DATA_SRC}\")
+ file(WRITE \"\${DATA_FILE}\" \"\${DATA_DST}\")
+ unset(DATA_FILE)
+ unset(DATA_SRC)
+ unset(DATA_DST)
+ "
+ )
+endfunction()
set(BLENDER_TEXT_FILES
${CMAKE_SOURCE_DIR}/release/text/GPL-license.txt
@@ -267,23 +277,23 @@ endif()
if(UNIX AND NOT APPLE)
if(WITH_INSTALL_PORTABLE)
- set(TARGETDIR_VER ${TARGETDIR}/${BLENDER_VERSION})
+ set(TARGETDIR_VER ${BLENDER_VERSION})
else()
if(WITH_PYTHON_MODULE)
set(TARGETDIR_VER ${PYTHON_LIBPATH}/python${PYTHON_VERSION}/site-packages/${BLENDER_VERSION})
else()
- set(TARGETDIR_VER ${CMAKE_INSTALL_PREFIX}/share/blender/${BLENDER_VERSION})
+ set(TARGETDIR_VER share/blender/${BLENDER_VERSION})
endif()
endif()
elseif(WIN32)
- set(TARGETDIR_VER ${TARGETDIR}/${BLENDER_VERSION})
+ set(TARGETDIR_VER ${BLENDER_VERSION})
elseif(APPLE)
if(WITH_PYTHON_MODULE)
- set(TARGETDIR_VER ${TARGETDIR}/${BLENDER_VERSION})
+ set(TARGETDIR_VER ${BLENDER_VERSION})
else()
- set(TARGETDIR_VER ${TARGETDIR}/blender.app/Contents/Resources/${BLENDER_VERSION})
+ set(TARGETDIR_VER blender.app/Contents/Resources/${BLENDER_VERSION})
endif()
endif()
@@ -401,74 +411,73 @@ endif()
if(UNIX AND NOT APPLE)
if(NOT WITH_PYTHON_MODULE)
- install(
- CODE
- "
- execute_process(COMMAND
- ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1.py
- ${TARGETDIR}/blender
- ${TARGETDIR}/blender.1)
- "
- )
+ if(WITH_DOC_MANPAGE)
+ add_custom_target(
+ blender_man_page ALL
+ COMMAND ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1.py
+ ${EXECUTABLE_OUTPUT_PATH}/blender
+ ${CMAKE_CURRENT_BINARY_DIR}/blender.1)
+ add_dependencies(blender_man_page blender)
+ endif()
endif()
# there are a few differences between portable and system install
if(WITH_INSTALL_PORTABLE)
+ if(WITH_PYTHON_MODULE)
+ # pass
+ else()
+ if(WITH_DOC_MANPAGE)
+ install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/blender.1
+ DESTINATION "."
+ )
+ endif()
+ endif()
install(
- FILES ${TARGETDIR}/blender.1
- DESTINATION ${TARGETDIR}
+ TARGETS blender
+ DESTINATION "."
)
install(
FILES
${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop
${CMAKE_SOURCE_DIR}/release/freedesktop/icons/scalable/apps/blender.svg
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
install(
PROGRAMS
${CMAKE_SOURCE_DIR}/release/bin/blender-thumbnailer.py
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
- install(
- FILES ${BLENDER_TEXT_FILES}
- DESTINATION ${TARGETDIR}
- )
+ set(BLENDER_TEXT_FILES_DESTINATION ".")
else()
# main blender binary
if(WITH_PYTHON_MODULE)
install(
TARGETS blender
- LIBRARY
- DESTINATION ${PYTHON_LIBPATH}/python${PYTHON_VERSION}/site-packages
+ LIBRARY DESTINATION ${PYTHON_LIBPATH}/python${PYTHON_VERSION}/site-packages
)
else()
install(
- PROGRAMS ${TARGETDIR}/blender
- DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
- )
- # manpage only with 'blender' binary
- install(
- FILES ${TARGETDIR}/blender.1
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1
- )
- endif()
-
-
- if(WITH_GAMEENGINE AND WITH_PLAYER)
- install(
- PROGRAMS ${TARGETDIR}/blenderplayer
- DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
+ TARGETS blender
+ DESTINATION bin
)
+ if(WITH_DOC_MANPAGE)
+ # manpage only with 'blender' binary
+ install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/blender.1
+ DESTINATION share/man/man1
+ )
+ endif()
endif()
# misc files
install(
FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications
+ DESTINATION share/applications
)
install(
DIRECTORY
@@ -478,21 +487,18 @@ if(UNIX AND NOT APPLE)
${CMAKE_SOURCE_DIR}/release/freedesktop/icons/32x32
${CMAKE_SOURCE_DIR}/release/freedesktop/icons/48x48
${CMAKE_SOURCE_DIR}/release/freedesktop/icons/256x256
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor
+ DESTINATION share/icons/hicolor
PATTERN "*.svg" EXCLUDE
)
install(
FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/icons/scalable/apps/blender.svg
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps
+ DESTINATION share/icons/hicolor/scalable/apps
)
install(
PROGRAMS ${CMAKE_SOURCE_DIR}/release/bin/blender-thumbnailer.py
- DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
- )
- install(
- FILES ${BLENDER_TEXT_FILES}
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/doc/blender
+ DESTINATION bin
)
+ set(BLENDER_TEXT_FILES_DESTINATION share/doc/blender)
endif()
if(WITH_PYTHON)
@@ -532,7 +538,7 @@ if(UNIX AND NOT APPLE)
)
# # doesnt work, todo
- # install(CODE "execute_process(COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/ -name '*.so' -exec strip -s {} '\;')")
+ # install(CODE "execute_process(COMMAND find ${CMAKE_INSTALL_PREFIX}/${BLENDER_VERSION}/python/lib/ -name '*.so' -exec strip -s {} '\;')")
if(WITH_PYTHON_INSTALL_NUMPY)
# Install to the same directory as the source, so debian-like
@@ -605,76 +611,77 @@ if(UNIX AND NOT APPLE)
endif()
elseif(WIN32)
- install(
- FILES ${BLENDER_TEXT_FILES}
- DESTINATION ${TARGETDIR}
- )
+ set(BLENDER_TEXT_FILES_DESTINATION ".")
if(WITH_PYTHON)
string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
install(
FILES ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}.dll ${LIBDIR}/python/lib/sqlite3.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
)
install(
FILES ${LIBDIR}/python/lib/python${_PYTHON_VERSION_NO_DOTS}_d.dll ${LIBDIR}/python/lib/sqlite3_d.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
CONFIGURATIONS Debug
)
if(WITH_PYTHON_INSTALL)
# note, as far as python is concerned 'RelWithDebInfo' is not debug since its without debug flags.
- # create the directory in multiple steps, so it actually gets created when it doesn't exist yet
- install(
- CODE
- "
- message(\"creating ${TARGETDIR_VER}/python/lib\")
- file(MAKE_DIRECTORY \"${TARGETDIR_VER}/python\")
- file(MAKE_DIRECTORY \"${TARGETDIR_VER}/python/lib\")
- message(\"done creating dir\")
- "
- )
+ install(DIRECTORY DESTINATION ${TARGETDIR_VER}/python)
+ install(DIRECTORY DESTINATION ${TARGETDIR_VER}/python/lib)
+ # WARNING: its important that 'CMAKE_INSTALL_CONFIG_NAME' is evaluated at build time
+ # and _NOT_ configuration time, when modifying the lines below,
+ # check it works in both Release & Debug mode.
+ #
+ # Edit with extreme care! - Campbell
+
+ # extract python
install(
CODE
"
- if(\"\${CMAKE_INSTALL_CONFIG_NAME}\" STREQUAL \"Debug\")
- execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib\"
- \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_d.tar.gz\")
+ message(STATUS \"Extracting Python to: \${CMAKE_INSTALL_PREFIX}/${BLENDER_VERSION}/python\")
+ if(\"\${CMAKE_INSTALL_CONFIG_NAME}\" MATCHES \"^([Dd][Ee][Bb][Uu][Gg])$\")
+ set(PYTHON_ZIP \"${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_d.tar.gz\")
else()
- execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib\"
- \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}.tar.gz\")
+ set(PYTHON_ZIP \"${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}.tar.gz\")
endif()
- "
- )
- if(WITH_PYTHON_INSTALL_NUMPY)
- install(
- CODE
- "
- execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib/site-packages\"
- \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_numpy_1.8.tar.gz\")
- "
+ execute_process(
+ COMMAND \${CMAKE_COMMAND} -E make_directory
+ \"\${CMAKE_INSTALL_PREFIX}/${BLENDER_VERSION}/python/lib\"
+ COMMAND \${CMAKE_COMMAND} -E
+ chdir \"\${CMAKE_INSTALL_PREFIX}/${BLENDER_VERSION}/python/lib\"
+ \${CMAKE_COMMAND} -E
+ tar xzfv \"\${PYTHON_ZIP}\"
)
- endif()
+ unset(PYTHON_ZIP)
+ "
+ )
# release/site-packages
install(
- CODE
- "
- execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy_directory
- ${LIBDIR}/release/site-packages
- \"${TARGETDIR_VER}/python/lib/site-packages\")
- "
+ DIRECTORY ${LIBDIR}/release/site-packages
+ DESTINATION ${BLENDER_VERSION}/python/lib
+ PATTERN ".svn" EXCLUDE
+ PATTERN "__pycache__" EXCLUDE # * any cache *
+ PATTERN "*.pyc" EXCLUDE # * any cache *
+ PATTERN "*.pyo" EXCLUDE # * any cache *)
)
-
- # doesnt work, todo
- # install(CODE "execute_process(COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/ -name '*.so' -exec strip -s {} '\;')")
+ if(WITH_PYTHON_INSTALL_NUMPY)
+ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages/numpy
+ COMMAND ${CMAKE_COMMAND} -E tar xzvf "${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_numpy_1.9.tar.gz"
+ DEPENDS ${LIBDIR}/release/python${_PYTHON_VERSION_NO_DOTS}_numpy_1.9.tar.gz
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages)
+ add_custom_target(python_numpy ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages/numpy)
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages/numpy
+ DESTINATION ${BLENDER_VERSION}/python/lib/site-packages)
+ endif()
endif()
unset(_PYTHON_VERSION_NO_DOTS)
@@ -683,11 +690,11 @@ elseif(WIN32)
# EGL Runtime Components
if(WITH_GL_EGL)
if(WIN32)
- install(FILES "${OPENGLES_DLL}" DESTINATION ${TARGETDIR})
- install(FILES "${OPENGLES_EGL_DLL}" DESTINATION ${TARGETDIR})
+ install(FILES "${OPENGLES_DLL}" DESTINATION ".")
+ install(FILES "${OPENGLES_EGL_DLL}" DESTINATION ".")
if(WITH_GL_ANGLE)
- install(FILES "${D3DCOMPILER_DLL}" DESTINATION ${TARGETDIR})
+ install(FILES "${D3DCOMPILER_DLL}" DESTINATION ".")
endif()
endif()
endif()
@@ -695,14 +702,14 @@ elseif(WIN32)
if(MSVC)
install(
FILES ${LIBDIR}/pthreads/lib/pthreadVC2.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
else()
#MinGW64 comes with own version. For portable builds it will probaly have to be copied to work
if(NOT WITH_MINGW64)
install(
FILES ${LIBDIR}/pthreads/lib/pthreadGC2.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
elseif(WITH_MINGW64)
install(
@@ -710,14 +717,14 @@ elseif(WIN32)
${LIBDIR}/binaries/libgcc_s_sjlj-1.dll
${LIBDIR}/binaries/libwinpthread-1.dll
${LIBDIR}/binaries/libstdc++-6.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
if(WITH_OPENMP)
install(
FILES
${LIBDIR}/binaries/libgomp-1.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
endif()
endif()
@@ -734,7 +741,7 @@ elseif(WIN32)
${LIBDIR}/ffmpeg/lib/swscale-2.dll
${LIBDIR}/ffmpeg/lib/swresample-0.dll
${LIBDIR}/ffmpeg/lib/xvidcore.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
else()
install(
@@ -744,7 +751,7 @@ elseif(WIN32)
${LIBDIR}/ffmpeg/lib/avdevice-55.dll
${LIBDIR}/ffmpeg/lib/avutil-52.dll
${LIBDIR}/ffmpeg/lib/swscale-2.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
endif()
endif()
@@ -752,7 +759,7 @@ elseif(WIN32)
if(WITH_CODEC_SNDFILE)
install(
FILES ${LIBDIR}/sndfile/lib/libsndfile-1.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
endif()
@@ -760,28 +767,27 @@ elseif(WIN32)
install(
FILES
${LIBDIR}/openal/lib/OpenAL32.dll
- ${LIBDIR}/openal/lib/wrap_oal.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
endif()
if(WITH_SDL)
install(
- FILES ${LIBDIR}/sdl/lib/SDL.dll
- DESTINATION ${TARGETDIR}
+ FILES ${LIBDIR}/sdl/lib/SDL2.dll
+ DESTINATION "."
)
endif()
if(NOT CMAKE_CL_64)
install(
FILES ${LIBDIR}/thumbhandler/lib/BlendThumb.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
endif()
install( # x86 builds can run on x64 Windows, so this is required at all times
FILES ${LIBDIR}/thumbhandler/lib/BlendThumb64.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
if(WITH_OPENCOLORIO)
@@ -790,13 +796,13 @@ elseif(WIN32)
install(
FILES
${OCIOBIN}/OpenColorIO.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
else()
install(
FILES
${OCIOBIN}/libOpenColorIO.dll
- DESTINATION ${TARGETDIR}
+ DESTINATION "."
)
endif()
endif()
@@ -824,41 +830,52 @@ elseif(APPLE)
set(OSX_APP_SOURCEDIR ${CMAKE_SOURCE_DIR}/release/darwin/blender.app)
# setup Info.plist
- execute_process(COMMAND date "+%Y-%m-%d" OUTPUT_VARIABLE BLENDER_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(COMMAND date "+%Y-%m-%d"
+ OUTPUT_VARIABLE BLENDER_DATE
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
set_target_properties(blender PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${OSX_APP_SOURCEDIR}/Contents/Info.plist
MACOSX_BUNDLE_SHORT_VERSION_STRING ${BLENDER_VERSION}
MACOSX_BUNDLE_LONG_VERSION_STRING "${BLENDER_VERSION} ${BLENDER_DATE}")
+ # Gather the date in finder-style
+ execute_process(COMMAND date "+%m/%d/%Y/%H:%M"
+ OUTPUT_VARIABLE SETFILE_DATE
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ # Give the bundle actual creation/modification date
+ execute_process(COMMAND SetFile -d ${SETFILE_DATE} -m ${SETFILE_DATE} ${EXECUTABLE_OUTPUT_PATH}/blender.app)
- # install release and app files
install(
- FILES ${BLENDER_TEXT_FILES}
- DESTINATION ${TARGETDIR}
+ TARGETS blender
+ DESTINATION "."
)
+ # install release and app files
+ set(BLENDER_TEXT_FILES_DESTINATION blender.app/Contents)
+
install(
FILES ${OSX_APP_SOURCEDIR}/Contents/PkgInfo
- DESTINATION ${TARGETDIR}/blender.app/Contents
+ DESTINATION blender.app/Contents
)
install_dir(
${OSX_APP_SOURCEDIR}/Contents/Resources
- \${TARGETDIR}/blender.app/Contents/
+ blender.app/Contents/
)
if(WITH_OPENMP AND CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS '3.4')
install(
FILES ${LIBDIR}/openmp/lib/libiomp5.dylib
- DESTINATION ${TARGETDIR}/blender.app/Contents/MacOS
+ DESTINATION blender.app/Contents/Resources/lib/
)
endif()
if(WITH_LLVM AND NOT LLVM_STATIC)
install(
FILES ${LIBDIR}/llvm/lib/libLLVM-3.4.dylib
- DESTINATION ${TARGETDIR}/blender.app/Contents/MacOS
+ DESTINATION blender.app/Contents/MacOS
)
endif()
@@ -901,7 +918,7 @@ elseif(APPLE)
if(WITH_GAMEENGINE AND WITH_PLAYER)
set(OSX_APP_PLAYER_SOURCEDIR ${CMAKE_SOURCE_DIR}/release/darwin/blenderplayer.app)
set(PLAYER_SOURCEINFO ${OSX_APP_PLAYER_SOURCEDIR}/Contents/Info.plist)
- set(PLAYER_TARGETDIR_VER ${TARGETDIR}/blenderplayer.app/Contents/Resources/${BLENDER_VERSION})
+ set(PLAYER_TARGETDIR_VER blenderplayer.app/Contents/Resources/${BLENDER_VERSION})
# important to make a clean install each time else old scripts get loaded.
@@ -910,15 +927,26 @@ elseif(APPLE)
"file(REMOVE_RECURSE ${PLAYER_TARGETDIR_VER})"
)
+ # Give the bundle actual creation/modification date
+ execute_process(COMMAND SetFile -d ${SETFILE_DATE} -m ${SETFILE_DATE} ${EXECUTABLE_OUTPUT_PATH}/blenderplayer.app)
+
install(
FILES ${OSX_APP_PLAYER_SOURCEDIR}/Contents/PkgInfo
- DESTINATION ${TARGETDIR}/blenderplayer.app/Contents
+ DESTINATION blenderplayer.app/Contents
)
install_dir(
${OSX_APP_PLAYER_SOURCEDIR}/Contents/Resources
- \${TARGETDIR}/blenderplayer.app/Contents/
+ blenderplayer.app/Contents/
+ )
+
+ if(WITH_OPENMP AND CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS '3.4')
+ install(
+ FILES ${LIBDIR}/openmp/lib/libiomp5.dylib
+ DESTINATION blenderplayer.app/Contents/Resources/lib/
)
+ endif()
+
# python
if(WITH_PYTHON AND NOT WITH_PYTHON_FRAMEWORK)
@@ -943,12 +971,20 @@ endif()
# -----------------------------------------------------------------------------
# Generic Install, for all targets
+if(DEFINED BLENDER_TEXT_FILES_DESTINATION)
+ install(
+ FILES ${BLENDER_TEXT_FILES}
+ DESTINATION "${BLENDER_TEXT_FILES_DESTINATION}"
+ )
+ install_text_files_patch("\${CMAKE_INSTALL_PREFIX}/${BLENDER_TEXT_FILES_DESTINATION}")
+endif()
# install more files specified elsewhere
delayed_do_install(${TARGETDIR_VER})
unset(BLENDER_TEXT_FILES)
+unset(BLENDER_TEXT_FILES_DESTINATION)
# -----------------------------------------------------------------------------
@@ -988,4 +1024,25 @@ if(WIN32 AND NOT WITH_PYTHON_MODULE)
set_target_properties(blender PROPERTIES OUTPUT_NAME blender-app)
set_target_properties(blender-launcher PROPERTIES OUTPUT_NAME blender)
+
+ install(TARGETS blender blender-launcher
+ COMPONENT Blender
+ DESTINATION ".")
+
+ if(MSVC12_REDIST_DIR)
+ if(CMAKE_CL_64)
+ set(_WIN_PLATFORM x64)
+ else()
+ set(_WIN_PLATFORM x86)
+ endif()
+ install(
+ FILES ${MSVC12_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC120.CRT/msvcp120.dll
+ ${MSVC12_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC120.CRT/msvcr120.dll
+ DESTINATION ".")
+ if(WITH_OPENMP)
+ install(
+ FILES ${MSVC12_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC120.OpenMP/vcomp120.dll
+ DESTINATION ".")
+ endif()
+ endif()
endif()
diff --git a/source/creator/blender.map b/source/creator/blender.map
index f583ddc1a89..359cbe0415f 100644
--- a/source/creator/blender.map
+++ b/source/creator/blender.map
@@ -18,5 +18,6 @@ local:
NumNamedVarArgParams;
X86CompilationCallback*;
*boost*;
+ *SDL*;
};
diff --git a/source/creator/creator.c b/source/creator/creator.c
index d779095c1ee..0ca5fbeccac 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -48,13 +48,6 @@
# include "utfconv.h"
#endif
-/* for backtrace */
-#if defined(__linux__) || defined(__APPLE__)
-# include <execinfo.h>
-#elif defined(_MSV_VER)
-# include <DbgHelp.h>
-#endif
-
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
@@ -82,6 +75,7 @@
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
+#include "BKE_appdir.h"
#include "BKE_blender.h"
#include "BKE_brush.h"
#include "BKE_context.h"
@@ -154,6 +148,10 @@
# include "CCL_api.h"
#endif
+#ifdef WITH_SDL_DYNLOAD
+# include "sdlew.h"
+#endif
+
/* from buildinfo.c */
#ifdef BUILD_DATE
extern char build_date[];
@@ -197,12 +195,13 @@ static void setCallbacks(void);
#ifndef WITH_PYTHON_MODULE
static bool use_crash_handler = true;
+static bool use_abort_handler = true;
/* set breakpoints here when running in debug mode, useful to catch floating point errors */
#if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
static void fpe_handler(int UNUSED(sig))
{
- // printf("SIGFPE trapped\n");
+ fprintf(stderr, "debug: SIGFPE trapped\n");
}
#endif
@@ -420,6 +419,12 @@ static int disable_crash_handler(int UNUSED(argc), const char **UNUSED(argv), vo
return 0;
}
+static int disable_abort_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
+{
+ use_abort_handler = false;
+ return 0;
+}
+
static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
G.background = 1;
@@ -511,73 +516,12 @@ static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(dat
return 0;
}
-#if defined(__linux__) || defined(__APPLE__)
-
-/* Unix */
static void blender_crash_handler_backtrace(FILE *fp)
{
-#define SIZE 100
- void *buffer[SIZE];
- int nptrs;
- char **strings;
- int i;
-
fputs("\n# backtrace\n", fp);
-
- /* include a backtrace for good measure */
- nptrs = backtrace(buffer, SIZE);
- strings = backtrace_symbols(buffer, nptrs);
- for (i = 0; i < nptrs; i++) {
- fputs(strings[i], fp);
- fputc('\n', fp);
- }
-
- free(strings);
-#undef SIZE
-}
-
-#elif defined(_MSC_VER)
-
-static void blender_crash_handler_backtrace(FILE *fp)
-{
- (void)fp;
-
-#if 0
-#define MAXSYMBOL 256
- unsigned short i;
- void *stack[SIZE];
- unsigned short nframes;
- SYMBOL_INFO *symbolinfo;
- HANDLE process;
-
- process = GetCurrentProcess();
-
- SymInitialize(process, NULL, true);
-
- nframes = CaptureStackBackTrace(0, SIZE, stack, NULL);
- symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof(char), "crash Symbol table");
- symbolinfo->MaxNameLen = MAXSYMBOL - 1;
- symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO);
-
- for (i = 0; i < nframes; i++) {
- SymFromAddr(process, ( DWORD64 )( stack[ i ] ), 0, symbolinfo);
-
- fprintf(fp, "%u: %s - 0x%0X\n", nframes - i - 1, symbolinfo->Name, symbolinfo->Address);
- }
-
- MEM_freeN(symbolinfo);
-#endif
-}
-
-#else /* non msvc/osx/linux */
-
-static void blender_crash_handler_backtrace(FILE *fp)
-{
- (void)fp;
+ BLI_system_backtrace(fp);
}
-#endif
-
static void blender_crash_handler(int signum)
{
@@ -586,7 +530,7 @@ static void blender_crash_handler(int signum)
char fname[FILE_MAX];
if (!G.main->name[0]) {
- BLI_make_file_string("/", fname, BLI_temp_dir_base(), "crash.blend");
+ BLI_make_file_string("/", fname, BKE_tempdir_base(), "crash.blend");
}
else {
BLI_strncpy(fname, G.main->name, sizeof(fname));
@@ -607,10 +551,10 @@ static void blender_crash_handler(int signum)
char fname[FILE_MAX];
if (!G.main->name[0]) {
- BLI_join_dirfile(fname, sizeof(fname), BLI_temp_dir_base(), "blender.crash.txt");
+ BLI_join_dirfile(fname, sizeof(fname), BKE_tempdir_base(), "blender.crash.txt");
}
else {
- BLI_join_dirfile(fname, sizeof(fname), BLI_temp_dir_base(), BLI_path_basename(G.main->name));
+ BLI_join_dirfile(fname, sizeof(fname), BKE_tempdir_base(), BLI_path_basename(G.main->name));
BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
}
@@ -642,7 +586,7 @@ static void blender_crash_handler(int signum)
}
/* Delete content of temp dir! */
- BLI_temp_dir_session_purge();
+ BKE_tempdir_session_purge();
/* really crash */
signal(signum, SIG_DFL);
@@ -653,6 +597,93 @@ static void blender_crash_handler(int signum)
#endif
}
+#ifdef WIN32
+LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
+{
+ switch (ExceptionInfo->ExceptionRecord->ExceptionCode) {
+ case EXCEPTION_ACCESS_VIOLATION:
+ fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr);
+ break;
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ fputs("Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr);
+ break;
+ case EXCEPTION_BREAKPOINT:
+ fputs("Error: EXCEPTION_BREAKPOINT\n", stderr);
+ break;
+ case EXCEPTION_DATATYPE_MISALIGNMENT:
+ fputs("Error: EXCEPTION_DATATYPE_MISALIGNMENT\n", stderr);
+ break;
+ case EXCEPTION_FLT_DENORMAL_OPERAND:
+ fputs("Error: EXCEPTION_FLT_DENORMAL_OPERAND\n", stderr);
+ break;
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ fputs("Error: EXCEPTION_FLT_DIVIDE_BY_ZERO\n", stderr);
+ break;
+ case EXCEPTION_FLT_INEXACT_RESULT:
+ fputs("Error: EXCEPTION_FLT_INEXACT_RESULT\n", stderr);
+ break;
+ case EXCEPTION_FLT_INVALID_OPERATION:
+ fputs("Error: EXCEPTION_FLT_INVALID_OPERATION\n", stderr);
+ break;
+ case EXCEPTION_FLT_OVERFLOW:
+ fputs("Error: EXCEPTION_FLT_OVERFLOW\n", stderr);
+ break;
+ case EXCEPTION_FLT_STACK_CHECK:
+ fputs("Error: EXCEPTION_FLT_STACK_CHECK\n", stderr);
+ break;
+ case EXCEPTION_FLT_UNDERFLOW:
+ fputs("Error: EXCEPTION_FLT_UNDERFLOW\n", stderr);
+ break;
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ fputs("Error: EXCEPTION_ILLEGAL_INSTRUCTION\n", stderr);
+ break;
+ case EXCEPTION_IN_PAGE_ERROR:
+ fputs("Error: EXCEPTION_IN_PAGE_ERROR\n", stderr);
+ break;
+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
+ fputs("Error: EXCEPTION_INT_DIVIDE_BY_ZERO\n", stderr);
+ break;
+ case EXCEPTION_INT_OVERFLOW:
+ fputs("Error: EXCEPTION_INT_OVERFLOW\n", stderr);
+ break;
+ case EXCEPTION_INVALID_DISPOSITION:
+ fputs("Error: EXCEPTION_INVALID_DISPOSITION\n", stderr);
+ break;
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
+ fputs("Error: EXCEPTION_NONCONTINUABLE_EXCEPTION\n", stderr);
+ break;
+ case EXCEPTION_PRIV_INSTRUCTION:
+ fputs("Error: EXCEPTION_PRIV_INSTRUCTION\n", stderr);
+ break;
+ case EXCEPTION_SINGLE_STEP:
+ fputs("Error: EXCEPTION_SINGLE_STEP\n", stderr);
+ break;
+ case EXCEPTION_STACK_OVERFLOW:
+ fputs("Error: EXCEPTION_STACK_OVERFLOW\n", stderr);
+ break;
+ default:
+ fputs("Error: Unrecognized Exception\n", stderr);
+ break;
+ }
+
+ fflush(stderr);
+
+ /* If this is a stack overflow then we can't walk the stack, so just show
+ * where the error happened */
+ if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) {
+ blender_crash_handler(SIGSEGV);
+ }
+
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+#endif
+
+
+static void blender_abort_handler(int UNUSED(signum))
+{
+ /* Delete content of temp dir! */
+ BKE_tempdir_session_purge();
+}
static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
@@ -818,7 +849,7 @@ static int set_engine(int argc, const char **argv, void *data)
{
bContext *C = data;
if (argc >= 2) {
- if (!strcmp(argv[1], "help")) {
+ if (STREQ(argv[1], "help")) {
RenderEngineType *type = NULL;
printf("Blender Engine Listing:\n");
for (type = R_engines.first; type; type = type->next) {
@@ -836,6 +867,7 @@ static int set_engine(int argc, const char **argv, void *data)
}
else {
printf("\nError: engine not found '%s'\n", argv[1]);
+ exit(1);
}
}
else {
@@ -987,11 +1019,11 @@ static int set_ge_parameters(int argc, const char **argv, void *data)
SYS_WriteCommandLineInt(syshandle, argv[a], 1);
#endif
/* doMipMap */
- if (!strcmp(argv[a], "nomipmap")) {
+ if (STREQ(argv[a], "nomipmap")) {
GPU_set_mipmap(0); //doMipMap = 0;
}
/* linearMipMap */
- if (!strcmp(argv[a], "linearmipmap")) {
+ if (STREQ(argv[a], "linearmipmap")) {
GPU_set_linear_mipmap(1); //linearMipMap = 1;
}
@@ -1191,7 +1223,7 @@ static int run_python_file(int argc, const char **argv, void *data)
return 0;
}
#else
- (void)argc; (void)argv; (void)data; /* unused */
+ UNUSED_VARS(argc, argv, data);
printf("This blender was built without python support\n");
return 0;
#endif /* WITH_PYTHON */
@@ -1221,7 +1253,7 @@ static int run_python_text(int argc, const char **argv, void *data)
return 0;
}
#else
- (void)argc; (void)argv; (void)data; /* unused */
+ UNUSED_VARS(argc, argv, data);
printf("This blender was built without python support\n");
return 0;
#endif /* WITH_PYTHON */
@@ -1236,7 +1268,7 @@ static int run_python_console(int UNUSED(argc), const char **argv, void *data)
return 0;
#else
- (void)argv; (void)data; /* unused */
+ UNUSED_VARS(argv, data);
printf("This blender was built without python support\n");
return 0;
#endif /* WITH_PYTHON */
@@ -1254,7 +1286,7 @@ static int set_addons(int argc, const char **argv, void *data)
BPY_CTX_SETUP(BPY_string_exec(C, str));
free(str);
#else
- (void)argv; (void)data; /* unused */
+ UNUSED_VARS(argv, data);
#endif /* WITH_PYTHON */
return 1;
}
@@ -1303,7 +1335,14 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
CTX_wm_manager_set(C, NULL); /* remove wm to force check */
WM_check(C);
- G.relbase_valid = 1;
+ if (bmain->name[0]) {
+ G.save_over = 1;
+ G.relbase_valid = 1;
+ }
+ else {
+ G.save_over = 0;
+ G.relbase_valid = 0;
+ }
if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
/* WM_file_read would call normally */
@@ -1409,6 +1448,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL);
+ BLI_argsAdd(ba, 1, NULL, "--disable-abort-handler", "\n\tDisable the abort handler", disable_abort_handler, NULL);
#undef PY_ENABLE_AUTO
#undef PY_DISABLE_AUTO
@@ -1586,6 +1626,10 @@ int main(
}
#endif
+#ifdef WITH_SDL_DYNLOAD
+ sdlewInit();
+#endif
+
C = CTX_create();
#ifdef WITH_PYTHON_MODULE
@@ -1610,13 +1654,28 @@ int main(
#endif
setCallbacks();
+
+#if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
+/* patch to ignore argument finder gives us (pid?) */
+ if (argc == 2 && STREQLEN(argv[1], "-psn_", 5)) {
+ extern int GHOST_HACK_getFirstFile(char buf[]);
+ static char firstfilebuf[512];
+
+ argc = 1;
+ if (GHOST_HACK_getFirstFile(firstfilebuf)) {
+ argc = 2;
+ argv[1] = firstfilebuf;
+ }
+ }
+#endif
+
#ifdef __FreeBSD__
fpsetmask(0);
#endif
/* initialize path to executable */
- BLI_init_program_path(argv[0]);
+ BKE_appdir_program_path_init(argv[0]);
BLI_threadapi_init();
@@ -1647,9 +1706,18 @@ int main(
BLI_argsParse(ba, 1, NULL, NULL);
if (use_crash_handler) {
+#ifdef WIN32
+ SetUnhandledExceptionFilter(windows_exception_handler);
+#else
/* after parsing args */
signal(SIGSEGV, blender_crash_handler);
+#endif
+ }
+
+ if (use_abort_handler) {
+ signal(SIGABRT, blender_abort_handler);
}
+
#else
G.factory_startup = true; /* using preferences or user startup makes no sense for py-as-module */
(void)syshandle;
@@ -1695,7 +1763,7 @@ int main(
/* this is properly initialized with user defs, but this is default */
/* call after loading the startup.blend so we can read U.tempdir */
- BLI_temp_dir_init(U.tempdir);
+ BKE_tempdir_init(U.tempdir);
}
else {
#ifndef WITH_PYTHON_MODULE
@@ -1705,7 +1773,7 @@ int main(
WM_init(C, argc, (const char **)argv);
/* don't use user preferences temp dir */
- BLI_temp_dir_init(NULL);
+ BKE_tempdir_init(NULL);
}
#ifdef WITH_PYTHON
/**
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 2a7e631637e..511b61528f8 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -280,8 +280,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0);
#endif
// bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0);
- bool mouse_state = startscene->gm.flag & GAME_SHOW_MOUSE;
- bool restrictAnimFPS = startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES;
+ bool mouse_state = (startscene->gm.flag & GAME_SHOW_MOUSE) != 0;
+ bool restrictAnimFPS = (startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES) != 0;
short drawtype = v3d->drawtype;
@@ -457,21 +457,13 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO));
ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat));
ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat));
- if (rv3d->persp == RV3D_ORTHO)
- {
- ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far);
- }
- else
- {
- ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far);
- }
+ ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far);
ketsjiengine->SetCameraOverrideLens(v3d->lens);
}
// create a scene converter, create and convert the startingscene
KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine);
ketsjiengine->SetSceneConverter(sceneconverter);
- sceneconverter->addInitFromFrame=false;
if (always_use_expand_framing)
sceneconverter->SetAlwaysUseExpandFraming(true);
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
index 31f3b1b2047..3a31806fad4 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
@@ -67,6 +67,7 @@ m_frame_rect(rect)
// area boundaries needed for mouse coordinates in Letterbox framing mode
m_area_left = ar->winrct.xmin;
m_area_top = ar->winrct.ymax;
+ m_frame = 1;
glGetIntegerv(GL_VIEWPORT, (GLint *)m_viewport);
}
@@ -350,7 +351,9 @@ void KX_BlenderCanvas::MakeScreenShot(const char *filename)
char path[FILE_MAX];
BLI_strncpy(path, filename, sizeof(path));
BLI_path_abs(path, G.main->name);
- BKE_add_image_extension_from_type(path, im_format.imtype);
+ BLI_path_frame(path, m_frame, 0);
+ m_frame++;
+ BKE_image_path_ensure_ext_from_imtype(path, im_format.imtype);
/* create and save imbuf */
ImBuf *ibuf = IMB_allocImBuf(dumpsx, dumpsy, 24, 0);
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
index 917e0136cb1..c150af21230 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
@@ -210,6 +210,7 @@ private:
RAS_Rect m_area_rect;
int m_area_left;
int m_area_top;
+ int m_frame;
#ifdef WITH_CXX_GUARDEDALLOC
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index 3dd013dfd63..c756d8695e6 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -256,12 +256,14 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
if ((m_flag & ACT_FLAG_PLAY_END) && (m_flag & ACT_FLAG_ACTIVE) && obj->IsActionDone(m_layer))
{
m_flag &= ~ACT_FLAG_ACTIVE;
- m_flag &= ~ACT_FLAG_ATTEMPT_PLAY;
- if (m_playtype == ACT_ACTION_PINGPONG)
+ if (m_playtype == ACT_ACTION_PINGPONG) {
m_flag ^= ACT_FLAG_REVERSE;
- else
+ }
+ else {
+ m_flag &= ~ACT_FLAG_ATTEMPT_PLAY;
return false;
+ }
}
// If a different action is playing, we've been overruled and are no longer active
@@ -320,8 +322,9 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
case ACT_ACTION_FLIPPER:
// Convert into a play action and play back to the beginning
+ float temp = end;
end = start;
- start = obj->GetActionFrame(m_layer);
+ start = curr_action ? obj->GetActionFrame(m_layer) : temp;
obj->PlayAction(m_action->id.name+2, start, end, m_layer, m_priority, 0, BL_Action::ACT_MODE_PLAY, m_layer_weight, m_ipo_flags, 1.f, blendmode);
m_flag |= ACT_FLAG_PLAY_END;
diff --git a/source/gameengine/Converter/BL_ArmatureChannel.cpp b/source/gameengine/Converter/BL_ArmatureChannel.cpp
index cb33ff0e1e3..2b8dfd8f8d1 100644
--- a/source/gameengine/Converter/BL_ArmatureChannel.cpp
+++ b/source/gameengine/Converter/BL_ArmatureChannel.cpp
@@ -295,7 +295,7 @@ PyObject *BL_ArmatureChannel::py_attr_get_joint_rotation(void *self_v, const str
mul_v3_fl(joints,norm);
break;
}
- return Vector_CreatePyObject(joints, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(joints, 3, NULL);
}
int BL_ArmatureChannel::py_attr_set_joint_rotation(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
index e01130a8970..bc2fc0179fd 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -234,6 +234,9 @@ BL_ArmatureObject::BL_ArmatureObject(
// need this to get iTaSC working ok in the BGE
m_pose->flag |= POSE_GAME_ENGINE;
memcpy(m_obmat, m_objArma->obmat, sizeof(m_obmat));
+
+ // The side-effect of this method registers this object as "animatable" with the KX_Scene.
+ GetActionManager();
}
BL_ArmatureObject::~BL_ArmatureObject()
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 87b64582e11..7e0588fc7d0 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -52,23 +52,13 @@
#include <algorithm>
#include "BL_BlenderDataConversion.h"
-#include "KX_BlenderScalarInterpolator.h"
-#include "RAS_IPolygonMaterial.h"
-
-// Expressions
-#include "ListValue.h"
-#include "IntValue.h"
-// Collision & Fuzzics LTD
+#include "MT_Transform.h"
+#include "MT_MinMax.h"
#include "PHY_Pro.h"
#include "PHY_IPhysicsEnvironment.h"
-#include "PHY_DynamicTypes.h"
-
-#include "KX_Scene.h"
-#include "KX_GameObject.h"
-#include "RAS_FramingManager.h"
#include "RAS_MeshObject.h"
#include "RAS_IRasterizer.h"
#include "RAS_ILightObject.h"
@@ -76,31 +66,27 @@
#include "KX_ConvertActuators.h"
#include "KX_ConvertControllers.h"
#include "KX_ConvertSensors.h"
-
#include "SCA_LogicManager.h"
-#include "SCA_EventManager.h"
#include "SCA_TimeEventManager.h"
+
+#include "KX_ClientObjectInfo.h"
+#include "KX_Scene.h"
+#include "KX_GameObject.h"
#include "KX_Light.h"
#include "KX_Camera.h"
-#include "KX_ClientObjectInfo.h"
#include "KX_EmptyObject.h"
#include "KX_FontObject.h"
-#include "MT_Point3.h"
-#include "MT_Transform.h"
-#include "MT_MinMax.h"
-#include "SCA_IInputDevice.h"
+
#include "RAS_TexMatrix.h"
#include "RAS_ICanvas.h"
-#include "RAS_MaterialBucket.h"
-//#include "KX_BlenderPolyMaterial.h"
#include "RAS_Polygon.h"
#include "RAS_TexVert.h"
#include "RAS_BucketManager.h"
+#include "RAS_IPolygonMaterial.h"
#include "BL_Material.h"
#include "KX_BlenderMaterial.h"
#include "BL_Texture.h"
-#include "DNA_action_types.h"
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_object.h"
@@ -109,9 +95,9 @@
#include "BL_SkinDeformer.h"
#include "BL_MeshDeformer.h"
#include "KX_SoftBodyDeformer.h"
-//#include "BL_ArmatureController.h"
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
+
#include "BlenderWorldInfo.h"
#include "KX_KetsjiEngine.h"
@@ -143,13 +129,14 @@
#include "DNA_sound_types.h"
#include "DNA_key_types.h"
#include "DNA_armature_types.h"
+#include "DNA_action_types.h"
#include "DNA_object_force.h"
+#include "DNA_constraint_types.h"
#include "MEM_guardedalloc.h"
#include "BKE_key.h"
#include "BKE_mesh.h"
-#include "MT_Point3.h"
#include "BLI_math.h"
@@ -170,29 +157,19 @@ extern Material defmaterial; /* material.c */
#include "KX_BlenderInputDevice.h"
#include "KX_ConvertProperties.h"
-#include "KX_HashedPtr.h"
-
-
-#include "KX_ScalarInterpolator.h"
-
-#include "KX_IpoConvert.h"
-#include "BL_System.h"
#include "SG_Node.h"
#include "SG_BBox.h"
#include "SG_Tree.h"
+#include "KX_SG_NodeRelationships.h"
+#include "KX_SG_BoneParentNodeRelationship.h"
#ifdef WITH_BULLET
#include "CcdPhysicsEnvironment.h"
#include "CcdGraphicController.h"
#endif
-#include "KX_MotionState.h"
-
-// This file defines relationships between parents and children
-// in the game engine.
-#include "KX_SG_NodeRelationships.h"
-#include "KX_SG_BoneParentNodeRelationship.h"
+#include "KX_MotionState.h"
#include "BL_ArmatureObject.h"
#include "BL_DeformableGameObject.h"
@@ -200,18 +177,9 @@ extern Material defmaterial; /* material.c */
#include "KX_NavMeshObject.h"
#include "KX_ObstacleSimulation.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-//XXX void update_for_newframe();
-//void BKE_scene_update_for_newframe(struct Scene *sce, unsigned int lay);
-//void do_all_data_ipos(void);
-#ifdef __cplusplus
-}
-#endif
-
#include "BLI_threads.h"
+
static bool default_light_mode = 0;
static std::map<int, SCA_IInputDevice::KX_EnumInputs> create_translate_table()
@@ -389,6 +357,11 @@ static std::map<int, SCA_IInputDevice::KX_EnumInputs> create_translate_table()
static std::map<int, SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable = create_translate_table();
+SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code)
+{
+ return gReverseKeyTranslateTable[key_code];
+}
+
static unsigned int KX_rgbaint2uint_new(unsigned int icol)
{
union
@@ -889,10 +862,10 @@ static bool ConvertMaterial(
// swap the material color, so MCol on bitmap font works
if (validmat && (use_vcol == false) && (mat->game.flag & GEMAT_TEXT))
{
- rgb[0] = KX_rgbaint2uint_new(rgb[0]);
- rgb[1] = KX_rgbaint2uint_new(rgb[1]);
- rgb[2] = KX_rgbaint2uint_new(rgb[2]);
- rgb[3] = KX_rgbaint2uint_new(rgb[3]);
+ material->rgb[0] = KX_rgbaint2uint_new(rgb[0]);
+ material->rgb[1] = KX_rgbaint2uint_new(rgb[1]);
+ material->rgb[2] = KX_rgbaint2uint_new(rgb[2]);
+ material->rgb[3] = KX_rgbaint2uint_new(rgb[3]);
}
if (validmat)
@@ -1389,16 +1362,14 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
}
bool isCompoundChild = false;
- bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD);
+ bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD) && !(blenderobject->gameflag & OB_SOFT_BODY);
/* When the parent is not OB_DYNAMIC and has no OB_COLLISION then it gets no bullet controller
- * and cant be apart of the parents compound shape */
+ * and cant be apart of the parents compound shape, same goes for OB_SOFT_BODY */
if (parent && (parent->gameflag & (OB_DYNAMIC | OB_COLLISION))) {
-
- if ((parent->gameflag & OB_CHILD) != 0 && (blenderobject->gameflag & OB_CHILD))
- {
+ if( (parent->gameflag & OB_CHILD)!=0 && (blenderobject->gameflag & OB_CHILD) && !(parent->gameflag & OB_SOFT_BODY)) {
isCompoundChild = true;
- }
+ }
}
if (processCompoundChildren != isCompoundChild)
return;
@@ -1568,7 +1539,7 @@ static KX_GameObject *gameobject_from_blenderobject(
gameobj->AddMesh(meshobj);
// gather levels of detail
- if (BLI_countlist(&ob->lodlevels) > 1) {
+ if (BLI_listbase_count_ex(&ob->lodlevels, 2) > 1) {
LodLevel *lod = ((LodLevel*)ob->lodlevels.first)->next;
Mesh* lodmesh = mesh;
Object* lodmatob = ob;
@@ -1711,9 +1682,6 @@ struct parentChildLink {
SG_Node* m_gamechildnode;
};
-#include "DNA_constraint_types.h"
-//XXX #include "BIF_editconstraint.h"
-
static bPoseChannel *get_active_posechannel2(Object *ob)
{
bArmature *arm= (bArmature*)ob->data;
@@ -1747,20 +1715,15 @@ static ListBase *get_active_constraints2(Object *ob)
return NULL;
}
-static void UNUSED_FUNCTION(RBJconstraints)(Object *ob)//not used
+static void UNUSED_FUNCTION(print_active_constraints2)(Object *ob) //not used, use to debug
{
- ListBase *conlist;
- bConstraint *curcon;
-
- conlist = get_active_constraints2(ob);
+ bConstraint* curcon;
+ ListBase* conlist = get_active_constraints2(ob);
if (conlist) {
for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) {
-
printf("%i\n",curcon->type);
}
-
-
}
}
@@ -1782,8 +1745,7 @@ static KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist)
* note: all var names match args are passed from the caller */
static void bl_ConvertBlenderObject_Single(
KX_BlenderSceneConverter *converter,
- Scene *blenderscene, Object *blenderobject,
- vector<MT_Vector3> &inivel, vector<MT_Vector3> &iniang,
+ Object *blenderobject,
vector<parentChildLink> &vec_parent_child,
CListValue* logicbrick_conversionlist,
CListValue* objectlist, CListValue* inactivelist, CListValue* sumolist,
@@ -1792,10 +1754,6 @@ static void bl_ConvertBlenderObject_Single(
bool isInActiveLayer
)
{
- MT_Point3 posPrev;
- MT_Matrix3x3 angor;
- if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra;
-
MT_Point3 pos(
blenderobject->loc[0]+blenderobject->dloc[0],
blenderobject->loc[1]+blenderobject->dloc[1],
@@ -1809,35 +1767,6 @@ static void bl_ConvertBlenderObject_Single(
MT_Vector3 scale(blenderobject->size);
- if (converter->addInitFromFrame) {//rcruiz
- blenderscene->r.cfra=blenderscene->r.sfra-1;
- //XXX update_for_newframe();
- MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
- blenderobject->loc[1]+blenderobject->dloc[1],
- blenderobject->loc[2]+blenderobject->dloc[2]
- );
-
- float rotmatPrev[3][3];
- BKE_object_rot_to_mat3(blenderobject, rotmatPrev, false);
-
- float eulxyz[3], eulxyzPrev[3];
- mat3_to_eul(eulxyz, rotmat);
- mat3_to_eul(eulxyzPrev, rotmatPrev);
-
- double fps = (double) blenderscene->r.frs_sec/
- (double) blenderscene->r.frs_sec_base;
-
- tmp.scale(fps, fps, fps);
- inivel.push_back(tmp);
- tmp[0]=eulxyz[0]-eulxyzPrev[0];
- tmp[1]=eulxyz[1]-eulxyzPrev[1];
- tmp[2]=eulxyz[2]-eulxyzPrev[2];
- tmp.scale(fps, fps, fps);
- iniang.push_back(tmp);
- blenderscene->r.cfra=blenderscene->r.sfra;
- //XXX update_for_newframe();
- }
-
gameobj->NodeSetLocalPosition(pos);
gameobj->NodeSetLocalOrientation(rotation);
gameobj->NodeSetLocalScale(scale);
@@ -1850,7 +1779,7 @@ static void bl_ConvertBlenderObject_Single(
gameobj->SetName(blenderobject->id.name + 2);
// update children/parent hierarchy
- if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
+ if (blenderobject->parent != 0)
{
// blender has an additional 'parentinverse' offset in each object
SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc);
@@ -1909,10 +1838,6 @@ static void bl_ConvertBlenderObject_Single(
logicbrick_conversionlist->Add(gameobj->AddRef());
- if (converter->addInitFromFrame) {
- posPrev=gameobj->NodeGetWorldPosition();
- angor=gameobj->NodeGetWorldOrientation();
- }
if (isInActiveLayer)
{
objectlist->Add(gameobj->AddRef());
@@ -1920,7 +1845,6 @@ static void bl_ConvertBlenderObject_Single(
gameobj->NodeUpdateGS(0);
gameobj->AddMeshUser();
-
}
else
{
@@ -1928,11 +1852,6 @@ static void bl_ConvertBlenderObject_Single(
//at the end of this function if it is not a root object
inactivelist->Add(gameobj->AddRef());
}
-
- if (converter->addInitFromFrame) {
- gameobj->NodeSetLocalPosition(posPrev);
- gameobj->NodeSetLocalOrientation(angor);
- }
}
@@ -1951,8 +1870,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
#define BL_CONVERTBLENDEROBJECT_SINGLE \
bl_ConvertBlenderObject_Single(converter, \
- blenderscene, blenderobject, \
- inivel, iniang, \
+ blenderobject, \
vec_parent_child, \
logicbrick_conversionlist, \
objectlist, inactivelist, sumolist, \
@@ -1974,7 +1892,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
RAS_FrameSettings::RAS_FrameType frame_type;
int aspect_width;
int aspect_height;
- vector<MT_Vector3> inivel,iniang;
set<Group*> grouplist; // list of groups to be converted
set<Object*> allblobj; // all objects converted
set<Object*> groupobj; // objects from groups (never in active layer)
@@ -2061,23 +1978,15 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
rendertools,
converter,
libloading);
-
- bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
- bool addobj=true;
-
- if (converter->addInitFromFrame)
- if (!isInActiveLayer)
- addobj=false;
+ bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
if (gameobj)
{
- if (addobj)
- { /* macro calls object conversion funcs */
- BL_CONVERTBLENDEROBJECT_SINGLE;
+ /* macro calls object conversion funcs */
+ BL_CONVERTBLENDEROBJECT_SINGLE;
- if (gameobj->IsDupliGroup()) {
- grouplist.insert(blenderobject->dup_group);
- }
+ if (gameobj->IsDupliGroup()) {
+ grouplist.insert(blenderobject->dup_group);
}
/* Note about memory leak issues:
@@ -2121,22 +2030,12 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
rendertools,
converter,
libloading);
-
- // this code is copied from above except that
- // object from groups are never in active layer
- bool isInActiveLayer = false;
- bool addobj=true;
-
- if (converter->addInitFromFrame)
- if (!isInActiveLayer)
- addobj=false;
+ bool isInActiveLayer = false;
if (gameobj)
{
- if (addobj)
- { /* macro calls object conversion funcs */
- BL_CONVERTBLENDEROBJECT_SINGLE;
- }
+ /* macro calls object conversion funcs */
+ BL_CONVERTBLENDEROBJECT_SINGLE;
if (gameobj->IsDupliGroup())
{
@@ -2146,7 +2045,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
}
-
/* see comment above re: mem leaks */
gameobj->Release();
}
@@ -2338,7 +2236,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
bool processCompoundChildren = false;
-
// create physics information
for (i=0;i<sumolist->GetCount();i++)
{
@@ -2369,32 +2266,19 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,converter,processCompoundChildren);
}
-
- //set ini linearVel and int angularVel //rcruiz
- if (converter->addInitFromFrame)
- for (i=0;i<sumolist->GetCount();i++)
- {
- KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
- if (gameobj->IsDynamic()) {
- gameobj->setLinearVelocity(inivel[i],false);
- gameobj->setAngularVelocity(iniang[i],false);
- }
-
-
- }
- // create physics joints
+ // create physics joints
for (i=0;i<sumolist->GetCount();i++)
{
KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
struct Object* blenderobject = gameobj->GetBlenderObject();
ListBase *conlist;
bConstraint *curcon;
- conlist = get_active_constraints2(blenderobject);
if ((gameobj->GetLayer()&activeLayerBitInfo)==0)
continue;
+ conlist = get_active_constraints2(blenderobject);
if (conlist) {
for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) {
if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT) {
@@ -2405,15 +2289,13 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
PHY_IPhysicsController* physctr2 = 0;
- if (dat->tar)
- {
+ if (dat->tar) {
KX_GameObject *gotar=getGameOb(dat->tar->id.name+2,sumolist);
if (gotar && ((gotar->GetLayer()&activeLayerBitInfo)!=0) && gotar->GetPhysicsController())
physctr2 = gotar->GetPhysicsController();
}
- if (gameobj->GetPhysicsController())
- {
+ if (gameobj->GetPhysicsController()) {
PHY_IPhysicsController* physctrl = gameobj->GetPhysicsController();
//we need to pass a full constraint frame, not just axis
@@ -2422,62 +2304,47 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
MT_Vector3 axis0 = localCFrame.getColumn(0);
MT_Vector3 axis1 = localCFrame.getColumn(1);
MT_Vector3 axis2 = localCFrame.getColumn(2);
-
+
int constraintId = kxscene->GetPhysicsEnvironment()->CreateConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,
(float)dat->pivY,(float)dat->pivZ,
(float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
(float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
(float)axis2.x(),(float)axis2.y(),(float)axis2.z(),dat->flag);
- if (constraintId)
- {
+ if (constraintId) {
//if it is a generic 6DOF constraint, set all the limits accordingly
- if (dat->type == PHY_GENERIC_6DOF_CONSTRAINT)
- {
+ if (dat->type == PHY_GENERIC_6DOF_CONSTRAINT) {
int dof;
int dofbit=1;
- for (dof=0;dof<6;dof++)
- {
- if (dat->flag & dofbit)
- {
+ for (dof=0;dof<6;dof++) {
+ if (dat->flag & dofbit) {
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
- } else
- {
+ } else {
//minLimit > maxLimit means free(disabled limit) for this degree of freedom
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1);
}
dofbit<<=1;
}
- }
- else if (dat->type == PHY_CONE_TWIST_CONSTRAINT)
- {
+ } else if (dat->type == PHY_CONE_TWIST_CONSTRAINT) {
int dof;
int dofbit = 1<<3; // bitflag use_angular_limit_x
-
- for (dof=3;dof<6;dof++)
- {
- if (dat->flag & dofbit)
- {
+
+ for (dof=3;dof<6;dof++) {
+ if (dat->flag & dofbit) {
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
- }
- else
- {
+ } else {
//maxLimit < 0 means free(disabled limit) for this degree of freedom
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1);
}
dofbit<<=1;
}
- }
- else if (dat->type == PHY_LINEHINGE_CONSTRAINT)
- {
+ } else if (dat->type == PHY_LINEHINGE_CONSTRAINT) {
int dof = 3; // dof for angular x
int dofbit = 1<<3; // bitflag use_angular_limit_x
-
- if (dat->flag & dofbit)
- {
+
+ if (dat->flag & dofbit) {
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,
dat->minLimit[dof],dat->maxLimit[dof]);
- } else
- {
+ } else {
//minLimit > maxLimit means free(disabled limit) for this degree of freedom
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1);
}
@@ -2537,8 +2404,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
}
-#define CONVERT_LOGIC
-#ifdef CONVERT_LOGIC
// convert logic bricks, sensors, controllers and actuators
for (i=0;i<logicbrick_conversionlist->GetCount();i++)
{
@@ -2573,8 +2438,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->ResetState();
}
-#endif //CONVERT_LOGIC
-
logicbrick_conversionlist->Release();
// Calculate the scene btree -
@@ -2601,7 +2464,3 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
bucketmanager->OptimizeBuckets(distance);
}
-SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code)
-{
- return gReverseKeyTranslateTable[key_code];
-}
diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp
index 71dc1bdec87..3bc07113ff6 100644
--- a/source/gameengine/Converter/BL_ModifierDeformer.cpp
+++ b/source/gameengine/Converter/BL_ModifierDeformer.cpp
@@ -186,6 +186,7 @@ bool BL_ModifierDeformer::Update(void)
m_dm->release(m_dm);
// HACK! use deformedOnly as a user counter
m_dm->deformedOnly = 1;
+ DM_update_materials(m_dm, blendobj);
/* update the graphic controller */
PHY_IGraphicController *ctrl = m_gameobj->GetGraphicController();
if (ctrl) {
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
index e7137a5c379..950c1dcad11 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.cpp
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -200,12 +200,14 @@ void BL_SkinDeformer::BGEDeformVerts()
Object *par_arma = m_armobj->GetArmatureObject();
MDeformVert *dverts = m_bmesh->dvert;
bDeformGroup *dg;
- int defbase_tot = BLI_countlist(&m_objMesh->defbase);
+ int defbase_tot;
Eigen::Matrix4f pre_mat, post_mat, chan_mat, norm_chan_mat;
if (!dverts)
return;
+ defbase_tot = BLI_listbase_count(&m_objMesh->defbase);
+
if (m_dfnrToPC == NULL)
{
m_dfnrToPC = new bPoseChannel*[defbase_tot];
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index a20ebb3a081..09cc74d717f 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -69,6 +69,7 @@
#include "DNA_scene_types.h"
#include "DNA_world_types.h"
#include "BKE_main.h"
+#include "BKE_fcurve.h"
#include "BLI_math.h"
@@ -87,6 +88,7 @@ extern "C"
#include "BKE_mesh.h" // BKE_mesh_copy
#include "DNA_space_types.h"
#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
#include "RNA_define.h"
#include "../../blender/editors/include/ED_keyframing.h"
}
@@ -527,76 +529,59 @@ void KX_BlenderSceneConverter::CacheBlenderMaterial(KX_Scene *scene, struct Mate
m_mat_cache[scene][mat] = blmat;
}
+
BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(KX_Scene *scene, struct Material *mat)
{
return (m_use_mat_cache) ? m_mat_cache[scene][mat] : NULL;
}
-void KX_BlenderSceneConverter::RegisterInterpolatorList(
- BL_InterpolatorList *actList,
- struct bAction *for_act)
+
+void KX_BlenderSceneConverter::RegisterInterpolatorList(BL_InterpolatorList *actList, struct bAction *for_act)
{
m_map_blender_to_gameAdtList.insert(CHashedPtr(for_act), actList);
}
-
-
-BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(
- struct bAction *for_act)
+BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(struct bAction *for_act)
{
BL_InterpolatorList **listp = m_map_blender_to_gameAdtList[CHashedPtr(for_act)];
-
return listp?*listp:NULL;
}
-
-void KX_BlenderSceneConverter::RegisterGameActuator(
- SCA_IActuator *act,
- struct bActuator *for_actuator)
+void KX_BlenderSceneConverter::RegisterGameActuator(SCA_IActuator *act, struct bActuator *for_actuator)
{
m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act);
}
-
-
-SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(
- struct bActuator *for_actuator)
+SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(struct bActuator *for_actuator)
{
SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
-
return actp?*actp:NULL;
}
-
-void KX_BlenderSceneConverter::RegisterGameController(
- SCA_IController *cont,
- struct bController *for_controller)
+void KX_BlenderSceneConverter::RegisterGameController(SCA_IController *cont, struct bController *for_controller)
{
m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont);
}
-
-
-SCA_IController *KX_BlenderSceneConverter::FindGameController(
- struct bController *for_controller)
+SCA_IController *KX_BlenderSceneConverter::FindGameController(struct bController *for_controller)
{
SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
-
return contp?*contp:NULL;
}
-void KX_BlenderSceneConverter::RegisterWorldInfo(
- KX_WorldInfo *worldinfo)
+void KX_BlenderSceneConverter::RegisterWorldInfo(KX_WorldInfo *worldinfo)
{
m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo));
}
void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
{
+ //TODO this entire function is deprecated, written for 2.4x
+ //the functionality should be rewritten, currently it does nothing
KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
int numScenes = scenes->size();
@@ -612,7 +597,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
{
KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
if (gameObj->IsRecordAnimation()) {
-
+
Object* blenderObject = gameObj->GetBlenderObject();
if (blenderObject)
{
@@ -623,21 +608,21 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
{ //clear the curve data
if (clearIpo) {//rcruiz
IpoCurve *icu1;
-
+
int numCurves = 0;
for ( icu1 = (IpoCurve*)ipo->curve.first; icu1; ) {
-
+
IpoCurve* tmpicu = icu1;
-
+
/*int i;
BezTriple *bezt;
for ( bezt = tmpicu->bezt, i = 0; i < tmpicu->totvert; i++, bezt++) {
printf("(%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",bezt->vec[0][0],bezt->vec[0][1],bezt->vec[0][2],bezt->vec[1][0],bezt->vec[1][1],bezt->vec[1][2],bezt->vec[2][0],bezt->vec[2][1],bezt->vec[2][2]);
}*/
-
+
icu1 = icu1->next;
numCurves++;
-
+
BLI_remlink( &( blenderObject->ipo->curve ), tmpicu );
if ( tmpicu->bezt )
MEM_freeN( tmpicu->bezt );
@@ -655,8 +640,8 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
}
}
-
-
+
+
}
@@ -665,45 +650,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo()
{
- if (addInitFromFrame) {
- KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
- int numScenes = scenes->size();
- if (numScenes>=0) {
- KX_Scene* scene = scenes->at(0);
- CListValue* parentList = scene->GetRootParentList();
- for (int ix=0;ix<parentList->GetCount();ix++) {
- KX_GameObject* gameobj = (KX_GameObject*)parentList->GetValue(ix);
- if (!gameobj->IsRecordAnimation()) {
- Object* blenderobject = gameobj->GetBlenderObject();
- if (!blenderobject)
- continue;
- if (blenderobject->type==OB_ARMATURE)
- continue;
- float eu[3];
- mat4_to_eul(eu,blenderobject->obmat);
- MT_Point3 pos = MT_Point3(
- blenderobject->obmat[3][0],
- blenderobject->obmat[3][1],
- blenderobject->obmat[3][2]
- );
- MT_Vector3 eulxyz = MT_Vector3(
- eu[0],
- eu[1],
- eu[2]
- );
- MT_Vector3 scale = MT_Vector3(
- blenderobject->size[0],
- blenderobject->size[1],
- blenderobject->size[2]
- );
- gameobj->NodeSetLocalPosition(pos);
- gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
- gameobj->NodeSetLocalScale(scale);
- gameobj->NodeUpdateGS(0);
- }
- }
- }
- }
+ //TODO the functionality should be rewritten
}
@@ -843,13 +790,26 @@ void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
{
KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
if (gameObj->IsRecordAnimation()) {
-#if 0
Object* blenderObject = gameObj->GetBlenderObject();
- if (blenderObject && blenderObject->ipo)
+ if (blenderObject && blenderObject->adt)
{
+ bAction *act = verify_adt_action(&blenderObject->id, false);
+ FCurve *fcu;
+
+ if (!act) {
+ continue;
+ }
+
+ /* for now, not much choice but to run this on all curves... */
+ for (fcu = (FCurve *)act->curves.first; fcu; fcu = fcu->next) {
+ /* Note: calling `sort_time_fcurve()` here is not needed, since
+ * all keys have been added in 'right' order. */
+ calchandles_fcurve(fcu);
+ }
+#if 0
// XXX animato
Ipo* ipo = blenderObject->ipo;
-
+
//create the curves, if not existing
//testhandles_ipocurve checks for NULL
testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"));
@@ -858,8 +818,8 @@ void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"));
testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"));
testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"));
- }
#endif
+ }
}
}
}
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index f6ed3366625..ff4b5a61d12 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -1087,11 +1087,12 @@ void BL_ConvertActuators(const char* maggiename,
bool enableVisualization = (stAct->flag & ACT_STEERING_ENABLEVISUALIZATION) !=0;
short facingMode = (stAct->flag & ACT_STEERING_AUTOMATICFACING) ? stAct->facingaxis : 0;
bool normalup = (stAct->flag & ACT_STEERING_NORMALUP) !=0;
+ bool lockzvel = (stAct->flag & ACT_STEERING_LOCKZVEL) !=0;
KX_SteeringActuator *tmpstact
= new KX_SteeringActuator(gameobj, mode, targetob, navmeshob,stAct->dist,
stAct->velocity, stAct->acceleration, stAct->turnspeed,
selfTerminated, stAct->updateTime,
- scene->GetObstacleSimulation(), facingMode, normalup, enableVisualization);
+ scene->GetObstacleSimulation(), facingMode, normalup, enableVisualization, lockzvel);
baseact = tmpstact;
break;
}
diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp
index 75e3b490505..5e0eb92eb58 100644
--- a/source/gameengine/Expressions/ListValue.cpp
+++ b/source/gameengine/Expressions/ListValue.cpp
@@ -432,7 +432,7 @@ static PyObject *listvalue_buffer_concat(PyObject *self, PyObject *other)
for (i=0;i<numitems;i++)
{
- listitemval = listval->ConvertPythonToValue(PyList_GetItem(other,i), true, "cList + pyList: CListValue, ");
+ listitemval = listval->ConvertPythonToValue(PyList_GET_ITEM(other, i), true, "cList + pyList: CListValue, ");
if (listitemval) {
listval_new->SetValue(i+numitems_orig, listitemval);
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index c025d439fc0..a65d61bc98b 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -418,7 +418,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
return NULL;
}
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject(val, attrdef->m_imax, Py_NEW, NULL);
+ return Vector_CreatePyObject(val, attrdef->m_imax, NULL);
#else
PyObject *resultlist = PyList_New(attrdef->m_imax);
for (unsigned int i=0; i<attrdef->m_imax; i++)
@@ -435,7 +435,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
return NULL;
}
#ifdef USE_MATHUTILS
- return Matrix_CreatePyObject(val, attrdef->m_imin, attrdef->m_imax, Py_WRAP, NULL);
+ return Matrix_CreatePyObject_wrap(val, attrdef->m_imin, attrdef->m_imax, NULL);
#else
PyObject *collist = PyList_New(attrdef->m_imin);
for (unsigned int i=0; i<attrdef->m_imin; i++)
@@ -458,7 +458,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *
#ifdef USE_MATHUTILS
float fval[3];
val->getValue(fval);
- return Vector_CreatePyObject(fval, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(fval, 3, NULL);
#else
PyObject *resultlist = PyList_New(3);
for (unsigned int i=0; i<3; i++)
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index e2e7c248795..34b814d7416 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -65,21 +65,21 @@ typedef struct {
#define ShowDeprecationWarning(old_way, new_way) \
{ \
static WarnLink wlink = {false, NULL}; \
- if ((m_ignore_deprecation_warnings || wlink.warn_done)==0) \
+ if ((PyObjectPlus::m_ignore_deprecation_warnings || wlink.warn_done)==0) \
{ \
- ShowDeprecationWarning_func(old_way, new_way); \
+ PyObjectPlus::ShowDeprecationWarning_func(old_way, new_way); \
\
- WarnLink *wlink_last= GetDeprecationWarningLinkLast(); \
+ WarnLink *wlink_last= PyObjectPlus::GetDeprecationWarningLinkLast(); \
wlink.warn_done = true; \
wlink.link = NULL; \
\
if(wlink_last) { \
wlink_last->link= (void *)&(wlink); \
- SetDeprecationWarningLinkLast(&(wlink)); \
+ PyObjectPlus::SetDeprecationWarningLinkLast(&(wlink)); \
} \
else { \
- SetDeprecationWarningFirst(&(wlink)); \
- SetDeprecationWarningLinkLast(&(wlink)); \
+ PyObjectPlus::SetDeprecationWarningFirst(&(wlink)); \
+ PyObjectPlus::SetDeprecationWarningLinkLast(&(wlink)); \
} \
} \
} \
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
index bdef2dbd5b0..286db016476 100644
--- a/source/gameengine/Expressions/Value.cpp
+++ b/source/gameengine/Expressions/Value.cpp
@@ -568,7 +568,7 @@ CValue *CValue::ConvertPythonToValue(PyObject *pyobj, const bool do_type_excepti
Py_ssize_t numitems = PyList_GET_SIZE(pyobj);
for (i=0;i<numitems;i++)
{
- PyObject *listitem = PyList_GetItem(pyobj,i); /* borrowed ref */
+ PyObject *listitem = PyList_GET_ITEM(pyobj,i); /* borrowed ref */
CValue* listitemval = ConvertPythonToValue(listitem, error_prefix);
if (listitemval)
{
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index 6e379c91d0c..b03570e3c28 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -41,6 +41,10 @@
#include "BLI_path_util.h"
+#ifdef WITH_SDL
+# define SDL_CHECK(x) ((x) != (void *)0)
+#endif
+
SCA_Joystick::SCA_Joystick(short int index)
:
m_joyindex(index),
@@ -82,6 +86,9 @@ SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
#ifndef WITH_SDL
return NULL;
#else /* WITH_SDL */
+ if (!SDL_CHECK(SDL_InitSubSystem)) {
+ return NULL;
+ }
if (joyindex < 0 || joyindex >= JOYINDEX_MAX) {
JOYSTICK_ECHO("Error-invalid joystick index: " << joyindex);
return NULL;
@@ -104,7 +111,11 @@ SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
char *videodriver = getenv("SDL_VIDEODRIVER");
BLI_setenv("SDL_VIDEODRIVER", "dummy");
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ int success = (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1 );
+#else
int success = (SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) != -1 );
+#endif
BLI_setenv("SDL_VIDEODRIVER", videodriver);
# endif
@@ -116,7 +127,7 @@ SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
m_joynum = SDL_NumJoysticks();
- for (i=0; i<JOYINDEX_MAX; i++) {
+ for (i = 0; i < m_joynum; i++) {
m_instance[i] = new SCA_Joystick(i);
m_instance[i]->CreateJoystickDevice();
}
@@ -135,8 +146,10 @@ void SCA_Joystick::ReleaseInstance()
if (--m_refCount == 0)
{
#ifdef WITH_SDL
- int i;
- for (i=0; i<JOYINDEX_MAX; i++) {
+ if (!SDL_CHECK(SDL_QuitSubSystem)) {
+ return;
+ }
+ for (int i = 0; i < m_joynum; i++) {
if (m_instance[i]) {
m_instance[i]->DestroyJoystickDevice();
delete m_instance[i];
@@ -147,11 +160,11 @@ void SCA_Joystick::ReleaseInstance()
/* The video subsystem is required for joystick input to work. However,
* when GHOST is running under SDL, video is freed elsewhere.
* Do this once only. */
-# ifdef WITH_GHOST_SDL
+#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
-# else
+#else
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
-# endif
+#endif
#endif /* WITH_SDL */
}
}
@@ -191,6 +204,9 @@ bool SCA_Joystick::aAxisIsPositive(int axis_single)
bool SCA_Joystick::aAnyButtonPressIsPositive(void)
{
#ifdef WITH_SDL
+ if (!SDL_CHECK(SDL_JoystickGetButton)) {
+ return false;
+ }
/* this is needed for the "all events" option
* so we know if there are no buttons pressed */
for (int i=0; i<m_buttonmax; i++)
@@ -206,7 +222,7 @@ bool SCA_Joystick::aButtonPressIsPositive(int button)
return false;
#else
bool result;
- SDL_JoystickGetButton(m_private->m_joystick, button)? result = true:result = false;
+ result = SDL_CHECK(SDL_JoystickGetButton) && SDL_JoystickGetButton(m_private->m_joystick, button);
return result;
#endif
}
@@ -218,7 +234,7 @@ bool SCA_Joystick::aButtonReleaseIsPositive(int button)
return false;
#else
bool result;
- SDL_JoystickGetButton(m_private->m_joystick, button)? result = false : result = true;
+ result = !(SDL_CHECK(SDL_JoystickGetButton) && SDL_JoystickGetButton(m_private->m_joystick, button));
return result;
#endif
}
@@ -253,7 +269,7 @@ bool SCA_Joystick::CreateJoystickDevice(void)
m_axismax = m_buttonmax = m_hatmax = 0;
return false;
#else /* WITH_SDL */
- if (m_isinit == false) {
+ if (m_isinit == false && SDL_CHECK(SDL_JoystickOpen)) {
if (m_joyindex>=m_joynum) {
/* don't print a message, because this is done anyway */
//JOYSTICK_ECHO("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)");
@@ -293,9 +309,9 @@ void SCA_Joystick::DestroyJoystickDevice(void)
#ifdef WITH_SDL
if (m_isinit) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
- if (SDL_JoystickGetAttached(m_private->m_joystick))
+ if (SDL_CHECK(SDL_JoystickGetAttached) && SDL_JoystickGetAttached(m_private->m_joystick))
#else
- if (SDL_JoystickOpened(m_joyindex))
+ if (SDL_CHECK(SDL_JoystickOpened) && SDL_JoystickOpened(m_joyindex))
#endif
{
JOYSTICK_ECHO("Closing-joystick " << m_joyindex);
@@ -309,13 +325,16 @@ void SCA_Joystick::DestroyJoystickDevice(void)
int SCA_Joystick::Connected(void)
{
#ifdef WITH_SDL
- if (m_isinit
+ if (m_isinit &&
#if SDL_VERSION_ATLEAST(2, 0, 0)
- && SDL_JoystickGetAttached(m_private->m_joystick))
+ SDL_CHECK(SDL_JoystickGetAttached) && SDL_JoystickGetAttached(m_private->m_joystick)
#else
- && SDL_JoystickOpened(m_joyindex))
+ SDL_CHECK(SDL_JoystickOpened) && SDL_JoystickOpened(m_joyindex)
#endif
+ )
+ {
return 1;
+ }
#endif
return 0;
}
@@ -353,9 +372,9 @@ const char *SCA_Joystick::GetName()
{
#ifdef WITH_SDL
#if SDL_VERSION_ATLEAST(2, 0, 0)
- return SDL_JoystickName(m_private->m_joystick);
+ return (SDL_CHECK(SDL_JoystickName)) ? SDL_JoystickName(m_private->m_joystick) : "";
#else
- return SDL_JoystickName(m_joyindex);
+ return (SDL_CHECK(SDL_JoystickName)) ? SDL_JoystickName(m_joyindex) : "";
#endif
#else /* WITH_SDL */
return "";
diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp
index 2911b3b1a14..0033c137eb6 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp
@@ -36,6 +36,9 @@
#include "SCA_Joystick.h"
#include "SCA_JoystickPrivate.h"
+#ifdef _MSC_VER
+# include <cstdio> /* printf */
+#endif
#ifdef WITH_SDL
void SCA_Joystick::OnAxisMotion(SDL_Event* sdl_event)
@@ -82,7 +85,11 @@ void SCA_Joystick::OnNothing(SDL_Event* sdl_event)
void SCA_Joystick::HandleEvents(void)
{
SDL_Event sdl_event;
-
+
+ if (SDL_PollEvent == (void*)0) {
+ return;
+ }
+
int i;
for (i=0; i<m_joynum; i++) { /* could use JOYINDEX_MAX but no reason to */
if (SCA_Joystick::m_instance[i])
@@ -117,6 +124,12 @@ void SCA_Joystick::HandleEvents(void)
SCA_Joystick::m_instance[sdl_event.jball.which]->OnBallMotion(&sdl_event);
break;
#endif
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ case SDL_JOYDEVICEADDED:
+ case SDL_JOYDEVICEREMOVED:
+ /* pass */
+ break;
+#endif
default:
printf("SCA_Joystick::HandleEvents, Unknown SDL event (%d), this should not happen\n", sdl_event.type);
break;
diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.h b/source/gameengine/GameLogic/SCA_IInputDevice.h
index 23346c29601..d4cd66fb564 100644
--- a/source/gameengine/GameLogic/SCA_IInputDevice.h
+++ b/source/gameengine/GameLogic/SCA_IInputDevice.h
@@ -25,7 +25,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file SCA_IController.h
+/** \file SCA_IInputDevice.h
* \ingroup gamelogic
* \brief Interface for input devices. The defines for keyboard/system/mouse events
* here are for internal use in the KX module.
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
index 365e2b0c853..d5972a0a807 100644
--- a/source/gameengine/GameLogic/SCA_IObject.h
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -24,7 +24,7 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file SCA_IController.h
+/** \file SCA_IObject.h
* \ingroup gamelogic
* \brief An abstract object that has some logic, python scripting and
* reference counting Note: transformation stuff has been moved to
@@ -221,6 +221,7 @@ public:
OBJ_ARMATURE=0,
OBJ_CAMERA=1,
OBJ_LIGHT=2,
+ OBJ_FONT=3,
} ObjectTypes;
};
diff --git a/source/gameengine/GameLogic/SCA_IScene.cpp b/source/gameengine/GameLogic/SCA_IScene.cpp
index 3ca4b6607b3..b6ce1d86ba7 100644
--- a/source/gameengine/GameLogic/SCA_IScene.cpp
+++ b/source/gameengine/GameLogic/SCA_IScene.cpp
@@ -114,7 +114,7 @@ void SCA_IScene::RemoveDebugProperty(class CValue *gameobj,
const STR_String &name)
{
vector<SCA_DebugProp*>::iterator it = m_debugList.begin();
- while(it != m_debugList.end()) {
+ while (it != m_debugList.end()) {
STR_String debugname = (*it)->m_name;
CValue *debugobj = (*it)->m_obj;
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index 091aa675741..7bbba7aaafe 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -25,7 +25,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file SCA_IController.h
+/** \file SCA_ISensor.h
* \ingroup gamelogic
* \brief Interface Class for all logic Sensors. Implements
* pulsemode and pulsefrequency, and event suppression.
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
index 3cae3bcf160..e20dd8bcd74 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
@@ -351,8 +351,8 @@ PyObject *SCA_JoystickSensor::pyattr_get_axis_values(void *self_v, const KX_PYAT
SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
- int axis_index= joy->GetNumberOfAxes();
- PyObject *list= PyList_New(axis_index);
+ int axis_index = (joy ? joy->GetNumberOfAxes() : 0);
+ PyObject *list = PyList_New(axis_index);
while (axis_index--) {
PyList_SET_ITEM(list, axis_index, PyLong_FromLong(joy->GetAxisPosition(axis_index)));
@@ -371,7 +371,7 @@ PyObject *SCA_JoystickSensor::pyattr_get_axis_single(void *self_v, const KX_PYAT
return NULL;
}
- return PyLong_FromLong(joy->GetAxisPosition(self->m_axis-1));
+ return PyLong_FromLong(joy ? joy->GetAxisPosition(self->m_axis - 1) : 0);
}
PyObject *SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -379,8 +379,8 @@ PyObject *SCA_JoystickSensor::pyattr_get_hat_values(void *self_v, const KX_PYATT
SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
- int hat_index= joy->GetNumberOfHats();
- PyObject *list= PyList_New(hat_index);
+ int hat_index = (joy ? joy->GetNumberOfHats() : 0);
+ PyObject *list = PyList_New(hat_index);
while (hat_index--) {
PyList_SET_ITEM(list, hat_index, PyLong_FromLong(joy->GetHat(hat_index)));
@@ -394,7 +394,7 @@ PyObject *SCA_JoystickSensor::pyattr_get_hat_single(void *self_v, const KX_PYATT
SCA_JoystickSensor* self = static_cast<SCA_JoystickSensor*>(self_v);
SCA_Joystick *joy = ((SCA_JoystickManager *)self->m_eventmgr)->GetJoystickDevice(self->m_joyindex);
- return PyLong_FromLong(joy->GetHat(self->m_hat-1));
+ return PyLong_FromLong(joy ? joy->GetHat(self->m_hat - 1) : 0);
}
PyObject *SCA_JoystickSensor::pyattr_get_num_axis(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
index cc203880f94..e5d717e0140 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -511,6 +511,7 @@ PyObject *SCA_KeyboardSensor::pyattr_get_events(void *self_v, const KX_PYATTRIBU
PyList_SET_ITEM(keypair,0,PyLong_FromLong(i));
PyList_SET_ITEM(keypair,1,PyLong_FromLong(inevent.m_status));
PyList_Append(resultlist,keypair);
+ Py_DECREF(keypair);
}
}
return resultlist;
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h
index 4d8c20065b5..1275a7c5085 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.h
+++ b/source/gameengine/GameLogic/SCA_LogicManager.h
@@ -24,7 +24,7 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file SCA_IController.h
+/** \file SCA_LogicManager.h
* \ingroup gamelogic
* \brief Regulates the top-level logic behavior for one scene.
*/
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
index be7cf6629f0..52c4d13c638 100644
--- a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp
@@ -69,6 +69,7 @@ GPC_Canvas::GPC_Canvas(
m_displayarea.m_y1 = 0;
m_displayarea.m_x2 = width;
m_displayarea.m_y2 = height;
+ m_frame = 1;
glGetIntegerv(GL_VIEWPORT, (GLint*)m_viewport);
}
@@ -180,7 +181,9 @@ MakeScreenShot(
char path[FILE_MAX];
BLI_strncpy(path, filename, sizeof(path));
BLI_path_abs(path, G.main->name);
- BKE_add_image_extension_from_type(path, im_format.imtype);
+ BLI_path_frame(path, m_frame, 0);
+ m_frame++;
+ BKE_image_path_ensure_ext_from_imtype(path, im_format.imtype);
// create and save imbuf
ImBuf *ibuf = IMB_allocImBuf(GetWidth(), GetHeight(), 24, 0);
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h
index 338f9647b3e..acbea477e38 100644
--- a/source/gameengine/GamePlayer/common/GPC_Canvas.h
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h
@@ -56,6 +56,8 @@ protected:
/** Rect that defines the area used for rendering,
* relative to the context */
RAS_Rect m_displayarea;
+ /** Frame counter for screenshots */
+ int m_frame;
int m_viewport[4];
diff --git a/source/gameengine/GamePlayer/ghost/CMakeLists.txt b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
index 8ab090eac02..a1bc7e88840 100644
--- a/source/gameengine/GamePlayer/ghost/CMakeLists.txt
+++ b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
@@ -91,4 +91,11 @@ if(WITH_AUDASPACE)
add_definitions(-DWITH_AUDASPACE)
endif()
+if(WITH_SDL AND WITH_SDL_DYNLOAD)
+ list(APPEND INC
+ ../../../../extern/sdlew/include
+ )
+ add_definitions(-DWITH_SDL_DYNLOAD)
+endif()
+
blender_add_lib_nolist(ge_player_ghost "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index d7a63c28da3..6b69a991968 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -250,9 +250,15 @@ bool GPG_Application::startScreenSaverPreview(
int windowWidth = rc.right - rc.left;
int windowHeight = rc.bottom - rc.top;
STR_String title = "";
-
+ GHOST_GLSettings glSettings = {0};
+
+ if (stereoVisual) {
+ glSettings.flags |= GHOST_glStereoVisual;
+ }
+ glSettings.numOfAASamples = samples;
+
m_mainWindow = fSystem->createWindow(title, 0, 0, windowWidth, windowHeight, GHOST_kWindowStateMinimized,
- GHOST_kDrawingContextTypeOpenGL, stereoVisual, samples);
+ GHOST_kDrawingContextTypeOpenGL, glSettings);
if (!m_mainWindow) {
printf("error: could not create main window\n");
exit(-1);
@@ -323,11 +329,16 @@ bool GPG_Application::startWindow(
const int stereoMode,
const GHOST_TUns16 samples)
{
+ GHOST_GLSettings glSettings = {0};
bool success;
// Create the main window
//STR_String title ("Blender Player - GHOST");
+ if (stereoVisual)
+ glSettings.flags |= GHOST_glStereoVisual;
+ glSettings.numOfAASamples = samples;
+
m_mainWindow = fSystem->createWindow(title, windowLeft, windowTop, windowWidth, windowHeight, GHOST_kWindowStateNormal,
- GHOST_kDrawingContextTypeOpenGL, stereoVisual, false, samples);
+ GHOST_kDrawingContextTypeOpenGL, glSettings);
if (!m_mainWindow) {
printf("error: could not create main window\n");
exit(-1);
@@ -354,10 +365,16 @@ bool GPG_Application::startEmbeddedWindow(
const GHOST_TUns16 samples)
{
GHOST_TWindowState state = GHOST_kWindowStateNormal;
+ GHOST_GLSettings glSettings = {0};
+
+ if (stereoVisual)
+ glSettings.flags |= GHOST_glStereoVisual;
+ glSettings.numOfAASamples = samples;
+
if (parentWindow != 0)
state = GHOST_kWindowStateEmbedded;
m_mainWindow = fSystem->createWindow(title, 0, 0, 0, 0, state,
- GHOST_kDrawingContextTypeOpenGL, stereoVisual, false, samples, parentWindow);
+ GHOST_kDrawingContextTypeOpenGL, glSettings, parentWindow);
if (!m_mainWindow) {
printf("error: could not create main window\n");
@@ -567,7 +584,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
bool useLists = (SYS_GetCommandLineInt(syshandle, "displaylists", gm->flag & GAME_DISPLAY_LISTS) != 0) && GPU_display_list_support();
bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 1) != 0);
- bool restrictAnimFPS = gm->flag & GAME_RESTRICT_ANIM_UPDATES;
+ bool restrictAnimFPS = (gm->flag & GAME_RESTRICT_ANIM_UPDATES) != 0;
if (GLEW_ARB_multitexture && GLEW_VERSION_1_1)
m_blendermat = (SYS_GetCommandLineInt(syshandle, "blender_material", 1) != 0);
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index 3bb5f17841d..915fe614957 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -64,6 +64,7 @@ extern "C"
#include "BLO_readfile.h"
#include "BLO_runtime.h"
+#include "BKE_appdir.h"
#include "BKE_blender.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
@@ -79,6 +80,10 @@ extern "C"
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
+#ifdef __APPLE__
+ int GHOST_HACK_getFirstFile(char buf[]);
+#endif
+
// For BLF
#include "BLF_api.h"
#include "BLF_translation.h"
@@ -114,6 +119,10 @@ extern char datatoc_bmonofont_ttf[];
#endif // !defined(DEBUG)
#endif // WIN32
+#ifdef WITH_SDL_DYNLOAD
+# include "sdlew.h"
+#endif
+
const int kMinWindowWidth = 100;
const int kMinWindowHeight = 100;
@@ -292,6 +301,12 @@ static void get_filename(int argc, char **argv, char *filename)
if (BLI_exists(argv[argc-1])) {
BLI_strncpy(filename, argv[argc-1], FILE_MAX);
}
+ if (::strncmp(argv[argc-1], "-psn_", 5)==0) {
+ static char firstfilebuf[512];
+ if (GHOST_HACK_getFirstFile(firstfilebuf)) {
+ BLI_strncpy(filename, firstfilebuf, FILE_MAX);
+ }
+ }
}
srclen -= ::strlen("MacOS/blenderplayer");
@@ -421,8 +436,13 @@ int main(int argc, char** argv)
signal (SIGFPE, SIG_IGN);
#endif /* __alpha__ */
#endif /* __linux__ */
- BLI_init_program_path(argv[0]);
- BLI_temp_dir_init(NULL);
+
+#ifdef WITH_SDL_DYNLOAD
+ sdlewInit();
+#endif
+
+ BKE_appdir_program_path_init(argv[0]);
+ BKE_tempdir_init(NULL);
// We don't use threads directly in the BGE, but we need to call this so things like
// freeing up GPU_Textures works correctly.
@@ -861,7 +881,7 @@ int main(int argc, char** argv)
}
}
else {
- bfd = load_game_data(BLI_program_path(), filename[0]? filename: NULL);
+ bfd = load_game_data(BKE_appdir_program_path(), filename[0]? filename: NULL);
}
#if defined(DEBUG)
@@ -1133,7 +1153,7 @@ int main(int argc, char** argv)
MEM_printmemlist();
}
- BLI_temp_dir_session_purge();
+ BKE_tempdir_session_purge();
return error ? -1 : 0;
}
diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript
index d4c31889a5e..610abcd0357 100644
--- a/source/gameengine/GamePlayer/ghost/SConscript
+++ b/source/gameengine/GamePlayer/ghost/SConscript
@@ -87,4 +87,8 @@ if env['WITH_BF_FFMPEG']:
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
+if env['WITH_BF_SDL'] and env['WITH_BF_SDL_DYNLOAD']:
+ defs.append('WITH_SDL_DYNLOAD')
+ incs += ['#extern/sdlew/include']
+
env.BlenderLib (libname='ge_player_ghost', sources=source_files, includes = incs, defines = defs, libtype=['player'],priority=[0], cxx_compileflags=env['BGE_CXXFLAGS'])
diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h
index 5b340257881..148097f995e 100644
--- a/source/gameengine/Ketsji/BL_ActionManager.h
+++ b/source/gameengine/Ketsji/BL_ActionManager.h
@@ -20,7 +20,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file BL_ActionManager.cpp
+/** \file BL_ActionManager.h
* \ingroup ketsji
*/
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index bcdef85bc8a..de6b36b189d 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -77,7 +77,7 @@ void BL_BlenderShader::SetProg(bool enable, double time, RAS_IRasterizer* rasty)
view.getValue((float*)viewmat);
viewinv.getValue((float*)viewinvmat);
- GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1, viewmat, viewinvmat, false);
+ GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1, viewmat, viewinvmat, NULL, false);
}
else
GPU_material_unbind(mGPUMat);
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
index 006c1f7202c..849b5e0f3c3 100644
--- a/source/gameengine/Ketsji/BL_Material.cpp
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -47,10 +47,10 @@ BL_Material::BL_Material()
void BL_Material::Initialize()
{
- rgb[0] = 0;
- rgb[1] = 0;
- rgb[2] = 0;
- rgb[3] = 0;
+ rgb[0] = 0xFFFFFFFFL;
+ rgb[1] = 0xFFFFFFFFL;
+ rgb[2] = 0xFFFFFFFFL;
+ rgb[3] = 0xFFFFFFFFL;
IdMode = 0;
ras_mode = 0;
glslmat = 0;
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index 1a78efb3c18..58739e7ef81 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -239,26 +239,26 @@ void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
int nx= power_of_2_min_i(x);
int ny= power_of_2_min_i(y);
- unsigned int *newPixels = (unsigned int *)malloc(nx*ny*sizeof(unsigned int));
-
- gluScaleImage(GL_RGBA, x, y, GL_UNSIGNED_BYTE, pix, nx,ny, GL_UNSIGNED_BYTE, newPixels);
+ ImBuf *ibuf = IMB_allocFromBuffer(pix, NULL, x, y);
+ IMB_scaleImBuf(ibuf, nx, ny);
+
glBindTexture(GL_TEXTURE_2D, mTexture );
if ( mipmap ) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, nx, ny, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
+ gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, nx, ny, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect );
}
else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_RGBA, GL_UNSIGNED_BYTE, newPixels );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect );
}
if (GLEW_EXT_texture_filter_anisotropic)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic());
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- free(newPixels);
+ IMB_freeImBuf(ibuf);
}
diff --git a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
index 0c661cf2c87..cfc6ded4e65 100644
--- a/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
+++ b/source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
@@ -30,6 +30,7 @@ set(INC
../../GameLogic
../../Network
../../SceneGraph
+ ../../../blender/blenlib
../../../../intern/container
../../../../intern/string
)
diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript
index 355dcc4f78f..ab03e03e74d 100644
--- a/source/gameengine/Ketsji/KXNetwork/SConscript
+++ b/source/gameengine/Ketsji/KXNetwork/SConscript
@@ -39,6 +39,7 @@ incs = [
'#source/gameengine/Ketsji',
'#source/gameengine/Network',
'#source/gameengine/SceneGraph',
+ '../../../blender/blenlib',
]
incs = ' '.join(incs)
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index e0761154ed2..ce2fe5f5ad8 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -747,7 +747,7 @@ int KX_Camera::pyattr_set_lens(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef,
KX_Camera* self = static_cast<KX_Camera*>(self_v);
float param = PyFloat_AsDouble(value);
if (param == -1) {
- PyErr_SetString(PyExc_AttributeError, "camera.lens = float: KX_Camera, expected a float greater then zero");
+ PyErr_SetString(PyExc_AttributeError, "camera.lens = float: KX_Camera, expected a float greater than zero");
return PY_SET_ATTR_FAIL;
}
@@ -772,7 +772,7 @@ int KX_Camera::pyattr_set_fov(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, P
KX_Camera* self = static_cast<KX_Camera*>(self_v);
float fov = PyFloat_AsDouble(value);
if (fov <= 0.0) {
- PyErr_SetString(PyExc_AttributeError, "camera.fov = float: KX_Camera, expected a float greater then zero");
+ PyErr_SetString(PyExc_AttributeError, "camera.fov = float: KX_Camera, expected a float greater than zero");
return PY_SET_ATTR_FAIL;
}
@@ -796,7 +796,7 @@ int KX_Camera::pyattr_set_ortho_scale(void *self_v, const KX_PYATTRIBUTE_DEF *at
KX_Camera* self = static_cast<KX_Camera*>(self_v);
float param = PyFloat_AsDouble(value);
if (param == -1) {
- PyErr_SetString(PyExc_AttributeError, "camera.ortho_scale = float: KX_Camera, expected a float greater then zero");
+ PyErr_SetString(PyExc_AttributeError, "camera.ortho_scale = float: KX_Camera, expected a float greater than zero");
return PY_SET_ATTR_FAIL;
}
@@ -816,7 +816,7 @@ int KX_Camera::pyattr_set_near(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef,
KX_Camera* self = static_cast<KX_Camera*>(self_v);
float param = PyFloat_AsDouble(value);
if (param == -1) {
- PyErr_SetString(PyExc_AttributeError, "camera.near = float: KX_Camera, expected a float greater then zero");
+ PyErr_SetString(PyExc_AttributeError, "camera.near = float: KX_Camera, expected a float greater than zero");
return PY_SET_ATTR_FAIL;
}
@@ -836,7 +836,7 @@ int KX_Camera::pyattr_set_far(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, P
KX_Camera* self = static_cast<KX_Camera*>(self_v);
float param = PyFloat_AsDouble(value);
if (param == -1) {
- PyErr_SetString(PyExc_AttributeError, "camera.far = float: KX_Camera, expected a float greater then zero");
+ PyErr_SetString(PyExc_AttributeError, "camera.far = float: KX_Camera, expected a float greater than zero");
return PY_SET_ATTR_FAIL;
}
diff --git a/source/gameengine/Ketsji/KX_Dome.cpp b/source/gameengine/Ketsji/KX_Dome.cpp
index a77269c116d..f58fee88d48 100644
--- a/source/gameengine/Ketsji/KX_Dome.cpp
+++ b/source/gameengine/Ketsji/KX_Dome.cpp
@@ -2044,7 +2044,6 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i)
cam->NodeUpdateGS(0.f);
scene->CalculateVisibleMeshes(m_rasterizer,cam);
- scene->UpdateAnimations(m_engine->GetFrameTime());
scene->RenderBuckets(camtrans, m_rasterizer);
}
diff --git a/source/gameengine/Ketsji/KX_FontObject.cpp b/source/gameengine/Ketsji/KX_FontObject.cpp
index 9789a8294ee..f3b098f407a 100644
--- a/source/gameengine/Ketsji/KX_FontObject.cpp
+++ b/source/gameengine/Ketsji/KX_FontObject.cpp
@@ -118,7 +118,6 @@ CValue* KX_FontObject::GetReplica()
void KX_FontObject::ProcessReplica()
{
KX_GameObject::ProcessReplica();
- KX_GetActiveScene()->AddFont(this);
}
int GetFontId(VFont *vfont)
diff --git a/source/gameengine/Ketsji/KX_FontObject.h b/source/gameengine/Ketsji/KX_FontObject.h
index 209ab6ca69f..3a25d366148 100644
--- a/source/gameengine/Ketsji/KX_FontObject.h
+++ b/source/gameengine/Ketsji/KX_FontObject.h
@@ -54,6 +54,7 @@ public:
*/
virtual CValue* GetReplica();
virtual void ProcessReplica();
+ virtual int GetGameObjectType() { return OBJ_FONT; }
protected:
std::vector<STR_String> m_text;
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index dc246406a88..71af263bf46 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -36,14 +36,6 @@
# pragma warning( disable:4786 )
#endif
-#if defined(_WIN64) && !defined(FREE_WINDOWS64)
-typedef unsigned __int64 uint_ptr;
-#elif defined(FREE_WINDOWS64)
-typedef unsigned long long uint_ptr;
-#else
-typedef unsigned long uint_ptr;
-#endif
-
#include "RAS_IPolygonMaterial.h"
#include "KX_BlenderMaterial.h"
#include "KX_GameObject.h"
@@ -77,6 +69,8 @@ typedef unsigned long uint_ptr;
#include "BL_Action.h"
#include "PyObjectPlus.h" /* python stuff */
+#include "BLI_utildefines.h"
+#include "python_utildefines.h"
// This file defines relationships between parents and children
// in the game engine.
@@ -97,6 +91,7 @@ KX_GameObject::KX_GameObject(
: SCA_IObject(),
m_bDyna(false),
m_layer(0),
+ m_currentLodLevel(0),
m_pBlenderObject(NULL),
m_pBlenderGroupObject(NULL),
m_bSuspendDynamics(false),
@@ -575,6 +570,39 @@ CValue* KX_GameObject::GetReplica()
return replica;
}
+float KX_GameObject::getLinearDamping() const
+{
+ if (m_pPhysicsController)
+ return m_pPhysicsController->GetLinearDamping();
+ return 0;
+}
+
+float KX_GameObject::getAngularDamping() const
+{
+ if (m_pPhysicsController)
+ return m_pPhysicsController->GetAngularDamping();
+ return 0;
+}
+
+void KX_GameObject::setLinearDamping(float damping)
+{
+ if (m_pPhysicsController)
+ m_pPhysicsController->SetLinearDamping(damping);
+}
+
+
+void KX_GameObject::setAngularDamping(float damping)
+{
+ if (m_pPhysicsController)
+ m_pPhysicsController->SetAngularDamping(damping);
+}
+
+
+void KX_GameObject::setDamping(float linear, float angular)
+{
+ if (m_pPhysicsController)
+ m_pPhysicsController->SetDamping(linear, angular);
+}
void KX_GameObject::ApplyForce(const MT_Vector3& force,bool local)
@@ -767,7 +795,7 @@ void KX_GameObject::UpdateLod(MT_Vector3 &cam_pos)
}
RAS_MeshObject *mesh = this->m_lodmeshes[level];
-
+ this->m_currentLodLevel = level;
if (mesh != this->m_meshes[0]) {
this->GetScene()->ReplaceMesh(this, mesh, true, false);
}
@@ -930,27 +958,6 @@ KX_GameObject::SetVisible(
}
}
-bool KX_GameObject::GetCulled()
-{
- // If we're set to not cull, double-check with
- // the mesh slots first. This is kind of nasty, but
- // it allows us to get proper culling information.
- if (!m_bCulled)
- {
- SG_QList::iterator<RAS_MeshSlot> mit(m_meshSlots);
- for (mit.begin(); !mit.end(); ++mit)
- {
- if ((*mit)->m_bCulled)
- {
- m_bCulled = true;
- break;
- }
- }
- }
-
- return m_bCulled;
-}
-
static void setOccluder_recursive(SG_Node* node, bool v)
{
NodeList& children = node->GetSGChildren();
@@ -1486,7 +1493,7 @@ void KX_GameObject::RegisterCollisionCallbacks()
pe->AddSensor(spc);
}
}
-void KX_GameObject::RunCollisionCallbacks(KX_GameObject *collider)
+void KX_GameObject::RunCollisionCallbacks(KX_GameObject *collider, const MT_Vector3 &point, const MT_Vector3 &normal)
{
#ifdef WITH_PYTHON
Py_ssize_t len;
@@ -1494,15 +1501,50 @@ void KX_GameObject::RunCollisionCallbacks(KX_GameObject *collider)
if (collision_callbacks && (len=PyList_GET_SIZE(collision_callbacks)))
{
- PyObject* args = Py_BuildValue("(O)", collider->GetProxy()); // save python creating each call
+ // Argument tuples are created lazily, only when they are needed.
+ PyObject *args_3 = NULL;
+ PyObject *args_1 = NULL; // Only for compatibility with pre-2.74 callbacks that take 1 argument.
+
PyObject *func;
PyObject *ret;
+ int co_argcount;
// Iterate the list and run the callbacks
for (Py_ssize_t pos=0; pos < len; pos++)
{
func = PyList_GET_ITEM(collision_callbacks, pos);
- ret = PyObject_Call(func, args, NULL);
+
+ // Get the number of arguments, supporting functions, methods and generic callables.
+ if (PyMethod_Check(func)) {
+ // Take away the 'self' argument for methods.
+ co_argcount = ((PyCodeObject *)PyFunction_GET_CODE(PyMethod_GET_FUNCTION(func)))->co_argcount - 1;
+ } else if (PyFunction_Check(func)) {
+ co_argcount = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_argcount;
+ } else {
+ // We'll just assume the callable takes the correct number of arguments.
+ co_argcount = 3;
+ }
+
+ // Check whether the function expects the colliding object only,
+ // or also the point and normal.
+ if (co_argcount <= 1) {
+ // One argument, or *args (which gives co_argcount == 0)
+ if (args_1 == NULL) {
+ args_1 = PyTuple_New(1);
+ PyTuple_SET_ITEMS(args_1, collider->GetProxy());
+ }
+ ret = PyObject_Call(func, args_1, NULL);
+ } else {
+ // More than one argument, assume we can give point & normal.
+ if (args_3 == NULL) {
+ args_3 = PyTuple_New(3);
+ PyTuple_SET_ITEMS(args_3,
+ collider->GetProxy(),
+ PyObjectFrom(point),
+ PyObjectFrom(normal));
+ }
+ ret = PyObject_Call(func, args_3, NULL);
+ }
if (ret == NULL) {
PyErr_Print();
@@ -1513,7 +1555,8 @@ void KX_GameObject::RunCollisionCallbacks(KX_GameObject *collider)
}
}
- Py_DECREF(args);
+ if (args_3) Py_DECREF(args_3);
+ if (args_1) Py_DECREF(args_1);
}
#endif
}
@@ -1824,7 +1867,7 @@ static Mathutils_Callback mathutils_kxgameob_matrix_cb = {
void KX_GameObject_Mathutils_Callback_Init(void)
{
- // register mathutils callbacks, ok to run more then once.
+ // register mathutils callbacks, ok to run more than once.
mathutils_kxgameob_vector_cb_index= Mathutils_RegisterCallback(&mathutils_kxgameob_vector_cb);
mathutils_kxgameob_matrix_cb_index= Mathutils_RegisterCallback(&mathutils_kxgameob_matrix_cb);
}
@@ -1843,6 +1886,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getAngularVelocity", (PyCFunction) KX_GameObject::sPyGetAngularVelocity, METH_VARARGS},
{"setAngularVelocity", (PyCFunction) KX_GameObject::sPySetAngularVelocity, METH_VARARGS},
{"getVelocity", (PyCFunction) KX_GameObject::sPyGetVelocity, METH_VARARGS},
+ {"setDamping", (PyCFunction) KX_GameObject::sPySetDamping, METH_VARARGS},
{"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_NOARGS},
{"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS},
{"getAxisVect",(PyCFunction) KX_GameObject::sPyGetAxisVect, METH_O},
@@ -1884,6 +1928,7 @@ PyMethodDef KX_GameObject::Methods[] = {
};
PyAttributeDef KX_GameObject::Attributes[] = {
+ KX_PYATTRIBUTE_INT_RO("currentLodLevel", KX_GameObject, m_currentLodLevel),
KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name),
KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent),
KX_PYATTRIBUTE_RO_FUNCTION("groupMembers", KX_GameObject, pyattr_get_group_members),
@@ -1918,6 +1963,8 @@ PyAttributeDef KX_GameObject::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("angularVelocity", KX_GameObject, pyattr_get_localAngularVelocity, pyattr_set_worldAngularVelocity),
KX_PYATTRIBUTE_RW_FUNCTION("localAngularVelocity", KX_GameObject, pyattr_get_localAngularVelocity, pyattr_set_localAngularVelocity),
KX_PYATTRIBUTE_RW_FUNCTION("worldAngularVelocity", KX_GameObject, pyattr_get_worldAngularVelocity, pyattr_set_worldAngularVelocity),
+ KX_PYATTRIBUTE_RW_FUNCTION("linearDamping", KX_GameObject, pyattr_get_linearDamping, pyattr_set_linearDamping),
+ KX_PYATTRIBUTE_RW_FUNCTION("angularDamping", KX_GameObject, pyattr_get_angularDamping, pyattr_set_angularDamping),
KX_PYATTRIBUTE_RO_FUNCTION("children", KX_GameObject, pyattr_get_children),
KX_PYATTRIBUTE_RO_FUNCTION("childrenRecursive", KX_GameObject, pyattr_get_children_recursive),
KX_PYATTRIBUTE_RO_FUNCTION("attrDict", KX_GameObject, pyattr_get_attrDict),
@@ -2708,6 +2755,34 @@ int KX_GameObject::pyattr_set_localAngularVelocity(void *self_v, const KX_PYATTR
return PY_SET_ATTR_SUCCESS;
}
+PyObject *KX_GameObject::pyattr_get_linearDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+ return PyFloat_FromDouble(self->getLinearDamping());
+}
+
+int KX_GameObject::pyattr_set_linearDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+ float val = PyFloat_AsDouble(value);
+ self->setLinearDamping(val);
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject *KX_GameObject::pyattr_get_angularDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+ return PyFloat_FromDouble(self->getAngularDamping());
+}
+
+int KX_GameObject::pyattr_set_angularDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+ float val = PyFloat_AsDouble(value);
+ self->setAngularDamping(val);
+ return PY_SET_ATTR_SUCCESS;
+}
+
PyObject *KX_GameObject::pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
@@ -3004,6 +3079,18 @@ PyObject *KX_GameObject::PySetAngularVelocity(PyObject *args)
return NULL;
}
+PyObject *KX_GameObject::PySetDamping(PyObject *args)
+{
+ float linear;
+ float angular;
+
+ if (!PyArg_ParseTuple(args,"ff|i:setDamping", &linear, &angular))
+ return NULL;
+
+ setDamping(linear, angular);
+ Py_RETURN_NONE;
+}
+
PyObject *KX_GameObject::PySetVisible(PyObject *args)
{
int visible, recursive = 0;
@@ -3201,12 +3288,12 @@ PyObject *KX_GameObject::PyGetAxisVect(PyObject *value)
PyObject *KX_GameObject::PyGetPhysicsId()
{
PHY_IPhysicsController* ctrl = GetPhysicsController();
- uint_ptr physid=0;
+ unsigned long long physid = 0;
if (ctrl)
{
- physid= (uint_ptr)ctrl;
+ physid = (unsigned long long)ctrl;
}
- return PyLong_FromLong((long)physid);
+ return PyLong_FromUnsignedLongLong(physid);
}
PyObject *KX_GameObject::PyGetPropertyNames()
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index d4fa4851696..7d1a934bcec 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -88,6 +88,7 @@ protected:
int m_layer;
std::vector<RAS_MeshObject*> m_meshes;
std::vector<RAS_MeshObject*> m_lodmeshes;
+ int m_currentLodLevel;
SG_QList m_meshSlots; // head of mesh slots of this
struct Object* m_pBlenderObject;
struct Object* m_pBlenderGroupObject;
@@ -684,6 +685,12 @@ public:
bool local
);
+ virtual float getLinearDamping() const;
+ virtual float getAngularDamping() const;
+ virtual void setLinearDamping(float damping);
+ virtual void setAngularDamping(float damping);
+ virtual void setDamping(float linear, float angular);
+
/**
* Update the physics object transform based upon the current SG_Node
* position.
@@ -852,10 +859,10 @@ public:
/**
* Was this object culled?
*/
- bool
+ inline bool
GetCulled(
void
- );
+ ) { return m_bCulled; }
/**
* Set culled flag of this object
@@ -913,7 +920,7 @@ public:
void RegisterCollisionCallbacks();
void UnregisterCollisionCallbacks();
- void RunCollisionCallbacks(KX_GameObject *collider);
+ void RunCollisionCallbacks(KX_GameObject *collider, const MT_Vector3 &point, const MT_Vector3 &normal);
/**
* Stop making progress
*/
@@ -965,6 +972,7 @@ public:
KX_PYMETHOD_VARARGS(KX_GameObject,GetAngularVelocity);
KX_PYMETHOD_VARARGS(KX_GameObject,SetAngularVelocity);
KX_PYMETHOD_VARARGS(KX_GameObject,GetVelocity);
+ KX_PYMETHOD_VARARGS(KX_GameObject,SetDamping);
KX_PYMETHOD_NOARGS(KX_GameObject,GetReactionForce);
@@ -1070,6 +1078,10 @@ public:
static int pyattr_set_debug(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_debugRecursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_debugRecursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_linearDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_linearDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_angularDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_angularDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
/* Experimental! */
static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h
index a07d4b2195c..b6647cdf3dc 100644
--- a/source/gameengine/Ketsji/KX_ISceneConverter.h
+++ b/source/gameengine/Ketsji/KX_ISceneConverter.h
@@ -45,8 +45,8 @@ class KX_ISceneConverter
{
public:
- KX_ISceneConverter() :addInitFromFrame(false) {}//this addInitFromFrame is a back hack, todo remove
- virtual ~KX_ISceneConverter () {};
+ KX_ISceneConverter() {}
+ virtual ~KX_ISceneConverter () {}
/*
* scenename: name of the scene to be converted,
@@ -59,7 +59,7 @@ public:
class RAS_IRasterizer* rendertools,
class RAS_ICanvas* canvas,
bool libloading=false)=0;
-
+
virtual void RemoveScene(class KX_Scene *scene)=0;
// handle any pending merges from asynchronous loads
@@ -69,11 +69,9 @@ public:
virtual void SetNewFileName(const STR_String& filename) = 0;
virtual bool TryAndLoadNewFile() = 0;
- bool addInitFromFrame;//rcruiz
virtual void ResetPhysicsObjectsAnimationIpo(bool clearIpo) = 0;
-
///this generates ipo curves for position, rotation, allowing to use game physics in animation
virtual void WritePhysicsObjectToAnimationIpo(int frameNumber) = 0;
virtual void TestHandlesPhysicsObjectToAnimationIpo() = 0;
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index f76580cd44d..e453b757b7e 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -80,9 +80,6 @@
#include "KX_NavMeshObject.h"
-// If define: little test for Nzc: guarded drawing. If the canvas is
-// not valid, skip rendering this frame.
-//#define NZC_GUARDED_OUTPUT
#define DEFAULT_LOGIC_TIC_RATE 60.0
//#define DEFAULT_PHYSICS_TIC_RATE 60.0
@@ -140,6 +137,7 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
m_frameTime(0.f),
m_clockTime(0.f),
m_previousClockTime(0.f),
+ m_previousAnimTime(0.f),
m_exitcode(KX_EXIT_REQUEST_NO_REQUEST),
@@ -686,6 +684,16 @@ bool KX_KetsjiEngine::NextFrame()
SG_SetActiveStage(SG_STAGE_ACTUATOR_UPDATE);
scene->UpdateParents(m_frameTime);
+ // update levels of detail
+ scene->UpdateObjectLods();
+
+ if (!GetRestrictAnimationFPS())
+ {
+ m_logger->StartLog(tc_animations, m_kxsystem->GetTimeInSeconds(), true);
+ SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE);
+ scene->UpdateAnimations(m_frameTime);
+ }
+
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
SG_SetActiveStage(SG_STAGE_PHYSICS2);
scene->GetPhysicsEnvironment()->BeginFrame();
@@ -730,61 +738,23 @@ bool KX_KetsjiEngine::NextFrame()
frames--;
}
- bool bUseAsyncLogicBricks= false;//true;
-
- if (bUseAsyncLogicBricks)
+ // Handle the animations independently of the logic time step
+ if (GetRestrictAnimationFPS())
{
- // Logic update sub frame: this will let some logic bricks run at the
- // full frame rate.
- for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
- // for each scene, call the proceed functions
- {
- KX_Scene* scene = *sceneit;
+ double clocktime = m_kxsystem->GetTimeInSeconds();
+ m_logger->StartLog(tc_animations, clocktime, true);
+ SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE);
- if (!scene->IsSuspended())
+ double anim_timestep = 1.0/KX_GetActiveScene()->GetAnimationFPS();
+ if (clocktime - m_previousAnimTime > anim_timestep)
+ {
+ // Sanity/debug print to make sure we're actually going at the fps we want (should be close to anim_timestep)
+ // printf("Anim fps: %f\n", 1.0/(m_clockTime - m_previousAnimTime));
+ m_previousAnimTime = clocktime;
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
{
- // if the scene was suspended recalcutlate the delta tu "curtime"
- m_suspendedtime = scene->getSuspendedTime();
- if (scene->getSuspendedTime()!=0.0)
- scene->setSuspendedDelta(scene->getSuspendedDelta()+m_clockTime-scene->getSuspendedTime());
- m_suspendeddelta = scene->getSuspendedDelta();
-
- // set Python hooks for each scene
-#ifdef WITH_PYTHON
- PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
-#endif
- KX_SetActiveScene(scene);
-
- m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
- SG_SetActiveStage(SG_STAGE_PHYSICS1);
- scene->UpdateParents(m_clockTime);
-
- // Perform physics calculations on the scene. This can involve
- // many iterations of the physics solver.
- m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
- scene->GetPhysicsEnvironment()->ProceedDeltaTime(m_clockTime,timestep,timestep);
- // Update scenegraph after physics step. This maps physics calculations
- // into node positions.
- m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
- SG_SetActiveStage(SG_STAGE_PHYSICS2);
- scene->UpdateParents(m_clockTime);
-
- // Do some cleanup work for this logic frame
- m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
- scene->LogicUpdateFrame(m_clockTime, false);
-
- // Actuators can affect the scenegraph
- m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
- SG_SetActiveStage(SG_STAGE_ACTUATOR);
- scene->UpdateParents(m_clockTime);
-
- scene->setSuspendedTime(0.0);
- } // suspended
- else
- if (scene->getSuspendedTime()==0.0)
- scene->setSuspendedTime(m_clockTime);
-
- m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
+ (*sceneit)->UpdateAnimations(clocktime);
+ }
}
}
@@ -1155,15 +1125,8 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
raslight->BindShadowBuffer(m_canvas, cam, camtrans);
/* update scene */
- m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
scene->CalculateVisibleMeshes(m_rasterizer, cam, raslight->GetShadowLayer());
- m_logger->StartLog(tc_animations, m_kxsystem->GetTimeInSeconds(), true);
- scene->UpdateAnimations(GetFrameTime());
-
- m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
-
-
/* render */
m_rasterizer->ClearDepthBuffer();
m_rasterizer->ClearColorBuffer();
@@ -1295,11 +1258,6 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
scene->CalculateVisibleMeshes(m_rasterizer,cam);
- m_logger->StartLog(tc_animations, m_kxsystem->GetTimeInSeconds(), true);
- SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE);
-
- scene->UpdateAnimations(GetFrameTime());
-
m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
SG_SetActiveStage(SG_STAGE_RENDER);
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 2b80e3bd69a..e18b203b675 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -111,6 +111,7 @@ private:
double m_frameTime;//discrete timestamp of the 'game logic frame'
double m_clockTime;//current time
double m_previousClockTime;//previous clock time
+ double m_previousAnimTime; //the last time animations were updated
double m_remainingTime;
static int m_maxLogicFrame; /* maximum number of consecutive logic frame */
diff --git a/source/gameengine/Ketsji/KX_MouseActuator.cpp b/source/gameengine/Ketsji/KX_MouseActuator.cpp
index aae5d18189a..c372e6e9ce2 100644
--- a/source/gameengine/Ketsji/KX_MouseActuator.cpp
+++ b/source/gameengine/Ketsji/KX_MouseActuator.cpp
@@ -126,24 +126,33 @@ bool KX_MouseActuator::Update()
float movement[2];
MT_Vector3 rotation;
float setposition[2] = {0.0};
+ float center_x = 0.5, center_y = 0.5;
getMousePosition(position);
movement[0] = position[0];
movement[1] = position[1];
+ //preventing undesired drifting when resolution is odd
+ if ((m_canvas->GetWidth() % 2) != 0) {
+ center_x = ((m_canvas->GetWidth() - 1.0) / 2.0) / (m_canvas->GetWidth());
+ }
+ if ((m_canvas->GetHeight() % 2) != 0) {
+ center_y = ((m_canvas->GetHeight() - 1.0) / 2.0) / (m_canvas->GetHeight());
+ }
+
//preventing initial skipping.
if ((m_oldposition[0] <= -0.9) && (m_oldposition[1] <= -0.9)) {
if (m_reset_x) {
- m_oldposition[0] = 0.5;
+ m_oldposition[0] = center_x;
}
else {
m_oldposition[0] = position[0];
}
if (m_reset_y) {
- m_oldposition[1] = 0.5;
+ m_oldposition[1] = center_y;
}
else {
m_oldposition[1] = position[1];
@@ -156,8 +165,8 @@ bool KX_MouseActuator::Update()
if (m_use_axis_x) {
if (m_reset_x) {
- setposition[0] = 0.5;
- movement[0] -= 0.5;
+ setposition[0] = center_x;
+ movement[0] -= center_x;
}
else {
setposition[0] = position[0];
@@ -166,12 +175,10 @@ bool KX_MouseActuator::Update()
movement[0] *= -1.0;
- /* Don't apply the rotation when width resolution is odd (+ little movement) to
- avoid undesired drifting or when we are under a certain threshold for mouse
+ /* Don't apply the rotation when we are under a certain threshold for mouse
movement */
- if (!((m_canvas->GetWidth() % 2 != 0) && MT_abs(movement[0]) < 0.01) &&
- ((movement[0] > (m_threshold[0] / 10.0)) ||
+ if (((movement[0] > (m_threshold[0] / 10.0)) ||
((movement[0] * (-1.0)) > (m_threshold[0] / 10.0)))) {
movement[0] *= m_sensitivity[0];
@@ -209,15 +216,15 @@ bool KX_MouseActuator::Update()
}
}
else {
- setposition[0] = 0.5;
+ setposition[0] = center_x;
}
//Calculating Y axis.
if (m_use_axis_y) {
if (m_reset_y) {
- setposition[1] = 0.5;
- movement[1] -= 0.5;
+ setposition[1] = center_y;
+ movement[1] -= center_y;
}
else {
setposition[1] = position[1];
@@ -226,12 +233,10 @@ bool KX_MouseActuator::Update()
movement[1] *= -1.0;
- /* Don't apply the rotation when height resolution is odd (+ little movement) to
- avoid undesired drifting or when we are under a certain threshold for mouse
+ /* Don't apply the rotation when we are under a certain threshold for mouse
movement */
- if (!((m_canvas->GetHeight() % 2 != 0) && MT_abs(movement[1]) < 0.01) &&
- ((movement[1] > (m_threshold[1] / 10.0)) ||
+ if (((movement[1] > (m_threshold[1] / 10.0)) ||
((movement[1] * (-1.0)) > (m_threshold[1] / 10.0)))) {
movement[1] *= m_sensitivity[1];
@@ -270,10 +275,13 @@ bool KX_MouseActuator::Update()
}
}
else {
- setposition[1] = 0.5;
+ setposition[1] = center_y;
}
- setMousePosition(setposition[0], setposition[1]);
+ // only trigger mouse event when it is necessary
+ if (m_oldposition[0] != position[0] || m_oldposition[1] != position[1]) {
+ setMousePosition(setposition[0], setposition[1]);
+ }
m_oldposition[0] = position[0];
m_oldposition[1] = position[1];
@@ -311,7 +319,7 @@ void KX_MouseActuator::ProcessReplica()
void KX_MouseActuator::getMousePosition(float* pos)
{
- MT_assert(!m_mouse);
+ MT_assert(m_mouse);
const SCA_InputEvent & xevent = m_mouse->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
const SCA_InputEvent & yevent = m_mouse->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
@@ -399,8 +407,8 @@ int KX_MouseActuator::pyattr_set_limit_x(void *self_v, const KX_PYATTRIBUTE_DEF
if (PyList_Size(value) != 2)
return PY_SET_ATTR_FAIL;
- item1 = PyList_GetItem(value, 0);
- item2 = PyList_GetItem(value, 1);
+ item1 = PyList_GET_ITEM(value, 0);
+ item2 = PyList_GET_ITEM(value, 1);
if (!(PyFloat_Check(item1)) || !(PyFloat_Check(item2))) {
return PY_SET_ATTR_FAIL;
@@ -430,8 +438,8 @@ int KX_MouseActuator::pyattr_set_limit_y(void *self_v, const KX_PYATTRIBUTE_DEF
if (PyList_Size(value) != 2)
return PY_SET_ATTR_FAIL;
- item1 = PyList_GetItem(value, 0);
- item2 = PyList_GetItem(value, 1);
+ item1 = PyList_GET_ITEM(value, 0);
+ item2 = PyList_GET_ITEM(value, 1);
if (!(PyFloat_Check(item1)) || !(PyFloat_Check(item2))) {
return PY_SET_ATTR_FAIL;
@@ -461,8 +469,8 @@ int KX_MouseActuator::pyattr_set_angle(void *self_v, const KX_PYATTRIBUTE_DEF *a
if (PyList_Size(value) != 2)
return PY_SET_ATTR_FAIL;
- item1 = PyList_GetItem(value, 0);
- item2 = PyList_GetItem(value, 1);
+ item1 = PyList_GET_ITEM(value, 0);
+ item2 = PyList_GET_ITEM(value, 1);
if (!(PyFloat_Check(item1)) || !(PyFloat_Check(item2))) {
return PY_SET_ATTR_FAIL;
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index a9f6bb0d2ff..c2c83266791 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -269,8 +269,8 @@ bool KX_MouseFocusSensor::ParentObjectHasFocusCamera(KX_Camera *cam)
m_kxengine->GetSceneViewport(m_kxscene, cam, area, viewport);
/* Check if the mouse is in the viewport */
- if (( m_x < viewport.m_x2 && // less then right
- m_x > viewport.m_x1 && // more then then left
+ if (( m_x < viewport.m_x2 && // less than right
+ m_x > viewport.m_x1 && // more than then left
m_y_inv < viewport.m_y2 && // below top
m_y_inv > viewport.m_y1) == 0) // above bottom
{
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
index ebf1b9ec577..94f5064261f 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -56,38 +56,95 @@
// if there is a better way (without global), please do so!
static PHY_IPhysicsEnvironment* g_CurrentActivePhysicsEnvironment = NULL;
-static char PhysicsConstraints_module_documentation[] =
-"This is the Python API for the Physics Constraints";
-
-
-static char gPySetGravity__doc__[] = "setGravity(float x,float y,float z)";
-static char gPySetDebugMode__doc__[] = "setDebugMode(int mode)";
-
-static char gPySetNumIterations__doc__[] = "setNumIterations(int numiter) This sets the number of iterations for an iterative constraint solver";
-static char gPySetNumTimeSubSteps__doc__[] = "setNumTimeSubSteps(int numsubstep) This sets the number of substeps for each physics proceed. Tradeoff quality for performance.";
-
-
-static char gPySetDeactivationTime__doc__[] = "setDeactivationTime(float time) This sets the time after which a resting rigidbody gets deactived";
-static char gPySetDeactivationLinearTreshold__doc__[] = "setDeactivationLinearTreshold(float linearTreshold)";
-static char gPySetDeactivationAngularTreshold__doc__[] = "setDeactivationAngularTreshold(float angularTreshold)";
-static char gPySetContactBreakingTreshold__doc__[] = "setContactBreakingTreshold(float breakingTreshold) Reasonable default is 0.02 (if units are meters)";
-
-static char gPySetCcdMode__doc__[] = "setCcdMode(int ccdMode) Very experimental, not recommended";
-static char gPySetSorConstant__doc__[] = "setSorConstant(float sor) Very experimental, not recommended";
-static char gPySetSolverTau__doc__[] = "setTau(float tau) Very experimental, not recommended";
-static char gPySetSolverDamping__doc__[] = "setDamping(float damping) Very experimental, not recommended";
-static char gPySetLinearAirDamping__doc__[] = "setLinearAirDamping(float damping) Very experimental, not recommended";
-static char gPySetUseEpa__doc__[] = "setUseEpa(int epa) Very experimental, not recommended";
-static char gPySetSolverType__doc__[] = "setSolverType(int solverType) Very experimental, not recommended";
-
-
-static char gPyCreateConstraint__doc__[] = "createConstraint(ob1,ob2,float restLength,float restitution,float damping)";
-static char gPyGetVehicleConstraint__doc__[] = "getVehicleConstraint(int constraintId)";
-static char gPyGetCharacter__doc__[] = "getCharacter(KX_GameObject obj)";
-static char gPyRemoveConstraint__doc__[] = "removeConstraint(int constraintId)";
-static char gPyGetAppliedImpulse__doc__[] = "getAppliedImpulse(int constraintId)";
-
+PyDoc_STRVAR(PhysicsConstraints_module_documentation,
+"This is the Python API for the Physics Constraints"
+);
+
+PyDoc_STRVAR(gPySetGravity__doc__,
+"setGravity(float x,float y,float z)\n"
+""
+);
+PyDoc_STRVAR(gPySetDebugMode__doc__,
+"setDebugMode(int mode)\n"
+""
+);
+
+PyDoc_STRVAR(gPySetNumIterations__doc__,
+"setNumIterations(int numiter)\n"
+"This sets the number of iterations for an iterative constraint solver"
+);
+PyDoc_STRVAR(gPySetNumTimeSubSteps__doc__,
+"setNumTimeSubSteps(int numsubstep)\n"
+"This sets the number of substeps for each physics proceed. Tradeoff quality for performance."
+);
+
+PyDoc_STRVAR(gPySetDeactivationTime__doc__,
+"setDeactivationTime(float time)\n"
+"This sets the time after which a resting rigidbody gets deactived"
+);
+PyDoc_STRVAR(gPySetDeactivationLinearTreshold__doc__,
+"setDeactivationLinearTreshold(float linearTreshold)\n"
+""
+);
+PyDoc_STRVAR(gPySetDeactivationAngularTreshold__doc__,
+"setDeactivationAngularTreshold(float angularTreshold)\n"
+""
+);
+PyDoc_STRVAR(gPySetContactBreakingTreshold__doc__,
+"setContactBreakingTreshold(float breakingTreshold)\n"
+"Reasonable default is 0.02 (if units are meters)"
+);
+
+PyDoc_STRVAR(gPySetCcdMode__doc__,
+"setCcdMode(int ccdMode)\n"
+"Very experimental, not recommended"
+);
+PyDoc_STRVAR(gPySetSorConstant__doc__,
+"setSorConstant(float sor)\n"
+"Very experimental, not recommended"
+);
+PyDoc_STRVAR(gPySetSolverTau__doc__,
+"setTau(float tau)\n"
+"Very experimental, not recommended"
+);
+PyDoc_STRVAR(gPySetSolverDamping__doc__,
+"setDamping(float damping)\n"
+"Very experimental, not recommended"
+);
+PyDoc_STRVAR(gPySetLinearAirDamping__doc__,
+"setLinearAirDamping(float damping)\n"
+"Very experimental, not recommended"
+);
+PyDoc_STRVAR(gPySetUseEpa__doc__,
+"setUseEpa(int epa)\n"
+"Very experimental, not recommended"
+);
+PyDoc_STRVAR(gPySetSolverType__doc__,
+"setSolverType(int solverType)\n"
+"Very experimental, not recommended"
+);
+
+PyDoc_STRVAR(gPyCreateConstraint__doc__,
+"createConstraint(ob1,ob2,float restLength,float restitution,float damping)\n"
+""
+);
+PyDoc_STRVAR(gPyGetVehicleConstraint__doc__,
+"getVehicleConstraint(int constraintId)\n"
+""
+);
+PyDoc_STRVAR(gPyGetCharacter__doc__,
+"getCharacter(KX_GameObject obj)\n"
+""
+);
+PyDoc_STRVAR(gPyRemoveConstraint__doc__,
+"removeConstraint(int constraintId)\n"
+""
+);
+PyDoc_STRVAR(gPyGetAppliedImpulse__doc__,
+"getAppliedImpulse(int constraintId)\n"
+""
+);
@@ -438,11 +495,7 @@ static PyObject *gPyCreateConstraint(PyObject *self,
PyObject *kwds)
{
/* FIXME - physicsid is a long being cast to a pointer, should at least use PyCapsule */
-#if defined(_WIN64)
- __int64 physicsid=0,physicsid2 = 0;
-#else
- long physicsid=0,physicsid2 = 0;
-#endif
+ unsigned long long physicsid = 0, physicsid2 = 0;
int constrainttype=0, extrainfo=0;
int len = PyTuple_Size(args);
int success = 1;
@@ -451,51 +504,28 @@ static PyObject *gPyCreateConstraint(PyObject *self,
float pivotX=1,pivotY=1,pivotZ=1,axisX=0,axisY=0,axisZ=1;
if (len == 3)
{
-#if defined(_WIN64)
- success = PyArg_ParseTuple(args,"LLi",&physicsid,&physicsid2,&constrainttype);
-#else
- success = PyArg_ParseTuple(args,"lli",&physicsid,&physicsid2,&constrainttype);
-#endif
+ success = PyArg_ParseTuple(args, "KKi", &physicsid, &physicsid2, &constrainttype);
}
else if (len == 6)
{
-#if defined(_WIN64)
- success = PyArg_ParseTuple(args,"LLifff",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ);
-#else
- success = PyArg_ParseTuple(args,"llifff",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ);
-#endif
+ success = PyArg_ParseTuple(args, "KKifff", &physicsid, &physicsid2, &constrainttype,
+ &pivotX, &pivotY, &pivotZ);
}
else if (len == 9)
{
-#if defined(_WIN64)
- success = PyArg_ParseTuple(args,"LLiffffff",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ);
-#else
- success = PyArg_ParseTuple(args,"lliffffff",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ);
-#endif
+ success = PyArg_ParseTuple(args, "KKiffffff", &physicsid, &physicsid2, &constrainttype,
+ &pivotX, &pivotY, &pivotZ, &axisX, &axisY, &axisZ);
}
else if (len == 10)
{
-#if defined(_WIN64)
- success = PyArg_ParseTuple(args,"LLiffffffi",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ,&flag);
-#else
- success = PyArg_ParseTuple(args,"lliffffffi",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ,&flag);
-#endif
+ success = PyArg_ParseTuple(args, "KKiffffffi", &physicsid, &physicsid2, &constrainttype,
+ &pivotX, &pivotY, &pivotZ, &axisX, &axisY, &axisZ, &flag);
}
/* XXX extrainfo seems to be nothing implemented. right now it works as a pivot with [X,0,0] */
else if (len == 4)
{
-#if defined(_WIN64)
- success = PyArg_ParseTuple(args,"LLii",&physicsid,&physicsid2,&constrainttype,&extrainfo);
-#else
- success = PyArg_ParseTuple(args,"llii",&physicsid,&physicsid2,&constrainttype,&extrainfo);
-#endif
+ success = PyArg_ParseTuple(args,"KKii", &physicsid, &physicsid2, &constrainttype, &extrainfo);
pivotX=extrainfo;
}
@@ -508,31 +538,24 @@ static PyObject *gPyCreateConstraint(PyObject *self,
PHY_IPhysicsController* physctrl2 = (PHY_IPhysicsController*) physicsid2;
if (physctrl) //TODO:check for existence of this pointer!
{
- PHY_ConstraintType ct = (PHY_ConstraintType) constrainttype;
int constraintid =0;
- if (ct == PHY_GENERIC_6DOF_CONSTRAINT)
- {
- //convert from euler angle into axis
- float radsPerDeg = 6.283185307179586232f / 360.f;
-
- //we need to pass a full constraint frame, not just axis
- //localConstraintFrameBasis
- MT_Matrix3x3 localCFrame(MT_Vector3(radsPerDeg*axisX,radsPerDeg*axisY,radsPerDeg*axisZ));
- MT_Vector3 axis0 = localCFrame.getColumn(0);
- MT_Vector3 axis1 = localCFrame.getColumn(1);
- MT_Vector3 axis2 = localCFrame.getColumn(2);
-
- constraintid = PHY_GetActiveEnvironment()->CreateConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,
- pivotX,pivotY,pivotZ,
- (float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
- (float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
- (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),flag);
- }
- else {
- constraintid = PHY_GetActiveEnvironment()->CreateConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ,0);
- }
-
+ //convert from euler angle into axis
+ float radsPerDeg = 6.283185307179586232f / 360.f;
+
+ //we need to pass a full constraint frame, not just axis
+ //localConstraintFrameBasis
+ MT_Matrix3x3 localCFrame(MT_Vector3(radsPerDeg*axisX,radsPerDeg*axisY,radsPerDeg*axisZ));
+ MT_Vector3 axis0 = localCFrame.getColumn(0);
+ MT_Vector3 axis1 = localCFrame.getColumn(1);
+ MT_Vector3 axis2 = localCFrame.getColumn(2);
+
+ constraintid = PHY_GetActiveEnvironment()->CreateConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,
+ pivotX,pivotY,pivotZ,
+ (float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
+ (float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
+ (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),flag);
+
KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,PHY_GetActiveEnvironment());
return wrap->NewProxy(true);
@@ -677,7 +700,7 @@ static struct PyMethodDef physicsconstraints_methods[] = {
};
static struct PyModuleDef PhysicsConstraints_module_def = {
- {}, /* m_base */
+ PyModuleDef_HEAD_INIT,
"PhysicsConstraints", /* m_name */
PhysicsConstraints_module_documentation, /* m_doc */
0, /* m_size */
@@ -688,7 +711,7 @@ static struct PyModuleDef PhysicsConstraints_module_def = {
0, /* m_free */
};
-PyObject *initPythonConstraintBinding()
+PyMODINIT_FUNC initConstraintPythonBinding()
{
PyObject *ErrorObject;
@@ -696,19 +719,8 @@ PyObject *initPythonConstraintBinding()
PyObject *d;
PyObject *item;
- /* Use existing module where possible
- * be careful not to init any runtime vars after this */
- m = PyImport_ImportModule( "PhysicsConstraints" );
- if (m) {
- Py_DECREF(m);
- return m;
- }
- else {
- PyErr_Clear();
-
- m = PyModule_Create(&PhysicsConstraints_module_def);
- PyDict_SetItemString(PySys_GetObject("modules"), PhysicsConstraints_module_def.m_name, m);
- }
+ m = PyModule_Create(&PhysicsConstraints_module_def);
+ PyDict_SetItemString(PySys_GetObject("modules"), PhysicsConstraints_module_def.m_name, m);
// Add some symbolic constants to the module
d = PyModule_GetDict(m);
@@ -747,7 +759,7 @@ PyObject *initPythonConstraintBinding()
Py_FatalError("can't initialize module PhysicsConstraints");
}
- return d;
+ return m;
}
#if 0
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.h b/source/gameengine/Ketsji/KX_PyConstraintBinding.h
index b4a520ce71b..2bf9f7e197d 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.h
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.h
@@ -36,7 +36,8 @@
#include <Python.h>
-PyObject* initPythonConstraintBinding();
+PyMODINIT_FUNC initConstraintPythonBinding();
+
void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env);
PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment();
#endif /* WITH_PYTHON */
diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp
index 804e8de2ad1..76332e75204 100644
--- a/source/gameengine/Ketsji/KX_PyMath.cpp
+++ b/source/gameengine/Ketsji/KX_PyMath.cpp
@@ -100,7 +100,7 @@ PyObject *PyObjectFrom(const MT_Matrix4x4 &mat)
#ifdef USE_MATHUTILS
float fmat[16];
mat.getValue(fmat);
- return Matrix_CreatePyObject(fmat, 4, 4, Py_NEW, NULL);
+ return Matrix_CreatePyObject(fmat, 4, 4, NULL);
#else
PyObject *collist = PyList_New(4);
PyObject *col;
@@ -124,7 +124,7 @@ PyObject *PyObjectFrom(const MT_Matrix3x3 &mat)
#ifdef USE_MATHUTILS
float fmat[9];
mat.getValue3x3(fmat);
- return Matrix_CreatePyObject(fmat, 3, 3, Py_NEW, NULL);
+ return Matrix_CreatePyObject(fmat, 3, 3, NULL);
#else
PyObject *collist = PyList_New(3);
PyObject *col;
@@ -148,7 +148,7 @@ PyObject *PyObjectFrom(const MT_Quaternion &qrot)
/* NOTE, were re-ordering here for Mathutils compat */
float fvec[4];
qrot.getValue(fvec);
- return Quaternion_CreatePyObject(fvec, Py_NEW, NULL);
+ return Quaternion_CreatePyObject(fvec, NULL);
}
#endif
@@ -157,7 +157,7 @@ PyObject *PyObjectFrom(const MT_Tuple4 &vec)
#ifdef USE_MATHUTILS
float fvec[4];
vec.getValue(fvec);
- return Vector_CreatePyObject(fvec, 4, Py_NEW, NULL);
+ return Vector_CreatePyObject(fvec, 4, NULL);
#else
PyObject *list = PyList_New(4);
PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
@@ -173,7 +173,7 @@ PyObject *PyObjectFrom(const MT_Tuple3 &vec)
#ifdef USE_MATHUTILS
float fvec[3];
vec.getValue(fvec);
- return Vector_CreatePyObject(fvec, 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(fvec, 3, NULL);
#else
PyObject *list = PyList_New(3);
PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
@@ -188,7 +188,7 @@ PyObject *PyObjectFrom(const MT_Tuple2 &vec)
#ifdef USE_MATHUTILS
float fvec[2];
vec.getValue(fvec);
- return Vector_CreatePyObject(fvec, 2, Py_NEW, NULL);
+ return Vector_CreatePyObject(fvec, 2, NULL);
#else
PyObject *list = PyList_New(2);
PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index fefc64b4bad..d7dd3fe5253 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -130,12 +130,16 @@ extern "C" {
#include "DNA_scene_types.h"
#include "PHY_IPhysicsEnvironment.h"
+
+extern "C" {
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_library.h"
+#include "BKE_appdir.h"
#include "BLI_blenlib.h"
#include "GPU_material.h"
#include "MEM_guardedalloc.h"
+}
/* for converting new scenes */
#include "KX_BlenderSceneConverter.h"
@@ -219,8 +223,11 @@ static void KX_MACRO_addTypesToDict_fn(PyObject *dict, const char *name, long va
// List of methods defined in the module
static PyObject *ErrorObject;
-static const char *gPyGetRandomFloat_doc="getRandomFloat returns a random floating point value in the range [0..1]";
+PyDoc_STRVAR(gPyGetRandomFloat_doc,
+"getRandomFloat()\n"
+"returns a random floating point value in the range [0..1]"
+);
static PyObject *gPyGetRandomFloat(PyObject *)
{
return PyFloat_FromDouble(MT_random());
@@ -238,15 +245,15 @@ static PyObject *gPySetGravity(PyObject *, PyObject *value)
Py_RETURN_NONE;
}
-static char gPyExpandPath_doc[] =
-"(path) - Converts a blender internal path into a proper file system path.\n\
-path - the string path to convert.\n\n\
-Use / as directory separator in path\n\
-You can use '//' at the start of the string to define a relative path;\n\
-Blender replaces that string by the directory of the current .blend or runtime\n\
-file to make a full path name.\n\
-The function also converts the directory separator to the local file system format.";
-
+PyDoc_STRVAR(gPyExpandPath_doc,
+"expandPath(path)\n"
+"Converts a blender internal path into a proper file system path.\n"
+" path - the string path to convert.\n"
+"Use / as directory separator in path\n"
+"You can use '//' at the start of the string to define a relative path."
+"Blender replaces that string by the directory of the current .blend or runtime file to make a full path name.\n"
+"The function also converts the directory separator to the local file system format."
+);
static PyObject *gPyExpandPath(PyObject *, PyObject *args)
{
char expanded[FILE_MAX];
@@ -260,10 +267,10 @@ static PyObject *gPyExpandPath(PyObject *, PyObject *args)
return PyC_UnicodeFromByte(expanded);
}
-static char gPyStartGame_doc[] =
-"startGame(blend)\n\
-Loads the blend file";
-
+PyDoc_STRVAR(gPyStartGame_doc,
+"startGame(blend)\n"
+"Loads the blend file"
+);
static PyObject *gPyStartGame(PyObject *, PyObject *args)
{
char* blendfile;
@@ -277,10 +284,10 @@ static PyObject *gPyStartGame(PyObject *, PyObject *args)
Py_RETURN_NONE;
}
-static char gPyEndGame_doc[] =
-"endGame()\n\
-Ends the current game";
-
+PyDoc_STRVAR(gPyEndGame_doc,
+"endGame()\n"
+"Ends the current game"
+);
static PyObject *gPyEndGame(PyObject *)
{
gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_QUIT_GAME);
@@ -290,10 +297,10 @@ static PyObject *gPyEndGame(PyObject *)
Py_RETURN_NONE;
}
-static char gPyRestartGame_doc[] =
-"restartGame()\n\
-Restarts the current game by reloading the .blend file";
-
+PyDoc_STRVAR(gPyRestartGame_doc,
+"restartGame()\n"
+"Restarts the current game by reloading the .blend file"
+);
static PyObject *gPyRestartGame(PyObject *)
{
gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_RESTART_GAME);
@@ -302,10 +309,10 @@ static PyObject *gPyRestartGame(PyObject *)
Py_RETURN_NONE;
}
-static char gPySaveGlobalDict_doc[] =
- "saveGlobalDict()\n"
- "Saves bge.logic.globalDict to a file";
-
+PyDoc_STRVAR(gPySaveGlobalDict_doc,
+"saveGlobalDict()\n"
+"Saves bge.logic.globalDict to a file"
+);
static PyObject *gPySaveGlobalDict(PyObject *)
{
char marshal_path[512];
@@ -339,10 +346,10 @@ static PyObject *gPySaveGlobalDict(PyObject *)
Py_RETURN_NONE;
}
-static char gPyLoadGlobalDict_doc[] =
- "LoadGlobalDict()\n"
- "Loads bge.logic.globalDict from a file";
-
+PyDoc_STRVAR(gPyLoadGlobalDict_doc,
+"LoadGlobalDict()\n"
+"Loads bge.logic.globalDict from a file"
+);
static PyObject *gPyLoadGlobalDict(PyObject *)
{
char marshal_path[512];
@@ -380,23 +387,23 @@ static PyObject *gPyLoadGlobalDict(PyObject *)
Py_RETURN_NONE;
}
-static char gPyGetProfileInfo_doc[] =
+PyDoc_STRVAR(gPyGetProfileInfo_doc,
"getProfileInfo()\n"
-"returns a dictionary with profiling information";
-
+"returns a dictionary with profiling information"
+);
static PyObject *gPyGetProfileInfo(PyObject *)
{
return gp_KetsjiEngine->GetPyProfileDict();
}
-static char gPySendMessage_doc[] =
-"sendMessage(subject, [body, to, from])\n\
-sends a message in same manner as a message actuator\
-subject = Subject of the message\
-body = Message body\
-to = Name of object to send the message to\
-from = Name of object to send the string from";
-
+PyDoc_STRVAR(gPySendMessage_doc,
+"sendMessage(subject, [body, to, from])\n"
+"sends a message in same manner as a message actuator"
+" subject = Subject of the message"
+" body = Message body"
+" to = Name of object to send the message to"
+" from = Name of object to send the string from"
+);
static PyObject *gPySendMessage(PyObject *, PyObject *args)
{
char* subject;
@@ -556,11 +563,12 @@ static PyObject *gPyGetBlendFileList(PyObject *, PyObject *args)
return list;
}
-static char gPyAddScene_doc[] =
-"addScene(name, [overlay])\n\
-adds a scene to the game engine\n\
-name = Name of the scene\n\
-overlay = Overlay or underlay";
+PyDoc_STRVAR(gPyAddScene_doc,
+"addScene(name, [overlay])\n"
+"Adds a scene to the game engine.\n"
+" name = Name of the scene\n"
+" overlay = Overlay or underlay"
+);
static PyObject *gPyAddScene(PyObject *, PyObject *args)
{
char* name;
@@ -574,17 +582,19 @@ static PyObject *gPyAddScene(PyObject *, PyObject *args)
Py_RETURN_NONE;
}
-static const char *gPyGetCurrentScene_doc =
+PyDoc_STRVAR(gPyGetCurrentScene_doc,
"getCurrentScene()\n"
-"Gets a reference to the current scene.\n";
+"Gets a reference to the current scene."
+);
static PyObject *gPyGetCurrentScene(PyObject *self)
{
return gp_KetsjiScene->GetProxy();
}
-static const char *gPyGetSceneList_doc =
+PyDoc_STRVAR(gPyGetSceneList_doc,
"getSceneList()\n"
-"Return a list of converted scenes.\n";
+"Return a list of converted scenes."
+);
static PyObject *gPyGetSceneList(PyObject *self)
{
KX_KetsjiEngine* m_engine = KX_GetActiveEngine();
@@ -1002,6 +1012,21 @@ static PyObject *gPyGetFocalLength(PyObject *, PyObject *, PyObject *)
Py_RETURN_NONE;
}
+static PyObject *gPyGetStereoEye(PyObject *, PyObject *, PyObject *)
+{
+ int flag = RAS_IRasterizer::RAS_STEREO_LEFTEYE;
+
+ if (!gp_Rasterizer) {
+ PyErr_SetString(PyExc_RuntimeError, "Rasterizer.getStereoEye(), Rasterizer not available");
+ return NULL;
+ }
+
+ if (gp_Rasterizer->Stereo())
+ flag = gp_Rasterizer->GetEye();
+
+ return PyLong_FromLong(flag);
+}
+
static PyObject *gPySetBackgroundColor(PyObject *, PyObject *value)
{
@@ -1465,6 +1490,9 @@ static PyObject *gPyClearDebugList(PyObject *)
Py_RETURN_NONE;
}
+PyDoc_STRVAR(Rasterizer_module_documentation,
+"This is the Python API for the game engine of Rasterizer"
+);
static struct PyMethodDef rasterizer_methods[] = {
{"getWindowWidth",(PyCFunction) gPyGetWindowWidth,
@@ -1492,6 +1520,7 @@ static struct PyMethodDef rasterizer_methods[] = {
{"getEyeSeparation", (PyCFunction) gPyGetEyeSeparation, METH_NOARGS, "get the eye separation for stereo mode"},
{"setFocalLength", (PyCFunction) gPySetFocalLength, METH_VARARGS, "set the focal length for stereo mode"},
{"getFocalLength", (PyCFunction) gPyGetFocalLength, METH_VARARGS, "get the focal length for stereo mode"},
+ {"getStereoEye", (PyCFunction) gPyGetStereoEye, METH_VARARGS, "get the current stereoscopy eye being rendered"},
{"setMaterialMode",(PyCFunction) gPySetMaterialType,
METH_VARARGS, "set the material mode to use for OpenGL rendering"},
{"getMaterialMode",(PyCFunction) gPyGetMaterialType,
@@ -1521,15 +1550,11 @@ static struct PyMethodDef rasterizer_methods[] = {
{ NULL, (PyCFunction) NULL, 0, NULL }
};
-// Initialization function for the module (*must* be called initGameLogic)
-static char GameLogic_module_documentation[] =
-"This is the Python API for the game engine of bge.logic"
-;
-static char Rasterizer_module_documentation[] =
-"This is the Python API for the game engine of Rasterizer"
-;
+PyDoc_STRVAR(GameLogic_module_documentation,
+"This is the Python API for the game engine of bge.logic"
+);
static struct PyModuleDef GameLogic_module_def = {
{}, /* m_base */
@@ -1543,33 +1568,20 @@ static struct PyModuleDef GameLogic_module_def = {
0, /* m_free */
};
-PyObject *initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack to get gravity hook
+PyMODINIT_FUNC initGameLogicPythonBinding()
{
PyObject *m;
PyObject *d;
PyObject *item; /* temp PyObject *storage */
-
- gp_KetsjiEngine = engine;
- gp_KetsjiScene = scene;
gUseVisibilityTemp=false;
-
+
PyObjectPlus::ClearDeprecationWarning(); /* Not that nice to call here but makes sure warnings are reset between loading scenes */
-
- /* Use existing module where possible
- * be careful not to init any runtime vars after this */
- m = PyImport_ImportModule( "GameLogic" );
- if (m) {
- Py_DECREF(m);
- return m;
- }
- else {
- PyErr_Clear();
- // Create the module and add the functions
- m = PyModule_Create(&GameLogic_module_def);
- PyDict_SetItemString(PySys_GetObject("modules"), GameLogic_module_def.m_name, m);
- }
-
+
+ m = PyModule_Create(&GameLogic_module_def);
+ PyDict_SetItemString(PySys_GetObject("modules"), GameLogic_module_def.m_name, m);
+
+
// Add some symbolic constants to the module
d = PyModule_GetDict(m);
@@ -1589,17 +1601,22 @@ PyObject *initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
PyObject* joylist = PyList_New(JOYINDEX_MAX);
for (int i=0; i<JOYINDEX_MAX; ++i) {
- SCA_Joystick* joy = SCA_Joystick::GetInstance(i);
+ SCA_Joystick *joy = SCA_Joystick::GetInstance(i);
+ PyObject *item;
+
if (joy && joy->Connected()) {
gp_PythonJoysticks[i] = new SCA_PythonJoystick(joy);
- PyObject* tmp = gp_PythonJoysticks[i]->NewProxy(true);
- Py_INCREF(tmp);
- PyList_SET_ITEM(joylist, i, tmp);
- } else {
- joy->ReleaseInstance();
- Py_INCREF(Py_None);
- PyList_SET_ITEM(joylist, i, Py_None);
+ item = gp_PythonJoysticks[i]->NewProxy(true);
}
+ else {
+ if (joy) {
+ joy->ReleaseInstance();
+ }
+ item = Py_None;
+ }
+
+ Py_INCREF(item);
+ PyList_SET_ITEM(joylist, i, item);
}
PyDict_SetItemString(d, "joysticks", joylist);
@@ -2049,7 +2066,60 @@ void removeImportMain(struct Main *maggie)
bpy_import_main_extra_remove(maggie);
}
-// Copied from bpy_interface.c
+
+PyDoc_STRVAR(BGE_module_documentation,
+ "This module contains submodules for the Blender Game Engine.\n"
+);
+
+static struct PyModuleDef BGE_module_def = {
+ PyModuleDef_HEAD_INIT,
+ "bge", /* m_name */
+ BGE_module_documentation, /* m_doc */
+ 0, /* m_size */
+ NULL, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+PyMODINIT_FUNC initBGE(void)
+{
+ PyObject *mod;
+ PyObject *submodule;
+ PyObject *sys_modules = PyThreadState_GET()->interp->modules;
+
+ mod = PyModule_Create(&BGE_module_def);
+
+ PyModule_AddObject(mod, "constraints", (submodule = initConstraintPythonBinding()));
+ PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
+ Py_INCREF(submodule);
+
+ PyModule_AddObject(mod, "events", (submodule = initGameKeysPythonBinding()));
+ PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
+ Py_INCREF(submodule);
+
+ PyModule_AddObject(mod, "logic", (submodule = initGameLogicPythonBinding()));
+ PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
+ Py_INCREF(submodule);
+
+ PyModule_AddObject(mod, "render", (submodule = initRasterizerPythonBinding()));
+ PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
+ Py_INCREF(submodule);
+
+ PyModule_AddObject(mod, "texture", (submodule = initVideoTexturePythonBinding()));
+ PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
+ Py_INCREF(submodule);
+
+ PyModule_AddObject(mod, "types", (submodule = initGameTypesPythonBinding()));
+ PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule);
+ Py_INCREF(submodule);
+
+ return mod;
+}
+
+
+/* minimal required blender modules to run blenderplayer */
static struct _inittab bge_internal_modules[] = {
{"mathutils", PyInit_mathutils},
{"bgl", BPyInit_bgl},
@@ -2062,7 +2132,7 @@ static struct _inittab bge_internal_modules[] = {
* Python is not initialized.
* see bpy_interface.c's BPY_python_start() which shares the same functionality in blender.
*/
-PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie, int argc, char** argv)
+PyObject *initGamePlayerPythonScripting(Main *maggie, int argc, char** argv)
{
/* Yet another gotcha in the py api
* Cant run PySys_SetArgv more than once because this adds the
@@ -2071,16 +2141,22 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
* somehow it remembers the sys.path - Campbell
*/
static bool first_time = true;
- const char * const py_path_bundle = BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL);
-
-#if 0 // TODO - py3
- STR_String pname = progname;
- Py_SetProgramName(pname.Ptr());
-#endif
-
+ const char * const py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL);
+
+ /* not essential but nice to set our name */
+ static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */
+ BLI_strncpy_wchar_from_utf8(program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar));
+ Py_SetProgramName(program_path_wchar);
+
+ /* Update, Py3.3 resolves attempting to parse non-existing header */
+ #if 0
+ /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to
+ * parse from the 'sysconfig' module which is used by 'site',
+ * so for now disable site. alternatively we could copy the file. */
if (py_path_bundle != NULL) {
- Py_NoSiteFlag = 1;
+ Py_NoSiteFlag = 1; /* inhibits the automatic importing of 'site' */
}
+ #endif
Py_FrozenFlag = 1;
@@ -2104,12 +2180,16 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
PySys_SetObject("argv", py_argv);
Py_DECREF(py_argv);
}
-
+
/* Initialize thread support (also acquires lock) */
PyEval_InitThreads();
bpy_import_init(PyEval_GetBuiltins());
+ bpy_import_main_set(maggie);
+
+ initPySysObjects(maggie);
+
/* mathutils types are used by the BGE even if we don't import them */
{
PyObject *mod = PyImport_ImportModuleLevel("mathutils", NULL, NULL, NULL, 0);
@@ -2124,12 +2204,8 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
}
#endif
- initPyTypes();
-
- bpy_import_main_set(maggie);
-
- initPySysObjects(maggie);
-
+ PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE());
+
first_time = false;
PyObjectPlus::ClearDeprecationWarning();
@@ -2166,12 +2242,13 @@ void exitGamePlayerPythonScripting()
/**
* Python is already initialized.
*/
-PyObject *initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie)
+PyObject *initGamePythonScripting(Main *maggie)
{
-#if 0 // XXX TODO Py3
- STR_String pname = progname;
- Py_SetProgramName(pname.Ptr());
-#endif
+ /* no need to Py_SetProgramName, it was already taken care of in BPY_python_start */
+
+ bpy_import_main_set(maggie);
+
+ initPySysObjects(maggie);
#ifdef WITH_AUDASPACE
/* accessing a SoundActuator's sound results in a crash if aud is not initialized... */
@@ -2181,11 +2258,7 @@ PyObject *initGamePythonScripting(const STR_String& progname, TPythonSecurityLev
}
#endif
- initPyTypes();
-
- bpy_import_main_set(maggie);
-
- initPySysObjects(maggie);
+ PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE());
PyObjectPlus::NullDeprecationWarning();
@@ -2218,51 +2291,32 @@ void exitGamePythonScripting()
void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene *startscene, Main *blenderdata,
PyObject *pyGlobalDict, PyObject **gameLogic, PyObject **gameLogic_keys, int argc, char** argv)
{
- PyObject *dictionaryobject;
+ PyObject *modules, *dictionaryobject;
+
+ gp_Canvas = ketsjiengine->GetCanvas();
+ gp_Rasterizer = ketsjiengine->GetRasterizer();
+ gp_KetsjiEngine = ketsjiengine;
+ gp_KetsjiScene = startscene;
if (argv) /* player only */
- dictionaryobject= initGamePlayerPythonScripting("Ketsji", psl_Lowest, blenderdata, argc, argv);
+ dictionaryobject= initGamePlayerPythonScripting(blenderdata, argc, argv);
else
- dictionaryobject= initGamePythonScripting("Ketsji", psl_Lowest, blenderdata);
+ dictionaryobject= initGamePythonScripting(blenderdata);
ketsjiengine->SetPyNamespace(dictionaryobject);
- initRasterizer(ketsjiengine->GetRasterizer(), ketsjiengine->GetCanvas());
- *gameLogic = initGameLogic(ketsjiengine, startscene);
- /* is set in initGameLogic so only set here if we want it to persist between scenes */
+ modules = PyImport_GetModuleDict();
+
+ *gameLogic = PyDict_GetItemString(modules, "GameLogic");
+ /* is set in initGameLogicPythonBinding so only set here if we want it to persist between scenes */
if (pyGlobalDict)
PyDict_SetItemString(PyModule_GetDict(*gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.
*gameLogic_keys = PyDict_Keys(PyModule_GetDict(*gameLogic));
-
- initGameKeys();
- initPythonConstraintBinding();
- initVideoTexture();
-
- /* could be done a lot more nicely, but for now a quick way to get bge.* working */
- PyRun_SimpleString("sys = __import__('sys');"
- "bge = type(sys)('bge');"
- "bge.__dict__.update({'logic':__import__('GameLogic'), "
- "'render':__import__('Rasterizer'), "
- "'events':__import__('GameKeys'), "
- "'constraints':__import__('PhysicsConstraints'), "
- "'physics':__import__('PhysicsConstraints'),"
- "'types':__import__('GameTypes'), "
- "'texture':__import__('VideoTexture')});"
- /* so we can do 'import bge.foo as bar' */
- "sys.modules.update({'bge': bge, "
- "'bge.logic':bge.logic, "
- "'bge.render':bge.render, "
- "'bge.events':bge.events, "
- "'bge.constraints':bge.constraints, "
- "'bge.physics':bge.physics,"
- "'bge.types':bge.types, "
- "'bge.texture':bge.texture})"
- );
}
static struct PyModuleDef Rasterizer_module_def = {
- {}, /* m_base */
+ PyModuleDef_HEAD_INIT,
"Rasterizer", /* m_name */
Rasterizer_module_documentation, /* m_doc */
0, /* m_size */
@@ -2273,29 +2327,14 @@ static struct PyModuleDef Rasterizer_module_def = {
0, /* m_free */
};
-PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
+PyMODINIT_FUNC initRasterizerPythonBinding()
{
- gp_Canvas = canvas;
- gp_Rasterizer = rasty;
-
-
PyObject *m;
PyObject *d;
- /* Use existing module where possible
- * be careful not to init any runtime vars after this */
- m = PyImport_ImportModule( "Rasterizer" );
- if (m) {
- Py_DECREF(m);
- return m;
- }
- else {
- PyErr_Clear();
+ m = PyModule_Create(&Rasterizer_module_def);
+ PyDict_SetItemString(PySys_GetObject("modules"), Rasterizer_module_def.m_name, m);
- // Create the module and add the functions
- m = PyModule_Create(&Rasterizer_module_def);
- PyDict_SetItemString(PySys_GetObject("modules"), Rasterizer_module_def.m_name, m);
- }
// Add some symbolic constants to the module
d = PyModule_GetDict(m);
@@ -2316,6 +2355,10 @@ PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
KX_MACRO_addTypesToDict(d, VSYNC_ON, VSYNC_ON);
KX_MACRO_addTypesToDict(d, VSYNC_ADAPTIVE, VSYNC_ADAPTIVE);
+ /* stereoscopy */
+ KX_MACRO_addTypesToDict(d, LEFT_EYE, RAS_IRasterizer::RAS_STEREO_LEFTEYE);
+ KX_MACRO_addTypesToDict(d, RIGHT_EYE, RAS_IRasterizer::RAS_STEREO_RIGHTEYE);
+
// XXXX Add constants here
// Check for errors
@@ -2324,7 +2367,7 @@ PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
Py_FatalError("can't initialize module Rasterizer");
}
- return d;
+ return m;
}
@@ -2333,13 +2376,14 @@ PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
/* GameKeys: symbolic constants for key mapping */
/* ------------------------------------------------------------------------- */
-static char GameKeys_module_documentation[] =
+PyDoc_STRVAR(GameKeys_module_documentation,
"This modules provides defines for key-codes"
-;
+);
-static char gPyEventToString_doc[] =
-"EventToString(event) - Take a valid event from the GameKeys module or Keyboard Sensor and return a name"
-;
+PyDoc_STRVAR(gPyEventToString_doc,
+"EventToString(event)\n"
+"Take a valid event from the GameKeys module or Keyboard Sensor and return a name"
+);
static PyObject *gPyEventToString(PyObject *, PyObject *value)
{
@@ -2367,9 +2411,11 @@ static PyObject *gPyEventToString(PyObject *, PyObject *value)
return ret;
}
-static char gPyEventToCharacter_doc[] =
-"EventToCharacter(event, is_shift) - Take a valid event from the GameKeys module or Keyboard Sensor and return a character"
-;
+
+PyDoc_STRVAR(gPyEventToCharacter_doc,
+"EventToCharacter(event, is_shift)\n"
+"Take a valid event from the GameKeys module or Keyboard Sensor and return a character"
+);
static PyObject *gPyEventToCharacter(PyObject *, PyObject *args)
{
@@ -2395,7 +2441,7 @@ static struct PyMethodDef gamekeys_methods[] = {
};
static struct PyModuleDef GameKeys_module_def = {
- {}, /* m_base */
+ PyModuleDef_HEAD_INIT,
"GameKeys", /* m_name */
GameKeys_module_documentation, /* m_doc */
0, /* m_size */
@@ -2406,24 +2452,13 @@ static struct PyModuleDef GameKeys_module_def = {
0, /* m_free */
};
-PyObject *initGameKeys()
+PyMODINIT_FUNC initGameKeysPythonBinding()
{
PyObject *m;
PyObject *d;
-
- /* Use existing module where possible */
- m = PyImport_ImportModule( "GameKeys" );
- if (m) {
- Py_DECREF(m);
- return m;
- }
- else {
- PyErr_Clear();
-
- // Create the module and add the functions
- m = PyModule_Create(&GameKeys_module_def);
- PyDict_SetItemString(PySys_GetObject("modules"), GameKeys_module_def.m_name, m);
- }
+
+ m = PyModule_Create(&GameKeys_module_def);
+ PyDict_SetItemString(PySys_GetObject("modules"), GameKeys_module_def.m_name, m);
// Add some symbolic constants to the module
d = PyModule_GetDict(m);
@@ -2568,7 +2603,7 @@ PyObject *initGameKeys()
Py_FatalError("can't initialize module GameKeys");
}
- return d;
+ return m;
}
// utility function for loading and saving the globalDict
diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h
index 719a74ee219..f74a4b3865f 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.h
+++ b/source/gameengine/Ketsji/KX_PythonInit.h
@@ -36,6 +36,9 @@
#include "STR_String.h"
#include "MT_Vector3.h"
+class KX_KetsjiEngine;
+class KX_Scene;
+
typedef enum {
psl_Lowest = 0,
psl_Highest,
@@ -44,13 +47,13 @@ typedef enum {
extern bool gUseVisibilityTemp;
#ifdef WITH_PYTHON
-PyObject *initGameLogic(class KX_KetsjiEngine *engine, class KX_Scene *ketsjiscene);
-PyObject *initGameKeys();
-PyObject *initRasterizer(class RAS_IRasterizer *rasty,class RAS_ICanvas *canvas);
-PyObject *initGamePlayerPythonScripting(const STR_String &progname, TPythonSecurityLevel level,
- struct Main *maggie, int argc, char **argv);
-PyObject *initVideoTexture(void);
-PyObject *initGamePythonScripting(const STR_String &progname, TPythonSecurityLevel level, struct Main *maggie);
+PyMODINIT_FUNC initBGE(void);
+PyMODINIT_FUNC initGameLogicPythonBinding(void);
+PyMODINIT_FUNC initGameKeysPythonBinding(void);
+PyMODINIT_FUNC initRasterizerPythonBinding(void);
+PyMODINIT_FUNC initVideoTexturePythonBinding(void);
+PyObject *initGamePlayerPythonScripting(struct Main *maggie, int argc, char **argv);
+PyObject *initGamePythonScripting(struct Main *maggie);
void exitGamePlayerPythonScripting();
void exitGamePythonScripting();
@@ -69,9 +72,9 @@ void removeImportMain(struct Main *maggie);
class KX_KetsjiEngine;
class KX_Scene;
-void KX_SetActiveScene(class KX_Scene *scene);
-class KX_Scene *KX_GetActiveScene();
-class KX_KetsjiEngine *KX_GetActiveEngine();
+void KX_SetActiveScene(KX_Scene *scene);
+KX_Scene *KX_GetActiveScene();
+KX_KetsjiEngine *KX_GetActiveEngine();
typedef int (*PyNextFrameFunc)(void *);
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
index 7d38ce58eee..828fd62f205 100644
--- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
@@ -163,21 +163,34 @@ static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *a
#define PyType_Ready_Attr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, NULL, i)
#define PyType_Ready_AttrPtr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, n::AttributesPtr, i)
-void initPyTypes(void)
+
+
+PyDoc_STRVAR(GameTypes_module_documentation,
+"This module provides access to the game engine data types."
+);
+static struct PyModuleDef GameTypes_module_def = {
+ PyModuleDef_HEAD_INIT,
+ "GameTypes", /* m_name */
+ GameTypes_module_documentation, /* m_doc */
+ 0, /* m_size */
+ NULL, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+};
+
+
+PyMODINIT_FUNC initGameTypesPythonBinding(void)
{
+ PyObject *m;
+ PyObject *dict;
-/*
- * initPyObjectPlusType(BL_ActionActuator::Parents);
- * .....
- */
+ m = PyModule_Create(&GameTypes_module_def);
+ PyDict_SetItemString(PySys_GetObject("modules"), GameTypes_module_def.m_name, m);
+
+ dict = PyModule_GetDict(m);
- /* For now just do PyType_Ready */
- PyObject *mod = PyModule_New("GameTypes");
- PyObject *dict = PyModule_GetDict(mod);
- PyDict_SetItemString(PySys_GetObject("modules"), "GameTypes", mod);
- Py_DECREF(mod);
-
-
for (int init_getset= 1; init_getset > -1; init_getset--) { /* run twice, once to init the getsets another to run PyType_Ready */
PyType_Ready_Attr(dict, BL_ActionActuator, init_getset);
PyType_Ready_Attr(dict, BL_Shader, init_getset);
@@ -267,6 +280,8 @@ void initPyTypes(void)
KX_GameObject_Mathutils_Callback_Init();
KX_ObjectActuator_Mathutils_Callback_Init();
#endif
+
+ return m;
}
#endif // WITH_PYTHON
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.h b/source/gameengine/Ketsji/KX_PythonInitTypes.h
index d8ee4f75fdd..cfc49a1dc93 100644
--- a/source/gameengine/Ketsji/KX_PythonInitTypes.h
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.h
@@ -33,7 +33,8 @@
#define __KX_PYTHON_INIT_TYPES__
#ifdef WITH_PYTHON
-void initPyTypes(void);
+#include <Python.h>
+PyMODINIT_FUNC initGameTypesPythonBinding(void);
#endif
#endif /* __KX_PYTHON_INIT_TYPES__ */
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index d0eab9de1c1..6d989ca1760 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -218,7 +218,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_bucketmanager=new RAS_BucketManager();
- bool showObstacleSimulation = scene->gm.flag & GAME_SHOW_OBSTACLE_SIMULATION;
+ bool showObstacleSimulation = (scene->gm.flag & GAME_SHOW_OBSTACLE_SIMULATION) != 0;
switch (scene->gm.obstacleSimulation)
{
case OBSTSIMULATION_TOI_rays:
@@ -532,6 +532,8 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
m_objectlist->Add(newobj->AddRef());
if (newobj->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
m_lightlist->Add(newobj->AddRef());
+ else if (newobj->GetGameObjectType()==SCA_IObject::OBJ_FONT)
+ AddFont((KX_FontObject*)newobj);
newobj->AddMeshUser();
// logic cannot be replicated, until the whole hierarchy is replicated.
@@ -867,8 +869,6 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
m_map_gameobject_to_replica.clear();
m_groupGameObjects.clear();
- // todo: place a timebomb in the object, for temporarily objects :)
- // lifespan of zero means 'this object lives forever'
KX_GameObject* originalobj = (KX_GameObject*) originalobject;
KX_GameObject* parentobj = (KX_GameObject*) parentobject;
@@ -877,9 +877,10 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
// lets create a replica
KX_GameObject* replica = (KX_GameObject*) AddNodeReplicaObject(NULL,originalobj);
+ // add a timebomb to this object
+ // lifespan of zero means 'this object lives forever'
if (lifespan > 0)
{
- // add a timebomb to this object
// for now, convert between so called frames and realtime
m_tempObjectList->Add(replica->AddRef());
// this convert the life from frames to sort-of seconds, hard coded 0.02 that assumes we have 50 frames per second
@@ -915,7 +916,6 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
// get the rootnode's scale
MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
-
// set the replica's relative scale with the rootnode's scale
replica->NodeSetRelativeScale(newscale);
@@ -1502,6 +1502,15 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int
bool dbvt_culling = false;
if (m_dbvt_culling)
{
+ /* Reset KX_GameObject m_bCulled to true before doing culling
+ * since DBVT culling will only set it to false.
+ * This is similar to what RAS_BucketManager does for RAS_MeshSlot culling.
+ */
+ for (int i = 0; i < m_objectlist->GetCount(); i++) {
+ KX_GameObject *gameobj = static_cast<KX_GameObject*>(m_objectlist->GetValue(i));
+ gameobj->SetCulled(true);
+ }
+
// test culling through Bullet
MT_Vector4 planes[6];
// get the clip planes
@@ -1531,9 +1540,6 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int
MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer);
}
}
-
- // Now that we know visible meshes, update LoDs
- UpdateObjectLods();
}
// logic stuff
@@ -1642,20 +1648,6 @@ static void update_anim_thread_func(TaskPool *pool, void *taskdata, int UNUSED(t
void KX_Scene::UpdateAnimations(double curtime)
{
- KX_KetsjiEngine *engine = KX_GetActiveEngine();
-
- if (engine->GetRestrictAnimationFPS())
- {
- // Handle the animations independently of the logic time step
- double anim_timestep = 1.0 / GetAnimationFPS();
- if (curtime - m_previousAnimTime < anim_timestep)
- return;
-
- // Sanity/debug print to make sure we're actually going at the fps we want (should be close to anim_timestep)
- // printf("Anim fps: %f\n", 1.0/(m_clockTime - m_previousAnimTime));
- m_previousAnimTime = curtime;
- }
-
TaskPool *pool = BLI_task_pool_create(KX_GetActiveEngine()->GetTaskScheduler(), &curtime);
for (int i=0; i<m_animatedlist->GetCount(); ++i) {
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index c5840c28041..2e1ee9f101d 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -289,8 +289,6 @@ protected:
double m_suspendedtime;
double m_suspendeddelta;
- double m_previousAnimTime; //the last time animations were updated
-
struct Scene* m_blenderScene;
RAS_2DFilterManager m_filtermanager;
diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.cpp b/source/gameengine/Ketsji/KX_SteeringActuator.cpp
index ff192299702..f859b1ceae9 100644
--- a/source/gameengine/Ketsji/KX_SteeringActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SteeringActuator.cpp
@@ -41,7 +41,7 @@
/* Native functions */
/* ------------------------------------------------------------------------- */
-KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj,
+KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj,
int mode,
KX_GameObject *target,
KX_GameObject *navmesh,
@@ -54,7 +54,8 @@ KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj,
KX_ObstacleSimulation* simulation,
short facingmode,
bool normalup,
- bool enableVisualization)
+ bool enableVisualization,
+ bool lockzvel)
: SCA_IActuator(gameobj, KX_ACT_STEERING),
m_target(target),
m_mode(mode),
@@ -72,6 +73,7 @@ KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj,
m_normalUp(normalup),
m_pathLen(0),
m_pathUpdatePeriod(pathUpdatePeriod),
+ m_lockzvel(lockzvel),
m_wayPointIdx(-1),
m_steerVec(MT_Vector3(0, 0, 0))
{
@@ -261,31 +263,39 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
if (apply_steerforce)
{
+ MT_Vector3 newvel;
bool isdyna = obj->IsDynamic();
if (isdyna)
m_steerVec.z() = 0;
if (!m_steerVec.fuzzyZero())
m_steerVec.normalize();
- MT_Vector3 newvel = m_velocity*m_steerVec;
//adjust velocity to avoid obstacles
if (m_simulation && m_obstacle /*&& !newvel.fuzzyZero()*/)
{
if (m_enableVisualization)
KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(1.0, 0.0, 0.0));
- m_simulation->AdjustObstacleVelocity(m_obstacle, m_mode!=KX_STEERING_PATHFOLLOWING ? m_navmesh : NULL,
+ m_simulation->AdjustObstacleVelocity(m_obstacle, m_mode!=KX_STEERING_PATHFOLLOWING ? m_navmesh : NULL,
newvel, m_acceleration*delta, m_turnspeed/180.0f*M_PI*delta);
if (m_enableVisualization)
KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(0.0, 1.0, 0.0));
}
- HandleActorFace(newvel);
+ HandleActorFace(m_steerVec);
if (isdyna)
{
- //temporary solution: set 2D steering velocity directly to obj
- //correct way is to apply physical force
+ //TODO: Take into account angular velocity on turns
MT_Vector3 curvel = obj->GetLinearVelocity();
- newvel.z() = curvel.z();
+
+ newvel = (curvel.length() * m_steerVec) + (m_acceleration * delta) * m_steerVec;
+ if (newvel.length2() >= (m_velocity * m_velocity))
+ newvel = m_velocity * m_steerVec;
+
+ if (m_lockzvel)
+ newvel.z() = 0.0f;
+ else
+ newvel.z() = curvel.z();
+
obj->setLinearVelocity(newvel, false);
}
else
@@ -554,6 +564,7 @@ PyAttributeDef KX_SteeringActuator::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("steeringVec", KX_SteeringActuator, pyattr_get_steeringVec),
KX_PYATTRIBUTE_SHORT_RW("facingMode", 0, 6, true, KX_SteeringActuator, m_facingMode),
KX_PYATTRIBUTE_INT_RW("pathUpdatePeriod", -1, 100000, true, KX_SteeringActuator, m_pathUpdatePeriod),
+ KX_PYATTRIBUTE_BOOL_RW("lockZVelocity", KX_SteeringActuator, m_lockzvel),
{ NULL } //Sentinel
};
diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.h b/source/gameengine/Ketsji/KX_SteeringActuator.h
index 1e8ac9a54f0..3273471c166 100644
--- a/source/gameengine/Ketsji/KX_SteeringActuator.h
+++ b/source/gameengine/Ketsji/KX_SteeringActuator.h
@@ -62,6 +62,7 @@ class KX_SteeringActuator : public SCA_IActuator
int m_pathLen;
int m_pathUpdatePeriod;
double m_pathUpdateTime;
+ bool m_lockzvel;
int m_wayPointIdx;
MT_Matrix3x3 m_parentlocalmat;
MT_Vector3 m_steerVec;
@@ -89,7 +90,8 @@ public:
KX_ObstacleSimulation* simulation,
short facingmode,
bool normalup,
- bool enableVisualization);
+ bool enableVisualization,
+ bool lockzvel);
virtual ~KX_SteeringActuator();
virtual bool Update(double curtime, bool frame);
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
index 7ec379eec26..eb774960d41 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
@@ -60,7 +60,7 @@ bool KX_TouchEventManager::NewHandleCollision(void* object1, void* object2, cons
PHY_IPhysicsController* obj1 = static_cast<PHY_IPhysicsController*>(object1);
PHY_IPhysicsController* obj2 = static_cast<PHY_IPhysicsController*>(object2);
- m_newCollisions.insert(std::pair<PHY_IPhysicsController*, PHY_IPhysicsController*>(obj1, obj2));
+ m_newCollisions.insert(NewCollision(obj1, obj2, coll_data));
return false;
}
@@ -209,9 +209,11 @@ void KX_TouchEventManager::NextFrame()
}
}
// Run python callbacks
- kxObj1->RunCollisionCallbacks(kxObj2);
- kxObj2->RunCollisionCallbacks(kxObj1);
+ PHY_CollData *colldata = cit->colldata;
+ kxObj1->RunCollisionCallbacks(kxObj2, colldata->m_point1, colldata->m_normal);
+ kxObj2->RunCollisionCallbacks(kxObj1, colldata->m_point2, -colldata->m_normal);
+ delete cit->colldata;
}
m_newCollisions.clear();
@@ -219,3 +221,19 @@ void KX_TouchEventManager::NextFrame()
for (it.begin();!it.end();++it)
(*it)->Activate(m_logicmgr);
}
+
+
+KX_TouchEventManager::NewCollision::NewCollision(PHY_IPhysicsController *first,
+ PHY_IPhysicsController *second,
+ const PHY_CollData *colldata)
+ : first(first), second(second), colldata(new PHY_CollData(*colldata))
+{}
+
+KX_TouchEventManager::NewCollision::NewCollision(const NewCollision &to_copy)
+ : first(to_copy.first), second(to_copy.second), colldata(to_copy.colldata)
+{}
+
+bool KX_TouchEventManager::NewCollision::operator<(const NewCollision &other) const
+{
+ return first < other.first || second < other.second || colldata < other.colldata;
+}
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h
index bd4903c1545..d9c6fdad307 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.h
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.h
@@ -45,7 +45,29 @@ class PHY_IPhysicsEnvironment;
class KX_TouchEventManager : public SCA_EventManager
{
- typedef std::pair<PHY_IPhysicsController*, PHY_IPhysicsController*> NewCollision;
+ /**
+ * Contains two colliding objects and the first contact point.
+ */
+ class NewCollision {
+ public:
+ PHY_IPhysicsController *first;
+ PHY_IPhysicsController *second;
+ PHY_CollData *colldata;
+
+ /**
+ * Creates a copy of the given PHY_CollData; freeing that copy should be done by the owner of
+ * the NewCollision object.
+ *
+ * This allows us to efficiently store NewCollision objects in a std::set without creating more
+ * copies of colldata, as the NewCollision copy constructor reuses the pointer and doesn't clone
+ * it again. */
+ NewCollision(PHY_IPhysicsController *first,
+ PHY_IPhysicsController *second,
+ const PHY_CollData *colldata);
+ NewCollision(const NewCollision &to_copy);
+ bool operator<(const NewCollision &other) const;
+ };
+
PHY_IPhysicsEnvironment* m_physEnv;
std::set<NewCollision> m_newCollisions;
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
index 535ed5ed39a..d10e51a491a 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
@@ -53,6 +53,22 @@ KX_VehicleWrapper::~KX_VehicleWrapper()
#ifdef WITH_PYTHON
+
+static bool raise_exc_wheel(PHY_IVehicle* vehicle, int i, const char *method)
+{
+ if ( i < 0 || i >= vehicle->GetNumWheels() ) {
+ PyErr_Format(PyExc_ValueError,
+ "%s(...): wheel index %d out of range (0 to %d).", method, i, vehicle->GetNumWheels()-1);
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+#define WHEEL_INDEX_CHECK_OR_RETURN(i, method) \
+ if (raise_exc_wheel(m_vehicle, i, method) == -1) { return NULL; } (void)0
+
+
PyObject *KX_VehicleWrapper::PyAddWheel(PyObject *args)
{
@@ -67,22 +83,37 @@ PyObject *KX_VehicleWrapper::PyAddWheel(PyObject *args)
KX_GameObject *gameOb;
if (!ConvertPythonToGameObject(wheelGameObject, &gameOb, false, "vehicle.addWheel(...): KX_VehicleWrapper (first argument)"))
return NULL;
-
if (gameOb->GetSGNode())
{
PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode());
- /* TODO - no error checking here! - bad juju */
MT_Vector3 attachPos,attachDir,attachAxle;
- PyVecTo(pylistPos,attachPos);
- PyVecTo(pylistDir,attachDir);
- PyVecTo(pylistAxleDir,attachAxle);
+ if(!PyVecTo(pylistPos,attachPos)) {
+ PyErr_SetString(PyExc_AttributeError,
+ "addWheel(...) Unable to add wheel. attachPos must be a vector with 3 elements.");
+ return NULL;
+ }
+ if(!PyVecTo(pylistDir,attachDir)) {
+ PyErr_SetString(PyExc_AttributeError,
+ "addWheel(...) Unable to add wheel. downDir must be a vector with 3 elements.");
+ return NULL;
+ }
+ if(!PyVecTo(pylistAxleDir,attachAxle)) {
+ PyErr_SetString(PyExc_AttributeError,
+ "addWheel(...) Unable to add wheel. axleDir must be a vector with 3 elements.");
+ return NULL;
+ }
//someone reverse some conventions inside Bullet (axle winding)
attachAxle = -attachAxle;
- printf("attempt for addWheel: suspensionRestLength%f wheelRadius %f, hasSteering:%d\n",suspensionRestLength,wheelRadius,hasSteering);
+ if(wheelRadius<=0) {
+ PyErr_SetString(PyExc_AttributeError,
+ "addWheel(...) Unable to add wheel. wheelRadius must be positive.");
+ return NULL;
+ }
+
m_vehicle->AddWheel(motionState,attachPos,attachDir,attachAxle,suspensionRestLength,wheelRadius,hasSteering);
}
@@ -93,8 +124,6 @@ PyObject *KX_VehicleWrapper::PyAddWheel(PyObject *args)
}
-
-
PyObject *KX_VehicleWrapper::PyGetWheelPosition(PyObject *args)
{
@@ -103,6 +132,8 @@ PyObject *KX_VehicleWrapper::PyGetWheelPosition(PyObject *args)
if (PyArg_ParseTuple(args,"i:getWheelPosition",&wheelIndex))
{
float position[3];
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "getWheelPosition");
+
m_vehicle->GetWheelPosition(wheelIndex,position[0],position[1],position[2]);
MT_Vector3 pos(position[0],position[1],position[2]);
return PyObjectFrom(pos);
@@ -115,6 +146,8 @@ PyObject *KX_VehicleWrapper::PyGetWheelRotation(PyObject *args)
int wheelIndex;
if (PyArg_ParseTuple(args,"i:getWheelRotation",&wheelIndex))
{
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "getWheelRotation");
+
return PyFloat_FromDouble(m_vehicle->GetWheelRotation(wheelIndex));
}
return NULL;
@@ -126,6 +159,8 @@ PyObject *KX_VehicleWrapper::PyGetWheelOrientationQuaternion(PyObject *args)
if (PyArg_ParseTuple(args,"i:getWheelOrientationQuaternion",&wheelIndex))
{
float orn[4];
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "getWheelOrientationQuaternion");
+
m_vehicle->GetWheelOrientationQuaternion(wheelIndex,orn[0],orn[1],orn[2],orn[3]);
MT_Quaternion quatorn(orn[0],orn[1],orn[2],orn[3]);
MT_Matrix3x3 ornmat(quatorn);
@@ -148,7 +183,6 @@ PyObject *KX_VehicleWrapper::PyGetConstraintId(PyObject *args)
}
-
PyObject *KX_VehicleWrapper::PyApplyEngineForce(PyObject *args)
{
float force;
@@ -156,6 +190,8 @@ PyObject *KX_VehicleWrapper::PyApplyEngineForce(PyObject *args)
if (PyArg_ParseTuple(args,"fi:applyEngineForce",&force,&wheelIndex))
{
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "applyEngineForce");
+
force *= -1.f;//someone reverse some conventions inside Bullet (axle winding)
m_vehicle->ApplyEngineForce(force,wheelIndex);
}
@@ -172,6 +208,8 @@ PyObject *KX_VehicleWrapper::PySetTyreFriction(PyObject *args)
if (PyArg_ParseTuple(args,"fi:setTyreFriction",&wheelFriction,&wheelIndex))
{
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setTyreFriction");
+
m_vehicle->SetWheelFriction(wheelFriction,wheelIndex);
}
else {
@@ -187,6 +225,8 @@ PyObject *KX_VehicleWrapper::PySetSuspensionStiffness(PyObject *args)
if (PyArg_ParseTuple(args,"fi:setSuspensionStiffness",&suspensionStiffness,&wheelIndex))
{
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setSuspensionStiffness");
+
m_vehicle->SetSuspensionStiffness(suspensionStiffness,wheelIndex);
}
else {
@@ -202,6 +242,8 @@ PyObject *KX_VehicleWrapper::PySetSuspensionDamping(PyObject *args)
if (PyArg_ParseTuple(args,"fi:setSuspensionDamping",&suspensionDamping,&wheelIndex))
{
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setSuspensionDamping");
+
m_vehicle->SetSuspensionDamping(suspensionDamping,wheelIndex);
} else {
return NULL;
@@ -216,6 +258,8 @@ PyObject *KX_VehicleWrapper::PySetSuspensionCompression(PyObject *args)
if (PyArg_ParseTuple(args,"fi:setSuspensionCompression",&suspensionCompression,&wheelIndex))
{
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setSuspensionCompression");
+
m_vehicle->SetSuspensionCompression(suspensionCompression,wheelIndex);
} else {
return NULL;
@@ -230,6 +274,8 @@ PyObject *KX_VehicleWrapper::PySetRollInfluence(PyObject *args)
if (PyArg_ParseTuple(args,"fi:setRollInfluence",&rollInfluence,&wheelIndex))
{
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setRollInfluence");
+
m_vehicle->SetRollInfluence(rollInfluence,wheelIndex);
}
else {
@@ -246,6 +292,8 @@ PyObject *KX_VehicleWrapper::PyApplyBraking(PyObject *args)
if (PyArg_ParseTuple(args,"fi:applyBraking",&braking,&wheelIndex))
{
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "applyBraking");
+
m_vehicle->ApplyBraking(braking,wheelIndex);
}
else {
@@ -255,8 +303,6 @@ PyObject *KX_VehicleWrapper::PyApplyBraking(PyObject *args)
}
-
-
PyObject *KX_VehicleWrapper::PySetSteeringValue(PyObject *args)
{
float steeringValue;
@@ -264,6 +310,8 @@ PyObject *KX_VehicleWrapper::PySetSteeringValue(PyObject *args)
if (PyArg_ParseTuple(args,"fi:setSteeringValue",&steeringValue,&wheelIndex))
{
+ WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setSteeringValue");
+
m_vehicle->SetSteeringValue(steeringValue,wheelIndex);
}
else {
@@ -316,17 +364,11 @@ PyMethodDef KX_VehicleWrapper::Methods[] = {
{"setSteeringValue",(PyCFunction) KX_VehicleWrapper::sPySetSteeringValue, METH_VARARGS},
{"applyEngineForce",(PyCFunction) KX_VehicleWrapper::sPyApplyEngineForce, METH_VARARGS},
{"applyBraking",(PyCFunction) KX_VehicleWrapper::sPyApplyBraking, METH_VARARGS},
-
{"setTyreFriction",(PyCFunction) KX_VehicleWrapper::sPySetTyreFriction, METH_VARARGS},
-
{"setSuspensionStiffness",(PyCFunction) KX_VehicleWrapper::sPySetSuspensionStiffness, METH_VARARGS},
-
{"setSuspensionDamping",(PyCFunction) KX_VehicleWrapper::sPySetSuspensionDamping, METH_VARARGS},
-
{"setSuspensionCompression",(PyCFunction) KX_VehicleWrapper::sPySetSuspensionCompression, METH_VARARGS},
-
{"setRollInfluence",(PyCFunction) KX_VehicleWrapper::sPySetRollInfluence, METH_VARARGS},
-
{NULL,NULL} //Sentinel
};
diff --git a/source/gameengine/Network/CMakeLists.txt b/source/gameengine/Network/CMakeLists.txt
index bae00c464f2..019fc3e6032 100644
--- a/source/gameengine/Network/CMakeLists.txt
+++ b/source/gameengine/Network/CMakeLists.txt
@@ -27,6 +27,7 @@ set(INC
.
../../../intern/container
../../../intern/string
+ ../../blender/blenlib
)
set(INC_SYS
diff --git a/source/gameengine/Network/SConscript b/source/gameengine/Network/SConscript
index 1d78cdba174..feb14e29552 100644
--- a/source/gameengine/Network/SConscript
+++ b/source/gameengine/Network/SConscript
@@ -31,6 +31,7 @@ sources = env.Glob('*.cpp') #'NG_NetworkMessage.cpp NG_NetworkObject.cpp NG_Netw
incs = [
'.',
+ '../../blender/blenlib',
'#intern/container',
'#intern/string',
'#intern/moto/include',
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 72c3b13e301..44c4e284e7c 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -148,11 +148,34 @@ CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
m_savedCollisionFilterGroup = 0;
m_savedCollisionFilterMask = 0;
m_savedMass = 0.0;
+ m_savedDyna = false;
m_suspended = false;
CreateRigidbody();
}
+void CcdPhysicsController::addCcdConstraintRef(btTypedConstraint* c)
+{
+ int index = m_ccdConstraintRefs.findLinearSearch(c);
+ if (index == m_ccdConstraintRefs.size())
+ m_ccdConstraintRefs.push_back(c);
+}
+
+void CcdPhysicsController::removeCcdConstraintRef(btTypedConstraint* c)
+{
+ m_ccdConstraintRefs.remove(c);
+}
+
+btTypedConstraint* CcdPhysicsController::getCcdConstraintRef(int index)
+{
+ return m_ccdConstraintRefs[index];
+}
+
+int CcdPhysicsController::getNumCcdConstraintRefs() const
+{
+ return m_ccdConstraintRefs.size();
+}
+
btTransform& CcdPhysicsController::GetTransformFromMotionState(PHY_IMotionState* motionState)
{
static btTransform trans;
@@ -207,6 +230,11 @@ btRigidBody* CcdPhysicsController::GetRigidBody()
{
return btRigidBody::upcast(m_object);
}
+const btRigidBody* CcdPhysicsController::GetRigidBody() const
+{
+ return btRigidBody::upcast(m_object);
+}
+
btCollisionObject* CcdPhysicsController::GetCollisionObject()
{
return m_object;
@@ -1063,6 +1091,7 @@ void CcdPhysicsController::SuspendDynamics(bool ghost)
m_savedCollisionFlags = body->getCollisionFlags();
m_savedMass = GetMass();
+ m_savedDyna = m_cci.m_bDyna;
m_savedCollisionFilterGroup = handle->m_collisionFilterGroup;
m_savedCollisionFilterMask = handle->m_collisionFilterMask;
m_suspended = true;
@@ -1071,6 +1100,7 @@ void CcdPhysicsController::SuspendDynamics(bool ghost)
btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)),
btBroadphaseProxy::StaticFilter,
btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
+ m_cci.m_bDyna = false;
}
}
@@ -1087,6 +1117,7 @@ void CcdPhysicsController::RestoreDynamics()
m_savedCollisionFilterGroup,
m_savedCollisionFilterMask);
body->activate();
+ m_cci.m_bDyna = m_savedDyna;
m_suspended = false;
}
}
@@ -1354,6 +1385,42 @@ void CcdPhysicsController::Jump()
void CcdPhysicsController::SetActive(bool active)
{
}
+
+float CcdPhysicsController::GetLinearDamping() const
+{
+ const btRigidBody* body = GetRigidBody();
+ if (body)
+ return body->getLinearDamping();
+ return 0;
+}
+
+float CcdPhysicsController::GetAngularDamping() const
+{
+ const btRigidBody* body = GetRigidBody();
+ if (body)
+ return body->getAngularDamping();
+ return 0;
+}
+
+void CcdPhysicsController::SetLinearDamping(float damping)
+{
+ SetDamping(damping, GetAngularDamping());
+}
+
+void CcdPhysicsController::SetAngularDamping(float damping)
+{
+ SetDamping(GetLinearDamping(), damping);
+}
+
+void CcdPhysicsController::SetDamping(float linear, float angular)
+{
+ btRigidBody* body = GetRigidBody();
+ if (!body) return;
+
+ body->setDamping(linear, angular);
+}
+
+
// reading out information from physics
MT_Vector3 CcdPhysicsController::GetLinearVelocity()
{
@@ -2265,7 +2332,7 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
/* transverts are only used for deformed RAS_Meshes, the RAS_TexVert data
* is too hard to get at, see below for details */
float (*transverts)[3] = NULL;
- int transverts_tot= 0; /* with deformed meshes - should always be greater then the max orginal index, or we get crashes */
+ int transverts_tot= 0; /* with deformed meshes - should always be greater than the max orginal index, or we get crashes */
if (deformer) {
/* map locations from the deformed array
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 4d0d96e07c6..de40624d7bb 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -461,6 +461,7 @@ protected:
class CcdShapeConstructionInfo* m_shapeInfo;
btCollisionShape* m_bulletChildShape;
+ btAlignedObjectArray<btTypedConstraint*> m_ccdConstraintRefs; // keep track of typed constraints referencing this rigid body
friend class CcdPhysicsEnvironment; // needed when updating the controller
//some book keeping for replication
@@ -480,6 +481,7 @@ protected:
short m_savedCollisionFilterGroup;
short m_savedCollisionFilterMask;
MT_Scalar m_savedMass;
+ bool m_savedDyna;
bool m_suspended;
@@ -496,6 +498,11 @@ protected:
return (--m_registerCount == 0) ? true : false;
}
+ void addCcdConstraintRef(btTypedConstraint* c);
+ void removeCcdConstraintRef(btTypedConstraint* c);
+ btTypedConstraint* getCcdConstraintRef(int index);
+ int getNumCcdConstraintRefs() const;
+
void SetWorldOrientation(const btMatrix3x3& mat);
void ForceWorldTransform(const btMatrix3x3& mat, const btVector3& pos);
@@ -522,6 +529,7 @@ protected:
btRigidBody* GetRigidBody();
+ const btRigidBody* GetRigidBody() const;
btCollisionObject* GetCollisionObject();
btSoftBody* GetSoftBody();
btKinematicCharacterController* GetCharacterController();
@@ -573,6 +581,12 @@ protected:
virtual void Jump();
virtual void SetActive(bool active);
+ virtual float GetLinearDamping() const;
+ virtual float GetAngularDamping() const;
+ virtual void SetLinearDamping(float damping);
+ virtual void SetAngularDamping(float damping);
+ virtual void SetDamping(float linear, float angular);
+
// reading out information from physics
virtual MT_Vector3 GetLinearVelocity();
virtual MT_Vector3 GetAngularVelocity();
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index e17d4402556..ac74029fbe3 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -174,26 +174,27 @@ public:
virtual void GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const
{
- btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex);
- posX = trans.getOrigin().x();
- posY = trans.getOrigin().y();
- posZ = trans.getOrigin().z();
+ if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels()))
+ {
+ btVector3 origin = m_vehicle->getWheelTransformWS(wheelIndex).getOrigin();
+
+ posX = origin.x();
+ posY = origin.y();
+ posZ = origin.z();
+ }
}
+
virtual void GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const
{
- btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex);
- btQuaternion quat = trans.getRotation();
- btMatrix3x3 orn2(quat);
-
- quatX = trans.getRotation().x();
- quatY = trans.getRotation().y();
- quatZ = trans.getRotation().z();
- quatW = trans.getRotation()[3];
-
-
- //printf("test");
-
+ if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels()))
+ {
+ btQuaternion quat = m_vehicle->getWheelTransformWS(wheelIndex).getRotation();
+ quatX = quat.x();
+ quatY = quat.y();
+ quatZ = quat.z();
+ quatW = quat.w();
+ }
}
virtual float GetWheelRotation(int wheelIndex) const
@@ -205,8 +206,8 @@ public:
btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
rotation = info.m_rotation;
}
- return rotation;
+ return rotation;
}
@@ -223,12 +224,16 @@ public:
virtual void SetSteeringValue(float steering,int wheelIndex)
{
- m_vehicle->setSteeringValue(steering,wheelIndex);
+ if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) {
+ m_vehicle->setSteeringValue(steering,wheelIndex);
+ }
}
virtual void ApplyEngineForce(float force,int wheelIndex)
{
- m_vehicle->applyEngineForce(force,wheelIndex);
+ if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) {
+ m_vehicle->applyEngineForce(force,wheelIndex);
+ }
}
virtual void ApplyBraking(float braking,int wheelIndex)
@@ -504,11 +509,13 @@ bool CcdPhysicsEnvironment::RemoveCcdPhysicsController(CcdPhysicsController* ctr
btRigidBody* body = ctrl->GetRigidBody();
if (body)
{
- for (int i=body->getNumConstraintRefs()-1;i>=0;i--)
+ for (int i = ctrl->getNumCcdConstraintRefs() - 1; i >= 0; i--)
{
- btTypedConstraint* con = body->getConstraintRef(i);
+ btTypedConstraint* con = ctrl->getCcdConstraintRef(i);
+ con->getRigidBodyA().activate();
+ con->getRigidBodyB().activate();
m_dynamicsWorld->removeConstraint(con);
- body->removeConstraintRef(con);
+ ctrl->removeCcdConstraintRef(con);
//delete con; //might be kept by python KX_ConstraintWrapper
}
m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody());
@@ -2251,64 +2258,77 @@ bool CcdPhysicsEnvironment::RequestCollisionCallback(PHY_IPhysicsController* ctr
void CcdPhysicsEnvironment::CallbackTriggers()
{
- if (m_triggerCallbacks[PHY_OBJECT_RESPONSE] || (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)))
- {
- //walk over all overlapping pairs, and if one of the involved bodies is registered for trigger callback, perform callback
- btDispatcher* dispatcher = m_dynamicsWorld->getDispatcher();
- int numManifolds = dispatcher->getNumManifolds();
- for (int i=0;i<numManifolds;i++)
- {
- btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
- int numContacts = manifold->getNumContacts();
- if (numContacts)
- {
- const btRigidBody* rb0 = static_cast<const btRigidBody*>(manifold->getBody0());
- const btRigidBody* rb1 = static_cast<const btRigidBody*>(manifold->getBody1());
- if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints))
- {
- for (int j=0;j<numContacts;j++)
- {
- btVector3 color(1,0,0);
- const btManifoldPoint& cp = manifold->getContactPoint(j);
- if (m_debugDrawer)
- m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
- }
- }
- const btRigidBody* obj0 = rb0;
- const btRigidBody* obj1 = rb1;
+ bool draw_contact_points = m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints);
- //m_internalOwner is set in 'addPhysicsController'
- CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->getUserPointer());
- CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->getUserPointer());
+ if (!m_triggerCallbacks[PHY_OBJECT_RESPONSE] && !draw_contact_points)
+ return;
- std::set<CcdPhysicsController*>::const_iterator i = m_triggerControllers.find(ctrl0);
- if (i == m_triggerControllers.end())
- {
- i = m_triggerControllers.find(ctrl1);
- }
+ //walk over all overlapping pairs, and if one of the involved bodies is registered for trigger callback, perform callback
+ btDispatcher* dispatcher = m_dynamicsWorld->getDispatcher();
+ int numManifolds = dispatcher->getNumManifolds();
+ for (int i=0;i<numManifolds;i++)
+ {
+ bool colliding_ctrl0 = true;
+ btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
+ int numContacts = manifold->getNumContacts();
+ if (!numContacts) continue;
- if (!(i == m_triggerControllers.end()))
- {
- m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE],
- ctrl0,ctrl1,0);
- }
- // Bullet does not refresh the manifold contact point for object without contact response
- // may need to remove this when a newer Bullet version is integrated
- if (!dispatcher->needsResponse(rb0, rb1))
- {
- // Refresh algorithm fails sometimes when there is penetration
- // (usuall the case with ghost and sensor objects)
- // Let's just clear the manifold, in any case, it is recomputed on each frame.
- manifold->clearManifold(); //refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform());
- }
+ const btRigidBody* rb0 = static_cast<const btRigidBody*>(manifold->getBody0());
+ const btRigidBody* rb1 = static_cast<const btRigidBody*>(manifold->getBody1());
+ if (draw_contact_points)
+ {
+ for (int j=0;j<numContacts;j++)
+ {
+ btVector3 color(1,1,0);
+ const btManifoldPoint& cp = manifold->getContactPoint(j);
+ m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB,
+ cp.m_normalWorldOnB,
+ cp.getDistance(),
+ cp.getLifeTime(),
+ color);
}
}
+ //m_internalOwner is set in 'addPhysicsController'
+ CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(rb0->getUserPointer());
+ CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(rb1->getUserPointer());
+ std::set<CcdPhysicsController*>::const_iterator iter = m_triggerControllers.find(ctrl0);
+ if (iter == m_triggerControllers.end())
+ {
+ iter = m_triggerControllers.find(ctrl1);
+ colliding_ctrl0 = false;
+ }
- }
+ if (iter != m_triggerControllers.end())
+ {
+ static PHY_CollData coll_data;
+ const btManifoldPoint &cp = manifold->getContactPoint(0);
+
+ /* Make sure that "point1" is always on the object we report on, and
+ * "point2" on the other object. Also ensure the normal is oriented
+ * correctly. */
+ btVector3 point1 = colliding_ctrl0 ? cp.m_positionWorldOnA : cp.m_positionWorldOnB;
+ btVector3 point2 = colliding_ctrl0 ? cp.m_positionWorldOnB : cp.m_positionWorldOnA;
+ btVector3 normal = colliding_ctrl0 ? -cp.m_normalWorldOnB : cp.m_normalWorldOnB;
+ coll_data.m_point1 = MT_Vector3(point1.m_floats);
+ coll_data.m_point2 = MT_Vector3(point2.m_floats);
+ coll_data.m_normal = MT_Vector3(normal.m_floats);
+ m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE],
+ ctrl0, ctrl1, &coll_data);
+ }
+ // Bullet does not refresh the manifold contact point for object without contact response
+ // may need to remove this when a newer Bullet version is integrated
+ if (!dispatcher->needsResponse(rb0, rb1))
+ {
+ // Refresh algorithm fails sometimes when there is penetration
+ // (usuall the case with ghost and sensor objects)
+ // Let's just clear the manifold, in any case, it is recomputed on each frame.
+ manifold->clearManifold(); //refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform());
+ }
+ }
}
// This call back is called before a pair is added in the cache
@@ -2624,7 +2644,9 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
if (!rb0)
return 0;
-
+ // If either of the controllers is missing, we can't do anything.
+ if (!c0 || !c1) return 0;
+
btVector3 pivotInB = rb1 ? rb1->getCenterOfMassTransform().inverse()(rb0->getCenterOfMassTransform()(pivotInA)) :
rb0->getCenterOfMassTransform() * pivotInA;
btVector3 axisInA(axisX,axisY,axisZ);
@@ -2649,6 +2671,8 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
pivotInA);
}
+ c0->addCcdConstraintRef(p2p);
+ c1->addCcdConstraintRef(p2p);
m_dynamicsWorld->addConstraint(p2p,disableCollisionBetweenLinkedBodies);
// m_constraints.push_back(p2p);
@@ -2719,6 +2743,8 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
if (genericConstraint)
{
//m_constraints.push_back(genericConstraint);
+ c0->addCcdConstraintRef(genericConstraint);
+ c1->addCcdConstraintRef(genericConstraint);
m_dynamicsWorld->addConstraint(genericConstraint,disableCollisionBetweenLinkedBodies);
genericConstraint->setUserConstraintId(gConstraintUid++);
genericConstraint->setUserConstraintType(type);
@@ -2785,6 +2811,8 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
if (coneTwistContraint)
{
//m_constraints.push_back(genericConstraint);
+ c0->addCcdConstraintRef(coneTwistContraint);
+ c1->addCcdConstraintRef(coneTwistContraint);
m_dynamicsWorld->addConstraint(coneTwistContraint,disableCollisionBetweenLinkedBodies);
coneTwistContraint->setUserConstraintId(gConstraintUid++);
coneTwistContraint->setUserConstraintType(type);
@@ -2858,6 +2886,8 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
hinge->setAngularOnly(angularOnly);
//m_constraints.push_back(hinge);
+ c0->addCcdConstraintRef(hinge);
+ c1->addCcdConstraintRef(hinge);
m_dynamicsWorld->addConstraint(hinge,disableCollisionBetweenLinkedBodies);
hinge->setUserConstraintId(gConstraintUid++);
hinge->setUserConstraintType(type);
@@ -2999,7 +3029,8 @@ struct BlenderDebugDraw : public btIDebugDraw
virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color)
{
- //not yet
+ drawLine(PointOnB, PointOnB + normalOnB, color);
+ drawSphere(PointOnB, 0.1, color);
}
virtual void setDebugMode(int debugMode)
@@ -3339,46 +3370,50 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject
//take relative transform into account!
CcdPhysicsController* parentCtrl = (CcdPhysicsController*)parent->GetPhysicsController();
assert(parentCtrl);
- CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo();
- btRigidBody* rigidbody = parentCtrl->GetRigidBody();
- btCollisionShape* colShape = rigidbody->getCollisionShape();
- assert(colShape->isCompound());
- btCompoundShape* compoundShape = (btCompoundShape*)colShape;
-
- // compute the local transform from parent, this may include several node in the chain
- SG_Node* gameNode = gameobj->GetSGNode();
- SG_Node* parentNode = parent->GetSGNode();
- // relative transform
- MT_Vector3 parentScale = parentNode->GetWorldScaling();
- parentScale[0] = MT_Scalar(1.0)/parentScale[0];
- parentScale[1] = MT_Scalar(1.0)/parentScale[1];
- parentScale[2] = MT_Scalar(1.0)/parentScale[2];
- MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale;
- MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed();
- MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale);
- MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation();
-
- shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]);
- bm->setLocalScaling(shapeInfo->m_childScale);
- shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]);
- float rot[12];
- relativeRot.getValue(rot);
- shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot);
-
- parentShapeInfo->AddShape(shapeInfo);
- compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
- //do some recalc?
- //recalc inertia for rigidbody
- if (!rigidbody->isStaticOrKinematicObject())
- {
- btVector3 localInertia;
- float mass = 1.f/rigidbody->getInvMass();
- compoundShape->calculateLocalInertia(mass,localInertia);
- rigidbody->setMassProps(mass,localInertia);
+
+ // only makes compound shape if parent has a physics controller (i.e not an empty, etc)
+ if (parentCtrl) {
+ CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo();
+ btRigidBody* rigidbody = parentCtrl->GetRigidBody();
+ btCollisionShape* colShape = rigidbody->getCollisionShape();
+ assert(colShape->isCompound());
+ btCompoundShape* compoundShape = (btCompoundShape*)colShape;
+
+ // compute the local transform from parent, this may include several node in the chain
+ SG_Node* gameNode = gameobj->GetSGNode();
+ SG_Node* parentNode = parent->GetSGNode();
+ // relative transform
+ MT_Vector3 parentScale = parentNode->GetWorldScaling();
+ parentScale[0] = MT_Scalar(1.0)/parentScale[0];
+ parentScale[1] = MT_Scalar(1.0)/parentScale[1];
+ parentScale[2] = MT_Scalar(1.0)/parentScale[2];
+ MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale;
+ MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed();
+ MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale);
+ MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation();
+
+ shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]);
+ bm->setLocalScaling(shapeInfo->m_childScale);
+ shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]);
+ float rot[12];
+ relativeRot.getValue(rot);
+ shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot);
+
+ parentShapeInfo->AddShape(shapeInfo);
+ compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
+ //do some recalc?
+ //recalc inertia for rigidbody
+ if (!rigidbody->isStaticOrKinematicObject())
+ {
+ btVector3 localInertia;
+ float mass = 1.f/rigidbody->getInvMass();
+ compoundShape->calculateLocalInertia(mass,localInertia);
+ rigidbody->setMassProps(mass,localInertia);
+ }
+ shapeInfo->Release();
+ // delete motionstate as it's not used
+ delete motionstate;
}
- shapeInfo->Release();
- // delete motionstate as it's not used
- delete motionstate;
return;
}
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h
index f9975484fa7..1717f8d90cb 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsController.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h
@@ -89,6 +89,12 @@ class PHY_IPhysicsController : public PHY_IController
virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local)=0;
virtual void ResolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) = 0;
+ virtual float GetLinearDamping() const=0;
+ virtual float GetAngularDamping() const=0;
+ virtual void SetLinearDamping(float damping)=0;
+ virtual void SetAngularDamping(float damping)=0;
+ virtual void SetDamping(float linear, float angular)=0;
+
virtual void SuspendDynamics(bool ghost=false)=0;
virtual void RestoreDynamics()=0;
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 415ea87fb1b..116a11339d9 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -1269,28 +1269,32 @@ void RAS_OpenGLRasterizer::RemoveLight(RAS_ILightObject* lightobject)
bool RAS_OpenGLRasterizer::RayHit(struct KX_ClientObjectInfo *client, KX_RayCast *result, void * const data)
{
- double* const oglmatrix = (double* const) data;
-
- RAS_Polygon* poly = result->m_hitMesh->GetPolygon(result->m_hitPolygon);
- if (!poly->IsVisible())
+ if (result->m_hitMesh) {
+ double* const oglmatrix = (double* const) data;
+
+ RAS_Polygon* poly = result->m_hitMesh->GetPolygon(result->m_hitPolygon);
+ if (!poly->IsVisible())
+ return false;
+
+ MT_Vector3 resultnormal(result->m_hitNormal);
+ MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
+ MT_Vector3 dir = -(left.cross(resultnormal)).safe_normalized();
+ left = (dir.cross(resultnormal)).safe_normalized();
+ // for the up vector, we take the 'resultnormal' returned by the physics
+
+ double maat[16] = {left[0], left[1], left[2], 0,
+ dir[0], dir[1], dir[2], 0,
+ resultnormal[0], resultnormal[1], resultnormal[2], 0,
+ 0, 0, 0, 1};
+
+ glTranslated(oglmatrix[12],oglmatrix[13],oglmatrix[14]);
+ //glMultMatrixd(oglmatrix);
+ glMultMatrixd(maat);
+ return true;
+ }
+ else {
return false;
-
- MT_Point3 resultpoint(result->m_hitPoint);
- MT_Vector3 resultnormal(result->m_hitNormal);
- MT_Vector3 left(oglmatrix[0],oglmatrix[1],oglmatrix[2]);
- MT_Vector3 dir = -(left.cross(resultnormal)).safe_normalized();
- left = (dir.cross(resultnormal)).safe_normalized();
- // for the up vector, we take the 'resultnormal' returned by the physics
-
- double maat[16] = {left[0], left[1], left[2], 0,
- dir[0], dir[1], dir[2], 0,
- resultnormal[0], resultnormal[1], resultnormal[2], 0,
- 0, 0, 0, 1};
-
- glTranslated(resultpoint[0],resultpoint[1],resultpoint[2]);
- //glMultMatrixd(oglmatrix);
- glMultMatrixd(maat);
- return true;
+ }
}
void RAS_OpenGLRasterizer::applyTransform(double* oglmatrix,int objectdrawmode )
diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp
index 0d46160a11e..23da528009d 100644
--- a/source/gameengine/VideoTexture/ImageBase.cpp
+++ b/source/gameengine/VideoTexture/ImageBase.cpp
@@ -713,25 +713,18 @@ static int Image_getbuffer(PyImage *self, Py_buffer *view, int flags)
unsigned int * image;
int ret;
- try
- {
+ try {
// can throw in case of resize
image = self->m_image->getImage();
}
- catch (Exception & exp)
- {
- // cannot return -1, this creates a crash in Python, for now we will just return an empty buffer
+ catch (Exception & exp) {
exp.report();
- //return -1;
- goto error;
+ return -1;
}
- if (!image)
- {
- // same remark, see above
- //PyErr_SetString(PyExc_BufferError, "Image buffer is not available");
- //return -1;
- goto error;
+ if (!image) {
+ PyErr_SetString(PyExc_BufferError, "Image buffer is not available");
+ return -1;
}
if (view == NULL)
{
@@ -742,17 +735,6 @@ static int Image_getbuffer(PyImage *self, Py_buffer *view, int flags)
if (ret >= 0)
self->m_image->m_exports++;
return ret;
-
-error:
- // Return a empty buffer to avoid a crash in Python 3.1
- // The bug is fixed in Python SVN 77916, as soon as the python revision used by Blender is
- // updated, you can simply return -1 and set the error
- static char* buf = (char *)"";
- ret = PyBuffer_FillInfo(view, (PyObject *)self, buf, 0, 0, flags);
- if (ret >= 0)
- self->m_image->m_exports++;
- return ret;
-
}
static void Image_releaseBuffer(PyImage *self, Py_buffer *buffer)
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index 617e7fd1d8e..57b2e85845c 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -274,8 +274,6 @@ void ImageRender::Render()
m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
- m_scene->UpdateAnimations(m_engine->GetFrameTime());
-
m_scene->RenderBuckets(camtrans, m_rasterizer);
m_scene->RenderFonts();
diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp
index 74f36207774..9640c5544da 100644
--- a/source/gameengine/VideoTexture/Texture.cpp
+++ b/source/gameengine/VideoTexture/Texture.cpp
@@ -41,6 +41,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_image_types.h"
#include "IMB_imbuf_types.h"
+#include "BKE_image.h"
#include "MEM_guardedalloc.h"
@@ -56,6 +57,9 @@
#include <memory.h>
#include "glew-mx.h"
+extern "C" {
+ #include "IMB_imbuf.h"
+}
// macro for exception handling and logging
#define CATCH_EXCP catch (Exception & exp) \
@@ -158,11 +162,11 @@ static PyObject *Texture_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
// initialize object structure
self->m_actTex = 0;
self->m_orgSaved = false;
+ self->m_imgBuf = NULL;
self->m_imgTexture = NULL;
self->m_matTexture = NULL;
self->m_mipmap = false;
- self->m_scaledImg = NULL;
- self->m_scaledImgSize = 0;
+ self->m_scaledImBuf = NULL;
self->m_source = NULL;
self->m_lastClock = 0.0;
// return allocated object
@@ -184,7 +188,7 @@ static void Texture_dealloc(Texture *self)
PyObject *ret = Texture_close(self);
Py_DECREF(ret);
// release scaled image buffer
- delete [] self->m_scaledImg;
+ IMB_freeImBuf(self->m_scaledImBuf);
// release object
Py_TYPE((PyObject *)self)->tp_free((PyObject *)self);
}
@@ -282,7 +286,11 @@ PyObject *Texture_close(Texture * self)
if (self->m_useMatTexture)
self->m_matTexture->swapTexture(self->m_orgTex);
else
+ {
self->m_imgTexture->bindcode = self->m_orgTex;
+ BKE_image_release_ibuf(self->m_imgTexture, self->m_imgBuf, NULL);
+ self->m_imgBuf = NULL;
+ }
// drop actual texture
if (self->m_actTex != 0)
{
@@ -331,6 +339,12 @@ static PyObject *Texture_refresh(Texture *self, PyObject *args)
self->m_orgTex = self->m_matTexture->swapTexture(self->m_actTex);
else
{
+ // Swapping will work only if the GPU has already loaded the image.
+ // If not, it will delete and overwrite our texture on next render.
+ // To avoid that, we acquire the image buffer now.
+ // WARNING: GPU has a ImageUser to pass, we don't. Using NULL
+ // works on image file, not necessarily on other type of image.
+ self->m_imgBuf = BKE_image_acquire_ibuf(self->m_imgTexture, NULL, NULL);
self->m_orgTex = self->m_imgTexture->bindcode;
self->m_imgTexture->bindcode = self->m_actTex;
}
@@ -358,20 +372,12 @@ static PyObject *Texture_refresh(Texture *self, PyObject *args)
// scale texture if needed
if (size[0] != orgSize[0] || size[1] != orgSize[1])
{
- // if scaled image buffer is smaller than needed
- if (self->m_scaledImgSize < (unsigned int)(size[0] * size[1]))
- {
- // new size
- self->m_scaledImgSize = size[0] * size[1];
- // allocate scaling image
- delete [] self->m_scaledImg;
- self->m_scaledImg = new unsigned int[self->m_scaledImgSize];
- }
- // scale texture
- gluScaleImage(GL_RGBA, orgSize[0], orgSize[1], GL_UNSIGNED_BYTE, texture,
- size[0], size[1], GL_UNSIGNED_BYTE, self->m_scaledImg);
+ IMB_freeImBuf(self->m_scaledImBuf);
+ self->m_scaledImBuf = IMB_allocFromBuffer(texture, NULL, orgSize[0], orgSize[1]);
+ IMB_scaleImBuf(self->m_scaledImBuf, size[0], size[1]);
+
// use scaled image instead original
- texture = self->m_scaledImg;
+ texture = self->m_scaledImBuf->rect;
}
// load texture for rendering
loadTexture(self->m_actTex, texture, size, self->m_mipmap);
diff --git a/source/gameengine/VideoTexture/Texture.h b/source/gameengine/VideoTexture/Texture.h
index c85b1228864..ae778bae704 100644
--- a/source/gameengine/VideoTexture/Texture.h
+++ b/source/gameengine/VideoTexture/Texture.h
@@ -43,6 +43,8 @@
#include "Exception.h"
+struct ImBuf;
+
// type Texture declaration
struct Texture
{
@@ -58,6 +60,8 @@ struct Texture
// original texture saved
bool m_orgSaved;
+ // kernel image buffer, to make sure the image is loaded before we swap the bindcode
+ struct ImBuf *m_imgBuf;
// texture image for game materials
Image * m_imgTexture;
// texture for blender materials
@@ -67,9 +71,7 @@ struct Texture
bool m_mipmap;
// scaled image buffer
- unsigned int * m_scaledImg;
- // scaled image buffer size
- unsigned int m_scaledImgSize;
+ ImBuf * m_scaledImBuf;
// last refresh
double m_lastClock;
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
index edf3c58bcbe..db76ba5822a 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
@@ -86,6 +86,13 @@ VideoFFmpeg::~VideoFFmpeg ()
{
}
+void VideoFFmpeg::refresh(void)
+{
+ // a fixed image will not refresh because it is loaded only once at creation
+ if (m_isImage)
+ return;
+ m_avail = false;
+}
// release components
bool VideoFFmpeg::release()
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h
index 4a948fe61de..4834a7cef6d 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.h
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.h
@@ -85,7 +85,8 @@ public:
/// release video source
virtual bool release (void);
-
+ /// overwrite base refresh to handle fixed image
+ virtual void refresh(void);
/// play video
virtual bool play (void);
/// pause video
diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp
index ab6dca0958f..6c9294873a6 100644
--- a/source/gameengine/VideoTexture/blendVideoTex.cpp
+++ b/source/gameengine/VideoTexture/blendVideoTex.cpp
@@ -157,10 +157,14 @@ static void registerAllTypes(void)
pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24");
}
+PyDoc_STRVAR(VideoTexture_module_documentation,
+"Module that allows to play video files on textures in GameBlender."
+);
+
static struct PyModuleDef VideoTexture_module_def = {
- {}, /* m_base */
+ PyModuleDef_HEAD_INIT,
"VideoTexture", /* m_name */
- "Module that allows to play video files on textures in GameBlender.", /* m_doc */
+ VideoTexture_module_documentation, /* m_doc */
0, /* m_size */
moduleMethods, /* m_methods */
0, /* m_reload */
@@ -169,7 +173,7 @@ static struct PyModuleDef VideoTexture_module_def = {
0, /* m_free */
};
-PyObject *initVideoTexture(void)
+PyMODINIT_FUNC initVideoTexturePythonBinding(void)
{
PyObject *m;
@@ -187,20 +191,9 @@ PyObject *initVideoTexture(void)
if (PyType_Ready(&TextureType) < 0)
return NULL;
- /* Use existing module where possible
- * be careful not to init any runtime vars after this */
- m = PyImport_ImportModule( "VideoTexture" );
- if (m) {
- Py_DECREF(m);
- return m;
- }
- else {
- PyErr_Clear();
-
- m = PyModule_Create(&VideoTexture_module_def);
- PyDict_SetItemString(PySys_GetObject("modules"), VideoTexture_module_def.m_name, m);
- }
-
+ m = PyModule_Create(&VideoTexture_module_def);
+ PyDict_SetItemString(PySys_GetObject("modules"), VideoTexture_module_def.m_name, m);
+
if (m == NULL)
return NULL;
diff --git a/tests/gtests/blenlib/BLI_hash_mm2a_test.cc b/tests/gtests/blenlib/BLI_hash_mm2a_test.cc
new file mode 100644
index 00000000000..b35a1a809d6
--- /dev/null
+++ b/tests/gtests/blenlib/BLI_hash_mm2a_test.cc
@@ -0,0 +1,75 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+extern "C" {
+#include "BLI_hash_mm2a.h"
+}
+
+/* Note: Reference results are taken from reference implementation (cpp code, CMurmurHash2A variant):
+ * https://smhasher.googlecode.com/svn-history/r130/trunk/MurmurHash2.cpp
+ */
+
+TEST(hash_mm2a, MM2ABasic)
+{
+ BLI_HashMurmur2A mm2;
+
+ const char *data = "Blender";
+
+ BLI_hash_mm2a_init(&mm2, 0);
+ BLI_hash_mm2a_add(&mm2, (const unsigned char *)data, strlen(data));
+#ifdef __LITTLE_ENDIAN__
+ EXPECT_EQ(1633988145, BLI_hash_mm2a_end(&mm2));
+#else
+ EXPECT_EQ(959283772, BLI_hash_mm2a_end(&mm2));
+#endif
+}
+
+TEST(hash_mm2a, MM2AConcatenateStrings)
+{
+ BLI_HashMurmur2A mm2;
+ uint32_t hash;
+
+ const char *data1 = "Blender";
+ const char *data2 = " is ";
+ const char *data3 = "FaNtAsTiC";
+ const char *data123 = "Blender is FaNtAsTiC";
+
+ BLI_hash_mm2a_init(&mm2, 0);
+ BLI_hash_mm2a_add(&mm2, (const unsigned char *)data1, strlen(data1));
+ BLI_hash_mm2a_add(&mm2, (const unsigned char *)data2, strlen(data2));
+ BLI_hash_mm2a_add(&mm2, (const unsigned char *)data3, strlen(data3));
+ hash = BLI_hash_mm2a_end(&mm2);
+ BLI_hash_mm2a_init(&mm2, 0);
+ BLI_hash_mm2a_add(&mm2, (const unsigned char *)data123, strlen(data123));
+#ifdef __LITTLE_ENDIAN__
+ EXPECT_EQ(1545105348, hash);
+#else
+ EXPECT_EQ(2604964730, hash);
+#endif
+ EXPECT_EQ(hash, BLI_hash_mm2a_end(&mm2));
+}
+
+TEST(hash_mm2a, MM2AIntegers)
+{
+ BLI_HashMurmur2A mm2;
+ uint32_t hash;
+
+ const int ints[4] = {1, 2, 3, 4};
+
+ BLI_hash_mm2a_init(&mm2, 0);
+ BLI_hash_mm2a_add_int(&mm2, ints[0]);
+ BLI_hash_mm2a_add_int(&mm2, ints[1]);
+ BLI_hash_mm2a_add_int(&mm2, ints[2]);
+ BLI_hash_mm2a_add_int(&mm2, ints[3]);
+ hash = BLI_hash_mm2a_end(&mm2);
+ BLI_hash_mm2a_init(&mm2, 0);
+ BLI_hash_mm2a_add(&mm2, (const unsigned char *)ints, sizeof(ints));
+ /* Yes, same hash here on little and big endian. */
+#ifdef __LITTLE_ENDIAN__
+ EXPECT_EQ(405493096, hash);
+#else
+ EXPECT_EQ(405493096, hash);
+#endif
+ EXPECT_EQ(hash, BLI_hash_mm2a_end(&mm2));
+}
diff --git a/tests/gtests/blenlib/BLI_path_util_test.cc b/tests/gtests/blenlib/BLI_path_util_test.cc
index ea761bcf32e..c4ef7c2c970 100644
--- a/tests/gtests/blenlib/BLI_path_util_test.cc
+++ b/tests/gtests/blenlib/BLI_path_util_test.cc
@@ -31,6 +31,7 @@ const char *GHOST_getSystemDir(int version, const char *versionstr)
struct ImBuf;
void IMB_freeImBuf(struct ImBuf *ibuf) {}
+struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf) {return NULL;}
#ifdef __linux__
char *zLhm65070058860608_br_find_exe(const char *default_exe)
diff --git a/tests/gtests/blenlib/BLI_polyfill2d_test.cc b/tests/gtests/blenlib/BLI_polyfill2d_test.cc
index 785274757aa..8ca19b11632 100644
--- a/tests/gtests/blenlib/BLI_polyfill2d_test.cc
+++ b/tests/gtests/blenlib/BLI_polyfill2d_test.cc
@@ -7,9 +7,10 @@
/* test every possible offset and reverse */
#define USE_COMBINATIONS_ALL
+#define USE_BEAUTIFY
extern "C" {
-#include "BLI_array.h"
+#include "BLI_array_utils.h"
#include "BLI_polyfill2d.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
@@ -18,6 +19,12 @@ extern "C" {
#ifdef USE_OBJ_PREVIEW
# include "BLI_string.h"
#endif
+
+#ifdef USE_BEAUTIFY
+#include "BLI_polyfill2d_beautify.h"
+#include "BLI_memarena.h"
+#include "BLI_heap.h"
+#endif
}
static void polyfill_to_obj(
@@ -179,6 +186,25 @@ static void test_polyfill_template(
/* check all went well */
test_polyfill_template_check(id, is_degenerate, poly, poly_tot, tris, tris_tot);
+
+#ifdef USE_BEAUTIFY
+ /* check beautify gives good results too */
+ {
+ MemArena *pf_arena = BLI_memarena_new(BLI_POLYFILL_ARENA_SIZE, __func__);
+ Heap *pf_heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE);
+ EdgeHash *pf_ehash = BLI_edgehash_new_ex(__func__, BLI_POLYFILL_ALLOC_NGON_RESERVE);
+
+ BLI_polyfill_beautify(
+ poly, poly_tot, tris,
+ pf_arena, pf_heap, pf_ehash);
+
+ test_polyfill_template_check(id, is_degenerate, poly, poly_tot, tris, tris_tot);
+
+ BLI_memarena_free(pf_arena);
+ BLI_heap_free(pf_heap, NULL);
+ BLI_edgehash_free(pf_ehash, NULL);
+ }
+#endif
}
#ifdef USE_COMBINATIONS_ALL
diff --git a/tests/gtests/blenlib/CMakeLists.txt b/tests/gtests/blenlib/CMakeLists.txt
index c949c1e1f5c..3a86d3f770d 100644
--- a/tests/gtests/blenlib/CMakeLists.txt
+++ b/tests/gtests/blenlib/CMakeLists.txt
@@ -42,3 +42,4 @@ BLENDER_TEST(BLI_string "bf_blenlib")
BLENDER_TEST(BLI_path_util "bf_blenlib;extern_wcwidth;${ZLIB_LIBRARIES}")
BLENDER_TEST(BLI_polyfill2d "bf_blenlib")
BLENDER_TEST(BLI_listbase "bf_blenlib")
+BLENDER_TEST(BLI_hash_mm2a "bf_blenlib")
diff --git a/tests/gtests/testing/testing_main.cc b/tests/gtests/testing/testing_main.cc
index ef8e743b642..b2dcc445aca 100644
--- a/tests/gtests/testing/testing_main.cc
+++ b/tests/gtests/testing/testing_main.cc
@@ -28,7 +28,7 @@
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
- google::ParseCommandLineFlags(&argc, &argv, true);
+ gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]);
return RUN_ALL_TESTS();
diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt
index 85c68693792..fd47bba4182 100644
--- a/tests/python/CMakeLists.txt
+++ b/tests/python/CMakeLists.txt
@@ -48,6 +48,7 @@ else()
endif()
# for testing with valgrind prefix: valgrind --track-origins=yes --error-limit=no
+set(TEST_BLENDER_EXE_BARE ${TEST_BLENDER_EXE})
set(TEST_BLENDER_EXE ${TEST_BLENDER_EXE} --background -noaudio --factory-startup --env-system-scripts ${CMAKE_SOURCE_DIR}/release/scripts)
@@ -88,6 +89,8 @@ add_test(bevel ${TEST_BLENDER_EXE}
# IO TESTS
# OBJ Import tests
+# disabled until updated & working
+if(FALSE)
add_test(import_obj_cube ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.obj\(filepath='${TEST_SRC_DIR}/io_tests/obj/cube.obj'\)
@@ -108,6 +111,7 @@ add_test(import_obj_makehuman ${TEST_BLENDER_EXE}
--md5=c9f78b185e58358daa4ecaecfa75464e --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_obj_makehuman.blend
)
+endif()
# OBJ Export tests
add_test(export_obj_cube ${TEST_BLENDER_EXE}
@@ -128,6 +132,8 @@ add_test(export_obj_nurbs ${TEST_BLENDER_EXE}
--md5=a733ae4fa4a591ea9b0912da3af042de --md5_method=FILE
)
+# disabled until updated & working
+if(FALSE)
add_test(export_obj_all_objects ${TEST_BLENDER_EXE}
${TEST_SRC_DIR}/io_tests/blend_scene/all_objects.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
@@ -136,6 +142,7 @@ add_test(export_obj_all_objects ${TEST_BLENDER_EXE}
--md5_source=${TEST_OUT_DIR}/export_obj_all_objects.mtl
--md5=04b3ed97cede07a19548fc518ce9f8ca --md5_method=FILE
)
+endif()
@@ -162,6 +169,8 @@ add_test(import_ply_small_holes ${TEST_BLENDER_EXE}
)
# PLY Export
+# disabled until updated & working
+if(FALSE)
add_test(export_ply_cube_all_data ${TEST_BLENDER_EXE}
${TEST_SRC_DIR}/io_tests/blend_geometry/cube_all_data.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
@@ -177,6 +186,7 @@ add_test(export_ply_suzanne_all_data ${TEST_BLENDER_EXE}
--md5_source=${TEST_OUT_DIR}/export_ply_suzanne_all_data.ply
--md5=68ba23f02efd6511bfd093f45f703221 --md5_method=FILE
)
+endif()
add_test(export_ply_vertices ${TEST_BLENDER_EXE} # lame, add a better one
${TEST_SRC_DIR}/io_tests/blend_geometry/vertices.blend
@@ -188,6 +198,8 @@ add_test(export_ply_vertices ${TEST_BLENDER_EXE} # lame, add a better one
# STL Import tests
+# disabled until updated & working
+if(FALSE)
add_test(import_stl_cube ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_mesh.stl\(filepath='${TEST_SRC_DIR}/io_tests/stl/cube.stl'\)
@@ -208,8 +220,11 @@ add_test(import_stl_knot_max_simplified ${TEST_BLENDER_EXE}
--md5=baf82803f45a84ec4ddbad9cef57dd3e --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_stl_knot_max_simplified.blend
)
+endif()
# STL Export
+# disabled until updated & working
+if(FALSE)
add_test(export_stl_cube_all_data ${TEST_BLENDER_EXE}
${TEST_SRC_DIR}/io_tests/blend_geometry/cube_all_data.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
@@ -233,9 +248,12 @@ add_test(export_stl_vertices ${TEST_BLENDER_EXE} # lame, add a better one
--md5_source=${TEST_OUT_DIR}/export_stl_vertices.stl
--md5=3fd3c877e573beeebc782532cc005820 --md5_method=FILE
)
+endif()
# X3D Import
+# disabled until updated & working
+if(FALSE)
add_test(import_x3d_cube ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.x3d\(filepath='${TEST_SRC_DIR}/io_tests/x3d/color_cube.x3d'\)
@@ -281,10 +299,13 @@ add_test(export_x3d_all_objects ${TEST_BLENDER_EXE}
--md5_source=${TEST_OUT_DIR}/export_x3d_all_objects.x3d
--md5=f5f9fa4c5619a0eeab66685aafd2f7f0 --md5_method=FILE
)
+endif()
# 3DS Import
+# disabled until updated & working
+if(FALSE)
add_test(import_3ds_cube ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.autodesk_3ds\(filepath='${TEST_SRC_DIR}/io_tests/3ds/cube.3ds'\)
@@ -305,8 +326,11 @@ add_test(import_3ds_hierarchy_greek_trireme ${TEST_BLENDER_EXE}
--md5=b62ee30101e8999cb91ef4f8a8760056 --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_3ds_hierarchy_greek_trireme.blend
)
+endif()
# 3DS Export
+# disabled until updated & working
+if(FALSE)
add_test(export_3ds_cube ${TEST_BLENDER_EXE}
${TEST_SRC_DIR}/io_tests/blend_geometry/all_quads.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
@@ -330,11 +354,14 @@ add_test(export_3ds_all_objects ${TEST_BLENDER_EXE}
--md5_source=${TEST_OUT_DIR}/export_3ds_all_objects.3ds
--md5=68447761ab0ca38e1e22e7c177ed48a8 --md5_method=FILE
)
+endif()
# FBX Export
# 'use_metadata=False' for reliable md5's
+# disabled until updated & working
+if(FALSE)
add_test(export_fbx_cube ${TEST_BLENDER_EXE}
${TEST_SRC_DIR}/io_tests/blend_geometry/all_quads.blend
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
@@ -358,3 +385,23 @@ add_test(export_fbx_all_objects ${TEST_BLENDER_EXE}
--md5_source=${TEST_OUT_DIR}/export_fbx_all_objects.fbx
--md5=b35eb2a9d0e73762ecae2278c25a38ac --md5_method=FILE
)
+endif()
+
+if(WITH_CYCLES)
+ if(OPENIMAGEIO_IDIFF AND EXISTS "${TEST_SRC_DIR}/cycles/ctests/shader")
+ add_test(cycles_reports_test
+ ${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
+ -blender "${TEST_BLENDER_EXE_BARE}"
+ -testdir "${TEST_SRC_DIR}/cycles/ctests/reports"
+ -idiff "${OPENIMAGEIO_IDIFF}"
+ )
+ add_test(cycles_shaders_test
+ ${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
+ -blender "${TEST_BLENDER_EXE_BARE}"
+ -testdir "${TEST_SRC_DIR}/cycles/ctests/shader"
+ -idiff "${OPENIMAGEIO_IDIFF}"
+ )
+ else()
+ MESSAGE(STATUS "Disabling Cycles tests because tests folder does not exist")
+ endif()
+endif()
diff --git a/tests/python/batch_import.py b/tests/python/batch_import.py
index dea08b45c3a..8fc679a7c15 100644
--- a/tests/python/batch_import.py
+++ b/tests/python/batch_import.py
@@ -78,7 +78,9 @@ def batch_import(operator="",
path = os.path.abspath(path)
match_upper = match.upper()
- pattern_match = lambda a: fnmatch.fnmatchcase(a.upper(), match_upper)
+
+ def pattern_match(a):
+ return fnmatch.fnmatchcase(a.upper(), match_upper)
def file_generator(path):
for dirpath, dirnames, filenames in os.walk(path):
diff --git a/tests/python/bl_load_addons.py b/tests/python/bl_load_addons.py
index f04ae64ee73..227edf4164d 100644
--- a/tests/python/bl_load_addons.py
+++ b/tests/python/bl_load_addons.py
@@ -20,12 +20,28 @@
# simple script to enable all addons, and disable
+"""
+./blender.bin --background -noaudio --factory-startup --python tests/python/bl_load_addons.py
+"""
+
import bpy
import addon_utils
+import os
import sys
import imp
+BLACKLIST_DIRS = (
+ os.path.join(bpy.utils.resource_path('USER'), "scripts"),
+ ) + tuple(addon_utils.paths()[1:])
+
+
+def addon_modules_sorted():
+ modules = addon_utils.modules({})
+ modules[:] = [mod for mod in modules if not mod.__file__.startswith(BLACKLIST_DIRS)]
+ modules.sort(key=lambda mod: mod.__name__)
+ return modules
+
def disable_addons():
# first disable all
@@ -36,8 +52,7 @@ def disable_addons():
def test_load_addons():
- modules = addon_utils.modules({})
- modules.sort(key=lambda mod: mod.__name__)
+ modules = addon_modules_sorted()
disable_addons()
@@ -48,7 +63,7 @@ def test_load_addons():
for mod in modules:
mod_name = mod.__name__
print("\tenabling:", mod_name)
- addon_utils.enable(mod_name)
+ addon_utils.enable(mod_name, default_set=True)
if mod_name not in addons:
addons_fail.append(mod_name)
@@ -62,8 +77,7 @@ def test_load_addons():
def reload_addons(do_reload=True, do_reverse=True):
- modules = addon_utils.modules({})
- modules.sort(key=lambda mod: mod.__name__)
+ modules = addon_modules_sorted()
addons = bpy.context.user_preferences.addons
disable_addons()
@@ -73,10 +87,10 @@ def reload_addons(do_reload=True, do_reverse=True):
for mod in modules:
mod_name = mod.__name__
print("\tenabling:", mod_name)
- addon_utils.enable(mod_name)
+ addon_utils.enable(mod_name, default_set=True)
assert(mod_name in addons)
- for mod in addon_utils.modules({}):
+ for mod in modules:
mod_name = mod.__name__
print("\tdisabling:", mod_name)
addon_utils.disable(mod_name)
@@ -86,9 +100,9 @@ def reload_addons(do_reload=True, do_reverse=True):
if do_reload:
imp.reload(sys.modules[mod_name])
- if do_reverse:
- # in case order matters when it shouldn't
- modules.reverse()
+ if do_reverse:
+ # in case order matters when it shouldn't
+ modules.reverse()
def main():
diff --git a/tests/python/bl_load_py_modules.py b/tests/python/bl_load_py_modules.py
index 9677397e01d..07905dfa4b4 100644
--- a/tests/python/bl_load_py_modules.py
+++ b/tests/python/bl_load_py_modules.py
@@ -20,6 +20,10 @@
# simple script to enable all addons, and disable
+"""
+./blender.bin --background -noaudio --factory-startup --python tests/python/bl_load_py_modules.py
+"""
+
import bpy
import addon_utils
@@ -30,8 +34,20 @@ BLACKLIST = {
"bl_i18n_utils",
"cycles",
"io_export_dxf", # TODO, check on why this fails
+ 'io_import_dxf', # Because of cydxfentity.so dependency
}
+BLACKLIST_DIRS = (
+ os.path.join(bpy.utils.resource_path('USER'), "scripts"),
+ ) + tuple(addon_utils.paths()[1:])
+
+
+def addon_modules_sorted():
+ modules = addon_utils.modules({})
+ modules[:] = [mod for mod in modules if not mod.__file__.startswith(BLACKLIST_DIRS)]
+ modules.sort(key=lambda mod: mod.__name__)
+ return modules
+
def source_list(path, filename_check=None):
from os.path import join
@@ -47,8 +63,7 @@ def source_list(path, filename_check=None):
def load_addons():
- modules = addon_utils.modules({})
- modules.sort(key=lambda mod: mod.__name__)
+ modules = addon_modules_sorted()
addons = bpy.context.user_preferences.addons
# first disable all
@@ -59,7 +74,7 @@ def load_addons():
for mod in modules:
mod_name = mod.__name__
- addon_utils.enable(mod_name)
+ addon_utils.enable(mod_name, default_set=True)
assert(mod_name in addons)
@@ -79,9 +94,10 @@ def load_modules():
for script_path in paths:
for mod_dir in sys.path:
if mod_dir.startswith(script_path):
- if mod_dir not in module_paths:
- if os.path.exists(mod_dir):
- module_paths.append(mod_dir)
+ if not mod_dir.startswith(BLACKLIST_DIRS):
+ if mod_dir not in module_paths:
+ if os.path.exists(mod_dir):
+ module_paths.append(mod_dir)
#
# collect modules from our paths.
diff --git a/tests/python/bl_pyapi_mathutils.py b/tests/python/bl_pyapi_mathutils.py
index 85232e465d7..b7f61df0e40 100644
--- a/tests/python/bl_pyapi_mathutils.py
+++ b/tests/python/bl_pyapi_mathutils.py
@@ -2,7 +2,7 @@
# ./blender.bin --background -noaudio --python tests/python/bl_pyapi_mathutils.py -- --verbose
import unittest
-from mathutils import Matrix, Vector
+from mathutils import Matrix, Vector, Quaternion
from mathutils import kdtree
import math
@@ -210,6 +210,35 @@ class VectorTesting(unittest.TestCase):
self.assertAlmostEqual(v.angle(v.orthogonal()), angle_90d)
+class QuaternionTesting(unittest.TestCase):
+
+ def test_to_expmap(self):
+ q = Quaternion((0, 0, 1), math.radians(90))
+
+ e = q.to_exponential_map()
+ self.assertAlmostEqual(e.x, 0)
+ self.assertAlmostEqual(e.y, 0)
+ self.assertAlmostEqual(e.z, math.radians(90), 6)
+
+ def test_expmap_axis_normalization(self):
+ q = Quaternion((1, 1, 0), 2)
+ e = q.to_exponential_map()
+
+ self.assertAlmostEqual(e.x, 2 * math.sqrt(0.5), 6)
+ self.assertAlmostEqual(e.y, 2 * math.sqrt(0.5), 6)
+ self.assertAlmostEqual(e.z, 0)
+
+ def test_from_expmap(self):
+ e = Vector((1, 1, 0))
+ q = Quaternion(e)
+ axis, angle = q.to_axis_angle()
+
+ self.assertAlmostEqual(angle, math.sqrt(2), 6)
+ self.assertAlmostEqual(axis.x, math.sqrt(0.5), 6)
+ self.assertAlmostEqual(axis.y, math.sqrt(0.5), 6)
+ self.assertAlmostEqual(axis.z, 0)
+
+
class KDTreeTesting(unittest.TestCase):
@staticmethod
diff --git a/tests/python/bl_rna_wiki_reference.py b/tests/python/bl_rna_wiki_reference.py
index 5781c53c045..a637f6d555c 100644
--- a/tests/python/bl_rna_wiki_reference.py
+++ b/tests/python/bl_rna_wiki_reference.py
@@ -92,13 +92,18 @@ def test_language_coverage():
def test_urls():
+ import os
import sys
import rna_wiki_reference
import urllib.error
from urllib.request import urlopen
- prefix = rna_wiki_reference.url_manual_prefix
+ # avoid URL lookups if possible
+ LOCAL_PREFIX = os.environ.get("LOCAL_PREFIX")
+ if LOCAL_PREFIX is None:
+ prefix = rna_wiki_reference.url_manual_prefix
+
urls = {suffix for (rna_id, suffix) in rna_wiki_reference.url_manual_mapping}
urls_len = "%d" % len(urls)
@@ -113,16 +118,26 @@ def test_urls():
urls_fail = []
- for url in sorted(urls):
- url_full = prefix + url
- print(" %s ... " % url_full, end="")
- sys.stdout.flush()
- try:
- urlopen(url_full)
- print(color_green + "OK" + color_normal)
- except urllib.error.HTTPError:
- print(color_red + "FAIL!" + color_normal)
- urls_fail.append(url)
+ if LOCAL_PREFIX:
+ for url in sorted(urls):
+ url_full = os.path.join(LOCAL_PREFIX, url.partition("#")[0])
+ print(" %s ... " % url_full, end="")
+ if os.path.exists(url_full):
+ print(color_green + "OK" + color_normal)
+ else:
+ print(color_red + "FAIL!" + color_normal)
+ urls_fail.append(url)
+ else:
+ for url in sorted(urls):
+ url_full = prefix + url
+ print(" %s ... " % url_full, end="")
+ sys.stdout.flush()
+ try:
+ urlopen(url_full)
+ print(color_green + "OK" + color_normal)
+ except urllib.error.HTTPError:
+ print(color_red + "FAIL!" + color_normal)
+ urls_fail.append(url)
if urls_fail:
urls_len = "%d" % len(urls_fail)
diff --git a/tests/python/bl_run_operators.py b/tests/python/bl_run_operators.py
index f7fafe833aa..d511cd19ff7 100644
--- a/tests/python/bl_run_operators.py
+++ b/tests/python/bl_run_operators.py
@@ -34,6 +34,10 @@ RANDOM_SEED = [1] # so we can redo crashes
RANDOM_RESET = 0.1 # 10% chance of resetting on each new operator
RANDOM_MULTIPLY = 10
+STATE = {
+ "counter": 0,
+ }
+
op_blacklist = (
"script.reload",
@@ -75,6 +79,7 @@ op_blacklist = (
"wm.properties_context_change",
"wm.operator_cheat_sheet",
"wm.interface_theme_*",
+ "wm.previews_ensure", # slow - but harmless
"wm.appconfig_*", # just annoying - but harmless
"wm.keyitem_add", # just annoying - but harmless
"wm.keyconfig_activate", # just annoying - but harmless
@@ -248,7 +253,8 @@ def run_ops(operators, setup_func=None, reset=True):
# first invoke
for op_id, op in operators:
if op.poll():
- print(" operator:", op_id)
+ print(" operator: %4d, %s" % (STATE["counter"], op_id))
+ STATE["counter"] += 1
sys.stdout.flush() # in case of crash
# disable will get blender in a bad state and crash easy!
diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py
new file mode 100755
index 00000000000..36fad175cfa
--- /dev/null
+++ b/tests/python/cycles_render_tests.py
@@ -0,0 +1,166 @@
+#!/usr/bin/env python3
+# Apache License, Version 2.0
+
+import argparse
+import os
+import subprocess
+import sys
+import tempfile
+
+
+def render_file(filepath):
+ command = (
+ BLENDER,
+ "--background",
+ "-noaudio",
+ "--factory-startup",
+ filepath,
+ "-E", "CYCLES",
+ "-o", TEMP_FILE_MASK,
+ "-F", "PNG",
+ "-f", "1",
+ )
+ try:
+ output = subprocess.check_output(command)
+ if VERBOSE:
+ print(output.decode("utf-8"))
+ return None
+ except subprocess.CalledProcessError as e:
+ if os.path.exists(TEMP_FILE):
+ os.remove(TEMP_FILE)
+ if VERBOSE:
+ print(e.output.decode("utf-8"))
+ if b"Error: engine not found" in e.output:
+ return "NO_CYCLES"
+ elif b"blender probably wont start" in e.output:
+ return "NO_START"
+ return "CRASH"
+ except:
+ if os.path.exists(TEMP_FILE):
+ os.remove(TEMP_FILE)
+ if VERBOSE:
+ print(e.output.decode("utf-8"))
+ return "CRASH"
+
+
+def test_get_name(filepath):
+ filename = os.path.basename(filepath)
+ return os.path.splitext(filename)[0]
+
+
+def verify_output(filepath):
+ testname = test_get_name(filepath)
+ dirpath = os.path.dirname(filepath)
+ reference_dirpath = os.path.join(dirpath, "reference_renders")
+ reference_image = os.path.join(reference_dirpath, testname + ".png")
+ if not os.path.exists(reference_image):
+ return False
+ command = (
+ IDIFF,
+ "-fail", "0.01",
+ "-failpercent", "1",
+ reference_image,
+ TEMP_FILE,
+ )
+ try:
+ subprocess.check_output(command)
+ return True
+ except subprocess.CalledProcessError as e:
+ if VERBOSE:
+ print(e.output.decode("utf-8"))
+ return e.returncode == 1
+
+
+def run_test(filepath):
+ testname = test_get_name(filepath)
+ spacer = "." * (32 - len(testname))
+ print(testname, spacer, end="")
+ sys.stdout.flush()
+ error = render_file(filepath)
+ if not error:
+ if verify_output(filepath):
+ print("PASS")
+ else:
+ error = "VERIFY"
+ if error:
+ print("FAIL", error)
+ return error
+
+
+def blend_list(path):
+ for dirpath, dirnames, filenames in os.walk(path):
+ for filename in filenames:
+ if filename.lower().endswith(".blend"):
+ filepath = os.path.join(dirpath, filename)
+ yield filepath
+
+
+def run_all_tests(dirpath):
+ failed_tests = []
+ all_files = list(blend_list(dirpath))
+ all_files.sort()
+ for filepath in all_files:
+ error = run_test(filepath)
+ if error:
+ if error == "NO_CYCLES":
+ print("Can't perform tests because Cycles failed to load!")
+ return False
+ elif error == "NO_START":
+ print('Can not perform tests because blender fails to start.',
+ 'Make sure INSTALL target was run.')
+ return False
+ elif error == 'VERIFY':
+ pass
+ else:
+ print("Unknown error %r" % error)
+ testname = test_get_name(filepath)
+ failed_tests.append(testname)
+ if failed_tests:
+ failed_tests.sort()
+ print("\n\nFAILED tests:")
+ for test in failed_tests:
+ print(" ", test)
+ return False
+ return True
+
+
+def create_argparse():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-blender", nargs="+")
+ parser.add_argument("-testdir", nargs=1)
+ parser.add_argument("-idiff", nargs=1)
+ return parser
+
+
+def main():
+ parser = create_argparse()
+ args = parser.parse_args()
+
+ global BLENDER, ROOT, IDIFF
+ global TEMP_FILE, TEMP_FILE_MASK, TEST_SCRIPT
+ global VERBOSE
+
+ BLENDER = args.blender[0]
+ ROOT = args.testdir[0]
+ IDIFF = args.idiff[0]
+
+ TEMP = tempfile.mkdtemp()
+ TEMP_FILE_MASK = os.path.join(TEMP, "test")
+ TEMP_FILE = TEMP_FILE_MASK + "0001.png"
+
+ TEST_SCRIPT = os.path.join(os.path.dirname(__file__), "runtime_check.py")
+
+ VERBOSE = os.environ.get("BLENDER_VERBOSE") is not None
+
+ ok = run_all_tests(ROOT)
+
+ # Cleanup temp files and folders
+ if os.path.exists(TEMP_FILE):
+ os.remove(TEMP_FILE)
+ os.rmdir(TEMP)
+
+ sys.exit(not ok)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/python/pep8.py b/tests/python/pep8.py
index 7713ffeaaa4..551e2a87e9b 100644
--- a/tests/python/pep8.py
+++ b/tests/python/pep8.py
@@ -95,13 +95,23 @@ def main():
print(" %s" % f)
# strict imports
- print("\n\n\n# running pep8...")
+ print("\n\n\n# checking imports...")
import re
import_check = re.compile(r"\s*from\s+[A-z\.]+\s+import \*\s*")
for f, pep8_type in files:
for i, l in enumerate(open(f, 'r', encoding='utf8')):
if import_check.match(l):
print("%s:%d:0: global import bad practice" % (f, i + 1))
+ del re, import_check
+
+ print("\n\n\n# checking class definitions...")
+ import re
+ class_check = re.compile(r"\s*class\s+.*\(\):.*")
+ for f, pep8_type in files:
+ for i, l in enumerate(open(f, 'r', encoding='utf8')):
+ if class_check.match(l):
+ print("%s:%d:0: empty class (), remove" % (f, i + 1))
+ del re, class_check
print("\n\n\n# running pep8...")